概要
ChatGPT の Discord Bot を試しに作ってみたら数時間で完成したので、記事にしてみました。
以下のようにBotにメンションすると返事をしてくれます。
注意事項
- お金が掛かります。
- 筆者はDiscord Botを作るのが初めてです。
- 普段 Python を書かないのでコードも雑です。
- 本記事は忙しい人向けです。時間がある人は他の記事も参考にしましょう。
1. とりあえず Discord Bot を用意する
最速で Discord の Bot が作れる方法を発見しました。
以下の記事に従って、Discord Bot を用意します。
注意点がいくつかあります!
- BOTの追加設定が必要
- 課金が必要
- 2つ目の記事の冒頭にも書いてありますが、Herokuの無料プランが廃止されたため、課金が必要です。
- 筆者は一番安いプランの
Eco dynos
に登録しました。月5ドルです。
記事に従い /ping
に対して pong
が返ってきたら、次へ進みましょう。
2. OpenAI のアカウントを作成する
以下からアカウントを作成します。
特に詰まるポイントは無かったので説明は省きますが、困ったら「openai アカウント 作成」とかでググりましょう。
アカウントが作成できたら、以下から API key を作成します。
以下から API key が表示されていればOKです。
作成した API key は手順1で登録した Bot のトークンと同様に、Herokuに OPENAI_API_KEY
という名前で登録しておきましょう。
アカウント作成時に無料クレジットが付与されるので、そのクレジットを消費しきるまでは無料です。
Usage
から、使用量が確認できるので、定期的に確認しておきましょう。
クレジットを消費しきると止まると思うので、使い続けたい場合は課金しましょう。
1000トークンあたり0.002ドルなので、安いと思います。
3. Bot に対してメンションが来たら ChatGPT で返事をするようにする
ここからが本番です。手順1で作成したリポジトリの discordbot.py
を編集していきます。
その前に、requirements.txt
に pythonのパッケージ openai
を追加します。
discord.py[voice]
+ openai
これで、デプロイ時に以下の OpenAI のパッケージがインストールされます。
最後に、OpenAI のパッケージを利用して、以下のように discordbot.py
を編集します。
import discord
import traceback
from discord.ext import commands
from os import getenv
import openai
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix='/', intents=intents)
messages = [
{"role": "system", "content": "You are a helpful assistant. The AI assistant's name is AI Qiitan."},
{"role": "user", "content": "こんにちは。あなたは誰ですか?"},
{"role": "assistant", "content": "私は AI アシスタントの AI Qiitan です。なにかお手伝いできることはありますか?"}
]
@bot.event
async def on_command_error(ctx, error):
orig_error = getattr(error, "original", error)
error_msg = ''.join(traceback.TracebackException.from_exception(orig_error).format())
await ctx.send(error_msg)
@bot.event
async def on_message(message):
if message.author == bot.user:
return
if bot.user.id in [member.id for member in message.mentions]:
print(message.content)
print(message.content.split('>')[1].lstrip())
messages.append({"role": "user", "content": message.content.split('>')[1].lstrip()})
openai_api_key = getenv('OPENAI_API_KEY')
openai.api_key = openai_api_key
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=messages
)
print(completion.choices[0].message.content)
await message.channel.send(completion.choices[0].message.content)
token = getenv('DISCORD_BOT_TOKEN')
bot.run(token)
これで完成です!!
おまけ
上記の discordbot.py
を少し解説します。
その前に、今回使用しているパッケージのリファレンスを紹介します。
discord.py
以下が discord.py
日本語のドキュメントです。困ったらここを読みましょう。
一番参考にしたのは、APIリファレンスのページです。
例として、下で出てくる on_message
の引数 Message
がどんなクラスで、何を持っているかを参照しました。
openai-python
リポジトリは以下です。
公式ドキュメントは英語ですが、何となく雰囲気で理解できます。
他には、今回使用している openai.ChatCompletion
でググって出てきた例を参考にすれば実装できます。
discordbot.py
解説
以下のように on_message
で、Discordのメッセージを処理します。
@bot.event
async def on_message(message):
以下で、メッセージのメンションがある場合のみ、処理を行うようにしています。
if bot.user.id in [member.id for member in message.mentions]:
message.content
でメッセージを文字列で取得できますが、メンションが含まれる場合以下のようになっています。
<@123456789123456789> こんにちは
なので、以下のようにメンションより後ろの部分を取得しています。
message.content.split('>')[1].lstrip()
今回使用している API のopenai.ChatCompletion
は、3つのロール(system
, user
, assistant
)による会話に続く次のメッセージが返ってきます。今回は以下のように設定してみました。
system : あなたはアシスタントです。なまえは AI Qiitan です。
user : あなたは誰ですか?
assistant : 私は AI アシスタントの AI Qiitan です。
user : (ここに Discord から取得したメッセージを入れる)
assistant : (ここを ChatGPT が生成する)
これを python で書くと以下のようになります。
messages = [
{"role": "system", "content": "You are a helpful assistant. The AI assistant's name is AI Qiitan."},
{"role": "user", "content": "こんにちは。あなたは誰ですか?"},
{"role": "assistant", "content": "私は AI アシスタントの AI Qiitan です。なにかお手伝いできることはありますか?"}
]
messages.append({"role": "user", "content": message.content.split('>')[1].lstrip()})
そして、以下で ChatGPTが返したメッセージが取得できるので、これを Discord に投げています。
completion.choices[0].message.content
あとがき
きっかけは社内の Slack の ChatGPT API を使った bot でした。
社内でとても盛り上がっていたので、普段入り浸っているDiscordサーバーに導入したら盛り上がるのでは?と思い、作ってみました。
爆速で雑に作ったのでまだまだ改善の余地がありますが、こんな状態でもサーバーのメンバーが様々な質問をBotに投げかけており、めちゃくちゃ盛り上がりました。