Files
deskhub/Plugins/plugins/community-bot/pages/community-bot.php
T
2026-10-24 20:15:15 +00:00

124 lines
8.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
// Seite des Community-Bot-Plugins. Verfügbar: $staff, $pdo.
$isAdmin = ($staff['role'] ?? '') === 'admin';
if (!$isAdmin) { echo '<h1>Discord und Telegram</h1><div class="flash error">Diese Seite ist nur für Administratoren zugänglich.</div>'; return; }
$message = null;
$error = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
verify_csrf();
if (!$isAdmin) {
$error = 'Einstellungen ändern darf nur ein Administrator.';
} else {
$action = $_POST['action'] ?? '';
if ($action === 'save') {
$key = strtolower(trim((string) ($_POST['discord_key'] ?? '')));
if ($key !== '' && !preg_match('/^[0-9a-f]{64}$/', $key)) {
$error = 'Der öffentliche Schlüssel von Discord besteht aus 64 Zeichen (0–9, a–f).';
} else {
plugin_set_setting(COMMUNITYBOT, 'discord_key', $key);
plugin_set_setting(COMMUNITYBOT, 'discord_app', preg_replace('/[^0-9]/', '', (string) ($_POST['discord_app'] ?? '')));
// Geheimnisse: leeres Feld lässt den bisherigen Wert stehen
foreach (['discord_token', 'telegram_token'] as $k) {
$v = trim((string) ($_POST[$k] ?? ''));
if ($v !== '') communitybot_set_secret($k, $v);
}
if (!empty($_POST['clear_discord'])) communitybot_set_secret('discord_token', '');
if (!empty($_POST['clear_telegram'])) { communitybot_set_secret('telegram_token', ''); communitybot_set_secret('telegram_secret', ''); }
plugin_set_setting(COMMUNITYBOT, 'department_id', (string) (int) ($_POST['department_id'] ?? 0));
plugin_set_setting(COMMUNITYBOT, 'priority_id', (string) (int) ($_POST['priority_id'] ?? 0));
plugin_set_setting(COMMUNITYBOT, 'limit', (string) max(1, min(50, (int) ($_POST['limit'] ?? 3))));
plugin_set_setting(COMMUNITYBOT, 'notify', !empty($_POST['notify']) ? '1' : '0');
$message = 'Einstellungen gespeichert.';
}
} elseif ($action === 'discord_register') {
$r = communitybot_discord_register();
if ($r['ok']) $message = $r['message']; else $error = $r['message'];
} elseif ($action === 'telegram_register') {
$r = communitybot_telegram_register();
if ($r['ok']) $message = $r['message']; else $error = $r['message'];
}
}
}
$cfg = communitybot_config();
$depts = $pdo->query('SELECT id, name FROM departments ORDER BY name')->fetchAll();
$prios = $pdo->query('SELECT id, name FROM priorities ORDER BY sort_order')->fetchAll();
$recent = $pdo->query('SELECT l.*, t.ticket_number, t.subject, t.status FROM plugin_communitybot_links l JOIN tickets t ON t.id = l.ticket_id ORDER BY l.id DESC LIMIT 30')->fetchAll();
$week = (int) $pdo->query("SELECT COUNT(*) FROM plugin_communitybot_links WHERE created_at >= '" . date('Y-m-d H:i:s', time() - 7 * 86400) . "'")->fetchColumn();
?>
<h1>Discord und Telegram</h1>
<?php if ($message): ?><div class="flash success"><?= e($message) ?></div><?php endif; ?>
<?php if ($error): ?><div class="flash error"><?= e($error) ?></div><?php endif; ?>
<div class="card" style="max-width:900px;margin-bottom:16px">
<h3>Zustand</h3>
<p style="font-size:.92rem"><strong><?= $week ?></strong> Tickets in den letzten 7 Tagen über Discord oder Telegram angelegt.</p>
<p style="font-size:.88rem">
Discord: <?= ($cfg['discord_key'] !== '' ? '<strong style="color:#15803d">Schlüssel eingetragen</strong>' : '<strong style="color:#b45309">Schlüssel fehlt</strong>') ?>
· Benachrichtigung per Direktnachricht: <?= $cfg['discord_token'] !== '' ? 'möglich' : '<strong style="color:#b45309">Bot-Token fehlt</strong>' ?><br>
Telegram: <?= $cfg['telegram_token'] !== '' ? '<strong style="color:#15803d">Token eingetragen</strong>' : '<strong style="color:#b45309">Token fehlt</strong>' ?>
<?php if (!function_exists('sodium_crypto_sign_verify_detached')): ?><br><strong style="color:#b91c1c">Auf diesem Server fehlt die PHP-Erweiterung „sodium“, Discord-Anfragen können nicht geprüft werden.</strong><?php endif; ?>
</p>
<p class="muted" style="font-size:.82rem">Adressen für die Einrichtung (nur aus dem Internet erreichbar, mit https):<br>
Discord „Interactions Endpoint URL“: <code><?= e(communitybot_url('discord')) ?></code><br>
Telegram wird mit dem Knopf unten automatisch verbunden.</p>
</div>
<?php if ($isAdmin): ?>
<form method="post" class="card" style="max-width:900px;margin-bottom:16px">
<?= csrf_field() ?>
<input type="hidden" name="action" value="save">
<h3>Einstellungen</h3>
<h4 style="margin:10px 0 4px">Discord</h4>
<p class="muted" style="font-size:.82rem">Im Discord Developer Portal eine Anwendung anlegen. „General Information“ liefert die Anwendungs-ID und den öffentlichen Schlüssel (Public Key), „Bot“ das Token. Als „Interactions Endpoint URL“ die Adresse oben eintragen.</p>
<label>Anwendungs-ID</label><input type="text" name="discord_app" value="<?= e($cfg['discord_app']) ?>" inputmode="numeric">
<label style="margin-top:8px">Öffentlicher Schlüssel (Public Key)</label><input type="text" name="discord_key" value="<?= e($cfg['discord_key']) ?>" maxlength="64" autocomplete="off">
<label style="margin-top:8px">Bot-Token (für die Befehle und Direktnachrichten) <?= $cfg['discord_token'] !== '' ? '– gespeichert, leer lassen zum Behalten' : '' ?></label>
<input type="password" name="discord_token" value="" autocomplete="new-password">
<?php if ($cfg['discord_token'] !== ''): ?><label style="font-size:.82rem"><input type="checkbox" name="clear_discord" value="1"> Gespeichertes Bot-Token entfernen</label><?php endif; ?>
<h4 style="margin:14px 0 4px">Telegram</h4>
<p class="muted" style="font-size:.82rem">Bei @BotFather mit /newbot einen Bot anlegen und das Token hier eintragen.</p>
<label>Bot-Token <?= $cfg['telegram_token'] !== '' ? '– gespeichert, leer lassen zum Behalten' : '' ?></label>
<input type="password" name="telegram_token" value="" autocomplete="new-password">
<?php if ($cfg['telegram_token'] !== ''): ?><label style="font-size:.82rem"><input type="checkbox" name="clear_telegram" value="1"> Telegram-Token entfernen und Verbindung trennen</label><?php endif; ?>
<h4 style="margin:14px 0 4px">Neue Tickets</h4>
<div style="display:flex;gap:14px;flex-wrap:wrap">
<div><label>Abteilung</label><select name="department_id"><option value="0">Standard</option><?php foreach ($depts as $d): ?><option value="<?= (int) $d['id'] ?>" <?= (int) $d['id'] === $cfg['department_id'] ? 'selected' : '' ?>><?= e($d['name']) ?></option><?php endforeach; ?></select></div>
<div><label>Priorität</label><select name="priority_id"><option value="0">Standard</option><?php foreach ($prios as $p): ?><option value="<?= (int) $p['id'] ?>" <?= (int) $p['id'] === $cfg['priority_id'] ? 'selected' : '' ?>><?= e($p['name']) ?></option><?php endforeach; ?></select></div>
<div><label>Höchstens Tickets pro Stunde und Person</label><input type="number" name="limit" min="1" max="50" value="<?= (int) $cfg['limit'] ?>" style="max-width:120px"></div>
</div>
<label style="display:block;margin-top:10px"><input type="checkbox" name="notify" value="1" <?= $cfg['notify'] ? 'checked' : '' ?>> Absender bei Antworten und bei Lösung benachrichtigen</label>
<div class="btn-row"><button type="submit" class="btn">Speichern</button></div>
</form>
<div class="card" style="max-width:900px;margin-bottom:16px">
<h3>Verbinden</h3>
<p class="muted" style="font-size:.85rem">Erst speichern, dann verbinden.</p>
<form method="post" style="display:inline"><?= csrf_field() ?><input type="hidden" name="action" value="discord_register"><button class="btn secondary" type="submit">Discord-Befehle eintragen</button></form>
<form method="post" style="display:inline"><?= csrf_field() ?><input type="hidden" name="action" value="telegram_register"><button class="btn secondary" type="submit">Telegram-Bot verbinden</button></form>
</div>
<?php endif; ?>
<div class="card">
<h3>Zuletzt angelegt</h3>
<?php if (!$recent): ?><p class="muted">Noch keine Tickets über Discord oder Telegram.</p><?php else: ?>
<table style="width:100%">
<thead><tr><th>Ticket</th><th>Kanal</th><th>Absender</th><th>Status</th><th>Angelegt</th></tr></thead>
<tbody>
<?php foreach ($recent as $l): ?>
<tr>
<td><a href="/staff/ticket_view.php?n=<?= e(urlencode((string) $l['ticket_number'])) ?>">#<?= e((string) $l['ticket_number']) ?></a><div class="muted" style="font-size:.76rem"><?= e(mb_strimwidth((string) $l['subject'], 0, 50, '…')) ?></div></td>
<td><?= $l['platform'] === 'discord' ? 'Discord' : 'Telegram' ?></td>
<td><?= e((string) $l['ext_name']) ?></td>
<td><?= e(status_label((string) $l['status'])[0]) ?></td>
<td><?= e(format_dt((string) $l['created_at'])) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>