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),因为斜杠命令并非基于消息触发,和传统前缀命令的逻辑不同。
具体修复步骤
修正发起者获取方式
将member = interaction.message.author替换为member = interaction.user,斜杠命令中interaction.user直接指向命令发起者,且在服务器内使用时为discord.Member类型。修复数据库字段名不匹配
插入语句中字段名levels与查询的level不一致,修改为:
await cursor.execute("INSERT INTO levels (level, xp, user, guild) VALUES (?, ?, ?, ?)", (0, 0, member.id, interaction.guild.id,))
- 补充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 # 修正百分比计算逻辑 }
- 添加数据库提交操作
执行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
相关产品推荐
相关产品推荐

