Kord/apps/bot/src/services/PresenceService.ts

82 lines
2.6 KiB
TypeScript

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.');
}
}
}