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

Discord.py实现基于用户反应修改消息及相关功能求助

问题解决:Discord机器人反应处理与消息编辑功能实现

需求回顾

我开发了一个Discord机器人,当检测到消息中的'ping'词汇时,会在指定频道发送'pong!'消息并添加三个自定义表情反应(blue、red、yellow)。现在需要实现以下功能:

  • 用户添加反应后,机器人编辑消息,追加该用户的操作记录(如“{用户} said blue pong!”);
  • 移除用户添加的反应,保留机器人的三个初始反应;
  • 30分钟后自动移除所有反应。

但我无法完成on_raw_reaction_add事件的逻辑实现,现有代码如下:

blue = '<:blue:1033370324135333898>'
red = '<:red:1033370379663704148>'
yellow = '<:yellow:1033370423078952970>'

@client.event
async def on_message(message):
    if 'ping' in message.content.lower():
        if message.channel.id == 1032275628470308895:
            channel = client.get_channel(1032275628470308895)
            react = await channel.send('pong!')
            await react.add_reaction(blue)
            await react.add_reaction(red)
            await react.add_reaction(yellow)
            
@client.event
async def on_raw_reaction_add(payload):

# and then I don't know what to do, everything I've tried doesn't work
# I wanted to modify the message to (for example "{user} said blue pong!" and remove the reaction the user just use, and just keep the 3 from the bot)
# And then if another user use the yellow reaction, the bot modify his message to for example "{user] said yellow pong!"
# That could be great if the message was edited but keeping what was said before (in that case "pong! \n{user} said blue pong! \n{user} said yellow pong!")
# And last thing, if possible I want the bot to remove all reactions including his after 30mins

完整实现代码

import discord
from discord.ext import commands
import asyncio

# 初始化客户端,必须开启对应权限
intents = discord.Intents.default()
intents.message_content = True
intents.reactions = True
client = commands.Bot(command_prefix='!', intents=intents)

# 自定义表情ID与名称映射,方便后续判断
EMOJI_MAP = {
    1033370324135333898: 'blue',
    1033370379663704148: 'red',
    1033370423078952970: 'yellow'
}
# 指定目标频道ID
TARGET_CHANNEL_ID = 1032275628470308895

@client.event
async def on_ready():
    print(f'已登录:{client.user}')

@client.event
async def on_message(message):
    # 忽略机器人自身发送的消息
    if message.author == client.user:
        return
    # 只处理目标频道的ping消息
    if 'ping' in message.content.lower() and message.channel.id == TARGET_CHANNEL_ID:
        pong_msg = await message.channel.send('pong!')
        # 批量添加预设反应
        for emoji_id in EMOJI_MAP.keys():
            emoji = client.get_emoji(emoji_id)
            if emoji:
                await pong_msg.add_reaction(emoji)
        # 启动30分钟后清除所有反应的异步任务
        asyncio.create_task(clear_reactions_after_delay(pong_msg, 1800))

async def clear_reactions_after_delay(message, delay_sec):
    await asyncio.sleep(delay_sec)
    try:
        await message.clear_reactions()
    except discord.errors.NotFound:
        # 消息已被删除,直接跳过
        pass

@client.event
async def on_raw_reaction_add(payload):
    # 过滤机器人自己的反应
    if payload.user_id == client.user.id:
        return
    # 只处理目标频道的消息
    if payload.channel_id != TARGET_CHANNEL_ID:
        return
    
    # 提取表情ID(自定义表情是整数,普通表情是字符串)
    emoji_id = payload.emoji.id if payload.emoji.id else payload.emoji.name
    # 只处理我们预设的三个表情
    if emoji_id not in EMOJI_MAP:
        return
    
    try:
        # 获取消息和用户对象
        channel = client.get_channel(payload.channel_id)
        message = await channel.fetch_message(payload.message_id)
        user = client.get_user(payload.user_id) or await client.fetch_user(payload.user_id)
        
        # 构建追加内容并编辑消息
        emoji_name = EMOJI_MAP[emoji_id]
        new_content = f"{message.content}\n{user.display_name} said {emoji_name} pong!"
        await message.edit(content=new_content)
        
        # 移除用户添加的这个反应
        await message.remove_reaction(payload.emoji, user)
    except discord.errors.NotFound:
        # 消息或用户不存在,忽略错误
        pass
    except discord.errors.Forbidden:
        print("机器人没有编辑消息或移除反应的权限,请检查权限设置")

# 替换成你的机器人Token
client.run('YOUR_BOT_TOKEN')

关键逻辑说明

  1. 权限配置:必须开启message_content和reactions权限,否则机器人无法读取消息内容和监听反应事件。
  2. 表情映射:用字典存储表情ID和对应名称,快速判断用户点击的目标表情。
  3. 自动清除反应:发送pong消息后启动异步任务,等待30分钟后清除所有反应,不阻塞其他操作。
  4. 反应事件处理:
    • 先过滤机器人自身的反应和非目标频道的消息;
    • 验证反应是否属于预设的三个表情;
    • 编辑消息追加用户操作记录;
    • 移除用户添加的反应,保留机器人初始的三个反应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 06:15:38