blob: 8f9f688e6e3bb07bbb3cb7ba673708c2d23f82ce [file] [log] [blame]
PineaFan0d06edc2023-01-17 22:10:31 +00001import { LoadingEmbed } from "../../utils/defaults.js";
pineafan6702cef2022-06-13 17:52:37 +01002import getEmojiByName from "../../utils/getEmojiByName.js";
pineafan4edb7762022-06-26 19:21:04 +01003import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
pineafan6702cef2022-06-13 17:52:37 +01004import confirmationMessage from "../../utils/confirmationMessage.js";
Skyler Grey75ea9172022-08-06 10:22:23 +01005import Discord, {
6 CommandInteraction,
7 GuildChannel,
8 Message,
TheCodedProf21c08592022-09-13 14:14:43 -04009 ActionRowBuilder,
TheCodedProf21c08592022-09-13 14:14:43 -040010 ButtonBuilder,
Skyler Grey75ea9172022-08-06 10:22:23 +010011 MessageComponentInteraction,
TheCodedProfa16d1672023-01-18 18:58:34 -050012 StringSelectMenuBuilder,
Skyler Grey75ea9172022-08-06 10:22:23 +010013 Role,
TheCodedProf59772f82023-01-18 22:17:16 -050014 ButtonStyle,
15 TextInputBuilder,
16 ButtonComponent,
TheCodedProf59772f82023-01-18 22:17:16 -050017 ModalSubmitInteraction,
18 APIMessageComponentEmoji
Skyler Grey75ea9172022-08-06 10:22:23 +010019} from "discord.js";
TheCodedProf59772f82023-01-18 22:17:16 -050020import { SlashCommandSubcommandBuilder, StringSelectMenuOptionBuilder } from "@discordjs/builders";
Skyler Greyc634e2b2022-08-06 17:50:48 +010021import { ChannelType } from "discord-api-types/v9";
pineafan6702cef2022-06-13 17:52:37 +010022import client from "../../utils/client.js";
Skyler Grey11236ba2022-08-08 21:13:33 +010023import { toHexInteger, toHexArray, tickets as ticketTypes } from "../../utils/calculate.js";
pineafan63fc5e22022-08-04 22:04:10 +010024import { capitalize } from "../../utils/generateKeyValueList.js";
pineafan6702cef2022-06-13 17:52:37 +010025import { modalInteractionCollector } from "../../utils/dualCollector.js";
pineafan3a02ea32022-08-11 21:35:04 +010026import type { GuildConfig } from "../../utils/database.js";
pineafan4f164f32022-02-26 22:07:12 +000027
Skyler Grey75ea9172022-08-06 10:22:23 +010028const command = (builder: SlashCommandSubcommandBuilder) =>
29 builder
30 .setName("tickets")
Skyler Grey11236ba2022-08-08 21:13:33 +010031 .setDescription("Shows settings for tickets | Use no arguments to manage custom types")
Skyler Grey75ea9172022-08-06 10:22:23 +010032 .addStringOption((option) =>
33 option
34 .setName("enabled")
35 .setDescription("If users should be able to create tickets")
36 .setRequired(false)
PineaFan64486c42022-12-28 09:21:04 +000037 .addChoices(
38 {name: "Yes", value: "yes"},
39 {name: "No",value: "no"}
40 )
Skyler Grey75ea9172022-08-06 10:22:23 +010041 )
42 .addChannelOption((option) =>
43 option
44 .setName("category")
45 .setDescription("The category where tickets are created")
PineaFan64486c42022-12-28 09:21:04 +000046 .addChannelTypes(ChannelType.GuildCategory)
Skyler Grey75ea9172022-08-06 10:22:23 +010047 .setRequired(false)
48 )
49 .addNumberOption((option) =>
50 option
51 .setName("maxticketsperuser")
Skyler Grey11236ba2022-08-08 21:13:33 +010052 .setDescription("The maximum amount of tickets a user can create | Default: 5")
Skyler Grey75ea9172022-08-06 10:22:23 +010053 .setRequired(false)
54 .setMinValue(1)
55 )
56 .addRoleOption((option) =>
57 option
58 .setName("supportrole")
59 .setDescription(
60 "This role will have view access to all tickets and will be pinged when a ticket is created"
61 )
62 .setRequired(false)
63 );
pineafan4f164f32022-02-26 22:07:12 +000064
pineafan3a02ea32022-08-11 21:35:04 +010065const callback = async (interaction: CommandInteraction): Promise<unknown> => {
PineaFana00db1b2023-01-02 15:32:54 +000066 if (!interaction.guild) return;
Skyler Grey75ea9172022-08-06 10:22:23 +010067 let m = (await interaction.reply({
68 embeds: LoadingEmbed,
69 ephemeral: true,
70 fetchReply: true
71 })) as Message;
pineafan63fc5e22022-08-04 22:04:10 +010072 const options = {
TheCodedProfa16d1672023-01-18 18:58:34 -050073 enabled: (interaction.options.get("enabled")?.value as string).startsWith("yes") as boolean | null,
PineaFan638eb132023-01-19 10:41:22 +000074 category: interaction.options.get("category")?.channel as Discord.CategoryChannel | null,
75 maxtickets: interaction.options.get("maxticketsperuser")?.value as number | null,
76 supportping: interaction.options.get("supportrole")?.role as Role | null
pineafan63fc5e22022-08-04 22:04:10 +010077 };
Skyler Grey11236ba2022-08-08 21:13:33 +010078 if (options.enabled !== null || options.category || options.maxtickets || options.supportping) {
pineafan6702cef2022-06-13 17:52:37 +010079 if (options.category) {
pineafan3a02ea32022-08-11 21:35:04 +010080 let channel: GuildChannel | null;
pineafan6702cef2022-06-13 17:52:37 +010081 try {
TheCodedProf59772f82023-01-18 22:17:16 -050082 channel = await interaction.guild.channels.fetch(options.category.id) as GuildChannel;
pineafan6702cef2022-06-13 17:52:37 +010083 } catch {
84 return await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +010085 embeds: [
86 new EmojiEmbed()
87 .setEmoji("CHANNEL.TEXT.DELETE")
88 .setTitle("Tickets > Category")
Skyler Grey11236ba2022-08-08 21:13:33 +010089 .setDescription("The channel you provided is not a valid category")
Skyler Grey75ea9172022-08-06 10:22:23 +010090 .setStatus("Danger")
pineafan6702cef2022-06-13 17:52:37 +010091 ]
pineafan63fc5e22022-08-04 22:04:10 +010092 });
pineafan6702cef2022-06-13 17:52:37 +010093 }
pineafan63fc5e22022-08-04 22:04:10 +010094 channel = channel as Discord.CategoryChannel;
PineaFana00db1b2023-01-02 15:32:54 +000095 if (channel.guild.id !== interaction.guild.id)
Skyler Grey75ea9172022-08-06 10:22:23 +010096 return interaction.editReply({
97 embeds: [
98 new EmojiEmbed()
99 .setTitle("Tickets > Category")
Skyler Grey11236ba2022-08-08 21:13:33 +0100100 .setDescription("You must choose a category in this server")
Skyler Grey75ea9172022-08-06 10:22:23 +0100101 .setStatus("Danger")
102 .setEmoji("CHANNEL.TEXT.DELETE")
103 ]
104 });
pineafan6702cef2022-06-13 17:52:37 +0100105 }
106 if (options.maxtickets) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100107 if (options.maxtickets < 1)
108 return interaction.editReply({
109 embeds: [
110 new EmojiEmbed()
111 .setTitle("Tickets > Max Tickets")
Skyler Grey11236ba2022-08-08 21:13:33 +0100112 .setDescription("You must choose a number greater than 0")
Skyler Grey75ea9172022-08-06 10:22:23 +0100113 .setStatus("Danger")
114 .setEmoji("CHANNEL.TEXT.DELETE")
115 ]
116 });
pineafan6702cef2022-06-13 17:52:37 +0100117 }
pineafan3a02ea32022-08-11 21:35:04 +0100118 let role: Role | null;
pineafan6702cef2022-06-13 17:52:37 +0100119 if (options.supportping) {
120 try {
PineaFana00db1b2023-01-02 15:32:54 +0000121 role = await interaction.guild.roles.fetch(options.supportping.id);
pineafan6702cef2022-06-13 17:52:37 +0100122 } catch {
123 return await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100124 embeds: [
125 new EmojiEmbed()
126 .setEmoji("GUILD.ROLE.DELETE")
127 .setTitle("Tickets > Support Ping")
Skyler Grey11236ba2022-08-08 21:13:33 +0100128 .setDescription("The role you provided is not a valid role")
Skyler Grey75ea9172022-08-06 10:22:23 +0100129 .setStatus("Danger")
pineafan6702cef2022-06-13 17:52:37 +0100130 ]
pineafan63fc5e22022-08-04 22:04:10 +0100131 });
pineafan6702cef2022-06-13 17:52:37 +0100132 }
pineafan3a02ea32022-08-11 21:35:04 +0100133 if (!role) return;
pineafan63fc5e22022-08-04 22:04:10 +0100134 role = role as Discord.Role;
PineaFana00db1b2023-01-02 15:32:54 +0000135 if (role.guild.id !== interaction.guild.id)
Skyler Grey75ea9172022-08-06 10:22:23 +0100136 return interaction.editReply({
137 embeds: [
138 new EmojiEmbed()
139 .setTitle("Tickets > Support Ping")
Skyler Grey11236ba2022-08-08 21:13:33 +0100140 .setDescription("You must choose a role in this server")
Skyler Grey75ea9172022-08-06 10:22:23 +0100141 .setStatus("Danger")
142 .setEmoji("GUILD.ROLE.DELETE")
143 ]
144 });
pineafan6702cef2022-06-13 17:52:37 +0100145 }
146
pineafan63fc5e22022-08-04 22:04:10 +0100147 const confirmation = await new confirmationMessage(interaction)
TheCodedProf59772f82023-01-18 22:17:16 -0500148 .setEmoji("GUILD.TICKET.ARCHIVED")
pineafan6702cef2022-06-13 17:52:37 +0100149 .setTitle("Tickets")
150 .setDescription(
Skyler Grey11236ba2022-08-08 21:13:33 +0100151 (options.category ? `**Category:** ${options.category.name}\n` : "") +
152 (options.maxtickets ? `**Max Tickets:** ${options.maxtickets}\n` : "") +
153 (options.supportping ? `**Support Ping:** ${options.supportping.name}\n` : "") +
Skyler Grey75ea9172022-08-06 10:22:23 +0100154 (options.enabled !== null
155 ? `**Enabled:** ${
pineafan62ce1922022-08-25 20:34:45 +0100156 options.enabled
157 ? `${getEmojiByName("CONTROL.TICK")} Yes`
158 : `${getEmojiByName("CONTROL.CROSS")} No`
159 }\n`
Skyler Grey75ea9172022-08-06 10:22:23 +0100160 : "") +
161 "\nAre you sure you want to apply these settings?"
pineafan6702cef2022-06-13 17:52:37 +0100162 )
163 .setColor("Warning")
PineaFan5d98a4b2023-01-19 16:15:47 +0000164 .setFailedMessage("No changes were made", "Success", "GUILD.TICKET.OPEN")
pineafan6702cef2022-06-13 17:52:37 +0100165 .setInverted(true)
pineafan63fc5e22022-08-04 22:04:10 +0100166 .send(true);
167 if (confirmation.cancelled) return;
pineafan6702cef2022-06-13 17:52:37 +0100168 if (confirmation.success) {
pineafan3a02ea32022-08-11 21:35:04 +0100169 const toUpdate: Record<string, string | boolean | number> = {};
Skyler Grey11236ba2022-08-08 21:13:33 +0100170 if (options.enabled !== null) toUpdate["tickets.enabled"] = options.enabled;
171 if (options.category) toUpdate["tickets.category"] = options.category.id;
172 if (options.maxtickets) toUpdate["tickets.maxTickets"] = options.maxtickets;
173 if (options.supportping) toUpdate["tickets.supportRole"] = options.supportping.id;
pineafan6702cef2022-06-13 17:52:37 +0100174 try {
PineaFana00db1b2023-01-02 15:32:54 +0000175 await client.database.guilds.write(interaction.guild.id, toUpdate);
pineafan6702cef2022-06-13 17:52:37 +0100176 } catch (e) {
177 return interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100178 embeds: [
179 new EmojiEmbed()
180 .setTitle("Tickets")
Skyler Grey11236ba2022-08-08 21:13:33 +0100181 .setDescription("Something went wrong and the staff notifications channel could not be set")
Skyler Grey75ea9172022-08-06 10:22:23 +0100182 .setStatus("Danger")
183 .setEmoji("GUILD.TICKET.DELETE")
184 ],
185 components: []
pineafan6702cef2022-06-13 17:52:37 +0100186 });
187 }
188 } else {
189 return interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100190 embeds: [
191 new EmojiEmbed()
192 .setTitle("Tickets")
193 .setDescription("No changes were made")
194 .setStatus("Success")
195 .setEmoji("GUILD.TICKET.OPEN")
196 ],
197 components: []
pineafan6702cef2022-06-13 17:52:37 +0100198 });
199 }
200 }
PineaFan638eb132023-01-19 10:41:22 +0000201 const data = await client.database.guilds.read(interaction.guild.id);
202 data.tickets.customTypes = (data.tickets.customTypes ?? []).filter(
Skyler Grey11236ba2022-08-08 21:13:33 +0100203 (value: string, index: number, array: string[]) => array.indexOf(value) === index
Skyler Grey75ea9172022-08-06 10:22:23 +0100204 );
pineafan6702cef2022-06-13 17:52:37 +0100205 let lastClicked = "";
PineaFan638eb132023-01-19 10:41:22 +0000206 const embed: EmojiEmbed = new EmojiEmbed();
207 const compiledData = {
pineafan6702cef2022-06-13 17:52:37 +0100208 enabled: data.tickets.enabled,
209 category: data.tickets.category,
210 maxTickets: data.tickets.maxTickets,
211 supportRole: data.tickets.supportRole,
212 useCustom: data.tickets.useCustom,
213 types: data.tickets.types,
PineaFan638eb132023-01-19 10:41:22 +0000214 customTypes: data.tickets.customTypes as string[] | null
pineafan63fc5e22022-08-04 22:04:10 +0100215 };
Skyler Greyad002172022-08-16 18:48:26 +0100216 let timedOut = false;
217 while (!timedOut) {
TheCodedProf59772f82023-01-18 22:17:16 -0500218 embed
pineafan6702cef2022-06-13 17:52:37 +0100219 .setTitle("Tickets")
220 .setDescription(
TheCodedProf59772f82023-01-18 22:17:16 -0500221 `${compiledData.enabled ? "" : getEmojiByName("TICKETS.REPORT")} **Enabled:** ${
222 compiledData.enabled ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`
Skyler Grey75ea9172022-08-06 10:22:23 +0100223 }\n` +
TheCodedProf59772f82023-01-18 22:17:16 -0500224 `${compiledData.category ? "" : getEmojiByName("TICKETS.REPORT")} **Category:** ${
225 compiledData.category ? `<#${compiledData.category}>` : "*None set*"
Skyler Grey75ea9172022-08-06 10:22:23 +0100226 }\n` +
TheCodedProf59772f82023-01-18 22:17:16 -0500227 `**Max Tickets:** ${compiledData.maxTickets ? compiledData.maxTickets : "*No limit*"}\n` +
228 `**Support Ping:** ${compiledData.supportRole ? `<@&${compiledData.supportRole}>` : "*None set*"}\n\n` +
229 (compiledData.useCustom && compiledData.customTypes === null ? `${getEmojiByName("TICKETS.REPORT")} ` : "") +
230 `${compiledData.useCustom ? "Custom" : "Default"} types in use` +
Skyler Grey75ea9172022-08-06 10:22:23 +0100231 "\n\n" +
Skyler Grey11236ba2022-08-08 21:13:33 +0100232 `${getEmojiByName("TICKETS.REPORT")} *Indicates a setting stopping tickets from being used*`
pineafan6702cef2022-06-13 17:52:37 +0100233 )
234 .setStatus("Success")
pineafan63fc5e22022-08-04 22:04:10 +0100235 .setEmoji("GUILD.TICKET.OPEN");
Skyler Grey75ea9172022-08-06 10:22:23 +0100236 m = (await interaction.editReply({
237 embeds: [embed],
238 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500239 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400240 new ButtonBuilder()
TheCodedProf59772f82023-01-18 22:17:16 -0500241 .setLabel("Tickets " + (compiledData.enabled ? "enabled" : "disabled"))
242 .setEmoji(getEmojiByName("CONTROL." + (compiledData.enabled ? "TICK" : "CROSS"), "id"))
243 .setStyle(compiledData.enabled ? ButtonStyle.Success : ButtonStyle.Danger)
Skyler Grey75ea9172022-08-06 10:22:23 +0100244 .setCustomId("enabled"),
TheCodedProf21c08592022-09-13 14:14:43 -0400245 new ButtonBuilder()
Skyler Grey11236ba2022-08-08 21:13:33 +0100246 .setLabel(lastClicked === "cat" ? "Click again to confirm" : "Clear category")
Skyler Grey75ea9172022-08-06 10:22:23 +0100247 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400248 .setStyle(ButtonStyle.Danger)
Skyler Grey75ea9172022-08-06 10:22:23 +0100249 .setCustomId("clearCategory")
TheCodedProf59772f82023-01-18 22:17:16 -0500250 .setDisabled(compiledData.category === null),
TheCodedProf21c08592022-09-13 14:14:43 -0400251 new ButtonBuilder()
Skyler Grey11236ba2022-08-08 21:13:33 +0100252 .setLabel(lastClicked === "max" ? "Click again to confirm" : "Reset max tickets")
Skyler Grey75ea9172022-08-06 10:22:23 +0100253 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400254 .setStyle(ButtonStyle.Danger)
Skyler Grey75ea9172022-08-06 10:22:23 +0100255 .setCustomId("clearMaxTickets")
TheCodedProf59772f82023-01-18 22:17:16 -0500256 .setDisabled(compiledData.maxTickets === 5),
TheCodedProf21c08592022-09-13 14:14:43 -0400257 new ButtonBuilder()
Skyler Grey11236ba2022-08-08 21:13:33 +0100258 .setLabel(lastClicked === "sup" ? "Click again to confirm" : "Clear support ping")
Skyler Grey75ea9172022-08-06 10:22:23 +0100259 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400260 .setStyle(ButtonStyle.Danger)
Skyler Grey75ea9172022-08-06 10:22:23 +0100261 .setCustomId("clearSupportPing")
TheCodedProf59772f82023-01-18 22:17:16 -0500262 .setDisabled(compiledData.supportRole === null)
Skyler Grey75ea9172022-08-06 10:22:23 +0100263 ]),
TheCodedProf59772f82023-01-18 22:17:16 -0500264 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400265 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100266 .setLabel("Manage types")
267 .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400268 .setStyle(ButtonStyle.Secondary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100269 .setCustomId("manageTypes"),
TheCodedProf21c08592022-09-13 14:14:43 -0400270 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100271 .setLabel("Add create ticket button")
272 .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400273 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100274 .setCustomId("send")
275 ])
276 ]
277 })) as Message;
Skyler Grey1a67e182022-08-04 23:05:44 +0100278 let i: MessageComponentInteraction;
pineafan6702cef2022-06-13 17:52:37 +0100279 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000280 i = await m.awaitMessageComponent({
281 time: 300000,
282 filter: (i) => { return i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.id }
283 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100284 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100285 timedOut = true;
286 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100287 }
pineafan63fc5e22022-08-04 22:04:10 +0100288 i.deferUpdate();
TheCodedProf59772f82023-01-18 22:17:16 -0500289 if ((i.component as ButtonComponent).customId === "clearCategory") {
pineafane23c4ec2022-07-27 21:56:27 +0100290 if (lastClicked === "cat") {
pineafan6702cef2022-06-13 17:52:37 +0100291 lastClicked = "";
PineaFana00db1b2023-01-02 15:32:54 +0000292 await client.database.guilds.write(interaction.guild.id, null, ["tickets.category"]);
TheCodedProf59772f82023-01-18 22:17:16 -0500293 compiledData.category = null;
pineafan6702cef2022-06-13 17:52:37 +0100294 } else lastClicked = "cat";
TheCodedProf59772f82023-01-18 22:17:16 -0500295 } else if ((i.component as ButtonComponent).customId === "clearMaxTickets") {
pineafane23c4ec2022-07-27 21:56:27 +0100296 if (lastClicked === "max") {
pineafan6702cef2022-06-13 17:52:37 +0100297 lastClicked = "";
PineaFana00db1b2023-01-02 15:32:54 +0000298 await client.database.guilds.write(interaction.guild.id, null, ["tickets.maxTickets"]);
TheCodedProf59772f82023-01-18 22:17:16 -0500299 compiledData.maxTickets = 5;
pineafan6702cef2022-06-13 17:52:37 +0100300 } else lastClicked = "max";
TheCodedProf59772f82023-01-18 22:17:16 -0500301 } else if ((i.component as ButtonComponent).customId === "clearSupportPing") {
pineafane23c4ec2022-07-27 21:56:27 +0100302 if (lastClicked === "sup") {
pineafan6702cef2022-06-13 17:52:37 +0100303 lastClicked = "";
PineaFana00db1b2023-01-02 15:32:54 +0000304 await client.database.guilds.write(interaction.guild.id, null, ["tickets.supportRole"]);
TheCodedProf59772f82023-01-18 22:17:16 -0500305 compiledData.supportRole = null;
pineafan6702cef2022-06-13 17:52:37 +0100306 } else lastClicked = "sup";
TheCodedProf59772f82023-01-18 22:17:16 -0500307 } else if ((i.component as ButtonComponent).customId === "send") {
pineafan41d93562022-07-30 22:10:15 +0100308 const ticketMessages = [
Skyler Grey75ea9172022-08-06 10:22:23 +0100309 {
310 label: "Create ticket",
311 description: "Click the button below to create a ticket"
312 },
313 {
314 label: "Issues, questions or feedback?",
Skyler Grey11236ba2022-08-08 21:13:33 +0100315 description: "Click below to open a ticket and get help from our staff team"
Skyler Grey75ea9172022-08-06 10:22:23 +0100316 },
317 {
318 label: "Contact Us",
Skyler Grey11236ba2022-08-08 21:13:33 +0100319 description: "Click the button below to speak to us privately"
Skyler Grey75ea9172022-08-06 10:22:23 +0100320 }
pineafan63fc5e22022-08-04 22:04:10 +0100321 ];
Skyler Greyad002172022-08-16 18:48:26 +0100322 let innerTimedOut = false;
323 let templateSelected = false;
324 while (!innerTimedOut && !templateSelected) {
TheCodedProf59772f82023-01-18 22:17:16 -0500325 const enabled = compiledData.enabled && compiledData.category !== null;
Skyler Grey75ea9172022-08-06 10:22:23 +0100326 await interaction.editReply({
327 embeds: [
328 new EmojiEmbed()
329 .setTitle("Ticket Button")
Skyler Grey11236ba2022-08-08 21:13:33 +0100330 .setDescription("Select a message template to send in this channel")
Skyler Grey75ea9172022-08-06 10:22:23 +0100331 .setFooter({
332 text: enabled
333 ? ""
334 : "Tickets are not set up correctly so the button may not work for users. Check the main menu to find which options must be set."
335 })
336 .setStatus(enabled ? "Success" : "Warning")
337 .setEmoji("GUILD.ROLES.CREATE")
338 ],
339 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500340 new ActionRowBuilder<StringSelectMenuBuilder>().addComponents([
TheCodedProfa16d1672023-01-18 18:58:34 -0500341 new StringSelectMenuBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100342 .setOptions(
343 ticketMessages.map(
344 (
345 t: {
346 label: string;
347 description: string;
348 value?: string;
349 },
350 index
351 ) => {
352 t.value = index.toString();
353 return t as {
354 value: string;
355 label: string;
356 description: string;
357 };
358 }
359 )
360 )
361 .setCustomId("template")
362 .setMaxValues(1)
363 .setMinValues(1)
364 .setPlaceholder("Select a message template")
365 ]),
TheCodedProf59772f82023-01-18 22:17:16 -0500366 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400367 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100368 .setCustomId("back")
369 .setLabel("Back")
370 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400371 .setStyle(ButtonStyle.Danger),
372 new ButtonBuilder().setCustomId("blank").setLabel("Empty").setStyle(ButtonStyle.Secondary),
373 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100374 .setCustomId("custom")
375 .setLabel("Custom")
376 .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400377 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100378 ])
379 ]
380 });
Skyler Grey1a67e182022-08-04 23:05:44 +0100381 let i: MessageComponentInteraction;
pineafan41d93562022-07-30 22:10:15 +0100382 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000383 i = await m.awaitMessageComponent({
384 time: 300000,
385 filter: (i) => { return i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.id }
386 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100387 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100388 innerTimedOut = true;
389 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100390 }
TheCodedProf4a6d5712023-01-19 15:54:40 -0500391 if (i.isStringSelectMenu() && i.customId === "template") {
pineafan63fc5e22022-08-04 22:04:10 +0100392 i.deferUpdate();
pineafan3a02ea32022-08-11 21:35:04 +0100393 await interaction.channel!.send({
Skyler Grey75ea9172022-08-06 10:22:23 +0100394 embeds: [
395 new EmojiEmbed()
TheCodedProf4a6d5712023-01-19 15:54:40 -0500396 .setTitle(ticketMessages[parseInt(i.values[0]!)]!.label)
Skyler Grey75ea9172022-08-06 10:22:23 +0100397 .setDescription(
TheCodedProf4a6d5712023-01-19 15:54:40 -0500398 ticketMessages[parseInt(i.values[0]!)]!.description
Skyler Grey75ea9172022-08-06 10:22:23 +0100399 )
400 .setStatus("Success")
401 .setEmoji("GUILD.TICKET.OPEN")
402 ],
403 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500404 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400405 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100406 .setLabel("Create Ticket")
Skyler Grey11236ba2022-08-08 21:13:33 +0100407 .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400408 .setStyle(ButtonStyle.Success)
Skyler Grey75ea9172022-08-06 10:22:23 +0100409 .setCustomId("createticket")
410 ])
411 ]
412 });
Skyler Greyad002172022-08-16 18:48:26 +0100413 templateSelected = true;
414 continue;
TheCodedProf59772f82023-01-18 22:17:16 -0500415 } else if ((i.component as ButtonComponent).customId === "blank") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100416 i.deferUpdate();
pineafan3a02ea32022-08-11 21:35:04 +0100417 await interaction.channel!.send({
Skyler Grey75ea9172022-08-06 10:22:23 +0100418 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500419 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400420 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100421 .setLabel("Create Ticket")
Skyler Grey11236ba2022-08-08 21:13:33 +0100422 .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400423 .setStyle(ButtonStyle.Success)
Skyler Grey75ea9172022-08-06 10:22:23 +0100424 .setCustomId("createticket")
425 ])
426 ]
427 });
Skyler Greyad002172022-08-16 18:48:26 +0100428 templateSelected = true;
429 continue;
TheCodedProf59772f82023-01-18 22:17:16 -0500430 } else if ((i.component as ButtonComponent).customId === "custom") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100431 await i.showModal(
TheCodedProf59772f82023-01-18 22:17:16 -0500432 new Discord.ModalBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100433 .setCustomId("modal")
434 .setTitle("Enter embed details")
435 .addComponents(
TheCodedProf59772f82023-01-18 22:17:16 -0500436 new ActionRowBuilder<TextInputBuilder>().addComponents(
437 new TextInputBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100438 .setCustomId("title")
439 .setLabel("Title")
440 .setMaxLength(256)
441 .setRequired(true)
TheCodedProf59772f82023-01-18 22:17:16 -0500442 .setStyle(Discord.TextInputStyle.Short)
Skyler Grey75ea9172022-08-06 10:22:23 +0100443 ),
TheCodedProf59772f82023-01-18 22:17:16 -0500444 new ActionRowBuilder<TextInputBuilder>().addComponents(
445 new TextInputBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100446 .setCustomId("description")
447 .setLabel("Description")
448 .setMaxLength(4000)
449 .setRequired(true)
TheCodedProf59772f82023-01-18 22:17:16 -0500450 .setStyle(Discord.TextInputStyle.Paragraph)
Skyler Grey75ea9172022-08-06 10:22:23 +0100451 )
452 )
453 );
pineafan41d93562022-07-30 22:10:15 +0100454 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100455 embeds: [
456 new EmojiEmbed()
457 .setTitle("Ticket Button")
Skyler Grey11236ba2022-08-08 21:13:33 +0100458 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100459 .setStatus("Success")
460 .setEmoji("GUILD.TICKET.OPEN")
461 ],
462 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500463 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400464 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100465 .setLabel("Back")
Skyler Grey11236ba2022-08-08 21:13:33 +0100466 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400467 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100468 .setCustomId("back")
469 ])
470 ]
pineafan41d93562022-07-30 22:10:15 +0100471 });
472 let out;
473 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100474 out = await modalInteractionCollector(
475 m,
pineafan3a02ea32022-08-11 21:35:04 +0100476 (m) => m.channel!.id === interaction.channel!.id,
Skyler Grey75ea9172022-08-06 10:22:23 +0100477 (m) => m.customId === "modify"
478 );
479 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100480 innerTimedOut = true;
481 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100482 }
TheCodedProf59772f82023-01-18 22:17:16 -0500483 out = out as ModalSubmitInteraction;
PineaFan638eb132023-01-19 10:41:22 +0000484 const title = out.fields.getTextInputValue("title");
485 const description = out.fields.getTextInputValue("description");
486 await interaction.channel!.send({
487 embeds: [
488 new EmojiEmbed()
489 .setTitle(title)
490 .setDescription(description)
491 .setStatus("Success")
492 .setEmoji("GUILD.TICKET.OPEN")
493 ],
494 components: [
495 new ActionRowBuilder<ButtonBuilder>().addComponents([
496 new ButtonBuilder()
497 .setLabel("Create Ticket")
498 .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
499 .setStyle(ButtonStyle.Success)
500 .setCustomId("createticket")
501 ])
502 ]
503 });
504 templateSelected = true;
pineafan41d93562022-07-30 22:10:15 +0100505 }
506 }
TheCodedProf59772f82023-01-18 22:17:16 -0500507 } else if ((i.component as ButtonComponent).customId === "enabled") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100508 await client.database.guilds.write(interaction.guild.id, {
TheCodedProf59772f82023-01-18 22:17:16 -0500509 "tickets.enabled": !compiledData.enabled
Skyler Grey75ea9172022-08-06 10:22:23 +0100510 });
TheCodedProf59772f82023-01-18 22:17:16 -0500511 compiledData.enabled = !compiledData.enabled;
512 } else if ((i.component as ButtonComponent).customId === "manageTypes") {
PineaFan638eb132023-01-19 10:41:22 +0000513 data.tickets = await manageTypes(interaction, data.tickets, m as Message);
pineafan6702cef2022-06-13 17:52:37 +0100514 }
515 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100516 await interaction.editReply({
TheCodedProf59772f82023-01-18 22:17:16 -0500517 embeds: [ embed.setFooter({ text: "Message timed out" })],
Skyler Grey75ea9172022-08-06 10:22:23 +0100518 components: []
519 });
pineafan63fc5e22022-08-04 22:04:10 +0100520};
pineafan4f164f32022-02-26 22:07:12 +0000521
Skyler Grey11236ba2022-08-08 21:13:33 +0100522async function manageTypes(interaction: CommandInteraction, data: GuildConfig["tickets"], m: Message) {
Skyler Greyad002172022-08-16 18:48:26 +0100523 let timedOut = false;
524 let backPressed = false;
525 while (!timedOut && !backPressed) {
pineafan6702cef2022-06-13 17:52:37 +0100526 if (data.useCustom) {
pineafan63fc5e22022-08-04 22:04:10 +0100527 const customTypes = data.customTypes;
pineafanc6158ab2022-06-17 16:34:07 +0100528 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100529 embeds: [
530 new EmojiEmbed()
531 .setTitle("Tickets > Types")
532 .setDescription(
533 "**Custom types enabled**\n\n" +
534 "**Types in use:**\n" +
Skyler Grey11236ba2022-08-08 21:13:33 +0100535 (customTypes !== null ? customTypes.map((t) => `> ${t}`).join("\n") : "*None set*") +
Skyler Grey75ea9172022-08-06 10:22:23 +0100536 "\n\n" +
537 (customTypes === null
538 ? `${getEmojiByName(
539 "TICKETS.REPORT"
540 )} Having no types will disable tickets. Please add at least 1 type or use default types`
541 : "")
pineafan6702cef2022-06-13 17:52:37 +0100542 )
Skyler Grey75ea9172022-08-06 10:22:23 +0100543 .setStatus("Success")
544 .setEmoji("GUILD.TICKET.OPEN")
545 ],
546 components: (customTypes
547 ? [
TheCodedProf59772f82023-01-18 22:17:16 -0500548 new ActionRowBuilder<StringSelectMenuBuilder | ButtonBuilder>().addComponents([
TheCodedProfa16d1672023-01-18 18:58:34 -0500549 new Discord.StringSelectMenuBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100550 .setCustomId("removeTypes")
551 .setPlaceholder("Select types to remove")
552 .setMaxValues(customTypes.length)
553 .setMinValues(1)
554 .addOptions(
555 customTypes.map((t) => ({
556 label: t,
557 value: t
558 }))
559 )
560 ])
561 ]
562 : []
563 ).concat([
TheCodedProf59772f82023-01-18 22:17:16 -0500564 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400565 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100566 .setLabel("Back")
567 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400568 .setStyle(ButtonStyle.Primary)
pineafan6702cef2022-06-13 17:52:37 +0100569 .setCustomId("back"),
TheCodedProf21c08592022-09-13 14:14:43 -0400570 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100571 .setLabel("Add new type")
Skyler Grey11236ba2022-08-08 21:13:33 +0100572 .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400573 .setStyle(ButtonStyle.Primary)
pineafan6702cef2022-06-13 17:52:37 +0100574 .setCustomId("addType")
Skyler Grey11236ba2022-08-08 21:13:33 +0100575 .setDisabled(customTypes !== null && customTypes.length >= 25),
TheCodedProf21c08592022-09-13 14:14:43 -0400576 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100577 .setLabel("Switch to default types")
TheCodedProf21c08592022-09-13 14:14:43 -0400578 .setStyle(ButtonStyle.Secondary)
pineafan63fc5e22022-08-04 22:04:10 +0100579 .setCustomId("switchToDefault")
pineafan6702cef2022-06-13 17:52:37 +0100580 ])
581 ])
582 });
583 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100584 const inUse = toHexArray(data.types, ticketTypes);
TheCodedProf59772f82023-01-18 22:17:16 -0500585 const options: StringSelectMenuOptionBuilder[] = [];
Skyler Grey75ea9172022-08-06 10:22:23 +0100586 ticketTypes.forEach((type) => {
587 options.push(
TheCodedProf59772f82023-01-18 22:17:16 -0500588 new StringSelectMenuOptionBuilder({
Skyler Grey75ea9172022-08-06 10:22:23 +0100589 label: capitalize(type),
590 value: type,
TheCodedProf59772f82023-01-18 22:17:16 -0500591 emoji: client.emojis.cache.get(getEmojiByName(`TICKETS.${type.toUpperCase()}`, "id")) as APIMessageComponentEmoji,
Skyler Grey75ea9172022-08-06 10:22:23 +0100592 default: inUse.includes(type)
593 })
594 );
pineafan63fc5e22022-08-04 22:04:10 +0100595 });
TheCodedProf59772f82023-01-18 22:17:16 -0500596 const selectPane = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents([
TheCodedProfa16d1672023-01-18 18:58:34 -0500597 new Discord.StringSelectMenuBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100598 .addOptions(options)
599 .setCustomId("types")
600 .setMaxValues(ticketTypes.length)
601 .setMinValues(1)
602 .setPlaceholder("Select types to use")
pineafan63fc5e22022-08-04 22:04:10 +0100603 ]);
pineafanc6158ab2022-06-17 16:34:07 +0100604 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100605 embeds: [
606 new EmojiEmbed()
607 .setTitle("Tickets > Types")
608 .setDescription(
609 "**Default types enabled**\n\n" +
610 "**Types in use:**\n" +
611 inUse
Skyler Grey11236ba2022-08-08 21:13:33 +0100612 .map((t) => `> ${getEmojiByName("TICKETS." + t.toUpperCase())} ${capitalize(t)}`)
Skyler Grey75ea9172022-08-06 10:22:23 +0100613 .join("\n")
614 )
615 .setStatus("Success")
616 .setEmoji("GUILD.TICKET.OPEN")
617 ],
618 components: [
pineafan6702cef2022-06-13 17:52:37 +0100619 selectPane,
TheCodedProf59772f82023-01-18 22:17:16 -0500620 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400621 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100622 .setLabel("Back")
623 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400624 .setStyle(ButtonStyle.Primary)
pineafan6702cef2022-06-13 17:52:37 +0100625 .setCustomId("back"),
TheCodedProf21c08592022-09-13 14:14:43 -0400626 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100627 .setLabel("Switch to custom types")
TheCodedProf21c08592022-09-13 14:14:43 -0400628 .setStyle(ButtonStyle.Secondary)
pineafan63fc5e22022-08-04 22:04:10 +0100629 .setCustomId("switchToCustom")
pineafan6702cef2022-06-13 17:52:37 +0100630 ])
631 ]
632 });
633 }
634 let i;
635 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000636 i = await m.awaitMessageComponent({
637 time: 300000,
638 filter: (i) => { return i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.id }
639 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100640 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100641 timedOut = true;
642 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100643 }
TheCodedProf4a6d5712023-01-19 15:54:40 -0500644 if (i.isStringSelectMenu() && i.customId === "types") {
pineafan63fc5e22022-08-04 22:04:10 +0100645 i.deferUpdate();
TheCodedProf4a6d5712023-01-19 15:54:40 -0500646 const types = toHexInteger(i.values, ticketTypes);
TheCodedProf59772f82023-01-18 22:17:16 -0500647 await client.database.guilds.write(interaction.guild!.id, {
Skyler Grey75ea9172022-08-06 10:22:23 +0100648 "tickets.types": types
649 });
pineafan6702cef2022-06-13 17:52:37 +0100650 data.types = types;
TheCodedProf4a6d5712023-01-19 15:54:40 -0500651 } else if (i.isStringSelectMenu() && i.customId === "removeTypes") {
pineafan63fc5e22022-08-04 22:04:10 +0100652 i.deferUpdate();
TheCodedProf4a6d5712023-01-19 15:54:40 -0500653 const types = i.values;
pineafan6702cef2022-06-13 17:52:37 +0100654 let customTypes = data.customTypes;
655 if (customTypes) {
656 customTypes = customTypes.filter((t) => !types.includes(t));
657 customTypes = customTypes.length > 0 ? customTypes : null;
TheCodedProf59772f82023-01-18 22:17:16 -0500658 await client.database.guilds.write(interaction.guild!.id, {
Skyler Grey75ea9172022-08-06 10:22:23 +0100659 "tickets.customTypes": customTypes
660 });
pineafan6702cef2022-06-13 17:52:37 +0100661 data.customTypes = customTypes;
662 }
TheCodedProf59772f82023-01-18 22:17:16 -0500663 } else if ((i.component as ButtonComponent).customId === "addType") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100664 await i.showModal(
TheCodedProf59772f82023-01-18 22:17:16 -0500665 new Discord.ModalBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100666 .setCustomId("modal")
667 .setTitle("Enter a name for the new type")
668 .addComponents(
TheCodedProf59772f82023-01-18 22:17:16 -0500669 new ActionRowBuilder<TextInputBuilder>().addComponents(
670 new TextInputBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100671 .setCustomId("type")
672 .setLabel("Name")
673 .setMaxLength(100)
674 .setMinLength(1)
675 .setPlaceholder('E.g. "Server Idea"')
676 .setRequired(true)
TheCodedProf59772f82023-01-18 22:17:16 -0500677 .setStyle(Discord.TextInputStyle.Short)
Skyler Grey75ea9172022-08-06 10:22:23 +0100678 )
679 )
680 );
pineafan6702cef2022-06-13 17:52:37 +0100681 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100682 embeds: [
683 new EmojiEmbed()
684 .setTitle("Tickets > Types")
Skyler Grey11236ba2022-08-08 21:13:33 +0100685 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100686 .setStatus("Success")
687 .setEmoji("GUILD.TICKET.OPEN")
688 ],
689 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500690 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400691 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100692 .setLabel("Back")
693 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400694 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100695 .setCustomId("back")
696 ])
697 ]
pineafan6702cef2022-06-13 17:52:37 +0100698 });
pineafan4edb7762022-06-26 19:21:04 +0100699 let out;
pineafan6702cef2022-06-13 17:52:37 +0100700 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100701 out = await modalInteractionCollector(
702 m,
TheCodedProf59772f82023-01-18 22:17:16 -0500703 (m) => m.channel!.id === interaction.channel!.id,
Skyler Grey75ea9172022-08-06 10:22:23 +0100704 (m) => m.customId === "addType"
705 );
706 } catch (e) {
707 continue;
708 }
TheCodedProf4a6d5712023-01-19 15:54:40 -0500709 if (!out || out.isButton()) continue;
TheCodedProf59772f82023-01-18 22:17:16 -0500710 out = out as ModalSubmitInteraction;
PineaFan638eb132023-01-19 10:41:22 +0000711 let toAdd = out.fields.getTextInputValue("type");
712 if (!toAdd) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100713 continue;
714 }
PineaFan638eb132023-01-19 10:41:22 +0000715 toAdd = toAdd.substring(0, 80);
716 try {
717 await client.database.guilds.append(interaction.guild!.id, "tickets.customTypes", toAdd);
718 } catch {
719 continue;
720 }
721 data.customTypes = data.customTypes ?? [];
722 if (!data.customTypes.includes(toAdd)) {
723 data.customTypes.push(toAdd);
724 }
TheCodedProf59772f82023-01-18 22:17:16 -0500725 } else if ((i.component as ButtonComponent).customId === "switchToDefault") {
pineafan63fc5e22022-08-04 22:04:10 +0100726 i.deferUpdate();
TheCodedProf59772f82023-01-18 22:17:16 -0500727 await client.database.guilds.write(interaction.guild!.id, { "tickets.useCustom": false }, []);
pineafan6702cef2022-06-13 17:52:37 +0100728 data.useCustom = false;
TheCodedProf59772f82023-01-18 22:17:16 -0500729 } else if ((i.component as ButtonComponent).customId === "switchToCustom") {
pineafan63fc5e22022-08-04 22:04:10 +0100730 i.deferUpdate();
TheCodedProf59772f82023-01-18 22:17:16 -0500731 await client.database.guilds.write(interaction.guild!.id, { "tickets.useCustom": true }, []);
pineafan6702cef2022-06-13 17:52:37 +0100732 data.useCustom = true;
733 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100734 i.deferUpdate();
Skyler Greyad002172022-08-16 18:48:26 +0100735 backPressed = true;
pineafan6702cef2022-06-13 17:52:37 +0100736 }
737 }
pineafan63fc5e22022-08-04 22:04:10 +0100738 return data;
pineafan6702cef2022-06-13 17:52:37 +0100739}
740
Skyler Grey1a67e182022-08-04 23:05:44 +0100741const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100742 const member = interaction.member as Discord.GuildMember;
PineaFana00db1b2023-01-02 15:32:54 +0000743 if (!member.permissions.has("ManageGuild"))
PineaFan0d06edc2023-01-17 22:10:31 +0000744 return "You must have the *Manage Server* permission to use this command";
pineafan6702cef2022-06-13 17:52:37 +0100745 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100746};
pineafan4f164f32022-02-26 22:07:12 +0000747
748export { command };
749export { callback };
Skyler Grey1a67e182022-08-04 23:05:44 +0100750export { check };