[ 'method' => 'POST', 'header' => "Content-Type: application/json\r\n", 'content' => json_encode($data), 'timeout' => $timeoutSeconds, 'ignore_errors' => true, ]]; $result = @file_get_contents($url, false, stream_context_create($opts)); return $result !== false; } function http_post_form(string $url, array $data, int $timeoutSeconds = 5): bool { $opts = ['http' => [ 'method' => 'POST', 'header' => "Content-Type: application/x-www-form-urlencoded\r\n", 'content' => http_build_query($data), 'timeout' => $timeoutSeconds, 'ignore_errors' => true, ]]; $result = @file_get_contents($url, false, stream_context_create($opts)); return $result !== false; } function discord_notify(string $message): bool { $url = decrypt_secret(get_setting('discord_webhook_url') ?? ''); if (!$url) { return false; } return http_post_json($url, ['content' => $message]); } function telegram_notify(string $message): bool { $token = decrypt_secret(get_setting('telegram_bot_token') ?? ''); $chatId = get_setting('telegram_chat_id'); if (!$token || !$chatId) { return false; } $url = "https://api.telegram.org/bot{$token}/sendMessage"; return http_post_form($url, ['chat_id' => $chatId, 'text' => $message]); } /** Benachrichtigt E-Mail (Abteilung) + Discord + Telegram über ein neues Ticket */ function notify_new_ticket_channels(array $ticket, ?string $departmentEmail): void { fcm_notify_new_ticket($ticket); // Push auf die Android-App (läuft nach dem Senden der Seite) if ($departmentEmail) { notify_department_new_ticket($ticket, $departmentEmail); } $text = "🆕 Neues Ticket #{$ticket['ticket_number']}\n" . "Betreff: {$ticket['subject']}\n" . "Von: {$ticket['requester_name']} ({$ticket['requester_email']})"; if (!empty($ticket['department_name'])) { $text .= "\nAbteilung: {$ticket['department_name']}"; } $text .= "\n" . base_url() . '/staff/ticket_view.php?n=' . urlencode($ticket['ticket_number']); discord_notify($text); telegram_notify($text); } /** Benachrichtigt Discord + Telegram über eine neue Kundenantwort (kein Mail-Duplikat nötig) */ function notify_new_reply_channels(array $ticket, string $excerpt): void { fcm_notify_new_reply($ticket); // Push auf die Android-App (läuft nach dem Senden der Seite) try { // Antwort des Kunden holt das Ticket aus der Wiedervorlage und setzt die Erinnerung zurück; Beobachter erfahren davon $pdo = get_db(); ticket_snooze_clear($pdo, (int) $ticket['id'], null, 'Wiedervorlage beendet (Kunde hat geantwortet)'); $pdo->prepare('UPDATE tickets SET reminder_sent_at = NULL, updated_at = updated_at WHERE id = ?')->execute([$ticket['id']]); ticket_followers_notify($ticket, 'Neue Kundenantwort'); } catch (Throwable $e) { // Datenbank noch nicht aktualisiert: nicht schlimm } $short = mb_strlen($excerpt) > 200 ? mb_substr($excerpt, 0, 200) . '…' : $excerpt; $text = "💬 Neue Kundenantwort zu Ticket #{$ticket['ticket_number']}\n" . "Betreff: {$ticket['subject']}\n" . "„{$short}“\n" . base_url() . '/staff/ticket_view.php?n=' . urlencode($ticket['ticket_number']); discord_notify($text); telegram_notify($text); } /** * Benachrichtigt die Mitglieder eines Teams per E-Mail, wenn ihm ein Ticket zugewiesen wurde. * Entfällt bei deaktivierten Teams und wenn im Team "Benachrichtigung bei Ticketzuweisung * deaktivieren" gesetzt ist. Der auslösende Mitarbeiter ($actorId) bekommt keine Mail. * * @return int Anzahl verschickter Benachrichtigungen */ function notify_team_assignment(PDO $pdo, array $ticket, int $teamId, ?int $actorId = null): int { $stmt = $pdo->prepare('SELECT name, is_active, no_alerts FROM teams WHERE id = ?'); $stmt->execute([$teamId]); $team = $stmt->fetch(); if (!$team || !$team['is_active'] || $team['no_alerts']) return 0; $members = $pdo->prepare('SELECT s.id FROM team_members tm JOIN staff s ON s.id = tm.staff_id WHERE tm.team_id = ? AND s.is_active = 1'); $members->execute([$teamId]); // Mitglieder im Urlaub: stattdessen ihre Vertretung $memberRows = []; foreach (vacation_expand_ids($pdo, $members->fetchAll(PDO::FETCH_COLUMN)) as $mid) { $em = staff_emails_by_ids($pdo, [$mid]); if ($em) $memberRows[] = ['id' => $mid, 'email' => $em[0]]; } $sent = 0; $subject = 'Ticket #' . $ticket['ticket_number'] . ' wurde Team „' . $team['name'] . '“ zugewiesen'; $body = '
Das Ticket #' . e($ticket['ticket_number']) . ' („' . e($ticket['subject']) . '“) wurde dem Team ' . e($team['name']) . ' zugewiesen.
'; foreach ($memberRows as $m) { if ($actorId !== null && (int) $m['id'] === $actorId) continue; if (send_mail($m['email'], $subject, $body)) $sent++; } return $sent; }