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

修复Discord机器人斜杠命令的AttributeError: 'NoneType'无author属性问题

Discord斜杠命令AttributeError问题修复

错误原因

斜杠命令的discord.Interaction对象不存在message属性——斜杠命令通过Discord交互接口触发,而非消息触发,因此interaction.message的值为None,调用interaction.message.author会直接抛出AttributeError: 'NoneType' object has no attribute 'author'。

修复步骤

  1. 替换用户获取方式:
    用interaction.user替代interaction.message.author,这是斜杠命令中获取触发用户的正确方式。
  2. 优化服务器角色获取:
    无需遍历所有服务器,直接从当前交互的服务器中获取角色:guild = interaction.guild,避免无效遍历。
  3. 修正权限判断逻辑:
    原代码中判断无权限时使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 07:01:08