You need to enable JavaScript to run this app. discord.py实现石头剪刀布指令时机器人不响应表情反应的问题
优惠活动
大模型
产品
解决方案
定价
更多

discord.py实现石头剪刀布指令时机器人不响应表情反应的问题

discord.py 反应事件无响应排查与石头剪刀布功能修复

核心问题排查点

  • 事件未正确注册:on_reaction_add 是discord.py的内置事件回调,必须通过客户端/机器人实例的事件装饰器(如@bot.event)绑定,否则机器人不会识别该函数为事件处理逻辑,完全不会触发。
  • Intent权限未开启:discord.py 2.x+ 版本默认限制事件接收范围,必须手动在客户端初始化时开启reactions、guilds等相关intent,否则无法收到服务器的反应事件推送。
  • 反应对象判断逻辑错误:on_reaction_add 传入的reaction参数是discord.Reaction类实例,不是字符串,直接和emoji字符串对比永远为假,需要读取reaction.emoji属性匹配对应表情。
  • 未定义变量引用:代码中直接使用message变量,但on_reaction_add函数作用域内没有该变量,需从reaction.message获取反应所在的消息对象。
  • 拼写错误:message.chanel存在拼写错误,正确的通道属性为channel,错误拼写会直接抛出属性不存在的异常。
  • 随机逻辑不合理:rpsai 被定义为全局变量,仅在程序启动时随机生成1次,后续所有游戏局都会复用同一个随机值,不会随每局游戏重置。
  • 未过滤机器人自身反应:未排除user为机器人的情况,机器人自身添加的表情反应也会触发事件,导致逻辑误触发。

修复后可运行的示例代码

from random import randint
import discord
from discord.ext import commands

# 初始化客户端,开启所需intent
intents = discord.Intents.default()
intents.reactions = True  # 开启反应事件监听
intents.messages = True
intents.guilds = True
bot = commands.Bot(command_prefix="!", intents=intents)

# 石头剪刀布选项映射:1=石头,2=布,3=剪刀
rps_map = {
    1: "石头",
    2: "布",
    3: "剪刀"
}
rpsai = None

@bot.event
async def on_ready():
    print(f"机器人已登录:{bot.user}")

# 新增石头剪刀布发起指令,方便测试
@bot.command(name="rps")
async def start_rps(ctx):
    global rpsai
    # 每局游戏单独生成随机AI选项,不复用启动时的初始值
    rpsai = randint(1,3)
    msg = await ctx.send("请添加表情选择你的出拳:🧱=石头,📄=布,✂️=剪刀")
    # 给消息预设三个可选表情
    await msg.add_reaction("🧱")
    await msg.add_reaction("📄")
    await msg.add_reaction("✂️")

@bot.event
async def on_reaction_add(reaction, user):
    # 过滤机器人自身的反应,避免逻辑误触发
    if user.bot:
        return
    # 仅响应当前机器人发送的游戏消息的反应
    if reaction.message.author != bot.user:
        return
    # 判断用户添加的表情是否为游戏指定的石头表情
    if reaction.emoji == "🧱":
        ai_choice = rpsai
        channel = reaction.message.channel
        if ai_choice == 1:
            await channel.send(f"我出{rps_map[ai_choice]},平局!")
        elif ai_choice == 2:
            await channel.send(f"我出{rps_map[ai_choice]},我赢了!")
        elif ai_choice == 3:
            await channel.send(f"我出{rps_map[ai_choice]},你赢了!")
    # 可自行补充📄、✂️对应的判断逻辑

# 运行机器人,替换为你自己的机器人Token
bot.run("你的机器人Token")

额外注意事项

  • 若使用discord.py 2.x以上版本,需在Discord开发者后台的机器人设置页面,开启对应特权Intent权限,否则部分事件无法正常接收。
  • 若需要监听历史消息的反应事件,需确保机器人对对应服务器、目标消息有读取权限。
  • 全局rpsai变量建议替换为局内存储(如用消息ID绑定对应AI选项),避免多用户同时发起游戏时逻辑混乱。

内容的提问来源于stack exchange,提问作者Minecow 12345

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.28 00:24:09