discord.py开发:如何让Bot自动移除用户对指定消息的表情反应
问题原因与解决方法
核心问题1:操作的消息对象错误
你调用
remove_reaction的对象是用户发起游戏命令的原始message,但你要移除的反应是加在Bot发送的游戏面板消息The_Board上的,自然操作无效。
问题2:权限缺失
Discord要求Bot拥有*管理消息(Manage Messages)*权限,才能移除服务器内其他用户在消息上添加的反应,没有该权限时API会静默拒绝请求或者抛出403错误。
问题3:代码逻辑漏洞
- 你把
turn = 0写在了游戏循环内部,每次循环都会把回合重置为玩家1的回合,永远不会轮到玩家2操作 - 移除反应时不需要遍历所有7个表情,只需要移除用户刚刚点击的那一个表情即可,减少不必要的API请求
- 示例代码缺少
try块对应的缩进、check函数的判断逻辑,容易出现异常
修正方案
修正后的可运行代码参考:
import discord player1 = message.author #发起游戏命令的用户 player2 = message.mentions[0] #命令中第一个被@的用户 nums = ["1️⃣","2️⃣","3️⃣","4️⃣","5️⃣","6️⃣","7️⃣"] # 发送游戏面板并添加表情 The_Board = await message.channel.send("游戏面板内容") for emoji in nums: await The_Board.add_reaction(emoji) game_over = False turn = 0 # 回合变量移到循环外面 # 定义check函数 def check(reaction, user): # 只响应对游戏面板消息的反应,且操作人是当前回合的玩家 target_user = player1 if turn == 0 else player2 return reaction.message.id == The_Board.id and user == target_user and str(reaction.emoji) in nums while not game_over: try: reaction, confirmation = await client.wait_for("reaction_add", check=check, timeout=30) except TimeoutError: await The_Board.edit(content="操作超时,游戏结束") break # 处理对应表情逻辑 colnum = nums.index(str(reaction.emoji)) # 此处执行游戏相关逻辑 # --- 你的游戏逻辑代码 --- # 移除用户刚刚添加的反应,操作对象是游戏面板消息The_Board await The_Board.remove_reaction(reaction.emoji, confirmation) # 切换回合 turn = 1 - turn
额外注意事项
- 如果你使用的是discord.py v2.0+版本,确保你在开发者后台开启了
message_content、guild_reactions等意图(Intent),同时代码中初始化客户端时也声明了对应意图,否则Bot无法监听到反应添加事件 - 可以在调用移除反应的代码外层加
try-except捕获异常,方便排查权限、消息不存在类的问题
内容的提问来源于stack exchange,提问作者Minylugin
相关产品推荐
相关产品推荐

