使用on_raw_reaction_remove时如何获取实际执行反应移除的操作用户?
核心问题根因
Discord 反应移除类事件携带的payload.user_id字段,从API设计层面就固定存储被移除反应的所属用户ID,而非执行移除操作的人的ID。
这不是intents配置缺失的问题,也不是你写的拉取用户、拉取成员的代码逻辑的问题,是Discord服务端推送事件的固定字段定义——哪怕你开启了全部intents,也不会在反应移除事件中透传第三方操作者的身份。这类审计性质的操作记录,Discord不会开放给普通bot应用的接口。
你之前所有尝试都拿到原反应作者的本质原因,是你一直在根据payload返回的「反应所属用户ID」去拉取用户/成员信息,这个数据源本身就不包含操作者身份,自然永远拿不到执行移除操作的bot身份。
可落地的实现方案
因为Discord不会主动推送bot自身操作的事件溯源信息,你不需要依赖事件回调反推操作者身份,只需要在自己的代码逻辑里给bot主动发起的移除操作加自定义标记,跳过对应的回调逻辑,就能实现等价于if user == bot: return的判断效果:
- 维护一个全局的临时标记集合,用来记录当前由bot主动触发的反应移除事件,避免事件回调重复触发业务逻辑
- 在每次执行bot主动移除反应的代码前,先把对应事件的唯一标识加入标记集合
- 在
on_raw_reaction_remove事件的最开头,先检查当前触发的事件是否在标记集合中,如果是就直接跳过后续业务逻辑
可参考的代码实现:
# 全局集合存储bot主动触发的移除事件标记 # 存储结构为 (消息ID, 表情对象, 被移除反应的所属用户ID) bot_self_removal_marks = set() @client.event async def on_raw_reaction_remove(payload): # 构造当前事件的唯一标识 event_identity = ( payload.message_id, payload.emoji, payload.user_id # 该字段为API固定返回的被移除反应的原作者ID ) # 检查当前事件是否为bot自身主动触发的移除操作 if event_identity in bot_self_removal_marks: # 及时移除标记,避免内存占用 bot_self_removal_marks.remove(event_identity) return # 以下为真实用户操作触发移除的业务逻辑 reaction_owner = await client.fetch_user(payload.user_id) # 你的原有业务逻辑可写在这里
当你需要写代码主动触发bot移除他人反应时,按如下逻辑操作:
# 替换为你的实际业务参数 target_channel = client.get_channel(你的目标频道ID) target_message = await target_channel.fetch_message(你的目标消息ID) target_emoji = discord.PartialEmoji(name="👍") reaction_owner_id = 你要移除的反应对应的原用户ID # 执行移除操作前,先把对应事件的标记存入集合 bot_self_removal_marks.add((target_message.id, target_emoji, reaction_owner_id)) # 执行真正的移除动作 await target_message.remove_reaction(target_emoji, client.get_user(reaction_owner_id))
新手常见认知误区:很多人会把反应添加和移除事件的
user_id字段定义搞混。在反应添加事件中,操作人就是反应的添加者,user_id自然就是操作人本身,逻辑是通顺的;但在反应移除场景下,这个字段只关联反应条目的归属,和实际操作人无关——不存在“因为权限不够拿不到操作人ID”的情况,这个字段本身就不会携带操作者的相关数据。
内容的提问来源于stack exchange,提问作者masky007
相关产品推荐
相关产品推荐

