DiscordチャットボットをPythonでつくる (5) - 「おみくじ」機能を追加する
![今回は、チャットに入力されたメッセージに対し、チャットボットが返信を行う仕組みを追加します。そして、その仕組みを利用した「おみくじ」機能を追加していきます。 今回は、チャットに入力されたメッセージに対し、チャットボットが返信を行う仕組みを追加します。そして、その仕組みを利用した「おみくじ」機能を追加していきます。](/images/chatbot.webp)
今回は、チャットに入力されたメッセージに対し、チャットボットが返信を行う仕組みを追加します。
そして、その仕組みを利用した「おみくじ」機能を追加していきます。
前回までのまとめ
前回までは、チャットに入力されたメッセージをチャットボットが受信するところまで完成しました。
現在のchatbot.py
は以下の様になっています。
import discord
class MyClient(discord.Client):
async def on_ready(self):
"""Discord接続時に実行される関数."""
print(f'{self.user}として接続しました。')
async def on_message(self, message: discord.Message):
"""メッセージ受信時に実行される関数."""
print(f'{message.author}よりメッセージを受信しました: {message.content}')
with open('.discord_token') as f:
token = f.read().strip()
intents = discord.Intents.default()
intents.message_content = True
client = MyClient(intents=intents)
client.run(token)
メッセージに返信する
それでは、メッセージに返信を行う仕組みを on_message
に追加していきましょう。
しかし、これを行う際に一点注意が必要です。
メッセージ送信時の注意点
以下の問について少し考えてみてください。
on_message
に書かれているprint
関数を「メッセージを送信する関数」に変更した場合、どのようなことが起きるでしょうか?
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
正解は、「メッセージの無限ループが発生する」です。
チャットボットが送信したメッセージに対しても on_message
が実行されるため、
自身のメッセージに対しても返信を行い無限ループが発生してしまいます。
無限ループを防止するため、on_message
の最初に送信者がボットの場合の処理を入れておきましょう。
async def on_message(self, message: discord.Message):
"""メッセージ受信時に実行される関数."""
# ボット自身のメッセージは無視する
if message.author == self.user:
return
...
message.channel.send
でメッセージを送信する
それでは、メッセージを返信する処理を追加します。
メッセージの送信は、message.channel.send
関数で行うことができます。
on_message
関数を以下のように変更しましょう。
async def on_message(self, message: discord.Message):
"""メッセージ受信時に実行される関数."""
# ボット自身のメッセージは無視する
if message.author == self.user:
return
print(f'{message.author}よりメッセージを受信しました: {message.content}')
await message.channel.send(f'こんにちは、{message.author}!')
コード解説
message.channel.send
関数はコルーチン関数であるため、実行する際に先頭に await
を付けます。
(コルーチンに関する説明は引き続き先延ばしにします。)
実行する
それでは実行してみましょう。
python chatbot.py
メッセージを送信すると、以下のようにチャットボットが返信することを確認できました。
![](images/bot_talk.webp)
「おみくじ」機能を追加する
メッセージに返信ができるようになったので、on_message
関数の調整を行うことで様々な機能を追加することができるようなります。
それでは最初に、「おみくじ」機能を追加してみましょう。
仕様
「おみくじ」機能は、以下の仕様にします。
!omikuji
というメッセージで発動する。- 「大吉」、「吉」、「小吉」、「凶」、「大凶」の5つのうちいずれかがランダムに選択される。
実装する
それでは実装してみましょう。
chatbot.py
の先頭にimport random
を追加し、on_message
を以下のように変更します。
async def on_message(self, message: discord.Message):
"""メッセージ受信時に実行される関数."""
# ボット自身のメッセージは無視する
if message.author == self.user:
return
print(f'{message.author}よりメッセージを受信しました: {message.content}')
if message.content == '!omikuji':
choice = random.choice(['大吉', '吉', '小吉', '凶', '大凶'])
await message.channel.send(f"あなたの今日の運勢は **{choice}** です!")
実行する
実行してみましょう。
先程から起動したままであった場合は一度Ctrl+C
で停止して再度起動します。
python chatbot.py
!omikuji
と入力すると、以下のようにチャットボットが今日の運勢を占ってくれます。
![](images/bot_omikuji.webp)
まとめ
今回は受信したメッセージに返信できるようになり、
それを利用してチャットボットに「おみくじ」機能を追加しました。
今回はユーザのメッセージに対しチャットボットが返信するという1往復のコミュニケーションでしたが、
次回は、複数回の往復を実現する仕組みについて紹介します。
そしてその仕組みを利用して、チャットボットに「クイズ」機能を新たに追加します。
今回のコード
import discord
import random
class MyClient(discord.Client):
async def on_ready(self):
"""Discord接続時に実行される関数."""
print(f'{self.user}として接続しました。')
async def on_message(self, message: discord.Message):
"""メッセージ受信時に実行される関数."""
# ボット自身のメッセージは無視する
if message.author == self.user:
return
print(f'{message.author}よりメッセージを受信しました: {message.content}')
if message.content == '!omikuji':
choice = random.choice(['大吉', '吉', '小吉', '凶', '大凶'])
await message.channel.send(f"あなたの今日の運勢は **{choice}** です!")
with open('.discord_token') as f:
token = f.read().strip()
intents = discord.Intents.default()
intents.message_content = True
client = MyClient(intents=intents)
client.run(token)