blob: b3eb11aad027979fe3f183b36b74f26283be595c [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> => {
Skyler Grey75ea9172022-08-06 10:22:23 +010033 const m = (await interaction.reply({
34 embeds: LoadingEmbed,
35 ephemeral: true,
36 fetchReply: true
37 })) as Message;
pineafan6702cef2022-06-13 17:52:37 +010038 if (interaction.options.getRole("role")) {
Skyler Grey1a67e182022-08-04 23:05:44 +010039 let role: Role;
pineafan6702cef2022-06-13 17:52:37 +010040 try {
Skyler Grey1a67e182022-08-04 23:05:44 +010041 role = interaction.options.getRole("role") as Role;
pineafan6702cef2022-06-13 17:52:37 +010042 } catch {
Skyler Grey75ea9172022-08-06 10:22:23 +010043 return await interaction.editReply({
44 embeds: [
45 new EmojiEmbed()
46 .setEmoji("GUILD.ROLES.DELETE")
47 .setTitle("Verify Role")
Skyler Grey11236ba2022-08-08 21:13:33 +010048 .setDescription("The role you provided is not a valid role")
Skyler Grey75ea9172022-08-06 10:22:23 +010049 .setStatus("Danger")
50 ]
51 });
pineafan6702cef2022-06-13 17:52:37 +010052 }
pineafan63fc5e22022-08-04 22:04:10 +010053 role = role as Discord.Role;
pineafan3a02ea32022-08-11 21:35:04 +010054 if (role.guild.id !== interaction.guild!.id) {
Skyler Grey75ea9172022-08-06 10:22:23 +010055 return interaction.editReply({
56 embeds: [
57 new EmojiEmbed()
58 .setTitle("Verify Role")
59 .setDescription("You must choose a role in this server")
60 .setStatus("Danger")
61 .setEmoji("GUILD.ROLES.DELETE")
62 ]
63 });
pineafan6702cef2022-06-13 17:52:37 +010064 }
pineafan63fc5e22022-08-04 22:04:10 +010065 const confirmation = await new confirmationMessage(interaction)
pineafan62ce1922022-08-25 20:34:45 +010066 .setEmoji("GUILD.ROLES.EDIT", "GUILD.ROLES.DELETE")
pineafan6702cef2022-06-13 17:52:37 +010067 .setTitle("Verify Role")
Skyler Grey11236ba2022-08-08 21:13:33 +010068 .setDescription(`Are you sure you want to set the verify role to <@&${role.id}>?`)
pineafan6702cef2022-06-13 17:52:37 +010069 .setColor("Warning")
70 .setInverted(true)
pineafan63fc5e22022-08-04 22:04:10 +010071 .send(true);
72 if (confirmation.cancelled) return;
pineafan6702cef2022-06-13 17:52:37 +010073 if (confirmation.success) {
74 try {
pineafan3a02ea32022-08-11 21:35:04 +010075 await client.database.guilds.write(interaction.guild!.id, {
Skyler Grey75ea9172022-08-06 10:22:23 +010076 "verify.role": role.id,
77 "verify.enabled": true
78 });
Skyler Grey11236ba2022-08-08 21:13:33 +010079 const { log, NucleusColors, entry, renderUser, renderRole } = client.logger;
pineafan63fc5e22022-08-04 22:04:10 +010080 const data = {
Skyler Grey75ea9172022-08-06 10:22:23 +010081 meta: {
pineafan63fc5e22022-08-04 22:04:10 +010082 type: "verifyRoleChanged",
83 displayName: "Verify Role Changed",
84 calculateType: "nucleusSettingsUpdated",
85 color: NucleusColors.green,
86 emoji: "CONTROL.BLOCKTICK",
87 timestamp: new Date().getTime()
88 },
89 list: {
Skyler Grey11236ba2022-08-08 21:13:33 +010090 memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
91 changedBy: entry(interaction.user.id, renderUser(interaction.user)),
pineafan63fc5e22022-08-04 22:04:10 +010092 role: entry(role.id, renderRole(role))
93 },
94 hidden: {
pineafan3a02ea32022-08-11 21:35:04 +010095 guild: interaction.guild!.id
pineafanda6e5342022-07-03 10:03:16 +010096 }
pineafan63fc5e22022-08-04 22:04:10 +010097 };
98 log(data);
pineafan6702cef2022-06-13 17:52:37 +010099 } catch (e) {
pineafan63fc5e22022-08-04 22:04:10 +0100100 console.log(e);
Skyler Grey75ea9172022-08-06 10:22:23 +0100101 return interaction.editReply({
102 embeds: [
103 new EmojiEmbed()
104 .setTitle("Verify Role")
Skyler Grey11236ba2022-08-08 21:13:33 +0100105 .setDescription("Something went wrong while setting the verify role")
Skyler Grey75ea9172022-08-06 10:22:23 +0100106 .setStatus("Danger")
107 .setEmoji("GUILD.ROLES.DELETE")
108 ],
109 components: []
110 });
pineafan6702cef2022-06-13 17:52:37 +0100111 }
112 } else {
Skyler Grey75ea9172022-08-06 10:22:23 +0100113 return interaction.editReply({
114 embeds: [
115 new EmojiEmbed()
116 .setTitle("Verify Role")
117 .setDescription("No changes were made")
118 .setStatus("Success")
119 .setEmoji("GUILD.ROLES.CREATE")
120 ],
121 components: []
122 });
pineafan6702cef2022-06-13 17:52:37 +0100123 }
124 }
125 let clicks = 0;
pineafan3a02ea32022-08-11 21:35:04 +0100126 const data = await client.database.guilds.read(interaction.guild!.id);
pineafan6702cef2022-06-13 17:52:37 +0100127 let role = data.verify.role;
Skyler Greyad002172022-08-16 18:48:26 +0100128
129 let timedOut = false;
130 while (!timedOut) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100131 await interaction.editReply({
132 embeds: [
133 new EmojiEmbed()
134 .setTitle("Verify Role")
135 .setDescription(
Skyler Grey11236ba2022-08-08 21:13:33 +0100136 role ? `Your verify role is currently set to <@&${role}>` : "You have not set a verify role"
Skyler Grey75ea9172022-08-06 10:22:23 +0100137 )
138 .setStatus("Success")
139 .setEmoji("GUILD.ROLES.CREATE")
140 ],
141 components: [
TheCodedProf21c08592022-09-13 14:14:43 -0400142 new ActionRowBuilder().addComponents([
143 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100144 .setCustomId("clear")
Skyler Grey11236ba2022-08-08 21:13:33 +0100145 .setLabel(clicks ? "Click again to confirm" : "Reset role")
146 .setEmoji(getEmojiByName(clicks ? "TICKETS.ISSUE" : "CONTROL.CROSS", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400147 .setStyle(ButtonStyle.Danger)
Skyler Grey75ea9172022-08-06 10:22:23 +0100148 .setDisabled(!role),
TheCodedProf21c08592022-09-13 14:14:43 -0400149 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100150 .setCustomId("send")
151 .setLabel("Add verify button")
152 .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400153 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100154 ])
155 ]
156 });
Skyler Grey1a67e182022-08-04 23:05:44 +0100157 let i: MessageComponentInteraction;
pineafan6702cef2022-06-13 17:52:37 +0100158 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100159 i = await m.awaitMessageComponent({ time: 300000 });
160 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100161 timedOut = true;
162 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100163 }
pineafan63fc5e22022-08-04 22:04:10 +0100164 i.deferUpdate();
TheCodedProf21c08592022-09-13 14:14:43 -0400165 if ((i.component as Component).customId === "clear") {
pineafan6702cef2022-06-13 17:52:37 +0100166 clicks += 1;
pineafane23c4ec2022-07-27 21:56:27 +0100167 if (clicks === 2) {
pineafan6702cef2022-06-13 17:52:37 +0100168 clicks = 0;
pineafan3a02ea32022-08-11 21:35:04 +0100169 await client.database.guilds.write(interaction.guild!.id, null, ["verify.role", "verify.enabled"]);
pineafan6702cef2022-06-13 17:52:37 +0100170 role = undefined;
171 }
TheCodedProf21c08592022-09-13 14:14:43 -0400172 } else if ((i.component as Component).customId === "send") {
pineafan41d93562022-07-30 22:10:15 +0100173 const verifyMessages = [
Skyler Grey75ea9172022-08-06 10:22:23 +0100174 {
175 label: "Verify",
176 description: "Click the button below to get verified"
177 },
178 {
179 label: "Get verified",
Skyler Grey11236ba2022-08-08 21:13:33 +0100180 description: "To get access to the rest of the server, click the button below"
Skyler Grey75ea9172022-08-06 10:22:23 +0100181 },
182 {
183 label: "Ready to verify?",
184 description: "Click the button below to verify yourself"
185 }
pineafan63fc5e22022-08-04 22:04:10 +0100186 ];
Skyler Greyad002172022-08-16 18:48:26 +0100187 let innerTimedOut = false;
188 let templateSelected = false;
189 while (!innerTimedOut && !templateSelected) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100190 await interaction.editReply({
191 embeds: [
192 new EmojiEmbed()
193 .setTitle("Verify Button")
Skyler Grey11236ba2022-08-08 21:13:33 +0100194 .setDescription("Select a message template to send in this channel")
Skyler Grey75ea9172022-08-06 10:22:23 +0100195 .setFooter({
Skyler Grey11236ba2022-08-08 21:13:33 +0100196 text: role ? "" : "You do no have a verify role set so the button will not work."
Skyler Grey75ea9172022-08-06 10:22:23 +0100197 })
198 .setStatus(role ? "Success" : "Warning")
199 .setEmoji("GUILD.ROLES.CREATE")
200 ],
201 components: [
TheCodedProf21c08592022-09-13 14:14:43 -0400202 new ActionRowBuilder().addComponents([
203 new SelectMenuBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100204 .setOptions(
205 verifyMessages.map(
206 (
207 t: {
208 label: string;
209 description: string;
210 value?: string;
211 },
212 index
213 ) => {
214 t.value = index.toString();
215 return t as {
216 value: string;
217 label: string;
218 description: string;
219 };
220 }
221 )
222 )
223 .setCustomId("template")
224 .setMaxValues(1)
225 .setMinValues(1)
226 .setPlaceholder("Select a message template")
227 ]),
TheCodedProf21c08592022-09-13 14:14:43 -0400228 new ActionRowBuilder().addComponents([
229 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100230 .setCustomId("back")
231 .setLabel("Back")
232 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400233 .setStyle(ButtonStyle.Danger),
234 new ButtonBuilder().setCustomId("blank").setLabel("Empty").setStyle(ButtonStyle.Secondary),
235 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100236 .setCustomId("custom")
237 .setLabel("Custom")
238 .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400239 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100240 ])
241 ]
242 });
Skyler Grey1a67e182022-08-04 23:05:44 +0100243 let i: MessageComponentInteraction;
pineafan41d93562022-07-30 22:10:15 +0100244 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100245 i = await m.awaitMessageComponent({ time: 300000 });
246 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100247 innerTimedOut = true;
248 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100249 }
TheCodedProf21c08592022-09-13 14:14:43 -0400250 if ((i.component as Component).customId === "template") {
pineafan63fc5e22022-08-04 22:04:10 +0100251 i.deferUpdate();
pineafan3a02ea32022-08-11 21:35:04 +0100252 await interaction.channel!.send({
Skyler Grey75ea9172022-08-06 10:22:23 +0100253 embeds: [
254 new EmojiEmbed()
pineafan3a02ea32022-08-11 21:35:04 +0100255 .setTitle(verifyMessages[parseInt((i as SelectMenuInteraction).values[0]!)]!.label)
Skyler Grey75ea9172022-08-06 10:22:23 +0100256 .setDescription(
pineafan3a02ea32022-08-11 21:35:04 +0100257 verifyMessages[parseInt((i as SelectMenuInteraction).values[0]!)]!.description
Skyler Grey75ea9172022-08-06 10:22:23 +0100258 )
259 .setStatus("Success")
260 .setEmoji("CONTROL.BLOCKTICK")
261 ],
262 components: [
TheCodedProf21c08592022-09-13 14:14:43 -0400263 new ActionRowBuilder().addComponents([
264 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100265 .setLabel("Verify")
Skyler Grey11236ba2022-08-08 21:13:33 +0100266 .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400267 .setStyle(ButtonStyle.Success)
Skyler Grey75ea9172022-08-06 10:22:23 +0100268 .setCustomId("verifybutton")
269 ])
270 ]
271 });
Skyler Greyad002172022-08-16 18:48:26 +0100272 templateSelected = true;
273 continue;
TheCodedProf21c08592022-09-13 14:14:43 -0400274 } else if ((i.component as Component).customId === "blank") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100275 i.deferUpdate();
pineafan3a02ea32022-08-11 21:35:04 +0100276 await interaction.channel!.send({
Skyler Grey75ea9172022-08-06 10:22:23 +0100277 components: [
TheCodedProf21c08592022-09-13 14:14:43 -0400278 new ActionRowBuilder().addComponents([
279 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100280 .setLabel("Verify")
Skyler Grey11236ba2022-08-08 21:13:33 +0100281 .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400282 .setStyle(ButtonStyle.Success)
Skyler Grey75ea9172022-08-06 10:22:23 +0100283 .setCustomId("verifybutton")
284 ])
285 ]
286 });
Skyler Greyad002172022-08-16 18:48:26 +0100287 templateSelected = true;
288 continue;
TheCodedProf21c08592022-09-13 14:14:43 -0400289 } else if ((i.component as Component).customId === "custom") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100290 await i.showModal(
291 new Discord.Modal()
292 .setCustomId("modal")
293 .setTitle("Enter embed details")
294 .addComponents(
TheCodedProf21c08592022-09-13 14:14:43 -0400295 new ActionRowBuilder<TextInputComponent>().addComponents(
Skyler Grey75ea9172022-08-06 10:22:23 +0100296 new TextInputComponent()
297 .setCustomId("title")
298 .setLabel("Title")
299 .setMaxLength(256)
300 .setRequired(true)
301 .setStyle("SHORT")
302 ),
TheCodedProf21c08592022-09-13 14:14:43 -0400303 new ActionRowBuilder<TextInputComponent>().addComponents(
Skyler Grey75ea9172022-08-06 10:22:23 +0100304 new TextInputComponent()
305 .setCustomId("description")
306 .setLabel("Description")
307 .setMaxLength(4000)
308 .setRequired(true)
309 .setStyle("PARAGRAPH")
310 )
311 )
312 );
pineafan41d93562022-07-30 22:10:15 +0100313 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100314 embeds: [
315 new EmojiEmbed()
316 .setTitle("Verify Button")
Skyler Grey11236ba2022-08-08 21:13:33 +0100317 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100318 .setStatus("Success")
319 .setEmoji("GUILD.TICKET.OPEN")
320 ],
321 components: [
TheCodedProf21c08592022-09-13 14:14:43 -0400322 new ActionRowBuilder().addComponents([
323 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100324 .setLabel("Back")
Skyler Grey11236ba2022-08-08 21:13:33 +0100325 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400326 .setStyle(ButtonStyle.Primary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100327 .setCustomId("back")
328 ])
329 ]
pineafan41d93562022-07-30 22:10:15 +0100330 });
331 let out;
332 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100333 out = await modalInteractionCollector(
334 m,
pineafan3a02ea32022-08-11 21:35:04 +0100335 (m: Interaction) =>
336 (m as MessageComponentInteraction | ModalSubmitInteraction).channelId ===
337 interaction.channelId,
Skyler Grey75ea9172022-08-06 10:22:23 +0100338 (m) => m.customId === "modify"
339 );
340 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100341 innerTimedOut = true;
pineafan3a02ea32022-08-11 21:35:04 +0100342 continue;
Skyler Greyad002172022-08-16 18:48:26 +0100343 }
344 if (out !== null && out instanceof ModalSubmitInteraction) {
pineafan63fc5e22022-08-04 22:04:10 +0100345 const title = out.fields.getTextInputValue("title");
Skyler Grey11236ba2022-08-08 21:13:33 +0100346 const description = out.fields.getTextInputValue("description");
pineafan3a02ea32022-08-11 21:35:04 +0100347 await interaction.channel!.send({
Skyler Grey75ea9172022-08-06 10:22:23 +0100348 embeds: [
349 new EmojiEmbed()
350 .setTitle(title)
351 .setDescription(description)
352 .setStatus("Success")
353 .setEmoji("CONTROL.BLOCKTICK")
354 ],
355 components: [
TheCodedProf21c08592022-09-13 14:14:43 -0400356 new ActionRowBuilder().addComponents([
357 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100358 .setLabel("Verify")
Skyler Grey11236ba2022-08-08 21:13:33 +0100359 .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
TheCodedProf21c08592022-09-13 14:14:43 -0400360 .setStyle(ButtonStyle.Success)
Skyler Grey75ea9172022-08-06 10:22:23 +0100361 .setCustomId("verifybutton")
362 ])
363 ]
364 });
Skyler Greyad002172022-08-16 18:48:26 +0100365 templateSelected = true;
Skyler Grey75ea9172022-08-06 10:22:23 +0100366 }
pineafan41d93562022-07-30 22:10:15 +0100367 }
368 }
pineafan6702cef2022-06-13 17:52:37 +0100369 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100370 i.deferUpdate();
pineafan41d93562022-07-30 22:10:15 +0100371 break;
pineafan6702cef2022-06-13 17:52:37 +0100372 }
373 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100374 await interaction.editReply({
375 embeds: [m.embeds[0]!.setFooter({ text: "Message closed" })],
376 components: []
377 });
pineafan63fc5e22022-08-04 22:04:10 +0100378};
pineafan4f164f32022-02-26 22:07:12 +0000379
Skyler Grey1a67e182022-08-04 23:05:44 +0100380const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100381 const member = interaction.member as Discord.GuildMember;
382 if (!member.permissions.has("MANAGE_GUILD"))
pineafan3a02ea32022-08-11 21:35:04 +0100383 throw new Error("You must have the *Manage Server* permission to use this command");
pineafan4f164f32022-02-26 22:07:12 +0000384 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100385};
pineafan4f164f32022-02-26 22:07:12 +0000386
387export { command };
388export { callback };
pineafan6702cef2022-06-13 17:52:37 +0100389export { check };