124 lines
8.9 KiB
PHP
124 lines
8.9 KiB
PHP
<?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>
|