blob: 849c88098dc64294c9df6805f58123aa0a06d1c8 [file] [log] [blame]
pineafan63fc5e22022-08-04 22:04:10 +01001import { LoadingEmbed } from "./../utils/defaultEmbeds.js";
2import { SelectMenuOption } from "@discordjs/builders";
pineafan813bdf42022-07-24 10:39:10 +01003import Discord, { MessageActionRow, MessageButton } from "discord.js";
4import EmojiEmbed from "../utils/generateEmojiEmbed.js";
5import getEmojiByName from "../utils/getEmojiByName.js";
6import createPageIndicator from "../utils/createPageIndicator.js";
pineafan813bdf42022-07-24 10:39:10 +01007
8class Embed {
9 embed: Discord.MessageEmbed;
10 title: string;
pineafan63fc5e22022-08-04 22:04:10 +010011 description = "";
12 pageId = 0;
Skyler Grey75ea9172022-08-06 10:22:23 +010013 setEmbed(embed: Discord.MessageEmbed) {
14 this.embed = embed;
15 return this;
16 }
17 setTitle(title: string) {
18 this.title = title;
19 return this;
20 }
21 setDescription(description: string) {
22 this.description = description;
23 return this;
24 }
25 setPageId(pageId: number) {
26 this.pageId = pageId;
27 return this;
28 }
pineafan813bdf42022-07-24 10:39:10 +010029}
30
31export default async (guild, interaction?) => {
Skyler Grey11236ba2022-08-08 21:13:33 +010032 let c = guild.publicUpdatesChannel ? guild.publicUpdatesChannel : guild.systemChannel;
Skyler Grey75ea9172022-08-06 10:22:23 +010033 c = c
34 ? c
35 : guild.channels.cache.find(
36 (ch) =>
37 ch.type === "GUILD_TEXT" &&
Skyler Grey11236ba2022-08-08 21:13:33 +010038 ch.permissionsFor(guild.roles.everyone).has("SEND_MESSAGES") &&
Skyler Grey75ea9172022-08-06 10:22:23 +010039 ch.permissionsFor(guild.me).has("EMBED_LINKS")
40 );
pineafan63fc5e22022-08-04 22:04:10 +010041 const pages = [
pineafan813bdf42022-07-24 10:39:10 +010042 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +010043 .setEmbed(
44 new EmojiEmbed()
45 .setTitle("Welcome to Nucleus")
46 .setDescription(
47 "Thanks for adding Nucleus to your server\n\n" +
48 "On the next few pages you can find instructions on getting started, and commands you may want to set up\n\n" +
49 "If you need support, have questions or want features, you can let us know in [Clicks](https://discord.gg/bPaNnxe)"
50 )
51 .setEmoji("NUCLEUS.LOGO")
52 .setStatus("Danger")
53 )
54 .setTitle("Welcome")
55 .setDescription("About Nucleus")
56 .setPageId(0),
pineafan813bdf42022-07-24 10:39:10 +010057 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +010058 .setEmbed(
59 new EmojiEmbed()
60 .setTitle("Logging")
61 .setDescription(
62 "Nucleus can log server events and keep you informed with what content is being posted to your server.\n" +
63 "We have 2 different types of logs, which each can be configured to send to a channel of your choice:\n" +
64 "**General Logs:** These are events like kicks and channel changes etc.\n" +
65 "**Warning Logs:** Warnings like NSFW avatars and spam etc. that may require action by a server staff member. " +
66 "These go to to a separate staff notifications channel.\n\n" +
67 "A general log channel can be set with `/settings log`\n" +
68 "A warning log channel can be set with `/settings warnings channel`"
69 )
70 .setEmoji("ICONS.LOGGING")
71 .setStatus("Danger")
72 )
73 .setTitle("Logging")
74 .setDescription("Logging, staff warning logs etc.")
75 .setPageId(1),
pineafan813bdf42022-07-24 10:39:10 +010076 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +010077 .setEmbed(
78 new EmojiEmbed()
79 .setTitle("Moderation")
80 .setDescription(
81 "Nucleus has a number of commands that can be used to moderate your server.\n" +
82 "These commands are all found under `/mod`, and they include:\n" +
83 `**${getEmojiByName(
84 "PUNISH.WARN.YELLOW"
85 )} Warn:** The user is warned (via DM) that they violated server rules.\n` +
86 `**${getEmojiByName(
87 "PUNISH.CLEARHISTORY"
88 )} Clear:** Some messages from a user are deleted in a channel.\n` +
89 `**${getEmojiByName(
90 "PUNISH.MUTE.YELLOW"
91 )} Mute:** The user is unable to send messages or join voice chats.\n` +
92 `**${getEmojiByName(
93 "PUNISH.MUTE.GREEN"
94 )} Unmute:** The user is able to send messages in the server.\n` +
Skyler Grey11236ba2022-08-08 21:13:33 +010095 `**${getEmojiByName("PUNISH.KICK.RED")} Kick:** The user is removed from the server.\n` +
Skyler Grey75ea9172022-08-06 10:22:23 +010096 `**${getEmojiByName(
97 "PUNISH.SOFTBAN"
98 )} Softban:** Kicks the user, deleting their messages from every channel.\n` +
99 `**${getEmojiByName(
100 "PUNISH.BAN.RED"
101 )} Ban:** The user is removed from the server, and they are unable to rejoin.\n` +
Skyler Grey11236ba2022-08-08 21:13:33 +0100102 `**${getEmojiByName("PUNISH.BAN.GREEN")} Unban:** The user is able to rejoin the server.`
Skyler Grey75ea9172022-08-06 10:22:23 +0100103 )
104 .setEmoji("PUNISH.BAN.RED")
105 .setStatus("Danger")
106 )
107 .setTitle("Moderation")
108 .setDescription("Basic moderation commands")
109 .setPageId(2),
pineafan813bdf42022-07-24 10:39:10 +0100110 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100111 .setEmbed(
112 new EmojiEmbed()
113 .setTitle("Verify")
114 .setDescription(
115 "Nucleus has a verification system that allows users to prove they aren't bots.\n" +
116 "This is done by running `/verify` which sends a message only the user can see, giving them a link to a CAPTCHA to verify.\n" +
117 "After the user complete's the CAPTCHA, they are given a role and can use the permissions accordingly.\n" +
118 "You can set the role given with `/settings verify`"
119 )
120 .setEmoji("CONTROL.REDTICK")
121 .setStatus("Danger")
122 )
123 .setTitle("Verify")
124 .setDescription("Captcha verification system")
125 .setPageId(3),
pineafan813bdf42022-07-24 10:39:10 +0100126 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100127 .setEmbed(
128 new EmojiEmbed()
129 .setTitle("Content Scanning")
130 .setDescription(
131 "Nucleus has a content scanning system that automatically scans links and images sent by users.\n" +
132 "Nucleus can detect, delete, and punish users for sending NSFW content, or links to scam or adult sites.\n" +
133 "You can set the threshold for this in `/settings automation`" // TODO
134 )
135 .setEmoji("MOD.IMAGES.TOOSMALL")
136 .setStatus("Danger")
137 )
138 .setTitle("Content Scanning")
139 .setDescription("Content (NSFW, malware, scams) scanning")
140 .setPageId(4),
pineafan813bdf42022-07-24 10:39:10 +0100141 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100142 .setEmbed(
143 new EmojiEmbed()
144 .setTitle("Tickets")
145 .setDescription(
146 "Nucleus has a ticket system that allows users to create tickets and have a support team respond to them.\n" +
147 "Tickets can be created with `/ticket create` and a channel is created, pinging the user and support role.\n" +
148 "When the ticket is resolved, anyone can run `/ticket close` (or click the button) to close it.\n" +
149 "Running `/ticket close` again will delete the ticket."
150 )
151 .setEmoji("GUILD.TICKET.CLOSE")
152 .setStatus("Danger")
153 )
154 .setTitle("Tickets")
155 .setDescription("Ticket system")
156 .setPageId(5),
pineafan813bdf42022-07-24 10:39:10 +0100157 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100158 .setEmbed(
159 new EmojiEmbed()
160 .setTitle("Tags")
161 .setDescription(
162 "Add a tag system to your server with the `/tag` and `/tags` commands.\n" +
163 "To create a tag, type `/tags create <tag name> <tag content>`.\n" +
164 "Tag names and content can be edited with `/tags edit`.\n" +
165 "To delete a tag, type `/tags delete <tag name>`.\n" +
166 "To view all tags, type `/tags list`.\n"
167 )
168 .setEmoji("PUNISH.NICKNAME.RED")
169 .setStatus("Danger")
170 )
171 .setTitle("Tags")
172 .setDescription("Tag system")
173 .setPageId(6),
pineafan813bdf42022-07-24 10:39:10 +0100174 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100175 .setEmbed(
176 new EmojiEmbed()
177 .setTitle("Premium")
178 .setDescription(
179 "In the near future, we will be releasing extra premium only features.\n" +
180 "These features will include:\n\n" +
181 "**Attachment logs**\n> When a message with attachments is edited or deleted, the logs will also include the images sent.\n" +
182 "\nPremium is not yet available. Check `/nucleus premium` for updates on features and pricing"
183 )
184 .setEmoji("NUCLEUS.COMMANDS.LOCK")
185 .setStatus("Danger")
186 )
187 .setTitle("Premium")
188 .setDescription("Premium features")
189 .setPageId(7)
pineafan63fc5e22022-08-04 22:04:10 +0100190 ];
pineafan813bdf42022-07-24 10:39:10 +0100191 let m;
Skyler Grey75ea9172022-08-06 10:22:23 +0100192 if (interaction) {
193 m = await interaction.reply({
194 embeds: LoadingEmbed,
195 fetchReply: true,
196 ephemeral: true
197 });
198 } else {
199 m = await c.send({ embeds: LoadingEmbed });
200 }
pineafan813bdf42022-07-24 10:39:10 +0100201 let page = 0;
202
pineafan63fc5e22022-08-04 22:04:10 +0100203 const f = async (component) => {
Skyler Grey11236ba2022-08-08 21:13:33 +0100204 return (component.member as Discord.GuildMember).permissions.has("MANAGE_GUILD");
pineafan63fc5e22022-08-04 22:04:10 +0100205 };
pineafan813bdf42022-07-24 10:39:10 +0100206
207 let selectPaneOpen = false;
208
209 while (true) {
pineafan63fc5e22022-08-04 22:04:10 +0100210 let selectPane = [];
pineafan813bdf42022-07-24 10:39:10 +0100211
212 if (selectPaneOpen) {
pineafan63fc5e22022-08-04 22:04:10 +0100213 const options = [];
Skyler Grey75ea9172022-08-06 10:22:23 +0100214 pages.forEach((embed) => {
215 options.push(
216 new SelectMenuOption({
217 label: embed.title,
218 value: embed.pageId.toString(),
219 description: embed.description || ""
220 })
221 );
pineafan63fc5e22022-08-04 22:04:10 +0100222 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100223 selectPane = [
224 new MessageActionRow().addComponents([
225 new Discord.MessageSelectMenu()
226 .addOptions(options)
227 .setCustomId("page")
228 .setMaxValues(1)
229 .setPlaceholder("Choose a page...")
230 ])
231 ];
pineafan813bdf42022-07-24 10:39:10 +0100232 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100233 const components = selectPane.concat([
234 new MessageActionRow().addComponents([
235 new MessageButton()
236 .setCustomId("left")
237 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
238 .setStyle("SECONDARY")
239 .setDisabled(page === 0),
240 new MessageButton()
241 .setCustomId("select")
242 .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
243 .setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY")
244 .setDisabled(false),
245 new MessageButton()
246 .setCustomId("right")
247 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
248 .setStyle("SECONDARY")
249 .setDisabled(page === pages.length - 1)
250 ])
251 ]);
pineafan813bdf42022-07-24 10:39:10 +0100252 if (interaction) {
pineafan63fc5e22022-08-04 22:04:10 +0100253 const em = new Discord.MessageEmbed(pages[page].embed);
Skyler Grey11236ba2022-08-08 21:13:33 +0100254 em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
pineafan813bdf42022-07-24 10:39:10 +0100255 await interaction.editReply({
256 embeds: [em],
257 components: components
258 });
259 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100260 const em = new Discord.MessageEmbed(pages[page].embed);
Skyler Grey11236ba2022-08-08 21:13:33 +0100261 em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
pineafan813bdf42022-07-24 10:39:10 +0100262 await m.edit({
263 embeds: [em],
264 components: components,
265 fetchReply: true
266 });
267 }
pineafan63fc5e22022-08-04 22:04:10 +0100268 let i;
pineafan813bdf42022-07-24 10:39:10 +0100269 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100270 i = await m.awaitMessageComponent({
271 filter: interaction
272 ? () => {
273 return true;
274 }
275 : f,
276 time: 300000
277 });
278 } catch (e) {
279 break;
280 }
pineafan63fc5e22022-08-04 22:04:10 +0100281 i.deferUpdate();
pineafane23c4ec2022-07-27 21:56:27 +0100282 if (i.component.customId === "left") {
pineafan813bdf42022-07-24 10:39:10 +0100283 if (page > 0) page--;
284 selectPaneOpen = false;
pineafane23c4ec2022-07-27 21:56:27 +0100285 } else if (i.component.customId === "right") {
pineafan813bdf42022-07-24 10:39:10 +0100286 if (page < pages.length - 1) page++;
287 selectPaneOpen = false;
pineafane23c4ec2022-07-27 21:56:27 +0100288 } else if (i.component.customId === "select") {
pineafan813bdf42022-07-24 10:39:10 +0100289 selectPaneOpen = !selectPaneOpen;
pineafane23c4ec2022-07-27 21:56:27 +0100290 } else if (i.component.customId === "page") {
pineafan813bdf42022-07-24 10:39:10 +0100291 page = parseInt(i.values[0]);
292 selectPaneOpen = false;
293 } else {
294 if (interaction) {
pineafan63fc5e22022-08-04 22:04:10 +0100295 const em = new Discord.MessageEmbed(pages[page].embed);
Skyler Grey11236ba2022-08-08 21:13:33 +0100296 em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
Skyler Grey75ea9172022-08-06 10:22:23 +0100297 em.setFooter({ text: "Message closed" });
298 interaction.editReply({
299 embeds: [em],
300 components: [
301 new MessageActionRow().addComponents([
302 new MessageButton()
303 .setCustomId("left")
304 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
305 .setStyle("SECONDARY")
306 .setDisabled(true),
307 new MessageButton()
308 .setCustomId("select")
309 .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
Skyler Grey11236ba2022-08-08 21:13:33 +0100310 .setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY")
Skyler Grey75ea9172022-08-06 10:22:23 +0100311 .setDisabled(true),
312 new MessageButton()
313 .setCustomId("right")
314 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
315 .setStyle("SECONDARY")
316 .setDisabled(true)
317 ])
318 ]
319 });
pineafan813bdf42022-07-24 10:39:10 +0100320 } else {
321 m.delete();
322 }
323 return;
324 }
325 }
pineafan813bdf42022-07-24 10:39:10 +0100326 if (interaction) {
pineafan63fc5e22022-08-04 22:04:10 +0100327 const em = new Discord.MessageEmbed(pages[page].embed);
Skyler Grey11236ba2022-08-08 21:13:33 +0100328 em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page)).setFooter({
329 text: "Message timed out"
330 });
pineafan813bdf42022-07-24 10:39:10 +0100331 await interaction.editReply({
332 embeds: [em],
Skyler Grey75ea9172022-08-06 10:22:23 +0100333 components: [
334 new MessageActionRow().addComponents([
335 new MessageButton()
336 .setCustomId("left")
337 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
338 .setStyle("SECONDARY")
339 .setDisabled(true),
340 new MessageButton()
341 .setCustomId("select")
342 .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
343 .setStyle("SECONDARY")
344 .setDisabled(true),
345 new MessageButton()
346 .setCustomId("right")
347 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
348 .setStyle("SECONDARY")
349 .setDisabled(true)
350 ])
351 ]
pineafan813bdf42022-07-24 10:39:10 +0100352 });
353 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100354 const em = new Discord.MessageEmbed(pages[page].embed);
Skyler Grey11236ba2022-08-08 21:13:33 +0100355 em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page)).setFooter({
356 text: "Message timed out"
357 });
pineafan813bdf42022-07-24 10:39:10 +0100358 await m.edit({
359 embeds: [em],
Skyler Grey75ea9172022-08-06 10:22:23 +0100360 components: [
361 new MessageActionRow().addComponents([
362 new MessageButton()
363 .setCustomId("left")
364 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
365 .setStyle("SECONDARY")
366 .setDisabled(true),
367 new MessageButton()
368 .setCustomId("select")
369 .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
370 .setStyle("SECONDARY")
371 .setDisabled(true),
372 new MessageButton()
373 .setCustomId("right")
374 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
375 .setStyle("SECONDARY")
376 .setDisabled(true)
377 ])
378 ]
pineafan813bdf42022-07-24 10:39:10 +0100379 });
380 }
pineafan63fc5e22022-08-04 22:04:10 +0100381};