Enhance purge command with additional filtering options
- Added user, bots, links, attachments, and regex options to the purge command for more granular message deletion. - Updated the command execution logic to filter messages based on the new options before bulk deletion. - Modified CreateCaseInput type to use Prisma.InputJsonValue for metadata.
This commit is contained in:
@@ -356,13 +356,49 @@ const purgeCommand: SlashCommand = {
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('purge')
|
||||
.setDescription('Bulk delete messages')
|
||||
.addIntegerOption((o) => o.setName('amount').setDescription('2-100').setRequired(true).setMinValue(2).setMaxValue(100)),
|
||||
.addIntegerOption((o) =>
|
||||
o.setName('amount').setDescription('2-100').setRequired(true).setMinValue(2).setMaxValue(100)
|
||||
)
|
||||
.addUserOption((o) => o.setName('user').setDescription('Only purge this user messages'))
|
||||
.addBooleanOption((o) => o.setName('bots').setDescription('Only purge bot messages'))
|
||||
.addBooleanOption((o) => o.setName('links').setDescription('Only purge messages containing links'))
|
||||
.addBooleanOption((o) =>
|
||||
o.setName('attachments').setDescription('Only purge messages with attachments')
|
||||
)
|
||||
.addStringOption((o) =>
|
||||
o.setName('regex').setDescription('Only purge messages matching regex')
|
||||
),
|
||||
async execute(interaction, context) {
|
||||
if (!(await ensureMod(interaction, PermissionFlagsBits.ManageMessages))) return;
|
||||
const amount = interaction.options.getInteger('amount', true);
|
||||
const targetUser = interaction.options.getUser('user');
|
||||
const botsOnly = interaction.options.getBoolean('bots') ?? false;
|
||||
const linksOnly = interaction.options.getBoolean('links') ?? false;
|
||||
const attachmentsOnly = interaction.options.getBoolean('attachments') ?? false;
|
||||
const regexInput = interaction.options.getString('regex');
|
||||
let regex: RegExp | null = null;
|
||||
if (regexInput) {
|
||||
try {
|
||||
regex = new RegExp(regexInput, 'i');
|
||||
} catch {
|
||||
await interaction.reply({ content: 'Invalid regex pattern.', ephemeral: true });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let deletedCount = 0;
|
||||
if (interaction.channel instanceof TextChannel) {
|
||||
const deleted = await interaction.channel.bulkDelete(amount, true);
|
||||
const fetched = await interaction.channel.messages.fetch({ limit: 100 });
|
||||
const filtered = fetched.filter((message) => {
|
||||
if (targetUser && message.author.id !== targetUser.id) return false;
|
||||
if (botsOnly && !message.author.bot) return false;
|
||||
if (linksOnly && !/(https?:\/\/|discord\.gg\/)/i.test(message.content)) return false;
|
||||
if (attachmentsOnly && message.attachments.size === 0) return false;
|
||||
if (regex && !regex.test(message.content)) return false;
|
||||
return true;
|
||||
});
|
||||
const toDelete = filtered.first(amount);
|
||||
const deleted = await interaction.channel.bulkDelete(toDelete, true);
|
||||
deletedCount = deleted.size;
|
||||
}
|
||||
await createCase(context, {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { moderationQueue } from '../../jobs.js';
|
||||
import type { BotContext } from '../../types.js';
|
||||
import { PermissionFlagsBits, type ChatInputCommandInteraction } from 'discord.js';
|
||||
import type { Prisma } from '@prisma/client';
|
||||
|
||||
type CreateCaseInput = {
|
||||
guildId: string;
|
||||
@@ -8,7 +9,7 @@ type CreateCaseInput = {
|
||||
moderatorId: string;
|
||||
action: string;
|
||||
reason?: string;
|
||||
metadata?: Record<string, unknown>;
|
||||
metadata?: Prisma.InputJsonValue;
|
||||
};
|
||||
|
||||
export async function createCase(context: BotContext, input: CreateCaseInput) {
|
||||
|
||||
Reference in New Issue
Block a user