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

Discord.py能否修改消息Embed?如何实现用户反应时添加用户到Embed?

当然能实现啦!Discord.py完全支持修改已发送消息里的Embed,刚好能满足你说的「用户反应后把用户加到Embed里」的需求。下面我给你拆解具体的实现思路和代码示例:

在Discord.py中修改消息Embed的实现方案

核心逻辑

机器人先发送带初始Embed的消息,我们需要保存这条消息的对象(或消息ID+频道ID);之后监听用户的反应事件,当触发目标反应时,重新构造包含新用户信息的Embed,最后调用消息对象的edit()方法替换原Embed即可。

具体步骤与代码示例

1. 发送初始Embed并保存消息对象

首先创建初始的报名Embed,发送后把返回的Message对象存起来(这里用字典存储,小体量机器人够用;如果是大型机器人,建议用数据库持久化存储):

import discord
from discord.ext import commands

# 开启所需权限,确保能监听反应、发送消息
intents = discord.Intents.default()
intents.message_content = True
intents.reactions = True

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

# 存储需要跟踪的消息:键是消息ID,值是消息对象
tracked_signup_msgs = {}

@bot.command()
async def start_signup(ctx):
    # 构造初始报名Embed
    signup_embed = discord.Embed(
        title="活动报名通道",
        description="点击✅按钮即可报名参加本次活动!",
        color=discord.Color.green()
    )
    signup_embed.add_field(name="已报名用户", value="暂无报名者", inline=False)
    
    # 发送消息并保存对象
    msg = await ctx.send(embed=signup_embed)
    # 添加触发用的反应表情
    await msg.add_reaction("✅")
    # 将消息存入跟踪字典
    tracked_signup_msgs[msg.id] = msg

2. 监听反应事件并更新Embed

用on_raw_reaction_add事件监听所有频道的反应(这个事件不受消息缓存限制,比on_reaction_add更可靠),当用户点击✅时更新Embed内容:

@bot.event
async def on_raw_reaction_add(payload):
    # 先判断是不是我们跟踪的报名消息
    if payload.message_id not in tracked_signup_msgs:
        return
    # 判断是不是目标反应表情
    if str(payload.emoji) != "✅":
        return
    
    # 获取消息对象和触发反应的用户
    target_msg = tracked_signup_msgs[payload.message_id]
    user = bot.get_user(payload.user_id)
    # 排除机器人自己的反应,避免循环触发
    if user.bot:
        return
    
    # 获取当前Embed并复制一份(直接修改原对象可能出问题)
    current_embed = target_msg.embeds[0]
    # 更新报名用户列表
    existing_users = current_embed.fields[0].value
    if existing_users == "暂无报名者":
        new_user_list = f"- {user.mention}"
    else:
        # 这里可以加个判断,避免用户重复报名
        if user.mention not in existing_users:
            new_user_list = f"{existing_users}\n- {user.mention}"
        else:
            # 如果用户已经报名了,可以悄悄移除反应或者提示
            await target_msg.remove_reaction("✅", user)
            return
    
    # 构造更新后的Embed(保留原标题、描述和颜色,只替换报名列表字段)
    updated_embed = discord.Embed(
        title=current_embed.title,
        description=current_embed.description,
        color=current_embed.color
    )
    updated_embed.add_field(name="已报名用户", value=new_user_list, inline=False)
    
    # 执行修改消息的操作
    await target_msg.edit(embed=updated_embed)

几个要注意的细节

  • 权限要求:确保机器人拥有manage_messages权限,否则无法修改已发送的消息。
  • 持久化问题:如果机器人重启,字典里存储的消息对象会丢失。如果需要长期保存报名信息,建议把消息ID、频道ID和报名用户列表存在数据库(比如SQLite、MongoDB)里,重启后重新获取消息对象。
  • 重复报名处理:上面的代码里加了简单的重复判断,你可以根据需求扩展,比如给重复报名的用户发私信提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:50:02