const { PermissionFlagsBits, ApplicationCommandOptionType, ChannelType } = require('discord.js') const guildConfig = require('../../model/guildConfig') const inviteLog = require('../../model/inviteLog') const inviteRotator = require('../../invites/inviteRotator') // Per-subcommand handlers, split out of execute() so the dispatch stays flat. async function handleChannel(interaction) { const channel = interaction.options.getChannel('channel') if (!channel) { const currentId = await guildConfig.getInviteChannelId(interaction.guildId) const content = currentId ? `Invites are created in <#${currentId}>.` : 'No invite channel is set yet.' await interaction.reply({ content, ephemeral: true }) return } await guildConfig.setInviteChannelId(interaction.guildId, channel.id) await interaction.reply({ content: `Invite channel set to ${channel}.`, ephemeral: true }) } async function handleRotate(interaction) { await interaction.deferReply({ ephemeral: true }) try { const invite = await inviteRotator.rotate(interaction.client, interaction.guildId, { triggeredBy: interaction.user.id, triggeredByTag: interaction.user.tag, }) await interaction.editReply({ content: `New invite: https://discord.gg/${invite.code}` }) } catch (err) { await interaction.editReply({ content: `Couldn't rotate the invite: ${err.message}` }) } } async function handleLog(interaction) { const rows = await inviteLog.list(interaction.guildId, 10) if (rows.length === 0) { await interaction.reply({ content: 'No invite rotations logged yet.', ephemeral: true }) return } const lines = rows.map((r) => { const who = r.triggered_by_tag || 'automatic (scheduled)' const status = r.revoked_at ? `revoked ${new Date(r.revoked_at).toLocaleString()}` : 'active' return `\`${r.invite_code}\` — by ${who} on ${new Date(r.created_at).toLocaleString()} (${status})` }) await interaction.reply({ content: lines.join('\n'), ephemeral: true }) } module.exports = { data: { name: 'invite', description: 'Manage the auto-rotating primary server invite.', default_member_permissions: PermissionFlagsBits.ManageGuild.toString(), options: [ { name: 'channel', description: 'View or set the channel new invites are created in.', type: ApplicationCommandOptionType.Subcommand, options: [ { name: 'channel', description: 'Channel to create invites in. Omit to view the current setting.', type: ApplicationCommandOptionType.Channel, channel_types: [ChannelType.GuildText], required: false, }, ], }, { name: 'rotate', description: 'Revoke the current invite and generate a new one now.', type: ApplicationCommandOptionType.Subcommand, options: [], }, { name: 'log', description: 'Show recent invite rotation history.', type: ApplicationCommandOptionType.Subcommand, options: [], }, ], }, async execute(interaction) { const sub = interaction.options.getSubcommand() if (sub === 'channel') return handleChannel(interaction) if (sub === 'rotate') return handleRotate(interaction) if (sub === 'log') return handleLog(interaction) }, }