AeThex-Bot-Master/aethex-bot/commands/announce.js
sirpiglr 7ca85f433a Add persistent storage for federation mappings and tickets
Integrates Supabase for persistent storage of federation mappings and active tickets, along with adding new commands for announcements, audit logs, and polls.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: aed2e46d-25bb-4b73-81a1-bb9e8437c261
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Event-Id: 110a0afc-77c3-48ac-afca-8e969438dafc
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3bdfff67-975a-46ad-9845-fbb6b4a4c4b5/aed2e46d-25bb-4b73-81a1-bb9e8437c261/hHBt1No
Replit-Helium-Checkpoint-Created: true
2025-12-08 03:38:13 +00:00

111 lines
3.7 KiB
JavaScript

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] });
},
};