mahnung/class/mahnungntfy.class.php
Eduard Wisch 10cf41a687
All checks were successful
Deploy mahnung / deploy (push) Successful in 14s
i18n: Alle Texte über $langs->trans() — ~100 neue Sprachschlüssel de_DE + en_US [deploy]
Umlaute in allen lang-Dateien korrigiert. Alle hardcodierten deutschen Strings
in 22 PHP-Dateien durch $langs->trans('Key') ersetzt. Neue Schlüssel für
Cron-Meldungen, Dokument-Aktionen, Bonität, Vorschlag-Status, Template-Vars u.a.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-13 16:25:50 +02:00

94 lines
2.9 KiB
PHP

<?php
/* Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 3.
*/
/**
* \file htdocs/custom/mahnung/class/mahnungntfy.class.php
* \ingroup mahnung
* \brief Schmaler Ntfy-Push für das Mahnwesen-Modul.
*
* Phase 3: standalone Ntfy.
* Phase 7: wird durch GlobalNotify-Integration ergänzt/ersetzt (notify-Skill).
*
* Konfig-Konstanten (Setup-Seite):
* MAHNUNG_NTFY_TOPIC Default 'vk-builds'
* MAHNUNG_NTFY_URL Default 'https://notify.data-it-solution.de'
* MAHNUNG_NTFY_AUTH Optional: 'Basic ...'
*/
class MahnungNtfy
{
/**
* Sendet einen Push. Nie blockierend — Fehler nur ins Syslog.
*
* @param string $title Titel (wird header-sanitisiert)
* @param string $message Body
* @param string $clickUrl Optional: Click-URL
* @param array $tags Optional: Emoji-Tags (z.B. ['envelope_with_arrow'])
* @return bool true wenn HTTP 2xx, sonst false
*/
public static function send($title, $message, $clickUrl = '', array $tags = array())
{
$url = trim((string) getDolGlobalString('MAHNUNG_NTFY_URL', 'https://notify.data-it-solution.de'));
$topic = trim((string) getDolGlobalString('MAHNUNG_NTFY_TOPIC', 'vk-builds'));
$auth = trim((string) getDolGlobalString('MAHNUNG_NTFY_AUTH', ''));
if (empty($url) || empty($topic)) {
dol_syslog('MahnungNtfy: URL oder Topic nicht konfiguriert', LOG_WARNING);
return false;
}
$endpoint = rtrim($url, '/').'/'.rawurlencode($topic);
$headers = array(
'Content-Type: text/plain; charset=utf-8',
'Title: '.self::sanitizeHeader($title),
'Priority: default',
);
if (!empty($tags)) {
$headers[] = 'Tags: '.self::sanitizeHeader(implode(',', $tags));
}
if (!empty($clickUrl)) {
$headers[] = 'Click: '.self::sanitizeHeader($clickUrl);
}
if (!empty($auth)) {
$headers[] = 'Authorization: '.$auth;
}
if (!function_exists('curl_init')) {
dol_syslog('MahnungNtfy: cURL nicht verfügbar', LOG_WARNING);
return false;
}
$ch = curl_init($endpoint);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $message);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($httpCode >= 200 && $httpCode < 300) {
return true;
}
dol_syslog('MahnungNtfy: Push fehlgeschlagen ('.$httpCode.') '.$error, LOG_WARNING);
return false;
}
/**
* Header-Werte müssen Single-Line sein. Newlines + Steuerzeichen entfernen.
*
* @param string $value
* @return string
*/
private static function sanitizeHeader($value)
{
return trim(preg_replace('/[\r\n\x00-\x1F\x7F]/', ' ', (string) $value));
}
}