import { ActivityType, Client } from 'discord.js'; import { logger } from '../utils/logger'; import { t, SupportedLocale, SUPPORTED_LOCALES } from '../i18n'; /** * Service for managing the bot's Discord presence (status message). * Rotates through multiple status messages and locales every 5 minutes. */ export class PresenceService { private static rotationInterval: NodeJS.Timeout | null = null; private static currentIndex = 0; private static currentLocaleIndex = 0; /** * The list of presence translation keys. */ private static readonly PRESENCE_KEYS = [ { key: 'presence.servers', type: ActivityType.Watching }, { key: 'presence.help', type: ActivityType.Listening }, { key: 'presence.managing', type: ActivityType.Playing }, { key: 'presence.version', type: ActivityType.Competing }, ]; /** * Starts the presence rotation cycle. * @param client The Discord client instance. */ public static startActivePresence(client: Client) { if (this.rotationInterval) { clearInterval(this.rotationInterval); } // Set initial presence this.updatePresence(client); // Set rotation timer (5 minutes) this.rotationInterval = setInterval(() => { // Rotate message index this.currentIndex = (this.currentIndex + 1) % this.PRESENCE_KEYS.length; // Rotate locale index to provide multi-language visibility this.currentLocaleIndex = (this.currentLocaleIndex + 1) % SUPPORTED_LOCALES.length; this.updatePresence(client); }, 5 * 60 * 1000); logger.info('PresenceService: Status rotation started (5m interval with i18n).'); } /** * Instantly updates the bot's presence using the current rotation state. * @param client The Discord client instance. */ public static updatePresence(client: Client) { if (!client.user) return; try { const item = this.PRESENCE_KEYS[this.currentIndex]; const locale = SUPPORTED_LOCALES[this.currentLocaleIndex]; const guildCount = client.guilds.cache.size; const statusText = t(locale, item.key, { guildCount: guildCount.toString() }); client.user.setActivity(statusText, { type: item.type }); logger.debug(`PresenceService: Updated presence [${locale}]: ${statusText} (${item.type})`); } catch (error) { logger.error('PresenceService: Failed to update presence:', error); } } /** * Stops the rotation cycle. */ public static stopRotation() { if (this.rotationInterval) { clearInterval(this.rotationInterval); this.rotationInterval = null; logger.info('PresenceService: Status rotation stopped.'); } } }