blob: c100d05792e84fa0df5816be264c8ca216ddc220 [file] [log] [blame]
pineafan63fc5e22022-08-04 22:04:10 +01001import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
pineafan41d93562022-07-30 22:10:15 +01002import Discord, { CommandInteraction, Emoji, MessageActionRow, MessageButton, MessageSelectMenu, 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";
pineafan4f164f32022-02-26 22:07:12 +00006import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
7import { WrappedCheck } from "jshaiku";
pineafanda6e5342022-07-03 10:03:16 +01008import client from "../../utils/client.js";
pineafan63fc5e22022-08-04 22:04:10 +01009import { modalInteractionCollector } from "../../utils/dualCollector.js";
pineafan4f164f32022-02-26 22:07:12 +000010
11const command = (builder: SlashCommandSubcommandBuilder) =>
12 builder
pineafan63fc5e22022-08-04 22:04:10 +010013 .setName("verify")
14 .setDescription("Manage the role given after typing /verify")
15 .addRoleOption(option => option.setName("role").setDescription("The role to give after verifying").setRequired(false));
pineafan4f164f32022-02-26 22:07:12 +000016
pineafan6702cef2022-06-13 17:52:37 +010017const callback = async (interaction: CommandInteraction): Promise<any> => {
18 let m;
pineafane23c4ec2022-07-27 21:56:27 +010019 m = await interaction.reply({embeds: LoadingEmbed, ephemeral: true, fetchReply: true});
pineafan6702cef2022-06-13 17:52:37 +010020 if (interaction.options.getRole("role")) {
pineafan63fc5e22022-08-04 22:04:10 +010021 let role;
pineafan6702cef2022-06-13 17:52:37 +010022 try {
pineafan63fc5e22022-08-04 22:04:10 +010023 role = interaction.options.getRole("role");
pineafan6702cef2022-06-13 17:52:37 +010024 } catch {
pineafan4edb7762022-06-26 19:21:04 +010025 return await interaction.editReply({embeds: [new EmojiEmbed()
pineafan6702cef2022-06-13 17:52:37 +010026 .setEmoji("GUILD.ROLES.DELETE")
27 .setTitle("Verify Role")
28 .setDescription("The role you provided is not a valid role")
29 .setStatus("Danger")
pineafan63fc5e22022-08-04 22:04:10 +010030 ]});
pineafan6702cef2022-06-13 17:52:37 +010031 }
pineafan63fc5e22022-08-04 22:04:10 +010032 role = role as Discord.Role;
pineafane23c4ec2022-07-27 21:56:27 +010033 if (role.guild.id !== interaction.guild.id) {
pineafan4edb7762022-06-26 19:21:04 +010034 return interaction.editReply({embeds: [new EmojiEmbed()
pineafan6702cef2022-06-13 17:52:37 +010035 .setTitle("Verify Role")
pineafan63fc5e22022-08-04 22:04:10 +010036 .setDescription("You must choose a role in this server")
pineafan6702cef2022-06-13 17:52:37 +010037 .setStatus("Danger")
38 .setEmoji("GUILD.ROLES.DELETE")
39 ]});
40 }
pineafan63fc5e22022-08-04 22:04:10 +010041 const confirmation = await new confirmationMessage(interaction)
pineafan6702cef2022-06-13 17:52:37 +010042 .setEmoji("GUILD.ROLES.EDIT")
43 .setTitle("Verify Role")
44 .setDescription(`Are you sure you want to set the verify role to <@&${role.id}>?`)
45 .setColor("Warning")
46 .setInverted(true)
pineafan63fc5e22022-08-04 22:04:10 +010047 .send(true);
48 if (confirmation.cancelled) return;
pineafan6702cef2022-06-13 17:52:37 +010049 if (confirmation.success) {
50 try {
pineafan4edb7762022-06-26 19:21:04 +010051 await client.database.guilds.write(interaction.guild.id, {"verify.role": role.id, "verify.enabled": true});
pineafan63fc5e22022-08-04 22:04:10 +010052 const { log, NucleusColors, entry, renderUser, renderRole } = client.logger;
53 const data = {
54 meta:{
55 type: "verifyRoleChanged",
56 displayName: "Verify Role Changed",
57 calculateType: "nucleusSettingsUpdated",
58 color: NucleusColors.green,
59 emoji: "CONTROL.BLOCKTICK",
60 timestamp: new Date().getTime()
61 },
62 list: {
63 memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
64 changedBy: entry(interaction.user.id, renderUser(interaction.user)),
65 role: entry(role.id, renderRole(role))
66 },
67 hidden: {
68 guild: interaction.guild.id
pineafanda6e5342022-07-03 10:03:16 +010069 }
pineafan63fc5e22022-08-04 22:04:10 +010070 };
71 log(data);
pineafan6702cef2022-06-13 17:52:37 +010072 } catch (e) {
pineafan63fc5e22022-08-04 22:04:10 +010073 console.log(e);
pineafan4edb7762022-06-26 19:21:04 +010074 return interaction.editReply({embeds: [new EmojiEmbed()
pineafan6702cef2022-06-13 17:52:37 +010075 .setTitle("Verify Role")
pineafan63fc5e22022-08-04 22:04:10 +010076 .setDescription("Something went wrong while setting the verify role")
pineafan6702cef2022-06-13 17:52:37 +010077 .setStatus("Danger")
78 .setEmoji("GUILD.ROLES.DELETE")
79 ], components: []});
80 }
81 } else {
pineafan4edb7762022-06-26 19:21:04 +010082 return interaction.editReply({embeds: [new EmojiEmbed()
pineafan6702cef2022-06-13 17:52:37 +010083 .setTitle("Verify Role")
pineafan63fc5e22022-08-04 22:04:10 +010084 .setDescription("No changes were made")
pineafan6702cef2022-06-13 17:52:37 +010085 .setStatus("Success")
86 .setEmoji("GUILD.ROLES.CREATE")
87 ], components: []});
88 }
89 }
90 let clicks = 0;
pineafan63fc5e22022-08-04 22:04:10 +010091 const data = await client.database.guilds.read(interaction.guild.id);
pineafan6702cef2022-06-13 17:52:37 +010092 let role = data.verify.role;
93 while (true) {
pineafan4edb7762022-06-26 19:21:04 +010094 await interaction.editReply({embeds: [new EmojiEmbed()
pineafan6702cef2022-06-13 17:52:37 +010095 .setTitle("Verify Role")
pineafan63fc5e22022-08-04 22:04:10 +010096 .setDescription(role ? `Your verify role is currently set to <@&${role}>` : "You have not set a verify role")
pineafan6702cef2022-06-13 17:52:37 +010097 .setStatus("Success")
98 .setEmoji("GUILD.ROLES.CREATE")
pineafane23c4ec2022-07-27 21:56:27 +010099 ], components: [new MessageActionRow().addComponents([
100 new MessageButton()
101 .setCustomId("clear")
102 .setLabel(clicks ? "Click again to confirm" : "Reset role")
103 .setEmoji(getEmojiByName(clicks ? "TICKETS.ISSUE" : "CONTROL.CROSS", "id"))
104 .setStyle("DANGER")
pineafan41d93562022-07-30 22:10:15 +0100105 .setDisabled(!role),
106 new MessageButton()
107 .setCustomId("send")
108 .setLabel("Add verify button")
109 .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
110 .setStyle("PRIMARY")
pineafan6702cef2022-06-13 17:52:37 +0100111 ])]});
112 let i;
113 try {
pineafanc6158ab2022-06-17 16:34:07 +0100114 i = await m.awaitMessageComponent({time: 300000});
pineafan63fc5e22022-08-04 22:04:10 +0100115 } catch(e) { break; }
116 i.deferUpdate();
pineafane23c4ec2022-07-27 21:56:27 +0100117 if (i.component.customId === "clear") {
pineafan6702cef2022-06-13 17:52:37 +0100118 clicks += 1;
pineafane23c4ec2022-07-27 21:56:27 +0100119 if (clicks === 2) {
pineafan6702cef2022-06-13 17:52:37 +0100120 clicks = 0;
pineafan63fc5e22022-08-04 22:04:10 +0100121 await client.database.guilds.write(interaction.guild.id, null, ["verify.role", "verify.enabled"]);
pineafan6702cef2022-06-13 17:52:37 +0100122 role = undefined;
123 }
pineafan41d93562022-07-30 22:10:15 +0100124 } else if (i.component.customId === "send") {
125 const verifyMessages = [
126 {label: "Verify", description: "Click the button below to get verified"},
127 {label: "Get verified", description: "To get access to the rest of the server, click the button below"},
pineafan63fc5e22022-08-04 22:04:10 +0100128 {label: "Ready to verify?", description: "Click the button below to verify yourself"}
129 ];
pineafan41d93562022-07-30 22:10:15 +0100130 while (true) {
131 await interaction.editReply({embeds: [new EmojiEmbed()
132 .setTitle("Verify Button")
133 .setDescription("Select a message template to send in this channel")
134 .setFooter({text: role ? "" : "You do no have a verify role set so the button will not work."})
135 .setStatus(role ? "Success" : "Warning")
136 .setEmoji("GUILD.ROLES.CREATE")
137 ], components: [
138 new MessageActionRow().addComponents([
139 new MessageSelectMenu().setOptions(verifyMessages.map((t: {label: string, description: string, value?: string}, index) => {
pineafan63fc5e22022-08-04 22:04:10 +0100140 t.value = index.toString(); return t as {value: string, label: string, description: string};
141 })).setCustomId("template").setMaxValues(1).setMinValues(1).setPlaceholder("Select a message template")
pineafan41d93562022-07-30 22:10:15 +0100142 ]),
143 new MessageActionRow().addComponents([
144 new MessageButton()
145 .setCustomId("back")
146 .setLabel("Back")
147 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
148 .setStyle("DANGER"),
149 new MessageButton()
150 .setCustomId("blank")
151 .setLabel("Empty")
152 .setStyle("SECONDARY"),
153 new MessageButton()
154 .setCustomId("custom")
155 .setLabel("Custom")
156 .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
157 .setStyle("PRIMARY")
158 ])
159 ]});
160 let i;
161 try {
162 i = await m.awaitMessageComponent({time: 300000});
pineafan63fc5e22022-08-04 22:04:10 +0100163 } catch(e) { break; }
pineafan41d93562022-07-30 22:10:15 +0100164 if (i.component.customId === "template") {
pineafan63fc5e22022-08-04 22:04:10 +0100165 i.deferUpdate();
pineafan41d93562022-07-30 22:10:15 +0100166 await interaction.channel.send({embeds: [new EmojiEmbed()
167 .setTitle(verifyMessages[parseInt(i.values[0])].label)
168 .setDescription(verifyMessages[parseInt(i.values[0])].description)
169 .setStatus("Success")
170 .setEmoji("CONTROL.BLOCKTICK")
171 ], components: [new MessageActionRow().addComponents([new MessageButton()
172 .setLabel("Verify")
173 .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
174 .setStyle("SUCCESS")
175 .setCustomId("verifybutton")
176 ])]});
pineafan63fc5e22022-08-04 22:04:10 +0100177 break;
pineafan41d93562022-07-30 22:10:15 +0100178 } else if (i.component.customId === "blank") {
pineafan63fc5e22022-08-04 22:04:10 +0100179 i.deferUpdate();
pineafan41d93562022-07-30 22:10:15 +0100180 await interaction.channel.send({components: [new MessageActionRow().addComponents([new MessageButton()
181 .setLabel("Verify")
182 .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
183 .setStyle("SUCCESS")
184 .setCustomId("verifybutton")
185 ])]});
pineafan63fc5e22022-08-04 22:04:10 +0100186 break;
pineafan41d93562022-07-30 22:10:15 +0100187 } else if (i.component.customId === "custom") {
pineafan63fc5e22022-08-04 22:04:10 +0100188 await i.showModal(new Discord.Modal().setCustomId("modal").setTitle("Enter embed details").addComponents(
pineafan41d93562022-07-30 22:10:15 +0100189 new MessageActionRow<TextInputComponent>().addComponents(new TextInputComponent()
190 .setCustomId("title")
191 .setLabel("Title")
192 .setMaxLength(256)
193 .setRequired(true)
194 .setStyle("SHORT")
195 ),
196 new MessageActionRow<TextInputComponent>().addComponents(new TextInputComponent()
197 .setCustomId("description")
198 .setLabel("Description")
199 .setMaxLength(4000)
200 .setRequired(true)
201 .setStyle("PARAGRAPH")
202 )
pineafan63fc5e22022-08-04 22:04:10 +0100203 ));
pineafan41d93562022-07-30 22:10:15 +0100204 await interaction.editReply({
205 embeds: [new EmojiEmbed()
206 .setTitle("Verify Button")
207 .setDescription("Modal opened. If you can't see it, click back and try again.")
208 .setStatus("Success")
209 .setEmoji("GUILD.TICKET.OPEN")
210 ], components: [new MessageActionRow().addComponents([new MessageButton()
211 .setLabel("Back")
212 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
213 .setStyle("PRIMARY")
214 .setCustomId("back")
215 ])]
216 });
217 let out;
218 try {
pineafan63fc5e22022-08-04 22:04:10 +0100219 out = await modalInteractionCollector(m, (m) => m.channel.id === interaction.channel.id, (m) => m.customId === "modify");
220 } catch (e) { break; }
pineafan41d93562022-07-30 22:10:15 +0100221 if (out.fields) {
pineafan63fc5e22022-08-04 22:04:10 +0100222 const title = out.fields.getTextInputValue("title");
223 const description = out.fields.getTextInputValue("description");
pineafan41d93562022-07-30 22:10:15 +0100224 await interaction.channel.send({embeds: [new EmojiEmbed()
225 .setTitle(title)
226 .setDescription(description)
227 .setStatus("Success")
228 .setEmoji("CONTROL.BLOCKTICK")
229 ], components: [new MessageActionRow().addComponents([new MessageButton()
230 .setLabel("Verify")
231 .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
232 .setStyle("SUCCESS")
233 .setCustomId("verifybutton")
234 ])]});
pineafan63fc5e22022-08-04 22:04:10 +0100235 break;
236 } else { continue; }
pineafan41d93562022-07-30 22:10:15 +0100237 }
238 }
pineafan6702cef2022-06-13 17:52:37 +0100239 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100240 i.deferUpdate();
pineafan41d93562022-07-30 22:10:15 +0100241 break;
pineafan6702cef2022-06-13 17:52:37 +0100242 }
243 }
pineafan41d93562022-07-30 22:10:15 +0100244 await interaction.editReply({embeds: [m.embeds[0].setFooter({text: "Message closed"})], components: []});
pineafan63fc5e22022-08-04 22:04:10 +0100245};
pineafan4f164f32022-02-26 22:07:12 +0000246
247const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
pineafan63fc5e22022-08-04 22:04:10 +0100248 const member = (interaction.member as Discord.GuildMember);
249 if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the *Manage Server* permission to use this command";
pineafan4f164f32022-02-26 22:07:12 +0000250 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100251};
pineafan4f164f32022-02-26 22:07:12 +0000252
253export { command };
254export { callback };
pineafan6702cef2022-06-13 17:52:37 +0100255export { check };