// writebot - Telegram bot + HTTP API + Web Admin // Zero npm dependencies. Node 18+ built-in everything. const config = require("./src/config"); const { getLanIP } = require("./src/helpers"); const { startWriteServer, stopWriteServer } = require("./src/write-server"); const { createControlServer } = require("./src/admin-panel"); const { tg, allowed } = require("./src/tg-core"); const { tgPoll } = require("./src/tg-poll"); async function main() { const ip = getLanIP(); console.log(""); console.log(" \\u250C\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2510"); console.log(" \\u2502 WriteBot \\u2502"); console.log(" \\u251C\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2524"); console.log(" \\u2502 Admin: http://127.0.0.1:" + config.CONTROL_PORT + "/ \\u2502"); console.log(" \\u2502 Write: http://" + ip + ":" + config.WRITE_PORT + " \\u2502"); console.log(" \\u2514\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2518"); console.log(""); // Start HTTP control server const controlServer = createControlServer(); // Connect Telegram if (config.TG_TOKEN) { try { const me = await tg("getMe", {}); if (me.ok) { console.log("[bot] Telegram: @" + me.result.username); try { await tg("setMyCommands", { commands: [ { command: "start", description: "\\u542F\\u52A8\\u5199\\u4F5C\\u540E\\u53F0" }, { command: "new", description: "\\u5F00\\u59CB\\u5199\\u4E00\\u7BC7" }, { command: "edit", description: "\\u7F16\\u8F91\\u5DF2\\u6709\\u6587\\u7AE0" }, { command: "list", description: "\\u6587\\u7AE0\\u5217\\u8868" }, { command: "stats", description: "\\u7F51\\u7AD9\\u6570\\u636E\\u7EDF\\u8BA1" }, { command: "publish", description: "\\u53D1\\u5E03\\u5230\\u7F51\\u7AD9" }, { command: "draft", description: "\\u4FDD\\u5B58\\u4E3A\\u8349\\u7A3F" }, { command: "preview", description: "\\u9884\\u89C8\\u5168\\u6587" }, { command: "links", description: "\\u53CB\\u94FE\\u5217\\u8868" }, { command: "feeds", description: "\\u8BA2\\u9605\\u6E90\\u5217\\u8868" }, { command: "help", description: "\\u5168\\u90E8\\u547D\\u4EE4" }, ], }); console.log("[bot] commands registered"); } catch (e) { console.error("[bot] failed to register commands:", e.message); } tgPoll(); } else { console.log("[bot] TG token invalid - HTTP-only mode"); } } catch { console.log("[bot] TG connection failed - HTTP-only mode"); } } else { console.log("[bot] no TG_TOKEN - HTTP-only mode"); } // Graceful shutdown for (const sig of ["SIGINT", "SIGTERM"]) { process.on(sig, () => { console.log("\\n[bot] " + sig + ", stopping..."); stopWriteServer(); controlServer.close(); process.exit(0); }); } } main();