blob: cceadae05f4cadca282acf2885059a9a88250728 [file] [log] [blame]
pineafan63fc5e22022-08-04 22:04:10 +01001import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
Skyler Grey75ea9172022-08-06 10:22:23 +01002import Discord, {
3 CommandInteraction,
pineafan3a02ea32022-08-11 21:35:04 +01004 Interaction,
Skyler Grey75ea9172022-08-06 10:22:23 +01005 Message,
TheCodedProf21c08592022-09-13 14:14:43 -04006 ActionRowBuilder,
7 Component,
8 ButtonBuilder,
Skyler Grey75ea9172022-08-06 10:22:23 +01009 MessageComponentInteraction,
TheCodedProf21c08592022-09-13 14:14:43 -040010 SelectMenuBuilder,
pineafan3a02ea32022-08-11 21:35:04 +010011 ModalSubmitInteraction,
Skyler Grey75ea9172022-08-06 10:22:23 +010012 Role,
13 SelectMenuInteraction,
TheCodedProf21c08592022-09-13 14:14:43 -040014 TextInputComponent,
15 ButtonStyle
Skyler Grey75ea9172022-08-06 10:22:23 +010016} from "discord.js";
pineafanda6e5342022-07-03 10:03:16 +010017import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
18import confirmationMessage from "../../utils/confirmationMessage.js";
19import getEmojiByName from "../../utils/getEmojiByName.js";
pineafan3a02ea32022-08-11 21:35:04 +010020import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
pineafanda6e5342022-07-03 10:03:16 +010021import client from "../../utils/client.js";
pineafan63fc5e22022-08-04 22:04:10 +010022import { modalInteractionCollector } from "../../utils/dualCollector.js";
pineafan4f164f32022-02-26 22:07:12 +000023
24const command = (builder: SlashCommandSubcommandBuilder) =>
25 builder
pineafan63fc5e22022-08-04 22:04:10 +010026 .setName("verify")
27 .setDescription("Manage the role given after typing /verify")
Skyler Grey75ea9172022-08-06 10:22:23 +010028 .addRoleOption((option) =>
Skyler Grey11236ba2022-08-08 21:13:33 +010029 option.setName("role").setDescription("The role to give after verifying").setRequired(false)
Skyler Grey75ea9172022-08-06 10:22:23 +010030 );
pineafan4f164f32022-02-26 22:07:12 +000031
pineafan3a02ea32022-08-11 21:35:04 +010032const callback = async (interaction: CommandInteraction): Promise<unknown> => {
PineaFana00db1b2023-01-02 15:32:54 +000033 if (!interaction.guild) return;
Skyler Grey75ea9172022-08-06 10:22:23 +010034 const m = (await interaction.reply({
35 embeds: LoadingEmbed,
36 ephemeral: true,
37 fetchReply: true
38 })) as Message;
pineafan6702cef2022-06-13 17:52:37 +010039 if (interaction.options.getRole("role")) {
Skyler Grey1a67e182022-08-04 23:05:44 +010040 let role: Role;
pineafan6702cef2022-06-13 17:52:37 +010041 try {
Skyler Grey1a67e182022-08-04 23:05:44 +010042 role = interaction.options.getRole("role") as Role;
pineafan6702cef2022-06-13 17:52:37 +010043 } catch {
Skyler Grey75ea9172022-08-06 10:22:23 +010044 return await interaction.editReply({
45 embeds: [
46 new EmojiEmbed()
47 .setEmoji("GUILD.ROLES.DELETE")
48 .setTitle("Verify Role")
Skyler Grey11236ba2022-08-08 21:13:33 +010049 .setDescription("The role you provided is not a valid role")
Skyler Grey75ea9172022-08-06 10:22:23 +010050 .setStatus("Danger")
51 ]
52 });
pineafan6702cef2022-06-13 17:52:37 +010053 }
pineafan63fc5e22022-08-04 22:04:10 +010054 role = role as Discord.Role;
PineaFana00db1b2023-01-02 15:32:54 +000055 if (role.guild.id !== interaction.guild.id) {
Skyler Grey75ea9172022-08-06 10:22:23 +010056 return interaction.editReply({
57 embeds: [
58 new EmojiEmbed()
59 .setTitle("Verify Role")
60 .setDescription("You must choose a role in this server")
61 .setStatus("Danger")
62 .setEmoji("GUILD.ROLES.DELETE")
63 ]
64 });
pineafan6702cef2022-06-13 17:52:37 +010065 }
pineafan63fc5e22022-08-04 22:04:10 +010066 const confirmation = await new confirmationMessage(interaction)
pineafan62ce1922022-08-25 20:34:45 +010067 .setEmoji("GUILD.ROLES.EDIT", "GUILD.ROLES.DELETE")
pineafan6702cef2022-06-13 17:52:37 +010068 .setTitle("Verify Role")
Skyler Grey11236ba2022-08-08 21:13:33 +010069 .setDescription(`Are you sure you want to set the verify role to <@&${role.id}>?`)
pineafan6702cef2022-06-13 17:52:37 +010070 .setColor("Warning")
71 .setInverted(true)
pineafan63fc5e22022-08-04 22:04:10 +010072 .send(true);
73 if (confirmation.cancelled) return;
pineafan6702cef2022-06-13 17:52:37 +010074 if (confirmation.success) {
75 try {
PineaFana00db1b2023-01-02 15:32:54 +000076 await client.database.guilds.write(interaction.guild.id, {
Skyler Grey75ea9172022-08-06 10:22:23 +010077 "verify.role": role.id,
78 "verify.enabled": true
79 });
Skyler Grey11236ba2022-08-08 21:13:33 +010080 const { log, NucleusColors, entry, renderUser, renderRole } = client.logger;
pineafan63fc5e22022-08-04 22:04:10 +010081 const data = {
Skyler Grey75ea9172022-08-06 10:22:23 +010082 meta: {
pineafan63fc5e22022-08-04 22:04:10 +010083 type: "verifyRoleChanged",
84 displayName: "Verify Role Changed",
85 calculateType: "nucleusSettingsUpdated",
86 color: NucleusColors.green,
87 emoji: "CONTROL.BLOCKTICK",
88 timestamp: new Date().getTime()
89 },
90 list: {
Skyler Grey11236ba2022-08-08 21:13:33 +010091 memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
92 changedBy: entry(interaction.user.id, renderUser(interaction.user)),
pineafan63fc5e22022-08-04 22:04:10 +010093 role: entry(role.id, renderRole(role))
94 },
95 hidden: {
PineaFana00db1b2023-01-02 15:32:54 +000096 guild: interaction.guild.id
pineafanda6e5342022-07-03 10:03:16 +010097 }
pineafan63fc5e22022-08-04 22:04:10 +010098 };
99 log(data);
pineafan6702cef2022-06-13 17:52:37 +0100100 } catch (e) {
pineafan63fc5e22022-08-04 22:04:10 +0100101 console.log(e);
Skyler Grey75ea9172022-08-06 10:22:23 +0100102 return interaction.editReply({
103 embeds: [
104 new EmojiEmbed()
105 .setTitle("Verify Role")
Skyler Grey11236ba2022-08-08 21:13:33 +0100106 .setDescription("Something went wrong while setting the verify role")
Skyler Grey75ea9172022-08-06 10:22:23 +0100107 .setStatus("Danger")
108 .setEmoji("GUILD.ROLES.DELETE")
109 ],
110 components: []
111 });
pineafan6702cef2022-06-13 17:52:37 +0100112 }
113 } else {
Skyler Grey75ea9172022-08-06 10:22:23 +0100114 return interaction.editReply({
115 embeds: [
116 new EmojiEmbed()
117 .setTitle("Verify Role")
118 .setDescription("No changes were made")
119 .setStatus("Success")
120 .setEmoji("GUILD.ROLES.CREATE")
121 ],
122 components: []
123 });
pineafan6702cef2022-06-13 17:52:37 +0100124 }
125 }
126 let clicks = 0;
PineaFana00db1b2023-01-02 15:32:54 +0000127 const data = await client.database.guilds.read(interaction.guild.id);
pineafan6702cef2022-06-13 17:52:37 +0100128 let role = data.verify.role;
Skyler Greyad002172022-08-16 18:48:26 +0100129
130 let timedOut = false;
131 while (!timedOut) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100132 await interaction.editReply({
133 embeds: [
134 new EmojiEmbed()
135 .setTitle("Verify Role")
136 .setDescription(
Skyler Grey11236ba2022-08-08 21:13:33 +0100137 role ? `Your verify role is currently set to <@&${role}>` : "You have not set a verify role"
Skyler Grey75ea9172022-08-06 10:22:23 +0100138 )
139 .setStatus("Success")
140 .setEmoji("GUILD.ROLES.CREATE")
141 ],
142 components: [
TheCodedProf21c08592022-09-13 14:14:43 -0400143 new ActionRowBuilder().addComponents([
144 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100145 .setCustomId("clear")
Skyler Grey11236ba2022-08-08 21:13:33 +0100146 .setLabel(clicks ? "Click again to confirm" : "Reset role")
147 .setEmoji(getEmojiByName(clicks ? "TICKETS.ISSUE" : "CONTROL.CROSS", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400148 .setStyle(ButtonStyle.Danger)
Skyler Grey75ea9172022-08-06 10:22:23 +0100149 .setDisabled(!role),
TheCodedProf21c08592022-09-13 14:14:43 -0400150 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100151 .setCustomId("send")
152 .setLabel("Add verify button")
153 .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400154 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100155 ])
156 ]
157 });
Skyler Grey1a67e182022-08-04 23:05:44 +0100158 let i: MessageComponentInteraction;
pineafan6702cef2022-06-13 17:52:37 +0100159 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100160 i = await m.awaitMessageComponent({ time: 300000 });
161 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100162 timedOut = true;
163 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100164 }
pineafan63fc5e22022-08-04 22:04:10 +0100165 i.deferUpdate();
TheCodedProf21c08592022-09-13 14:14:43 -0400166 if ((i.component as Component).customId === "clear") {
pineafan6702cef2022-06-13 17:52:37 +0100167 clicks += 1;
pineafane23c4ec2022-07-27 21:56:27 +0100168 if (clicks === 2) {
pineafan6702cef2022-06-13 17:52:37 +0100169 clicks = 0;
PineaFana00db1b2023-01-02 15:32:54 +0000170 await client.database.guilds.write(interaction.guild.id, null, ["verify.role", "verify.enabled"]);
pineafan6702cef2022-06-13 17:52:37 +0100171 role = undefined;
172 }
TheCodedProf21c08592022-09-13 14:14:43 -0400173 } else if ((i.component as Component).customId === "send") {
pineafan41d93562022-07-30 22:10:15 +0100174 const verifyMessages = [
Skyler Grey75ea9172022-08-06 10:22:23 +0100175 {
176 label: "Verify",
177 description: "Click the button below to get verified"
178 },
179 {
180 label: "Get verified",
Skyler Grey11236ba2022-08-08 21:13:33 +0100181 description: "To get access to the rest of the server, click the button below"
Skyler Grey75ea9172022-08-06 10:22:23 +0100182 },
183 {
184 label: "Ready to verify?",
185 description: "Click the button below to verify yourself"
186 }
pineafan63fc5e22022-08-04 22:04:10 +0100187 ];
Skyler Greyad002172022-08-16 18:48:26 +0100188 let innerTimedOut = false;
189 let templateSelected = false;
190 while (!innerTimedOut && !templateSelected) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100191 await interaction.editReply({
192 embeds: [
193 new EmojiEmbed()
194 .setTitle("Verify Button")
Skyler Grey11236ba2022-08-08 21:13:33 +0100195 .setDescription("Select a message template to send in this channel")
Skyler Grey75ea9172022-08-06 10:22:23 +0100196 .setFooter({
Skyler Grey11236ba2022-08-08 21:13:33 +0100197 text: role ? "" : "You do no have a verify role set so the button will not work."
Skyler Grey75ea9172022-08-06 10:22:23 +0100198 })
199 .setStatus(role ? "Success" : "Warning")
200 .setEmoji("GUILD.ROLES.CREATE")
201 ],
202 components: [
TheCodedProf21c08592022-09-13 14:14:43 -0400203 new ActionRowBuilder().addComponents([
204 new SelectMenuBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100205 .setOptions(
206 verifyMessages.map(
207 (
208 t: {
209 label: string;
210 description: string;
211 value?: string;
212 },
213 index
214 ) => {
215 t.value = index.toString();
216 return t as {
217 value: string;
218 label: string;
219 description: string;
220 };
221 }
222 )
223 )
224 .setCustomId("template")
225 .setMaxValues(1)
226 .setMinValues(1)
227 .setPlaceholder("Select a message template")
228 ]),
TheCodedProf21c08592022-09-13 14:14:43 -0400229 new ActionRowBuilder().addComponents([
230 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100231 .setCustomId("back")
232 .setLabel("Back")
233 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400234 .setStyle(ButtonStyle.Danger),
235 new ButtonBuilder().setCustomId("blank").setLabel("Empty").setStyle(ButtonStyle.Secondary),
236 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100237 .setCustomId("custom")
238 .setLabel("Custom")
239 .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400240 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100241 ])
242 ]
243 });
Skyler Grey1a67e182022-08-04 23:05:44 +0100244 let i: MessageComponentInteraction;
pineafan41d93562022-07-30 22:10:15 +0100245 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100246 i = await m.awaitMessageComponent({ time: 300000 });
247 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100248 innerTimedOut = true;
249 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100250 }
TheCodedProf21c08592022-09-13 14:14:43 -0400251 if ((i.component as Component).customId === "template") {
pineafan63fc5e22022-08-04 22:04:10 +0100252 i.deferUpdate();
pineafan3a02ea32022-08-11 21:35:04 +0100253 await interaction.channel!.send({
Skyler Grey75ea9172022-08-06 10:22:23 +0100254 embeds: [
255 new EmojiEmbed()
pineafan3a02ea32022-08-11 21:35:04 +0100256 .setTitle(verifyMessages[parseInt((i as SelectMenuInteraction).values[0]!)]!.label)
Skyler Grey75ea9172022-08-06 10:22:23 +0100257 .setDescription(
pineafan3a02ea32022-08-11 21:35:04 +0100258 verifyMessages[parseInt((i as SelectMenuInteraction).values[0]!)]!.description
Skyler Grey75ea9172022-08-06 10:22:23 +0100259 )
260 .setStatus("Success")
261 .setEmoji("CONTROL.BLOCKTICK")
262 ],
263 components: [
TheCodedProf21c08592022-09-13 14:14:43 -0400264 new ActionRowBuilder().addComponents([
265 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100266 .setLabel("Verify")
Skyler Grey11236ba2022-08-08 21:13:33 +0100267 .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400268 .setStyle(ButtonStyle.Success)
Skyler Grey75ea9172022-08-06 10:22:23 +0100269 .setCustomId("verifybutton")
270 ])
271 ]
272 });
Skyler Greyad002172022-08-16 18:48:26 +0100273 templateSelected = true;
274 continue;
TheCodedProf21c08592022-09-13 14:14:43 -0400275 } else if ((i.component as Component).customId === "blank") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100276 i.deferUpdate();
pineafan3a02ea32022-08-11 21:35:04 +0100277 await interaction.channel!.send({
Skyler Grey75ea9172022-08-06 10:22:23 +0100278 components: [
TheCodedProf21c08592022-09-13 14:14:43 -0400279 new ActionRowBuilder().addComponents([
280 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100281 .setLabel("Verify")
Skyler Grey11236ba2022-08-08 21:13:33 +0100282 .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400283 .setStyle(ButtonStyle.Success)
Skyler Grey75ea9172022-08-06 10:22:23 +0100284 .setCustomId("verifybutton")
285 ])
286 ]
287 });
Skyler Greyad002172022-08-16 18:48:26 +0100288 templateSelected = true;
289 continue;
TheCodedProf21c08592022-09-13 14:14:43 -0400290 } else if ((i.component as Component).customId === "custom") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100291 await i.showModal(
292 new Discord.Modal()
293 .setCustomId("modal")
294 .setTitle("Enter embed details")
295 .addComponents(
TheCodedProf21c08592022-09-13 14:14:43 -0400296 new ActionRowBuilder<TextInputComponent>().addComponents(
Skyler Grey75ea9172022-08-06 10:22:23 +0100297 new TextInputComponent()
298 .setCustomId("title")
299 .setLabel("Title")
300 .setMaxLength(256)
301 .setRequired(true)
302 .setStyle("SHORT")
303 ),
TheCodedProf21c08592022-09-13 14:14:43 -0400304 new ActionRowBuilder<TextInputComponent>().addComponents(
Skyler Grey75ea9172022-08-06 10:22:23 +0100305 new TextInputComponent()
306 .setCustomId("description")
307 .setLabel("Description")
308 .setMaxLength(4000)
309 .setRequired(true)
310 .setStyle("PARAGRAPH")
311 )
312 )
313 );
pineafan41d93562022-07-30 22:10:15 +0100314 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100315 embeds: [
316 new EmojiEmbed()
317 .setTitle("Verify Button")
Skyler Grey11236ba2022-08-08 21:13:33 +0100318 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100319 .setStatus("Success")
320 .setEmoji("GUILD.TICKET.OPEN")
321 ],
322 components: [
TheCodedProf21c08592022-09-13 14:14:43 -0400323 new ActionRowBuilder().addComponents([
324 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100325 .setLabel("Back")
Skyler Grey11236ba2022-08-08 21:13:33 +0100326 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400327 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100328 .setCustomId("back")
329 ])
330 ]
pineafan41d93562022-07-30 22:10:15 +0100331 });
332 let out;
333 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100334 out = await modalInteractionCollector(
335 m,
pineafan3a02ea32022-08-11 21:35:04 +0100336 (m: Interaction) =>
337 (m as MessageComponentInteraction | ModalSubmitInteraction).channelId ===
338 interaction.channelId,
Skyler Grey75ea9172022-08-06 10:22:23 +0100339 (m) => m.customId === "modify"
340 );
341 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100342 innerTimedOut = true;
pineafan3a02ea32022-08-11 21:35:04 +0100343 continue;
Skyler Greyad002172022-08-16 18:48:26 +0100344 }
345 if (out !== null && out instanceof ModalSubmitInteraction) {
pineafan63fc5e22022-08-04 22:04:10 +0100346 const title = out.fields.getTextInputValue("title");
Skyler Grey11236ba2022-08-08 21:13:33 +0100347 const description = out.fields.getTextInputValue("description");
pineafan3a02ea32022-08-11 21:35:04 +0100348 await interaction.channel!.send({
Skyler Grey75ea9172022-08-06 10:22:23 +0100349 embeds: [
350 new EmojiEmbed()
351 .setTitle(title)
352 .setDescription(description)
353 .setStatus("Success")
354 .setEmoji("CONTROL.BLOCKTICK")
355 ],
356 components: [
TheCodedProf21c08592022-09-13 14:14:43 -0400357 new ActionRowBuilder().addComponents([
358 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100359 .setLabel("Verify")
Skyler Grey11236ba2022-08-08 21:13:33 +0100360 .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400361 .setStyle(ButtonStyle.Success)
Skyler Grey75ea9172022-08-06 10:22:23 +0100362 .setCustomId("verifybutton")
363 ])
364 ]
365 });
Skyler Greyad002172022-08-16 18:48:26 +0100366 templateSelected = true;
Skyler Grey75ea9172022-08-06 10:22:23 +0100367 }
pineafan41d93562022-07-30 22:10:15 +0100368 }
369 }
pineafan6702cef2022-06-13 17:52:37 +0100370 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100371 i.deferUpdate();
pineafan41d93562022-07-30 22:10:15 +0100372 break;
pineafan6702cef2022-06-13 17:52:37 +0100373 }
374 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100375 await interaction.editReply({
376 embeds: [m.embeds[0]!.setFooter({ text: "Message closed" })],
377 components: []
378 });
pineafan63fc5e22022-08-04 22:04:10 +0100379};
pineafan4f164f32022-02-26 22:07:12 +0000380
Skyler Grey1a67e182022-08-04 23:05:44 +0100381const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100382 const member = interaction.member as Discord.GuildMember;
PineaFana00db1b2023-01-02 15:32:54 +0000383 if (!member.permissions.has("ManageGuild"))
pineafan3a02ea32022-08-11 21:35:04 +0100384 throw new Error("You must have the *Manage Server* permission to use this command");
pineafan4f164f32022-02-26 22:07:12 +0000385 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100386};
pineafan4f164f32022-02-26 22:07:12 +0000387
388export { command };
389export { callback };
pineafan6702cef2022-06-13 17:52:37 +0100390export { check };