如何让Discord.py机器人仅记录用户的首次表情反应?
解决Discord.py重复触发反应消息的问题
问题分析
你的代码存在两个核心问题:
- 定义了两个同名的
on_raw_reaction_add事件处理函数,这会导致前一个被后一个覆盖,只有最后一个事件逻辑会生效。 - 没有记录已完成首次反应的用户,用户取消反应后再次触发时,机器人会重复发送通知消息。
修复后的代码
我们可以通过一个全局集合存储已触发过反应的用户ID,同时合并事件处理逻辑,实现仅首次反应触发消息的需求:
from discord.utils import get # 存储已完成首次✅反应的用户ID,避免重复触发 reacted_users = set() @bot.event async def on_raw_reaction_add(payload): # 处理角色添加逻辑 if payload.channel_id == verify_channel_id: if str(payload.emoji) == "✅": guild = bot.get_guild(payload.guild_id) member = guild.get_member(payload.user_id) verified_role = get(guild.roles, name="REACTED") await member.add_roles(verified_role) # 处理消息通知逻辑,仅首次反应触发 if payload.channel_id == 1014925506606534689: if str(payload.emoji) == "✅": # 检查用户是否已触发过该反应 if payload.user_id not in reacted_users: reacted_users.add(payload.user_id) channel1 = bot.get_channel(1015516535223242762) member = bot.get_guild(payload.guild_id).get_member(payload.user_id) await channel1.send(f'{member.mention} REACTED WITH ✅!')
关键改进说明
- 使用
reacted_users集合记录已触发过的用户ID,每次触发前先做存在性检查,确保同一用户仅触发一次消息。 - 合并了两个重复的
on_raw_reaction_add事件,避免事件覆盖导致的逻辑失效问题。 - 注意:如果机器人重启,集合内的记录会丢失。若需要持久化存储已反应用户,可以改用JSON文件或数据库来保存用户ID。
内容的提问来源于stack exchange,提问作者Jellie
相关产品推荐
相关产品推荐

