You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 17:57:05