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

Discord机器人/level命令报错:'NoneType' object has no attribute 'author'

Discord机器人等级系统/level命令报错解决

问题描述

开发Discord机器人等级系统时,实现/level命令用于显示指定用户等级;未指定用户时默认显示命令发起者等级。编写代码if member is None: member = interaction.message.author时触发报错:'Nonetype' object has no attribute 'author'。

尝试过用ctx替代interaction,测试ctx.author、ctx.message.author,也试过interaction.author,修改参数名为user,但问题未解决。

命令代码

# Level Command | !level {member} | Shows you your current level or the level of another member.
@bot.tree.command(name="level", description="Shows you your current level or the level of another member.")
@app_commands.describe(member="The member who's level you want to see.")
async def level(interaction: discord.Interaction, member: discord.Member = None):
    if member is None:
        member = interaction.message.author
    async with bot.db.cursor() as cursor:
        await cursor.execute("SELECT level FROM levels WHERE user = ? AND guild = ?", (member.id, interaction.guild.id,))
        level = await cursor.fetchone()
        await cursor.execute("SELECT xp FROM levels WHERE user = ? AND guild = ?", (member.id, interaction.guild.id,))
        xp = await cursor.fetchone()
    
    if not xp or not level:
        await cursor.execute("INSERT INTO levels (levels, xp, user, guild) VALUES (?, ?, ?, ?)", (0, 0, member.id, interaction.guild.id,))

    try:
        xp = xp[0]
        level = level [0]
    except TypeError:
        xp = 0
        level = 0
    
    user_data = {
        "xp": xp,
        "level": level,
        "next_level_up": 100,
        "percentage": xp
    }

    background = Editor(Canvas((900, 300), color="#191919"))
    profile_picture = await load_image_async(str(member.avatar.url))
    profile = Editor(profile_picture).resize((150, 150)).circle_image()

    poppins = Font.poppins(size=40)
    poppins_small = Font.poppins(size=40)

    card_right_shape = [(600, 0), (750, 300), (900, 300), (900, 0)]

    background.polygon(card_right_shape, color="#FFFFFF")
    background.paste(profile, (30, 30))

    background.rectangle((30, 220), width=650, height=40, color="#FFFFFF")
    background.bar((30, 220), max_width=650, height=40, percentage=user_data["percentage"], color="#FF0000", radius=20)
    background.text((200, 40), user_data["name"], font=poppins, color="#FFFFFF")

    background.rectangle((200, 100), width=350, height=2, fill="#FFFFFF")
    background.text((200, 130), f"Level - {user_data['level']} | XP - {user_data['xp']}/{user_data['next_level_up']}", font=poppins_small, color="#FFFFFF")

    file = discord.File(fp=background.image_bytes, filename="levelcard.png")
    await interaction.response.send_message(file=file)

报错信息

Traceback (most recent call last):
    bot.py line 83, in level
    member = interaction.message.author
AttributeError: 'NoneType' object has no attribute 'author'

解决方案

核心问题

使用的是Discord.py的斜杠命令(slash command),这类命令的interaction对象不存在message属性(interaction.message为None),因为斜杠命令并非基于消息触发,和传统前缀命令的逻辑不同。

具体修复步骤

  1. 修正发起者获取方式
    将member = interaction.message.author替换为member = interaction.user,斜杠命令中interaction.user直接指向命令发起者,且在服务器内使用时为discord.Member类型。

  2. 修复数据库字段名不匹配
    插入语句中字段名levels与查询的level不一致,修改为:

await cursor.execute("INSERT INTO levels (level, xp, user, guild) VALUES (?, ?, ?, ?)", (0, 0, member.id, interaction.guild.id,))
  1. 补充user_data缺失的name字段
    代码中调用user_data["name"]但未定义,添加该字段:
user_data = {
    "name": member.display_name,
    "xp": xp,
    "level": level,
    "next_level_up": 100,
    "percentage": (xp / 100) * 100 if 100 > 0 else 0  # 修正百分比计算逻辑
}
  1. 添加数据库提交操作
    执行INSERT后未提交,数据不会写入数据库,添加提交语句:
if not xp or not level:
    await cursor.execute("INSERT INTO levels (level, xp, user, guild) VALUES (?, ?, ?, ?)", (0, 0, member.id, interaction.guild.id,))
    await bot.db.commit()

修复后核心代码片段

@bot.tree.command(name="level", description="Shows you your current level or the level of another member.")
@app_commands.describe(member="The member who's level you want to see.")
async def level(interaction: discord.Interaction, member: discord.Member = None):
    if member is None:
        member = interaction.user  # 修复发起者获取
    async with bot.db.cursor() as cursor:
        await cursor.execute("SELECT level FROM levels WHERE user = ? AND guild = ?", (member.id, interaction.guild.id,))
        level = await cursor.fetchone()
        await cursor.execute("SELECT xp FROM levels WHERE user = ? AND guild = ?", (member.id, interaction.guild.id,))
        xp = await cursor.fetchone()
    
    if not xp or not level:
        await cursor.execute("INSERT INTO levels (level, xp, user, guild) VALUES (?, ?, ?, ?)", (0, 0, member.id, interaction.guild.id,))
        await bot.db.commit()  # 提交数据库修改

    try:
        xp = xp[0]
        level = level[0]
    except TypeError:
        xp = 0
        level = 0
    
    user_data = {
        "name": member.display_name,  # 补充name字段
        "xp": xp,
        "level": level,
        "next_level_up": 100,
        "percentage": (xp / 100) * 100 if 100 > 0 else 0  # 修正百分比
    }

    # 后续图片编辑与发送代码保持不变

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 23:20:39