blob: 5284f8a7da98a55ee1cca4632380c03b4944abe4 [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,
TheCodedProf21c08592022-09-13 14:14:43 -04006 ActionRowBuilder,
7 ButtonBuilder,
Skyler Grey75ea9172022-08-06 10:22:23 +01008 MessageComponentInteraction,
TheCodedProf21c08592022-09-13 14:14:43 -04009 Role,
10 ButtonStyle
Skyler Grey75ea9172022-08-06 10:22:23 +010011} from "discord.js";
Skyler Greyc634e2b2022-08-06 17:50:48 +010012import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
pineafan41d93562022-07-30 22:10:15 +010013import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
pineafan63fc5e22022-08-04 22:04:10 +010014import client from "../../utils/client.js";
15import confirmationMessage from "../../utils/confirmationMessage.js";
16import generateKeyValueList from "../../utils/generateKeyValueList.js";
Skyler Greyc634e2b2022-08-06 17:50:48 +010017import { ChannelType } from "discord-api-types/v9";
pineafan63fc5e22022-08-04 22:04:10 +010018import getEmojiByName from "../../utils/getEmojiByName.js";
pineafan41d93562022-07-30 22:10:15 +010019
20const command = (builder: SlashCommandSubcommandBuilder) =>
21 builder
pineafan63fc5e22022-08-04 22:04:10 +010022 .setName("welcome")
Skyler Grey11236ba2022-08-08 21:13:33 +010023 .setDescription("Messages and roles sent or given when someone joins the server")
Skyler Grey75ea9172022-08-06 10:22:23 +010024 .addStringOption((option) =>
25 option
26 .setName("message")
Skyler Grey11236ba2022-08-08 21:13:33 +010027 .setDescription("The message to send when someone joins the server")
Skyler Grey75ea9172022-08-06 10:22:23 +010028 .setAutocomplete(true)
29 )
30 .addRoleOption((option) =>
Skyler Grey11236ba2022-08-08 21:13:33 +010031 option.setName("role").setDescription("The role given when someone joins the server")
Skyler Grey75ea9172022-08-06 10:22:23 +010032 )
33 .addRoleOption((option) =>
Skyler Grey11236ba2022-08-08 21:13:33 +010034 option.setName("ping").setDescription("The role pinged when someone joins the server")
Skyler Grey75ea9172022-08-06 10:22:23 +010035 )
36 .addChannelOption((option) =>
37 option
38 .setName("channel")
Skyler Grey11236ba2022-08-08 21:13:33 +010039 .setDescription("The channel the welcome message should be sent to")
PineaFan64486c42022-12-28 09:21:04 +000040 .addChannelTypes(ChannelType.GuildText)
Skyler Grey75ea9172022-08-06 10:22:23 +010041 );
pineafan41d93562022-07-30 22:10:15 +010042
Skyler Greyc634e2b2022-08-06 17:50:48 +010043const callback = async (interaction: CommandInteraction): Promise<unknown> => {
Skyler Grey11236ba2022-08-08 21:13:33 +010044 const { renderRole, renderChannel, log, NucleusColors, entry, renderUser } = client.logger;
Skyler Grey75ea9172022-08-06 10:22:23 +010045 await interaction.reply({
46 embeds: LoadingEmbed,
47 fetchReply: true,
48 ephemeral: true
49 });
Skyler Grey1a67e182022-08-04 23:05:44 +010050 let m: Message;
Skyler Grey75ea9172022-08-06 10:22:23 +010051 if (
52 interaction.options.getRole("role") ||
53 interaction.options.getChannel("channel") ||
54 interaction.options.getString("message")
55 ) {
pineafan4e425942022-08-08 22:01:47 +010056 let role: Role | null;
57 let ping: Role | null;
58 let channel: Channel | null;
59 const message: string | null = interaction.options.getString("message");
pineafan41d93562022-07-30 22:10:15 +010060 try {
pineafan4e425942022-08-08 22:01:47 +010061 role = interaction.options.getRole("role") as Role | null;
62 ping = interaction.options.getRole("ping") as Role | null;
pineafan41d93562022-07-30 22:10:15 +010063 } catch {
Skyler Grey75ea9172022-08-06 10:22:23 +010064 return await interaction.editReply({
65 embeds: [
66 new EmojiEmbed()
67 .setEmoji("GUILD.ROLES.DELETE")
68 .setTitle("Welcome Events")
Skyler Grey11236ba2022-08-08 21:13:33 +010069 .setDescription("The role you provided is not a valid role")
Skyler Grey75ea9172022-08-06 10:22:23 +010070 .setStatus("Danger")
71 ]
72 });
pineafan41d93562022-07-30 22:10:15 +010073 }
pineafan41d93562022-07-30 22:10:15 +010074 try {
pineafan4e425942022-08-08 22:01:47 +010075 channel = interaction.options.getChannel("channel") as Channel | null;
pineafan41d93562022-07-30 22:10:15 +010076 } catch {
Skyler Grey75ea9172022-08-06 10:22:23 +010077 return await interaction.editReply({
78 embeds: [
79 new EmojiEmbed()
80 .setEmoji("GUILD.ROLES.DELETE")
81 .setTitle("Welcome Events")
Skyler Grey11236ba2022-08-08 21:13:33 +010082 .setDescription("The channel you provided is not a valid channel")
Skyler Grey75ea9172022-08-06 10:22:23 +010083 .setStatus("Danger")
84 ]
85 });
pineafan41d93562022-07-30 22:10:15 +010086 }
pineafan4e425942022-08-08 22:01:47 +010087 const options: {
88 role?: string;
89 ping?: string;
90 channel?: string;
91 message?: string;
92 } = {};
93
Skyler Grey75ea9172022-08-06 10:22:23 +010094 if (role) options.role = renderRole(role);
95 if (ping) options.ping = renderRole(ping);
96 if (channel) options.channel = renderChannel(channel);
97 if (message) options.message = "\n> " + message;
pineafan63fc5e22022-08-04 22:04:10 +010098 const confirmation = await new confirmationMessage(interaction)
pineafan62ce1922022-08-25 20:34:45 +010099 .setEmoji("GUILD.ROLES.EDIT", "GUILD.ROLES.DELETE")
pineafan41d93562022-07-30 22:10:15 +0100100 .setTitle("Welcome Events")
101 .setDescription(generateKeyValueList(options))
102 .setColor("Warning")
103 .setInverted(true)
pineafan63fc5e22022-08-04 22:04:10 +0100104 .send(true);
105 if (confirmation.cancelled) return;
pineafan41d93562022-07-30 22:10:15 +0100106 if (confirmation.success) {
107 try {
pineafan4e425942022-08-08 22:01:47 +0100108 const toChange: {
109 "welcome.role"?: string;
110 "welcome.ping"?: string;
111 "welcome.channel"?: string;
112 "welcome.message"?: string;
113 } = {};
pineafan63fc5e22022-08-04 22:04:10 +0100114 if (role) toChange["welcome.role"] = role.id;
115 if (ping) toChange["welcome.ping"] = ping.id;
116 if (channel) toChange["welcome.channel"] = channel.id;
117 if (message) toChange["welcome.message"] = message;
pineafan4e425942022-08-08 22:01:47 +0100118 await client.database.guilds.write(interaction.guild!.id, toChange);
119 const list: {
120 memberId: ReturnType<typeof entry>;
121 changedBy: ReturnType<typeof entry>;
122 role?: ReturnType<typeof entry>;
123 ping?: ReturnType<typeof entry>;
124 channel?: ReturnType<typeof entry>;
125 message?: ReturnType<typeof entry>;
126 } = {
Skyler Grey11236ba2022-08-08 21:13:33 +0100127 memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
128 changedBy: entry(interaction.user.id, renderUser(interaction.user))
pineafan63fc5e22022-08-04 22:04:10 +0100129 };
Skyler Grey75ea9172022-08-06 10:22:23 +0100130 if (role) list.role = entry(role.id, renderRole(role));
131 if (ping) list.ping = entry(ping.id, renderRole(ping));
Skyler Grey11236ba2022-08-08 21:13:33 +0100132 if (channel) list.channel = entry(channel.id, renderChannel(channel.id));
Skyler Grey75ea9172022-08-06 10:22:23 +0100133 if (message) list.message = entry(message, `\`${message}\``);
pineafan63fc5e22022-08-04 22:04:10 +0100134 const data = {
Skyler Grey75ea9172022-08-06 10:22:23 +0100135 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100136 type: "welcomeSettingsUpdated",
137 displayName: "Welcome Settings Changed",
138 calculateType: "nucleusSettingsUpdated",
139 color: NucleusColors.green,
140 emoji: "CONTROL.BLOCKTICK",
141 timestamp: new Date().getTime()
142 },
143 list: list,
144 hidden: {
pineafan4e425942022-08-08 22:01:47 +0100145 guild: interaction.guild!.id
pineafan41d93562022-07-30 22:10:15 +0100146 }
pineafan63fc5e22022-08-04 22:04:10 +0100147 };
148 log(data);
pineafan41d93562022-07-30 22:10:15 +0100149 } catch (e) {
pineafan63fc5e22022-08-04 22:04:10 +0100150 console.log(e);
Skyler Grey75ea9172022-08-06 10:22:23 +0100151 return interaction.editReply({
152 embeds: [
153 new EmojiEmbed()
154 .setTitle("Welcome Events")
Skyler Grey11236ba2022-08-08 21:13:33 +0100155 .setDescription("Something went wrong while updating welcome settings")
Skyler Grey75ea9172022-08-06 10:22:23 +0100156 .setStatus("Danger")
157 .setEmoji("GUILD.ROLES.DELETE")
158 ],
159 components: []
160 });
pineafan41d93562022-07-30 22:10:15 +0100161 }
162 } else {
Skyler Grey75ea9172022-08-06 10:22:23 +0100163 return interaction.editReply({
164 embeds: [
165 new EmojiEmbed()
166 .setTitle("Welcome Events")
167 .setDescription("No changes were made")
168 .setStatus("Success")
169 .setEmoji("GUILD.ROLES.CREATE")
170 ],
171 components: []
172 });
pineafan41d93562022-07-30 22:10:15 +0100173 }
174 }
pineafan63fc5e22022-08-04 22:04:10 +0100175 let lastClicked = null;
Skyler Greyad002172022-08-16 18:48:26 +0100176 let timedOut = false;
177 do {
pineafan4e425942022-08-08 22:01:47 +0100178 const config = await client.database.guilds.read(interaction.guild!.id);
Skyler Grey75ea9172022-08-06 10:22:23 +0100179 m = (await interaction.editReply({
180 embeds: [
181 new EmojiEmbed()
182 .setTitle("Welcome Events")
183 .setDescription(
Skyler Grey11236ba2022-08-08 21:13:33 +0100184 `**Message:** ${config.welcome.message ? `\n> ${config.welcome.message}` : "*None set*"}\n` +
Skyler Grey75ea9172022-08-06 10:22:23 +0100185 `**Role:** ${
186 config.welcome.role
pineafan4e425942022-08-08 22:01:47 +0100187 ? renderRole(await interaction.guild!.roles.fetch(config.welcome.role))
Skyler Grey75ea9172022-08-06 10:22:23 +0100188 : "*None set*"
189 }\n` +
190 `**Ping:** ${
191 config.welcome.ping
pineafan4e425942022-08-08 22:01:47 +0100192 ? renderRole(await interaction.guild!.roles.fetch(config.welcome.ping))
Skyler Grey75ea9172022-08-06 10:22:23 +0100193 : "*None set*"
194 }\n` +
195 `**Channel:** ${
196 config.welcome.channel
197 ? config.welcome.channel == "dm"
198 ? "DM"
pineafan4e425942022-08-08 22:01:47 +0100199 : renderChannel(await interaction.guild!.channels.fetch(config.welcome.channel))
Skyler Grey75ea9172022-08-06 10:22:23 +0100200 : "*None set*"
201 }`
202 )
203 .setStatus("Success")
204 .setEmoji("CHANNEL.TEXT.CREATE")
205 ],
206 components: [
TheCodedProf21c08592022-09-13 14:14:43 -0400207 new ActionRowBuilder().addComponents([
208 new ButtonBuilder()
Skyler Grey11236ba2022-08-08 21:13:33 +0100209 .setLabel(lastClicked == "clear-message" ? "Click again to confirm" : "Clear Message")
Skyler Grey75ea9172022-08-06 10:22:23 +0100210 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
211 .setCustomId("clear-message")
212 .setDisabled(!config.welcome.message)
TheCodedProf21c08592022-09-13 14:14:43 -0400213 .setStyle(ButtonStyle.Danger),
214 new ButtonBuilder()
Skyler Grey11236ba2022-08-08 21:13:33 +0100215 .setLabel(lastClicked == "clear-role" ? "Click again to confirm" : "Clear Role")
Skyler Grey75ea9172022-08-06 10:22:23 +0100216 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
217 .setCustomId("clear-role")
218 .setDisabled(!config.welcome.role)
TheCodedProf21c08592022-09-13 14:14:43 -0400219 .setStyle(ButtonStyle.Danger),
220 new ButtonBuilder()
Skyler Grey11236ba2022-08-08 21:13:33 +0100221 .setLabel(lastClicked == "clear-ping" ? "Click again to confirm" : "Clear Ping")
Skyler Grey75ea9172022-08-06 10:22:23 +0100222 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
223 .setCustomId("clear-ping")
224 .setDisabled(!config.welcome.ping)
TheCodedProf21c08592022-09-13 14:14:43 -0400225 .setStyle(ButtonStyle.Danger),
226 new ButtonBuilder()
Skyler Grey11236ba2022-08-08 21:13:33 +0100227 .setLabel(lastClicked == "clear-channel" ? "Click again to confirm" : "Clear Channel")
Skyler Grey75ea9172022-08-06 10:22:23 +0100228 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
229 .setCustomId("clear-channel")
230 .setDisabled(!config.welcome.channel)
TheCodedProf21c08592022-09-13 14:14:43 -0400231 .setStyle(ButtonStyle.Danger),
232 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100233 .setLabel("Set Channel to DM")
234 .setCustomId("set-channel-dm")
235 .setDisabled(config.welcome.channel == "dm")
TheCodedProf21c08592022-09-13 14:14:43 -0400236 .setStyle(ButtonStyle.Secondary)
Skyler Grey75ea9172022-08-06 10:22:23 +0100237 ])
238 ]
239 })) as Message;
Skyler Grey1a67e182022-08-04 23:05:44 +0100240 let i: MessageComponentInteraction;
pineafan41d93562022-07-30 22:10:15 +0100241 try {
242 i = await m.awaitMessageComponent({ time: 300000 });
243 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100244 timedOut = true;
245 continue;
pineafan41d93562022-07-30 22:10:15 +0100246 }
pineafan63fc5e22022-08-04 22:04:10 +0100247 i.deferUpdate();
pineafan41d93562022-07-30 22:10:15 +0100248 if (i.customId == "clear-message") {
249 if (lastClicked == "clear-message") {
pineafan4e425942022-08-08 22:01:47 +0100250 await client.database.guilds.write(interaction.guild!.id, {
Skyler Grey75ea9172022-08-06 10:22:23 +0100251 "welcome.message": null
252 });
pineafan63fc5e22022-08-04 22:04:10 +0100253 lastClicked = null;
Skyler Grey75ea9172022-08-06 10:22:23 +0100254 } else {
255 lastClicked = "clear-message";
256 }
pineafan41d93562022-07-30 22:10:15 +0100257 } else if (i.customId == "clear-role") {
258 if (lastClicked == "clear-role") {
pineafan4e425942022-08-08 22:01:47 +0100259 await client.database.guilds.write(interaction.guild!.id, {
Skyler Grey75ea9172022-08-06 10:22:23 +0100260 "welcome.role": null
261 });
pineafan63fc5e22022-08-04 22:04:10 +0100262 lastClicked = null;
Skyler Grey75ea9172022-08-06 10:22:23 +0100263 } else {
264 lastClicked = "clear-role";
265 }
pineafan41d93562022-07-30 22:10:15 +0100266 } else if (i.customId == "clear-ping") {
267 if (lastClicked == "clear-ping") {
pineafan4e425942022-08-08 22:01:47 +0100268 await client.database.guilds.write(interaction.guild!.id, {
Skyler Grey75ea9172022-08-06 10:22:23 +0100269 "welcome.ping": null
270 });
pineafan63fc5e22022-08-04 22:04:10 +0100271 lastClicked = null;
Skyler Grey75ea9172022-08-06 10:22:23 +0100272 } else {
273 lastClicked = "clear-ping";
274 }
pineafan41d93562022-07-30 22:10:15 +0100275 } else if (i.customId == "clear-channel") {
276 if (lastClicked == "clear-channel") {
pineafan4e425942022-08-08 22:01:47 +0100277 await client.database.guilds.write(interaction.guild!.id, {
Skyler Grey75ea9172022-08-06 10:22:23 +0100278 "welcome.channel": null
279 });
pineafan63fc5e22022-08-04 22:04:10 +0100280 lastClicked = null;
Skyler Grey75ea9172022-08-06 10:22:23 +0100281 } else {
282 lastClicked = "clear-channel";
283 }
pineafan41d93562022-07-30 22:10:15 +0100284 } else if (i.customId == "set-channel-dm") {
pineafan4e425942022-08-08 22:01:47 +0100285 await client.database.guilds.write(interaction.guild!.id, {
Skyler Grey75ea9172022-08-06 10:22:23 +0100286 "welcome.channel": "dm"
287 });
pineafan63fc5e22022-08-04 22:04:10 +0100288 lastClicked = null;
pineafan41d93562022-07-30 22:10:15 +0100289 }
Skyler Greyad002172022-08-16 18:48:26 +0100290 } while (!timedOut);
Skyler Grey75ea9172022-08-06 10:22:23 +0100291 await interaction.editReply({
Skyler Greyad002172022-08-16 18:48:26 +0100292 embeds: [m.embeds[0]!.setFooter({ text: "Message timed out" })],
Skyler Grey75ea9172022-08-06 10:22:23 +0100293 components: []
294 });
pineafan63fc5e22022-08-04 22:04:10 +0100295};
pineafan41d93562022-07-30 22:10:15 +0100296
Skyler Grey1a67e182022-08-04 23:05:44 +0100297const check = (interaction: CommandInteraction) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100298 const member = interaction.member as Discord.GuildMember;
299 if (!member.permissions.has("MANAGE_GUILD"))
Skyler Grey11236ba2022-08-08 21:13:33 +0100300 throw new Error("You must have the *Manage Server* permission to use this command");
pineafan41d93562022-07-30 22:10:15 +0100301 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100302};
pineafan41d93562022-07-30 22:10:15 +0100303
304export { command };
305export { callback };
Skyler Grey1a67e182022-08-04 23:05:44 +0100306export { check };