Dpyで即時反応可能なリアクション対話式メニューを作る

この記事は約2分で読めます。

Discord.pyでBotがメッセージを送信し、そこにリアクションを付与し、反応されたリアクションによってBotが行動するタイプの処理例。

ボタン機能が実装されたため最早使うこともない気がするが、古いコードを見返していたら昔迷ったところに遭遇したので一応残しておく。

巷のサンプルコードでは単純にリアクションを付与してwait_forを使う物が多いが、それだとBotのリアクション付与が終わるまでユーザーが待たねばならず、先にリアクションしても反応してくれない問題が出る。create_taskを使おう。

事前に関数を定義しておき

async def add_emoji(message, emoji_list):
    for emoji in emoji_list:
        await message.add_reaction(emoji)

送信したい箇所でこのようにする

emoji_list = ("🇾", "🇳")

message = await ctx.send("実行しますか?")
asyncio.get_event_loop().create_task(add_emoji(message, emoji_list))

def check(pay: discord.RawReactionActionEvent):
    return pay.user_id == ctx.author.id and pay.channel_id == ctx.channel.id and pay.emoji.name in emoji_list

try:
    pay: discord.RawReactionActionEvent = await bot.wait_for('raw_reaction_add', timeout=30, check=check)
except asyncio.TimeoutError:
    await ctx.send("しばらく操作がないため中断します。最初からやり直してください。")
else:
    await ctx.send(pay.emoji)

基礎がわかっている人ならすぐ応用法もわかると思うので、詳細解説は略する。

この例のように2リアクションくらいならほぼ問題にならないが、10個並べるようなメニューの場合はリアクション付与速度が大きな問題になる場合があった。

コメント

タイトルとURLをコピーしました