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()
改动说明:
- 同时监听两种反应事件:使用
asyncio.wait同时等待reaction_add和reaction_remove,确保用户移除反应时也能触发列表更新。 - 全量刷新用户列表:每次反应变动时,重新获取当前所有点击✅的用户,而不是追加单个用户,这样能准确反映最新的响应状态。
- 简化逻辑:移除了不必要的
count判断,让代码更易读;同时处理了无用户响应的情况,还原默认提示文本。 - 清理未完成任务:每次处理完事件后取消pending的任务,避免内存泄漏。
额外注意事项:
- 确保你的Bot拥有
read_message_history和manage_messages权限,这样才能正确读取反应用户和编辑消息。 - 如果使用的是discord.py v2.x版本,语法基本一致,但需要注意
intents的配置(需要开启message_content和reactions意图)。
内容的提问来源于stack exchange,提问作者Kori LP
相关产品推荐
相关产品推荐

