import { Bot, type Context } from "grammy"; import { Store } from "./state/store.js"; import { SessionManager } from "./services/session-manager.js"; import { ClaudeService } from "./services/claude.js"; import { registerCommands } from "./handlers/commands.js"; import { createMessageHandler } from "./handlers/message.js"; export function createBot(token: string, ownerId: number): Bot { const bot = new Bot(token); // Owner-only middleware bot.use(async (ctx, next) => { if (ctx.from?.id !== ownerId) return; await next(); }); const store = new Store(); const manager = new SessionManager(store); const claude = new ClaudeService(); // Register command handlers const commands: Record Promise> = {}; registerCommands(manager, claude, commands); for (const [name, handler] of Object.entries(commands)) { bot.command(name, handler); } // Callback queries for inline buttons bot.on("callback_query:data", async (ctx) => { const data = ctx.callbackQuery.data; if (data.startsWith("switch:")) { const name = data.slice("switch:".length); if (manager.switchSession(name)) { await ctx.answerCallbackQuery({ text: `Switched to "${name}"` }); await ctx.reply(`Switched to "${name}".`); } else { await ctx.answerCallbackQuery({ text: `Session "${name}" not found` }); } } else if (data.startsWith("start:")) { const name = data.slice("start:".length); const resolved = manager.resolveProjectPath(name); if (!resolved) { await ctx.answerCallbackQuery({ text: "Project not found" }); return; } if (manager.getAllSessions()[resolved.name]) { manager.switchSession(resolved.name); await ctx.answerCallbackQuery({ text: `Switched to "${resolved.name}"` }); await ctx.reply(`Session "${resolved.name}" already exists. Switched to it.`); return; } await ctx.answerCallbackQuery({ text: `Starting "${resolved.name}"...` }); await ctx.reply(`Starting session "${resolved.name}" in ${resolved.path}...`); try { const { sessionId, result } = await claude.createSession( "You are now connected via Telegram. Briefly confirm you're ready and state the project directory.", resolved.path, ); manager.createSession(resolved.name, resolved.path, sessionId); await ctx.reply(`Session "${resolved.name}" created.\n\n${result}`); } catch (err) { await ctx.reply(`Failed to create session: ${err}`); } } }); // Plain text messages bot.on("message:text", createMessageHandler(manager, claude)); return bot; }