#!/bin/bash
# Alarm aufs Handy – so laut wie eine Warnmeldung: ntfy mit höchster Stufe (Priorität 5, „urgent“)
# LiSoftware · lisoftware.de/sicherheit · GPL-3.0
#
#   alarm-ntfy.sh "Tür am Serverschrank offen"          # Alarm mit Text
#   alarm-ntfy.sh --titel "Wächter" "Platte zu 95 % voll"
#   alarm-ntfy.sh --test                                  # Probealarm, um das Handy einzustellen
#
# Einstellungen in /etc/default/alarm-ntfy (Rechte 600, das Token ist geheim):
#   NTFY_URL=https://ntfy.example.org/alarm-7Hq2xV9kLm      # eigener ntfy-Server, Topic lang und zufällig
#   NTFY_TOKEN=tk_...                                       # Zugangstoken (ntfy token add …) – ohne Token kann jeder mitlesen
#   VERSUCHE=3                                              # nur wenn das Senden scheitert, z. B. ohne Netz am Server
#   ABSTAND=20                                              # Sekunden zwischen den Versuchen
# Gesendet wird genau ein Alarm: ntfy hält ihn, bis das Handy wieder Netz hat. Wer Nachdruck will, stellt in der App
# den Dauer-Alarm für die höchste Priorität ein.
#
# Am Handy (ntfy-App): Topic abonnieren, beim eigenen Server „Sofortige Zustellung“ (instant delivery) an. Android: für den Kanal „Höchste Priorität“
# „Nicht stören“ überschreiben erlauben und in den App-Einstellungen „Bei höchster Priorität dauerhaft alarmieren“
# einschalten. iPhone: ntfy in „Nicht stören“/Fokus als erlaubte App eintragen.
set -uo pipefail
[ -r /etc/default/alarm-ntfy ] && . /etc/default/alarm-ntfy
NTFY_URL=${NTFY_URL-""}
NTFY_TOKEN=${NTFY_TOKEN-""}
VERSUCHE=${VERSUCHE-3}
ABSTAND=${ABSTAND-20}

TITEL="Alarm $(hostname)"; TEXT=""
while [ $# -gt 0 ]; do
    case "$1" in
        --titel) shift; TITEL="${1:-$TITEL}" ;;
        --test) TITEL="Probealarm $(hostname)"; TEXT="Das ist nur ein Test. So klingt ein echter Alarm."; VERSUCHE=1 ;;
        -h|--help) sed -n '2,19p' "$0"; exit 0 ;;
        *) TEXT="$1" ;;
    esac
    shift
done
[ -n "$NTFY_URL" ] || { echo "NTFY_URL fehlt (in /etc/default/alarm-ntfy eintragen)"; exit 2; }
[ -n "$TEXT" ] || { echo "Kein Alarmtext (Hilfe: --help)"; exit 2; }
case "$NTFY_URL" in https://*) ;; *) echo "Bitte https:// verwenden, sonst kann jemand den Alarm unterwegs mitlesen oder fälschen"; exit 2 ;; esac

senden() {
    local titel="$TITEL"   # Umlaute im Header: als RFC-2047-Wort, das ntfy selbst dekodiert
    local LC_ALL=C; [[ "$titel" == *[![:print:]]* ]] && titel="=?UTF-8?B?$(printf '%s' "$TITEL" | base64 -w0)?="
    local kopf=(-H "Title: $titel" -H "Priority: urgent" -H "Tags: rotating_light,warning")
    [ -n "$NTFY_TOKEN" ] && kopf+=(-H "Authorization: Bearer $NTFY_TOKEN")
    curl -fsS -m 15 --retry 2 "${kopf[@]}" --data-binary "$TEXT" "$NTFY_URL" >/dev/null
}

gesendet=0
for ((i = 1; i <= VERSUCHE; i++)); do
    if senden; then gesendet=1; break; fi
    logger -t alarm-ntfy "Senden fehlgeschlagen (Versuch $i von $VERSUCHE)"
    [ "$i" -lt "$VERSUCHE" ] && sleep "$ABSTAND"
done
logger -t alarm-ntfy "$TITEL: $TEXT"
[ $gesendet = 1 ] || { echo "Alarm konnte nicht gesendet werden"; exit 1; }
