blob: d846511a514ef7392c2368a49e263ce757a6c76b [file] [log] [blame]
pineafan63fc5e22022-08-04 22:04:10 +01001import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
Skyler Grey1a67e182022-08-04 23:05:44 +01002import Discord, { CommandInteraction, Message, MessageActionRow, MessageActionRowComponent, MessageButton, MessageComponentInteraction, MessageSelectMenu, Role, SelectMenuInteraction, TextInputComponent } from "discord.js";
pineafanda6e5342022-07-03 10:03:16 +01003import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
4import confirmationMessage from "../../utils/confirmationMessage.js";
5import getEmojiByName from "../../utils/getEmojiByName.js";
Skyler Grey1a67e182022-08-04 23:05:44 +01006import { Embed, SlashCommandSubcommandBuilder } from "@discordjs/builders";
pineafanda6e5342022-07-03 10:03:16 +01007import client from "../../utils/client.js";
pineafan63fc5e22022-08-04 22:04:10 +01008import { modalInteractionCollector } from "../../utils/dualCollector.js";
pineafan4f164f32022-02-26 22:07:12 +00009
10const command = (builder: SlashCommandSubcommandBuilder) =>
11 builder
pineafan63fc5e22022-08-04 22:04:10 +010012 .setName("verify")
13 .setDescription("Manage the role given after typing /verify")
14 .addRoleOption(option => option.setName("role").setDescription("The role to give after verifying").setRequired(false));
pineafan4f164f32022-02-26 22:07:12 +000015
Skyler Grey1a67e182022-08-04 23:05:44 +010016const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
17 const m = await interaction.reply({embeds: LoadingEmbed, ephemeral: true, fetchReply: true});
pineafan6702cef2022-06-13 17:52:37 +010018 if (interaction.options.getRole("role")) {
Skyler Grey1a67e182022-08-04 23:05:44 +010019 let role: Role;
pineafan6702cef2022-06-13 17:52:37 +010020 try {
Skyler Grey1a67e182022-08-04 23:05:44 +010021 role = interaction.options.getRole("role") as Role;
pineafan6702cef2022-06-13 17:52:37 +010022 } catch {
pineafan4edb7762022-06-26 19:21:04 +010023 return await interaction.editReply({embeds: [new EmojiEmbed()
pineafan6702cef2022-06-13 17:52:37 +010024 .setEmoji("GUILD.ROLES.DELETE")
25 .setTitle("Verify Role")
26 .setDescription("The role you provided is not a valid role")
27 .setStatus("Danger")
pineafan63fc5e22022-08-04 22:04:10 +010028 ]});
pineafan6702cef2022-06-13 17:52:37 +010029 }
pineafan63fc5e22022-08-04 22:04:10 +010030 role = role as Discord.Role;
pineafane23c4ec2022-07-27 21:56:27 +010031 if (role.guild.id !== interaction.guild.id) {
pineafan4edb7762022-06-26 19:21:04 +010032 return interaction.editReply({embeds: [new EmojiEmbed()
pineafan6702cef2022-06-13 17:52:37 +010033 .setTitle("Verify Role")
pineafan63fc5e22022-08-04 22:04:10 +010034 .setDescription("You must choose a role in this server")
pineafan6702cef2022-06-13 17:52:37 +010035 .setStatus("Danger")
36 .setEmoji("GUILD.ROLES.DELETE")
37 ]});
38 }
pineafan63fc5e22022-08-04 22:04:10 +010039 const confirmation = await new confirmationMessage(interaction)
pineafan6702cef2022-06-13 17:52:37 +010040 .setEmoji("GUILD.ROLES.EDIT")
41 .setTitle("Verify Role")
42 .setDescription(`Are you sure you want to set the verify role to <@&${role.id}>?`)
43 .setColor("Warning")
44 .setInverted(true)
pineafan63fc5e22022-08-04 22:04:10 +010045 .send(true);
46 if (confirmation.cancelled) return;
pineafan6702cef2022-06-13 17:52:37 +010047 if (confirmation.success) {
48 try {
pineafan4edb7762022-06-26 19:21:04 +010049 await client.database.guilds.write(interaction.guild.id, {"verify.role": role.id, "verify.enabled": true});
pineafan63fc5e22022-08-04 22:04:10 +010050 const { log, NucleusColors, entry, renderUser, renderRole } = client.logger;
51 const data = {
52 meta:{
53 type: "verifyRoleChanged",
54 displayName: "Verify Role Changed",
55 calculateType: "nucleusSettingsUpdated",
56 color: NucleusColors.green,
57 emoji: "CONTROL.BLOCKTICK",
58 timestamp: new Date().getTime()
59 },
60 list: {
61 memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
62 changedBy: entry(interaction.user.id, renderUser(interaction.user)),
63 role: entry(role.id, renderRole(role))
64 },
65 hidden: {
66 guild: interaction.guild.id
pineafanda6e5342022-07-03 10:03:16 +010067 }
pineafan63fc5e22022-08-04 22:04:10 +010068 };
69 log(data);
pineafan6702cef2022-06-13 17:52:37 +010070 } catch (e) {
pineafan63fc5e22022-08-04 22:04:10 +010071 console.log(e);
pineafan4edb7762022-06-26 19:21:04 +010072 return interaction.editReply({embeds: [new EmojiEmbed()
pineafan6702cef2022-06-13 17:52:37 +010073 .setTitle("Verify Role")
pineafan63fc5e22022-08-04 22:04:10 +010074 .setDescription("Something went wrong while setting the verify role")
pineafan6702cef2022-06-13 17:52:37 +010075 .setStatus("Danger")
76 .setEmoji("GUILD.ROLES.DELETE")
77 ], components: []});
78 }
79 } else {
pineafan4edb7762022-06-26 19:21:04 +010080 return interaction.editReply({embeds: [new EmojiEmbed()
pineafan6702cef2022-06-13 17:52:37 +010081 .setTitle("Verify Role")
pineafan63fc5e22022-08-04 22:04:10 +010082 .setDescription("No changes were made")
pineafan6702cef2022-06-13 17:52:37 +010083 .setStatus("Success")
84 .setEmoji("GUILD.ROLES.CREATE")
85 ], components: []});
86 }
87 }
88 let clicks = 0;
pineafan63fc5e22022-08-04 22:04:10 +010089 const data = await client.database.guilds.read(interaction.guild.id);
pineafan6702cef2022-06-13 17:52:37 +010090 let role = data.verify.role;
91 while (true) {
pineafan4edb7762022-06-26 19:21:04 +010092 await interaction.editReply({embeds: [new EmojiEmbed()
pineafan6702cef2022-06-13 17:52:37 +010093 .setTitle("Verify Role")
pineafan63fc5e22022-08-04 22:04:10 +010094 .setDescription(role ? `Your verify role is currently set to <@&${role}>` : "You have not set a verify role")
pineafan6702cef2022-06-13 17:52:37 +010095 .setStatus("Success")
96 .setEmoji("GUILD.ROLES.CREATE")
pineafane23c4ec2022-07-27 21:56:27 +010097 ], components: [new MessageActionRow().addComponents([
98 new MessageButton()
99 .setCustomId("clear")
100 .setLabel(clicks ? "Click again to confirm" : "Reset role")
101 .setEmoji(getEmojiByName(clicks ? "TICKETS.ISSUE" : "CONTROL.CROSS", "id"))
102 .setStyle("DANGER")
pineafan41d93562022-07-30 22:10:15 +0100103 .setDisabled(!role),
104 new MessageButton()
105 .setCustomId("send")
106 .setLabel("Add verify button")
107 .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
108 .setStyle("PRIMARY")
pineafan6702cef2022-06-13 17:52:37 +0100109 ])]});
Skyler Grey1a67e182022-08-04 23:05:44 +0100110 let i: MessageComponentInteraction;
pineafan6702cef2022-06-13 17:52:37 +0100111 try {
Skyler Grey1a67e182022-08-04 23:05:44 +0100112 i = await (m as Message).awaitMessageComponent({time: 300000});
pineafan63fc5e22022-08-04 22:04:10 +0100113 } catch(e) { break; }
114 i.deferUpdate();
Skyler Grey1a67e182022-08-04 23:05:44 +0100115 if ((i.component as MessageActionRowComponent).customId === "clear") {
pineafan6702cef2022-06-13 17:52:37 +0100116 clicks += 1;
pineafane23c4ec2022-07-27 21:56:27 +0100117 if (clicks === 2) {
pineafan6702cef2022-06-13 17:52:37 +0100118 clicks = 0;
pineafan63fc5e22022-08-04 22:04:10 +0100119 await client.database.guilds.write(interaction.guild.id, null, ["verify.role", "verify.enabled"]);
pineafan6702cef2022-06-13 17:52:37 +0100120 role = undefined;
121 }
Skyler Grey1a67e182022-08-04 23:05:44 +0100122 } else if ((i.component as MessageActionRowComponent).customId === "send") {
pineafan41d93562022-07-30 22:10:15 +0100123 const verifyMessages = [
124 {label: "Verify", description: "Click the button below to get verified"},
125 {label: "Get verified", description: "To get access to the rest of the server, click the button below"},
pineafan63fc5e22022-08-04 22:04:10 +0100126 {label: "Ready to verify?", description: "Click the button below to verify yourself"}
127 ];
pineafan41d93562022-07-30 22:10:15 +0100128 while (true) {
129 await interaction.editReply({embeds: [new EmojiEmbed()
130 .setTitle("Verify Button")
131 .setDescription("Select a message template to send in this channel")
132 .setFooter({text: role ? "" : "You do no have a verify role set so the button will not work."})
133 .setStatus(role ? "Success" : "Warning")
134 .setEmoji("GUILD.ROLES.CREATE")
135 ], components: [
136 new MessageActionRow().addComponents([
137 new MessageSelectMenu().setOptions(verifyMessages.map((t: {label: string, description: string, value?: string}, index) => {
pineafan63fc5e22022-08-04 22:04:10 +0100138 t.value = index.toString(); return t as {value: string, label: string, description: string};
139 })).setCustomId("template").setMaxValues(1).setMinValues(1).setPlaceholder("Select a message template")
pineafan41d93562022-07-30 22:10:15 +0100140 ]),
141 new MessageActionRow().addComponents([
142 new MessageButton()
143 .setCustomId("back")
144 .setLabel("Back")
145 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
146 .setStyle("DANGER"),
147 new MessageButton()
148 .setCustomId("blank")
149 .setLabel("Empty")
150 .setStyle("SECONDARY"),
151 new MessageButton()
152 .setCustomId("custom")
153 .setLabel("Custom")
154 .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
155 .setStyle("PRIMARY")
156 ])
157 ]});
Skyler Grey1a67e182022-08-04 23:05:44 +0100158 let i: MessageComponentInteraction;
pineafan41d93562022-07-30 22:10:15 +0100159 try {
Skyler Grey1a67e182022-08-04 23:05:44 +0100160 i = await (m as Message).awaitMessageComponent({time: 300000});
pineafan63fc5e22022-08-04 22:04:10 +0100161 } catch(e) { break; }
Skyler Grey1a67e182022-08-04 23:05:44 +0100162 if ((i.component as MessageActionRowComponent).customId === "template") {
pineafan63fc5e22022-08-04 22:04:10 +0100163 i.deferUpdate();
pineafan41d93562022-07-30 22:10:15 +0100164 await interaction.channel.send({embeds: [new EmojiEmbed()
Skyler Grey1a67e182022-08-04 23:05:44 +0100165 .setTitle(verifyMessages[parseInt((i as SelectMenuInteraction).values[0])].label)
166 .setDescription(verifyMessages[parseInt((i as SelectMenuInteraction).values[0])].description)
pineafan41d93562022-07-30 22:10:15 +0100167 .setStatus("Success")
168 .setEmoji("CONTROL.BLOCKTICK")
169 ], components: [new MessageActionRow().addComponents([new MessageButton()
170 .setLabel("Verify")
171 .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
172 .setStyle("SUCCESS")
173 .setCustomId("verifybutton")
174 ])]});
pineafan63fc5e22022-08-04 22:04:10 +0100175 break;
Skyler Grey1a67e182022-08-04 23:05:44 +0100176 } else if ((i.component as MessageActionRowComponent).customId === "blank") {
pineafan63fc5e22022-08-04 22:04:10 +0100177 i.deferUpdate();
pineafan41d93562022-07-30 22:10:15 +0100178 await interaction.channel.send({components: [new MessageActionRow().addComponents([new MessageButton()
179 .setLabel("Verify")
180 .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
181 .setStyle("SUCCESS")
182 .setCustomId("verifybutton")
183 ])]});
pineafan63fc5e22022-08-04 22:04:10 +0100184 break;
Skyler Grey1a67e182022-08-04 23:05:44 +0100185 } else if ((i.component as MessageActionRowComponent).customId === "custom") {
pineafan63fc5e22022-08-04 22:04:10 +0100186 await i.showModal(new Discord.Modal().setCustomId("modal").setTitle("Enter embed details").addComponents(
pineafan41d93562022-07-30 22:10:15 +0100187 new MessageActionRow<TextInputComponent>().addComponents(new TextInputComponent()
188 .setCustomId("title")
189 .setLabel("Title")
190 .setMaxLength(256)
191 .setRequired(true)
192 .setStyle("SHORT")
193 ),
194 new MessageActionRow<TextInputComponent>().addComponents(new TextInputComponent()
195 .setCustomId("description")
196 .setLabel("Description")
197 .setMaxLength(4000)
198 .setRequired(true)
199 .setStyle("PARAGRAPH")
200 )
pineafan63fc5e22022-08-04 22:04:10 +0100201 ));
pineafan41d93562022-07-30 22:10:15 +0100202 await interaction.editReply({
203 embeds: [new EmojiEmbed()
204 .setTitle("Verify Button")
205 .setDescription("Modal opened. If you can't see it, click back and try again.")
206 .setStatus("Success")
207 .setEmoji("GUILD.TICKET.OPEN")
208 ], components: [new MessageActionRow().addComponents([new MessageButton()
209 .setLabel("Back")
210 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
211 .setStyle("PRIMARY")
212 .setCustomId("back")
213 ])]
214 });
215 let out;
216 try {
pineafan63fc5e22022-08-04 22:04:10 +0100217 out = await modalInteractionCollector(m, (m) => m.channel.id === interaction.channel.id, (m) => m.customId === "modify");
218 } catch (e) { break; }
pineafan41d93562022-07-30 22:10:15 +0100219 if (out.fields) {
pineafan63fc5e22022-08-04 22:04:10 +0100220 const title = out.fields.getTextInputValue("title");
221 const description = out.fields.getTextInputValue("description");
pineafan41d93562022-07-30 22:10:15 +0100222 await interaction.channel.send({embeds: [new EmojiEmbed()
223 .setTitle(title)
224 .setDescription(description)
225 .setStatus("Success")
226 .setEmoji("CONTROL.BLOCKTICK")
227 ], components: [new MessageActionRow().addComponents([new MessageButton()
228 .setLabel("Verify")
229 .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
230 .setStyle("SUCCESS")
231 .setCustomId("verifybutton")
232 ])]});
pineafan63fc5e22022-08-04 22:04:10 +0100233 break;
234 } else { continue; }
pineafan41d93562022-07-30 22:10:15 +0100235 }
236 }
pineafan6702cef2022-06-13 17:52:37 +0100237 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100238 i.deferUpdate();
pineafan41d93562022-07-30 22:10:15 +0100239 break;
pineafan6702cef2022-06-13 17:52:37 +0100240 }
241 }
Skyler Grey1a67e182022-08-04 23:05:44 +0100242 await interaction.editReply({embeds: [(m.embeds[0] as Embed).setFooter({text: "Message closed"})], components: []});
pineafan63fc5e22022-08-04 22:04:10 +0100243};
pineafan4f164f32022-02-26 22:07:12 +0000244
Skyler Grey1a67e182022-08-04 23:05:44 +0100245const check = (interaction: CommandInteraction) => {
pineafan63fc5e22022-08-04 22:04:10 +0100246 const member = (interaction.member as Discord.GuildMember);
247 if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the *Manage Server* permission to use this command";
pineafan4f164f32022-02-26 22:07:12 +0000248 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100249};
pineafan4f164f32022-02-26 22:07:12 +0000250
251export { command };
252export { callback };
pineafan6702cef2022-06-13 17:52:37 +0100253export { check };