Files
no-twitter-bot/src/main.ts
Lucid Kobold fa1e07e4af First build
2025-02-19 11:11:47 -05:00

105 lines
2.3 KiB
TypeScript

#!/usr/bin/env tsx
import type { PollingConfig, WebhookConfig } from "#root/config.js";
import type { RunnerHandle } from "@grammyjs/runner";
import process from "node:process";
import { createBot } from "#root/bot/index.js";
import { config } from "#root/config.js";
import { logger } from "#root/logger.js";
import { createServer, createServerManager } from "#root/server/index.js";
import { run } from "@grammyjs/runner";
async function startPolling(config: PollingConfig) {
const bot = createBot(config.botToken, {
config,
logger
});
// eslint-disable-next-line prefer-const
let runner: undefined | RunnerHandle;
// graceful shutdown
onShutdown(async () => {
logger.info("Shutdown");
await runner?.stop();
});
await Promise.all([bot.init(), bot.api.deleteWebhook()]);
// start bot
runner = run(bot, {
runner: {
fetch: {
allowed_updates: config.botAllowedUpdates
}
}
});
logger.info({
msg: "Bot running...",
username: bot.botInfo.username
});
}
async function startWebhook(config: WebhookConfig) {
const bot = createBot(config.botToken, {
config,
logger
});
const server = createServer({
bot,
config,
logger
});
const serverManager = createServerManager(server, {
host: config.serverHost,
port: config.serverPort
});
// graceful shutdown
onShutdown(async () => {
logger.info("Shutdown");
await serverManager.stop();
});
// to prevent receiving updates before the bot is ready
await bot.init();
// start server
const info = await serverManager.start();
logger.info({
msg: "Server started",
url: info.url
});
// set webhook
await bot.api.setWebhook(config.botWebhook, {
allowed_updates: config.botAllowedUpdates,
secret_token: config.botWebhookSecret
});
logger.info({
msg: "Webhook was set",
url: config.botWebhook
});
}
try {
if (config.isWebhookMode) await startWebhook(config);
else if (config.isPollingMode) await startPolling(config);
} catch (error) {
logger.error(error);
process.exit(1);
}
// Utils
function onShutdown(cleanUp: () => Promise<void>) {
let isShuttingDown = false;
const handleShutdown = async () => {
if (isShuttingDown) return;
isShuttingDown = true;
await cleanUp();
};
process.on("SIGINT", handleShutdown);
process.on("SIGTERM", handleShutdown);
}