Telegram: Bot=Session statt User-Level, Chat-Code-Refactoring
- Telegram-Config (Bot-Token, Webhook-Secret, ChatId) von User-Settings
in sessions-Tabelle verschoben → jede Session hat ihren eigenen Bot
- Link-Code-System komplett entfernt (TelegramLinkRecord gelöscht)
- /start verknüpft automatisch, kein /link mehr nötig
- Alle Endpoints session-basiert: /api/sessions/{id}/telegram/*
- Webhook-URL pro Session: /api/telegram/webhook/{sessionId}
Refactoring: Doppelten Chat-Code eliminiert
- Neuer ChatService: PrepareContext, BuildHistoryFromDb, ResolveModelId
- Neues ChatContext-Model als gemeinsame Datenstruktur
- AnthropicService.ChatNonStreaming() für Telegram (statt eigenem Loop)
- TelegramService um ~180 Zeilen reduziert, kein eigener Claude-Loop mehr
- ChatEndpoint nutzt ChatService.PrepareContext() statt eigener Setup-Logik
- Model-Mapping nur noch an einer Stelle (3x → 1x)
Frontend
- Telegram-Section von Settings-Page in Session-Bearbeitungsseite verschoben
- Webhook-Secret readonly, wird einmalig generiert und persistent gespeichert
- Status wird automatisch geladen, Register/Delete je nach Webhook-Status
- Toast-Notification-System (showToast) in ui.js
- Link-Code-Modal und Telegram-Menüpunkt im Dashboard entfernt
- Telegram-Badge auf Session-Cards (konfiguriert/verbunden)
Bugfix: Bearer statt x-api-key für OAuth-Tokens im TelegramService
This commit is contained in:
1 parent
a0752ea492
commit
0120bb8f73
21 files changed
+994
-1272
No files matched your search
@@ -55,6 +55,11 @@ registerPage('session', {
|
||||
// Befehl hinzufügen
|
||||
addCommandBtn.addEventListener('click', () => createCommandRow(commandsList));
|
||||
|
||||
// Telegram-Section nur für existierende Sessions
|
||||
if (!isNew) {
|
||||
initSessionTelegram(sessionId);
|
||||
}
|
||||
|
||||
// Agents laden
|
||||
const agents = await apiGetAgents();
|
||||
agentSelect.innerHTML = '<option value="">-- Kein Agent --</option>';
|
||||
@@ -135,6 +140,17 @@ registerPage('session', {
|
||||
await apiCreateSession(data);
|
||||
} else {
|
||||
await apiUpdateSession(sessionId, data);
|
||||
// Telegram-Config mitspeichern (falls Section sichtbar)
|
||||
var tgToken = document.getElementById('sessionTelegramToken');
|
||||
var tgSecret = document.getElementById('sessionTelegramSecret');
|
||||
if (tgToken) {
|
||||
try {
|
||||
await saveTelegramConfig(sessionId, tgToken, tgSecret);
|
||||
} catch(e) {
|
||||
showToast('Session gespeichert, aber Telegram-Fehler: ' + e.message, 'error');
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
navigateTo('dashboard');
|
||||
});
|
||||
@@ -157,3 +173,131 @@ registerPage('session', {
|
||||
_sessionImageData = null;
|
||||
}
|
||||
});
|
||||
|
||||
function initSessionTelegram(sessionId) {
|
||||
var tokenInput = document.getElementById('sessionTelegramToken');
|
||||
var secretInput = document.getElementById('sessionTelegramSecret');
|
||||
var registerBtn = document.getElementById('sessionTelegramRegisterBtn');
|
||||
var deleteBtn = document.getElementById('sessionTelegramDeleteBtn');
|
||||
var statusBox = document.getElementById('sessionTelegramStatusBox');
|
||||
|
||||
// Vorhandene Config laden + Status abrufen
|
||||
apiSessionTelegramGet(sessionId).then(async function(config) {
|
||||
if (config.botToken) tokenInput.value = config.botToken;
|
||||
if (config.webhookSecret) {
|
||||
secretInput.value = config.webhookSecret;
|
||||
} else {
|
||||
// Secret einmalig generieren und sofort persistent speichern
|
||||
var newSecret = crypto.randomUUID().replace(/-/g, '');
|
||||
secretInput.value = newSecret;
|
||||
await apiSessionTelegramSave(sessionId, config.botToken || '', newSecret);
|
||||
}
|
||||
// Status automatisch abrufen wenn Token konfiguriert ist
|
||||
if (config.botToken) {
|
||||
refreshTelegramStatus(sessionId, statusBox, registerBtn, deleteBtn);
|
||||
} else {
|
||||
showTelegramUnconfigured(statusBox, registerBtn, deleteBtn);
|
||||
}
|
||||
}).catch(function() {
|
||||
showTelegramUnconfigured(statusBox, registerBtn, deleteBtn);
|
||||
});
|
||||
|
||||
// Webhook registrieren
|
||||
registerBtn.addEventListener('click', async function() {
|
||||
var baseUrl = prompt('Base-URL der App:', window.location.origin);
|
||||
if (!baseUrl) return;
|
||||
registerBtn.disabled = true;
|
||||
registerBtn.textContent = 'Wird registriert...';
|
||||
try {
|
||||
// Erst Token + Secret speichern (falls geändert)
|
||||
await saveTelegramConfig(sessionId, tokenInput, secretInput);
|
||||
var res = await apiSessionTelegramRegisterWebhook(sessionId, baseUrl.trim());
|
||||
if (res.ok) {
|
||||
showToast('Webhook registriert!', 'success');
|
||||
} else {
|
||||
showToast('Antwort: ' + JSON.stringify(res), 'error');
|
||||
}
|
||||
} catch(e) {
|
||||
showToast('Fehler: ' + e.message, 'error');
|
||||
} finally {
|
||||
registerBtn.disabled = false;
|
||||
registerBtn.textContent = 'Webhook registrieren';
|
||||
refreshTelegramStatus(sessionId, statusBox, registerBtn, deleteBtn);
|
||||
}
|
||||
});
|
||||
|
||||
// Webhook entfernen
|
||||
deleteBtn.addEventListener('click', async function() {
|
||||
if (!confirm('Webhook wirklich entfernen?')) return;
|
||||
deleteBtn.disabled = true;
|
||||
deleteBtn.textContent = 'Wird entfernt...';
|
||||
try {
|
||||
var res = await apiSessionTelegramDeleteWebhook(sessionId);
|
||||
if (res.ok) {
|
||||
showToast('Webhook entfernt', 'success');
|
||||
} else {
|
||||
showToast('Antwort: ' + JSON.stringify(res), 'error');
|
||||
}
|
||||
} catch(e) {
|
||||
showToast('Fehler: ' + e.message, 'error');
|
||||
} finally {
|
||||
deleteBtn.disabled = false;
|
||||
deleteBtn.textContent = 'Webhook entfernen';
|
||||
refreshTelegramStatus(sessionId, statusBox, registerBtn, deleteBtn);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function showTelegramUnconfigured(statusBox, registerBtn, deleteBtn) {
|
||||
statusBox.innerHTML = '<p>⚠️ Kein Bot-Token konfiguriert. Speichere zuerst die Session mit einem Token.</p>';
|
||||
statusBox.hidden = false;
|
||||
registerBtn.hidden = true;
|
||||
deleteBtn.hidden = true;
|
||||
}
|
||||
|
||||
async function refreshTelegramStatus(sessionId, statusBox, registerBtn, deleteBtn) {
|
||||
statusBox.hidden = true;
|
||||
try {
|
||||
var info = await apiSessionTelegramWebhookInfo(sessionId);
|
||||
var result = info.result || {};
|
||||
var url = result.url || '';
|
||||
var pending = result.pending_update_count || 0;
|
||||
var lastError = result.last_error_message;
|
||||
var active = !!url;
|
||||
|
||||
var html = '';
|
||||
if (active) {
|
||||
html += '<p>✅ <strong>Webhook aktiv</strong></p>';
|
||||
html += '<p><strong>URL:</strong> ' + escapeHtml(url) + '</p>';
|
||||
html += '<p><strong>Ausstehend:</strong> ' + pending + '</p>';
|
||||
if (lastError) html += '<p class="tg-error"><strong>Letzter Fehler:</strong> ' + escapeHtml(lastError) + '</p>';
|
||||
} else {
|
||||
html += '<p>⚠️ <strong>Webhook nicht registriert</strong></p>';
|
||||
}
|
||||
statusBox.innerHTML = html;
|
||||
statusBox.hidden = false;
|
||||
|
||||
// Buttons ein/ausblenden je nach Status
|
||||
registerBtn.hidden = active;
|
||||
deleteBtn.hidden = !active;
|
||||
} catch(e) {
|
||||
statusBox.innerHTML = '<p class="tg-error">Status konnte nicht abgerufen werden: ' + escapeHtml(e.message) + '</p>';
|
||||
statusBox.hidden = false;
|
||||
registerBtn.hidden = false;
|
||||
deleteBtn.hidden = true;
|
||||
}
|
||||
}
|
||||
|
||||
async function saveTelegramConfig(sessionId, tokenInput, secretInput) {
|
||||
var token = tokenInput.value.trim();
|
||||
var secret = secretInput.value.trim();
|
||||
await apiSessionTelegramSave(sessionId, token, secret);
|
||||
}
|
||||
|
||||
function escapeHtml(str) {
|
||||
return String(str)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"');
|
||||
}
|
||||
Reference in new issue
Block a user