blob: aa8227fe173ef6fdf01d179559a691c02fb3f7de [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,
6 MessageActionRow,
7 MessageActionRowComponent,
8 MessageButton,
9 MessageComponentInteraction,
Skyler Grey75ea9172022-08-06 10:22:23 +010010 MessageSelectMenu,
pineafan3a02ea32022-08-11 21:35:04 +010011 ModalSubmitInteraction,
Skyler Grey75ea9172022-08-06 10:22:23 +010012 Role,
13 SelectMenuInteraction,
14 TextInputComponent
15} from "discord.js";
pineafanda6e5342022-07-03 10:03:16 +010016import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
17import confirmationMessage from "../../utils/confirmationMessage.js";
18import getEmojiByName from "../../utils/getEmojiByName.js";
pineafan3a02ea32022-08-11 21:35:04 +010019import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
pineafanda6e5342022-07-03 10:03:16 +010020import client from "../../utils/client.js";
pineafan63fc5e22022-08-04 22:04:10 +010021import { modalInteractionCollector } from "../../utils/dualCollector.js";
pineafan4f164f32022-02-26 22:07:12 +000022
23const command = (builder: SlashCommandSubcommandBuilder) =>
24 builder
pineafan63fc5e22022-08-04 22:04:10 +010025 .setName("verify")
26 .setDescription("Manage the role given after typing /verify")
Skyler Grey75ea9172022-08-06 10:22:23 +010027 .addRoleOption((option) =>
Skyler Grey11236ba2022-08-08 21:13:33 +010028 option.setName("role").setDescription("The role to give after verifying").setRequired(false)
Skyler Grey75ea9172022-08-06 10:22:23 +010029 );
pineafan4f164f32022-02-26 22:07:12 +000030
pineafan3a02ea32022-08-11 21:35:04 +010031const callback = async (interaction: CommandInteraction): Promise<unknown> => {
Skyler Grey75ea9172022-08-06 10:22:23 +010032 const m = (await interaction.reply({
33 embeds: LoadingEmbed,
34 ephemeral: true,
35 fetchReply: true
36 })) as Message;
pineafan6702cef2022-06-13 17:52:37 +010037 if (interaction.options.getRole("role")) {
Skyler Grey1a67e182022-08-04 23:05:44 +010038 let role: Role;
pineafan6702cef2022-06-13 17:52:37 +010039 try {
Skyler Grey1a67e182022-08-04 23:05:44 +010040 role = interaction.options.getRole("role") as Role;
pineafan6702cef2022-06-13 17:52:37 +010041 } catch {
Skyler Grey75ea9172022-08-06 10:22:23 +010042 return await interaction.editReply({
43 embeds: [
44 new EmojiEmbed()
45 .setEmoji("GUILD.ROLES.DELETE")
46 .setTitle("Verify Role")
Skyler Grey11236ba2022-08-08 21:13:33 +010047 .setDescription("The role you provided is not a valid role")
Skyler Grey75ea9172022-08-06 10:22:23 +010048 .setStatus("Danger")
49 ]
50 });
pineafan6702cef2022-06-13 17:52:37 +010051 }
pineafan63fc5e22022-08-04 22:04:10 +010052 role = role as Discord.Role;
pineafan3a02ea32022-08-11 21:35:04 +010053 if (role.guild.id !== interaction.guild!.id) {
Skyler Grey75ea9172022-08-06 10:22:23 +010054 return interaction.editReply({
55 embeds: [
56 new EmojiEmbed()
57 .setTitle("Verify Role")
58 .setDescription("You must choose a role in this server")
59 .setStatus("Danger")
60 .setEmoji("GUILD.ROLES.DELETE")
61 ]
62 });
pineafan6702cef2022-06-13 17:52:37 +010063 }
pineafan63fc5e22022-08-04 22:04:10 +010064 const confirmation = await new confirmationMessage(interaction)
pineafan6702cef2022-06-13 17:52:37 +010065 .setEmoji("GUILD.ROLES.EDIT")
66 .setTitle("Verify Role")
Skyler Grey11236ba2022-08-08 21:13:33 +010067 .setDescription(`Are you sure you want to set the verify role to <@&${role.id}>?`)
pineafan6702cef2022-06-13 17:52:37 +010068 .setColor("Warning")
69 .setInverted(true)
pineafan63fc5e22022-08-04 22:04:10 +010070 .send(true);
71 if (confirmation.cancelled) return;
pineafan6702cef2022-06-13 17:52:37 +010072 if (confirmation.success) {
73 try {
pineafan3a02ea32022-08-11 21:35:04 +010074 await client.database.guilds.write(interaction.guild!.id, {
Skyler Grey75ea9172022-08-06 10:22:23 +010075 "verify.role": role.id,
76 "verify.enabled": true
77 });
Skyler Grey11236ba2022-08-08 21:13:33 +010078 const { log, NucleusColors, entry, renderUser, renderRole } = client.logger;
pineafan63fc5e22022-08-04 22:04:10 +010079 const data = {
Skyler Grey75ea9172022-08-06 10:22:23 +010080 meta: {
pineafan63fc5e22022-08-04 22:04:10 +010081 type: "verifyRoleChanged",
82 displayName: "Verify Role Changed",
83 calculateType: "nucleusSettingsUpdated",
84 color: NucleusColors.green,
85 emoji: "CONTROL.BLOCKTICK",
86 timestamp: new Date().getTime()
87 },
88 list: {
Skyler Grey11236ba2022-08-08 21:13:33 +010089 memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
90 changedBy: entry(interaction.user.id, renderUser(interaction.user)),
pineafan63fc5e22022-08-04 22:04:10 +010091 role: entry(role.id, renderRole(role))
92 },
93 hidden: {
pineafan3a02ea32022-08-11 21:35:04 +010094 guild: interaction.guild!.id
pineafanda6e5342022-07-03 10:03:16 +010095 }
pineafan63fc5e22022-08-04 22:04:10 +010096 };
97 log(data);
pineafan6702cef2022-06-13 17:52:37 +010098 } catch (e) {
pineafan63fc5e22022-08-04 22:04:10 +010099 console.log(e);
Skyler Grey75ea9172022-08-06 10:22:23 +0100100 return interaction.editReply({
101 embeds: [
102 new EmojiEmbed()
103 .setTitle("Verify Role")
Skyler Grey11236ba2022-08-08 21:13:33 +0100104 .setDescription("Something went wrong while setting the verify role")
Skyler Grey75ea9172022-08-06 10:22:23 +0100105 .setStatus("Danger")
106 .setEmoji("GUILD.ROLES.DELETE")
107 ],
108 components: []
109 });
pineafan6702cef2022-06-13 17:52:37 +0100110 }
111 } else {
Skyler Grey75ea9172022-08-06 10:22:23 +0100112 return interaction.editReply({
113 embeds: [
114 new EmojiEmbed()
115 .setTitle("Verify Role")
116 .setDescription("No changes were made")
117 .setStatus("Success")
118 .setEmoji("GUILD.ROLES.CREATE")
119 ],
120 components: []
121 });
pineafan6702cef2022-06-13 17:52:37 +0100122 }
123 }
124 let clicks = 0;
pineafan3a02ea32022-08-11 21:35:04 +0100125 const data = await client.database.guilds.read(interaction.guild!.id);
pineafan6702cef2022-06-13 17:52:37 +0100126 let role = data.verify.role;
Skyler Greyad002172022-08-16 18:48:26 +0100127
128 let timedOut = false;
129 while (!timedOut) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100130 await interaction.editReply({
131 embeds: [
132 new EmojiEmbed()
133 .setTitle("Verify Role")
134 .setDescription(
Skyler Grey11236ba2022-08-08 21:13:33 +0100135 role ? `Your verify role is currently set to <@&${role}>` : "You have not set a verify role"
Skyler Grey75ea9172022-08-06 10:22:23 +0100136 )
137 .setStatus("Success")
138 .setEmoji("GUILD.ROLES.CREATE")
139 ],
140 components: [
141 new MessageActionRow().addComponents([
142 new MessageButton()
143 .setCustomId("clear")
Skyler Grey11236ba2022-08-08 21:13:33 +0100144 .setLabel(clicks ? "Click again to confirm" : "Reset role")
145 .setEmoji(getEmojiByName(clicks ? "TICKETS.ISSUE" : "CONTROL.CROSS", "id"))
Skyler Grey75ea9172022-08-06 10:22:23 +0100146 .setStyle("DANGER")
147 .setDisabled(!role),
148 new MessageButton()
149 .setCustomId("send")
150 .setLabel("Add verify button")
151 .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
152 .setStyle("PRIMARY")
153 ])
154 ]
155 });
Skyler Grey1a67e182022-08-04 23:05:44 +0100156 let i: MessageComponentInteraction;
pineafan6702cef2022-06-13 17:52:37 +0100157 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100158 i = await m.awaitMessageComponent({ time: 300000 });
159 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100160 timedOut = true;
161 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100162 }
pineafan63fc5e22022-08-04 22:04:10 +0100163 i.deferUpdate();
Skyler Grey1a67e182022-08-04 23:05:44 +0100164 if ((i.component as MessageActionRowComponent).customId === "clear") {
pineafan6702cef2022-06-13 17:52:37 +0100165 clicks += 1;
pineafane23c4ec2022-07-27 21:56:27 +0100166 if (clicks === 2) {
pineafan6702cef2022-06-13 17:52:37 +0100167 clicks = 0;
pineafan3a02ea32022-08-11 21:35:04 +0100168 await client.database.guilds.write(interaction.guild!.id, null, ["verify.role", "verify.enabled"]);
pineafan6702cef2022-06-13 17:52:37 +0100169 role = undefined;
170 }
Skyler Grey11236ba2022-08-08 21:13:33 +0100171 } else if ((i.component as MessageActionRowComponent).customId === "send") {
pineafan41d93562022-07-30 22:10:15 +0100172 const verifyMessages = [
Skyler Grey75ea9172022-08-06 10:22:23 +0100173 {
174 label: "Verify",
175 description: "Click the button below to get verified"
176 },
177 {
178 label: "Get verified",
Skyler Grey11236ba2022-08-08 21:13:33 +0100179 description: "To get access to the rest of the server, click the button below"
Skyler Grey75ea9172022-08-06 10:22:23 +0100180 },
181 {
182 label: "Ready to verify?",
183 description: "Click the button below to verify yourself"
184 }
pineafan63fc5e22022-08-04 22:04:10 +0100185 ];
Skyler Greyad002172022-08-16 18:48:26 +0100186 let innerTimedOut = false;
187 let templateSelected = false;
188 while (!innerTimedOut && !templateSelected) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100189 await interaction.editReply({
190 embeds: [
191 new EmojiEmbed()
192 .setTitle("Verify Button")
Skyler Grey11236ba2022-08-08 21:13:33 +0100193 .setDescription("Select a message template to send in this channel")
Skyler Grey75ea9172022-08-06 10:22:23 +0100194 .setFooter({
Skyler Grey11236ba2022-08-08 21:13:33 +0100195 text: role ? "" : "You do no have a verify role set so the button will not work."
Skyler Grey75ea9172022-08-06 10:22:23 +0100196 })
197 .setStatus(role ? "Success" : "Warning")
198 .setEmoji("GUILD.ROLES.CREATE")
199 ],
200 components: [
201 new MessageActionRow().addComponents([
202 new MessageSelectMenu()
203 .setOptions(
204 verifyMessages.map(
205 (
206 t: {
207 label: string;
208 description: string;
209 value?: string;
210 },
211 index
212 ) => {
213 t.value = index.toString();
214 return t as {
215 value: string;
216 label: string;
217 description: string;
218 };
219 }
220 )
221 )
222 .setCustomId("template")
223 .setMaxValues(1)
224 .setMinValues(1)
225 .setPlaceholder("Select a message template")
226 ]),
227 new MessageActionRow().addComponents([
228 new MessageButton()
229 .setCustomId("back")
230 .setLabel("Back")
231 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
232 .setStyle("DANGER"),
Skyler Grey11236ba2022-08-08 21:13:33 +0100233 new MessageButton().setCustomId("blank").setLabel("Empty").setStyle("SECONDARY"),
Skyler Grey75ea9172022-08-06 10:22:23 +0100234 new MessageButton()
235 .setCustomId("custom")
236 .setLabel("Custom")
237 .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
238 .setStyle("PRIMARY")
239 ])
240 ]
241 });
Skyler Grey1a67e182022-08-04 23:05:44 +0100242 let i: MessageComponentInteraction;
pineafan41d93562022-07-30 22:10:15 +0100243 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100244 i = await m.awaitMessageComponent({ time: 300000 });
245 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100246 innerTimedOut = true;
247 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100248 }
Skyler Grey11236ba2022-08-08 21:13:33 +0100249 if ((i.component as MessageActionRowComponent).customId === "template") {
pineafan63fc5e22022-08-04 22:04:10 +0100250 i.deferUpdate();
pineafan3a02ea32022-08-11 21:35:04 +0100251 await interaction.channel!.send({
Skyler Grey75ea9172022-08-06 10:22:23 +0100252 embeds: [
253 new EmojiEmbed()
pineafan3a02ea32022-08-11 21:35:04 +0100254 .setTitle(verifyMessages[parseInt((i as SelectMenuInteraction).values[0]!)]!.label)
Skyler Grey75ea9172022-08-06 10:22:23 +0100255 .setDescription(
pineafan3a02ea32022-08-11 21:35:04 +0100256 verifyMessages[parseInt((i as SelectMenuInteraction).values[0]!)]!.description
Skyler Grey75ea9172022-08-06 10:22:23 +0100257 )
258 .setStatus("Success")
259 .setEmoji("CONTROL.BLOCKTICK")
260 ],
261 components: [
262 new MessageActionRow().addComponents([
263 new MessageButton()
264 .setLabel("Verify")
Skyler Grey11236ba2022-08-08 21:13:33 +0100265 .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
Skyler Grey75ea9172022-08-06 10:22:23 +0100266 .setStyle("SUCCESS")
267 .setCustomId("verifybutton")
268 ])
269 ]
270 });
Skyler Greyad002172022-08-16 18:48:26 +0100271 templateSelected = true;
272 continue;
Skyler Grey11236ba2022-08-08 21:13:33 +0100273 } else if ((i.component as MessageActionRowComponent).customId === "blank") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100274 i.deferUpdate();
pineafan3a02ea32022-08-11 21:35:04 +0100275 await interaction.channel!.send({
Skyler Grey75ea9172022-08-06 10:22:23 +0100276 components: [
277 new MessageActionRow().addComponents([
278 new MessageButton()
279 .setLabel("Verify")
Skyler Grey11236ba2022-08-08 21:13:33 +0100280 .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
Skyler Grey75ea9172022-08-06 10:22:23 +0100281 .setStyle("SUCCESS")
282 .setCustomId("verifybutton")
283 ])
284 ]
285 });
Skyler Greyad002172022-08-16 18:48:26 +0100286 templateSelected = true;
287 continue;
Skyler Grey11236ba2022-08-08 21:13:33 +0100288 } else if ((i.component as MessageActionRowComponent).customId === "custom") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100289 await i.showModal(
290 new Discord.Modal()
291 .setCustomId("modal")
292 .setTitle("Enter embed details")
293 .addComponents(
294 new MessageActionRow<TextInputComponent>().addComponents(
295 new TextInputComponent()
296 .setCustomId("title")
297 .setLabel("Title")
298 .setMaxLength(256)
299 .setRequired(true)
300 .setStyle("SHORT")
301 ),
302 new MessageActionRow<TextInputComponent>().addComponents(
303 new TextInputComponent()
304 .setCustomId("description")
305 .setLabel("Description")
306 .setMaxLength(4000)
307 .setRequired(true)
308 .setStyle("PARAGRAPH")
309 )
310 )
311 );
pineafan41d93562022-07-30 22:10:15 +0100312 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +0100313 embeds: [
314 new EmojiEmbed()
315 .setTitle("Verify Button")
Skyler Grey11236ba2022-08-08 21:13:33 +0100316 .setDescription("Modal opened. If you can't see it, click back and try again.")
Skyler Grey75ea9172022-08-06 10:22:23 +0100317 .setStatus("Success")
318 .setEmoji("GUILD.TICKET.OPEN")
319 ],
320 components: [
321 new MessageActionRow().addComponents([
322 new MessageButton()
323 .setLabel("Back")
Skyler Grey11236ba2022-08-08 21:13:33 +0100324 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
Skyler Grey75ea9172022-08-06 10:22:23 +0100325 .setStyle("PRIMARY")
326 .setCustomId("back")
327 ])
328 ]
pineafan41d93562022-07-30 22:10:15 +0100329 });
330 let out;
331 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100332 out = await modalInteractionCollector(
333 m,
pineafan3a02ea32022-08-11 21:35:04 +0100334 (m: Interaction) =>
335 (m as MessageComponentInteraction | ModalSubmitInteraction).channelId ===
336 interaction.channelId,
Skyler Grey75ea9172022-08-06 10:22:23 +0100337 (m) => m.customId === "modify"
338 );
339 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100340 innerTimedOut = true;
pineafan3a02ea32022-08-11 21:35:04 +0100341 continue;
Skyler Greyad002172022-08-16 18:48:26 +0100342 }
343 if (out !== null && out instanceof ModalSubmitInteraction) {
pineafan63fc5e22022-08-04 22:04:10 +0100344 const title = out.fields.getTextInputValue("title");
Skyler Grey11236ba2022-08-08 21:13:33 +0100345 const description = out.fields.getTextInputValue("description");
pineafan3a02ea32022-08-11 21:35:04 +0100346 await interaction.channel!.send({
Skyler Grey75ea9172022-08-06 10:22:23 +0100347 embeds: [
348 new EmojiEmbed()
349 .setTitle(title)
350 .setDescription(description)
351 .setStatus("Success")
352 .setEmoji("CONTROL.BLOCKTICK")
353 ],
354 components: [
355 new MessageActionRow().addComponents([
356 new MessageButton()
357 .setLabel("Verify")
Skyler Grey11236ba2022-08-08 21:13:33 +0100358 .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
Skyler Grey75ea9172022-08-06 10:22:23 +0100359 .setStyle("SUCCESS")
360 .setCustomId("verifybutton")
361 ])
362 ]
363 });
Skyler Greyad002172022-08-16 18:48:26 +0100364 templateSelected = true;
Skyler Grey75ea9172022-08-06 10:22:23 +0100365 }
pineafan41d93562022-07-30 22:10:15 +0100366 }
367 }
pineafan6702cef2022-06-13 17:52:37 +0100368 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100369 i.deferUpdate();
pineafan41d93562022-07-30 22:10:15 +0100370 break;
pineafan6702cef2022-06-13 17:52:37 +0100371 }
372 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100373 await interaction.editReply({
374 embeds: [m.embeds[0]!.setFooter({ text: "Message closed" })],
375 components: []
376 });
pineafan63fc5e22022-08-04 22:04:10 +0100377};
pineafan4f164f32022-02-26 22:07:12 +0000378
Skyler Grey1a67e182022-08-04 23:05:44 +0100379const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100380 const member = interaction.member as Discord.GuildMember;
381 if (!member.permissions.has("MANAGE_GUILD"))
pineafan3a02ea32022-08-11 21:35:04 +0100382 throw new Error("You must have the *Manage Server* permission to use this command");
pineafan4f164f32022-02-26 22:07:12 +0000383 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100384};
pineafan4f164f32022-02-26 22:07:12 +0000385
386export { command };
387export { callback };
pineafan6702cef2022-06-13 17:52:37 +0100388export { check };