如何让discord.py的wait_for监听所有用户的reaction操作?
修复方案
你之前修改后功能失效的核心原因是:移除用户ID限制后,没有过滤机器人自身添加反应触发的reaction_add事件,机器人刚加完三个反应就会触发事件进入逻辑,导致后续流程异常。
修改后完整代码片段
embed = discord.Embed(title = "Currently Playing", colour = discord.Colour.blue()) embed.add_field(name = "Song", value = title, inline = False) embed.add_field(name = "Length", value = str(datetime.timedelta(seconds = length)), inline = False) embed.add_field(name = "Link", value = url, inline = False) msg = await ctx.send(embed=embed) await msg.add_reaction("\u23F8") await msg.add_reaction("\u25B6") await msg.add_reaction("\u23F9") while True: try: # 关键修改:移除ctx.author限制,新增过滤机器人自身的反应 reaction, user = await client.wait_for("reaction_add", check=lambda reaction, user: not user.bot and reaction.message.id == msg.id and reaction.emoji in ["\u23F8", "\u25B6", "\u23F9"], timeout = length) except asyncio.TimeoutError: return await msg.clear_reactions() async def process(): if reaction.emoji == "\u23F8": # 关键修改:移除当前点击用户的反应,而非最初点歌用户 await msg.remove_reaction(reaction.emoji, user) ctx.voice_client.pause() elif reaction.emoji == "\u25B6": await msg.remove_reaction(reaction.emoji, user) ctx.voice_client.resume() elif reaction.emoji == "\u23F9": await msg.remove_reaction(reaction.emoji, user) ctx.voice_client.stop() asyncio.create_task(process())
核心修改点说明
- 调整
wait_for的校验规则:删除user.id == ctx.author.id的限制,新增not user.bot条件过滤机器人自身触发的反应事件,避免机器人初始化加反应时误触发控制逻辑 - 替换
remove_reaction的目标用户:将所有移除反应的对象从ctx.author改为wait_for返回的user变量,保证点击反应的用户的操作可以被正常清除,支持重复点击
可选优化(按需添加)
如果需要限制只有和机器人在同一个语音频道的用户才能控制播放,可以在check校验中新增频道匹配逻辑:
check=lambda reaction, user: not user.bot and user.voice and user.voice.channel == ctx.voice_client.channel and reaction.message.id == msg.id and reaction.emoji in ["\u23F8", "\u25B6", "\u23F9"]
内容的提问来源于stack exchange,提问作者ZT255
相关产品推荐
相关产品推荐

