blob: 52773836a22d5c4fe36e71f29ed76dc566010de6 [file] [log] [blame]
pineafan63fc5e22022-08-04 22:04:10 +01001import { callback as roleMenu } from "../actions/roleMenu.js";
pineafan73a7c4a2022-07-24 10:38:04 +01002import verify from "../reflex/verify.js";
3import create from "../actions/tickets/create.js";
4import close from "../actions/tickets/delete.js";
5import createTranscript from "../premium/createTranscript.js";
PineaFana34d04b2023-01-03 22:05:42 +00006
TheCodedProfca29ebb2023-03-10 17:40:09 -05007import {
8 ActionRowBuilder,
9 ButtonBuilder,
10 ButtonInteraction,
11 ButtonStyle,
12 Interaction,
13 InteractionEditReplyOptions,
14 ModalBuilder,
15 ModalSubmitInteraction,
16 TextInputBuilder,
17 TextInputStyle
18} from "discord.js";
PineaFan752af462022-12-31 21:59:38 +000019import type { NucleusClient } from "../utils/client.js";
PineaFan1dee28f2023-01-16 22:09:07 +000020import EmojiEmbed from "../utils/generateEmojiEmbed.js";
pineafanad54d752022-04-18 19:01:43 +010021
pineafan6de4da52023-03-07 20:43:44 +000022import { callback as banCallback, check as banCheck } from "../commands/mod/ban.js";
23import { callback as kickCallback, check as kickCheck } from "../commands/mod/kick.js";
24import { callback as muteCallback, check as muteCheck } from "../commands/mod/mute.js";
25import { callback as nicknameCallback, check as nicknameCheck } from "../commands/mod/nick.js";
26import { callback as warnCallback, check as warnCheck } from "../commands/mod/warn.js";
TheCodedProf4a7c25d2023-06-07 17:09:45 -040027import { callback as logDetailsCallback } from "../actions/logs/showDetails.js";
TheCodedProf35e73712023-03-10 17:35:35 -050028import client from "../utils/client.js";
pineafan6de4da52023-03-07 20:43:44 +000029
pineafan63fc5e22022-08-04 22:04:10 +010030export const event = "interactionCreate";
pineafanad54d752022-04-18 19:01:43 +010031
pineafan6de4da52023-03-07 20:43:44 +000032async function errorMessage(interaction: ButtonInteraction, message: string) {
33 await interaction.reply({
pineafan1e462ab2023-03-07 21:34:06 +000034 embeds: [new EmojiEmbed().setDescription(message).setStatus("Danger")],
pineafan6de4da52023-03-07 20:43:44 +000035 ephemeral: true,
36 components: []
37 });
38}
39
pineafan0f5cc782022-08-12 21:55:42 +010040async function interactionCreate(interaction: Interaction) {
PineaFana34d04b2023-01-03 22:05:42 +000041 if (interaction.isButton()) {
TheCodedProf35e73712023-03-10 17:35:35 -050042 if (interaction.customId.endsWith(":Suggestion")) {
TheCodedProfca29ebb2023-03-10 17:40:09 -050043 const value =
44 interaction.customId.startsWith("accept") || interaction.customId.startsWith("implement")
45 ? true
46 : false;
TheCodedProf35e73712023-03-10 17:35:35 -050047 return await modifySuggestion(interaction, value);
48 }
TheCodedProfc3195b52023-06-23 15:53:00 -040049 if (interaction.customId.startsWith("log:edit:")) {
50 const messageId = interaction.customId.split(":")[2];
51 const message = await interaction.channel?.messages.fetch(messageId!);
52 const attachment = message?.attachments.find((a) => a.name === "log.json");
53 if (!attachment) return;
54 const log = JSON.parse(Buffer.from(await (await fetch(attachment.url)).text(), 'base64').toString('binary'));
55 console.log(log);
56 }
PineaFan538d3752023-01-12 21:48:23 +000057 switch (interaction.customId) {
Skyler Greyda16adf2023-03-05 10:22:12 +000058 case "rolemenu": {
59 return await roleMenu(interaction);
60 }
61 case "verifybutton": {
62 return await verify(interaction);
63 }
64 case "createticket": {
65 return await create(interaction);
66 }
67 case "closeticket": {
68 return await close(interaction);
69 }
70 case "createtranscript": {
71 return await createTranscript(interaction);
72 }
TheCodedProf4a7c25d2023-06-07 17:09:45 -040073 case "log:showDetails": {
74 return await logDetailsCallback(interaction);
75 }
pineafan02ba0232022-07-24 22:16:15 +010076 }
pineafan6de4da52023-03-07 20:43:44 +000077 // Mod actions
78 if (interaction.customId.startsWith("mod:")) {
79 const action = interaction.customId.split(":")[1];
80 const memberId = interaction.customId.split(":")[2];
81 const member = await interaction.guild?.members.fetch(memberId!);
82 switch (action) {
83 case "kick": {
TheCodedProf35e73712023-03-10 17:35:35 -050084 const check = kickCheck(interaction, false, member);
pineafan6de4da52023-03-07 20:43:44 +000085 if (check !== true) return await errorMessage(interaction, check!);
86 return await kickCallback(interaction, member);
pineafan1e462ab2023-03-07 21:34:06 +000087 }
88 case "ban": {
TheCodedProf35e73712023-03-10 17:35:35 -050089 const check = banCheck(interaction, false, member);
pineafan6de4da52023-03-07 20:43:44 +000090 if (check !== true) return await errorMessage(interaction, check!);
91 return await banCallback(interaction, member);
pineafan1e462ab2023-03-07 21:34:06 +000092 }
93 case "mute": {
TheCodedProf35e73712023-03-10 17:35:35 -050094 const check = muteCheck(interaction, false, member);
pineafan6de4da52023-03-07 20:43:44 +000095 if (check !== true) return await errorMessage(interaction, check!);
96 return await muteCallback(interaction, member);
pineafan1e462ab2023-03-07 21:34:06 +000097 }
98 case "nickname": {
TheCodedProf35e73712023-03-10 17:35:35 -050099 const check = nicknameCheck(interaction, false, member);
pineafan6de4da52023-03-07 20:43:44 +0000100 if (check !== true) return await errorMessage(interaction, check || "Something went wrong");
101 return await nicknameCallback(interaction, member);
pineafan1e462ab2023-03-07 21:34:06 +0000102 }
103 case "warn": {
TheCodedProf35e73712023-03-10 17:35:35 -0500104 const check = warnCheck(interaction, false, member);
pineafan6de4da52023-03-07 20:43:44 +0000105 if (check !== true) return await errorMessage(interaction, check!);
106 return await warnCallback(interaction, member);
107 }
108 }
109 }
pineafanad54d752022-04-18 19:01:43 +0100110 }
111}
112
TheCodedProf35e73712023-03-10 17:35:35 -0500113const getReason = async (buttonInteraction: ButtonInteraction, prompt: string) => {
114 const modal = new ModalBuilder()
115 .addComponents(
116 new ActionRowBuilder<TextInputBuilder>().addComponents(
TheCodedProfca29ebb2023-03-10 17:40:09 -0500117 new TextInputBuilder().setStyle(TextInputStyle.Paragraph).setLabel(prompt).setCustomId("typed")
TheCodedProf35e73712023-03-10 17:35:35 -0500118 )
119 )
120 .setTitle("Reason")
121 .setCustomId("modal");
122 await buttonInteraction.showModal(modal);
123 let out: ModalSubmitInteraction;
124 try {
125 out = await buttonInteraction.awaitModalSubmit({
126 filter: (i) => i.customId === "modal" && i.user.id === buttonInteraction.user.id,
127 time: 300000
128 });
129 } catch {
130 return null;
131 }
132 await out.deferUpdate();
133 return out.fields.getTextInputValue("typed");
TheCodedProfca29ebb2023-03-10 17:40:09 -0500134};
TheCodedProf35e73712023-03-10 17:35:35 -0500135
136async function modifySuggestion(interaction: ButtonInteraction, accept: boolean) {
137 const message = interaction.message;
PineaFan1dee28f2023-01-16 22:09:07 +0000138 await message.fetch();
139 if (message.embeds.length === 0) return;
TheCodedProf35e73712023-03-10 17:35:35 -0500140 const embed = message.embeds[0]!;
TheCodedProfca29ebb2023-03-10 17:40:09 -0500141 const issueNum = embed.footer!.text;
142 if (!issueNum) return;
TheCodedProf35e73712023-03-10 17:35:35 -0500143 const issue = {
144 owner: "ClicksMinutePer",
145 repo: "Nucleus",
146 issue_number: parseInt(issueNum)
TheCodedProfca29ebb2023-03-10 17:40:09 -0500147 };
TheCodedProf35e73712023-03-10 17:35:35 -0500148 let name = "Unknown";
149 const components: InteractionEditReplyOptions["components"] = [];
TheCodedProfca29ebb2023-03-10 17:40:09 -0500150 switch (interaction.customId) {
TheCodedProf35e73712023-03-10 17:35:35 -0500151 case "accept:Suggestion": {
152 name = "Accepted";
153 await interaction.deferUpdate();
TheCodedProfca29ebb2023-03-10 17:40:09 -0500154 await client.GitHub.rest.issues.createComment({
155 ...issue,
156 body: "Suggestion accepted by " + interaction.user.tag
157 });
158 components.push(
159 new ActionRowBuilder<ButtonBuilder>().addComponents(
160 new ButtonBuilder()
161 .setCustomId("close:Suggestion")
162 .setLabel("Close")
163 .setStyle(ButtonStyle.Secondary),
164 new ButtonBuilder()
165 .setCustomId("implemented:Suggestion")
166 .setLabel("Implemented")
167 .setStyle(ButtonStyle.Secondary)
168 )
169 );
TheCodedProf35e73712023-03-10 17:35:35 -0500170 break;
171 }
172 case "deny:Suggestion": {
173 name = "Denied";
174 const reason = await getReason(interaction, "Reason for denial");
TheCodedProfca29ebb2023-03-10 17:40:09 -0500175 await client.GitHub.rest.issues.createComment({
176 ...issue,
177 body: "Suggestion denied by " + interaction.user.tag + " for reason:\n>" + reason
178 });
179 await client.GitHub.rest.issues.update({ ...issue, state: "closed", state_reason: "not_planned" });
TheCodedProf35e73712023-03-10 17:35:35 -0500180 // await client.GitHub.rest.issues.lock({...issue, lock_reason: "resolved"})
TheCodedProfca29ebb2023-03-10 17:40:09 -0500181 components.push(
182 new ActionRowBuilder<ButtonBuilder>().addComponents(
183 new ButtonBuilder().setCustomId("lock:Suggestion").setLabel("Lock").setStyle(ButtonStyle.Danger)
184 )
185 );
TheCodedProf35e73712023-03-10 17:35:35 -0500186 break;
187 }
188 case "close:Suggestion": {
189 name = "Closed";
190 const reason = await getReason(interaction, "Reason for closing");
TheCodedProfca29ebb2023-03-10 17:40:09 -0500191 await client.GitHub.rest.issues.createComment({
192 ...issue,
193 body: "Suggestion closed by " + interaction.user.tag + " for reason:\n>" + reason
194 });
195 await client.GitHub.rest.issues.update({ ...issue, state: "closed" });
TheCodedProf35e73712023-03-10 17:35:35 -0500196 // await client.GitHub.rest.issues.lock({...issue})
TheCodedProfca29ebb2023-03-10 17:40:09 -0500197 components.push(
198 new ActionRowBuilder<ButtonBuilder>().addComponents(
199 new ButtonBuilder().setCustomId("lock:Suggestion").setLabel("Lock").setStyle(ButtonStyle.Danger)
200 )
201 );
TheCodedProf35e73712023-03-10 17:35:35 -0500202 break;
203 }
204 case "implement:Suggestion": {
205 name = "Implemented";
206 await interaction.deferUpdate();
TheCodedProfca29ebb2023-03-10 17:40:09 -0500207 await client.GitHub.rest.issues.createComment({ ...issue, body: "Suggestion implemented" });
208 await client.GitHub.rest.issues.update({ ...issue, state: "closed", state_reason: "completed" });
209 await client.GitHub.rest.issues.lock({ ...issue, lock_reason: "resolved" });
TheCodedProf35e73712023-03-10 17:35:35 -0500210 break;
211 }
212 case "lock:Suggestion": {
213 name = "Locked";
214 await interaction.deferUpdate();
TheCodedProfca29ebb2023-03-10 17:40:09 -0500215 await client.GitHub.rest.issues.lock({ ...issue });
TheCodedProf35e73712023-03-10 17:35:35 -0500216 break;
217 }
218 case "spam:Suggestion": {
219 name = "Marked as Spam";
220 await interaction.deferUpdate();
TheCodedProfca29ebb2023-03-10 17:40:09 -0500221 await client.GitHub.rest.issues.update({ ...issue, state: "closed", state_reason: "not_planned" });
222 await client.GitHub.rest.issues.lock({ ...issue, lock_reason: "spam" });
TheCodedProf35e73712023-03-10 17:35:35 -0500223 break;
224 }
225 }
226
TheCodedProf46518a42023-02-18 17:08:23 -0500227 const newcolor = accept ? "Success" : "Danger";
TheCodedProf35e73712023-03-10 17:35:35 -0500228 const newEmoji = accept ? "ICONS.ADD" : "ICONS.OPP.ADD";
PineaFan1dee28f2023-01-16 22:09:07 +0000229
230 const newEmbed = new EmojiEmbed()
TheCodedProf35e73712023-03-10 17:35:35 -0500231 .setEmoji(newEmoji)
232 .setTitle(embed!.title!.replace(/.+> /, ""))
PineaFan1dee28f2023-01-16 22:09:07 +0000233 .setDescription(embed!.description!)
TheCodedProf35e73712023-03-10 17:35:35 -0500234 .setFields({
235 name: name + " by",
TheCodedProfca29ebb2023-03-10 17:40:09 -0500236 value: interaction.user.tag
TheCodedProf35e73712023-03-10 17:35:35 -0500237 })
238 .setStatus(newcolor)
239 .setFooter(embed!.footer);
PineaFan1dee28f2023-01-16 22:09:07 +0000240
TheCodedProf35e73712023-03-10 17:35:35 -0500241 await interaction.editReply({
242 embeds: [newEmbed],
243 components: components
244 });
PineaFan1dee28f2023-01-16 22:09:07 +0000245}
246
PineaFan752af462022-12-31 21:59:38 +0000247export async function callback(_client: NucleusClient, interaction: Interaction) {
pineafan63fc5e22022-08-04 22:04:10 +0100248 await interactionCreate(interaction);
Skyler Grey75ea9172022-08-06 10:22:23 +0100249}