- Move core agent engine to packages/core/ - Add packages/types/ for shared TypeScript types - Add packages/utils/ for utility functions - Add apps/cli/ for command-line interface - Add apps/gateway/ for NestJS WebSocket gateway - Add apps/server/ for REST API server - Restructure desktop app (electron/ → src/main/, src/preload/) - Update pnpm workspace configuration - Remove legacy src/ directory Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
67 lines
2 KiB
TypeScript
67 lines
2 KiB
TypeScript
/**
|
|
* Telegram webhook controller.
|
|
*
|
|
* Receives webhook requests from Telegram Bot API.
|
|
*/
|
|
|
|
import { Controller, Inject, Logger, Post, Req, Res, Headers } from "@nestjs/common";
|
|
import { TelegramService } from "./telegram.service.js";
|
|
|
|
// Minimal Express types for webhook handling
|
|
interface ExpressRequest {
|
|
body: unknown;
|
|
header: (name: string) => string | undefined;
|
|
}
|
|
|
|
interface ExpressResponse {
|
|
status: (code: number) => ExpressResponse;
|
|
json: (data: unknown) => void;
|
|
headersSent: boolean;
|
|
}
|
|
|
|
@Controller("telegram")
|
|
export class TelegramController {
|
|
private readonly logger = new Logger(TelegramController.name);
|
|
|
|
constructor(@Inject(TelegramService) private readonly telegramService: TelegramService) {}
|
|
|
|
@Post("webhook")
|
|
async handleWebhook(
|
|
@Req() req: ExpressRequest,
|
|
@Res() res: ExpressResponse,
|
|
@Headers("x-telegram-bot-api-secret-token") secretToken?: string
|
|
): Promise<void> {
|
|
// Check if Telegram is configured
|
|
if (!this.telegramService.isConfigured()) {
|
|
this.logger.warn("Telegram webhook called but bot not configured");
|
|
res.status(503).json({ error: "Telegram not configured" });
|
|
return;
|
|
}
|
|
|
|
// Validate secret token if configured
|
|
const expectedToken = process.env["TELEGRAM_WEBHOOK_SECRET_TOKEN"];
|
|
if (expectedToken && secretToken !== expectedToken) {
|
|
this.logger.warn("Invalid Telegram webhook secret token");
|
|
res.status(401).json({ error: "Unauthorized" });
|
|
return;
|
|
}
|
|
|
|
// Get grammY webhook callback
|
|
const callback = this.telegramService.getWebhookCallback();
|
|
if (!callback) {
|
|
res.status(503).json({ error: "Telegram not configured" });
|
|
return;
|
|
}
|
|
|
|
// Let grammY handle the request
|
|
try {
|
|
await callback(req, res);
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : String(error);
|
|
this.logger.error(`Telegram webhook error: ${message}`);
|
|
if (!res.headersSent) {
|
|
res.status(500).json({ error: "Internal server error" });
|
|
}
|
|
}
|
|
}
|
|
}
|