如何用Python实现Discord机器人监听用户点击反应后触发消息发送
解决方法
前置配置说明
- 你需要先在Discord开发者后台的机器人设置页,开启「Message Content Intent」「Server Members Intent」权限,否则事件监听会失效
- 现有代码中同时初始化
discord.Client和discord.ext.commands.Bot属于冗余定义,我们直接保留Client即可,删除Bot的实例化代码即可
完整实现代码
import discord # 开启必要的意图 intents = discord.Intents.default() intents.message_content = True intents.members = True client = discord.Client(intents=intents) # 存储石头剪刀布游戏消息的ID,避免响应其他消息的反应 game_message_ids = set() @client.event async def on_ready(): print('login successful {0.user}'.format(client)) @client.event async def on_message(message): if not message.author.bot and message.content.startswith('!rps'): msg2 = await message.channel.send('**Rock Paper Scissors**\n:mountain: Rock\n:page_facing_up: Paper\n:scissors: Scissors') await msg2.add_reaction('⛰') await msg2.add_reaction('📄') await msg2.add_reaction('✂') # 把当前游戏消息ID存入集合 game_message_ids.add(msg2.id) @client.event async def on_raw_reaction_add(payload): # 排除机器人自己加的反应 if payload.user_id == client.user.id: return # 只响应石头剪刀布游戏消息的反应 if payload.message_id not in game_message_ids: return # 获取对应频道和用户 channel = client.get_channel(payload.channel_id) user = await client.fetch_user(payload.user_id) # 根据用户点击的反应返回克制的选项 reaction_emoji = str(payload.emoji) if reaction_emoji == '⛰': await channel.send(f"{user.mention} Paper") elif reaction_emoji == '📄': await channel.send(f"{user.mention} Scissors") elif reaction_emoji == '✂': await channel.send(f"{user.mention} Rock") client.run('你的机器人Token')
逻辑说明
- 用
game_message_ids集合存储所有触发!rps后生成的游戏消息ID,避免机器人响应其他消息的反应 - 用
on_raw_reaction_add而非on_reaction_add是为了避免机器人重启后旧消息不在缓存中无法触发监听的问题 - 所有用户的选择都会被机器人返回克制的选项,完全符合你要的几乎不可能获胜的高难度游戏效果
内容的提问来源于stack exchange,提问作者Metsakast
相关产品推荐
相关产品推荐

