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
JavaScript
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);