130 lines
4.9 KiB
JavaScript
130 lines
4.9 KiB
JavaScript
const { ActivityType } = require('discord.js');
|
|
const deployCommands = require('../deploy-commands');
|
|
const api = require('../api');
|
|
|
|
module.exports = {
|
|
name: 'clientReady',
|
|
once: true,
|
|
async execute(client) {
|
|
const guildIds = client.guilds.cache.map(guild => guild.id);
|
|
if (guildIds.length > 0) {
|
|
// Deploy commands for all guilds in parallel, but only log a single summary
|
|
try {
|
|
await Promise.all(guildIds.map(id => deployCommands(id)));
|
|
console.log(`🔁 Refreshed application commands for ${guildIds.length} guild(s)`);
|
|
} catch (e) {
|
|
console.error('Error refreshing application commands:', e && e.message ? e.message : e);
|
|
}
|
|
}
|
|
|
|
// Reconcile invites for all guilds to detect invites deleted while bot was offline
|
|
console.log('🔄 Reconciling invites for offline changes...');
|
|
let totalReconciled = 0;
|
|
for (const guildId of guildIds) {
|
|
try {
|
|
const guild = client.guilds.cache.get(guildId);
|
|
if (!guild) continue;
|
|
|
|
// Fetch current invites from Discord
|
|
const discordInvites = await guild.invites.fetch();
|
|
const currentInvites = Array.from(discordInvites.values());
|
|
|
|
// Reconcile with database
|
|
const reconciled = await api.reconcileInvites(guildId, currentInvites);
|
|
totalReconciled += reconciled;
|
|
} catch (e) {
|
|
console.error(`Failed to reconcile invites for guild ${guildId}:`, e && e.message ? e.message : e);
|
|
}
|
|
}
|
|
if (totalReconciled > 0) {
|
|
console.log(`✅ Invite reconciliation complete: removed ${totalReconciled} stale invites`);
|
|
} else {
|
|
console.log('✅ Invite reconciliation complete: no stale invites found');
|
|
}
|
|
|
|
// Reconcile reaction roles: ensure stored message IDs still exist, remove stale configs
|
|
console.log('🔄 Reconciling reaction roles (initial check)...');
|
|
try {
|
|
for (const guildId of guildIds) {
|
|
try {
|
|
const rrList = await api.listReactionRoles(guildId) || [];
|
|
for (const rr of rrList) {
|
|
if (!rr.message_id) continue; // not posted yet
|
|
try {
|
|
const guild = client.guilds.cache.get(guildId);
|
|
if (!guild) continue;
|
|
const channel = await guild.channels.fetch(rr.channel_id || rr.channelId).catch(() => null);
|
|
if (!channel) {
|
|
// channel missing -> delete RR
|
|
await api.deleteReactionRole(guildId, rr.id);
|
|
continue;
|
|
}
|
|
const msg = await channel.messages.fetch(rr.message_id).catch(() => null);
|
|
if (!msg) {
|
|
// message missing -> delete RR
|
|
await api.deleteReactionRole(guildId, rr.id);
|
|
continue;
|
|
}
|
|
} catch (inner) {
|
|
// ignore per-item errors
|
|
}
|
|
}
|
|
} catch (e) {
|
|
// ignore guild-level errors
|
|
}
|
|
}
|
|
console.log('✅ Reaction role initial reconciliation complete');
|
|
} catch (e) {
|
|
console.error('Failed reaction role reconciliation:', e && e.message ? e.message : e);
|
|
}
|
|
|
|
// Periodic reconciliation every 10 minutes
|
|
setInterval(async () => {
|
|
try {
|
|
for (const guildId of client.guilds.cache.map(g => g.id)) {
|
|
const rrList = await api.listReactionRoles(guildId) || [];
|
|
for (const rr of rrList) {
|
|
if (!rr.message_id) continue;
|
|
try {
|
|
const guild = client.guilds.cache.get(guildId);
|
|
if (!guild) continue;
|
|
const channel = await guild.channels.fetch(rr.channel_id || rr.channelId).catch(() => null);
|
|
if (!channel) {
|
|
await api.deleteReactionRole(guildId, rr.id);
|
|
continue;
|
|
}
|
|
const msg = await channel.messages.fetch(rr.message_id).catch(() => null);
|
|
if (!msg) {
|
|
await api.deleteReactionRole(guildId, rr.id);
|
|
continue;
|
|
}
|
|
} catch (e) {
|
|
// ignore
|
|
}
|
|
}
|
|
}
|
|
} catch (e) {
|
|
// ignore
|
|
}
|
|
}, 10 * 60 * 1000);
|
|
|
|
const activities = [
|
|
{ name: 'Watch EhChad Live!', type: ActivityType.Streaming, url: 'https://twitch.tv/ehchad' },
|
|
{ name: 'Follow EhChad!', type: ActivityType.Streaming, url: 'https://twitch.tv/ehchad' },
|
|
{ name: '/help', type: ActivityType.Streaming, url: 'https://twitch.tv/ehchad' },
|
|
{ name: 'EhChadServices', type: ActivityType.Streaming, url: 'https://twitch.tv/ehchad' },
|
|
];
|
|
|
|
let activityIndex = 0;
|
|
|
|
setInterval(() => {
|
|
const activity = activities[activityIndex];
|
|
client.user.setActivity(activity.name, { type: activity.type, url: activity.url });
|
|
activityIndex = (activityIndex + 1) % activities.length;
|
|
}, 3000);
|
|
|
|
// Signal that startup is complete
|
|
console.log('✅ ECS - Full Stack Bot Online!');
|
|
},
|
|
};
|