import { Router } from "express"; import { Bot } from "grammy"; import { assertBoard } from "./authz.js"; import { nexusSettingsService } from "../services/nexus-settings.js"; import type { TelegramService } from "../services/telegram.js"; import type { Db } from "@paperclipai/db"; export function telegramRoutes(db: Db, svc: TelegramService): Router { const router = Router(); // POST /telegram/token — validate and save bot token, restart bot router.post("/telegram/token", async (req, res) => { try { assertBoard(req); const { token } = req.body as { token?: string }; if (!token || typeof token !== "string" || token.trim() === "") { res.status(400).json({ error: "token is required" }); return; } // Validate token by calling getMe let botUsername: string; try { const tempBot = new Bot(token.trim()); const me = await tempBot.api.getMe(); botUsername = me.username ?? me.first_name; } catch { res.status(400).json({ error: "Invalid Telegram bot token" }); return; } // Save token to nexus settings await nexusSettingsService().set({ telegramToken: token.trim() }); // Stop old bot and start new one with new token await svc.stop(); svc.start(token.trim()).catch((err) => { // Log but don't fail the request — token is saved void err; }); res.json({ ok: true, botUsername }); } catch (err: unknown) { if (err && typeof err === "object" && "status" in err) { const e = err as { status: number; message: string }; res.status(e.status).json({ error: e.message }); return; } res.status(500).json({ error: "Unexpected error" }); } }); // GET /telegram/status — return running state router.get("/telegram/status", async (req, res) => { try { assertBoard(req); res.json({ running: svc.isRunning() }); } catch (err: unknown) { if (err && typeof err === "object" && "status" in err) { const e = err as { status: number; message: string }; res.status(e.status).json({ error: e.message }); return; } res.status(500).json({ error: "Unexpected error" }); } }); return router; }