基于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
相关产品推荐
相关产品推荐

