From 0d2e4403f740e8c158b7c1f795785d63829df722 Mon Sep 17 00:00:00 2001 From: Nix Krystik Date: Wed, 14 Oct 2026 10:23:00 +0800 Subject: [PATCH] (buttons): Implement `close-mod-ticket` button & fix `claim-ticket`. --- src/buttons/claim-ticket.ts | 15 ++++---- src/buttons/close-mod-ticket.ts | 62 +++++++++++++++++++-------------- 2 files changed, 42 insertions(+), 35 deletions(-) diff --git a/src/buttons/claim-ticket.ts b/src/buttons/claim-ticket.ts index 4abb018..7348e99 100644 --- a/src/buttons/claim-ticket.ts +++ b/src/buttons/claim-ticket.ts @@ -7,6 +7,7 @@ class ClaimTicketButton implements Button { async execute(context: Client, interaction: ButtonInteraction, ...args: any[]): Promise { if (!interaction.inGuild()) return; + await interaction.deferReply({ flags: [MessageFlags.Ephemeral] }); try { const channel = await context.channels.fetch(interaction.channelId); @@ -17,7 +18,10 @@ class ClaimTicketButton implements Button { const settings = await Database.getOrCreateSettings(interaction.guildId); if (!settings.private_help_role_id) throw new Error("\`private_help_role_id\` hasn't been configured. Please report this error to staff."); - if (!(interaction.member.roles as string[]).includes(settings.private_help_role_id)) throw new Error("You don't have permission to claim tickets."); + + const guild = await context.guilds.fetch(interaction.guildId); + const member = await guild.members.fetch(interaction.user.id); + if (!member.roles.cache.has(settings.private_help_role_id)) throw new Error("You don't have permission to claim tickets."); const closeButton = new ButtonBuilder() .setCustomId('close-ticket') @@ -36,14 +40,9 @@ class ClaimTicketButton implements Button { components: [row] }); - await interaction.reply({ content: `Ticket claimed by ${interaction.user}.` }); + await interaction.editReply({ content: `Ticket claimed by ${interaction.user}.` }); } catch (error: Error | any) { - await interaction.reply({ - content: error.message, - flags: MessageFlags.Ephemeral, - }).catch(() => {}); - - return; + await interaction.editReply({ content: error.message }).catch(() => {}); } } } diff --git a/src/buttons/close-mod-ticket.ts b/src/buttons/close-mod-ticket.ts index aa42cda..78b598c 100644 --- a/src/buttons/close-mod-ticket.ts +++ b/src/buttons/close-mod-ticket.ts @@ -1,31 +1,39 @@ -import { ButtonInteraction, Client, MessageFlags, ChannelType, PermissionFlagsBits } from 'discord.js'; +import { ButtonInteraction, Client, MessageFlags, ChannelType } from 'discord.js'; +import { Button } from '../types'; -export default { - name: 'close-mod-ticket', - handler: async function (client: Client, interaction: ButtonInteraction) { - await interaction.deferReply({ flags: [MessageFlags.Ephemeral] }); - const channel = await interaction.channel?.fetch(); - const guild = await interaction.guild?.fetch(); - const member = await guild?.members.fetch(interaction.user.id); +class CloseModTicketButton implements Button { + id = 'close-mod-ticket'; - if (!channel || !channel.isThread() || !channel.isSendable() || channel.type != ChannelType.PrivateThread || !member) - return interaction.editReply({ content: 'Oops. Something went wrong. Please report this to a staff member.' }); + async execute(context: Client, interaction: ButtonInteraction, ...args: any[]): Promise { + if (!interaction.inGuild()) return; + await interaction.deferReply({ flags: MessageFlags.Ephemeral }); - if (!member.permissions.has(PermissionFlagsBits.KickMembers)) - return interaction.editReply({ content: 'Only staff members may close mod tickets.' }); - - await interaction.message.edit({ - content: interaction.message.content, - components: [] - }); - - await channel.send('This ticket has been closed by staff.'); - - await interaction.editReply({ content: 'Ticket closed.' }); - - channel.edit({ - archived: true, - locked: true - }); + try { + const channel = await context.channels.fetch(interaction.channelId); + + if (!channel) throw new Error("The interaction channel couldn't be fetched."); + if (!channel.isThread() || channel.type != ChannelType.PrivateThread) throw new Error('This interaction was not run in a ticket thread.'); + if (!channel.isSendable()) throw new Error("I don't have permission to send messages in this channel."); + + if (!interaction.memberPermissions.has('KickMembers')) throw new Error("You don't have permission to close this ticket."); + + await interaction.message.edit({ + content: interaction.message.content, + components: [] + }); + + await channel.send('This ticket has been closed by staff.'); + + await interaction.editReply({ content: 'Ticket closed.' }); + + await channel.edit({ + archived: true, + locked: true + }); + } catch (error: Error | any) { + await interaction.editReply({ content: error.message }).catch(() => {}); + } } -}; \ No newline at end of file +} + +export default new CloseModTicketButton(); \ No newline at end of file