LoginSignup
2
3

More than 3 years have passed since last update.

Discord.pyとA3RTのTalkAPI(pya3rt)を利用して簡単にTalkBotを作る。

Last updated at Posted at 2020-01-26

とあるDiscord.pyを使って色々試してた昼下がりのこと、
Discordのサーバーでこんなことを言ってる人が居た。
「おしゃべりくん欲しい!!」
おしゃべりくんとは、一時期よく見た喋り相手が居ないぼっちに優しいDiscord上のTalkBotのことなわけだが....
そういえば、A3RTとかいう無料で使えるAPIがあったな。
よし、作ろう。

一応注意事項。

これを書いてる人はPython初心者勢なので至らぬところがあるかもしれません。そのときはやさしくお願いします....
あと、Qiita初投稿です。よろしくおねがいします。ねこです。

環境

環境についてはQiitaに落ちている記事のようなBotと比べるとかなりアウトローなのでこれを参考にされる方は自分の環境に合わせてください。

  • discord.py 1.3.0
  • Python 3.7.2
  • Herokuで複数のBotを回すためイベントループを共有させたりしてます。
  • Bot Commands Framework及びCogを使っています。

やりたいこと

特定のチャンネルで喋ったら無条件に反応し
→それにA3RTTalkAPIで返す。

じゃあやってこー。

A3RTのAPIKEY発行

TalkAPIのページからメール送信したりで簡単にAPIKEY発行できます。後で使います。

Botの中身書いてこー。

run.pyをこんな感じで。

run.py
import discord
from discord.ext import commands
import asyncio
import os
import sys
import traceback

loop = asyncio.get_event_loop()

airlinia_token = os.environ['AIRLINIA_DISCORD_TOKEN'] # 環境変数~~。
technetium_token = os.environ['TECHNETIUM_DISCORD_TOKEN']

class DISCORDBOT(commands.Bot):
    # コンストラクタ。
    def __init__(self, command_prefix, cogs, **options):
        # スーパークラスのコンストラクタに値を渡して実行。
        super().__init__(command_prefix, **options)
        # cogフォルダにある.pyファイルを読み込む。
        for cog in os.listdir(f'./{cogs}'):
            if cog.endswith('.py'):
                try:
                    self.load_extension(f'{cogs}.{cog[:-3]}')
                except Exception:
                    traceback.print_exc()

    async def on_ready(self): # 準備完了時に呼び出す。
        print(f"""ログインしました。
        ------\nBotのアカウントの概要\nユーザー名:{self.user.name}\nユーザーID:{self.user.id}
        ------\nDiscord.pyのバージョン\n{discord.__version__}
        ------\nPythonのバージョン\n{sys.version}
        ――――――――――――――――――――――――――――――""")
        await self.change_presence(activity=discord.Game(name=f'{self.command_prefix}{self.user.name} - by.amazakura0804'))

if __name__ == '__main__':
    airlinia = DISCORDBOT(command_prefix='al!', cogs='airlinia_cogs', loop=loop)
    airlinia_task = loop.create_task(airlinia.start(airlinia_token))

    technetium = DISCORDBOT(command_prefix='te!', cogs='technetium_cogs', loop=loop)
    technetium_task = loop.create_task(technetium.start(technetium_token))

    loop.run_until_complete(technetium_task)
    loop.run_until_complete(airlinia_task)
    loop.close()

discord.pyのBot Commands Frameworkを用いたBot開発など参考にしながら。
TOKENについては環境変数にしています。ここらへんも環境によって変えてください。
別に2つ以上動かさないよー。って方はこんな感じで十分だと思います。

run.py
import discord
from discord.ext import commands
import asyncio
import os
import sys
import traceback

token = os.environ['DISCORD_TOKEN']

class HogeBot(commands.Bot):
    # コンストラクタ。
    def __init__(self, command_prefix, cogs, **options):
        # スーパークラスのコンストラクタに値を渡して実行。
        super().__init__(command_prefix, **options)
        # cogフォルダにある.pyファイルを読み込む。
        for cog in os.listdir(f'./{cogs}'):
            if cog.endswith('.py'):
                try:
                    self.load_extension(f'{cogs}.{cog[:-3]}')
                except Exception:
                    traceback.print_exc()

    async def on_ready(self): # 準備完了時に呼び出す。
        print(f"""ログインしました。
        ------\nBotのアカウントの概要\nユーザー名:{self.user.name}\nユーザーID:{self.user.id}
        ------\nDiscord.pyのバージョン\n{discord.__version__}
        ------\nPythonのバージョン\n{sys.version}
        ――――――――――――――――――――――――――――――""")
        await self.change_presence(activity=discord.Game(name=f'{self.command_prefix}{self.user.name} - by.amazakura0804'))

if __name__ == '__main__':
    hogebot = HogeBot(command_prefix='!', cogs='hogebot_cogs')
    hogebot.run(token) # Botのトークン

Talk.py

Talk.py
import discord
from discord.ext import commands
import asyncio
import os
import pya3rt

class Talk_Bot(commands.Cog):
    def __init__(self, airlinia):
        self.bot = airlinia #botを受け取る。

    @commands.Cog.listener()
    async def on_message(self, message):
        if message.author.bot:  # ボットのメッセージをハネる
            return
        if message.channel.id == TALK_CHANNEL_ID: # 適宜喋らせたいCHANNELIDに置き換え。
            client = pya3rt.TalkClient(os.environ['TALK_API_KEY']) # ここも環境変数なので以下略。
            content = client.talk(message.content)['results'][0]['reply']
            await message.channel.send(content) # 返信メッセージを送信

def setup(airlinia):
    airlinia.add_cog(Talk_Bot(airlinia))

はい。A3RT半端ない。A3RTのAPIKEYは環境変数に当てはめるか直接ぶち込むかしてみてください。
たったこれだけのコードで...

image.png

やったー。神。
リクルートさんありがとうございます。

最後に

A3RT含めた様々なAPIを利用することでかなりできることに幅が広がるなと。
他にもいろいろ面白そうなのがあるので活用してみたい。

2
3
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3