const { PermissionFlagsBits, ApplicationCommandOptionType } = require('discord.js') const modLog = require('../modLog') const { parseDuration, MAX_TIMEOUT_MS } = require('../../utils/duration') module.exports = { data: { name: 'mute', description: 'Timeout a member for a duration (e.g. 10m, 2h, 1d).', default_member_permissions: PermissionFlagsBits.ModerateMembers.toString(), options: [ { name: 'user', description: 'Member to mute', type: ApplicationCommandOptionType.User, required: true }, { name: 'duration', description: 'e.g. 30s, 10m, 2h, 1d (max 28d)', type: ApplicationCommandOptionType.String, required: true }, { name: 'reason', description: 'Reason for the mute', type: ApplicationCommandOptionType.String, required: true }, ], }, async execute(interaction) { const user = interaction.options.getUser('user', true) const durationInput = interaction.options.getString('duration', true) const reason = interaction.options.getString('reason', true) if (user.id === interaction.user.id) { await interaction.reply({ content: "You can't mute yourself.", ephemeral: true }) return } const ms = parseDuration(durationInput) if (!ms) { await interaction.reply({ content: 'Invalid duration — use a number plus s/m/h/d, e.g. `10m`, `2h`, `1d`.', ephemeral: true }) return } const clampedMs = Math.min(ms, MAX_TIMEOUT_MS) const member = interaction.guild.members.cache.get(user.id) if (!member) { await interaction.reply({ content: 'That user is not a member of this server.', ephemeral: true }) return } if (!member.moderatable) { await interaction.reply({ content: "I don't have permission to timeout that member (role hierarchy).", ephemeral: true }) return } await member.timeout(clampedMs, reason) const durationSeconds = Math.round(clampedMs / 1000) await modLog.record({ client: interaction.client, guildId: interaction.guildId, actionType: 'mute', target: user, staffUser: interaction.user, reason, durationSeconds }) await interaction.reply({ content: `Muted ${user.tag} for ${durationInput}.`, ephemeral: true }) }, }