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

Discord.py无法检测用户反应问题:Modmail系统中反应触发回复功能失效的排查与修复

问题分析与修复方案

我帮你梳理下代码里的核心问题,这就是为什么反应检测功能失效的原因:

  1. 反应检查函数的逻辑完全写反了
    你写的check1里判断user == client.user,这意味着只有机器人自己的反应才会被触发,但我们要检测的是发起私信的用户的操作。另外,用user!='Mod Mail Humara#5439'这种字符串方式判断用户也不严谨,Discord用户应该用user.id或者直接和message.author对比来确认身份。

  2. 异步发送消息时缺少await关键字
    代码最后一行message.author.send('yes')是异步操作,必须加上await才能正确执行,否则会直接抛出运行时错误。

  3. 没有处理超时异常
    如果用户30秒内没反应,wait_for会抛出asyncio.TimeoutError,你的代码没捕获这个异常,会导致机器人直接崩溃。

  4. 冗余变量无实际作用
    sent_users列表在on_message函数内部定义,每次收到私信都会重置,对当前的确认功能来说没有意义,可以暂时移除。


修复后的完整代码
import discord
import asyncio

# 初始化客户端时需要启用必要的意图
client = discord.Client(intents=discord.Intents.default())
client.intents.messages = True
client.intents.reactions = True
client.intents.guilds = True

@client.event
async def on_ready():
    print(f'Logged in as {client.user} (ID: {client.user.id})')
    print('------')

@client.event
async def on_message(message):
    # 忽略机器人自己发送的消息
    if message.author == client.user:
        return
    
    # 仅处理私信频道的消息
    if str(message.channel.type) == "private":
        embed = discord.Embed(title='Confirmation', color=0x03d692)
        embed.add_field(
            name="You're sending this message to **The Dynamic Legends**",
            value="React with :white_check_mark: to confirm.\nTo cancel this request, react with :x:.",
            inline=False
        )
        confirmation_msg = await message.author.send(embed=embed)
        await confirmation_msg.add_reaction('✅')
        await confirmation_msg.add_reaction('❌')
        
        try:
            # 修正检查条件:只响应发起私信用户的✅反应
            def check(reaction, user):
                return user == message.author and str(reaction.emoji) == '✅'
            
            # 等待用户反应,超时30秒
            await client.wait_for("reaction_add", timeout=30.0, check=check)
            
            # 正确发送回复(添加await关键字)
            await message.author.send('OK')
            
        except asyncio.TimeoutError:
            # 用户超时未反应时的提示
            await message.author.send('Confirmation timed out. Please try again.')
        except Exception as e:
            # 捕获其他异常避免机器人崩溃
            print(f'An error occurred: {e}')

client.run('YOUR_BOT_TOKEN')

关键修改说明
  • 修正反应检测逻辑:check函数现在确保只有发起私信的用户(user == message.author)的✅反应才会触发后续操作,完全匹配你的需求。
  • 补全异步操作关键字:发送回复时加上await,保证异步函数正确执行。
  • 添加异常处理:捕获超时异常并给出提示,同时捕获其他未知异常,避免机器人崩溃。
  • 启用必要的Intents:Discord机器人必须启用对应的意图才能捕获消息和反应事件,这是很多新手容易忽略的关键配置。
  • 清理冗余代码:移除了无作用的sent_users变量,让代码更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 03:52:40