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

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令牌")

关键注意事项

  1. 权限意图配置:必须在代码和Discord开发者后台同时开启reactions、members意图,否则无法获取反应事件和用户信息。
  2. 禁用同步阻塞:永远不要在异步事件函数中使用time.sleep(),如果需要延迟操作,改用await asyncio.sleep(1)(需导入asyncio)。
  3. 消息过滤:通过集合存储目标消息ID,确保只处理我们主动发送的那条消息的反应,避免误触发其他消息的反应逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 00:22:07