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

Discord bot在Cog中发送Embed报'int'对象无send属性错误

问题描述

我在把Discord机器人的命令拆分到Cog模块时遇到问题:目前Cog可以正常加载,但执行对应命令、机器人尝试向日志频道发送Embed消息时会运行失败。
相关实现代码如下:

from discord.ext import commands 
import datetime
from ruamel.yaml import YAML

yaml = YAML()
with open(r"C:\Users\Jea\Desktop\Yuna-Discord-Bot\config.yml", "r", encoding="utf-8") as file:
    config = yaml.load(file)
    
bot = commands.Bot(command_prefix=config['Prefix'])

bot.debugchannel = config['Debug Channel ID']
bot.embed_color = discord.Color.from_rgb(
config['Embed Settings']['Color']['r'],
config['Embed Settings']['Color']['g'],
config['Embed Settings']['Color']['b'])
bot.footer = config['Embed Settings']['Footer']['Text']
bot.footerimg = config['Embed Settings']['Footer']['Icon URL']

class Testing(commands.Cog):

    def __init__(self, bot):
        self.bot = bot 

    @bot.command(name="ping",
             aliases=["p"],
             help="Check if the bot is online with a simple command")
    async def ping(self, ctx):
        embed = discord.Embed(title=f"Pinged {bot.user}", color=bot.embed_color, timestamp=datetime.datetime.now(datetime.timezone.utc))
        embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar_url)
        embed.set_footer(text=bot.footer, icon_url=bot.footerimg)
        await bot.debugchannel.send(embed=embed)
        print("Sent and embed")
        await ctx.message.add_reaction('✅')
        print("Added a reaction to a message")
        await ctx.send("Pong!")
        print("Sent a message")



def setup(bot):
    bot.add_cog(Testing(bot))

print("Loaded testing cog")

运行时抛出的错误信息:

Traceback (most recent call last):
  File "C:\Users\Jea\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
    ret = await coro(*args, **kwargs)
  File "c:\Users\Jea\Desktop\Yuna-Discord-Bot\cogs\testing.py", line 34, in ping
    await bot.debugchannel.send(embed=embed)
AttributeError: 'int' object has no attribute 'send'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\Jea\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\bot.py", line 939, in invoke
    await ctx.command.invoke(ctx)
  File "C:\Users\Jea\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 863, in invoke
    await injected(*ctx.args, **ctx.kwargs)
  File "C:\Users\Jea\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 94, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'int' object has no attribute 'send'

我已经确认问题出在await bot.debugchannel.send(embed=embed)这行,删掉这行之后命令就能正常运行,但不知道错误触发原因,需要对应的解决方案。

错误原因

报错AttributeError: 'int' object has no attribute 'send'的核心逻辑很明确:
你从配置文件读取到的Debug Channel ID是整数类型的频道ID,不是discord.py封装的频道对象,整数本身不存在send()方法,调用自然会报错。
除此之外你的代码还有3个Cog写法的常见问题:

  • 缺失discord模块导入,代码中用到的discord.Color、discord.Embed都会触发导入错误
  • Cog内部注册命令应该用@commands.command()装饰器,@bot.command()是主文件直接注册命令的写法,放在Cog里会出现注册时序异常
  • Cog内部调用bot实例应该用self.bot,不要直接引用全局bot变量,避免多实例加载时出现引用错误
修复方案
  1. 补上缺失的discord模块导入
  2. 配置项只存储整数类型的频道ID即可,不要尝试在机器人启动前直接获取频道对象——此时机器人还未连接Discord服务器,根本拿不到频道实例
  3. 修正Cog内的命令装饰器,所有bot实例调用统一换成self.bot
  4. 实际发送消息时,先通过频道ID从机器人缓存中获取对应的频道对象,再调用send()方法,可额外加判断避免频道不存在、机器人无权限访问时报错

修复后的完整参考代码:

# 补上缺失的discord导入
import discord
from discord.ext import commands 
import datetime
from ruamel.yaml import YAML

yaml = YAML()
with open(r"C:\Users\Jea\Desktop\Yuna-Discord-Bot\config.yml", "r", encoding="utf-8") as file:
    config = yaml.load(file)
    
bot = commands.Bot(command_prefix=config['Prefix'])

# 仅存储频道ID,不提前获取对象
bot.debug_channel_id = config['Debug Channel ID']
bot.embed_color = discord.Color.from_rgb(
config['Embed Settings']['Color']['r'],
config['Embed Settings']['Color']['g'],
config['Embed Settings']['Color']['b'])
bot.footer = config['Embed Settings']['Footer']['Text']
bot.footerimg = config['Embed Settings']['Footer']['Icon URL']

class Testing(commands.Cog):

    def __init__(self, bot):
        self.bot = bot 

    # Cog内使用commands.command装饰器注册命令
    @commands.command(name="ping",
             aliases=["p"],
             help="Check if the bot is online with a simple command")
    async def ping(self, ctx):
        # 命令触发时机器人已就绪,通过ID获取频道对象
        debug_channel = self.bot.get_channel(self.bot.debug_channel_id)
        if debug_channel:
            embed = discord.Embed(title=f"Pinged {self.bot.user}", color=self.bot.embed_color, timestamp=datetime.datetime.now(datetime.timezone.utc))
            embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar_url)
            embed.set_footer(text=self.bot.footer, icon_url=self.bot.footerimg)
            await debug_channel.send(embed=embed)
            print("Sent an embed")
        await ctx.message.add_reaction('✅')
        print("Added a reaction to a message")
        await ctx.send("Pong!")
        print("Sent a message")

def setup(bot):
    bot.add_cog(Testing(bot))

print("Loaded testing cog")

注意:get_channel依赖机器人本地缓存,仅能在on_ready事件触发后正常返回结果,命令触发时机器人已经完成缓存加载,所以这种写法没问题。如果需要在初始化阶段获取频道,要改用异步方法await self.bot.fetch_channel(频道ID)从接口拉取数据。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:15:30