blob: 60878900cc99d408ddb7703aa99401c11a1e509f [file] [log] [blame]
PineaFana34d04b2023-01-03 22:05:42 +00001import Discord, { CommandInteraction, GuildChannel, GuildMember, TextChannel, ButtonStyle, ButtonBuilder } from "discord.js";
pineafan3a02ea32022-08-11 21:35:04 +01002import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
pineafan8b4b17f2022-02-27 20:42:52 +00003import confirmationMessage from "../../utils/confirmationMessage.js";
pineafan4edb7762022-06-26 19:21:04 +01004import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
pineafan8b4b17f2022-02-27 20:42:52 +00005import keyValueList from "../../utils/generateKeyValueList.js";
6import getEmojiByName from "../../utils/getEmojiByName.js";
pineafan4edb7762022-06-26 19:21:04 +01007import client from "../../utils/client.js";
pineafan4f164f32022-02-26 22:07:12 +00008
9const command = (builder: SlashCommandSubcommandBuilder) =>
10 builder
pineafan63fc5e22022-08-04 22:04:10 +010011 .setName("purge")
12 .setDescription("Bulk deletes messages in a channel")
Skyler Grey75ea9172022-08-06 10:22:23 +010013 .addIntegerOption((option) =>
14 option
15 .setName("amount")
16 .setDescription("The amount of messages to delete")
17 .setRequired(false)
18 .setMinValue(1)
19 .setMaxValue(100)
20 )
21 .addUserOption((option) =>
Skyler Grey11236ba2022-08-08 21:13:33 +010022 option.setName("user").setDescription("The user to purge messages from").setRequired(false)
Skyler Grey75ea9172022-08-06 10:22:23 +010023 )
24 .addStringOption((option) =>
Skyler Grey11236ba2022-08-08 21:13:33 +010025 option.setName("reason").setDescription("The reason for the purge").setRequired(false)
Skyler Grey75ea9172022-08-06 10:22:23 +010026 );
pineafan4f164f32022-02-26 22:07:12 +000027
pineafan3a02ea32022-08-11 21:35:04 +010028const callback = async (interaction: CommandInteraction): Promise<unknown> => {
PineaFana34d04b2023-01-03 22:05:42 +000029 if (!interaction.guild) return;
30 const user = (interaction.options.getMember("user") as GuildMember | null);
Skyler Grey75ea9172022-08-06 10:22:23 +010031 const channel = interaction.channel as GuildChannel;
32 if (
Skyler Grey11236ba2022-08-08 21:13:33 +010033 !["GUILD_TEXT", "GUILD_NEWS", "GUILD_NEWS_THREAD", "GUILD_PUBLIC_THREAD", "GUILD_PRIVATE_THREAD"].includes(
34 channel.type.toString()
35 )
Skyler Grey75ea9172022-08-06 10:22:23 +010036 ) {
pineafan8b4b17f2022-02-27 20:42:52 +000037 return await interaction.reply({
38 embeds: [
pineafan4edb7762022-06-26 19:21:04 +010039 new EmojiEmbed()
pineafan8b4b17f2022-02-27 20:42:52 +000040 .setEmoji("CHANNEL.PURGE.RED")
41 .setTitle("Purge")
42 .setDescription("You cannot purge this channel")
43 .setStatus("Danger")
44 ],
45 components: [],
pineafan63fc5e22022-08-04 22:04:10 +010046 ephemeral: true
47 });
pineafan8b4b17f2022-02-27 20:42:52 +000048 }
49 // TODO:[Modals] Replace this with a modal
PineaFana34d04b2023-01-03 22:05:42 +000050 if (!interaction.options.get("amount")) {
pineafan8b4b17f2022-02-27 20:42:52 +000051 await interaction.reply({
52 embeds: [
pineafan4edb7762022-06-26 19:21:04 +010053 new EmojiEmbed()
pineafan8b4b17f2022-02-27 20:42:52 +000054 .setEmoji("CHANNEL.PURGE.RED")
55 .setTitle("Purge")
56 .setDescription("Select how many messages to delete")
57 .setStatus("Danger")
58 ],
59 components: [],
60 ephemeral: true,
61 fetchReply: true
pineafan63fc5e22022-08-04 22:04:10 +010062 });
63 let deleted = [] as Discord.Message[];
Skyler Greyad002172022-08-16 18:48:26 +010064 let timedOut = false;
65 let amountSelected = false;
66 while (!timedOut && !amountSelected) {
Skyler Grey75ea9172022-08-06 10:22:23 +010067 const m = (await interaction.editReply({
pineafan8b4b17f2022-02-27 20:42:52 +000068 embeds: [
pineafan4edb7762022-06-26 19:21:04 +010069 new EmojiEmbed()
pineafan8b4b17f2022-02-27 20:42:52 +000070 .setEmoji("CHANNEL.PURGE.RED")
71 .setTitle("Purge")
Skyler Grey75ea9172022-08-06 10:22:23 +010072 .setDescription(
73 "Select how many messages to delete. You can continue clicking until all messages are cleared."
74 )
pineafan8b4b17f2022-02-27 20:42:52 +000075 .setStatus("Danger")
76 ],
77 components: [
PineaFana34d04b2023-01-03 22:05:42 +000078 new Discord.ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -040079 new Discord.ButtonBuilder().setCustomId("1").setLabel("1").setStyle(ButtonStyle.Secondary),
80 new Discord.ButtonBuilder().setCustomId("3").setLabel("3").setStyle(ButtonStyle.Secondary),
81 new Discord.ButtonBuilder().setCustomId("5").setLabel("5").setStyle(ButtonStyle.Secondary)
pineafan63fc5e22022-08-04 22:04:10 +010082 ]),
PineaFana34d04b2023-01-03 22:05:42 +000083 new Discord.ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -040084 new Discord.ButtonBuilder().setCustomId("10").setLabel("10").setStyle(ButtonStyle.Secondary),
85 new Discord.ButtonBuilder().setCustomId("25").setLabel("25").setStyle(ButtonStyle.Secondary),
86 new Discord.ButtonBuilder().setCustomId("50").setLabel("50").setStyle(ButtonStyle.Secondary)
pineafan8b4b17f2022-02-27 20:42:52 +000087 ]),
PineaFana34d04b2023-01-03 22:05:42 +000088 new Discord.ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -040089 new Discord.ButtonBuilder()
pineafan8b4b17f2022-02-27 20:42:52 +000090 .setCustomId("done")
91 .setLabel("Done")
TheCodedProf21c08592022-09-13 14:14:43 -040092 .setStyle(ButtonStyle.Success)
pineafan8b4b17f2022-02-27 20:42:52 +000093 .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
94 ])
95 ]
Skyler Grey75ea9172022-08-06 10:22:23 +010096 })) as Discord.Message;
pineafan8b4b17f2022-02-27 20:42:52 +000097 let component;
98 try {
Skyler Grey75ea9172022-08-06 10:22:23 +010099 component = m.awaitMessageComponent({
100 filter: (m) => m.user.id === interaction.user.id,
101 time: 300000
102 });
103 } catch (e) {
Skyler Greyad002172022-08-16 18:48:26 +0100104 timedOut = true;
105 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100106 }
TheCodedProf21c08592022-09-13 14:14:43 -0400107 (await component).deferUpdate();
108 if ((await component).customId === "done") {
Skyler Greyad002172022-08-16 18:48:26 +0100109 amountSelected = true;
110 continue;
Skyler Grey75ea9172022-08-06 10:22:23 +0100111 }
TheCodedProf21c08592022-09-13 14:14:43 -0400112 const amount = parseInt((await component).customId);
Skyler Greyad002172022-08-16 18:48:26 +0100113
PineaFana34d04b2023-01-03 22:05:42 +0000114 let messages: Discord.Message[] = [];
Skyler Grey11236ba2022-08-08 21:13:33 +0100115 await (interaction.channel as TextChannel).messages.fetch({ limit: amount }).then(async (ms) => {
116 if (user) {
117 ms = ms.filter((m) => m.author.id === user.id);
118 }
PineaFana34d04b2023-01-03 22:05:42 +0000119 messages = (await (channel as TextChannel).bulkDelete(ms, true)).map(m => m as Discord.Message);
Skyler Grey11236ba2022-08-08 21:13:33 +0100120 });
PineaFana34d04b2023-01-03 22:05:42 +0000121 deleted = deleted.concat(messages);
pineafan8b4b17f2022-02-27 20:42:52 +0000122 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100123 if (deleted.length === 0)
124 return await interaction.editReply({
125 embeds: [
126 new EmojiEmbed()
127 .setEmoji("CHANNEL.PURGE.RED")
128 .setTitle("Purge")
129 .setDescription("No messages were deleted")
130 .setStatus("Danger")
131 ],
132 components: []
133 });
pineafan4edb7762022-06-26 19:21:04 +0100134 if (user) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100135 await client.database.history.create(
136 "purge",
137 interaction.guild.id,
PineaFana34d04b2023-01-03 22:05:42 +0000138 user.user,
139 interaction.user,
140 (interaction.options.get("reason")?.value as (string | null)) ?? "*No reason provided*",
Skyler Grey75ea9172022-08-06 10:22:23 +0100141 null,
142 null,
PineaFana34d04b2023-01-03 22:05:42 +0000143 deleted.length.toString()
Skyler Grey75ea9172022-08-06 10:22:23 +0100144 );
pineafan4edb7762022-06-26 19:21:04 +0100145 }
Skyler Grey11236ba2022-08-08 21:13:33 +0100146 const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger;
pineafan63fc5e22022-08-04 22:04:10 +0100147 const data = {
148 meta: {
149 type: "channelPurge",
150 displayName: "Channel Purged",
151 calculateType: "messageDelete",
152 color: NucleusColors.red,
153 emoji: "PUNISH.BAN.RED",
154 timestamp: new Date().getTime()
155 },
156 list: {
Skyler Grey11236ba2022-08-08 21:13:33 +0100157 memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
158 purgedBy: entry(interaction.user.id, renderUser(interaction.user)),
PineaFana34d04b2023-01-03 22:05:42 +0000159 channel: entry(interaction.channel!.id, renderChannel(interaction.channel! as GuildChannel)),
160 messagesCleared: entry(deleted.length.toString(), deleted.length.toString())
pineafan63fc5e22022-08-04 22:04:10 +0100161 },
162 hidden: {
163 guild: interaction.guild.id
pineafane625d782022-05-09 18:04:32 +0100164 }
pineafan63fc5e22022-08-04 22:04:10 +0100165 };
166 log(data);
167 let out = "";
Skyler Grey75ea9172022-08-06 10:22:23 +0100168 deleted.reverse().forEach((message) => {
Skyler Grey11236ba2022-08-08 21:13:33 +0100169 out += `${message.author.username}#${message.author.discriminator} (${message.author.id}) [${new Date(
Skyler Grey75ea9172022-08-06 10:22:23 +0100170 message.createdTimestamp
171 ).toISOString()}]\n`;
pineafan63fc5e22022-08-04 22:04:10 +0100172 const lines = message.content.split("\n");
Skyler Grey75ea9172022-08-06 10:22:23 +0100173 lines.forEach((line) => {
174 out += `> ${line}\n`;
175 });
pineafan63fc5e22022-08-04 22:04:10 +0100176 out += "\n\n";
177 });
178 const attachmentObject = {
179 attachment: Buffer.from(out),
180 name: `purge-${channel.id}-${Date.now()}.txt`,
181 description: "Purge log"
182 };
Skyler Grey75ea9172022-08-06 10:22:23 +0100183 const m = (await interaction.editReply({
184 embeds: [
185 new EmojiEmbed()
186 .setEmoji("CHANNEL.PURGE.GREEN")
187 .setTitle("Purge")
188 .setDescription("Messages cleared")
189 .setStatus("Success")
190 ],
191 components: [
PineaFana34d04b2023-01-03 22:05:42 +0000192 new Discord.ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400193 new Discord.ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100194 .setCustomId("download")
195 .setLabel("Download transcript")
TheCodedProf21c08592022-09-13 14:14:43 -0400196 .setStyle(ButtonStyle.Success)
Skyler Grey75ea9172022-08-06 10:22:23 +0100197 .setEmoji(getEmojiByName("CONTROL.DOWNLOAD", "id"))
198 ])
199 ]
200 })) as Discord.Message;
pineafan5d1908e2022-02-28 21:34:47 +0000201 let component;
202 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100203 component = await m.awaitMessageComponent({
204 filter: (m) => m.user.id === interaction.user.id,
205 time: 300000
206 });
207 } catch {
208 return;
209 }
PineaFana34d04b2023-01-03 22:05:42 +0000210 if (component.customId === "download") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100211 interaction.editReply({
212 embeds: [
213 new EmojiEmbed()
214 .setEmoji("CHANNEL.PURGE.GREEN")
215 .setTitle("Purge")
216 .setDescription("Uploaded")
217 .setStatus("Success")
218 ],
219 components: [],
220 files: [attachmentObject]
221 });
pineafan5d1908e2022-02-28 21:34:47 +0000222 } else {
Skyler Grey75ea9172022-08-06 10:22:23 +0100223 interaction.editReply({
224 embeds: [
225 new EmojiEmbed()
226 .setEmoji("CHANNEL.PURGE.GREEN")
227 .setTitle("Purge")
228 .setDescription("Messages cleared")
229 .setStatus("Success")
230 ],
231 components: []
232 });
pineafan5d1908e2022-02-28 21:34:47 +0000233 }
pineafan63fc5e22022-08-04 22:04:10 +0100234 return;
pineafan8b4b17f2022-02-27 20:42:52 +0000235 } else {
pineafan63fc5e22022-08-04 22:04:10 +0100236 const confirmation = await new confirmationMessage(interaction)
pineafan8b4b17f2022-02-27 20:42:52 +0000237 .setEmoji("CHANNEL.PURGE.RED")
238 .setTitle("Purge")
Skyler Grey75ea9172022-08-06 10:22:23 +0100239 .setDescription(
240 keyValueList({
241 channel: `<#${channel.id}>`,
PineaFana34d04b2023-01-03 22:05:42 +0000242 amount: (interaction.options.get("amount")?.value as number).toString(),
243 reason: `\n> ${interaction.options.get("reason")?.value ? interaction.options.get("reason")?.value : "*No reason provided*"}`
Skyler Grey75ea9172022-08-06 10:22:23 +0100244 })
245 )
pineafan8b4b17f2022-02-27 20:42:52 +0000246 .setColor("Danger")
pineafan63fc5e22022-08-04 22:04:10 +0100247 .send();
248 if (confirmation.cancelled) return;
pineafan377794f2022-04-18 19:01:01 +0100249 if (confirmation.success) {
pineafan5d1908e2022-02-28 21:34:47 +0000250 let messages;
pineafan8b4b17f2022-02-27 20:42:52 +0000251 try {
pineafan377794f2022-04-18 19:01:01 +0100252 if (!user) {
Skyler Grey11236ba2022-08-08 21:13:33 +0100253 const toDelete = await (interaction.channel as TextChannel).messages.fetch({
PineaFana34d04b2023-01-03 22:05:42 +0000254 limit: interaction.options.get("amount")?.value as number
Skyler Grey75ea9172022-08-06 10:22:23 +0100255 });
Skyler Grey11236ba2022-08-08 21:13:33 +0100256 messages = await (channel as TextChannel).bulkDelete(toDelete, true);
pineafan377794f2022-04-18 19:01:01 +0100257 } else {
Skyler Grey75ea9172022-08-06 10:22:23 +0100258 const toDelete = (
259 await (
Skyler Grey11236ba2022-08-08 21:13:33 +0100260 await (interaction.channel as TextChannel).messages.fetch({
Skyler Grey75ea9172022-08-06 10:22:23 +0100261 limit: 100
262 })
263 ).filter((m) => m.author.id === user.id)
PineaFana34d04b2023-01-03 22:05:42 +0000264 ).first(interaction.options.get("amount")?.value as number);
Skyler Grey11236ba2022-08-08 21:13:33 +0100265 messages = await (channel as TextChannel).bulkDelete(toDelete, true);
pineafan377794f2022-04-18 19:01:01 +0100266 }
Skyler Grey75ea9172022-08-06 10:22:23 +0100267 } catch (e) {
268 await interaction.editReply({
269 embeds: [
270 new EmojiEmbed()
271 .setEmoji("CHANNEL.PURGE.RED")
272 .setTitle("Purge")
Skyler Grey11236ba2022-08-08 21:13:33 +0100273 .setDescription("Something went wrong and no messages were deleted")
Skyler Grey75ea9172022-08-06 10:22:23 +0100274 .setStatus("Danger")
275 ],
276 components: []
277 });
pineafan8b4b17f2022-02-27 20:42:52 +0000278 }
PineaFana34d04b2023-01-03 22:05:42 +0000279 if (!messages) {
280 await interaction.editReply({
281 embeds: [
282 new EmojiEmbed()
283 .setEmoji("CHANNEL.PURGE.RED")
284 .setTitle("Purge")
285 .setDescription("No messages could be deleted")
286 .setStatus("Danger")
287 ],
288 components: []
289 });
290 return;
291 }
pineafan4edb7762022-06-26 19:21:04 +0100292 if (user) {
Skyler Grey75ea9172022-08-06 10:22:23 +0100293 await client.database.history.create(
294 "purge",
295 interaction.guild.id,
PineaFana34d04b2023-01-03 22:05:42 +0000296 user.user,
297 interaction.user,
298 (interaction.options.get("reason")?.value as (string | null)) ?? "*No reason provided*",
Skyler Grey75ea9172022-08-06 10:22:23 +0100299 null,
300 null,
PineaFana34d04b2023-01-03 22:05:42 +0000301 messages.size.toString()
Skyler Grey75ea9172022-08-06 10:22:23 +0100302 );
pineafan4edb7762022-06-26 19:21:04 +0100303 }
Skyler Grey11236ba2022-08-08 21:13:33 +0100304 const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger;
pineafan63fc5e22022-08-04 22:04:10 +0100305 const data = {
306 meta: {
307 type: "channelPurge",
308 displayName: "Channel Purged",
309 calculateType: "messageDelete",
310 color: NucleusColors.red,
311 emoji: "PUNISH.BAN.RED",
312 timestamp: new Date().getTime()
313 },
314 list: {
Skyler Grey11236ba2022-08-08 21:13:33 +0100315 memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
316 purgedBy: entry(interaction.user.id, renderUser(interaction.user)),
PineaFana34d04b2023-01-03 22:05:42 +0000317 channel: entry(interaction.channel!.id, renderChannel(interaction.channel! as GuildChannel)),
318 messagesCleared: entry(messages.size.toString(), messages.size.toString())
pineafan63fc5e22022-08-04 22:04:10 +0100319 },
320 hidden: {
321 guild: interaction.guild.id
pineafane625d782022-05-09 18:04:32 +0100322 }
pineafan63fc5e22022-08-04 22:04:10 +0100323 };
324 log(data);
325 let out = "";
Skyler Grey75ea9172022-08-06 10:22:23 +0100326 messages.reverse().forEach((message) => {
PineaFana34d04b2023-01-03 22:05:42 +0000327 if (!message) {
328 out += "Unknown message\n\n"
329 } else {
330 const author = message.author ?? { username: "Unknown", discriminator: "0000", id: "Unknown" };
331 out += `${author.username}#${author.discriminator} (${author.id}) [${new Date(
332 message.createdTimestamp
333 ).toISOString()}]\n`;
334 if (message.content) {
335 const lines = message.content.split("\n");
336 lines.forEach((line) => {
337 out += `> ${line}\n`;
338 });
339 }
340 if (message.attachments.size > 0) {
341 message.attachments.forEach((attachment) => {
342 out += `Attachment > ${attachment.url}\n`;
343 });
344 }
345 out += "\n\n";
346 }
pineafan63fc5e22022-08-04 22:04:10 +0100347 });
348 const attachmentObject = {
349 attachment: Buffer.from(out),
350 name: `purge-${channel.id}-${Date.now()}.txt`,
351 description: "Purge log"
352 };
Skyler Grey75ea9172022-08-06 10:22:23 +0100353 const m = (await interaction.editReply({
354 embeds: [
355 new EmojiEmbed()
356 .setEmoji("CHANNEL.PURGE.GREEN")
357 .setTitle("Purge")
358 .setDescription("Messages cleared")
359 .setStatus("Success")
360 ],
361 components: [
PineaFana34d04b2023-01-03 22:05:42 +0000362 new Discord.ActionRowBuilder<ButtonBuilder>().addComponents([
TheCodedProf21c08592022-09-13 14:14:43 -0400363 new Discord.ButtonBuilder()
Skyler Grey75ea9172022-08-06 10:22:23 +0100364 .setCustomId("download")
365 .setLabel("Download transcript")
TheCodedProf21c08592022-09-13 14:14:43 -0400366 .setStyle(ButtonStyle.Success)
Skyler Grey75ea9172022-08-06 10:22:23 +0100367 .setEmoji(getEmojiByName("CONTROL.DOWNLOAD", "id"))
368 ])
369 ]
370 })) as Discord.Message;
pineafan5d1908e2022-02-28 21:34:47 +0000371 let component;
372 try {
Skyler Grey75ea9172022-08-06 10:22:23 +0100373 component = await m.awaitMessageComponent({
374 filter: (m) => m.user.id === interaction.user.id,
375 time: 300000
376 });
377 } catch {
378 return;
379 }
PineaFana34d04b2023-01-03 22:05:42 +0000380 if (component.customId === "download") {
Skyler Grey75ea9172022-08-06 10:22:23 +0100381 interaction.editReply({
382 embeds: [
383 new EmojiEmbed()
384 .setEmoji("CHANNEL.PURGE.GREEN")
385 .setTitle("Purge")
386 .setDescription("Transcript uploaded above")
387 .setStatus("Success")
388 ],
389 components: [],
390 files: [attachmentObject]
391 });
pineafan5d1908e2022-02-28 21:34:47 +0000392 } else {
Skyler Grey75ea9172022-08-06 10:22:23 +0100393 interaction.editReply({
394 embeds: [
395 new EmojiEmbed()
396 .setEmoji("CHANNEL.PURGE.GREEN")
397 .setTitle("Purge")
398 .setDescription("Messages cleared")
399 .setStatus("Success")
400 ],
401 components: []
402 });
pineafan5d1908e2022-02-28 21:34:47 +0000403 }
pineafan8b4b17f2022-02-27 20:42:52 +0000404 } else {
Skyler Grey75ea9172022-08-06 10:22:23 +0100405 await interaction.editReply({
406 embeds: [
407 new EmojiEmbed()
408 .setEmoji("CHANNEL.PURGE.GREEN")
409 .setTitle("Purge")
410 .setDescription("No changes were made")
411 .setStatus("Success")
412 ],
413 components: []
414 });
pineafan8b4b17f2022-02-27 20:42:52 +0000415 }
416 }
pineafan63fc5e22022-08-04 22:04:10 +0100417};
pineafan4f164f32022-02-26 22:07:12 +0000418
pineafanbd02b4a2022-08-05 22:01:38 +0100419const check = (interaction: CommandInteraction) => {
PineaFana34d04b2023-01-03 22:05:42 +0000420 if (!interaction.guild) return false;
Skyler Grey75ea9172022-08-06 10:22:23 +0100421 const member = interaction.member as GuildMember;
PineaFana34d04b2023-01-03 22:05:42 +0000422 const me = interaction.guild.members.me!;
pineafanc1c18792022-08-03 21:41:36 +0100423 // Check if nucleus has the manage_messages permission
PineaFana34d04b2023-01-03 22:05:42 +0000424 if (!me.permissions.has("ManageMessages")) throw new Error("I do not have the *Manage Messages* permission");
pineafan8b4b17f2022-02-27 20:42:52 +0000425 // Allow the owner to purge
pineafan63fc5e22022-08-04 22:04:10 +0100426 if (member.id === interaction.guild.ownerId) return true;
pineafan8b4b17f2022-02-27 20:42:52 +0000427 // Check if the user has manage_messages permission
PineaFana34d04b2023-01-03 22:05:42 +0000428 if (!member.permissions.has("ManageMessages")) throw new Error("You do not have the *Manage Messages* permission");
pineafanc1c18792022-08-03 21:41:36 +0100429 // Allow purge
pineafan63fc5e22022-08-04 22:04:10 +0100430 return true;
431};
pineafan4f164f32022-02-26 22:07:12 +0000432
Skyler Grey75ea9172022-08-06 10:22:23 +0100433export { command, callback, check };