(interaction, config, client)
| 94 | category: "ticket", |
| 95 | |
| 96 | async execute(interaction, config, client) { |
| 97 | try { |
| 98 | |
| 99 | const deferred = await InteractionHelper.safeDefer(interaction, { flags: MessageFlags.Ephemeral }); |
| 100 | if (!deferred) { |
| 101 | return; |
| 102 | } |
| 103 | |
| 104 | if ( |
| 105 | !interaction.member.permissions.has( |
| 106 | PermissionFlagsBits.ManageChannels, |
| 107 | ) |
| 108 | ) { |
| 109 | logger.warn('Ticket command permission denied', { |
| 110 | userId: interaction.user.id, |
| 111 | guildId: interaction.guildId, |
| 112 | commandName: 'ticket' |
| 113 | }); |
| 114 | return await replyUserError(interaction, { type: ErrorTypes.PERMISSION, message: 'You need the `Manage Channels` permission for this action.' }); |
| 115 | } |
| 116 | |
| 117 | const subcommand = interaction.options.getSubcommand(); |
| 118 | |
| 119 | if (subcommand === "dashboard") { |
| 120 | return ticketConfig.execute(interaction, config, client); |
| 121 | } |
| 122 | |
| 123 | if (subcommand === "setup") { |
| 124 | const existingConfig = await getGuildConfig(client, interaction.guildId); |
| 125 | if (existingConfig?.ticketPanelChannelId) { |
| 126 | return await replyUserError(interaction, { type: ErrorTypes.UNKNOWN, message: 'This server already has a ticket system set up (panel in <#${existingConfig.ticketPanelChannelId}>).\n\nOnly one ticket system is supported per server. Use \\`/ticket dashboard\\` to edit or update the existing setup, or select **Delete System** from the dashboard to remove it and start fresh.' }); |
| 127 | } |
| 128 | |
| 129 | const panelChannel = |
| 130 | interaction.options.getChannel("panel_channel"); |
| 131 | const categoryChannel = interaction.options.getChannel("category"); |
| 132 | const closedCategoryChannel = interaction.options.getChannel("closed_category"); |
| 133 | const staffRole = interaction.options.getRole("staff_role"); |
| 134 | const panelMessage = interaction.options.getString("panel_message") || "Click the button below to create a support ticket."; |
| 135 | const buttonLabel = |
| 136 | interaction.options.getString("button_label") || |
| 137 | "Create Ticket"; |
| 138 | const maxTicketsPerUser = interaction.options.getInteger("max_tickets_per_user") || 3; |
| 139 | const dmOnClose = interaction.options.getBoolean("dm_on_close") !== false; |
| 140 | |
| 141 | const setupEmbed = createEmbed({ |
| 142 | title: "Support Tickets", |
| 143 | description: panelMessage, |
| 144 | color: getColor('info') |
| 145 | }); |
| 146 | |
| 147 | const ticketButton = new ActionRowBuilder().addComponents( |
| 148 | new ButtonBuilder() |
| 149 | .setCustomId("create_ticket") |
| 150 | .setLabel(buttonLabel) |
| 151 | .setStyle(ButtonStyle.Primary) |
| 152 | .setEmoji("📩"), |
| 153 | ); |
nothing calls this directly
no test coverage detected