import { Client, Events, GatewayIntentBits } from "discord.js"; import { config } from "./config.js"; process.on("unhandledRejection", (reason) => { console.error("Unhandled promise rejection:", reason); }); process.on("uncaughtException", (err) => { console.error("Uncaught exception:", err); }); import { openDatabase } from "./db/db.js"; import { initializeSchema } from "./db/init.js"; import type { BotStateRow } from "./db/schema.js"; import { loadStrings, makeT } from "./i18n/strings.js"; import { TTSRegistry } from "./tts/registry.js"; import { AudioService } from "./audio/AudioService.js"; import { CommandRegistry } from "./commands/CommandRegistry.js"; import { registerModules } from "./modules/registry.js"; import { repoRoot, type BotContext } from "./context.js"; const client = new Client({ intents: [ GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildMessageReactions, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildPresences, GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.Guilds, GatewayIntentBits.MessageContent, ], }); client.on(Events.Error, (err) => console.error("Discord client error:", err)); client.on(Events.Warn, (msg) => console.warn("Discord client warning:", msg)); const db = await openDatabase(config.DB_FILE); await initializeSchema(db); const savedEngine = await db.get( "select value from BotState where key='announcement_engine'", ); const savedVoice = await db.get( "select value from BotState where key='announcement_voice'", ); const tts = new TTSRegistry( savedEngine?.value ?? config.ANNOUNCEMENT_ENGINE, savedVoice?.value ?? config.ANNOUNCEMENT_VOICE, ); const audio = new AudioService({ voiceTmpPath: config.VOICE_TMP_PATH, tts }); const commands = new CommandRegistry(config.PREFIX); const strings = loadStrings(config.STRING_SET); const ctx: BotContext = { client, config, audio, commands, tts, db, strings, t: makeT(strings), rootDir: repoRoot, }; await registerModules(ctx); client.on(Events.MessageCreate, (message) => { void commands.handleMessage(message); }); await client.login(config.TOKEN);