discord.py中如何实现on_message与反应事件的协同运行?
问题解决:Discord.py中
on_message阻塞事件循环导致反应事件无法触发 问题根源
你代码里on_message中的while True+time.sleep(1)是同步阻塞操作,会直接卡死Discord客户端的事件循环,导致on_raw_reaction_add这类后续事件完全无法被处理。Discord.py的事件循环是单线程的,任何同步阻塞代码都会让整个Bot的事件处理停摆。
正确解决方案
移除阻塞循环,使用独立事件函数处理反应
你之前尝试的分开定义事件的思路是正确的,问题核心就出在on_message里的阻塞循环。只要去掉这个循环,两个事件就能正常协同工作。
完整代码示例
import discord from discord.ext import commands # 启用必要的权限意图 intents = discord.Intents.default() intents.message_content = True intents.reactions = True intents.members = True # 需开启此意图才能获取反应用户信息 client = commands.Bot(command_prefix="!", intents=intents) # 存储需要监听反应的消息ID(用于过滤非目标消息的反应) target_message_ids = set() @client.event async def on_message(message): if message.author == client.user: return if message.content.startswith("hi"): msg = await message.channel.send("Hello!") await msg.add_reaction("👋") # 将这条消息的ID加入监听集合 target_message_ids.add(msg.id) # 此处禁止添加任何阻塞循环! @client.event async def on_raw_reaction_add(payload): # 只处理我们监听的消息 if payload.message_id not in target_message_ids: return # 检查反应表情是否匹配 if str(payload.emoji) == "👋": # payload.member 即为触发反应的用户对象 print(f"用户 {payload.member.name} 发送了👋反应") client.run("你的Bot令牌")
关键注意事项
- 权限意图配置:必须在代码和Discord开发者后台同时开启
reactions、members意图,否则无法获取反应事件和用户信息。 - 禁用同步阻塞:永远不要在异步事件函数中使用
time.sleep(),如果需要延迟操作,改用await asyncio.sleep(1)(需导入asyncio)。 - 消息过滤:通过集合存储目标消息ID,确保只处理我们主动发送的那条消息的反应,避免误触发其他消息的反应逻辑。
内容的提问来源于stack exchange,提问作者idonthaveagoodname
相关产品推荐
相关产品推荐

