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

Discord.py中使用Cogs检测用户表情反应无响应问题求助

问题:Discord机器人无法检测用户表情反应(discord.py Cogs结构)

问题概述

使用discord.py的Cogs结构开发Discord机器人,目标是检测用户对特定消息的✅或❌表情反应,但触发反应后程序无任何响应,也未抛出报错,尝试相关方案后问题仍未解决。

项目结构

├── main.py
├── cogs
│   ├── member.py

原代码问题分析

  1. Intents权限不足:discord.py v2.x版本需要明确开启反应相关的Intents,否则无法监听reaction_add事件。原代码仅开启了message_content,缺少reactions和私信消息权限。
  2. Check函数未限定目标消息:当前的check只验证用户和表情,没有绑定到需要监听的特定消息,导致无法识别用户是对哪条消息做出的反应。
  3. Wait_for返回值处理错误:reaction_add事件返回的是(reaction, user)元组,原代码直接用res.content会引发属性错误(但因前面的监听问题未触发)。
  4. 变量未定义与冗余逻辑:第二个wait_for中使用了未定义的reaction变量,且重复监听同一反应属于冗余逻辑。
  5. 未过滤Bot自身消息:on_message监听器会处理Bot自己发送的消息,可能导致逻辑冲突或循环。

修复方案

1. 修正main.py的Intents配置

开启reactions和dm_messages权限,确保Bot能监听反应事件和私信消息:

import asyncio
import os
from dotenv import load_dotenv
import discord
from discord.ext import commands

load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')

class MyBot(commands.Bot):
    def __init__(self):
        intents = discord.Intents.default()
        intents.message_content = True
        # 新增:开启反应和私信消息权限
        intents.reactions = True
        intents.dm_messages = True
        super().__init__(command_prefix=commands.when_mentioned_or('-'), intents=intents, max_messages=1000)

    async def on_ready(self):
        print(f'Logged in as {self.user} (ID: {self.user.id})')

    async def setup_hook(self):
        for file in os.listdir("./cogs"):
            if file.endswith(".py"):
                extension = file[:-3]
                try:
                    await self.load_extension(f"cogs.{extension}")
                    print(f"Loaded extension '{extension}'")
                except Exception as e:
                    exception = f"{type(e).__name__}: {e}"
                    print(f"Failed to load extension {extension}\n{exception}")

bot = MyBot()
bot.run(TOKEN)

2. 修正member.py的反应监听逻辑

  • 过滤Bot自身消息
  • 限定check函数到目标消息
  • 正确处理wait_for的返回值
  • 清理冗余逻辑:
import discord
from discord.ext import commands
from datetime import datetime

class command(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.Cog.listener()
    async def on_message(self, message):
        # 过滤Bot自身发送的消息
        if message.author.bot:
            return
        
        # 省略原有逻辑...
        emojis = ['✅', '❌']
        # 发送私信并添加反应
        dm_msg = await message.author.send('Send me that ✅ reaction, mate')
        await dm_msg.add_reaction('✅')
        await dm_msg.add_reaction('❌')

        # 定义check函数,限定消息为目标私信,且用户是消息作者
        def check(reaction, user):
            return user == message.author and reaction.message.id == dm_msg.id and str(reaction.emoji) in ['✅', '❌']

        # 等待反应,解构返回的元组
        reaction, user = await self.bot.wait_for(
            "reaction_add",
            check=check, timeout=None
        )
        print(reaction.emoji)

        # 根据不同表情回复
        if str(reaction.emoji) == "✅":
            await message.author.send("Got it")
        else:
            await message.author.send("Thanks")

async def setup(bot):
    await bot.add_cog(command(bot))

关键修复点说明

  • Intents配置:必须开启reactions才能监听反应事件,若涉及私信则需开启dm_messages。
  • Check函数绑定消息:通过reaction.message.id == 目标消息ID确保只监听指定消息的反应。
  • 返回值解构:wait_for("reaction_add")返回(reaction, user),需正确解构后使用。
  • 过滤Bot消息:避免on_message处理Bot自身消息引发的逻辑问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 01:31:04