blob: d1c2011f7ec75c7c084f8d8e6e715d1d0d4c41b8 [file] [log] [blame]
pineafan63fc5e22022-08-04 22:04:10 +01001import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
Skyler Grey75ea9172022-08-06 10:22:23 +01002import Discord, {
3 Channel,
4 CommandInteraction,
5 Message,
6 MessageActionRow,
7 MessageButton,
8 MessageComponentInteraction,
9 Role
10} from "discord.js";
Skyler Greyc634e2b2022-08-06 17:50:48 +010011import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
pineafan41d93562022-07-30 22:10:15 +010012import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
pineafan63fc5e22022-08-04 22:04:10 +010013import client from "../../utils/client.js";
14import confirmationMessage from "../../utils/confirmationMessage.js";
15import generateKeyValueList from "../../utils/generateKeyValueList.js";
Skyler Greyc634e2b2022-08-06 17:50:48 +010016import { ChannelType } from "discord-api-types/v9";
pineafan63fc5e22022-08-04 22:04:10 +010017import getEmojiByName from "../../utils/getEmojiByName.js";
pineafan41d93562022-07-30 22:10:15 +010018
19const command = (builder: SlashCommandSubcommandBuilder) =>
20 builder
pineafan63fc5e22022-08-04 22:04:10 +010021 .setName("welcome")
Skyler Grey11236ba2022-08-08 21:13:33 +010022 .setDescription("Messages and roles sent or given when someone joins the server")
Skyler Grey75ea9172022-08-06 10:22:23 +010023 .addStringOption((option) =>
24 option
25 .setName("message")
Skyler Grey11236ba2022-08-08 21:13:33 +010026 .setDescription("The message to send when someone joins the server")
Skyler Grey75ea9172022-08-06 10:22:23 +010027 .setAutocomplete(true)
28 )
29 .addRoleOption((option) =>
Skyler Grey11236ba2022-08-08 21:13:33 +010030 option.setName("role").setDescription("The role given when someone joins the server")
Skyler Grey75ea9172022-08-06 10:22:23 +010031 )
32 .addRoleOption((option) =>
Skyler Grey11236ba2022-08-08 21:13:33 +010033 option.setName("ping").setDescription("The role pinged when someone joins the server")
Skyler Grey75ea9172022-08-06 10:22:23 +010034 )
35 .addChannelOption((option) =>
36 option
37 .setName("channel")
Skyler Grey11236ba2022-08-08 21:13:33 +010038 .setDescription("The channel the welcome message should be sent to")
Skyler Grey75ea9172022-08-06 10:22:23 +010039 .addChannelTypes([ChannelType.GuildText, ChannelType.GuildNews])
40 );
pineafan41d93562022-07-30 22:10:15 +010041
Skyler Greyc634e2b2022-08-06 17:50:48 +010042const callback = async (interaction: CommandInteraction): Promise<unknown> => {
Skyler Grey11236ba2022-08-08 21:13:33 +010043 const { renderRole, renderChannel, log, NucleusColors, entry, renderUser } = client.logger;
Skyler Grey75ea9172022-08-06 10:22:23 +010044 await interaction.reply({
45 embeds: LoadingEmbed,
46 fetchReply: true,
47 ephemeral: true
48 });
Skyler Grey1a67e182022-08-04 23:05:44 +010049 let m: Message;
Skyler Grey75ea9172022-08-06 10:22:23 +010050 if (
51 interaction.options.getRole("role") ||
52 interaction.options.getChannel("channel") ||
53 interaction.options.getString("message")
54 ) {
Skyler Grey1a67e182022-08-04 23:05:44 +010055 let role: Role;
56 let ping: Role;
pineafan63fc5e22022-08-04 22:04:10 +010057 const message = interaction.options.getString("message");
pineafan41d93562022-07-30 22:10:15 +010058 try {
Skyler Grey1a67e182022-08-04 23:05:44 +010059 role = interaction.options.getRole("role") as Role;
60 ping = interaction.options.getRole("ping") as Role;
pineafan41d93562022-07-30 22:10:15 +010061 } catch {
Skyler Grey75ea9172022-08-06 10:22:23 +010062 return await interaction.editReply({
63 embeds: [
64 new EmojiEmbed()
65 .setEmoji("GUILD.ROLES.DELETE")
66 .setTitle("Welcome Events")
Skyler Grey11236ba2022-08-08 21:13:33 +010067 .setDescription("The role you provided is not a valid role")
Skyler Grey75ea9172022-08-06 10:22:23 +010068 .setStatus("Danger")
69 ]
70 });
pineafan41d93562022-07-30 22:10:15 +010071 }
Skyler Grey1a67e182022-08-04 23:05:44 +010072 let channel: Channel;
pineafan41d93562022-07-30 22:10:15 +010073 try {
Skyler Grey1a67e182022-08-04 23:05:44 +010074 channel = interaction.options.getChannel("channel") as Channel;
pineafan41d93562022-07-30 22:10:15 +010075 } catch {
Skyler Grey75ea9172022-08-06 10:22:23 +010076 return await interaction.editReply({
77 embeds: [
78 new EmojiEmbed()
79 .setEmoji("GUILD.ROLES.DELETE")
80 .setTitle("Welcome Events")
Skyler Grey11236ba2022-08-08 21:13:33 +010081 .setDescription("The channel you provided is not a valid channel")
Skyler Grey75ea9172022-08-06 10:22:23 +010082 .setStatus("Danger")
83 ]
84 });
pineafan41d93562022-07-30 22:10:15 +010085 }
pineafan63fc5e22022-08-04 22:04:10 +010086 const options = {};
Skyler Grey75ea9172022-08-06 10:22:23 +010087 if (role) options.role = renderRole(role);
88 if (ping) options.ping = renderRole(ping);
89 if (channel) options.channel = renderChannel(channel);
90 if (message) options.message = "\n> " + message;
pineafan63fc5e22022-08-04 22:04:10 +010091 const confirmation = await new confirmationMessage(interaction)
pineafan41d93562022-07-30 22:10:15 +010092 .setEmoji("GUILD.ROLES.EDIT")
93 .setTitle("Welcome Events")
94 .setDescription(generateKeyValueList(options))
95 .setColor("Warning")
96 .setInverted(true)
pineafan63fc5e22022-08-04 22:04:10 +010097 .send(true);
98 if (confirmation.cancelled) return;
pineafan41d93562022-07-30 22:10:15 +010099 if (confirmation.success) {
100 try {
pineafan63fc5e22022-08-04 22:04:10 +0100101 const toChange = {};
102 if (role) toChange["welcome.role"] = role.id;
103 if (ping) toChange["welcome.ping"] = ping.id;
104 if (channel) toChange["welcome.channel"] = channel.id;
105 if (message) toChange["welcome.message"] = message;
Skyler Grey11236ba2022-08-08 21:13:33 +0100106 await client.database.guilds.write(interaction.guild.id, toChange);
pineafan63fc5e22022-08-04 22:04:10 +0100107 const list = {
Skyler Grey11236ba2022-08-08 21:13:33 +0100108 memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
109 changedBy: entry(interaction.user.id, renderUser(interaction.user))
pineafan63fc5e22022-08-04 22:04:10 +0100110 };
Skyler Grey75ea9172022-08-06 10:22:23 +0100111 if (role) list.role = entry(role.id, renderRole(role));
112 if (ping) list.ping = entry(ping.id, renderRole(ping));
Skyler Grey11236ba2022-08-08 21:13:33 +0100113 if (channel) list.channel = entry(channel.id, renderChannel(channel.id));
Skyler Grey75ea9172022-08-06 10:22:23 +0100114 if (message) list.message = entry(message, `\`${message}\``);
pineafan63fc5e22022-08-04 22:04:10 +0100115 const data = {
Skyler Grey75ea9172022-08-06 10:22:23 +0100116 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100117 type: "welcomeSettingsUpdated",
118 displayName: "Welcome Settings Changed",
119 calculateType: "nucleusSettingsUpdated",
120 color: NucleusColors.green,
121 emoji: "CONTROL.BLOCKTICK",
122 timestamp: new Date().getTime()
123 },
124 list: list,
125 hidden: {
126 guild: interaction.guild.id
pineafan41d93562022-07-30 22:10:15 +0100127 }
pineafan63fc5e22022-08-04 22:04:10 +0100128 };
129 log(data);
pineafan41d93562022-07-30 22:10:15 +0100130 } catch (e) {
pineafan63fc5e22022-08-04 22:04:10 +0100131 console.log(e);
Skyler Grey75ea9172022-08-06 10:22:23 +0100132 return interaction.editReply({
133 embeds: [
134 new EmojiEmbed()
135 .setTitle("Welcome Events")
Skyler Grey11236ba2022-08-08 21:13:33 +0100136 .setDescription("Something went wrong while updating welcome settings")
Skyler Grey75ea9172022-08-06 10:22:23 +0100137 .setStatus("Danger")
138 .setEmoji("GUILD.ROLES.DELETE")
139 ],
140 components: []
141 });
pineafan41d93562022-07-30 22:10:15 +0100142 }
143 } else {
Skyler Grey75ea9172022-08-06 10:22:23 +0100144 return interaction.editReply({
145 embeds: [
146 new EmojiEmbed()
147 .setTitle("Welcome Events")
148 .setDescription("No changes were made")
149 .setStatus("Success")
150 .setEmoji("GUILD.ROLES.CREATE")
151 ],
152 components: []
153 });
pineafan41d93562022-07-30 22:10:15 +0100154 }
155 }
pineafan63fc5e22022-08-04 22:04:10 +0100156 let lastClicked = null;
pineafan41d93562022-07-30 22:10:15 +0100157 while (true) {
pineafan63fc5e22022-08-04 22:04:10 +0100158 const config = await client.database.guilds.read(interaction.guild.id);
Skyler Grey75ea9172022-08-06 10:22:23 +0100159 m = (await interaction.editReply({
160 embeds: [
161 new EmojiEmbed()
162 .setTitle("Welcome Events")
163 .setDescription(
Skyler Grey11236ba2022-08-08 21:13:33 +0100164 `**Message:** ${config.welcome.message ? `\n> ${config.welcome.message}` : "*None set*"}\n` +
Skyler Grey75ea9172022-08-06 10:22:23 +0100165 `**Role:** ${
166 config.welcome.role
Skyler Grey11236ba2022-08-08 21:13:33 +0100167 ? renderRole(await interaction.guild.roles.fetch(config.welcome.role))
Skyler Grey75ea9172022-08-06 10:22:23 +0100168 : "*None set*"
169 }\n` +
170 `**Ping:** ${
171 config.welcome.ping
Skyler Grey11236ba2022-08-08 21:13:33 +0100172 ? renderRole(await interaction.guild.roles.fetch(config.welcome.ping))
Skyler Grey75ea9172022-08-06 10:22:23 +0100173 : "*None set*"
174 }\n` +
175 `**Channel:** ${
176 config.welcome.channel
177 ? config.welcome.channel == "dm"
178 ? "DM"
Skyler Grey11236ba2022-08-08 21:13:33 +0100179 : renderChannel(await interaction.guild.channels.fetch(config.welcome.channel))
Skyler Grey75ea9172022-08-06 10:22:23 +0100180 : "*None set*"
181 }`
182 )
183 .setStatus("Success")
184 .setEmoji("CHANNEL.TEXT.CREATE")
185 ],
186 components: [
187 new MessageActionRow().addComponents([
188 new MessageButton()
Skyler Grey11236ba2022-08-08 21:13:33 +0100189 .setLabel(lastClicked == "clear-message" ? "Click again to confirm" : "Clear Message")
Skyler Grey75ea9172022-08-06 10:22:23 +0100190 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
191 .setCustomId("clear-message")
192 .setDisabled(!config.welcome.message)
193 .setStyle("DANGER"),
194 new MessageButton()
Skyler Grey11236ba2022-08-08 21:13:33 +0100195 .setLabel(lastClicked == "clear-role" ? "Click again to confirm" : "Clear Role")
Skyler Grey75ea9172022-08-06 10:22:23 +0100196 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
197 .setCustomId("clear-role")
198 .setDisabled(!config.welcome.role)
199 .setStyle("DANGER"),
200 new MessageButton()
Skyler Grey11236ba2022-08-08 21:13:33 +0100201 .setLabel(lastClicked == "clear-ping" ? "Click again to confirm" : "Clear Ping")
Skyler Grey75ea9172022-08-06 10:22:23 +0100202 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
203 .setCustomId("clear-ping")
204 .setDisabled(!config.welcome.ping)
205 .setStyle("DANGER"),
206 new MessageButton()
Skyler Grey11236ba2022-08-08 21:13:33 +0100207 .setLabel(lastClicked == "clear-channel" ? "Click again to confirm" : "Clear Channel")
Skyler Grey75ea9172022-08-06 10:22:23 +0100208 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
209 .setCustomId("clear-channel")
210 .setDisabled(!config.welcome.channel)
211 .setStyle("DANGER"),
212 new MessageButton()
213 .setLabel("Set Channel to DM")
214 .setCustomId("set-channel-dm")
215 .setDisabled(config.welcome.channel == "dm")
216 .setStyle("SECONDARY")
217 ])
218 ]
219 })) as Message;
Skyler Grey1a67e182022-08-04 23:05:44 +0100220 let i: MessageComponentInteraction;
pineafan41d93562022-07-30 22:10:15 +0100221 try {
222 i = await m.awaitMessageComponent({ time: 300000 });
223 } catch (e) {
pineafan63fc5e22022-08-04 22:04:10 +0100224 break;
pineafan41d93562022-07-30 22:10:15 +0100225 }
pineafan63fc5e22022-08-04 22:04:10 +0100226 i.deferUpdate();
pineafan41d93562022-07-30 22:10:15 +0100227 if (i.customId == "clear-message") {
228 if (lastClicked == "clear-message") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100229 await client.database.guilds.write(interaction.guild.id, {
230 "welcome.message": null
231 });
pineafan63fc5e22022-08-04 22:04:10 +0100232 lastClicked = null;
Skyler Grey75ea9172022-08-06 10:22:23 +0100233 } else {
234 lastClicked = "clear-message";
235 }
pineafan41d93562022-07-30 22:10:15 +0100236 } else if (i.customId == "clear-role") {
237 if (lastClicked == "clear-role") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100238 await client.database.guilds.write(interaction.guild.id, {
239 "welcome.role": null
240 });
pineafan63fc5e22022-08-04 22:04:10 +0100241 lastClicked = null;
Skyler Grey75ea9172022-08-06 10:22:23 +0100242 } else {
243 lastClicked = "clear-role";
244 }
pineafan41d93562022-07-30 22:10:15 +0100245 } else if (i.customId == "clear-ping") {
246 if (lastClicked == "clear-ping") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100247 await client.database.guilds.write(interaction.guild.id, {
248 "welcome.ping": null
249 });
pineafan63fc5e22022-08-04 22:04:10 +0100250 lastClicked = null;
Skyler Grey75ea9172022-08-06 10:22:23 +0100251 } else {
252 lastClicked = "clear-ping";
253 }
pineafan41d93562022-07-30 22:10:15 +0100254 } else if (i.customId == "clear-channel") {
255 if (lastClicked == "clear-channel") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100256 await client.database.guilds.write(interaction.guild.id, {
257 "welcome.channel": null
258 });
pineafan63fc5e22022-08-04 22:04:10 +0100259 lastClicked = null;
Skyler Grey75ea9172022-08-06 10:22:23 +0100260 } else {
261 lastClicked = "clear-channel";
262 }
pineafan41d93562022-07-30 22:10:15 +0100263 } else if (i.customId == "set-channel-dm") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100264 await client.database.guilds.write(interaction.guild.id, {
265 "welcome.channel": "dm"
266 });
pineafan63fc5e22022-08-04 22:04:10 +0100267 lastClicked = null;
pineafan41d93562022-07-30 22:10:15 +0100268 }
269 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100270 await interaction.editReply({
271 embeds: [m.embeds[0].setFooter({ text: "Message closed" })],
272 components: []
273 });
pineafan63fc5e22022-08-04 22:04:10 +0100274};
pineafan41d93562022-07-30 22:10:15 +0100275
Skyler Grey1a67e182022-08-04 23:05:44 +0100276const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100277 const member = interaction.member as Discord.GuildMember;
278 if (!member.permissions.has("MANAGE_GUILD"))
Skyler Grey11236ba2022-08-08 21:13:33 +0100279 throw new Error("You must have the *Manage Server* permission to use this command");
pineafan41d93562022-07-30 22:10:15 +0100280 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100281};
pineafan41d93562022-07-30 22:10:15 +0100282
283export { command };
284export { callback };
Skyler Grey1a67e182022-08-04 23:05:44 +0100285export { check };