blob: 990b360c44d3cfa1f9ad85c8a3ac2de9fe46fc34 [file] [log] [blame]
TheCodedProff86ba092023-01-27 17:10:07 -05001import { getCommandMentionByName } from '../../utils/getCommandDataByName.js';
PineaFan9b2ac4d2023-01-18 14:41:07 +00002import Discord, { ActionRowBuilder, ButtonBuilder, ButtonInteraction, PrivateThreadChannel, TextChannel, ButtonStyle, CategoryChannel } from "discord.js";
pineafan813bdf42022-07-24 10:39:10 +01003import client from "../../utils/client.js";
4import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
5import getEmojiByName from "../../utils/getEmojiByName.js";
PineaFan0d06edc2023-01-17 22:10:31 +00006import { preloadPage } from '../../utils/createTemporaryStorage.js';
TheCodedProf9c51a7e2023-02-27 17:11:13 -05007import { LoadingEmbed } from '../../utils/defaults.js';
pineafan813bdf42022-07-24 10:39:10 +01008
PineaFan538d3752023-01-12 21:48:23 +00009export default async function (interaction: Discord.CommandInteraction | ButtonInteraction) {
PineaFana00db1b2023-01-02 15:32:54 +000010 if (!interaction.guild) return;
PineaFan0d06edc2023-01-17 22:10:31 +000011 const config = await client.database.guilds.read(interaction.guild.id);
Skyler Grey11236ba2022-08-08 21:13:33 +010012 const { log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger;
PineaFan0d06edc2023-01-17 22:10:31 +000013 const ticketChannel = config.tickets.category;
14 if (!("parent" in interaction.channel!)) {
15 return await interaction.reply({
Skyler Grey75ea9172022-08-06 10:22:23 +010016 embeds: [
17 new EmojiEmbed()
PineaFan0d06edc2023-01-17 22:10:31 +000018 .setTitle("Not a ticket")
19 .setDescription("This channel isn't a ticket, so you can't delete it.")
Skyler Grey75ea9172022-08-06 10:22:23 +010020 .setStatus("Danger")
21 .setEmoji("CONTROL.BLOCKCROSS")
PineaFan0d06edc2023-01-17 22:10:31 +000022 ], ephemeral: true
Skyler Grey75ea9172022-08-06 10:22:23 +010023 });
PineaFan0d06edc2023-01-17 22:10:31 +000024 } else if (interaction.channel!.parent!.id !== ticketChannel) {
25 return await interaction.reply({
Skyler Grey75ea9172022-08-06 10:22:23 +010026 embeds: [
27 new EmojiEmbed()
PineaFan0d06edc2023-01-17 22:10:31 +000028 .setTitle("Not a ticket")
29 .setDescription("This channel isn't a ticket, so you can't delete it.")
Skyler Grey75ea9172022-08-06 10:22:23 +010030 .setStatus("Danger")
PineaFan0d06edc2023-01-17 22:10:31 +000031 .setEmoji("CONTROL.BLOCKCROSS")
32 ], ephemeral: true
Skyler Grey75ea9172022-08-06 10:22:23 +010033 });
PineaFan0d06edc2023-01-17 22:10:31 +000034 }
35 const channel: PrivateThreadChannel | TextChannel = interaction.channel as PrivateThreadChannel | TextChannel;
36 let status: string | null = ("topic" in interaction.channel) ? interaction.channel!.topic : interaction.channel.name;
37 status = status ?? "";
38 if (status.endsWith("Archived")) { status = "Archived"; }
39 else { status = "Active"; }
40
41 const uID = channel.type === Discord.ChannelType.PrivateThread ? channel.name.split(" - ")[1] : channel.topic!.split(" ")[0];
42
43 if (status === "Archived") {
44 // Delete the ticket
45
pineafan63fc5e22022-08-04 22:04:10 +010046 const data = {
Skyler Grey75ea9172022-08-06 10:22:23 +010047 meta: {
PineaFan0d06edc2023-01-17 22:10:31 +000048 type: "ticketClosed",
49 displayName: "Ticket Closed",
pineafan813bdf42022-07-24 10:39:10 +010050 calculateType: "ticketUpdate",
51 color: NucleusColors.red,
pineafan63fc5e22022-08-04 22:04:10 +010052 emoji: "GUILD.TICKET.CLOSE",
TheCodedProf6ec331b2023-02-20 12:13:06 -050053 timestamp: Date.now()
pineafan813bdf42022-07-24 10:39:10 +010054 },
55 list: {
Skyler Grey75ea9172022-08-06 10:22:23 +010056 ticketFor: entry(
PineaFan0d06edc2023-01-17 22:10:31 +000057 uID!,
58 renderUser((await interaction.guild.members.fetch(uID!)).user)
Skyler Grey75ea9172022-08-06 10:22:23 +010059 ),
PineaFan0d06edc2023-01-17 22:10:31 +000060 closedBy: entry(interaction.member!.user.id, renderUser(interaction.member!.user as Discord.User)),
TheCodedProf6ec331b2023-02-20 12:13:06 -050061 closed: entry(Date.now(), renderDelta(Date.now())),
PineaFan0d06edc2023-01-17 22:10:31 +000062 ticketChannel: entry(channel.id, channel.name)
pineafan813bdf42022-07-24 10:39:10 +010063 },
64 hidden: {
65 guild: interaction.guild.id
66 }
pineafan63fc5e22022-08-04 22:04:10 +010067 };
pineafan813bdf42022-07-24 10:39:10 +010068 log(data);
PineaFan0d06edc2023-01-17 22:10:31 +000069
70 await channel.delete();
pineafane23c4ec2022-07-27 21:56:27 +010071 } else if (status === "Active") {
TheCodedProf9c51a7e2023-02-27 17:11:13 -050072 await interaction.reply({embeds: LoadingEmbed, fetchReply: true});
73 // Archive the ticket
74 await interaction.channel.fetch()
PineaFan0d06edc2023-01-17 22:10:31 +000075 if (channel.isThread()) {
76 channel.setName(`${channel.name.replace("Active", "Archived")}`);
77 channel.members.remove(channel.name.split(" - ")[1]!);
78 } else {
79 channel.setTopic(`${(channel.topic ?? "").replace("Active", "Archived")}`);
80 if (!channel.topic!.includes("Archived")) { channel.setTopic("0 Archived"); }
81 await channel.permissionOverwrites.delete(channel.topic!.split(" ")[0]!);
82 }
83 preloadPage(interaction.channel.id, "privacy", "2")
TheCodedProf9c51a7e2023-02-27 17:11:13 -050084 const hasPremium = await client.database.premium.hasPremium(interaction.guild.id);
85 await interaction.editReply({
Skyler Grey75ea9172022-08-06 10:22:23 +010086 embeds: [
87 new EmojiEmbed()
PineaFan0d06edc2023-01-17 22:10:31 +000088 .setTitle("Archived Ticket")
TheCodedProfcfe8e9a2023-02-26 17:28:09 -050089 .setDescription(`This ticket has been Archived. Type ${getCommandMentionByName("ticket/close")} to delete it.\n` +
TheCodedProff8ef7942023-03-03 15:32:32 -050090 hasPremium ? ("Creating a transcript will delete all messages in this ticket" +
91 `\n\nFor more info on transcripts, check ${getCommandMentionByName("privacy")}`): "")
Skyler Grey75ea9172022-08-06 10:22:23 +010092 .setStatus("Warning")
93 .setEmoji("GUILD.TICKET.ARCHIVED")
94 ],
95 components: [
PineaFan0d06edc2023-01-17 22:10:31 +000096 new ActionRowBuilder<ButtonBuilder>().addComponents(
Skyler Grey75ea9172022-08-06 10:22:23 +010097 [
TheCodedProf21c08592022-09-13 14:14:43 -040098 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010099 .setLabel("Delete")
TheCodedProf21c08592022-09-13 14:14:43 -0400100 .setStyle(ButtonStyle.Danger)
Skyler Grey75ea9172022-08-06 10:22:23 +0100101 .setCustomId("closeticket")
102 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
103 ].concat(
TheCodedProf9c51a7e2023-02-27 17:11:13 -0500104 hasPremium
Skyler Grey75ea9172022-08-06 10:22:23 +0100105 ? [
PineaFan0d06edc2023-01-17 22:10:31 +0000106 new ButtonBuilder()
107 .setLabel("Create Transcript and Delete")
108 .setStyle(ButtonStyle.Primary)
109 .setCustomId("createtranscript")
110 .setEmoji(getEmojiByName("CONTROL.DOWNLOAD", "id"))
111 ]
Skyler Grey75ea9172022-08-06 10:22:23 +0100112 : []
113 )
114 )
115 ]
116 });
PineaFan0d06edc2023-01-17 22:10:31 +0000117 const data = {
118 meta: {
119 type: "ticketClosed",
120 displayName: "Ticket Archived",
121 calculateType: "ticketUpdate",
122 color: NucleusColors.yellow,
123 emoji: "GUILD.TICKET.ARCHIVED",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500124 timestamp: Date.now()
PineaFan0d06edc2023-01-17 22:10:31 +0000125 },
126 list: {
127 ticketFor: entry(
128 uID!,
129 renderUser((await interaction.guild.members.fetch(uID!)).user)
130 ),
131 archivedBy: entry(interaction.member!.user.id, renderUser(interaction.member!.user as Discord.User)),
TheCodedProf6ec331b2023-02-20 12:13:06 -0500132 archived: entry(Date.now(), renderDelta(Date.now())),
PineaFan0d06edc2023-01-17 22:10:31 +0000133 ticketChannel: entry(channel.id, renderChannel(channel))
134 },
135 hidden: {
136 guild: interaction.guild.id
137 }
138 };
139 log(data);
pineafan813bdf42022-07-24 10:39:10 +0100140 }
PineaFan0d06edc2023-01-17 22:10:31 +0000141 return;
pineafan813bdf42022-07-24 10:39:10 +0100142}
143
PineaFan0d06edc2023-01-17 22:10:31 +0000144
145async function purgeByUser(member: string, guild: string) {
PineaFan9b2ac4d2023-01-18 14:41:07 +0000146 const config = await client.database.guilds.read(guild);
PineaFan0d06edc2023-01-17 22:10:31 +0000147 const fetchedGuild = await client.guilds.fetch(guild);
pineafan813bdf42022-07-24 10:39:10 +0100148 if (!config.tickets.category) return;
PineaFan9b2ac4d2023-01-18 14:41:07 +0000149 const tickets: CategoryChannel | TextChannel | undefined = fetchedGuild.channels.cache.get(config.tickets.category) as CategoryChannel | TextChannel | undefined;
pineafan813bdf42022-07-24 10:39:10 +0100150 if (!tickets) return;
pineafan63fc5e22022-08-04 22:04:10 +0100151 let deleted = 0;
PineaFan9b2ac4d2023-01-18 14:41:07 +0000152 if (tickets.type === Discord.ChannelType.GuildCategory) {
153 // For channels, the topic is the user ID, then the word Active
154 const category = tickets as Discord.CategoryChannel;
155 category.children.cache.forEach((element) => {
156 if (!(element.type === Discord.ChannelType.GuildText)) return;
157 if (!(((element as Discord.TextChannel).topic ?? "").includes(member))) return;
pineafan63fc5e22022-08-04 22:04:10 +0100158 try {
159 element.delete();
PineaFan9b2ac4d2023-01-18 14:41:07 +0000160 deleted++;
161 } catch (e) {
162 console.error(e);
Skyler Grey75ea9172022-08-06 10:22:23 +0100163 }
PineaFan9b2ac4d2023-01-18 14:41:07 +0000164 });
165 } else {
166 // For threads, the name is the users name, id, then the word Active
167 const channel = tickets as Discord.TextChannel;
168 channel.threads.cache.forEach((element: Discord.ThreadChannel) => {
169 if (!element.name.includes(member)) return;
170 try {
171 element.delete();
172 deleted++;
173 } catch (e) {
174 console.error(e);
pineafan813bdf42022-07-24 10:39:10 +0100175 }
PineaFan9b2ac4d2023-01-18 14:41:07 +0000176 });
pineafan813bdf42022-07-24 10:39:10 +0100177 }
PineaFan9b2ac4d2023-01-18 14:41:07 +0000178 if (!deleted) return
179 const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
180 const data = {
181 meta: {
182 type: "ticketPurge",
183 displayName: "Tickets Purged",
184 calculateType: "ticketUpdate",
185 color: NucleusColors.red,
186 emoji: "GUILD.TICKET.DELETE",
TheCodedProf6ec331b2023-02-20 12:13:06 -0500187 timestamp: Date.now()
PineaFan9b2ac4d2023-01-18 14:41:07 +0000188 },
189 list: {
190 ticketFor: entry(member, renderUser(member)),
191 deletedBy: entry(null, "Member left server"),
TheCodedProf6ec331b2023-02-20 12:13:06 -0500192 deleted: entry(Date.now(), renderDelta(Date.now())),
PineaFan9b2ac4d2023-01-18 14:41:07 +0000193 ticketsDeleted: deleted
194 },
195 hidden: {
196 guild: guild
197 }
198 };
199 log(data);
pineafan813bdf42022-07-24 10:39:10 +0100200}
201
TheCodedProf9c51a7e2023-02-27 17:11:13 -0500202export { purgeByUser };