tg-bot-ts/src/systems/slots.ts

68 lines
No EOL
2.3 KiB
TypeScript

import cron from "node-cron";
import { Client, TextChannel } from "discord.js";
import { cfg } from "./config";
import { TGSlot } from "../types";
import { polls, updatePollMessage } from "@systems/poll";
type PollCallback = (slot: TGSlot) => Promise<void>;
type CloseCallback = (slot: TGSlot) => Promise<void>;
type LockCallback = (slot: TGSlot) => Promise<void>;
let _scheduledTasks: cron.ScheduledTask[] = [];
export function scheduleSlots(
client: Client,
onPollOpen: PollCallback,
onPollLock: LockCallback,
onPollClose: CloseCallback,
): void {
_scheduledTasks.forEach((t) => t.stop());
_scheduledTasks = [];
const tz = process.env.TZ ?? "Etc/GMT-2";
const slots = cfg("slots").filter((s) => s.active);
for (const slot of slots) {
// Poll open
const [openHour, openMin] = slot.pollOpens.split(":").map(Number);
_scheduledTasks.push(cron.schedule(
`${openMin} ${openHour} * * *`,
() => onPollOpen(slot),
{ timezone: tz }
));
// Poll lock — exactly at tgHour (TG start, voting closes, lockedYesKeys snapshotted)
_scheduledTasks.push(cron.schedule(
`0 ${slot.tgHour} * * *`,
() => onPollLock(slot),
{ timezone: tz }
));
// Poll close — tgHour + closesAfter minutes (TG end, Submit Score button appears)
const closeMinTotal = slot.tgHour * 60 + slot.closesAfter;
const closeHour = Math.floor(closeMinTotal / 60) % 24;
const closeMin = closeMinTotal % 60;
_scheduledTasks.push(cron.schedule(
`${closeMin} ${closeHour} * * *`,
() => onPollClose(slot),
{ timezone: tz }
));
_scheduledTasks.push(cron.schedule("0 0 * * *", async () => {
const state = polls.get(slot.tgHour);
if (!state?.locked) return; // only if poll has been locked (TG happened)
const channel = await (client as any).channels.fetch(cfg("pollChannelId")) as TextChannel;
await updatePollMessage(channel, slot.tgHour, undefined, false);
console.log(`[${new Date().toISOString()}] Submit Score button removed.`);
}, { timezone: tz }));
}
// Weekly reset — Monday 00:00
_scheduledTasks.push(cron.schedule("0 0 * * 1", () => {
const { resetWeek } = require("./wrank");
resetWeek();
console.log("W.Rank weekly reset complete.");
}, { timezone: tz }));
console.log(`Scheduled ${slots.length} slot(s).`);
}