はじめに
discord.py を用いた Discord ボット開発において、ボットがメッセージを送信するまでの間に「○○○○が入力中...」と表示させようとしたときに、表示が消えてしまうことがあったのでその解決メモ
環境
Python 3.14.0
discord.py 2.6.4
基本のコード
async with message.channel.typing():
と記述し、このコードブロックの中でメッセージ送信処理を呼べばOK
↓何かしらかのメッセージを送信したら「こんにちは」と返すボットの例
@bot.event
async def on_message(message):
# 自身が送信したメッセージには反応しない
if message.author == bot.user:
return
# 「○○○○が入力中...」と表示 &「こんにちは」とメッセージを送信
async with message.channel.typing():
await message.channel.send("こんにちは")
トラブル
メッセージを送信するまでの間に時間のかかる処理を行う
→ 処理中にもかかわらず、一定時間で「○○○○が入力中...」の表示が消えてしまう
# 「○○○○が入力中...」と表示 &「こんにちは」とメッセージを送信
async with message.channel.typing():
# 時間のかかる処理
something()
await message.channel.send("こんにちは")
原因
時間のかかる処理を 同期 実行している。
解決
時間のかかる処理は 非同期 で実行する (非同期実行する処理を呼ぶ)
# 「○○○○が入力中...」と表示 &「こんにちは」とメッセージを送信
async with message.channel.typing():
# 時間のかかる処理
await async_something()
await message.channel.send("こんにちは")
同期処理しかない場合は、asyncio を用いれば非同期実行出来る。
import asyncio
(省略)
# 「○○○○が入力中...」と表示 &「こんにちは」とメッセージを送信
async with message.channel.typing():
# 時間のかかる処理
loop = asyncio.get_event_loop()
future = loop.run_in_executor(None, something)
await future
await message.channel.send("こんにちは")
補足など
同期処理だとボット全体の処理が止まってしまう。
「○○○○が入力中...」と表示する裏では、ボットから一定時間ごとに通信を行って表示を延長しているっぽい(たぶん)。
→ ボットからの通信が行えなくなるので表示が延長されなくなる
時間があれば詳しく調べてみようと思います。
おわりに
Discord ボット開発 の手助けになれば幸いです。
※本記事は非公式の内容であり、正しい説明を保証するものではありません。
※間違いなどございましたらコメントにてご連絡ください。