import fs from 'fs'; import path from 'path'; import { Client } from 'discord.js'; import { EventHandler } from '../utils/types'; import { logger } from '../utils/logger'; import { context } from '../config/context'; export class EventHandlerService { constructor(private client: Client) {} public async loadEvents() { const eventsPath = path.join(process.cwd(), 'src', 'events'); const files = this.walk(eventsPath); for (const file of files) { const mod = await import(file); const event: EventHandler = mod.default; if (!event?.name || !event.execute) continue; if (event.once) { this.client.once(event.name, (...args) => { this.track(event.name, args); event.execute(...args); }); } else { this.client.on(event.name, (...args) => { this.track(event.name, args); event.execute(...args); }); } logger.info(`Bound event ${event.name}`); } } private walk(dir: string): string[] { const entries = fs.readdirSync(dir, { withFileTypes: true }); const files: string[] = []; for (const entry of entries) { const res = path.resolve(dir, entry.name); if (entry.isDirectory()) files.push(...this.walk(res)); else if (entry.isFile() && (entry.name.endsWith('.ts') || entry.name.endsWith('.js'))) files.push(res); } return files; } private track(name: string, args: any[]) { try { const guildId = (args[0]?.guild?.id as string | undefined) || (args[0]?.guildId as string | undefined) || (args[0]?.message?.guildId as string | undefined); context.admin.trackEvent(name, guildId); } catch { /* ignore */ } } }