blob: eeef8fb29dfadc8a8eb89c3533770cc4f7285706 [file] [log] [blame]
PineaFan0d06edc2023-01-17 22:10:31 +00001import { LoadingEmbed } from "../../../utils/defaults.js";
Samuel Shuert27bf3cd2023-03-03 15:51:25 -05002import Discord, { CommandInteraction, ActionRowBuilder, ChannelSelectMenuBuilder, ChannelType, ButtonBuilder, ButtonStyle, StringSelectMenuBuilder, StringSelectMenuOptionBuilder, ButtonInteraction, StringSelectMenuInteraction, ChannelSelectMenuInteraction, APIMessageComponentEmoji } from "discord.js";
3import type { SlashCommandSubcommandBuilder } from "discord.js";
pineafan63fc5e22022-08-04 22:04:10 +01004import client from "../../../utils/client.js";
Samuel Shuert27bf3cd2023-03-03 15:51:25 -05005import compare from "lodash";
pineafan41d93562022-07-30 22:10:15 +01006import { toHexArray, toHexInteger } from "../../../utils/calculate.js";
Samuel Shuert27bf3cd2023-03-03 15:51:25 -05007import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
8import getEmojiByName from "../../../utils/getEmojiByName.js";
pineafan41d93562022-07-30 22:10:15 +01009
PineaFan638eb132023-01-19 10:41:22 +000010const logs: Record<string, string> = {
Skyler Grey75ea9172022-08-06 10:22:23 +010011 channelUpdate: "Channels created, deleted or modified",
12 emojiUpdate: "Server emojis modified",
13 stickerUpdate: "Server stickers modified",
14 guildUpdate: "Server settings updated",
15 guildMemberUpdate: "Member updated (i.e. nickname)",
16 guildMemberPunish: "Members punished (i.e. muted, banned, kicked)",
17 guildRoleUpdate: "Role settings changed",
18 guildInviteUpdate: "Server invite created or deleted",
19 messageUpdate: "Message edited",
20 messageDelete: "Message deleted",
21 messageDeleteBulk: "Messages purged",
22 messageReactionUpdate: "Message reactions cleared",
23 messageMassPing: "Message pings multiple members at once",
24 messageAnnounce: "Message published in announcement channel",
25 threadUpdate: "Thread created or deleted",
26 webhookUpdate: "Webhooks created or deleted",
27 guildMemberVerify: "Member runs verify",
28 autoModeratorDeleted: "Messages auto deleted by Nucleus",
Samuel Shuert27bf3cd2023-03-03 15:51:25 -050029 ticketUpdate: "Tickets created or deleted",
30 //nucleusSettingsUpdated: "Nucleus' settings updated by a moderator" // TODO
pineafan63fc5e22022-08-04 22:04:10 +010031};
pineafan4f164f32022-02-26 22:07:12 +000032
33const command = (builder: SlashCommandSubcommandBuilder) =>
Samuel Shuert27bf3cd2023-03-03 15:51:25 -050034 builder
35 .setName("events")
36 .setDescription("The general log channel for the server, and setting what events to show")
pineafan4f164f32022-02-26 22:07:12 +000037
pineafanbd02b4a2022-08-05 22:01:38 +010038const callback = async (interaction: CommandInteraction): Promise<void> => {
Samuel Shuert27bf3cd2023-03-03 15:51:25 -050039 const m = (await interaction.reply({
Skyler Grey75ea9172022-08-06 10:22:23 +010040 embeds: LoadingEmbed,
Samuel Shuert27bf3cd2023-03-03 15:51:25 -050041 ephemeral: true,
42 fetchReply: true
43 })) as Discord.Message;
44
45 let config = await client.database.guilds.read(interaction.guild!.id);
46 let data = Object.assign({}, config.logging.logs);
47 let closed = false;
48 let show = false;
Skyler Greyad002172022-08-16 18:48:26 +010049 do {
Samuel Shuert27bf3cd2023-03-03 15:51:25 -050050 const channelMenu = new ActionRowBuilder<ChannelSelectMenuBuilder>()
51 .addComponents(
52 new ChannelSelectMenuBuilder()
53 .setCustomId("channel")
54 .setPlaceholder("Select a channel")
55 .setChannelTypes(ChannelType.GuildText)
56 )
57 const buttons = new ActionRowBuilder<ButtonBuilder>()
58 .addComponents(
59 new ButtonBuilder()
60 .setCustomId("switch")
61 .setLabel(data.enabled ? "Enabled" : "Disabled")
62 .setStyle(data.enabled ? ButtonStyle.Success : ButtonStyle.Danger)
63 .setEmoji(getEmojiByName((data.enabled ? "CONTROL.TICK" : "CONTROL.CROSS"), "id") as APIMessageComponentEmoji),
64 new ButtonBuilder()
65 .setCustomId("remove")
66 .setLabel("Remove")
67 .setStyle(ButtonStyle.Danger)
68 .setDisabled(!data.channel),
69 new ButtonBuilder()
70 .setCustomId("show")
71 .setLabel("Manage Events")
72 .setStyle(ButtonStyle.Primary),
73 new ButtonBuilder()
74 .setCustomId("save")
75 .setLabel("Save")
76 .setStyle(ButtonStyle.Success)
77 .setDisabled(compare.isEqual(data, config.logging.logs))
78 )
79
80 const converted = toHexArray(data.toLog);
81 const toLogMenu = new ActionRowBuilder<StringSelectMenuBuilder>()
82 .addComponents(
83 new StringSelectMenuBuilder()
84 .setPlaceholder("Set events to log")
85 .setMaxValues(Object.keys(logs).length)
86 .setCustomId("logs")
87 .setMinValues(0)
88 )
89 Object.keys(logs).map((e) => {
90 toLogMenu.components[0]!.addOptions(
91 new StringSelectMenuOptionBuilder()
92 .setLabel(logs[e]!)
93 .setValue(e)
94 .setDefault(converted.includes(e))
PineaFan638eb132023-01-19 10:41:22 +000095 )
96 });
Samuel Shuert27bf3cd2023-03-03 15:51:25 -050097
98 const embed = new EmojiEmbed()
99 .setTitle("General Log Channel")
100 .setStatus("Success")
101 .setEmoji("CHANNEL.TEXT.CREATE")
102 .setDescription(
103 `This is the channel that all events you set to be logged will be stored\n` +
104 `**Channel:** ${data.channel ? `<#${data.channel}>` : "None"}\n`
105 )
106
107 const components: ActionRowBuilder<ButtonBuilder | ChannelSelectMenuBuilder | StringSelectMenuBuilder>[] = [channelMenu, buttons];
108 if(show) components.push(toLogMenu);
109
110 await interaction.editReply({
111 embeds: [embed],
112 components: components
113 });
114
115 let i: ButtonInteraction | StringSelectMenuInteraction | ChannelSelectMenuInteraction;
pineafan41d93562022-07-30 22:10:15 +0100116 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000117 i = await m.awaitMessageComponent({
Samuel Shuert27bf3cd2023-03-03 15:51:25 -0500118 filter: (i) => i.user.id === interaction.user.id,
119 time: 300000
120 }) as ButtonInteraction | StringSelectMenuInteraction | ChannelSelectMenuInteraction;
pineafan41d93562022-07-30 22:10:15 +0100121 } catch (e) {
Samuel Shuert27bf3cd2023-03-03 15:51:25 -0500122 closed = true;
Skyler Greyad002172022-08-16 18:48:26 +0100123 continue;
pineafan41d93562022-07-30 22:10:15 +0100124 }
Skyler Greyad002172022-08-16 18:48:26 +0100125
Samuel Shuert27bf3cd2023-03-03 15:51:25 -0500126 await i.deferUpdate();
127
128 if(i.isButton()) {
129 switch(i.customId) {
130 case "show": {
131 show = !show;
132 break;
133 }
134 case "switch": {
135 data.enabled = !data.enabled;
136 break;
137 }
138 case "save": {
139 await client.database.guilds.write(interaction.guild!.id, {"logging.logs": data});
140 config = await client.database.guilds.read(interaction.guild!.id);
141 data = Object.assign({}, config.logging.logs);
142 break;
143 }
144 case "remove": {
145 data.channel = null;
146 break;
147 }
148 }
149 } else if(i.isStringSelectMenu()) {
150 const hex = toHexInteger(i.values);
151 data.toLog = hex;
152 } else if(i.isChannelSelectMenu()) {
153 data.channel = i.values[0]!;
154 }
155
156 } while (!closed);
157 await interaction.deleteReply()
pineafan63fc5e22022-08-04 22:04:10 +0100158};
pineafan4f164f32022-02-26 22:07:12 +0000159
Samuel Shuert27bf3cd2023-03-03 15:51:25 -0500160const check = (interaction: CommandInteraction, _partial: boolean = false) => {
Skyler Grey75ea9172022-08-06 10:22:23 +0100161 const member = interaction.member as Discord.GuildMember;
PineaFan0d06edc2023-01-17 22:10:31 +0000162 if (!member.permissions.has("ManageGuild"))
163 return "You must have the *Manage Server* permission to use this command";
pineafan4f164f32022-02-26 22:07:12 +0000164 return true;
pineafan63fc5e22022-08-04 22:04:10 +0100165};
pineafan4f164f32022-02-26 22:07:12 +0000166
167export { command };
168export { callback };
Skyler Grey75ea9172022-08-06 10:22:23 +0100169export { check };