修复Discord机器人斜杠命令的AttributeError: 'NoneType'无author属性问题
Discord斜杠命令AttributeError问题修复
错误原因
斜杠命令的discord.Interaction对象不存在message属性——斜杠命令通过Discord交互接口触发,而非消息触发,因此interaction.message的值为None,调用interaction.message.author会直接抛出AttributeError: 'NoneType' object has no attribute 'author'。
修复步骤
- 替换用户获取方式:
用interaction.user替代interaction.message.author,这是斜杠命令中获取触发用户的正确方式。 - 优化服务器角色获取:
无需遍历所有服务器,直接从当前交互的服务器中获取角色:guild = interaction.guild,避免无效遍历。 - 修正权限判断逻辑:
原代码中判断无权限时使用or逻辑错误,应改为and,仅当用户同时没有所有指定角色时,才触发无权限提示。
修改后的完整代码
import discord from discord.ext import commands import json from apscheduler.schedulers.background import BackgroundScheduler intents = discord.Intents.all() bot = commands.Bot(command_prefix='/', intents=intents) @bot.event async def on_ready(): synced = await bot.tree.sync() print(f'Synced {len(synced)} command(s)') @bot.tree.command(name='help', description='Displays a list of all available commands.') async def help(interaction: discord.Interaction): help_embed = discord.Embed(title='Commands', description='``!help``\n**Displays this help message.**\n\n``!taskdone``\n **Adds +1 to your amount of completed tasks.**\n\n``!viewtasks``\n**Displays a list of every developer and their number of completed tasks.**', color=0x2f3136) await interaction.response.send_message(embed=help_embed) @bot.tree.command(name='ping', description='Shows latency.') async def ping(interaction: discord.Interaction): await interaction.response.send_message(f'**Latency:** {bot.latency} Milliseconds') @bot.tree.command(name='taskdone', description='Adds +1 to your amount of completed tasks.') async def taskdone(interaction: discord.Interaction): authorID = str(interaction.user.id) guild = interaction.guild if not guild: await interaction.response.send_message('此命令仅能在服务器内使用!') return juniorDevs = discord.utils.get(guild.roles, name='Junior Developers') seniorDevs = discord.utils.get(guild.roles, name='Senior Developers') leadDevs = discord.utils.get(guild.roles, name='Lead Developers') projectManagers = discord.utils.get(guild.roles, name="Project Managers") required_roles = [juniorDevs, seniorDevs, leadDevs, projectManagers] has_permission = any(role in interaction.user.roles for role in required_roles if role) if has_permission: with open('database.json', 'r') as f: data = json.load(f) data[authorID] = data.get(authorID, 0) + 1 with open('database.json', 'w') as f: json.dump(data, f, indent=2) await interaction.response.send_message('**Task amount updated!** :white_check_mark:') else: await interaction.response.send_message('**You do not have permission to run this command!** :x:') @bot.tree.command(name='viewtasks', description='Displays a list of every developer and their number of completed tasks.') async def viewtasks(interaction: discord.Interaction): guild = interaction.guild if not guild: await interaction.response.send_message('此命令仅能在服务器内使用!') return juniorDevs = discord.utils.get(guild.roles, name='Junior Developers') seniorDevs = discord.utils.get(guild.roles, name='Senior Developers') leadDevs = discord.utils.get(guild.roles, name='Lead Developers') projectManagers = discord.utils.get(guild.roles, name="Project Managers") required_roles = [juniorDevs, seniorDevs, leadDevs, projectManagers] has_permission = any(role in interaction.user.roles for role in required_roles if role) with open('database.json', 'r') as database: data = json.load(database) if has_permission: message_text = "" for user_id, value in sorted(data.items(), key=lambda x: x[1], reverse=True): message_text += f"<@{user_id}>**: {value}**\n" task_embed = discord.Embed(title='Tasks Completed This Week', description=message_text, color=0x2f3136) await interaction.response.send_message(embed=task_embed) else: await interaction.response.send_message('**You do not have permission to run this command!** :x:') def reset_values(): with open('database.json', 'r') as f: data = json.load(f) for key in data.keys(): data[key] = 0 with open('database.json', 'w') as f: json.dump(data, f, indent=2) scheduler = BackgroundScheduler() scheduler.add_job(reset_values, 'cron', day_of_week='1', hour=0, minute=0) scheduler.start() @bot.event async def on_message(message): args = str(message.content).lower().split(' ') if args[0] == 'bruh': await message.channel.send('<:bruh_stone:1059119664543825950>') elif args[0] == "i'm" and " ".join(args[1:]) == "horny": await message.channel.send('https://tenor.com/view/vorzek-vorzneck-oglg-og-lol-gang-gif-24901093') elif args[0] == "im" and " ".join(args[1:]) == "horny": await message.channel.send('https://tenor.com/view/vorzek-vorzneck-oglg-og-lol-gang-gif-24901093') await bot.process_commands(message) bot.run('your_token_here')
额外优化说明
- 用
data.get(authorID, 0) + 1简化原有的if-else判断,代码更简洁高效。 - 添加服务器判断,避免在DM中执行命令报错。
- 在
on_message末尾添加await bot.process_commands(message),确保前缀命令与斜杠命令都能正常触发(原代码缺失此行,可能导致前缀命令失效)。
内容的提问来源于stack exchange,提问作者Q99
相关产品推荐
相关产品推荐

