// Runs once at process start, before the internal Express server is // considered ready. Fetches current config from the main site (token, // guildId, enabled) and reconnects immediately if enabled — so a bot // container restart (crash, `docker compose restart`, host reboot) self-heals // without any admin-panel interaction. Node 20's built-in fetch is used; no // extra HTTP client dependency needed for a single startup call. const discordManager = require('./discord/discordManager') const createLogger = require('./utils/logger') const log = createLogger('bootstrap') async function bootstrap() { const siteUrl = process.env.SITE_INTERNAL_URL const key = process.env.BOT_INTERNAL_KEY if (!siteUrl || !key) { log.warn('SITE_INTERNAL_URL or BOT_INTERNAL_KEY not set — skipping boot-time config fetch, staying disconnected until the admin panel pushes config') return } try { const res = await fetch(siteUrl, { headers: { 'X-Internal-Key': key } }) if (!res.ok) { log.error('boot-time config fetch failed', { status: res.status }) return } const config = await res.json() if (config.enabled) { log.info('boot-time config says enabled — reconnecting', { guildId: config.guildId }) await discordManager.start({ token: config.token, guildId: config.guildId }) } else { log.info('boot-time config says disabled — staying disconnected') } } catch (err) { log.error('boot-time config fetch errored', { message: err.message }) } } module.exports = bootstrap