import { kitten } from "@/client"; import { option } from "@purrkit/router"; import { Result } from "@sapphire/result"; import * as actions from "./actions"; import { errorMessage, getTextChannel, PublicError } from "@/lib"; import { getGuildByDiscordId } from "@stealth-developers/db"; import { newTicketButton } from "@/components"; import { ButtonBuilder, ButtonStyle, ContainerBuilder, TextDisplayBuilder, ActionRowBuilder, } from "discord.js"; const ticketCommand = kitten.command("ticket", { description: "Ticket-related commands", }); ticketCommand.subcommand("new", { description: "Open a new ticket.", async run(interaction) { if (!interaction.guild) return errorMessage(interaction, "You must run this command in a guild"); const func = actions.createTicket(interaction.member ?? interaction.user, interaction.guild); const ticketResult = await Result.fromAsync(async () => func); if (ticketResult.isErr()) { const error = ticketResult.unwrapErr(); if (error instanceof PublicError) { return errorMessage(interaction, error.message); } else { console.error(error); return errorMessage(interaction, "An unexpected error occurred while creating the ticket."); } } const { channelId } = ticketResult.unwrap(); return interaction.reply({ content: `Opened ticket <#${channelId}>.`, flags: ["Ephemeral"], }); }, }); ticketCommand.subcommand("for", { description: "Open a new ticket on behalf of someone else", options: { user: option.user("The user to open the ticket for", { required: true }), reason: option.string("The reason for opening the ticket"), }, async run(interaction, args) { if (!interaction.guild) return errorMessage(interaction, "You must run this command in a guild"); const func = actions.createTicket(interaction.member ?? interaction.user, interaction.guild, { for: args.user, reason: args.reason, }); const ticketResult = await Result.fromAsync(async () => func); if (ticketResult.isErr()) { const error = ticketResult.unwrapErr(); if (error instanceof PublicError) { return errorMessage(interaction, error.message); } else { console.error(error); return errorMessage(interaction, "An unexpected error occurred while creating the ticket."); } } const { channelId } = ticketResult.unwrap(); return interaction.reply({ content: `Opened ticket <#${channelId}>.`, flags: ["Ephemeral"], }); }, }); ticketCommand.group( "manage", { description: "Manage ticket settings", }, (group) => { // channels & categories group.subcommand("transcript-channel", { description: "Set the channel where transcripts will be sent", options: { channel: option.channel("The channel to send transcripts to", { required: true }), }, async run(interaction) { await actions.manageConfig(interaction); }, }); group.subcommand("entrypoint-channel", { description: "Set the channel where the ticket prompt will be sent", options: { channel: option.channel("The channel to send the ticket prompt to", { required: true }), }, async run(interaction) { await actions.manageConfig(interaction); }, }); group.subcommand("category", { description: "Sets the category for new tickets", options: { category: option.channel("The category to create new tickets in", { required: true }), }, async run(interaction) { await actions.manageConfig(interaction); }, }); // text group.subcommand("prompt", { description: "Set the message sent in the entry point channel", async run(interaction) { await actions.manageConfig(interaction); }, }); group.subcommand("send-prompt", { description: "Send the prompt to the entry point channel", async run(interaction) { if (!interaction.guild) return errorMessage(interaction, "You must run this command in a guild"); const guild = await getGuildByDiscordId(interaction.guild.id); if (!guild) return errorMessage(interaction, "Failed to send prompt: Guild not found."); const commandString = (sub: string) => ``; const channelId = guild.ticketPromptChannel; const promptText = guild.ticketPrompt; if (!channelId) return errorMessage( interaction, `Prompt chnanel not configured. Use ${commandString("entrypoint-channel")} to set it up.`, ); if (!promptText) return errorMessage( interaction, `Ticket prompt not configured. Use ${commandString("prompt")} to set it up.`, ); const channelRes = await Result.fromAsync(() => getTextChannel(channelId)); if (channelRes.isErr()) { const err = channelRes.unwrapErr(); const errorMessageText = err instanceof Error ? err.message : "Unknown error"; return errorMessage(interaction, `Failed to fetch prompt channel: ${errorMessageText}`); } const channel = channelRes.unwrap(); if (!channel.isSendable()) { return errorMessage( interaction, "I don't have permission to send messages in the prompt channel.", ); } const button = new ButtonBuilder() .setLabel("Open a Ticket") .setStyle(ButtonStyle.Success) .setCustomId(newTicketButton.id()); const container = new ContainerBuilder() .addTextDisplayComponents(new TextDisplayBuilder().setContent(promptText)) .addActionRowComponents(new ActionRowBuilder().addComponents(button)); await channel.send({ flags: ["IsComponentsV2"], components: [container] }); return interaction.reply({ content: "Prompt sent!", flags: ["Ephemeral"], }); }, }); group.subcommand("greeting", { description: "Set the message sent in new tickets", async run(interaction) { await actions.manageConfig(interaction); }, }); }, ); export default ticketCommand;