blob: 892a420efdfb48ac8754e14d6cc9b932ebc8cf05 [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,
TheCodedProfa16d1672023-01-18 18:58:34 -050014 StringSelectMenuInteraction,
TheCodedProf59772f82023-01-18 22:17:16 -050015 ButtonStyle,
16 TextInputBuilder,
17 ButtonComponent,
18 StringSelectMenuComponent,
19 ModalSubmitInteraction,
20 APIMessageComponentEmoji
Skyler Grey75ea9172022-08-06 10:22:23 +010021} from "discord.js";
TheCodedProf59772f82023-01-18 22:17:16 -050022import { SlashCommandSubcommandBuilder, StringSelectMenuOptionBuilder } from "@discordjs/builders";
Skyler Greyc634e2b2022-08-06 17:50:48 +010023import { ChannelType } from "discord-api-types/v9";
pineafan6702cef2022-06-13 17:52:37 +010024import client from "../../utils/client.js";
Skyler Grey11236ba2022-08-08 21:13:33 +010025import { toHexInteger, toHexArray, tickets as ticketTypes } from "../../utils/calculate.js";
pineafan63fc5e22022-08-04 22:04:10 +010026import { capitalize } from "../../utils/generateKeyValueList.js";
pineafan6702cef2022-06-13 17:52:37 +010027import { modalInteractionCollector } from "../../utils/dualCollector.js";
pineafan3a02ea32022-08-11 21:35:04 +010028import type { GuildConfig } from "../../utils/database.js";
pineafan4f164f32022-02-26 22:07:12 +000029
Skyler Grey75ea9172022-08-06 10:22:23 +010030const command = (builder: SlashCommandSubcommandBuilder) =>
31 builder
32 .setName("tickets")
Skyler Grey11236ba2022-08-08 21:13:33 +010033 .setDescription("Shows settings for tickets | Use no arguments to manage custom types")
Skyler Grey75ea9172022-08-06 10:22:23 +010034 .addStringOption((option) =>
35 option
36 .setName("enabled")
37 .setDescription("If users should be able to create tickets")
38 .setRequired(false)
PineaFan64486c42022-12-28 09:21:04 +000039 .addChoices(
40 {name: "Yes", value: "yes"},
41 {name: "No",value: "no"}
42 )
Skyler Grey75ea9172022-08-06 10:22:23 +010043 )
44 .addChannelOption((option) =>
45 option
46 .setName("category")
47 .setDescription("The category where tickets are created")
PineaFan64486c42022-12-28 09:21:04 +000048 .addChannelTypes(ChannelType.GuildCategory)
Skyler Grey75ea9172022-08-06 10:22:23 +010049 .setRequired(false)
50 )
51 .addNumberOption((option) =>
52 option
53 .setName("maxticketsperuser")
Skyler Grey11236ba2022-08-08 21:13:33 +010054 .setDescription("The maximum amount of tickets a user can create | Default: 5")
Skyler Grey75ea9172022-08-06 10:22:23 +010055 .setRequired(false)
56 .setMinValue(1)
57 )
58 .addRoleOption((option) =>
59 option
60 .setName("supportrole")
61 .setDescription(
62 "This role will have view access to all tickets and will be pinged when a ticket is created"
63 )
64 .setRequired(false)
65 );
pineafan4f164f32022-02-26 22:07:12 +000066
pineafan3a02ea32022-08-11 21:35:04 +010067const callback = async (interaction: CommandInteraction): Promise<unknown> => {
PineaFana00db1b2023-01-02 15:32:54 +000068 if (!interaction.guild) return;
Skyler Grey75ea9172022-08-06 10:22:23 +010069 let m = (await interaction.reply({
70 embeds: LoadingEmbed,
71 ephemeral: true,
72 fetchReply: true
73 })) as Message;
pineafan63fc5e22022-08-04 22:04:10 +010074 const options = {
TheCodedProfa16d1672023-01-18 18:58:34 -050075 enabled: (interaction.options.get("enabled")?.value as string).startsWith("yes") as boolean | null,
PineaFan638eb132023-01-19 10:41:22 +000076 category: interaction.options.get("category")?.channel as Discord.CategoryChannel | null,
77 maxtickets: interaction.options.get("maxticketsperuser")?.value as number | null,
78 supportping: interaction.options.get("supportrole")?.role as Role | null
pineafan63fc5e22022-08-04 22:04:10 +010079 };
Skyler Grey11236ba2022-08-08 21:13:33 +010080 if (options.enabled !== null || options.category || options.maxtickets || options.supportping) {
pineafan6702cef2022-06-13 17:52:37 +010081 if (options.category) {
pineafan3a02ea32022-08-11 21:35:04 +010082 let channel: GuildChannel | null;
pineafan6702cef2022-06-13 17:52:37 +010083 try {
TheCodedProf59772f82023-01-18 22:17:16 -050084 channel = await interaction.guild.channels.fetch(options.category.id) as GuildChannel;
pineafan6702cef2022-06-13 17:52:37 +010085 } catch {
86 return await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +010087 embeds: [
88 new EmojiEmbed()
89 .setEmoji("CHANNEL.TEXT.DELETE")
90 .setTitle("Tickets > Category")
Skyler Grey11236ba2022-08-08 21:13:33 +010091 .setDescription("The channel you provided is not a valid category")
Skyler Grey75ea9172022-08-06 10:22:23 +010092 .setStatus("Danger")
pineafan6702cef2022-06-13 17:52:37 +010093 ]
pineafan63fc5e22022-08-04 22:04:10 +010094 });
pineafan6702cef2022-06-13 17:52:37 +010095 }
pineafan63fc5e22022-08-04 22:04:10 +010096 channel = channel as Discord.CategoryChannel;
PineaFana00db1b2023-01-02 15:32:54 +000097 if (channel.guild.id !== interaction.guild.id)
Skyler Grey75ea9172022-08-06 10:22:23 +010098 return interaction.editReply({
99 embeds: [
100 new EmojiEmbed()
101 .setTitle("Tickets > Category")
Skyler Grey11236ba2022-08-08 21:13:33 +0100102 .setDescription("You must choose a category in this server")
Skyler Grey75ea9172022-08-06 10:22:23 +0100103 .setStatus("Danger")
104 .setEmoji("CHANNEL.TEXT.DELETE")
105 ]
106 });
pineafan6702cef2022-06-13 17:52:37 +0100107 }
108 if (options.maxtickets) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100109 if (options.maxtickets < 1)
110 return interaction.editReply({
111 embeds: [
112 new EmojiEmbed()
113 .setTitle("Tickets > Max Tickets")
Skyler Grey11236ba2022-08-08 21:13:33 +0100114 .setDescription("You must choose a number greater than 0")
Skyler Grey75ea9172022-08-06 10:22:23 +0100115 .setStatus("Danger")
116 .setEmoji("CHANNEL.TEXT.DELETE")
117 ]
118 });
pineafan6702cef2022-06-13 17:52:37 +0100119 }
pineafan3a02ea32022-08-11 21:35:04 +0100120 let role: Role | null;
pineafan6702cef2022-06-13 17:52:37 +0100121 if (options.supportping) {
122 try {
PineaFana00db1b2023-01-02 15:32:54 +0000123 role = await interaction.guild.roles.fetch(options.supportping.id);
pineafan6702cef2022-06-13 17:52:37 +0100124 } catch {
125 return await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100126 embeds: [
127 new EmojiEmbed()
128 .setEmoji("GUILD.ROLE.DELETE")
129 .setTitle("Tickets > Support Ping")
Skyler Grey11236ba2022-08-08 21:13:33 +0100130 .setDescription("The role you provided is not a valid role")
Skyler Grey75ea9172022-08-06 10:22:23 +0100131 .setStatus("Danger")
pineafan6702cef2022-06-13 17:52:37 +0100132 ]
pineafan63fc5e22022-08-04 22:04:10 +0100133 });
pineafan6702cef2022-06-13 17:52:37 +0100134 }
pineafan3a02ea32022-08-11 21:35:04 +0100135 if (!role) return;
pineafan63fc5e22022-08-04 22:04:10 +0100136 role = role as Discord.Role;
PineaFana00db1b2023-01-02 15:32:54 +0000137 if (role.guild.id !== interaction.guild.id)
Skyler Grey75ea9172022-08-06 10:22:23 +0100138 return interaction.editReply({
139 embeds: [
140 new EmojiEmbed()
141 .setTitle("Tickets > Support Ping")
Skyler Grey11236ba2022-08-08 21:13:33 +0100142 .setDescription("You must choose a role in this server")
Skyler Grey75ea9172022-08-06 10:22:23 +0100143 .setStatus("Danger")
144 .setEmoji("GUILD.ROLE.DELETE")
145 ]
146 });
pineafan6702cef2022-06-13 17:52:37 +0100147 }
148
pineafan63fc5e22022-08-04 22:04:10 +0100149 const confirmation = await new confirmationMessage(interaction)
TheCodedProf59772f82023-01-18 22:17:16 -0500150 .setEmoji("GUILD.TICKET.ARCHIVED")
pineafan6702cef2022-06-13 17:52:37 +0100151 .setTitle("Tickets")
152 .setDescription(
Skyler Grey11236ba2022-08-08 21:13:33 +0100153 (options.category ? `**Category:** ${options.category.name}\n` : "") +
154 (options.maxtickets ? `**Max Tickets:** ${options.maxtickets}\n` : "") +
155 (options.supportping ? `**Support Ping:** ${options.supportping.name}\n` : "") +
Skyler Grey75ea9172022-08-06 10:22:23 +0100156 (options.enabled !== null
157 ? `**Enabled:** ${
pineafan62ce1922022-08-25 20:34:45 +0100158 options.enabled
159 ? `${getEmojiByName("CONTROL.TICK")} Yes`
160 : `${getEmojiByName("CONTROL.CROSS")} No`
161 }\n`
Skyler Grey75ea9172022-08-06 10:22:23 +0100162 : "") +
163 "\nAre you sure you want to apply these settings?"
pineafan6702cef2022-06-13 17:52:37 +0100164 )
165 .setColor("Warning")
TheCodedProf59772f82023-01-18 22:17:16 -0500166 .setFailedMessage("Cancelled", "Warning", "GUILD.TICKET.CLOSE") // TODO: Set Actual Message
pineafan6702cef2022-06-13 17:52:37 +0100167 .setInverted(true)
pineafan63fc5e22022-08-04 22:04:10 +0100168 .send(true);
169 if (confirmation.cancelled) return;
pineafan6702cef2022-06-13 17:52:37 +0100170 if (confirmation.success) {
pineafan3a02ea32022-08-11 21:35:04 +0100171 const toUpdate: Record<string, string | boolean | number> = {};
Skyler Grey11236ba2022-08-08 21:13:33 +0100172 if (options.enabled !== null) toUpdate["tickets.enabled"] = options.enabled;
173 if (options.category) toUpdate["tickets.category"] = options.category.id;
174 if (options.maxtickets) toUpdate["tickets.maxTickets"] = options.maxtickets;
175 if (options.supportping) toUpdate["tickets.supportRole"] = options.supportping.id;
pineafan6702cef2022-06-13 17:52:37 +0100176 try {
PineaFana00db1b2023-01-02 15:32:54 +0000177 await client.database.guilds.write(interaction.guild.id, toUpdate);
pineafan6702cef2022-06-13 17:52:37 +0100178 } catch (e) {
179 return interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100180 embeds: [
181 new EmojiEmbed()
182 .setTitle("Tickets")
Skyler Grey11236ba2022-08-08 21:13:33 +0100183 .setDescription("Something went wrong and the staff notifications channel could not be set")
Skyler Grey75ea9172022-08-06 10:22:23 +0100184 .setStatus("Danger")
185 .setEmoji("GUILD.TICKET.DELETE")
186 ],
187 components: []
pineafan6702cef2022-06-13 17:52:37 +0100188 });
189 }
190 } else {
191 return interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100192 embeds: [
193 new EmojiEmbed()
194 .setTitle("Tickets")
195 .setDescription("No changes were made")
196 .setStatus("Success")
197 .setEmoji("GUILD.TICKET.OPEN")
198 ],
199 components: []
pineafan6702cef2022-06-13 17:52:37 +0100200 });
201 }
202 }
PineaFan638eb132023-01-19 10:41:22 +0000203 const data = await client.database.guilds.read(interaction.guild.id);
204 data.tickets.customTypes = (data.tickets.customTypes ?? []).filter(
Skyler Grey11236ba2022-08-08 21:13:33 +0100205 (value: string, index: number, array: string[]) => array.indexOf(value) === index
Skyler Grey75ea9172022-08-06 10:22:23 +0100206 );
pineafan6702cef2022-06-13 17:52:37 +0100207 let lastClicked = "";
PineaFan638eb132023-01-19 10:41:22 +0000208 const embed: EmojiEmbed = new EmojiEmbed();
209 const compiledData = {
pineafan6702cef2022-06-13 17:52:37 +0100210 enabled: data.tickets.enabled,
211 category: data.tickets.category,
212 maxTickets: data.tickets.maxTickets,
213 supportRole: data.tickets.supportRole,
214 useCustom: data.tickets.useCustom,
215 types: data.tickets.types,
PineaFan638eb132023-01-19 10:41:22 +0000216 customTypes: data.tickets.customTypes as string[] | null
pineafan63fc5e22022-08-04 22:04:10 +0100217 };
Skyler Greyad002172022-08-16 18:48:26 +0100218 let timedOut = false;
219 while (!timedOut) {
TheCodedProf59772f82023-01-18 22:17:16 -0500220 embed
pineafan6702cef2022-06-13 17:52:37 +0100221 .setTitle("Tickets")
222 .setDescription(
TheCodedProf59772f82023-01-18 22:17:16 -0500223 `${compiledData.enabled ? "" : getEmojiByName("TICKETS.REPORT")} **Enabled:** ${
224 compiledData.enabled ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`
Skyler Grey75ea9172022-08-06 10:22:23 +0100225 }\n` +
TheCodedProf59772f82023-01-18 22:17:16 -0500226 `${compiledData.category ? "" : getEmojiByName("TICKETS.REPORT")} **Category:** ${
227 compiledData.category ? `<#${compiledData.category}>` : "*None set*"
Skyler Grey75ea9172022-08-06 10:22:23 +0100228 }\n` +
TheCodedProf59772f82023-01-18 22:17:16 -0500229 `**Max Tickets:** ${compiledData.maxTickets ? compiledData.maxTickets : "*No limit*"}\n` +
230 `**Support Ping:** ${compiledData.supportRole ? `<@&${compiledData.supportRole}>` : "*None set*"}\n\n` +
231 (compiledData.useCustom && compiledData.customTypes === null ? `${getEmojiByName("TICKETS.REPORT")} ` : "") +
232 `${compiledData.useCustom ? "Custom" : "Default"} types in use` +
Skyler Grey75ea9172022-08-06 10:22:23 +0100233 "\n\n" +
Skyler Grey11236ba2022-08-08 21:13:33 +0100234 `${getEmojiByName("TICKETS.REPORT")} *Indicates a setting stopping tickets from being used*`
pineafan6702cef2022-06-13 17:52:37 +0100235 )
236 .setStatus("Success")
pineafan63fc5e22022-08-04 22:04:10 +0100237 .setEmoji("GUILD.TICKET.OPEN");
Skyler Grey75ea9172022-08-06 10:22:23 +0100238 m = (await interaction.editReply({
239 embeds: [embed],
240 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500241 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400242 new ButtonBuilder()
TheCodedProf59772f82023-01-18 22:17:16 -0500243 .setLabel("Tickets " + (compiledData.enabled ? "enabled" : "disabled"))
244 .setEmoji(getEmojiByName("CONTROL." + (compiledData.enabled ? "TICK" : "CROSS"), "id"))
245 .setStyle(compiledData.enabled ? ButtonStyle.Success : ButtonStyle.Danger)
Skyler Grey75ea9172022-08-06 10:22:23 +0100246 .setCustomId("enabled"),
TheCodedProf21c08592022-09-13 14:14:43 -0400247 new ButtonBuilder()
Skyler Grey11236ba2022-08-08 21:13:33 +0100248 .setLabel(lastClicked === "cat" ? "Click again to confirm" : "Clear category")
Skyler Grey75ea9172022-08-06 10:22:23 +0100249 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400250 .setStyle(ButtonStyle.Danger)
Skyler Grey75ea9172022-08-06 10:22:23 +0100251 .setCustomId("clearCategory")
TheCodedProf59772f82023-01-18 22:17:16 -0500252 .setDisabled(compiledData.category === null),
TheCodedProf21c08592022-09-13 14:14:43 -0400253 new ButtonBuilder()
Skyler Grey11236ba2022-08-08 21:13:33 +0100254 .setLabel(lastClicked === "max" ? "Click again to confirm" : "Reset max tickets")
Skyler Grey75ea9172022-08-06 10:22:23 +0100255 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400256 .setStyle(ButtonStyle.Danger)
Skyler Grey75ea9172022-08-06 10:22:23 +0100257 .setCustomId("clearMaxTickets")
TheCodedProf59772f82023-01-18 22:17:16 -0500258 .setDisabled(compiledData.maxTickets === 5),
TheCodedProf21c08592022-09-13 14:14:43 -0400259 new ButtonBuilder()
Skyler Grey11236ba2022-08-08 21:13:33 +0100260 .setLabel(lastClicked === "sup" ? "Click again to confirm" : "Clear support ping")
Skyler Grey75ea9172022-08-06 10:22:23 +0100261 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400262 .setStyle(ButtonStyle.Danger)
Skyler Grey75ea9172022-08-06 10:22:23 +0100263 .setCustomId("clearSupportPing")
TheCodedProf59772f82023-01-18 22:17:16 -0500264 .setDisabled(compiledData.supportRole === null)
Skyler Grey75ea9172022-08-06 10:22:23 +0100265 ]),
TheCodedProf59772f82023-01-18 22:17:16 -0500266 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400267 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100268 .setLabel("Manage types")
269 .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400270 .setStyle(ButtonStyle.Secondary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100271 .setCustomId("manageTypes"),
TheCodedProf21c08592022-09-13 14:14:43 -0400272 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100273 .setLabel("Add create ticket button")
274 .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400275 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100276 .setCustomId("send")
277 ])
278 ]
279 })) as Message;
Skyler Grey1a67e182022-08-04 23:05:44 +0100280 let i: MessageComponentInteraction;
pineafan6702cef2022-06-13 17:52:37 +0100281 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000282 i = await m.awaitMessageComponent({
283 time: 300000,
284 filter: (i) => { return i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.id }
285 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100286 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100287 timedOut = true;
288 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100289 }
pineafan63fc5e22022-08-04 22:04:10 +0100290 i.deferUpdate();
TheCodedProf59772f82023-01-18 22:17:16 -0500291 if ((i.component as ButtonComponent).customId === "clearCategory") {
pineafane23c4ec2022-07-27 21:56:27 +0100292 if (lastClicked === "cat") {
pineafan6702cef2022-06-13 17:52:37 +0100293 lastClicked = "";
PineaFana00db1b2023-01-02 15:32:54 +0000294 await client.database.guilds.write(interaction.guild.id, null, ["tickets.category"]);
TheCodedProf59772f82023-01-18 22:17:16 -0500295 compiledData.category = null;
pineafan6702cef2022-06-13 17:52:37 +0100296 } else lastClicked = "cat";
TheCodedProf59772f82023-01-18 22:17:16 -0500297 } else if ((i.component as ButtonComponent).customId === "clearMaxTickets") {
pineafane23c4ec2022-07-27 21:56:27 +0100298 if (lastClicked === "max") {
pineafan6702cef2022-06-13 17:52:37 +0100299 lastClicked = "";
PineaFana00db1b2023-01-02 15:32:54 +0000300 await client.database.guilds.write(interaction.guild.id, null, ["tickets.maxTickets"]);
TheCodedProf59772f82023-01-18 22:17:16 -0500301 compiledData.maxTickets = 5;
pineafan6702cef2022-06-13 17:52:37 +0100302 } else lastClicked = "max";
TheCodedProf59772f82023-01-18 22:17:16 -0500303 } else if ((i.component as ButtonComponent).customId === "clearSupportPing") {
pineafane23c4ec2022-07-27 21:56:27 +0100304 if (lastClicked === "sup") {
pineafan6702cef2022-06-13 17:52:37 +0100305 lastClicked = "";
PineaFana00db1b2023-01-02 15:32:54 +0000306 await client.database.guilds.write(interaction.guild.id, null, ["tickets.supportRole"]);
TheCodedProf59772f82023-01-18 22:17:16 -0500307 compiledData.supportRole = null;
pineafan6702cef2022-06-13 17:52:37 +0100308 } else lastClicked = "sup";
TheCodedProf59772f82023-01-18 22:17:16 -0500309 } else if ((i.component as ButtonComponent).customId === "send") {
pineafan41d93562022-07-30 22:10:15 +0100310 const ticketMessages = [
Skyler Grey75ea9172022-08-06 10:22:23 +0100311 {
312 label: "Create ticket",
313 description: "Click the button below to create a ticket"
314 },
315 {
316 label: "Issues, questions or feedback?",
Skyler Grey11236ba2022-08-08 21:13:33 +0100317 description: "Click below to open a ticket and get help from our staff team"
Skyler Grey75ea9172022-08-06 10:22:23 +0100318 },
319 {
320 label: "Contact Us",
Skyler Grey11236ba2022-08-08 21:13:33 +0100321 description: "Click the button below to speak to us privately"
Skyler Grey75ea9172022-08-06 10:22:23 +0100322 }
pineafan63fc5e22022-08-04 22:04:10 +0100323 ];
Skyler Greyad002172022-08-16 18:48:26 +0100324 let innerTimedOut = false;
325 let templateSelected = false;
326 while (!innerTimedOut && !templateSelected) {
TheCodedProf59772f82023-01-18 22:17:16 -0500327 const enabled = compiledData.enabled && compiledData.category !== null;
Skyler Grey75ea9172022-08-06 10:22:23 +0100328 await interaction.editReply({
329 embeds: [
330 new EmojiEmbed()
331 .setTitle("Ticket Button")
Skyler Grey11236ba2022-08-08 21:13:33 +0100332 .setDescription("Select a message template to send in this channel")
Skyler Grey75ea9172022-08-06 10:22:23 +0100333 .setFooter({
334 text: enabled
335 ? ""
336 : "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."
337 })
338 .setStatus(enabled ? "Success" : "Warning")
339 .setEmoji("GUILD.ROLES.CREATE")
340 ],
341 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500342 new ActionRowBuilder<StringSelectMenuBuilder>().addComponents([
TheCodedProfa16d1672023-01-18 18:58:34 -0500343 new StringSelectMenuBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100344 .setOptions(
345 ticketMessages.map(
346 (
347 t: {
348 label: string;
349 description: string;
350 value?: string;
351 },
352 index
353 ) => {
354 t.value = index.toString();
355 return t as {
356 value: string;
357 label: string;
358 description: string;
359 };
360 }
361 )
362 )
363 .setCustomId("template")
364 .setMaxValues(1)
365 .setMinValues(1)
366 .setPlaceholder("Select a message template")
367 ]),
TheCodedProf59772f82023-01-18 22:17:16 -0500368 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400369 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100370 .setCustomId("back")
371 .setLabel("Back")
372 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400373 .setStyle(ButtonStyle.Danger),
374 new ButtonBuilder().setCustomId("blank").setLabel("Empty").setStyle(ButtonStyle.Secondary),
375 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100376 .setCustomId("custom")
377 .setLabel("Custom")
378 .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400379 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100380 ])
381 ]
382 });
Skyler Grey1a67e182022-08-04 23:05:44 +0100383 let i: MessageComponentInteraction;
pineafan41d93562022-07-30 22:10:15 +0100384 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000385 i = await m.awaitMessageComponent({
386 time: 300000,
387 filter: (i) => { return i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.id }
388 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100389 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100390 innerTimedOut = true;
391 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100392 }
TheCodedProf59772f82023-01-18 22:17:16 -0500393 if ((i.component as StringSelectMenuComponent).customId === "template") {
pineafan63fc5e22022-08-04 22:04:10 +0100394 i.deferUpdate();
pineafan3a02ea32022-08-11 21:35:04 +0100395 await interaction.channel!.send({
Skyler Grey75ea9172022-08-06 10:22:23 +0100396 embeds: [
397 new EmojiEmbed()
TheCodedProfa16d1672023-01-18 18:58:34 -0500398 .setTitle(ticketMessages[parseInt((i as StringSelectMenuInteraction).values[0]!)]!.label)
Skyler Grey75ea9172022-08-06 10:22:23 +0100399 .setDescription(
TheCodedProfa16d1672023-01-18 18:58:34 -0500400 ticketMessages[parseInt((i as StringSelectMenuInteraction).values[0]!)]!.description
Skyler Grey75ea9172022-08-06 10:22:23 +0100401 )
402 .setStatus("Success")
403 .setEmoji("GUILD.TICKET.OPEN")
404 ],
405 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500406 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400407 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100408 .setLabel("Create Ticket")
Skyler Grey11236ba2022-08-08 21:13:33 +0100409 .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400410 .setStyle(ButtonStyle.Success)
Skyler Grey75ea9172022-08-06 10:22:23 +0100411 .setCustomId("createticket")
412 ])
413 ]
414 });
Skyler Greyad002172022-08-16 18:48:26 +0100415 templateSelected = true;
416 continue;
TheCodedProf59772f82023-01-18 22:17:16 -0500417 } else if ((i.component as ButtonComponent).customId === "blank") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100418 i.deferUpdate();
pineafan3a02ea32022-08-11 21:35:04 +0100419 await interaction.channel!.send({
Skyler Grey75ea9172022-08-06 10:22:23 +0100420 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500421 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400422 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100423 .setLabel("Create Ticket")
Skyler Grey11236ba2022-08-08 21:13:33 +0100424 .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400425 .setStyle(ButtonStyle.Success)
Skyler Grey75ea9172022-08-06 10:22:23 +0100426 .setCustomId("createticket")
427 ])
428 ]
429 });
Skyler Greyad002172022-08-16 18:48:26 +0100430 templateSelected = true;
431 continue;
TheCodedProf59772f82023-01-18 22:17:16 -0500432 } else if ((i.component as ButtonComponent).customId === "custom") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100433 await i.showModal(
TheCodedProf59772f82023-01-18 22:17:16 -0500434 new Discord.ModalBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100435 .setCustomId("modal")
436 .setTitle("Enter embed details")
437 .addComponents(
TheCodedProf59772f82023-01-18 22:17:16 -0500438 new ActionRowBuilder<TextInputBuilder>().addComponents(
439 new TextInputBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100440 .setCustomId("title")
441 .setLabel("Title")
442 .setMaxLength(256)
443 .setRequired(true)
TheCodedProf59772f82023-01-18 22:17:16 -0500444 .setStyle(Discord.TextInputStyle.Short)
Skyler Grey75ea9172022-08-06 10:22:23 +0100445 ),
TheCodedProf59772f82023-01-18 22:17:16 -0500446 new ActionRowBuilder<TextInputBuilder>().addComponents(
447 new TextInputBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100448 .setCustomId("description")
449 .setLabel("Description")
450 .setMaxLength(4000)
451 .setRequired(true)
TheCodedProf59772f82023-01-18 22:17:16 -0500452 .setStyle(Discord.TextInputStyle.Paragraph)
Skyler Grey75ea9172022-08-06 10:22:23 +0100453 )
454 )
455 );
pineafan41d93562022-07-30 22:10:15 +0100456 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100457 embeds: [
458 new EmojiEmbed()
459 .setTitle("Ticket Button")
Skyler Grey11236ba2022-08-08 21:13:33 +0100460 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100461 .setStatus("Success")
462 .setEmoji("GUILD.TICKET.OPEN")
463 ],
464 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500465 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400466 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100467 .setLabel("Back")
Skyler Grey11236ba2022-08-08 21:13:33 +0100468 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400469 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100470 .setCustomId("back")
471 ])
472 ]
pineafan41d93562022-07-30 22:10:15 +0100473 });
474 let out;
475 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100476 out = await modalInteractionCollector(
477 m,
pineafan3a02ea32022-08-11 21:35:04 +0100478 (m) => m.channel!.id === interaction.channel!.id,
Skyler Grey75ea9172022-08-06 10:22:23 +0100479 (m) => m.customId === "modify"
480 );
481 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100482 innerTimedOut = true;
483 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100484 }
TheCodedProf59772f82023-01-18 22:17:16 -0500485 out = out as ModalSubmitInteraction;
PineaFan638eb132023-01-19 10:41:22 +0000486 const title = out.fields.getTextInputValue("title");
487 const description = out.fields.getTextInputValue("description");
488 await interaction.channel!.send({
489 embeds: [
490 new EmojiEmbed()
491 .setTitle(title)
492 .setDescription(description)
493 .setStatus("Success")
494 .setEmoji("GUILD.TICKET.OPEN")
495 ],
496 components: [
497 new ActionRowBuilder<ButtonBuilder>().addComponents([
498 new ButtonBuilder()
499 .setLabel("Create Ticket")
500 .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
501 .setStyle(ButtonStyle.Success)
502 .setCustomId("createticket")
503 ])
504 ]
505 });
506 templateSelected = true;
pineafan41d93562022-07-30 22:10:15 +0100507 }
508 }
TheCodedProf59772f82023-01-18 22:17:16 -0500509 } else if ((i.component as ButtonComponent).customId === "enabled") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100510 await client.database.guilds.write(interaction.guild.id, {
TheCodedProf59772f82023-01-18 22:17:16 -0500511 "tickets.enabled": !compiledData.enabled
Skyler Grey75ea9172022-08-06 10:22:23 +0100512 });
TheCodedProf59772f82023-01-18 22:17:16 -0500513 compiledData.enabled = !compiledData.enabled;
514 } else if ((i.component as ButtonComponent).customId === "manageTypes") {
PineaFan638eb132023-01-19 10:41:22 +0000515 data.tickets = await manageTypes(interaction, data.tickets, m as Message);
pineafan6702cef2022-06-13 17:52:37 +0100516 }
517 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100518 await interaction.editReply({
TheCodedProf59772f82023-01-18 22:17:16 -0500519 embeds: [ embed.setFooter({ text: "Message timed out" })],
Skyler Grey75ea9172022-08-06 10:22:23 +0100520 components: []
521 });
pineafan63fc5e22022-08-04 22:04:10 +0100522};
pineafan4f164f32022-02-26 22:07:12 +0000523
Skyler Grey11236ba2022-08-08 21:13:33 +0100524async function manageTypes(interaction: CommandInteraction, data: GuildConfig["tickets"], m: Message) {
Skyler Greyad002172022-08-16 18:48:26 +0100525 let timedOut = false;
526 let backPressed = false;
527 while (!timedOut && !backPressed) {
pineafan6702cef2022-06-13 17:52:37 +0100528 if (data.useCustom) {
pineafan63fc5e22022-08-04 22:04:10 +0100529 const customTypes = data.customTypes;
pineafanc6158ab2022-06-17 16:34:07 +0100530 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100531 embeds: [
532 new EmojiEmbed()
533 .setTitle("Tickets > Types")
534 .setDescription(
535 "**Custom types enabled**\n\n" +
536 "**Types in use:**\n" +
Skyler Grey11236ba2022-08-08 21:13:33 +0100537 (customTypes !== null ? customTypes.map((t) => `> ${t}`).join("\n") : "*None set*") +
Skyler Grey75ea9172022-08-06 10:22:23 +0100538 "\n\n" +
539 (customTypes === null
540 ? `${getEmojiByName(
541 "TICKETS.REPORT"
542 )} Having no types will disable tickets. Please add at least 1 type or use default types`
543 : "")
pineafan6702cef2022-06-13 17:52:37 +0100544 )
Skyler Grey75ea9172022-08-06 10:22:23 +0100545 .setStatus("Success")
546 .setEmoji("GUILD.TICKET.OPEN")
547 ],
548 components: (customTypes
549 ? [
TheCodedProf59772f82023-01-18 22:17:16 -0500550 new ActionRowBuilder<StringSelectMenuBuilder | ButtonBuilder>().addComponents([
TheCodedProfa16d1672023-01-18 18:58:34 -0500551 new Discord.StringSelectMenuBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100552 .setCustomId("removeTypes")
553 .setPlaceholder("Select types to remove")
554 .setMaxValues(customTypes.length)
555 .setMinValues(1)
556 .addOptions(
557 customTypes.map((t) => ({
558 label: t,
559 value: t
560 }))
561 )
562 ])
563 ]
564 : []
565 ).concat([
TheCodedProf59772f82023-01-18 22:17:16 -0500566 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400567 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100568 .setLabel("Back")
569 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400570 .setStyle(ButtonStyle.Primary)
pineafan6702cef2022-06-13 17:52:37 +0100571 .setCustomId("back"),
TheCodedProf21c08592022-09-13 14:14:43 -0400572 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100573 .setLabel("Add new type")
Skyler Grey11236ba2022-08-08 21:13:33 +0100574 .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400575 .setStyle(ButtonStyle.Primary)
pineafan6702cef2022-06-13 17:52:37 +0100576 .setCustomId("addType")
Skyler Grey11236ba2022-08-08 21:13:33 +0100577 .setDisabled(customTypes !== null && customTypes.length >= 25),
TheCodedProf21c08592022-09-13 14:14:43 -0400578 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100579 .setLabel("Switch to default types")
TheCodedProf21c08592022-09-13 14:14:43 -0400580 .setStyle(ButtonStyle.Secondary)
pineafan63fc5e22022-08-04 22:04:10 +0100581 .setCustomId("switchToDefault")
pineafan6702cef2022-06-13 17:52:37 +0100582 ])
583 ])
584 });
585 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100586 const inUse = toHexArray(data.types, ticketTypes);
TheCodedProf59772f82023-01-18 22:17:16 -0500587 const options: StringSelectMenuOptionBuilder[] = [];
Skyler Grey75ea9172022-08-06 10:22:23 +0100588 ticketTypes.forEach((type) => {
589 options.push(
TheCodedProf59772f82023-01-18 22:17:16 -0500590 new StringSelectMenuOptionBuilder({
Skyler Grey75ea9172022-08-06 10:22:23 +0100591 label: capitalize(type),
592 value: type,
TheCodedProf59772f82023-01-18 22:17:16 -0500593 emoji: client.emojis.cache.get(getEmojiByName(`TICKETS.${type.toUpperCase()}`, "id")) as APIMessageComponentEmoji,
Skyler Grey75ea9172022-08-06 10:22:23 +0100594 default: inUse.includes(type)
595 })
596 );
pineafan63fc5e22022-08-04 22:04:10 +0100597 });
TheCodedProf59772f82023-01-18 22:17:16 -0500598 const selectPane = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents([
TheCodedProfa16d1672023-01-18 18:58:34 -0500599 new Discord.StringSelectMenuBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100600 .addOptions(options)
601 .setCustomId("types")
602 .setMaxValues(ticketTypes.length)
603 .setMinValues(1)
604 .setPlaceholder("Select types to use")
pineafan63fc5e22022-08-04 22:04:10 +0100605 ]);
pineafanc6158ab2022-06-17 16:34:07 +0100606 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100607 embeds: [
608 new EmojiEmbed()
609 .setTitle("Tickets > Types")
610 .setDescription(
611 "**Default types enabled**\n\n" +
612 "**Types in use:**\n" +
613 inUse
Skyler Grey11236ba2022-08-08 21:13:33 +0100614 .map((t) => `> ${getEmojiByName("TICKETS." + t.toUpperCase())} ${capitalize(t)}`)
Skyler Grey75ea9172022-08-06 10:22:23 +0100615 .join("\n")
616 )
617 .setStatus("Success")
618 .setEmoji("GUILD.TICKET.OPEN")
619 ],
620 components: [
pineafan6702cef2022-06-13 17:52:37 +0100621 selectPane,
TheCodedProf59772f82023-01-18 22:17:16 -0500622 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400623 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100624 .setLabel("Back")
625 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400626 .setStyle(ButtonStyle.Primary)
pineafan6702cef2022-06-13 17:52:37 +0100627 .setCustomId("back"),
TheCodedProf21c08592022-09-13 14:14:43 -0400628 new ButtonBuilder()
pineafan6702cef2022-06-13 17:52:37 +0100629 .setLabel("Switch to custom types")
TheCodedProf21c08592022-09-13 14:14:43 -0400630 .setStyle(ButtonStyle.Secondary)
pineafan63fc5e22022-08-04 22:04:10 +0100631 .setCustomId("switchToCustom")
pineafan6702cef2022-06-13 17:52:37 +0100632 ])
633 ]
634 });
635 }
636 let i;
637 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000638 i = await m.awaitMessageComponent({
639 time: 300000,
640 filter: (i) => { return i.user.id === interaction.user.id && i.channel!.id === interaction.channel!.id }
641 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100642 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100643 timedOut = true;
644 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100645 }
TheCodedProf59772f82023-01-18 22:17:16 -0500646 if ((i.component as StringSelectMenuComponent).customId === "types") {
pineafan63fc5e22022-08-04 22:04:10 +0100647 i.deferUpdate();
TheCodedProf59772f82023-01-18 22:17:16 -0500648 const types = toHexInteger((i as StringSelectMenuInteraction).values, ticketTypes);
649 await client.database.guilds.write(interaction.guild!.id, {
Skyler Grey75ea9172022-08-06 10:22:23 +0100650 "tickets.types": types
651 });
pineafan6702cef2022-06-13 17:52:37 +0100652 data.types = types;
TheCodedProf59772f82023-01-18 22:17:16 -0500653 } else if ((i.component as StringSelectMenuComponent).customId === "removeTypes") {
pineafan63fc5e22022-08-04 22:04:10 +0100654 i.deferUpdate();
TheCodedProf59772f82023-01-18 22:17:16 -0500655 const types = (i as StringSelectMenuInteraction).values;
pineafan6702cef2022-06-13 17:52:37 +0100656 let customTypes = data.customTypes;
657 if (customTypes) {
658 customTypes = customTypes.filter((t) => !types.includes(t));
659 customTypes = customTypes.length > 0 ? customTypes : null;
TheCodedProf59772f82023-01-18 22:17:16 -0500660 await client.database.guilds.write(interaction.guild!.id, {
Skyler Grey75ea9172022-08-06 10:22:23 +0100661 "tickets.customTypes": customTypes
662 });
pineafan6702cef2022-06-13 17:52:37 +0100663 data.customTypes = customTypes;
664 }
TheCodedProf59772f82023-01-18 22:17:16 -0500665 } else if ((i.component as ButtonComponent).customId === "addType") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100666 await i.showModal(
TheCodedProf59772f82023-01-18 22:17:16 -0500667 new Discord.ModalBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100668 .setCustomId("modal")
669 .setTitle("Enter a name for the new type")
670 .addComponents(
TheCodedProf59772f82023-01-18 22:17:16 -0500671 new ActionRowBuilder<TextInputBuilder>().addComponents(
672 new TextInputBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100673 .setCustomId("type")
674 .setLabel("Name")
675 .setMaxLength(100)
676 .setMinLength(1)
677 .setPlaceholder('E.g. "Server Idea"')
678 .setRequired(true)
TheCodedProf59772f82023-01-18 22:17:16 -0500679 .setStyle(Discord.TextInputStyle.Short)
Skyler Grey75ea9172022-08-06 10:22:23 +0100680 )
681 )
682 );
pineafan6702cef2022-06-13 17:52:37 +0100683 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100684 embeds: [
685 new EmojiEmbed()
686 .setTitle("Tickets > Types")
Skyler Grey11236ba2022-08-08 21:13:33 +0100687 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100688 .setStatus("Success")
689 .setEmoji("GUILD.TICKET.OPEN")
690 ],
691 components: [
TheCodedProf59772f82023-01-18 22:17:16 -0500692 new ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400693 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100694 .setLabel("Back")
695 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400696 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100697 .setCustomId("back")
698 ])
699 ]
pineafan6702cef2022-06-13 17:52:37 +0100700 });
pineafan4edb7762022-06-26 19:21:04 +0100701 let out;
pineafan6702cef2022-06-13 17:52:37 +0100702 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100703 out = await modalInteractionCollector(
704 m,
TheCodedProf59772f82023-01-18 22:17:16 -0500705 (m) => m.channel!.id === interaction.channel!.id,
Skyler Grey75ea9172022-08-06 10:22:23 +0100706 (m) => m.customId === "addType"
707 );
708 } catch (e) {
709 continue;
710 }
TheCodedProf59772f82023-01-18 22:17:16 -0500711 out = out as ModalSubmitInteraction;
PineaFan638eb132023-01-19 10:41:22 +0000712 let toAdd = out.fields.getTextInputValue("type");
713 if (!toAdd) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100714 continue;
715 }
PineaFan638eb132023-01-19 10:41:22 +0000716 toAdd = toAdd.substring(0, 80);
717 try {
718 await client.database.guilds.append(interaction.guild!.id, "tickets.customTypes", toAdd);
719 } catch {
720 continue;
721 }
722 data.customTypes = data.customTypes ?? [];
723 if (!data.customTypes.includes(toAdd)) {
724 data.customTypes.push(toAdd);
725 }
TheCodedProf59772f82023-01-18 22:17:16 -0500726 } else if ((i.component as ButtonComponent).customId === "switchToDefault") {
pineafan63fc5e22022-08-04 22:04:10 +0100727 i.deferUpdate();
TheCodedProf59772f82023-01-18 22:17:16 -0500728 await client.database.guilds.write(interaction.guild!.id, { "tickets.useCustom": false }, []);
pineafan6702cef2022-06-13 17:52:37 +0100729 data.useCustom = false;
TheCodedProf59772f82023-01-18 22:17:16 -0500730 } else if ((i.component as ButtonComponent).customId === "switchToCustom") {
pineafan63fc5e22022-08-04 22:04:10 +0100731 i.deferUpdate();
TheCodedProf59772f82023-01-18 22:17:16 -0500732 await client.database.guilds.write(interaction.guild!.id, { "tickets.useCustom": true }, []);
pineafan6702cef2022-06-13 17:52:37 +0100733 data.useCustom = true;
734 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100735 i.deferUpdate();
Skyler Greyad002172022-08-16 18:48:26 +0100736 backPressed = true;
pineafan6702cef2022-06-13 17:52:37 +0100737 }
738 }
pineafan63fc5e22022-08-04 22:04:10 +0100739 return data;
pineafan6702cef2022-06-13 17:52:37 +0100740}
741
Skyler Grey1a67e182022-08-04 23:05:44 +0100742const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100743 const member = interaction.member as Discord.GuildMember;
PineaFana00db1b2023-01-02 15:32:54 +0000744 if (!member.permissions.has("ManageGuild"))
PineaFan0d06edc2023-01-17 22:10:31 +0000745 return "You must have the *Manage Server* permission to use this command";
pineafan6702cef2022-06-13 17:52:37 +0100746 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100747};
pineafan4f164f32022-02-26 22:07:12 +0000748
749export { command };
750export { callback };
Skyler Grey1a67e182022-08-04 23:05:44 +0100751export { check };