discord.py如何限制用户对单条消息仅添加一个反应?
在discord.py中实现单一反应限制(需移除旧反应才能添加新反应)
你的需求是让用户只能在"A""B""C""D""E"五个反应中选一个——如果用户已经选过一个反应,再点另一个新反应时,机器人要移除刚添加的新反应,逼用户先删掉旧反应才能选新的。
你之前的代码逻辑刚好搞反了:它会删掉用户之前选的旧反应,保留新的,这和需求不符。正确的逻辑应该是:检测到用户添加新反应时,先检查用户是否已有其他合法反应,要是有,就把刚加的这个新反应删掉。
下面是实现代码:
import discord from discord.ext import commands intents = discord.Intents.default() intents.message_content = True intents.reactions = True bot = commands.Bot(command_prefix='!', intents=intents) # 定义允许的反应表情 ALLOWED_EMOJIS = ['A', 'B', 'C', 'D', 'E'] # 可选:填写目标消息ID,只针对这条消息生效,不需要就删掉这行 TARGET_MESSAGE_ID = 123456789012345678 @bot.event async def on_raw_reaction_add(payload): # 跳过机器人自己的反应 if payload.member.bot: return # 可选:只处理指定消息,不需要就删掉这行 if payload.message_id != TARGET_MESSAGE_ID: return emoji_str = str(payload.emoji) # 只处理我们设定的五个表情 if emoji_str not in ALLOWED_EMOJIS: return # 获取目标消息对象 channel = bot.get_channel(payload.channel_id) message = await channel.fetch_message(payload.message_id) # 收集该用户当前在这条消息上的所有合法反应 user_valid_reactions = [] for reaction in message.reactions: reaction_str = str(reaction.emoji) if reaction_str in ALLOWED_EMOJIS: # 检查该反应下是否包含当前用户 users = await reaction.users().flatten() if payload.member in users: user_valid_reactions.append(reaction_str) # 如果用户已有超过1个合法反应,说明刚加的是第二个,直接移除它 if len(user_valid_reactions) > 1: await message.remove_reaction(payload.emoji, payload.member) bot.run('你的机器人TOKEN')
关键逻辑说明:
- 用
on_raw_reaction_add监听反应添加事件,能直接拿到刚添加的表情和用户信息。 - 先过滤掉机器人、非目标表情/消息的情况,只处理我们关心的场景。
- 统计用户当前在这条消息上的合法反应数量,要是超过1,说明用户刚加了第二个反应,直接移除刚添加的这个。
- 这样用户必须先手动删除之前的反应,才能添加新的,完全符合你的需求。
注意事项:
- 确保机器人拥有管理消息的权限,不然没法移除用户的反应。
- 如果不需要针对特定消息,删掉
TARGET_MESSAGE_ID相关的判断即可,这样所有消息的A-E反应都会触发这个逻辑。
内容的提问来源于stack exchange,提问作者Daniel Andersen
相关产品推荐
相关产品推荐

