feat: add bot setup with owner middleware, commands, callbacks
This commit is contained in:
+74
@@ -0,0 +1,74 @@
|
||||
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<string, (ctx: Context) => Promise<void>> = {};
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user