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

Discord机器人:用户移除✅反应后未从响应用户列表中删除的问题求助

解决Discord Bot中用户移除✅反应后仍保留在响应列表的问题

你的问题核心在于:当前代码只监听了reaction_add(添加反应)事件,完全没有处理用户移除反应的reaction_remove事件,所以当用户取消✅时,列表不会自动更新。同时,原逻辑是追加用户而不是全量刷新,也会导致状态不一致。

下面是修复后的完整代码片段,我会标注关键改动:

# hatch <type> <time>
now = datetime.now()
add_time = now + timedelta(minutes=int(args[2]))
cur = add_time.strftime('%H:%M')
embed = discord.Embed(title='Raid meldung von ' + str(message.author.display_name), color=discord.Color.green())
embed.add_field(name='Raid Typ: ', value=args[1], inline=True)
embed.add_field(name="Schluepft um: ", value=cur + "", inline=True)
embed.add_field(name='Interesse: ', value='Keine Zusagen', inline=False)
channel = bot.get_channel(818662081531740163)
mess = await channel.send(embed=embed)
re_time = int(float(args[2])) * 60
emoji_list = ['✅', '❌']
for i in emoji_list:
    await mess.add_reaction(i)

# ------------------- 关键改动开始 -------------------
while True:
    try:
        # 同时监听添加和移除反应事件,谁先触发就处理谁
        done, pending = await asyncio.wait(
            [
                bot.wait_for("reaction_add"),
                bot.wait_for("reaction_remove")
            ],
            timeout=re_time,
            return_when=asyncio.FIRST_COMPLETED
        )
        # 获取触发的事件结果
        for task in done:
            reaction, user = task.result()
        
        # 只处理✅反应的变动
        if str(reaction.emoji) == '✅':
            # 重新获取消息,确保反应数据是最新的
            mess = await channel.fetch_message(mess.id)
            # 获取✅的反应对象
            check_react = get(mess.reactions, emoji='✅')
            users = ""
            
            if check_react:
                # 全量获取所有点击✅的用户,排除bot自身
                user_list = [u async for u in check_react.users() if u != bot.user]
                # 拼接用户提及字符串
                users = "\n".join([u.mention for u in user_list])
            
            # 如果没有用户,显示默认文本
            if not users:
                users = 'Keine Zusagen'
            
            # 更新embed
            embed1 = discord.Embed(title='Raid meldung von ' + str(message.author.display_name), color=discord.Color.green())
            embed1.add_field(name='Raid Typ: ', value=args[1], inline=True)
            embed1.add_field(name="Schluepft um: ", value=cur + "", inline=True)
            embed1.add_field(name='Interesse: ', value=users, inline=False)
            await mess.edit(embed=embed1)
            
        # 取消未完成的任务,避免内存泄漏
        for task in pending:
            task.cancel()
            
    except asyncio.TimeoutError:
        break
# ------------------- 关键改动结束 -------------------

await asyncio.sleep(re_time)
embed_end = discord.Embed(title='Raid meldung von ' + str(message.author.display_name), color=discord.Color.red())
embed_end.add_field(name='Raid Typ: ', value=args[1], inline=True)
embed_end.add_field(name="Schluepft um: ", value="Beendet", inline=True)
await mess.edit(embed = embed_end)
for i in emoji_list:
    await mess.clear_reactions()

改动说明:

  1. 同时监听两种反应事件:使用asyncio.wait同时等待reaction_add和reaction_remove,确保用户移除反应时也能触发列表更新。
  2. 全量刷新用户列表:每次反应变动时,重新获取当前所有点击✅的用户,而不是追加单个用户,这样能准确反映最新的响应状态。
  3. 简化逻辑:移除了不必要的count判断,让代码更易读;同时处理了无用户响应的情况,还原默认提示文本。
  4. 清理未完成任务:每次处理完事件后取消pending的任务,避免内存泄漏。

额外注意事项:

  • 确保你的Bot拥有read_message_history和manage_messages权限,这样才能正确读取反应用户和编辑消息。
  • 如果使用的是discord.py v2.x版本,语法基本一致,但需要注意intents的配置(需要开启message_content和reactions意图)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 10:22:46