You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在discord.py中通过wait_for监听reaction_remove事件获取触发用户?

问题原因

  1. client.wait_for()的事件名参数不需要带on_前缀,你填写的on_reaction_remove是事件回调函数的命名规则,监听移除反应的正确事件名是reaction_remove。
  2. 原有的串行监听逻辑只能捕获加反应事件,无法同时处理加、删两种反应触发场景。

实现方案

你可以用asyncio.wait同时监听两种反应事件,谁先触发就先处理谁,同时建议在校验规则中限定仅处理你刚发送的embed消息的反应,避免其他消息的同表情反应干扰逻辑。

完整示例代码如下:

import asyncio
import discord
from discord.ext import commands

intents = discord.Intents.all()
client = commands.Bot(command_prefix='!', intents=intents)

@client.command()
async def test(ctx):
    emoji_yes = "✅"
    reacted_users = []
    # 构建并发送embed,保存消息对象
    test_embed = discord.Embed(title="反应测试", description="已同意用户:无")
    msg = await ctx.send(embed=test_embed)
    # 给消息添加初始表情
    await msg.add_reaction(emoji_yes)

    # 校验规则:仅匹配目标消息、指定表情、非bot自身的操作
    def check(reaction, user):
        return (
            reaction.message.id == msg.id
            and str(reaction.emoji) == emoji_yes
            and user != client.user
        )

    while True:
        # 同时创建两个监听任务
        add_task = asyncio.create_task(client.wait_for('reaction_add', check=check))
        remove_task = asyncio.create_task(client.wait_for('reaction_remove', check=check))
        # 等待任意一个任务触发
        done, pending = await asyncio.wait(
            [add_task, remove_task],
            return_when=asyncio.FIRST_COMPLETED
        )
        # 取消未触发的任务,避免内存泄漏
        for task in pending:
            task.cancel()

        # 处理触发的事件
        if add_task in done:
            reaction, user = add_task.result()
            if user not in reacted_users:
                reacted_users.append(user)
        else:
            reaction, user = remove_task.result()
            if user in reacted_users:
                reacted_users.remove(user)
        
        # 更新embed内容
        user_list = "、".join([u.name for u in reacted_users]) if reacted_users else "无"
        new_embed = discord.Embed(title="反应测试", description=f"已同意用户:{user_list}")
        await msg.edit(embed=new_embed)

注意事项

  • 你已经开启了Intents.all(),所以反应事件的权限是足够的,如果后续调整权限配置,需要确保intents.reactions = True处于开启状态。
  • 该场景下你是监听刚发送的消息,消息必然在bot的缓存中,不需要用到raw系列事件,普通反应事件即可正常触发。

内容的提问来源于stack exchange,提问作者DragonInTraining

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 15:24:01