UNPKG

discord-live-bot-status-advanced

Version:

Advanced real-time Discord bot status tracker with embed dashboard and pagination

197 lines (169 loc) 5.65 kB
const { Client, GatewayIntentBits, Partials, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, Events, REST, Routes, SlashCommandBuilder, } = require('discord.js'); class LiveBotStatus { constructor(config) { this.token = config.token; this.channelId = config.channelId; this.botsPerPage = 1; // Only one bot (self) this.statusMessage = null; this.trackedBots = new Map(); this.currentPage = 0; this.updateInterval = 15000; this.client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildPresences, ], partials: [Partials.Channel, Partials.GuildMember, Partials.User], }); this._registerEvents(); this._login(); } _registerEvents() { this.client.once(Events.ClientReady, async () => { console.log(`[LiveBotStatus] Logged in as ${this.client.user.tag}`); // Track self only this.trackedBots.set(this.client.user.id, { id: this.client.user.id, name: this.client.user.username, avatar: this.client.user.displayAvatarURL(), status: 'offline', guilds: 0, users: 0, ping: 0, uptime: 0, commands: 0, lastUpdate: new Date().toISOString(), }); await this._startTracking(); await this._registerCommands(); }); this.client.on(Events.InteractionCreate, async (interaction) => { if (interaction.isChatInputCommand()) { if (interaction.commandName === 'refreshbotstatus') { await this._updateAllBots(); await interaction.reply({ content: 'Bot status refreshed!', ephemeral: true }); } } }); } async _login() { await this.client.login(this.token); } async _registerCommands() { try { const rest = new REST({ version: '10' }).setToken(this.token); const commands = [ new SlashCommandBuilder() .setName('refreshbotstatus') .setDescription('Manually refresh the live bot status dashboard'), ].map((cmd) => cmd.toJSON()); await rest.put(Routes.applicationCommands(this.client.user.id), { body: commands }); console.log('[LiveBotStatus] Registered slash commands'); } catch (err) { console.error('Error registering slash commands:', err); } } async _fetchBotStats(botId) { const bot = this.trackedBots.get(botId); if (!bot) return; try { const presence = this.client.presence || this.client.user.presence || { status: 'offline' }; bot.status = presence.status || 'offline'; bot.guilds = this.client.guilds.cache.size; bot.users = this.client.guilds.cache.reduce((acc, g) => acc + g.memberCount, 0); bot.ping = this.client.ws.ping; bot.uptime = this.client.uptime; bot.lastUpdate = new Date().toISOString(); bot.commands = 0; // Update if you implement command tracking } catch (err) { console.error(`[LiveBotStatus] Error fetching stats:`, err); } } _formatUptime(ms) { if (!ms) return 'N/A'; const seconds = Math.floor(ms / 1000) % 60; const minutes = Math.floor(ms / (1000 * 60)) % 60; const hours = Math.floor(ms / (1000 * 60 * 60)) % 24; const days = Math.floor(ms / (1000 * 60 * 60 * 24)); return `${days}d ${hours}h ${minutes}m ${seconds}s`; } _getStatusEmoji(status) { return { online: '🟢', idle: '🟡', dnd: '🔴', offline: '⚫', }[status] || '⚪'; } _createEmbed() { const embed = new EmbedBuilder() .setTitle('🤖 Live Bot Status Dashboard') .setColor('#00ff00') .setTimestamp() .setFooter({ text: `Bot Status` }); const bot = Array.from(this.trackedBots.values())[0]; if (!bot) { embed.setDescription('Bot status not initialized.'); return embed; } embed.addFields({ name: `${this._getStatusEmoji(bot.status)} ${bot.name}`, value: [ `**Status:** ${bot.status}`, `**Servers:** ${bot.guilds.toLocaleString()}`, `**Users:** ${bot.users.toLocaleString()}`, `**Ping:** ${bot.ping}ms`, `**Uptime:** ${this._formatUptime(bot.uptime)}`, `**Commands:** ${bot.commands}`, `**Last Updated:** ${new Date(bot.lastUpdate).toLocaleString()}`, ].join('\n'), }); return embed; } async _updateEmbed() { const channel = await this.client.channels.fetch(this.channelId).catch(() => null); if (!channel) { console.warn('[LiveBotStatus] Channel not found'); return; } const embed = this._createEmbed(); if (this.statusMessage) { try { await this.statusMessage.edit({ embeds: [embed] }); } catch { this.statusMessage = null; } } if (!this.statusMessage) { this.statusMessage = await channel.send({ embeds: [embed] }); } } async _updateAllBots() { const botId = this.client.user.id; await this._fetchBotStats(botId); await this._updateEmbed(); } async _startTracking() { await this._updateAllBots(); this.updateIntervalId = setInterval(() => this._updateAllBots(), this.updateInterval); } async shutdown() { clearInterval(this.updateIntervalId); await this.client.destroy(); console.log('[LiveBotStatus] Shutdown complete'); } } module.exports = (config) => new LiveBotStatus(config);