Telegram: Webhook-Verwaltung in Einstellungen-Seite

- Backend: DELETE /api/telegram/webhook Endpoint + TelegramService.DeleteWebhook()
- api.js: apiTelegramWebhookInfo(), apiTelegramRegisterWebhook(), apiTelegramDeleteWebhook()
- Settings-Page: Neue 'Telegram Bot' Section (nur für Admins, nur wenn konfiguriert)
  - Status abrufen: Webhook-URL, ausstehende Updates, letzter Fehler, Aktiv-Badge
  - Webhook registrieren: prompt() für Base-URL, POST an Telegram API
  - Webhook entfernen: Bestätigungsdialog + DELETE
- CSS: .telegram-status-box, .tg-status-row, .tg-label, .tg-value, .tg-badge
This commit is contained in:
Meleki committed 2026-03-03 09:06:22 +01:00
1 parent 7d237c866a
commit 4ac042e512
6 files changed
+232 -1

No files matched your search

+22
View File
@@ -274,6 +274,28 @@ async function apiTelegramLink(sessionId) {
return resp.json();
}
async function apiTelegramWebhookInfo() {
const resp = await fetch('/api/telegram/webhook-info');
if (!resp.ok) throw new Error('Webhook-Info fehlgeschlagen');
return resp.json();
}
async function apiTelegramRegisterWebhook(baseUrl) {
const resp = await fetch('/api/telegram/register-webhook', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ baseUrl })
});
if (!resp.ok) throw new Error('Webhook-Registrierung fehlgeschlagen');
return resp.json();
}
async function apiTelegramDeleteWebhook() {
const resp = await fetch('/api/telegram/webhook', { method: 'DELETE' });
if (!resp.ok) throw new Error('Webhook-Löschung fehlgeschlagen');
return resp.json();
}
async function apiBackupDb() {
const resp = await fetch('/api/backup', { method: 'POST' });
if (!resp.ok) throw new Error('Backup fehlgeschlagen');
+94 -1
View File
@@ -40,10 +40,12 @@ registerPage('settings', {
const chainMetaSelect = document.getElementById('settingChainMetaDisplay');
const resetBtn = document.getElementById('settingsResetBtn');
const backupSection = document.getElementById('settingsBackupSection');
const telegramSection = document.getElementById('settingsTelegramSection');
// Backup nur für Admins
// Backup + Telegram nur für Admins
if (currentUser && currentUser.isAdmin) {
backupSection.style.display = '';
initTelegramSection();
}
const s = loadSettings();
@@ -99,6 +101,97 @@ registerPage('settings', {
toolCallSelect.value = SETTINGS_DEFAULTS.toolCallDisplay;
chainMetaSelect.value = SETTINGS_DEFAULTS.chainMetaDisplay;
});
function initTelegramSection() {
// Erst prüfen ob Telegram überhaupt konfiguriert ist
apiTelegramStatus().then(s => {
if (!s.configured) return; // Bot-Token nicht gesetzt → Section versteckt lassen
telegramSection.style.display = '';
const statusBtn = document.getElementById('settingsTelegramStatusBtn');
const statusBox = document.getElementById('settingsTelegramStatusBox');
const registerBtn = document.getElementById('settingsTelegramRegisterBtn');
const deleteBtn = document.getElementById('settingsTelegramDeleteBtn');
// Status abrufen
statusBtn.addEventListener('click', async () => {
statusBtn.disabled = true;
statusBtn.textContent = 'Wird abgerufen...';
statusBox.style.display = 'none';
try {
const info = await apiTelegramWebhookInfo();
const result = info.result || {};
const url = result.url || '(kein Webhook registriert)';
const pending = result.pending_update_count ?? 0;
const lastError = result.last_error_message;
let html = `<div class="tg-status-row"><span class="tg-label">Webhook-URL</span><span class="tg-value">${escapeHtml(url)}</span></div>`;
html += `<div class="tg-status-row"><span class="tg-label">Ausstehende Updates</span><span class="tg-value">${pending}</span></div>`;
if (lastError) {
html += `<div class="tg-status-row tg-error"><span class="tg-label">Letzter Fehler</span><span class="tg-value">${escapeHtml(lastError)}</span></div>`;
}
const active = !!result.url;
html += `<div class="tg-status-row"><span class="tg-label">Status</span><span class="tg-value tg-badge ${active ? 'tg-badge-ok' : 'tg-badge-off'}">${active ? '✅ Aktiv' : '⚠️ Nicht registriert'}</span></div>`;
statusBox.innerHTML = html;
statusBox.style.display = '';
} catch (e) {
statusBox.innerHTML = `<div class="tg-status-row tg-error"><span class="tg-value">Fehler: ${escapeHtml(e.message)}</span></div>`;
statusBox.style.display = '';
} finally {
statusBtn.disabled = false;
statusBtn.textContent = 'Status abrufen';
}
});
// Webhook registrieren
registerBtn.addEventListener('click', async () => {
const baseUrl = prompt('Base-URL der App (z.B. https://deine-domain.de):', window.location.origin);
if (!baseUrl) return;
registerBtn.disabled = true;
registerBtn.textContent = 'Wird registriert...';
try {
const res = await apiTelegramRegisterWebhook(baseUrl.trim());
if (res.result && res.result.ok) {
alert('✅ Webhook erfolgreich registriert!');
} else {
alert('Antwort: ' + JSON.stringify(res.result));
}
} catch (e) {
alert('Fehler: ' + e.message);
} finally {
registerBtn.disabled = false;
registerBtn.textContent = 'Registrieren';
}
});
// Webhook löschen
deleteBtn.addEventListener('click', async () => {
if (!confirm('Webhook wirklich entfernen? Der Bot empfängt dann keine Nachrichten mehr.')) return;
deleteBtn.disabled = true;
deleteBtn.textContent = 'Wird entfernt...';
try {
const res = await apiTelegramDeleteWebhook();
if (res.ok) {
alert('✅ Webhook erfolgreich entfernt.');
} else {
alert('Antwort: ' + JSON.stringify(res));
}
} catch (e) {
alert('Fehler: ' + e.message);
} finally {
deleteBtn.disabled = false;
deleteBtn.textContent = 'Webhook entfernen';
}
});
});
}
},
destroy() {}
});
function escapeHtml(str) {
return String(str)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}