blob: 517d7f4ae9d6efbacea45a1a5f052f847a61980d [file] [log] [blame]
pineafane23c4ec2022-07-27 21:56:27 +01001import { LoadingEmbed } from './../utils/defaultEmbeds.js';
pineafan813bdf42022-07-24 10:39:10 +01002import { SelectMenuOption } from '@discordjs/builders';
3import Discord, { MessageActionRow, MessageButton } from "discord.js";
4import EmojiEmbed from "../utils/generateEmojiEmbed.js";
5import getEmojiByName from "../utils/getEmojiByName.js";
6import createPageIndicator from "../utils/createPageIndicator.js";
7import client from "../utils/client.js";
8
9class Embed {
10 embed: Discord.MessageEmbed;
11 title: string;
12 description: string = "";
13 pageId: number = 0;
14 setEmbed(embed: Discord.MessageEmbed) { this.embed = embed; return this; }
15 setTitle(title: string) { this.title = title; return this; }
16 setDescription(description: string) { this.description = description; return this; }
17 setPageId(pageId: number) { this.pageId = pageId; return this; }
18}
19
20export default async (guild, interaction?) => {
21 let c = guild.publicUpdatesChannel ? guild.publicUpdatesChannel : guild.systemChannel;
22 c = c ? c : guild.channels.cache.find(ch => ch.type === "GUILD_TEXT" && ch.permissionsFor(guild.roles.everyone).has("SEND_MESSAGES") && ch.permissionsFor(guild.me).has("EMBED_LINKS"));
23 let pages = [
24 new Embed()
25 .setEmbed(new EmojiEmbed()
26 .setTitle("Welcome to Nucleus")
27 .setDescription(
28 "Thanks for adding Nucleus to your server\n\n" +
29 "On the next few pages you can find instructions on getting started, and commands you may want to set up\n\n" +
30 "If you need support, have questions or want features, you can let us know in [Clicks](https://discord.gg/bPaNnxe)"
31 )
32 .setEmoji("NUCLEUS.LOGO")
33 .setStatus("Danger")
34 ).setTitle("Welcome").setDescription("About Nucleus").setPageId(0),
35 new Embed()
36 .setEmbed(new EmojiEmbed()
37 .setTitle("Logging")
38 .setDescription(
39 "Nucleus can log server events and keep you informed with what content is being posted to your server.\n" +
40 "We have 2 different types of logs, which each can be configured to send to a channel of your choice:\n" +
41 "**General Logs:** These are events like kicks and channel changes etc.\n" +
42 "**Warning Logs:** Warnings like NSFW avatars and spam etc. that may require action by a server staff member. " +
43 "These go to to a separate staff notifications channel.\n\n" +
44 "A general log channel can be set with `/settings log`\n" +
45 "A warning log channel can be set with `/settings warnings channel`"
46 )
47 .setEmoji("ICONS.LOGGING")
48 .setStatus("Danger")
49 ).setTitle("Logging").setDescription("Logging, staff warning logs etc.").setPageId(1),
50 new Embed()
51 .setEmbed(new EmojiEmbed()
52 .setTitle("Moderation")
53 .setDescription(
54 "Nucleus has a number of commands that can be used to moderate your server.\n" +
55 "These commands are all found under `/mod`, and they include:\n" +
56 `**${getEmojiByName("PUNISH.WARN.YELLOW")} Warn:** The user is warned (via DM) that they violated server rules.\n` +
57 `**${getEmojiByName("PUNISH.CLEARHISTORY")} Clear:** Some messages from a user are deleted in a channel.\n` +
58 `**${getEmojiByName("PUNISH.MUTE.YELLOW")} Mute:** The user is unable to send messages or join voice chats.\n` +
59 `**${getEmojiByName("PUNISH.MUTE.GREEN")} Unmute:** The user is able to send messages in the server.\n` +
60 `**${getEmojiByName("PUNISH.KICK.RED")} Kick:** The user is removed from the server.\n` +
61 `**${getEmojiByName("PUNISH.SOFTBAN")} Softban:** Kicks the user, deleting their messages from every channel.\n` +
62 `**${getEmojiByName("PUNISH.BAN.RED")} Ban:** The user is removed from the server, and they are unable to rejoin.\n` +
63 `**${getEmojiByName("PUNISH.BAN.GREEN")} Unban:** The user is able to rejoin the server.`
64 )
65 .setEmoji("PUNISH.BAN.RED")
66 .setStatus("Danger")
67 ).setTitle("Moderation").setDescription("Basic moderation commands").setPageId(2),
68 new Embed()
69 .setEmbed(new EmojiEmbed()
70 .setTitle("Verify")
71 .setDescription(
72 "Nucleus has a verification system that allows users to prove they aren't bots.\n" +
73 "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" +
74 "After the user complete's the CAPTCHA, they are given a role and can use the permissions accordingly.\n" +
75 "You can set the role given with `/settings verify`"
76 )
77 .setEmoji("CONTROL.REDTICK")
78 .setStatus("Danger")
79 ).setTitle("Verify").setDescription("Captcha verification system").setPageId(3),
80 new Embed()
81 .setEmbed(new EmojiEmbed()
82 .setTitle("Content Scanning")
83 .setDescription(
84 "Nucleus has a content scanning system that automatically scans links and images sent by users.\n" +
85 "Nucleus can detect, delete, and punish users for sending NSFW content, or links to scam or adult sites.\n" +
86 "You can set the threshold for this in `/settings automation`" // TODO
87 )
88 .setEmoji("MOD.IMAGES.TOOSMALL")
89 .setStatus("Danger")
90 ).setTitle("Content Scanning").setDescription("Content (NSFW, malware, scams) scanning").setPageId(4),
91 new Embed()
92 .setEmbed(new EmojiEmbed()
93 .setTitle("Tickets")
94 .setDescription(
95 "Nucleus has a ticket system that allows users to create tickets and have a support team respond to them.\n" +
96 "Tickets can be created with `/ticket create` and a channel is created, pinging the user and support role.\n" +
97 "When the ticket is resolved, anyone can run `/ticket close` (or click the button) to close it.\n" +
98 "Running `/ticket close` again will delete the ticket."
99 )
100 .setEmoji("GUILD.TICKET.CLOSE")
101 .setStatus("Danger")
102 ).setTitle("Tickets").setDescription("Ticket system").setPageId(5),
103 new Embed()
104 .setEmbed(new EmojiEmbed()
105 .setTitle("Tags")
106 .setDescription(
107 "Add a tag system to your server with the `/tag` and `/tags` commands.\n" +
108 "To create a tag, type `/tags create <tag name> <tag content>`.\n" +
109 "Tag names and content can be edited with `/tags edit`.\n" +
110 "To delete a tag, type `/tags delete <tag name>`.\n" +
111 "To view all tags, type `/tags list`.\n"
112 )
113 .setEmoji("PUNISH.NICKNAME.RED")
114 .setStatus("Danger")
115 ).setTitle("Tags").setDescription("Tag system").setPageId(6),
116 new Embed()
117 .setEmbed(new EmojiEmbed()
118 .setTitle("Premium")
119 .setDescription(
120 "In the near future, we will be releasing extra premium only features.\n" +
121 "These features will include:\n\n" +
122 "**Attachment logs**\n> When a message with attachments is edited or deleted, the logs will also include the images sent.\n" +
123 "\nPremium is not yet available. Check `/nucleus premium` for updates on features and pricing"
124 )
125 .setEmoji("NUCLEUS.COMMANDS.LOCK")
126 .setStatus("Danger")
127 ).setTitle("Premium").setDescription("Premium features").setPageId(7),
128 ]
129 let m;
pineafane23c4ec2022-07-27 21:56:27 +0100130 if (interaction) { m = await interaction.reply({embeds: LoadingEmbed, fetchReply: true, ephemeral: true}); }
131 else { m = await c.send({embeds: LoadingEmbed }); }
pineafan813bdf42022-07-24 10:39:10 +0100132 let page = 0;
133
134 let f = async (component) => {
135 return (component.member as Discord.GuildMember).permissions.has("MANAGE_GUILD");
136 }
137
138 let selectPaneOpen = false;
139
140 while (true) {
141 let selectPane = []
142
143 if (selectPaneOpen) {
144 let options = [];
145 pages.forEach(embed => {
146 options.push(new SelectMenuOption({
147 label: embed.title,
148 value: embed.pageId.toString(),
149 description: embed.description || "",
150 }))
151 })
152 selectPane = [new MessageActionRow().addComponents([
153 new Discord.MessageSelectMenu()
154 .addOptions(options)
155 .setCustomId("page")
156 .setMaxValues(1)
157 .setPlaceholder("Choose a page...")
158 ])]
159 }
160 let components = selectPane.concat([new MessageActionRow().addComponents([
161 new MessageButton().setCustomId("left").setEmoji(getEmojiByName("CONTROL.LEFT", "id")).setStyle("SECONDARY").setDisabled(page === 0),
162 new MessageButton().setCustomId("select").setEmoji(getEmojiByName("CONTROL.MENU", "id")).setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY").setDisabled(false),
pineafane23c4ec2022-07-27 21:56:27 +0100163 new MessageButton().setCustomId("right").setEmoji(getEmojiByName("CONTROL.RIGHT", "id")).setStyle("SECONDARY").setDisabled(page === pages.length - 1)
pineafan813bdf42022-07-24 10:39:10 +0100164 ])])
165 if (interaction) {
166 let em = new Discord.MessageEmbed(pages[page].embed)
167 em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
168 await interaction.editReply({
169 embeds: [em],
170 components: components
171 });
172 } else {
173 let em = new Discord.MessageEmbed(pages[page].embed)
174 em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
175 await m.edit({
176 embeds: [em],
177 components: components,
178 fetchReply: true
179 });
180 }
181 let i
182 try {
183 i = await m.awaitMessageComponent({filter: interaction ? () => { return true } : f, time: 300000});
184 } catch(e) { break }
185 i.deferUpdate()
pineafane23c4ec2022-07-27 21:56:27 +0100186 if (i.component.customId === "left") {
pineafan813bdf42022-07-24 10:39:10 +0100187 if (page > 0) page--;
188 selectPaneOpen = false;
pineafane23c4ec2022-07-27 21:56:27 +0100189 } else if (i.component.customId === "right") {
pineafan813bdf42022-07-24 10:39:10 +0100190 if (page < pages.length - 1) page++;
191 selectPaneOpen = false;
pineafane23c4ec2022-07-27 21:56:27 +0100192 } else if (i.component.customId === "select") {
pineafan813bdf42022-07-24 10:39:10 +0100193 selectPaneOpen = !selectPaneOpen;
pineafane23c4ec2022-07-27 21:56:27 +0100194 } else if (i.component.customId === "page") {
pineafan813bdf42022-07-24 10:39:10 +0100195 page = parseInt(i.values[0]);
196 selectPaneOpen = false;
197 } else {
198 if (interaction) {
199 let em = new Discord.MessageEmbed(pages[page].embed)
pineafane23c4ec2022-07-27 21:56:27 +0100200 em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
201 em.setFooter({text: "Message closed"})
pineafan813bdf42022-07-24 10:39:10 +0100202 interaction.editReply({embeds: [em], components: [new MessageActionRow().addComponents([
203 new MessageButton().setCustomId("left").setEmoji(getEmojiByName("CONTROL.LEFT", "id")).setStyle("SECONDARY").setDisabled(true),
204 new MessageButton().setCustomId("select").setEmoji(getEmojiByName("CONTROL.MENU", "id")).setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY").setDisabled(true),
pineafane23c4ec2022-07-27 21:56:27 +0100205 new MessageButton().setCustomId("right").setEmoji(getEmojiByName("CONTROL.RIGHT", "id")).setStyle("SECONDARY").setDisabled(true)
206 ])]});
pineafan813bdf42022-07-24 10:39:10 +0100207 } else {
208 m.delete();
209 }
210 return;
211 }
212 }
pineafan813bdf42022-07-24 10:39:10 +0100213 if (interaction) {
214 let em = new Discord.MessageEmbed(pages[page].embed)
pineafane23c4ec2022-07-27 21:56:27 +0100215 em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page)).setFooter({text: "Message timed out"});
pineafan813bdf42022-07-24 10:39:10 +0100216 await interaction.editReply({
217 embeds: [em],
218 components: [new MessageActionRow().addComponents([
219 new MessageButton().setCustomId("left").setEmoji(getEmojiByName("CONTROL.LEFT", "id")).setStyle("SECONDARY").setDisabled(true),
220 new MessageButton().setCustomId("select").setEmoji(getEmojiByName("CONTROL.MENU", "id")).setStyle("SECONDARY").setDisabled(true),
pineafane23c4ec2022-07-27 21:56:27 +0100221 new MessageButton().setCustomId("right").setEmoji(getEmojiByName("CONTROL.RIGHT", "id")).setStyle("SECONDARY").setDisabled(true)
pineafan813bdf42022-07-24 10:39:10 +0100222 ])]
223 });
224 } else {
225 let em = new Discord.MessageEmbed(pages[page].embed)
pineafane23c4ec2022-07-27 21:56:27 +0100226 em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page)).setFooter({text: "Message timed out"});
pineafan813bdf42022-07-24 10:39:10 +0100227 await m.edit({
228 embeds: [em],
229 components: [new MessageActionRow().addComponents([
230 new MessageButton().setCustomId("left").setEmoji(getEmojiByName("CONTROL.LEFT", "id")).setStyle("SECONDARY").setDisabled(true),
231 new MessageButton().setCustomId("select").setEmoji(getEmojiByName("CONTROL.MENU", "id")).setStyle("SECONDARY").setDisabled(true),
pineafane23c4ec2022-07-27 21:56:27 +0100232 new MessageButton().setCustomId("right").setEmoji(getEmojiByName("CONTROL.RIGHT", "id")).setStyle("SECONDARY").setDisabled(true)
pineafan813bdf42022-07-24 10:39:10 +0100233 ])]
234 });
235 }
236}