Files
EllyDiscordBot/src/commands/moderation/purge.ts

181 lines
5.8 KiB
TypeScript

/**
* Purge Command
* Delete multiple messages at once
*/
import {
SlashCommandBuilder,
EmbedBuilder,
PermissionFlagsBits,
type ChatInputCommandInteraction,
type TextChannel,
} from 'discord.js';
import type { Command } from '../../types/index.ts';
import { PermissionLevel } from '../../types/index.ts';
import type { EllyClient } from '../../client/EllyClient.ts';
export const purgeCommand: Command = {
data: new SlashCommandBuilder()
.setName('purge')
.setDescription('Delete multiple messages at once')
.addIntegerOption((option) =>
option
.setName('amount')
.setDescription('Number of messages to delete (1-100)')
.setRequired(true)
.setMinValue(1)
.setMaxValue(100)
)
.addUserOption((option) =>
option
.setName('user')
.setDescription('Only delete messages from this user')
.setRequired(false)
)
.addStringOption((option) =>
option
.setName('contains')
.setDescription('Only delete messages containing this text')
.setRequired(false)
)
.setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages),
permission: PermissionLevel.Officer,
cooldown: 5,
guildOnly: true,
async execute(interaction: ChatInputCommandInteraction): Promise<void> {
const client = interaction.client as EllyClient;
if (!interaction.guild || !interaction.channel) {
await interaction.reply({
content: 'This command can only be used in a server.',
ephemeral: true,
});
return;
}
const channel = interaction.channel as TextChannel;
const amount = interaction.options.getInteger('amount', true);
const targetUser = interaction.options.getUser('user');
const containsText = interaction.options.getString('contains');
// Check bot permissions
const botMember = interaction.guild.members.me;
if (!botMember?.permissions.has(PermissionFlagsBits.ManageMessages)) {
await interaction.reply({
embeds: [
new EmbedBuilder()
.setColor(client.config.colors.error)
.setTitle('❌ Missing Permissions')
.setDescription('I need the **Manage Messages** permission to delete messages.'),
],
ephemeral: true,
});
return;
}
// Defer reply since this might take a moment
await interaction.deferReply({ ephemeral: true });
try {
// Fetch messages
const messages = await channel.messages.fetch({ limit: 100 });
// Filter messages
let filtered = messages.filter((msg) => {
// Can't delete messages older than 14 days
const twoWeeksAgo = Date.now() - 14 * 24 * 60 * 60 * 1000;
if (msg.createdTimestamp < twoWeeksAgo) return false;
// Filter by user if specified
if (targetUser && msg.author.id !== targetUser.id) return false;
// Filter by content if specified
if (containsText && !msg.content.toLowerCase().includes(containsText.toLowerCase())) {
return false;
}
return true;
});
// Limit to requested amount
filtered = filtered.first(amount);
if (filtered.length === 0) {
await interaction.editReply({
embeds: [
new EmbedBuilder()
.setColor(client.config.colors.warning)
.setTitle('⚠️ No Messages Found')
.setDescription(
'No messages matching your criteria were found.\n\n' +
'**Note:** Messages older than 14 days cannot be bulk deleted.'
),
],
});
return;
}
// Delete messages
const deleted = await channel.bulkDelete(filtered, true);
// Build result embed
const embed = new EmbedBuilder()
.setColor(client.config.colors.success)
.setTitle('🗑️ Messages Purged')
.setDescription(`Successfully deleted **${deleted.size}** message${deleted.size !== 1 ? 's' : ''}.`)
.addFields(
{ name: 'Channel', value: `${channel}`, inline: true },
{ name: 'Requested', value: String(amount), inline: true },
{ name: 'Deleted', value: String(deleted.size), inline: true }
)
.setFooter({
text: `Purged by ${interaction.user.tag}`,
iconURL: interaction.user.displayAvatarURL(),
})
.setTimestamp();
if (targetUser) {
embed.addFields({ name: 'User Filter', value: `${targetUser}`, inline: true });
}
if (containsText) {
embed.addFields({ name: 'Content Filter', value: `"${containsText}"`, inline: true });
}
await interaction.editReply({ embeds: [embed] });
// Log to development channel if configured
if (client.channels_cache.developmentLogs) {
const logEmbed = new EmbedBuilder()
.setColor(client.config.colors.warning)
.setTitle('📋 Purge Log')
.addFields(
{ name: 'Moderator', value: `${interaction.user} (${interaction.user.id})`, inline: true },
{ name: 'Channel', value: `${channel} (${channel.id})`, inline: true },
{ name: 'Messages Deleted', value: String(deleted.size), inline: true }
)
.setTimestamp();
if (targetUser) {
logEmbed.addFields({ name: 'Target User', value: `${targetUser} (${targetUser.id})`, inline: true });
}
await client.channels_cache.developmentLogs.send({ embeds: [logEmbed] });
}
} catch (error) {
client.logger.error('Error purging messages', error);
await interaction.editReply({
embeds: [
new EmbedBuilder()
.setColor(client.config.colors.error)
.setTitle('❌ Error')
.setDescription('An error occurred while trying to delete messages.'),
],
});
}
},
};