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

基于Discord.py实现仅提及用户可反应的!join命令开发需求

Discord机器人!join命令修正方案

原代码存在的问题

  • on_reaction_add事件中使用未定义的ctx参数,会直接触发报错
  • 错误检查reaction.message.mentions:允许反应的用户是在**!join命令的原始消息**中提及的,而非机器人发送的带反应消息
  • 未过滤机器人自身的反应,会导致事件被误触发
  • 多余的member.emoji添加逻辑,用户仅需要🟢和❌两个反应

修正后的完整代码

# 全局字典,存储消息ID对应的允许反应用户ID列表
allowed_reactors = {}

@bot.command()
async def join(ctx, *members: discord.Member):
    # 未提及用户时给出提示
    if not members:
        await ctx.send("请至少提及一个用户!")
        return
    
    # 关联反应消息与允许的用户
    message = await ctx.send("Möchten Sie sich einschreiben? 🟢 / ❌")
    allowed_reactors[message.id] = [member.id for member in members]
    
    # 添加指定的两个反应
    await message.add_reaction("🟢")
    await message.add_reaction("❌")

@bot.event 
async def on_reaction_add(reaction, user):
    # 忽略机器人自身的反应
    if user.bot:
        return
    
    message_id = reaction.message.id
    # 非!join命令生成的消息直接跳过
    if message_id not in allowed_reactors:
        return
    
    # 检查用户是否在允许列表内,不在则移除反应
    allowed_user_ids = allowed_reactors[message_id]
    if user.id not in allowed_user_ids:
        await reaction.remove(user)
        return
    
    # 仅处理指定的两个反应
    if reaction.emoji == "🟢":
        await reaction.message.channel.send(f"{user.name} hat sich eingeschrieben.")
    elif reaction.emoji == "❌":
        await reaction.message.channel.send(f"{user.name} hat sich abgemeldet.")
    else:
        # 移除非指定的反应
        await reaction.remove(user)

关键修正点说明

  • 全局字典allowed_reactors:建立消息ID与允许反应用户ID的映射,解决了命令提及用户与反应消息的关联问题
  • 过滤机器人反应:避免机器人自身添加反应时触发事件逻辑
  • 使用用户ID存储:相比存储用户对象,ID更稳定,避免缓存失效问题
  • 反应校验:仅允许🟢和❌两个反应,其他反应直接移除
  • 错误提示:添加了未提及用户时的友好提示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 04:25:18