import { Client, GatewayIntentBits, REST, Routes } from "discord.js"; import { loadConfig, cfg } from "@systems/config"; import { loadMessages } from "@systems/messages"; import { loadEmojis } from "@systems/emojis"; import { loadCharacters } from "@systems/characters"; import { loadWRank } from "@systems/wrank"; import { scheduleSlots } from "@systems/slots"; import { postPoll, polls, lockPoll, updatePollMessage } from "@systems/poll"; import { handleInteraction } from "@handlers/interactions"; import { buildTgCommand } from "@commands/tg"; import { buildTgConfigCommand } from "@commands/tgConfig"; import cron from "node-cron"; // npm i node-cron @types/node-cron import { TGSlot } from "@src/types"; const TOKEN = process.env.DISCORD_TOKEN!; const CLIENT_ID = process.env.CLIENT_ID!; const GUILD_ID = process.env.GUILD_ID!; const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers], }); async function registerCommands(): Promise { const rest = new REST({ version: "10" }).setToken(TOKEN); await rest.put(Routes.applicationGuildCommands(CLIENT_ID, GUILD_ID), { body: [buildTgCommand().toJSON(), buildTgConfigCommand().toJSON()], }); console.log("Slash commands registered."); } async function onPollOpen(slot: TGSlot): Promise { const channelId = cfg("pollChannelId"); const channel = await client.channels.fetch(channelId) as any; if (!channel) return console.error("Poll channel not found."); await postPoll(channel, slot); } async function onPollClose(slot: TGSlot): Promise { const state = polls.get(slot.tgHour); if (!state) return; state.locked = true; const channelId = cfg("pollChannelId"); const channel = await client.channels.fetch(channelId) as any; if (!channel) return; const { updatePollMessage } = require("@systems/poll"); await updatePollMessage(channel, slot.tgHour); console.log(`[${new Date().toISOString()}] Poll closed for ${slot.tgHour}:00.`); } client.on("interactionCreate", handleInteraction); client.once("clientReady", async () => { console.log(`Logged in as ${client.user!.tag}`); // Load all data loadConfig(); loadMessages(); loadEmojis(); loadCharacters(); loadWRank(); // Warm member cache const guild = await client.guilds.fetch(GUILD_ID); await guild.members.fetch(); console.log(`Member cache warmed: ${guild.members.cache.size} members`); // Register commands if --register flag passed if (process.argv.includes("--register")) { await registerCommands(); } // Schedule slots scheduleSlots(client, onPollOpen, onPollClose); console.log("Bot ready."); }); client.login(TOKEN);