const { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits } = require('discord.js'); module.exports = { data: new SlashCommandBuilder() .setName('announce') .setDescription('Send an announcement to all realms') .setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .addStringOption(option => option.setName('title') .setDescription('Announcement title') .setRequired(true) .setMaxLength(256) ) .addStringOption(option => option.setName('message') .setDescription('Announcement message') .setRequired(true) .setMaxLength(2000) ) .addStringOption(option => option.setName('color') .setDescription('Embed color') .setRequired(false) .addChoices( { name: 'Purple (Default)', value: '7c3aed' }, { name: 'Green (Success)', value: '00ff00' }, { name: 'Red (Alert)', value: 'ff0000' }, { name: 'Blue (Info)', value: '3b82f6' }, { name: 'Yellow (Warning)', value: 'fbbf24' } ) ) .addBooleanOption(option => option.setName('ping') .setDescription('Ping @everyone with this announcement') .setRequired(false) ), async execute(interaction, supabase, client) { await interaction.deferReply({ ephemeral: true }); const title = interaction.options.getString('title'); const message = interaction.options.getString('message'); const color = parseInt(interaction.options.getString('color') || '7c3aed', 16); const ping = interaction.options.getBoolean('ping') || false; const embed = new EmbedBuilder() .setColor(color) .setTitle(title) .setDescription(message) .setFooter({ text: `Announced by ${interaction.user.tag}` }) .setTimestamp(); const results = []; const REALM_GUILDS = client.REALM_GUILDS; for (const [realm, guildId] of Object.entries(REALM_GUILDS)) { if (!guildId) continue; const guild = client.guilds.cache.get(guildId); if (!guild) { results.push({ realm, status: 'offline' }); continue; } try { const announcementChannel = guild.channels.cache.find( c => c.isTextBased() && !c.isThread() && !c.isVoiceBased() && (c.name.includes('announcement') || c.name.includes('general')) ); if (announcementChannel && announcementChannel.isTextBased()) { const content = ping ? '@everyone' : null; await announcementChannel.send({ content, embeds: [embed] }); results.push({ realm, status: 'sent', channel: announcementChannel.name }); } else { results.push({ realm, status: 'no_channel' }); } } catch (error) { console.error(`Announce error for ${realm}:`, error); results.push({ realm, status: 'error', error: error.message }); } } if (supabase) { try { await supabase.from('audit_logs').insert({ action: 'announce', user_id: interaction.user.id, username: interaction.user.tag, guild_id: interaction.guildId, details: { title, message, results }, }); } catch (e) { console.warn('Failed to log announcement:', e.message); } } const resultText = results.map(r => { const emoji = r.status === 'sent' ? '✅' : r.status === 'offline' ? '⚫' : '❌'; return `${emoji} **${r.realm}**: ${r.status}${r.channel ? ` (#${r.channel})` : ''}`; }).join('\n'); const resultEmbed = new EmbedBuilder() .setColor(0x7c3aed) .setTitle('Announcement Results') .setDescription(resultText || 'No realms configured') .setTimestamp(); await interaction.editReply({ embeds: [resultEmbed] }); }, };