Files
adminandClaude Opus 5 df48432133 Benachrichtigungen: Geraet, Abos und der Reiter Meldungen
Der Geraetesuchlauf legt "Benachrichtigungen" an (benachrichtigung_module.py),
ein Kommando je Kanal. Damit kann jede Automatik melden, ohne dass Editor,
Zeitleiste oder Datenbank etwas davon wissen muessten.

Fuer die Meldung aufs Handy braucht es keine App: Der Browser meldet sich
unter Einstellungen -> Meldungen selbst an (sw.js, ajax/push.php), das Abo
steht in homeMesh.push_abos, verschickt wird vom Runner. Auf dem iPhone geht
es erst ab der Ablage auf dem Home-Bildschirm - der Reiter sagt das auch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 08:37:31 +02:00

77 lines
2.7 KiB
PHP

<?php
/**
* Web-Push-Abos: anmelden, abmelden, auflisten, Probe schicken.
*
* GET ?action=stand {schluessel, abos: [...]}
* POST ?action=anmelden {"abo": {endpoint, keys:{p256dh, auth}}, "name": "..."}
* POST ?action=abmelden {"endpoint": "..."} - dieses Gerät
* POST ?action=entfernen {"id": 3} - ein anderes Gerät
* POST ?action=probe {"titel": "...", "text": "..."}
*
* Verschickt wird nirgends hier: Das macht der Runner auf der NAS, der die
* Verschlüsselung und den privaten Schlüssel hat. Die Probe geht deshalb als
* MQTT-Nachricht an ihn - denselben Weg nimmt auch eine Automatik.
*/
require_once("../helper.php");
require_once("../restricted/push.php");
header("Content-Type: application/json; charset=utf-8");
if (!checkLogin()) {
http_response_code(403);
echo json_encode(["error" => "Nicht angemeldet."]);
exit;
}
function pushAntwort($daten, $code = 200)
{
http_response_code($code);
echo json_encode($daten, JSON_UNESCAPED_UNICODE);
exit;
}
$action = $_GET["action"] ?? "stand";
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$body = json_decode(file_get_contents("php://input"), true);
if (!is_array($body)) {
pushAntwort(["error" => "Konnte die Anfrage nicht lesen."], 400);
}
try {
switch ($action) {
case "anmelden":
pushAboSpeichern($body["abo"] ?? [], $body["name"] ?? "",
$_SERVER["HTTP_USER_AGENT"] ?? "");
pushAntwort(["ok" => true, "abos" => pushAbos()]);
case "abmelden":
$weg = pushAboEntfernenNachEndpoint(strval($body["endpoint"] ?? ""));
pushAntwort(["ok" => true, "entfernt" => $weg, "abos" => pushAbos()]);
case "entfernen":
$weg = pushAboEntfernen($body["id"] ?? 0);
pushAntwort(["ok" => true, "entfernt" => $weg, "abos" => pushAbos()]);
case "probe":
$titel = trim(strval($body["titel"] ?? "")) ?: "Probe";
$text = trim(strval($body["text"] ?? "")) ?: "Wenn das ankommt, stimmt der Weg.";
pushProbe($titel, $text);
pushAntwort(["ok" => true]);
}
pushAntwort(["error" => "Unbekannte Aktion."], 400);
} catch (InvalidArgumentException $e) {
pushAntwort(["error" => $e->getMessage()], 400);
} catch (Throwable $e) {
pushAntwort(["error" => $e->getMessage()], 500);
}
}
if ($action === "stand") {
pushAntwort([
"schluessel" => pushSchluessel(),
"abos" => pushAbos(),
]);
}
pushAntwort(["error" => "Unbekannte Aktion."], 400);