- TelegramService: IsChatIdAllowed() prüft Owner + Whitelist - /start von unbekannter ChatId: Zugriff verweigert + ChatId angezeigt - Owner wird bei Zugriffsanfrage benachrichtigt (Username + ChatId) - Alle Commands/Messages prüfen Whitelist vor Verarbeitung - Neues Feld telegram_allowed_chat_ids in sessions-Tabelle - Frontend: Input für erlaubte Chat-IDs in Session-Telegram-Settings - API: allowedChatIds in Save/Get durchgereicht
165 lines
6.1 KiB
C#
165 lines
6.1 KiB
C#
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 pro Session (von Telegram aufgerufen – keine Cookie-Auth!)
|
||
app.MapPost("/api/telegram/webhook/{sessionId}", HandleWebhook);
|
||
|
||
// Session Telegram-Config speichern
|
||
app.MapPut("/api/sessions/{sessionId}/telegram", HandleSaveTelegram);
|
||
|
||
// Session Telegram-Config abrufen
|
||
app.MapGet("/api/sessions/{sessionId}/telegram", HandleGetTelegram);
|
||
|
||
// Webhook registrieren (pro Session)
|
||
app.MapPost("/api/sessions/{sessionId}/telegram/register-webhook", HandleRegisterWebhook);
|
||
|
||
// Webhook-Info (pro Session)
|
||
app.MapGet("/api/sessions/{sessionId}/telegram/webhook-info", HandleWebhookInfo);
|
||
|
||
// Webhook löschen (pro Session)
|
||
app.MapDelete("/api/sessions/{sessionId}/telegram/webhook", HandleDeleteWebhook);
|
||
}
|
||
|
||
private static async Task HandleWebhook(string sessionId, HttpRequest req, HttpResponse res, TelegramService telegram, DatabaseService db)
|
||
{
|
||
var session = await db.GetSession(sessionId);
|
||
if (session == null || string.IsNullOrEmpty(session.TelegramBotToken))
|
||
{
|
||
res.StatusCode = 404;
|
||
return;
|
||
}
|
||
|
||
// Secret-Token prüfen
|
||
var secret = req.Headers["X-Telegram-Bot-Api-Secret-Token"].ToString();
|
||
if (!string.IsNullOrEmpty(session.TelegramWebhookSecret) && secret != session.TelegramWebhookSecret)
|
||
{
|
||
res.StatusCode = 403;
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
var body = await JsonSerializer.DeserializeAsync<JsonElement>(req.Body);
|
||
// Fire-and-forget – Telegram erwartet schnelle 200 OK Antwort
|
||
_ = Task.Run(async () =>
|
||
{
|
||
try { await telegram.HandleUpdate(body, session); }
|
||
catch (Exception ex) { Console.Error.WriteLine($"[Telegram] Fehler für Session {sessionId}: {ex.Message}"); }
|
||
});
|
||
}
|
||
catch
|
||
{
|
||
// Malformed JSON – ignorieren
|
||
}
|
||
|
||
res.StatusCode = 200;
|
||
}
|
||
|
||
private static async Task HandleSaveTelegram(string sessionId, HttpRequest req, HttpResponse res, DatabaseService db)
|
||
{
|
||
var userId = req.HttpContext.GetUserId();
|
||
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 body = await JsonSerializer.DeserializeAsync<JsonElement>(req.Body);
|
||
var botToken = body.TryGetProperty("botToken", out var t) ? t.GetString() : null;
|
||
var webhookSecret = body.TryGetProperty("webhookSecret", out var s) ? s.GetString() : null;
|
||
var allowedChatIds = body.TryGetProperty("allowedChatIds", out var a) ? a.GetString() : session.TelegramAllowedChatIds;
|
||
|
||
await db.UpdateSessionTelegram(sessionId, botToken, webhookSecret, session.TelegramChatId, allowedChatIds);
|
||
await res.WriteAsJsonAsync(new { ok = true });
|
||
}
|
||
|
||
private static async Task HandleGetTelegram(string sessionId, HttpRequest req, HttpResponse res, DatabaseService db)
|
||
{
|
||
var userId = req.HttpContext.GetUserId();
|
||
var session = await db.GetSession(sessionId);
|
||
if (session == null || session.UserId != userId)
|
||
{
|
||
res.StatusCode = 404;
|
||
await res.WriteAsJsonAsync(new { error = "Session nicht gefunden" });
|
||
return;
|
||
}
|
||
|
||
await res.WriteAsJsonAsync(new
|
||
{
|
||
botToken = session.TelegramBotToken ?? "",
|
||
webhookSecret = session.TelegramWebhookSecret ?? "",
|
||
chatId = session.TelegramChatId ?? "",
|
||
allowedChatIds = session.TelegramAllowedChatIds ?? "",
|
||
configured = !string.IsNullOrEmpty(session.TelegramBotToken)
|
||
});
|
||
}
|
||
|
||
private static async Task HandleRegisterWebhook(string sessionId, HttpRequest req, HttpResponse res, DatabaseService db, TelegramService telegram)
|
||
{
|
||
var userId = req.HttpContext.GetUserId();
|
||
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 body = await JsonSerializer.DeserializeAsync<JsonElement>(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(), sessionId);
|
||
res.ContentType = "application/json";
|
||
await res.WriteAsync(result);
|
||
}
|
||
|
||
private static async Task HandleWebhookInfo(string sessionId, HttpRequest req, HttpResponse res, DatabaseService db, TelegramService telegram)
|
||
{
|
||
var userId = req.HttpContext.GetUserId();
|
||
var session = await db.GetSession(sessionId);
|
||
if (session == null || session.UserId != userId)
|
||
{
|
||
res.StatusCode = 404;
|
||
return;
|
||
}
|
||
|
||
var result = await telegram.GetWebhookInfo(sessionId);
|
||
res.ContentType = "application/json";
|
||
await res.WriteAsync(result);
|
||
}
|
||
|
||
private static async Task HandleDeleteWebhook(string sessionId, HttpRequest req, HttpResponse res, DatabaseService db, TelegramService telegram)
|
||
{
|
||
var userId = req.HttpContext.GetUserId();
|
||
var session = await db.GetSession(sessionId);
|
||
if (session == null || session.UserId != userId)
|
||
{
|
||
res.StatusCode = 404;
|
||
return;
|
||
}
|
||
|
||
var result = await telegram.DeleteWebhook(sessionId);
|
||
res.ContentType = "application/json";
|
||
await res.WriteAsync(result);
|
||
}
|
||
}
|