blob: fa1f7a482bdd3487d3297815efb69605c1a1740d [file] [log] [blame]
Skyler Greyf21323a2022-08-13 23:58:22 +01001import {
2 CommandInteraction,
3 GuildMember,
4 Message,
TheCodedProf21c08592022-09-13 14:14:43 -04005 ActionRowBuilder,
6 ButtonBuilder,
Skyler Greyf21323a2022-08-13 23:58:22 +01007 MessageComponentInteraction,
TheCodedProf21c08592022-09-13 14:14:43 -04008 TextChannel,
PineaFan538d3752023-01-12 21:48:23 +00009 ButtonStyle,
TheCodedProf2e54a772023-02-14 16:26:47 -050010 User,
TheCodedProfcfe8e9a2023-02-26 17:28:09 -050011 ThreadChannel
Skyler Greyf21323a2022-08-13 23:58:22 +010012} from "discord.js";
pineafan813bdf42022-07-24 10:39:10 +010013import EmojiEmbed from "../utils/generateEmojiEmbed.js";
14import getEmojiByName from "../utils/getEmojiByName.js";
pineafan813bdf42022-07-24 10:39:10 +010015import client from "../utils/client.js";
Skyler Greyda16adf2023-03-05 10:22:12 +000016import { messageException } from "../utils/createTemporaryStorage.js";
pineafan813bdf42022-07-24 10:39:10 +010017
TheCodedProfcfe8e9a2023-02-26 17:28:09 -050018const noTopic = new EmojiEmbed()
19 .setTitle("User not found")
20 .setDescription("There is no user associated with this ticket.")
21 .setStatus("Danger")
Skyler Greyda16adf2023-03-05 10:22:12 +000022 .setEmoji("CONTROL.BLOCKCROSS");
TheCodedProfcfe8e9a2023-02-26 17:28:09 -050023
pineafan0f5cc782022-08-12 21:55:42 +010024export default async function (interaction: CommandInteraction | MessageComponentInteraction) {
Skyler Grey11236ba2022-08-08 21:13:33 +010025 if (interaction.channel === null) return;
TheCodedProfcfe8e9a2023-02-26 17:28:09 -050026 if (!(interaction.channel instanceof TextChannel || interaction.channel instanceof ThreadChannel)) return;
Skyler Grey11236ba2022-08-08 21:13:33 +010027 const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
pineafan813bdf42022-07-24 10:39:10 +010028
Skyler Grey11236ba2022-08-08 21:13:33 +010029 let messages: Message[] = [];
30 let deletedCount: number;
pineafan813bdf42022-07-24 10:39:10 +010031
Skyler Grey11236ba2022-08-08 21:13:33 +010032 do {
33 const fetched = await (interaction.channel as TextChannel).messages.fetch({ limit: 100 });
34 const deleted = await (interaction.channel as TextChannel).bulkDelete(fetched, true);
35 deletedCount = deleted.size;
TheCodedProfbc94a5c2023-01-18 18:59:31 -050036 messages = messages.concat(Array.from(deleted.values() as Iterable<Message>));
Skyler Greyda16adf2023-03-05 10:22:12 +000037 if (messages.length === 1) messageException(interaction.guild!.id, interaction.channel.id, messages[0]!.id);
Skyler Grey11236ba2022-08-08 21:13:33 +010038 } while (deletedCount === 100);
Skyler Greyda16adf2023-03-05 10:22:12 +000039 messages = messages.filter(
40 (message) =>
41 !message.components.some((component) =>
42 component.components.some((child) => child.customId?.includes("transcript") ?? false)
TheCodedProfcfe8e9a2023-02-26 17:28:09 -050043 )
Skyler Greyda16adf2023-03-05 10:22:12 +000044 );
Skyler Grey11236ba2022-08-08 21:13:33 +010045
Skyler Greyda16adf2023-03-05 10:22:12 +000046 let topic;
TheCodedProf9c51a7e2023-02-27 17:11:13 -050047 let member: GuildMember = interaction.guild?.members.me!;
TheCodedProfcfe8e9a2023-02-26 17:28:09 -050048 if (interaction.channel instanceof TextChannel) {
49 topic = interaction.channel.topic;
50 if (topic === null) return await interaction.reply({ embeds: [noTopic] });
TheCodedProf9c51a7e2023-02-27 17:11:13 -050051 const mem = interaction.guild!.members.cache.get(topic.split(" ")[1]!);
52 if (mem) member = mem;
TheCodedProfcfe8e9a2023-02-26 17:28:09 -050053 } else {
54 topic = interaction.channel.name;
Skyler Greyda16adf2023-03-05 10:22:12 +000055 const split = topic.split("-").map((p) => p.trim()) as [string, string, string];
56 const mem = interaction.guild!.members.cache.get(split[1]);
TheCodedProf9c51a7e2023-02-27 17:11:13 -050057 if (mem) member = mem;
TheCodedProfcfe8e9a2023-02-26 17:28:09 -050058 }
59
Skyler Greye0c511b2023-03-06 10:30:17 +000060 const newOut = await client.database.transcripts.createTranscript("ticket", messages, interaction, member);
TheCodedProf2e54a772023-02-14 16:26:47 -050061
TheCodedProf75c51be2023-03-03 17:18:18 -050062 const [code, key, iv] = await client.database.transcripts.create(newOut);
Skyler Greyda16adf2023-03-05 10:22:12 +000063 if (!code)
64 return await interaction.reply({
65 embeds: [
66 new EmojiEmbed()
67 .setTitle("Error")
68 .setDescription("An error occurred while creating the transcript.")
69 .setStatus("Danger")
70 .setEmoji("CONTROL.BLOCKCROSS")
71 ]
72 });
TheCodedProf9c51a7e2023-02-27 17:11:13 -050073 const guildConfig = await client.database.guilds.read(interaction.guild!.id);
74 const m: Message = (await interaction.reply({
75 embeds: [
76 new EmojiEmbed()
77 .setTitle("Transcript")
78 .setDescription(
79 "You can view the transcript using the link below. You can save the link for later" +
80 (guildConfig.logging.logs.channel
81 ? ` or find it in <#${guildConfig.logging.logs.channel}> once you press delete below. After this the channel will be deleted.`
TheCodedProf003160f2023-03-04 17:09:40 -050082 : ". It will be automatically deleted after 30 days if a logging channel is not set.")
TheCodedProf9c51a7e2023-02-27 17:11:13 -050083 )
84 .setStatus("Success")
85 .setEmoji("CONTROL.DOWNLOAD")
86 ],
87 components: [
88 new ActionRowBuilder<ButtonBuilder>().addComponents([
Skyler Greyda16adf2023-03-05 10:22:12 +000089 new ButtonBuilder()
90 .setLabel("View")
91 .setStyle(ButtonStyle.Link)
92 .setURL(`https://testing.coded.codes/nucleus/transcript/${code}?key=${key}&iv=${iv}`),
TheCodedProf9c51a7e2023-02-27 17:11:13 -050093 new ButtonBuilder()
94 .setLabel("Delete")
95 .setStyle(ButtonStyle.Danger)
96 .setCustomId("close")
97 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
98 ])
99 ],
100 fetchReply: true
101 })) as Message;
pineafan813bdf42022-07-24 10:39:10 +0100102 let i;
103 try {
PineaFan0d06edc2023-01-17 22:10:31 +0000104 i = await m.awaitMessageComponent({
105 time: 300000,
Skyler Greyda16adf2023-03-05 10:22:12 +0000106 filter: (i) => {
107 return (
108 i.user.id === interaction.user.id &&
109 i.channel!.id === interaction.channel!.id &&
110 i.message.id === m.id
111 );
112 }
PineaFan0d06edc2023-01-17 22:10:31 +0000113 });
TheCodedProf267563a2023-01-21 17:00:57 -0500114 await i.deferUpdate();
Skyler Grey75ea9172022-08-06 10:22:23 +0100115 } catch {
116 return;
117 }
pineafan63fc5e22022-08-04 22:04:10 +0100118 const data = {
Skyler Grey75ea9172022-08-06 10:22:23 +0100119 meta: {
pineafan63fc5e22022-08-04 22:04:10 +0100120 type: "ticketDeleted",
121 displayName: "Ticket Deleted",
pineafan813bdf42022-07-24 10:39:10 +0100122 calculateType: "ticketUpdate",
123 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +0100124 emoji: "GUILD.TICKET.CLOSE",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500125 timestamp: Date.now()
pineafan813bdf42022-07-24 10:39:10 +0100126 },
127 list: {
TheCodedProf9c51a7e2023-02-27 17:11:13 -0500128 ticketFor: entry(member.id, renderUser(member.user)),
PineaFan538d3752023-01-12 21:48:23 +0000129 deletedBy: entry(interaction.member!.user.id, renderUser(interaction.member!.user as User)),
TheCodedProff8ef7942023-03-03 15:32:32 -0500130 deleted: entry(Date.now().toString(), renderDelta(Date.now())),
131 transcript: entry(code, `https://clicks.codes/nucleus/transcript/${code}`)
pineafan813bdf42022-07-24 10:39:10 +0100132 },
133 hidden: {
pineafan4e425942022-08-08 22:01:47 +0100134 guild: interaction.guild!.id
pineafan813bdf42022-07-24 10:39:10 +0100135 }
pineafan63fc5e22022-08-04 22:04:10 +0100136 };
Skyler Greyf4f21c42023-03-08 14:36:29 +0000137 await log(data);
pineafan63fc5e22022-08-04 22:04:10 +0100138 await interaction.channel.delete();
139 return;
Skyler Grey75ea9172022-08-06 10:22:23 +0100140}