Telegram Bots als eigenständige Entität mit eigener Page
- Neue Tabelle 'telegram_bots' (bot_id, name, bot_token, webhook_secret, is_public)
- Automatische Migration bestehender Session-Telegram-Configs in telegram_bots
- Sessions verweisen via telegram_bot_id auf Bot (mehrere Sessions pro Bot möglich)
- Webhook-URL: /api/telegram/webhook/{botId} statt {sessionId}
- Eigene Telegram-Bot-Page (wie Agent/Cronjob/Session) statt Modal
- Bot-Page: Name, Token, Secret, Webhook-Verwaltung (registrieren/status/entfernen), Löschen
- Dashboard: Telegram Bots Section mit Cards (Name, maskierter Token, Session-Count)
- Session-Page: Bot-Picker (wie Agent-Picker) statt Token-Input, Chat-ID readonly + Unlink-Button
- Public-Flag: Bot kann von anderen Usern in ihren Sessions ausgewählt werden
- Vereinfacht: 1 Session = max. 1 Telegram Chat, allowed_chat_ids entfällt
- /start zeigt Chat-ID an, /unlink entfernt (Unlink nur über Web-UI)
- Nachrichten-Routing: Bot + Chat-ID → Session Lookup
This commit is contained in:
1 parent
3b7bdb7a20
commit
ec73ccd71e
13 files changed
+907
-371
No files matched your search
+159
-17
@@ -167,6 +167,7 @@ public class DatabaseService
|
||||
TryAddColumn(conn, "sessions", "telegram_webhook_secret", "TEXT");
|
||||
TryAddColumn(conn, "sessions", "telegram_chat_id", "TEXT");
|
||||
TryAddColumn(conn, "sessions", "telegram_allowed_chat_ids", "TEXT");
|
||||
TryAddColumn(conn, "sessions", "telegram_bot_id", "TEXT");
|
||||
TryAddColumn(conn, "agents", "user_id", "TEXT");
|
||||
TryAddColumn(conn, "users", "is_admin", "INTEGER NOT NULL DEFAULT 0");
|
||||
TryAddColumn(conn, "users", "persona", "TEXT");
|
||||
@@ -227,6 +228,25 @@ public class DatabaseService
|
||||
CREATE INDEX IF NOT EXISTS idx_telegram_links_code ON telegram_links(link_code);
|
||||
");
|
||||
|
||||
conn.Execute(@"
|
||||
CREATE TABLE IF NOT EXISTS telegram_bots (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
bot_id TEXT NOT NULL UNIQUE,
|
||||
user_id TEXT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
bot_token TEXT NOT NULL,
|
||||
webhook_secret TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_telegram_bots_user ON telegram_bots(user_id);
|
||||
");
|
||||
|
||||
TryAddColumn(conn, "telegram_bots", "is_public", "INTEGER NOT NULL DEFAULT 0");
|
||||
|
||||
// Migration: Bestehende Session-Telegram-Daten in telegram_bots überführen
|
||||
MigrateTelegramBotsFromSessions(conn);
|
||||
|
||||
conn.Execute(@"
|
||||
CREATE TABLE IF NOT EXISTS cronjobs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
@@ -578,7 +598,7 @@ public class DatabaseService
|
||||
MessageCount = activeCount,
|
||||
ArchiveMessageCount = totalCount - activeCount,
|
||||
TotalMessageCount = totalCount,
|
||||
TelegramConfigured = !string.IsNullOrEmpty(s.TelegramBotToken),
|
||||
TelegramConfigured = !string.IsNullOrEmpty(s.TelegramBotId),
|
||||
TelegramLinked = !string.IsNullOrEmpty(s.TelegramChatId)
|
||||
});
|
||||
}
|
||||
@@ -1147,37 +1167,140 @@ public class DatabaseService
|
||||
await conn.ExecuteAsync("DELETE FROM users WHERE user_id = @userId", new { userId });
|
||||
}
|
||||
|
||||
// ── Telegram (Session-basiert) ──
|
||||
// ── Telegram Bots ──
|
||||
|
||||
public async Task<SessionRecord> GetSessionByTelegramChatId(long chatId)
|
||||
private void MigrateTelegramBotsFromSessions(SqliteConnection conn)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
return await conn.QuerySingleOrDefaultAsync<SessionRecord>(
|
||||
"SELECT * FROM sessions WHERE telegram_chat_id = @chatId AND is_deleted = 0",
|
||||
new { chatId = chatId.ToString() });
|
||||
// Prüfe ob es Sessions mit bot_token gibt, die noch kein telegram_bot_id haben
|
||||
var sessions = conn.Query<dynamic>(
|
||||
"SELECT session_id, user_id, name, telegram_bot_token, telegram_webhook_secret FROM sessions WHERE telegram_bot_token IS NOT NULL AND telegram_bot_token != '' AND (telegram_bot_id IS NULL OR telegram_bot_id = '')").ToList();
|
||||
|
||||
if (sessions.Count == 0) return;
|
||||
|
||||
var now = DateTime.UtcNow.ToString("o");
|
||||
foreach (var s in sessions)
|
||||
{
|
||||
string token = s.telegram_bot_token;
|
||||
string userId = s.user_id ?? "";
|
||||
string sessionName = s.name ?? "Unbenannt";
|
||||
string secret = s.telegram_webhook_secret ?? Guid.NewGuid().ToString("N");
|
||||
|
||||
// Prüfe ob für diesen Token bereits ein Bot existiert
|
||||
var existing = conn.QuerySingleOrDefault<dynamic>(
|
||||
"SELECT bot_id FROM telegram_bots WHERE bot_token = @token", new { token });
|
||||
|
||||
string botId;
|
||||
if (existing != null)
|
||||
{
|
||||
botId = existing.bot_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
botId = Guid.NewGuid().ToString();
|
||||
conn.Execute(@"
|
||||
INSERT INTO telegram_bots (bot_id, user_id, name, bot_token, webhook_secret, created_at, updated_at)
|
||||
VALUES (@botId, @userId, @name, @token, @secret, @now, @now)",
|
||||
new { botId, userId, name = $"Bot von {sessionName}", token, secret, now });
|
||||
}
|
||||
|
||||
conn.Execute(
|
||||
"UPDATE sessions SET telegram_bot_id = @botId, updated_at = @now WHERE session_id = @sessionId",
|
||||
new { botId, sessionId = (string)s.session_id, now });
|
||||
}
|
||||
}
|
||||
|
||||
public async Task UpdateSessionTelegram(string sessionId, string botToken, string webhookSecret, string chatId, string allowedChatIds = null)
|
||||
public async Task<IEnumerable<TelegramBotRecord>> GetTelegramBots(string userId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
return await conn.QueryAsync<TelegramBotRecord>(
|
||||
"SELECT * FROM telegram_bots WHERE user_id = @userId ORDER BY created_at DESC",
|
||||
new { userId });
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<TelegramBotRecord>> GetAvailableTelegramBots(string userId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
return await conn.QueryAsync<TelegramBotRecord>(
|
||||
"SELECT * FROM telegram_bots WHERE user_id = @userId OR is_public = 1 ORDER BY created_at DESC",
|
||||
new { userId });
|
||||
}
|
||||
|
||||
public async Task<TelegramBotRecord> GetTelegramBot(string botId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
return await conn.QuerySingleOrDefaultAsync<TelegramBotRecord>(
|
||||
"SELECT * FROM telegram_bots WHERE bot_id = @botId",
|
||||
new { botId });
|
||||
}
|
||||
|
||||
public async Task<TelegramBotRecord> CreateTelegramBot(string userId, string name, string botToken)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
var botId = Guid.NewGuid().ToString();
|
||||
var secret = Guid.NewGuid().ToString("N");
|
||||
var now = DateTime.UtcNow.ToString("o");
|
||||
await conn.ExecuteAsync(@"
|
||||
UPDATE sessions SET telegram_bot_token = @botToken, telegram_webhook_secret = @webhookSecret,
|
||||
telegram_chat_id = @chatId, telegram_allowed_chat_ids = @allowedChatIds, updated_at = @now
|
||||
INSERT INTO telegram_bots (bot_id, user_id, name, bot_token, webhook_secret, created_at, updated_at)
|
||||
VALUES (@botId, @userId, @name, @botToken, @secret, @now, @now)",
|
||||
new { botId, userId, name, botToken, secret, now });
|
||||
return await GetTelegramBot(botId);
|
||||
}
|
||||
|
||||
public async Task UpdateTelegramBot(string botId, string name, string botToken, bool isPublic)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
var now = DateTime.UtcNow.ToString("o");
|
||||
await conn.ExecuteAsync(@"
|
||||
UPDATE telegram_bots SET name = @name, bot_token = @botToken, is_public = @isPublic, updated_at = @now
|
||||
WHERE bot_id = @botId",
|
||||
new { botId, name, botToken, isPublic, now });
|
||||
}
|
||||
|
||||
public async Task DeleteTelegramBot(string botId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
var now = DateTime.UtcNow.ToString("o");
|
||||
// Erst alle Session-Verknüpfungen entfernen
|
||||
await conn.ExecuteAsync(
|
||||
"UPDATE sessions SET telegram_bot_id = NULL, updated_at = @now WHERE telegram_bot_id = @botId",
|
||||
new { botId, now });
|
||||
await conn.ExecuteAsync("DELETE FROM telegram_bots WHERE bot_id = @botId", new { botId });
|
||||
}
|
||||
|
||||
public async Task<int> GetTelegramBotSessionCount(string botId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
return await conn.ExecuteScalarAsync<int>(
|
||||
"SELECT COUNT(*) FROM sessions WHERE telegram_bot_id = @botId AND is_deleted = 0",
|
||||
new { botId });
|
||||
}
|
||||
|
||||
public async Task SetSessionTelegramBot(string sessionId, string botId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
var now = DateTime.UtcNow.ToString("o");
|
||||
await conn.ExecuteAsync(
|
||||
"UPDATE sessions SET telegram_bot_id = @botId, updated_at = @now WHERE session_id = @sessionId",
|
||||
new { sessionId, botId = (object)botId ?? DBNull.Value, now });
|
||||
}
|
||||
|
||||
public async Task UpdateSessionTelegramChat(string sessionId, string chatId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
var now = DateTime.UtcNow.ToString("o");
|
||||
await conn.ExecuteAsync(@"
|
||||
UPDATE sessions SET telegram_chat_id = @chatId, updated_at = @now
|
||||
WHERE session_id = @sessionId",
|
||||
new { sessionId, botToken, webhookSecret, chatId, allowedChatIds, now = DateTime.UtcNow.ToString("o") });
|
||||
new { sessionId, chatId, now });
|
||||
}
|
||||
|
||||
public async Task SetSessionTelegramChatId(string sessionId, string chatId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
// Erst alte Verknüpfung mit dieser chatId entfernen (ein Telegram-Chat = eine Session)
|
||||
await conn.ExecuteAsync(
|
||||
"UPDATE sessions SET telegram_chat_id = NULL, updated_at = @now WHERE telegram_chat_id = @chatId",
|
||||
new { chatId, now = DateTime.UtcNow.ToString("o") });
|
||||
// Dann diese Session verknüpfen
|
||||
var now = DateTime.UtcNow.ToString("o");
|
||||
await conn.ExecuteAsync(
|
||||
"UPDATE sessions SET telegram_chat_id = @chatId, updated_at = @now WHERE session_id = @sessionId",
|
||||
new { sessionId, chatId, now = DateTime.UtcNow.ToString("o") });
|
||||
new { sessionId, chatId, now });
|
||||
}
|
||||
|
||||
public async Task ClearSessionTelegramChatId(string sessionId)
|
||||
@@ -1188,6 +1311,25 @@ public class DatabaseService
|
||||
new { sessionId, now = DateTime.UtcNow.ToString("o") });
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<SessionRecord>> GetSessionsByTelegramBot(string botId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
return await conn.QueryAsync<SessionRecord>(
|
||||
"SELECT * FROM sessions WHERE telegram_bot_id = @botId AND is_deleted = 0",
|
||||
new { botId });
|
||||
}
|
||||
|
||||
public async Task<SessionRecord> FindSessionForTelegramChat(string botId, long chatId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
var chatIdStr = chatId.ToString();
|
||||
// Erst exakte Chat-ID-Verknüpfung suchen
|
||||
var session = await conn.QuerySingleOrDefaultAsync<SessionRecord>(
|
||||
"SELECT * FROM sessions WHERE telegram_bot_id = @botId AND telegram_chat_id = @chatIdStr AND is_deleted = 0",
|
||||
new { botId, chatIdStr });
|
||||
return session;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<SessionRecord>> GetUserSessions(string userId)
|
||||
{
|
||||
using var conn = CreateConnection();
|
||||
|
||||
+49
-132
@@ -30,21 +30,9 @@ public class TelegramService
|
||||
_maxIterations = maxIterations;
|
||||
}
|
||||
|
||||
// ── Bot-Token / Secret aus Session laden ──
|
||||
|
||||
public string GetBotTokenForSession(SessionRecord session)
|
||||
{
|
||||
return session?.TelegramBotToken;
|
||||
}
|
||||
|
||||
public string GetWebhookSecretForSession(SessionRecord session)
|
||||
{
|
||||
return session?.TelegramWebhookSecret;
|
||||
}
|
||||
|
||||
// ── Webhook-Update verarbeiten ──
|
||||
|
||||
public async Task HandleUpdate(JsonElement update, SessionRecord session)
|
||||
public async Task HandleUpdate(JsonElement update, TelegramBotRecord bot)
|
||||
{
|
||||
if (!update.TryGetProperty("message", out var message)) return;
|
||||
if (!message.TryGetProperty("chat", out var chat)) return;
|
||||
@@ -55,77 +43,54 @@ public class TelegramService
|
||||
|
||||
if (string.IsNullOrEmpty(text)) return;
|
||||
|
||||
var botToken = session.TelegramBotToken;
|
||||
if (string.IsNullOrEmpty(botToken)) return;
|
||||
// Session für diesen Chat finden (1 Session = max 1 Chat)
|
||||
var session = await _db.FindSessionForTelegramChat(bot.BotId, chatId);
|
||||
|
||||
if (text.StartsWith("/start"))
|
||||
{
|
||||
if (!IsChatIdAllowed(session, chatId))
|
||||
{
|
||||
// Telegram-Username aus dem Update extrahieren
|
||||
var username = "";
|
||||
if (message.TryGetProperty("from", out var from))
|
||||
{
|
||||
if (from.TryGetProperty("username", out var uname))
|
||||
username = uname.GetString() ?? "";
|
||||
else if (from.TryGetProperty("first_name", out var fname))
|
||||
username = fname.GetString() ?? "";
|
||||
}
|
||||
|
||||
await SendMessage(chatId, botToken,
|
||||
"🔒 Zugriff verweigert.\n\n" +
|
||||
"Du bist nicht für diesen Bot freigegeben. " +
|
||||
"Bitte kontaktiere den Inhaber und teile deine Chat-ID mit:\n\n" +
|
||||
$"📋 Deine Chat-ID: `{chatId}`",
|
||||
parseMode: "Markdown");
|
||||
|
||||
// Owner benachrichtigen (wenn chatId gesetzt)
|
||||
if (!string.IsNullOrEmpty(session.TelegramChatId))
|
||||
{
|
||||
var ownerChatId = long.Parse(session.TelegramChatId);
|
||||
var requesterInfo = string.IsNullOrEmpty(username) ? chatId.ToString() : $"@{username} ({chatId})";
|
||||
await SendMessage(ownerChatId, botToken,
|
||||
$"🔔 *Zugriffsanfrage*\n\n" +
|
||||
$"Benutzer {EscapeMd(requesterInfo)} möchte diesen Bot nutzen\\.\n\n" +
|
||||
$"Chat\\-ID: `{chatId}`\n\n" +
|
||||
"Zum Freigeben: Chat\\-ID in den Session\\-Einstellungen unter _Erlaubte Chat\\-IDs_ hinzufügen\\.",
|
||||
parseMode: "MarkdownV2");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Erste Verbindung: chatId als Owner setzen (wenn noch keine gesetzt)
|
||||
if (string.IsNullOrEmpty(session.TelegramChatId))
|
||||
{
|
||||
await _db.SetSessionTelegramChatId(session.SessionId, chatId.ToString());
|
||||
}
|
||||
|
||||
var sessionName = session.Name ?? session.SessionId;
|
||||
await SendMessage(chatId, botToken,
|
||||
$"✅ *Verbunden mit Session: {EscapeMd(sessionName)}*\n\n" +
|
||||
"Du kannst jetzt einfach drauflos schreiben\\!\n\n" +
|
||||
"Befehle:\n" +
|
||||
"/clear – History archivieren\n" +
|
||||
"/status – Aktuelle Session\\-Info\n" +
|
||||
"/unlink – Verknüpfung aufheben",
|
||||
parseMode: "MarkdownV2");
|
||||
await HandleStart(chatId, bot, session);
|
||||
return;
|
||||
}
|
||||
|
||||
// Alle anderen Befehle/Nachrichten: Zugriff prüfen
|
||||
if (!IsChatIdAllowed(session, chatId))
|
||||
if (session == null)
|
||||
{
|
||||
await SendMessage(chatId, botToken, "🔒 Du bist nicht für diesen Bot freigegeben. Sende /start für mehr Informationen.");
|
||||
await SendMessage(chatId, bot.BotToken,
|
||||
$"🔒 Keine Session mit diesem Chat verknüpft.\n\nDeine Chat-ID: `{chatId}`\nBitte weise diese Chat-ID im Web-UI einer Session zu.",
|
||||
parseMode: "Markdown");
|
||||
return;
|
||||
}
|
||||
|
||||
if (text.StartsWith("/"))
|
||||
{
|
||||
await HandleCommand(chatId, text, botToken, session);
|
||||
await HandleCommand(chatId, text, bot.BotToken, session);
|
||||
return;
|
||||
}
|
||||
|
||||
await HandleMessage(chatId, text, botToken, session);
|
||||
await HandleMessage(chatId, text, bot.BotToken, session);
|
||||
}
|
||||
|
||||
private async Task HandleStart(long chatId, TelegramBotRecord bot, SessionRecord session)
|
||||
{
|
||||
if (session != null)
|
||||
{
|
||||
// Bereits verknüpft – Willkommensinfo
|
||||
var sessionName = session.Name ?? session.SessionId;
|
||||
await SendMessage(chatId, bot.BotToken,
|
||||
$"✅ *Verbunden mit Session: {EscapeMd(sessionName)}*\n\n" +
|
||||
"Du kannst jetzt einfach drauflos schreiben\\!\n\n" +
|
||||
"Befehle:\n" +
|
||||
"/clear – History archivieren\n" +
|
||||
"/status – Aktuelle Session\\-Info",
|
||||
parseMode: "MarkdownV2");
|
||||
return;
|
||||
}
|
||||
|
||||
// Nicht verknüpft – Chat-ID anzeigen
|
||||
await SendMessage(chatId, bot.BotToken,
|
||||
$"📋 Deine Chat-ID: `{chatId}`\n\n" +
|
||||
"Bitte weise diese Chat-ID im Web-UI einer Session zu, " +
|
||||
"die diesen Bot verwendet.",
|
||||
parseMode: "Markdown");
|
||||
}
|
||||
|
||||
// ── Commands ──
|
||||
@@ -153,11 +118,6 @@ public class TelegramService
|
||||
await SendMessage(chatId, botToken, sb.ToString(), parseMode: "MarkdownV2");
|
||||
break;
|
||||
|
||||
case "/unlink":
|
||||
await _db.ClearSessionTelegramChatId(session.SessionId);
|
||||
await SendMessage(chatId, botToken, "✅ Verknüpfung aufgehoben. Sende /start um erneut zu verbinden.");
|
||||
break;
|
||||
|
||||
default:
|
||||
await SendMessage(chatId, botToken, "❓ Unbekannter Befehl. Sende /start für Hilfe.");
|
||||
break;
|
||||
@@ -168,13 +128,6 @@ public class TelegramService
|
||||
|
||||
private async Task HandleMessage(long chatId, string userText, string botToken, SessionRecord session)
|
||||
{
|
||||
if (!IsChatIdAllowed(session, chatId))
|
||||
{
|
||||
await SendMessage(chatId, botToken, "🔒 Du bist nicht für diesen Bot freigegeben. Sende /start für mehr Informationen.");
|
||||
return;
|
||||
}
|
||||
|
||||
// ChatService für Setup nutzen (userId = null → kein Auth-Check, Session ist bereits authentifiziert via Webhook-Secret)
|
||||
var ctx = await _chatService.PrepareContext(session.SessionId, null, _maxIterations);
|
||||
if (ctx == null)
|
||||
{
|
||||
@@ -186,7 +139,6 @@ public class TelegramService
|
||||
|
||||
try
|
||||
{
|
||||
// History aus DB laden + User-Nachricht anhängen
|
||||
var history = await _chatService.BuildHistoryFromDb(session.SessionId);
|
||||
history.Add(new Dictionary<string, object>
|
||||
{
|
||||
@@ -194,7 +146,6 @@ public class TelegramService
|
||||
["content"] = userText
|
||||
});
|
||||
|
||||
// User-Nachricht in DB speichern
|
||||
await _db.SaveMessage(new MessageRecord
|
||||
{
|
||||
ChainId = ctx.ChainId,
|
||||
@@ -204,7 +155,6 @@ public class TelegramService
|
||||
Content = userText
|
||||
});
|
||||
|
||||
// AnthropicService für Non-Streaming-Chat nutzen
|
||||
var reply = await _anthropic.ChatNonStreaming(ctx, history, onIteration: async (iteration) =>
|
||||
{
|
||||
if (iteration % 3 == 0)
|
||||
@@ -224,11 +174,14 @@ public class TelegramService
|
||||
public async Task SendNotification(string sessionId, string text)
|
||||
{
|
||||
var session = await _db.GetSession(sessionId);
|
||||
if (session == null || string.IsNullOrEmpty(session.TelegramBotToken) || string.IsNullOrEmpty(session.TelegramChatId))
|
||||
if (session == null || string.IsNullOrEmpty(session.TelegramBotId) || string.IsNullOrEmpty(session.TelegramChatId))
|
||||
return;
|
||||
|
||||
var bot = await _db.GetTelegramBot(session.TelegramBotId);
|
||||
if (bot == null || string.IsNullOrEmpty(bot.BotToken)) return;
|
||||
|
||||
var chatId = long.Parse(session.TelegramChatId);
|
||||
await SendMessage(chatId, session.TelegramBotToken, text);
|
||||
await SendMessage(chatId, bot.BotToken, text);
|
||||
}
|
||||
|
||||
// ── Telegram Bot API ──
|
||||
@@ -274,15 +227,11 @@ public class TelegramService
|
||||
new StringContent(JsonSerializer.Serialize(new { chat_id = chatId, action }), Encoding.UTF8, "application/json"));
|
||||
}
|
||||
|
||||
// ── Webhook-Verwaltung (pro Session) ──
|
||||
// ── Webhook-Verwaltung (pro Bot) ──
|
||||
|
||||
public async Task<string> RegisterWebhook(string baseUrl, string sessionId)
|
||||
public async Task<string> RegisterWebhook(string baseUrl, TelegramBotRecord bot)
|
||||
{
|
||||
var session = await _db.GetSession(sessionId);
|
||||
if (session == null || string.IsNullOrEmpty(session.TelegramBotToken))
|
||||
return JsonSerializer.Serialize(new { ok = false, error = "Kein Bot-Token für diese Session konfiguriert" });
|
||||
|
||||
var webhookUrl = $"{baseUrl.TrimEnd('/')}/api/telegram/webhook/{sessionId}";
|
||||
var webhookUrl = $"{baseUrl.TrimEnd('/')}/api/telegram/webhook/{bot.BotId}";
|
||||
var client = _httpFactory.CreateClient();
|
||||
var payload = new Dictionary<string, object>
|
||||
{
|
||||
@@ -290,66 +239,34 @@ public class TelegramService
|
||||
["allowed_updates"] = new[] { "message" }
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(session.TelegramWebhookSecret))
|
||||
payload["secret_token"] = session.TelegramWebhookSecret;
|
||||
if (!string.IsNullOrEmpty(bot.WebhookSecret))
|
||||
payload["secret_token"] = bot.WebhookSecret;
|
||||
|
||||
var resp = await client.PostAsync(
|
||||
$"https://api.telegram.org/bot{session.TelegramBotToken}/setWebhook",
|
||||
$"https://api.telegram.org/bot{bot.BotToken}/setWebhook",
|
||||
new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json"));
|
||||
|
||||
return await resp.Content.ReadAsStringAsync();
|
||||
}
|
||||
|
||||
public async Task<string> GetWebhookInfo(string sessionId)
|
||||
public async Task<string> GetWebhookInfo(TelegramBotRecord bot)
|
||||
{
|
||||
var session = await _db.GetSession(sessionId);
|
||||
if (session == null || string.IsNullOrEmpty(session.TelegramBotToken))
|
||||
return JsonSerializer.Serialize(new { ok = false, error = "Kein Bot-Token konfiguriert" });
|
||||
|
||||
var client = _httpFactory.CreateClient();
|
||||
var resp = await client.GetAsync($"https://api.telegram.org/bot{session.TelegramBotToken}/getWebhookInfo");
|
||||
var resp = await client.GetAsync($"https://api.telegram.org/bot{bot.BotToken}/getWebhookInfo");
|
||||
return await resp.Content.ReadAsStringAsync();
|
||||
}
|
||||
|
||||
public async Task<string> DeleteWebhook(string sessionId)
|
||||
public async Task<string> DeleteWebhook(TelegramBotRecord bot)
|
||||
{
|
||||
var session = await _db.GetSession(sessionId);
|
||||
if (session == null || string.IsNullOrEmpty(session.TelegramBotToken))
|
||||
return JsonSerializer.Serialize(new { ok = false, error = "Kein Bot-Token konfiguriert" });
|
||||
|
||||
var client = _httpFactory.CreateClient();
|
||||
var resp = await client.PostAsync(
|
||||
$"https://api.telegram.org/bot{session.TelegramBotToken}/deleteWebhook",
|
||||
$"https://api.telegram.org/bot{bot.BotToken}/deleteWebhook",
|
||||
new StringContent("{}", Encoding.UTF8, "application/json"));
|
||||
return await resp.Content.ReadAsStringAsync();
|
||||
}
|
||||
|
||||
// ── Helper ──
|
||||
|
||||
private static bool IsChatIdAllowed(SessionRecord session, long chatId)
|
||||
{
|
||||
var chatIdStr = chatId.ToString();
|
||||
|
||||
// Owner (die primäre verknüpfte chatId) ist immer erlaubt
|
||||
if (session.TelegramChatId == chatIdStr) return true;
|
||||
|
||||
// Wenn noch kein Owner gesetzt und keine Whitelist → erster User wird Owner
|
||||
if (string.IsNullOrEmpty(session.TelegramChatId) && string.IsNullOrEmpty(session.TelegramAllowedChatIds))
|
||||
return true;
|
||||
|
||||
// Whitelist prüfen
|
||||
if (!string.IsNullOrEmpty(session.TelegramAllowedChatIds))
|
||||
{
|
||||
var allowed = session.TelegramAllowedChatIds.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
foreach (var id in allowed)
|
||||
{
|
||||
if (id == chatIdStr) return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static string EscapeMd(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text)) return "";
|
||||
|
||||
Reference in new issue
Block a user