Implement confirmation flow for destructive moderation actions

- Added confirmation prompts for destructive commands such as `/ban`, `/purge`, and `/case delete` to enhance user safety.
- Integrated locale support for confirmation messages, ensuring clarity in both German and English.
- Refactored command logic to utilize the new confirmation system, improving user experience and reducing accidental actions.
This commit is contained in:
smueller
2026-07-22 11:26:49 +02:00
parent a17d161c06
commit 878478e4fc
6 changed files with 402 additions and 51 deletions

View File

@@ -14,6 +14,12 @@ import { registerCommands, routeCommand } from './commands.js';
import { ensureRecurringJobs, startWorkers } from './jobs.js';
import type { BotContext } from './types.js';
import { startHealthServer } from './health.js';
import {
handleModerationConfirmation,
isModerationConfirmation
} from './modules/moderation/confirmations.js';
import { getGuildLocale } from './i18n.js';
import { t } from '@nexumi/shared';
const isShard = process.argv.includes('--shard');
@@ -47,15 +53,26 @@ if (!isShard) {
});
client.on(Events.InteractionCreate, async (interaction: Interaction) => {
if (!interaction.isChatInputCommand()) return;
try {
await routeCommand(interaction, context);
if (interaction.isChatInputCommand()) {
await routeCommand(interaction, context);
return;
}
if (interaction.isButton() && isModerationConfirmation(interaction.customId)) {
await handleModerationConfirmation(interaction, context);
return;
}
} catch (error) {
logger.error({ error }, 'Command execution failed');
if (interaction.replied || interaction.deferred) {
await interaction.followUp({ content: 'An error occurred.', ephemeral: true });
} else {
await interaction.reply({ content: 'An error occurred.', ephemeral: true });
logger.error({ error }, 'Interaction handling failed');
const locale = await getGuildLocale(context.prisma, interaction.guildId);
const message = t(locale, 'generic.error');
if (interaction.isRepliable()) {
if (interaction.replied || interaction.deferred) {
await interaction.followUp({ content: message, ephemeral: true });
} else {
await interaction.reply({ content: message, ephemeral: true });
}
}
}
});