import { createCommand } from "@/lib/utils"; import { SlashCommandBuilder, PermissionFlagsBits, MessageFlags } from "discord.js"; import { ModerationService } from "@/modules/moderation/moderation.service"; import { getWarnSuccessEmbed, getModerationErrorEmbed, getUserWarningEmbed } from "@/modules/moderation/moderation.view"; import { config } from "@/lib/config"; export const warn = createCommand({ data: new SlashCommandBuilder() .setName("warn") .setDescription("Issue a warning to a user") .addUserOption(option => option .setName("user") .setDescription("The user to warn") .setRequired(true) ) .addStringOption(option => option .setName("reason") .setDescription("Reason for the warning") .setRequired(true) .setMaxLength(1000) ) .setDefaultMemberPermissions(PermissionFlagsBits.Administrator), execute: async (interaction) => { await interaction.deferReply({ flags: MessageFlags.Ephemeral }); try { const targetUser = interaction.options.getUser("user", true); const reason = interaction.options.getString("reason", true); // Don't allow warning bots if (targetUser.bot) { await interaction.editReply({ embeds: [getModerationErrorEmbed("You cannot warn bots.")] }); return; } // Don't allow self-warnings if (targetUser.id === interaction.user.id) { await interaction.editReply({ embeds: [getModerationErrorEmbed("You cannot warn yourself.")] }); return; } // Create the warning case const moderationCase = await ModerationService.createCase({ type: 'warn', userId: targetUser.id, username: targetUser.username, moderatorId: interaction.user.id, moderatorName: interaction.user.username, reason, }); if (!moderationCase) { await interaction.editReply({ embeds: [getModerationErrorEmbed("Failed to create warning case.")] }); return; } // Get total warning count for the user const warningCount = await ModerationService.getActiveWarningCount(targetUser.id); // Send success message to moderator await interaction.editReply({ embeds: [getWarnSuccessEmbed(moderationCase.caseId, targetUser.username, reason)] }); // Try to DM the user if configured if (config.moderation.cases.dmOnWarn) { try { const serverName = interaction.guild?.name || 'this server'; await targetUser.send({ embeds: [getUserWarningEmbed(serverName, reason, moderationCase.caseId, warningCount)] }); } catch (error) { // Silently fail if user has DMs disabled console.log(`Could not DM warning to ${targetUser.username}: ${error}`); } } // Optional: Check for auto-timeout threshold if (config.moderation.cases.autoTimeoutThreshold && warningCount >= config.moderation.cases.autoTimeoutThreshold) { try { const member = await interaction.guild?.members.fetch(targetUser.id); if (member) { // Auto-timeout for 24 hours (86400000 ms) await member.timeout(86400000, `Automatic timeout: ${warningCount} warnings`); // Create a timeout case await ModerationService.createCase({ type: 'timeout', userId: targetUser.id, username: targetUser.username, moderatorId: interaction.client.user!.id, moderatorName: interaction.client.user!.username, reason: `Automatic timeout: reached ${warningCount} warnings`, metadata: { duration: '24h', automatic: true } }); await interaction.followUp({ embeds: [getModerationErrorEmbed( `⚠️ User has reached ${warningCount} warnings and has been automatically timed out for 24 hours.` )], flags: MessageFlags.Ephemeral }); } } catch (error) { console.error('Failed to auto-timeout user:', error); } } } catch (error) { console.error("Warn command error:", error); await interaction.editReply({ embeds: [getModerationErrorEmbed("An error occurred while issuing the warning.")] }); } } });