using System; using System.Text.Json; using System.Threading.Tasks; using Gott.Extensions; using Gott.Services; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; namespace Gott.Endpoints; public static class TelegramEndpoint { public static void MapTelegramEndpoints(this IEndpointRouteBuilder app) { // Webhook (von Telegram aufgerufen – keine Cookie-Auth!) app.MapPost("/api/telegram/webhook", HandleWebhook); // Link-Code generieren (aus Web-UI, braucht Auth) app.MapPost("/api/telegram/link", HandleCreateLink); // Webhook registrieren (Admin) app.MapPost("/api/telegram/register-webhook", HandleRegisterWebhook); // Telegram-Status (ob konfiguriert – für Frontend) app.MapGet("/api/telegram/status", HandleStatus); // Webhook-Info (Admin) app.MapGet("/api/telegram/webhook-info", HandleWebhookInfo); } private static async Task HandleWebhook(HttpRequest req, HttpResponse res, TelegramService telegram) { if (!telegram.IsConfigured) { res.StatusCode = 404; return; } // Secret-Token prüfen var secret = req.Headers["X-Telegram-Bot-Api-Secret-Token"].ToString(); if (secret != telegram.WebhookSecret) { res.StatusCode = 403; return; } try { var body = await JsonSerializer.DeserializeAsync(req.Body); // Fire-and-forget – Telegram erwartet schnelle 200 OK Antwort _ = Task.Run(async () => { try { await telegram.HandleUpdate(body); } catch (Exception ex) { Console.Error.WriteLine($"[Telegram] Fehler: {ex.Message}"); } }); } catch { // Malformed JSON – ignorieren } res.StatusCode = 200; } private static async Task HandleCreateLink(HttpRequest req, HttpResponse res, DatabaseService db, TelegramService telegram) { if (!telegram.IsConfigured) { res.StatusCode = 400; await res.WriteAsJsonAsync(new { error = "Telegram Bot nicht konfiguriert" }); return; } var userId = req.HttpContext.GetUserId(); var body = await JsonSerializer.DeserializeAsync(req.Body); if (!body.TryGetProperty("sessionId", out var sidEl)) { res.StatusCode = 400; await res.WriteAsJsonAsync(new { error = "sessionId required" }); return; } var sessionId = sidEl.GetString(); var session = await db.GetSession(sessionId); if (session == null || session.UserId != userId) { res.StatusCode = 404; await res.WriteAsJsonAsync(new { error = "Session nicht gefunden" }); return; } var agentId = session.AgentId; var code = await db.CreateTelegramLinkCode(userId, sessionId, agentId); await res.WriteAsJsonAsync(new { code, expiresInSeconds = 300 }); } private static async Task HandleRegisterWebhook(HttpRequest req, HttpResponse res, TelegramService telegram) { if (!req.HttpContext.IsAdmin()) { res.StatusCode = 403; await res.WriteAsJsonAsync(new { error = "Admin required" }); return; } var body = await JsonSerializer.DeserializeAsync(req.Body); if (!body.TryGetProperty("baseUrl", out var urlEl)) { res.StatusCode = 400; await res.WriteAsJsonAsync(new { error = "baseUrl required" }); return; } var result = await telegram.RegisterWebhook(urlEl.GetString()); await res.WriteAsJsonAsync(new { result }); } private static async Task HandleStatus(HttpResponse res, TelegramService telegram) { await res.WriteAsJsonAsync(new { configured = telegram.IsConfigured }); } private static async Task HandleWebhookInfo(HttpRequest req, HttpResponse res, TelegramService telegram) { if (!req.HttpContext.IsAdmin()) { res.StatusCode = 403; await res.WriteAsJsonAsync(new { error = "Admin required" }); return; } var result = await telegram.GetWebhookInfo(); res.ContentType = "application/json"; await res.WriteAsync(result); } }