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

如何在discord.py中结合反应监听与!info消息触发输出功能?

解决discord.py中反应监听与!info命令结合的问题

核心思路是用一个全局存储结构(比如字典)来跨事件共享反应数据,把on_reaction_add中捕获的反应信息存起来,在on_message处理!info命令时读取这些数据。

完整代码示例

import discord
from discord.ext import commands

intents = discord.Intents.default()
intents.messages = True
intents.reactions = True
intents.message_content = True

bot = commands.Bot(command_prefix="!", intents=intents)

# 用字典存储反应数据:键是消息ID,值是{"emoji": 表情对象, "users": 用户ID列表}
bot.reaction_data = {}

@bot.event
async def on_reaction_add(reaction, user):
    # 忽略机器人自己的反应,避免循环触发
    if user.bot:
        return
    
    # 存储当前消息的反应信息,覆盖旧数据(如果需要保留多个表情,可改成嵌套字典)
    bot.reaction_data[reaction.message.id] = {
        "emoji": str(reaction.emoji),
        "users": [str(u) for u in await reaction.users().flatten()]
    }

@bot.event
async def on_message(message):
    # 先让bot处理自带的命令逻辑,避免冲突
    await bot.process_commands(message)
    
    # 过滤机器人消息,避免自触发
    if message.author.bot:
        return
    
    if message.content.startswith("!info"):
        # 拆分命令,支持指定消息ID(比如!info 123456789)
        parts = message.content.split()
        if len(parts) == 2:
            try:
                msg_id = int(parts[1])
                data = bot.reaction_data.get(msg_id)
            except ValueError:
                await message.channel.send("请输入有效的消息ID")
                return
        else:
            # 如果没指定ID,取最近一条有反应的消息数据
            if not bot.reaction_data:
                await message.channel.send("暂无反应记录")
                return
            msg_id = next(reversed(bot.reaction_data.keys()))
            data = bot.reaction_data[msg_id]
        
        if not data:
            await message.channel.send("该消息没有反应记录")
            return
        
        # 格式化输出信息
        response = (
            f"📝 目标消息ID: {msg_id}\n"
            f"😀 反应表情: {data['emoji']}\n"
            f"👥 反应用户列表:\n" + "\n".join([f"- {user}" for user in data['users']])
        )
        await message.channel.send(response)

bot.run("你的机器人TOKEN")

关键说明

  1. 跨事件数据共享:通过给bot对象添加reaction_data属性,实现on_reaction_add和on_message事件之间的数据传递,避免了局部变量无法跨事件访问的问题。
  2. 消息ID关联:用消息ID作为字典的键,确保每条消息的反应数据可以被精准定位。
  3. 命令扩展性:支持两种使用方式:
    • 直接输入!info:输出最近一条有反应的消息的信息
    • 输入!info 消息ID:输出指定消息的反应信息
  4. 边界处理:加入了忽略机器人消息、无效ID提示、无数据提示等逻辑,避免报错。

可选优化

  • 如果需要支持同一消息的多个表情反应,可以把bot.reaction_data改成嵌套字典,结构为{消息ID: {表情字符串: [用户列表]}}
  • 添加on_reaction_remove事件,实时更新用户列表,确保数据准确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 01:36:32