blob: fbfa221f903184568f69bc673549f3b5a9074409 [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';
pineafan813bdf42022-07-24 10:39:10 +01007
PineaFan538d3752023-01-12 21:48:23 +00008export default async function (interaction: Discord.CommandInteraction | ButtonInteraction) {
PineaFana00db1b2023-01-02 15:32:54 +00009 if (!interaction.guild) return;
PineaFan0d06edc2023-01-17 22:10:31 +000010 const config = await client.database.guilds.read(interaction.guild.id);
Skyler Grey11236ba2022-08-08 21:13:33 +010011 const { log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger;
pineafan813bdf42022-07-24 10:39:10 +010012
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",
pineafan813bdf42022-07-24 10:39:10 +010053 timestamp: new Date().getTime()
54 },
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)),
61 closed: entry(new Date().getTime(), renderDelta(new Date().getTime())),
62 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") {
PineaFan0d06edc2023-01-17 22:10:31 +000072 // Close the ticket
73
74 if (channel.isThread()) {
75 channel.setName(`${channel.name.replace("Active", "Archived")}`);
76 channel.members.remove(channel.name.split(" - ")[1]!);
77 } else {
78 channel.setTopic(`${(channel.topic ?? "").replace("Active", "Archived")}`);
79 if (!channel.topic!.includes("Archived")) { channel.setTopic("0 Archived"); }
80 await channel.permissionOverwrites.delete(channel.topic!.split(" ")[0]!);
81 }
82 preloadPage(interaction.channel.id, "privacy", "2")
Skyler Grey75ea9172022-08-06 10:22:23 +010083 await interaction.reply({
84 embeds: [
85 new EmojiEmbed()
PineaFan0d06edc2023-01-17 22:10:31 +000086 .setTitle("Archived Ticket")
TheCodedProff86ba092023-01-27 17:10:07 -050087 .setDescription(`This ticket has been Archived. Type ${getCommandMentionByName("ticket/close")} to delete it.` +
PineaFan0d06edc2023-01-17 22:10:31 +000088 await client.database.premium.hasPremium(interaction.guild.id) ?
TheCodedProff86ba092023-01-27 17:10:07 -050089 `\n\nFor more info on transcripts, check ${getCommandMentionByName("privacy")}` :
PineaFan0d06edc2023-01-17 22:10:31 +000090 "")
Skyler Grey75ea9172022-08-06 10:22:23 +010091 .setStatus("Warning")
92 .setEmoji("GUILD.TICKET.ARCHIVED")
93 ],
94 components: [
PineaFan0d06edc2023-01-17 22:10:31 +000095 new ActionRowBuilder<ButtonBuilder>().addComponents(
Skyler Grey75ea9172022-08-06 10:22:23 +010096 [
TheCodedProf21c08592022-09-13 14:14:43 -040097 new ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +010098 .setLabel("Delete")
TheCodedProf21c08592022-09-13 14:14:43 -040099 .setStyle(ButtonStyle.Danger)
Skyler Grey75ea9172022-08-06 10:22:23 +0100100 .setCustomId("closeticket")
101 .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
102 ].concat(
PineaFan0d06edc2023-01-17 22:10:31 +0000103 await client.database.premium.hasPremium(interaction.guild.id)
Skyler Grey75ea9172022-08-06 10:22:23 +0100104 ? [
PineaFan0d06edc2023-01-17 22:10:31 +0000105 new ButtonBuilder()
106 .setLabel("Create Transcript and Delete")
107 .setStyle(ButtonStyle.Primary)
108 .setCustomId("createtranscript")
109 .setEmoji(getEmojiByName("CONTROL.DOWNLOAD", "id"))
110 ]
Skyler Grey75ea9172022-08-06 10:22:23 +0100111 : []
112 )
113 )
114 ]
115 });
PineaFan0d06edc2023-01-17 22:10:31 +0000116 const data = {
117 meta: {
118 type: "ticketClosed",
119 displayName: "Ticket Archived",
120 calculateType: "ticketUpdate",
121 color: NucleusColors.yellow,
122 emoji: "GUILD.TICKET.ARCHIVED",
123 timestamp: new Date().getTime()
124 },
125 list: {
126 ticketFor: entry(
127 uID!,
128 renderUser((await interaction.guild.members.fetch(uID!)).user)
129 ),
130 archivedBy: entry(interaction.member!.user.id, renderUser(interaction.member!.user as Discord.User)),
131 archived: entry(new Date().getTime(), renderDelta(new Date().getTime())),
132 ticketChannel: entry(channel.id, renderChannel(channel))
133 },
134 hidden: {
135 guild: interaction.guild.id
136 }
137 };
138 log(data);
pineafan813bdf42022-07-24 10:39:10 +0100139 }
PineaFan0d06edc2023-01-17 22:10:31 +0000140 return;
pineafan813bdf42022-07-24 10:39:10 +0100141}
142
PineaFan0d06edc2023-01-17 22:10:31 +0000143
144async function purgeByUser(member: string, guild: string) {
PineaFan9b2ac4d2023-01-18 14:41:07 +0000145 const config = await client.database.guilds.read(guild);
PineaFan0d06edc2023-01-17 22:10:31 +0000146 const fetchedGuild = await client.guilds.fetch(guild);
pineafan813bdf42022-07-24 10:39:10 +0100147 if (!config.tickets.category) return;
PineaFan9b2ac4d2023-01-18 14:41:07 +0000148 const tickets: CategoryChannel | TextChannel | undefined = fetchedGuild.channels.cache.get(config.tickets.category) as CategoryChannel | TextChannel | undefined;
pineafan813bdf42022-07-24 10:39:10 +0100149 if (!tickets) return;
pineafan63fc5e22022-08-04 22:04:10 +0100150 let deleted = 0;
PineaFan9b2ac4d2023-01-18 14:41:07 +0000151 if (tickets.type === Discord.ChannelType.GuildCategory) {
152 // For channels, the topic is the user ID, then the word Active
153 const category = tickets as Discord.CategoryChannel;
154 category.children.cache.forEach((element) => {
155 if (!(element.type === Discord.ChannelType.GuildText)) return;
156 if (!(((element as Discord.TextChannel).topic ?? "").includes(member))) return;
pineafan63fc5e22022-08-04 22:04:10 +0100157 try {
158 element.delete();
PineaFan9b2ac4d2023-01-18 14:41:07 +0000159 deleted++;
160 } catch (e) {
161 console.error(e);
Skyler Grey75ea9172022-08-06 10:22:23 +0100162 }
PineaFan9b2ac4d2023-01-18 14:41:07 +0000163 });
164 } else {
165 // For threads, the name is the users name, id, then the word Active
166 const channel = tickets as Discord.TextChannel;
167 channel.threads.cache.forEach((element: Discord.ThreadChannel) => {
168 if (!element.name.includes(member)) return;
169 try {
170 element.delete();
171 deleted++;
172 } catch (e) {
173 console.error(e);
pineafan813bdf42022-07-24 10:39:10 +0100174 }
PineaFan9b2ac4d2023-01-18 14:41:07 +0000175 });
pineafan813bdf42022-07-24 10:39:10 +0100176 }
PineaFan9b2ac4d2023-01-18 14:41:07 +0000177 if (!deleted) return
178 const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
179 const data = {
180 meta: {
181 type: "ticketPurge",
182 displayName: "Tickets Purged",
183 calculateType: "ticketUpdate",
184 color: NucleusColors.red,
185 emoji: "GUILD.TICKET.DELETE",
186 timestamp: new Date().getTime()
187 },
188 list: {
189 ticketFor: entry(member, renderUser(member)),
190 deletedBy: entry(null, "Member left server"),
191 deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
192 ticketsDeleted: deleted
193 },
194 hidden: {
195 guild: guild
196 }
197 };
198 log(data);
pineafan813bdf42022-07-24 10:39:10 +0100199}
200
PineaFan0d06edc2023-01-17 22:10:31 +0000201export { purgeByUser };