如何实现Discord机器人仅允许先加骷髅头表情后再加手提包表情?
Discord表情权限限制逻辑修复
问题背景
需求:仅当用户给消息添加过☠️(\U00002620\U0000fe0f)表情后,才允许其添加👜(\U0001F5BC\U0000FE0F)表情。
现有代码整合后存在以下问题:
- 无权限用户添加👜时,机器人仍会向目标频道发送消息
- 用户后续添加☠️后,不会自动触发添加👜的操作
问题分析
- 原代码未将权限校验与消息发送逻辑绑定,导致即使用户无权限,消息发送逻辑依然执行
- 缺少对用户添加☠️后的后续处理逻辑,无法自动补加👜
- 代码顺序不合理,权限校验在消息发送之后,无法阻止无效的消息发送
修复后的完整代码
import re import discord @client.event async def on_reaction_add(reaction, user): # 忽略机器人自身的反应,避免自触发 if user == client.user: return # 定义常量提升代码可读性 SKULL_EMOJI = "\U00002620\U0000fe0f" BAG_EMOJI = "\U0001F5BC\U0000FE0F" REWARD_CHANNEL_ID = 1245390045859549285 # 场景1:用户添加👜表情,先做权限校验 if str(reaction.emoji) == BAG_EMOJI: # 检查当前用户是否给该消息添加过☠️ skull_reaction = discord.utils.get(reaction.message.reactions, emoji=SKULL_EMOJI) has_skull_permission = False if skull_reaction: async for reacted_user in skull_reaction.users(): if reacted_user == user: has_skull_permission = True break # 无权限则移除用户的👜表情,终止后续流程 if not has_skull_permission: await reaction.remove(user) return # 有权限则执行消息转发逻辑 target_channel = client.get_channel(REWARD_CHANNEL_ID) # 过滤消息开头的角色提及 mention_regex = re.compile(r"^<@&(\d+)> ") filtered_content = mention_regex.sub("", reaction.message.content, 1) forwarded_message = await target_channel.send(f"{filtered_content} by {reaction.message.author.mention}") await forwarded_message.add_reaction(BAG_EMOJI) # 场景2:用户添加☠️表情,自动为用户补加👜(如果未添加过) elif str(reaction.emoji) == SKULL_EMOJI: # 检查用户是否已经添加过👜 bag_reaction = discord.utils.get(reaction.message.reactions, emoji=BAG_EMOJI) has_added_bag = False if bag_reaction: async for reacted_user in bag_reaction.users(): if reacted_user == user: has_added_bag = True break # 未添加过则自动为用户添加👜 if not has_added_bag: await reaction.message.add_reaction(BAG_EMOJI)
关键修复点
- 权限前置校验:在执行消息转发前先验证用户的☠️权限,无权限直接移除👜并终止流程,彻底避免无效消息发送
- 补加逻辑补充:新增用户添加☠️后的自动补加👜逻辑,满足用户后续操作的预期
- 代码健壮性优化:增加表情反应的空值判断,防止因消息无对应表情导致的报错;用常量统一管理表情和频道ID,提升代码可维护性
- 自触发规避:优先判断是否为机器人自身的反应,避免循环触发逻辑
内容的提问来源于stack exchange,提问作者Rivendare
相关产品推荐
相关产品推荐

