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

Discord工单机器人无法创建频道/分类,点击按钮触发AttributeError

Discord工单机器人创建频道失败:AttributeError 问题解决

错误现象

点击「Create Ticket」按钮时无法创建频道或分类,触发如下错误:

[2023-08-12 20:05:06] [ERROR   ] discord.ui.view: Ignoring exception in view     <TicketPanelView timeout=None children=1> for item <Button style=<ButtonStyle.secondary: 2>     url=None disabled=False label='Create Ticket' emoji=<PartialEmoji animated=False name='✉️'     id=None> row=None>
Traceback (most recent call last):
  File     "C:\Users\user\AppData\Local\Programs\Python\Python311\Lib\site-packages\discord\ui\view.py", line 427, in _scheduled_task
        await item.callback(interaction)
      File "C:\Users\user\Desktop\ticket bot\main2.py", line 15,     in create_ticket
        if interaction.user.id in open_tickets:
           ^^^^^^^^^^^^^^^^
AttributeError: 'Button' object has no attribute 'user'

问题分析

  1. 按钮回调方法位置错误:@discord.ui.button装饰的create_ticket方法必须定义在TicketPanelView类内部,否则Discord.py无法正确绑定视图上下文,导致回调参数顺序错乱(把interaction传入了button参数位置)。
  2. 变量未初始化:open_tickets字典未提前定义,后续使用会触发NameError。
  3. 缩进错误:创建分类、频道的代码块缩进在return语句之后,永远不会被执行。

修正后的完整代码

import discord
from discord.ext import commands

intents = discord.Intents.default()
intents.message_content = True
intents.members = True  # 新增:获取成员权限所需的意图

bot = commands.Bot(command_prefix='!', intents=intents)

# 初始化工单跟踪字典
open_tickets = {}

class TicketPanelView(discord.ui.View):
    def __init__(self):
        super().__init__(timeout=None)

    # 将按钮回调方法移至类内部
    @discord.ui.button(label='Create Ticket', emoji='✉️', style=discord.ButtonStyle.secondary)
    async def create_ticket(self, button: discord.ui.Button, interaction: discord.Interaction):
        if interaction.user.id in open_tickets:
            await interaction.response.send_message("你已经有一个未关闭的工单了。", ephemeral=True)
            return

        # 修正缩进:确保这部分逻辑能正常执行
        category = discord.utils.get(interaction.guild.categories, name='Tickets')
        if not category:
            category = await interaction.guild.create_category('Tickets')

        ticket_channel = await category.create_text_channel(f'ticket-{interaction.user.display_name}')
        # 设置权限:隐藏工单频道对普通用户的可见性
        await ticket_channel.set_permissions(interaction.guild.default_role, read_messages=False)
        await ticket_channel.set_permissions(interaction.user, read_messages=True, send_messages=True)

        await ticket_channel.send(f'欢迎 {interaction.user.mention}!你的工单已创建。')
        await interaction.response.send_message('正在创建新工单...', ephemeral=True)
    
        open_tickets[interaction.user.id] = ticket_channel.id

@bot.command()
async def panel(ctx):
    embed = discord.Embed(
        title='工单系统',
        description='点击下方按钮创建你的专属工单', 
        color=discord.Color.blue()
    )
    view = TicketPanelView()
    await ctx.send(embed=embed, view=view)

# 替换为你的机器人令牌
bot.run('YOUR_BOT_TOKEN')

关键修改说明

  • 将create_ticket方法移至TicketPanelView类内部,确保装饰器正确绑定视图上下文。
  • 新增open_tickets = {}初始化工单跟踪字典,避免未定义变量错误。
  • 修正代码缩进,让创建分类和频道的逻辑不再被return语句阻断。
  • 新增intents.members = True,确保机器人能正确处理成员权限设置。
  • 补充@everyone角色的权限移除,增强工单频道的私密性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 11:25:11