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

discord.py中反应命令编辑嵌入消息报NameError问题

问题:Discord机器人投票平均值更新嵌入消息页脚时触发NameError

我正在开发一款Discord机器人,希望实现机器人计算投票反应的平均值并更新至嵌入消息的页脚功能。目前其他功能已正常运行,但无法完成消息编辑操作,当触发反应时会报错:NameError: name 'embed' is not defined。简化后的代码如下:

#imports

intents = discord.Intents.default()
intents.message_content = True
intents.members = True
intents.dm_messages = True

#bot client
client = discord.Client(intents=intents)

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

divider=0
sumofnumbers=0
average=0

@client.event
async def on_message(message):
      if message.content.startswith('!viikonlista'):
        embed=discord.Embed(color=0x76b52f)
        embed.add_field(name="Vote now!", value="Votes appear on the footer")
        embed.set_footer(text=average)
        msg=await message.channel.send("Here's the embed!",embed=embed)
        await msg.add_reaction("1️⃣")
        await msg.add_reaction("2️⃣")
        await msg.add_reaction("3️⃣")
        await msg.add_reaction("4️⃣")
        await msg.add_reaction("5️⃣")


@client.event
async def on_reaction_add(reaction, user):
    global divider
    global sumofnumbers
    global average
    if reaction.emoji == "1️⃣" and not user.bot:
      divider+=1
      sumofnumbers+=1
      average=(sumofnumbers)/divider
      embed.set_footer(text=average)
      msg.edit(embed=embed)
      print(average)
#same for the other numbers

#same but minus

client.run("token")

解决方案

问题根源

embed和msg是on_message事件内的局部变量,on_reaction_add无法直接访问;同时全局的divider、sumofnumbers、average没有和具体投票消息绑定,多用户发起投票时会导致数据混乱。

修复步骤

  1. 使用全局字典存储每一条投票消息的独立数据,包括消息ID、嵌入对象、投票总数、数值总和、平均值。
  2. 创建投票时将数据存入字典,以消息ID为键。
  3. 触发反应时,通过消息ID从字典中获取对应数据,更新后重新编辑消息。
  4. 补充取消反应的逻辑,同步更新数据和嵌入内容。

修改后的完整代码

import discord

intents = discord.Intents.default()
intents.message_content = True
intents.members = True
intents.dm_messages = True

client = discord.Client(intents=intents)

# 存储投票数据:键为消息ID,值为包含嵌入、投票总数、总和、平均值的字典
vote_data = {}

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

@client.event
async def on_message(message):
    if message.content.startswith('!viikonlista'):
        embed = discord.Embed(color=0x76b52f)
        embed.add_field(name="Vote now!", value="Votes appear on the footer")
        embed.set_footer(text="当前平均值: 0.0")
        msg = await message.channel.send("Here's the embed!", embed=embed)
        # 初始化这条消息的投票数据
        vote_data[msg.id] = {
            "embed": embed,
            "divider": 0,
            "sumofnumbers": 0,
            "average": 0.0
        }
        await msg.add_reaction("1️⃣")
        await msg.add_reaction("2️⃣")
        await msg.add_reaction("3️⃣")
        await msg.add_reaction("4️⃣")
        await msg.add_reaction("5️⃣")

# 反应对应的数值映射
emoji_to_value = {
    "1️⃣": 1,
    "2️⃣": 2,
    "3️⃣": 3,
    "4️⃣": 4,
    "5️⃣": 5
}

@client.event
async def on_reaction_add(reaction, user):
    if user.bot:
        return
    # 检查当前消息是否在投票数据中
    msg_id = reaction.message.id
    if msg_id not in vote_data:
        return
    emoji = reaction.emoji
    if emoji not in emoji_to_value:
        return
    
    data = vote_data[msg_id]
    # 更新数据
    data["divider"] += 1
    data["sumofnumbers"] += emoji_to_value[emoji]
    data["average"] = data["sumofnumbers"] / data["divider"]
    # 更新嵌入页脚
    data["embed"].set_footer(text=f"当前平均值: {data['average']:.2f}")
    # 编辑消息
    await reaction.message.edit(embed=data["embed"])
    print(f"平均值更新为: {data['average']:.2f}")

@client.event
async def on_reaction_remove(reaction, user):
    if user.bot:
        return
    msg_id = reaction.message.id
    if msg_id not in vote_data:
        return
    emoji = reaction.emoji
    if emoji not in emoji_to_value:
        return
    
    data = vote_data[msg_id]
    # 防止投票数为0时除以0
    if data["divider"] <= 0:
        return
    # 更新数据
    data["divider"] -= 1
    data["sumofnumbers"] -= emoji_to_value[emoji]
    # 计算平均值,避免除以0
    data["average"] = data["sumofnumbers"] / data["divider"] if data["divider"] > 0 else 0.0
    # 更新嵌入页脚
    data["embed"].set_footer(text=f"当前平均值: {data['average']:.2f}")
    # 编辑消息
    await reaction.message.edit(embed=data["embed"])
    print(f"平均值更新为: {data['average']:.2f}")

client.run("你的Bot令牌")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 03:15:46