blob: 0b09f6987cc27fd3bf4629988bde15df103a4af0 [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 Grey75ea9172022-08-06 10:22:23 +010032 let c = guild.publicUpdatesChannel
33 ? guild.publicUpdatesChannel
34 : guild.systemChannel;
35 c = c
36 ? c
37 : guild.channels.cache.find(
38 (ch) =>
39 ch.type === "GUILD_TEXT" &&
40 ch
41 .permissionsFor(guild.roles.everyone)
42 .has("SEND_MESSAGES") &&
43 ch.permissionsFor(guild.me).has("EMBED_LINKS")
44 );
pineafan63fc5e22022-08-04 22:04:10 +010045 const pages = [
pineafan813bdf42022-07-24 10:39:10 +010046 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +010047 .setEmbed(
48 new EmojiEmbed()
49 .setTitle("Welcome to Nucleus")
50 .setDescription(
51 "Thanks for adding Nucleus to your server\n\n" +
52 "On the next few pages you can find instructions on getting started, and commands you may want to set up\n\n" +
53 "If you need support, have questions or want features, you can let us know in [Clicks](https://discord.gg/bPaNnxe)"
54 )
55 .setEmoji("NUCLEUS.LOGO")
56 .setStatus("Danger")
57 )
58 .setTitle("Welcome")
59 .setDescription("About Nucleus")
60 .setPageId(0),
pineafan813bdf42022-07-24 10:39:10 +010061 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +010062 .setEmbed(
63 new EmojiEmbed()
64 .setTitle("Logging")
65 .setDescription(
66 "Nucleus can log server events and keep you informed with what content is being posted to your server.\n" +
67 "We have 2 different types of logs, which each can be configured to send to a channel of your choice:\n" +
68 "**General Logs:** These are events like kicks and channel changes etc.\n" +
69 "**Warning Logs:** Warnings like NSFW avatars and spam etc. that may require action by a server staff member. " +
70 "These go to to a separate staff notifications channel.\n\n" +
71 "A general log channel can be set with `/settings log`\n" +
72 "A warning log channel can be set with `/settings warnings channel`"
73 )
74 .setEmoji("ICONS.LOGGING")
75 .setStatus("Danger")
76 )
77 .setTitle("Logging")
78 .setDescription("Logging, staff warning logs etc.")
79 .setPageId(1),
pineafan813bdf42022-07-24 10:39:10 +010080 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +010081 .setEmbed(
82 new EmojiEmbed()
83 .setTitle("Moderation")
84 .setDescription(
85 "Nucleus has a number of commands that can be used to moderate your server.\n" +
86 "These commands are all found under `/mod`, and they include:\n" +
87 `**${getEmojiByName(
88 "PUNISH.WARN.YELLOW"
89 )} Warn:** The user is warned (via DM) that they violated server rules.\n` +
90 `**${getEmojiByName(
91 "PUNISH.CLEARHISTORY"
92 )} Clear:** Some messages from a user are deleted in a channel.\n` +
93 `**${getEmojiByName(
94 "PUNISH.MUTE.YELLOW"
95 )} Mute:** The user is unable to send messages or join voice chats.\n` +
96 `**${getEmojiByName(
97 "PUNISH.MUTE.GREEN"
98 )} Unmute:** The user is able to send messages in the server.\n` +
99 `**${getEmojiByName(
100 "PUNISH.KICK.RED"
101 )} Kick:** The user is removed from the server.\n` +
102 `**${getEmojiByName(
103 "PUNISH.SOFTBAN"
104 )} Softban:** Kicks the user, deleting their messages from every channel.\n` +
105 `**${getEmojiByName(
106 "PUNISH.BAN.RED"
107 )} Ban:** The user is removed from the server, and they are unable to rejoin.\n` +
108 `**${getEmojiByName(
109 "PUNISH.BAN.GREEN"
110 )} Unban:** The user is able to rejoin the server.`
111 )
112 .setEmoji("PUNISH.BAN.RED")
113 .setStatus("Danger")
114 )
115 .setTitle("Moderation")
116 .setDescription("Basic moderation commands")
117 .setPageId(2),
pineafan813bdf42022-07-24 10:39:10 +0100118 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100119 .setEmbed(
120 new EmojiEmbed()
121 .setTitle("Verify")
122 .setDescription(
123 "Nucleus has a verification system that allows users to prove they aren't bots.\n" +
124 "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" +
125 "After the user complete's the CAPTCHA, they are given a role and can use the permissions accordingly.\n" +
126 "You can set the role given with `/settings verify`"
127 )
128 .setEmoji("CONTROL.REDTICK")
129 .setStatus("Danger")
130 )
131 .setTitle("Verify")
132 .setDescription("Captcha verification system")
133 .setPageId(3),
pineafan813bdf42022-07-24 10:39:10 +0100134 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100135 .setEmbed(
136 new EmojiEmbed()
137 .setTitle("Content Scanning")
138 .setDescription(
139 "Nucleus has a content scanning system that automatically scans links and images sent by users.\n" +
140 "Nucleus can detect, delete, and punish users for sending NSFW content, or links to scam or adult sites.\n" +
141 "You can set the threshold for this in `/settings automation`" // TODO
142 )
143 .setEmoji("MOD.IMAGES.TOOSMALL")
144 .setStatus("Danger")
145 )
146 .setTitle("Content Scanning")
147 .setDescription("Content (NSFW, malware, scams) scanning")
148 .setPageId(4),
pineafan813bdf42022-07-24 10:39:10 +0100149 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100150 .setEmbed(
151 new EmojiEmbed()
152 .setTitle("Tickets")
153 .setDescription(
154 "Nucleus has a ticket system that allows users to create tickets and have a support team respond to them.\n" +
155 "Tickets can be created with `/ticket create` and a channel is created, pinging the user and support role.\n" +
156 "When the ticket is resolved, anyone can run `/ticket close` (or click the button) to close it.\n" +
157 "Running `/ticket close` again will delete the ticket."
158 )
159 .setEmoji("GUILD.TICKET.CLOSE")
160 .setStatus("Danger")
161 )
162 .setTitle("Tickets")
163 .setDescription("Ticket system")
164 .setPageId(5),
pineafan813bdf42022-07-24 10:39:10 +0100165 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100166 .setEmbed(
167 new EmojiEmbed()
168 .setTitle("Tags")
169 .setDescription(
170 "Add a tag system to your server with the `/tag` and `/tags` commands.\n" +
171 "To create a tag, type `/tags create <tag name> <tag content>`.\n" +
172 "Tag names and content can be edited with `/tags edit`.\n" +
173 "To delete a tag, type `/tags delete <tag name>`.\n" +
174 "To view all tags, type `/tags list`.\n"
175 )
176 .setEmoji("PUNISH.NICKNAME.RED")
177 .setStatus("Danger")
178 )
179 .setTitle("Tags")
180 .setDescription("Tag system")
181 .setPageId(6),
pineafan813bdf42022-07-24 10:39:10 +0100182 new Embed()
Skyler Grey75ea9172022-08-06 10:22:23 +0100183 .setEmbed(
184 new EmojiEmbed()
185 .setTitle("Premium")
186 .setDescription(
187 "In the near future, we will be releasing extra premium only features.\n" +
188 "These features will include:\n\n" +
189 "**Attachment logs**\n> When a message with attachments is edited or deleted, the logs will also include the images sent.\n" +
190 "\nPremium is not yet available. Check `/nucleus premium` for updates on features and pricing"
191 )
192 .setEmoji("NUCLEUS.COMMANDS.LOCK")
193 .setStatus("Danger")
194 )
195 .setTitle("Premium")
196 .setDescription("Premium features")
197 .setPageId(7)
pineafan63fc5e22022-08-04 22:04:10 +0100198 ];
pineafan813bdf42022-07-24 10:39:10 +0100199 let m;
Skyler Grey75ea9172022-08-06 10:22:23 +0100200 if (interaction) {
201 m = await interaction.reply({
202 embeds: LoadingEmbed,
203 fetchReply: true,
204 ephemeral: true
205 });
206 } else {
207 m = await c.send({ embeds: LoadingEmbed });
208 }
pineafan813bdf42022-07-24 10:39:10 +0100209 let page = 0;
210
pineafan63fc5e22022-08-04 22:04:10 +0100211 const f = async (component) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100212 return (component.member as Discord.GuildMember).permissions.has(
213 "MANAGE_GUILD"
214 );
pineafan63fc5e22022-08-04 22:04:10 +0100215 };
pineafan813bdf42022-07-24 10:39:10 +0100216
217 let selectPaneOpen = false;
218
219 while (true) {
pineafan63fc5e22022-08-04 22:04:10 +0100220 let selectPane = [];
pineafan813bdf42022-07-24 10:39:10 +0100221
222 if (selectPaneOpen) {
pineafan63fc5e22022-08-04 22:04:10 +0100223 const options = [];
Skyler Grey75ea9172022-08-06 10:22:23 +0100224 pages.forEach((embed) => {
225 options.push(
226 new SelectMenuOption({
227 label: embed.title,
228 value: embed.pageId.toString(),
229 description: embed.description || ""
230 })
231 );
pineafan63fc5e22022-08-04 22:04:10 +0100232 });
Skyler Grey75ea9172022-08-06 10:22:23 +0100233 selectPane = [
234 new MessageActionRow().addComponents([
235 new Discord.MessageSelectMenu()
236 .addOptions(options)
237 .setCustomId("page")
238 .setMaxValues(1)
239 .setPlaceholder("Choose a page...")
240 ])
241 ];
pineafan813bdf42022-07-24 10:39:10 +0100242 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100243 const components = selectPane.concat([
244 new MessageActionRow().addComponents([
245 new MessageButton()
246 .setCustomId("left")
247 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
248 .setStyle("SECONDARY")
249 .setDisabled(page === 0),
250 new MessageButton()
251 .setCustomId("select")
252 .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
253 .setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY")
254 .setDisabled(false),
255 new MessageButton()
256 .setCustomId("right")
257 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
258 .setStyle("SECONDARY")
259 .setDisabled(page === pages.length - 1)
260 ])
261 ]);
pineafan813bdf42022-07-24 10:39:10 +0100262 if (interaction) {
pineafan63fc5e22022-08-04 22:04:10 +0100263 const em = new Discord.MessageEmbed(pages[page].embed);
Skyler Grey75ea9172022-08-06 10:22:23 +0100264 em.setDescription(
265 em.description +
266 "\n\n" +
267 createPageIndicator(pages.length, page)
268 );
pineafan813bdf42022-07-24 10:39:10 +0100269 await interaction.editReply({
270 embeds: [em],
271 components: components
272 });
273 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100274 const em = new Discord.MessageEmbed(pages[page].embed);
Skyler Grey75ea9172022-08-06 10:22:23 +0100275 em.setDescription(
276 em.description +
277 "\n\n" +
278 createPageIndicator(pages.length, page)
279 );
pineafan813bdf42022-07-24 10:39:10 +0100280 await m.edit({
281 embeds: [em],
282 components: components,
283 fetchReply: true
284 });
285 }
pineafan63fc5e22022-08-04 22:04:10 +0100286 let i;
pineafan813bdf42022-07-24 10:39:10 +0100287 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100288 i = await m.awaitMessageComponent({
289 filter: interaction
290 ? () => {
291 return true;
292 }
293 : f,
294 time: 300000
295 });
296 } catch (e) {
297 break;
298 }
pineafan63fc5e22022-08-04 22:04:10 +0100299 i.deferUpdate();
pineafane23c4ec2022-07-27 21:56:27 +0100300 if (i.component.customId === "left") {
pineafan813bdf42022-07-24 10:39:10 +0100301 if (page > 0) page--;
302 selectPaneOpen = false;
pineafane23c4ec2022-07-27 21:56:27 +0100303 } else if (i.component.customId === "right") {
pineafan813bdf42022-07-24 10:39:10 +0100304 if (page < pages.length - 1) page++;
305 selectPaneOpen = false;
pineafane23c4ec2022-07-27 21:56:27 +0100306 } else if (i.component.customId === "select") {
pineafan813bdf42022-07-24 10:39:10 +0100307 selectPaneOpen = !selectPaneOpen;
pineafane23c4ec2022-07-27 21:56:27 +0100308 } else if (i.component.customId === "page") {
pineafan813bdf42022-07-24 10:39:10 +0100309 page = parseInt(i.values[0]);
310 selectPaneOpen = false;
311 } else {
312 if (interaction) {
pineafan63fc5e22022-08-04 22:04:10 +0100313 const em = new Discord.MessageEmbed(pages[page].embed);
Skyler Grey75ea9172022-08-06 10:22:23 +0100314 em.setDescription(
315 em.description +
316 "\n\n" +
317 createPageIndicator(pages.length, page)
318 );
319 em.setFooter({ text: "Message closed" });
320 interaction.editReply({
321 embeds: [em],
322 components: [
323 new MessageActionRow().addComponents([
324 new MessageButton()
325 .setCustomId("left")
326 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
327 .setStyle("SECONDARY")
328 .setDisabled(true),
329 new MessageButton()
330 .setCustomId("select")
331 .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
332 .setStyle(
333 selectPaneOpen ? "PRIMARY" : "SECONDARY"
334 )
335 .setDisabled(true),
336 new MessageButton()
337 .setCustomId("right")
338 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
339 .setStyle("SECONDARY")
340 .setDisabled(true)
341 ])
342 ]
343 });
pineafan813bdf42022-07-24 10:39:10 +0100344 } else {
345 m.delete();
346 }
347 return;
348 }
349 }
pineafan813bdf42022-07-24 10:39:10 +0100350 if (interaction) {
pineafan63fc5e22022-08-04 22:04:10 +0100351 const em = new Discord.MessageEmbed(pages[page].embed);
Skyler Grey75ea9172022-08-06 10:22:23 +0100352 em.setDescription(
353 em.description + "\n\n" + createPageIndicator(pages.length, page)
354 ).setFooter({ text: "Message timed out" });
pineafan813bdf42022-07-24 10:39:10 +0100355 await interaction.editReply({
356 embeds: [em],
Skyler Grey75ea9172022-08-06 10:22:23 +0100357 components: [
358 new MessageActionRow().addComponents([
359 new MessageButton()
360 .setCustomId("left")
361 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
362 .setStyle("SECONDARY")
363 .setDisabled(true),
364 new MessageButton()
365 .setCustomId("select")
366 .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
367 .setStyle("SECONDARY")
368 .setDisabled(true),
369 new MessageButton()
370 .setCustomId("right")
371 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
372 .setStyle("SECONDARY")
373 .setDisabled(true)
374 ])
375 ]
pineafan813bdf42022-07-24 10:39:10 +0100376 });
377 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100378 const em = new Discord.MessageEmbed(pages[page].embed);
Skyler Grey75ea9172022-08-06 10:22:23 +0100379 em.setDescription(
380 em.description + "\n\n" + createPageIndicator(pages.length, page)
381 ).setFooter({ text: "Message timed out" });
pineafan813bdf42022-07-24 10:39:10 +0100382 await m.edit({
383 embeds: [em],
Skyler Grey75ea9172022-08-06 10:22:23 +0100384 components: [
385 new MessageActionRow().addComponents([
386 new MessageButton()
387 .setCustomId("left")
388 .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
389 .setStyle("SECONDARY")
390 .setDisabled(true),
391 new MessageButton()
392 .setCustomId("select")
393 .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
394 .setStyle("SECONDARY")
395 .setDisabled(true),
396 new MessageButton()
397 .setCustomId("right")
398 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
399 .setStyle("SECONDARY")
400 .setDisabled(true)
401 ])
402 ]
pineafan813bdf42022-07-24 10:39:10 +0100403 });
404 }
pineafan63fc5e22022-08-04 22:04:10 +0100405};