index.ts
· 2.6 KiB · TypeScript
原始文件
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<void> {
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<void> {
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<void> {
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);
| 1 | import { Client, GatewayIntentBits, REST, Routes } from "discord.js"; |
| 2 | import { loadConfig, cfg } from "@systems/config"; |
| 3 | import { loadMessages } from "@systems/messages"; |
| 4 | import { loadEmojis } from "@systems/emojis"; |
| 5 | import { loadCharacters } from "@systems/characters"; |
| 6 | import { loadWRank } from "@systems/wrank"; |
| 7 | import { scheduleSlots } from "@systems/slots"; |
| 8 | import { postPoll, polls, lockPoll, updatePollMessage } from "@systems/poll"; |
| 9 | import { handleInteraction } from "@handlers/interactions"; |
| 10 | import { buildTgCommand } from "@commands/tg"; |
| 11 | import { buildTgConfigCommand } from "@commands/tgConfig"; |
| 12 | import cron from "node-cron"; // npm i node-cron @types/node-cron |
| 13 | import { TGSlot } from "@src/types"; |
| 14 | |
| 15 | const TOKEN = process.env.DISCORD_TOKEN!; |
| 16 | const CLIENT_ID = process.env.CLIENT_ID!; |
| 17 | const GUILD_ID = process.env.GUILD_ID!; |
| 18 | |
| 19 | const client = new Client({ |
| 20 | intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers], |
| 21 | }); |
| 22 | |
| 23 | async function registerCommands(): Promise<void> { |
| 24 | const rest = new REST({ version: "10" }).setToken(TOKEN); |
| 25 | await rest.put(Routes.applicationGuildCommands(CLIENT_ID, GUILD_ID), { |
| 26 | body: [buildTgCommand().toJSON(), buildTgConfigCommand().toJSON()], |
| 27 | }); |
| 28 | console.log("Slash commands registered."); |
| 29 | } |
| 30 | |
| 31 | async function onPollOpen(slot: TGSlot): Promise<void> { |
| 32 | const channelId = cfg("pollChannelId"); |
| 33 | const channel = await client.channels.fetch(channelId) as any; |
| 34 | if (!channel) return console.error("Poll channel not found."); |
| 35 | await postPoll(channel, slot); |
| 36 | } |
| 37 | |
| 38 | async function onPollClose(slot: TGSlot): Promise<void> { |
| 39 | const state = polls.get(slot.tgHour); |
| 40 | if (!state) return; |
| 41 | state.locked = true; |
| 42 | const channelId = cfg("pollChannelId"); |
| 43 | const channel = await client.channels.fetch(channelId) as any; |
| 44 | if (!channel) return; |
| 45 | const { updatePollMessage } = require("@systems/poll"); |
| 46 | await updatePollMessage(channel, slot.tgHour); |
| 47 | console.log(`[${new Date().toISOString()}] Poll closed for ${slot.tgHour}:00.`); |
| 48 | } |
| 49 | |
| 50 | client.on("interactionCreate", handleInteraction); |
| 51 | |
| 52 | client.once("clientReady", async () => { |
| 53 | console.log(`Logged in as ${client.user!.tag}`); |
| 54 | |
| 55 | // Load all data |
| 56 | loadConfig(); |
| 57 | loadMessages(); |
| 58 | loadEmojis(); |
| 59 | loadCharacters(); |
| 60 | loadWRank(); |
| 61 | |
| 62 | // Warm member cache |
| 63 | const guild = await client.guilds.fetch(GUILD_ID); |
| 64 | await guild.members.fetch(); |
| 65 | console.log(`Member cache warmed: ${guild.members.cache.size} members`); |
| 66 | |
| 67 | // Register commands if --register flag passed |
| 68 | if (process.argv.includes("--register")) { |
| 69 | await registerCommands(); |
| 70 | } |
| 71 | |
| 72 | // Schedule slots |
| 73 | scheduleSlots(client, onPollOpen, onPollClose); |
| 74 | |
| 75 | console.log("Bot ready."); |
| 76 | }); |
| 77 | |
| 78 | client.login(TOKEN); |
| 79 |