Signal Nachrichten per API versenden: signal-cli-rest-api
Der bekannte Signal Messenger kann nicht nur über dessen App, sondern auch über die Befehlszeile oder von anderen Systemen verwendet werden. Eine einfache Möglichkeit dafür bietet die signal-cli-rest-api, welche in Form eines Docker-Containers zur Verfügung steht. Damit die API funktioniert, muss diese zuvor über die Signal-App gekoppelt werden.
Profil Docker Basics
Ein Container ist eine vom Betriebssystem (OS) unabhängige isolierte Umgebung:
Beim ersten Start eines Containers, lädt Docker selbstständig alle notwendigen Quellen
aus dem Internet.
Docker kann unter Windows, macOS oder einer Linux-Distribution installiert werden,
siehe auch: Docker
Software | Signal-cli-rest-api |
---|---|
GitHub | https://github.com/bbernhard/signal-cli-rest-api |
aktuelle Version | 0.89 |
gefunden | 08.10.2024 |
Wer Docker auf seinem System installiert hat, kann die API mit folgendem Befehl starten:
docker run -d --name signal-api --restart=always -p 8080:8080 \
-v $HOME/.local/share/signal-cli:/home/.local/share/signal-cli \
-e 'MODE=native' bbernhard/signal-cli-rest-api
Für das Einbinden der API in einem anderen Projekt oder für das Dokumentieren der Parameter bietet sich der Einsatz einer docker-compose.yml - Datei an:
version: "3"
services:
signal:
container_name: signal-api
image: bbernhard/signal-cli-rest-api:latest
restart: always
ports:
- "8080:8080"
environment:
MODE: 'normal'
volumes:
- "./signal:/home/.local/share/signal-cli"
Nachdem der Inhalt in eine Datei gespeichert oder zu einer anderen Docker-Compose-Datei hinzugefügt wurde, kann der Container mit "docker compose up -d" gestartet werden.
Signal-App verbinden
Der Container erzeugt einen QR-Code über welchen die Signal-App gekoppelt werden kann. Der Aufruf erfolgt über den Browser: http://localhost:8080/v1/qrcodelink?device_name=signal-api
In der Signal-App, am Smartphone, kann die API unter Einstellungen und "Gekoppelte Geräte" mit "+" gekoppelt werden:
Signal-Nachricht senden
Die API ermöglicht das Versenden und Abrufen von Nachrichten über eine POST-Anfrage:
Signal-Nachricht aus dem Terminal versenden (curl)
Folgender Terminal-Befehl kann nach dem Koppeln eine Signal-Nachricht an eine oder mehrere Telefonnummern senden:
curl -X POST -H "Content-Type: application/json" 'http://localhost:8080/v2/send' \
-d '{"message": "Test via Signal API!", "number": "+4412345", "recipients": [ "+44987654" ]}'
Der Parameter "number" steht für die Telefonnummer des Absenders, also für die eigene Nummer. Als Ziel: "recipients" können die eigene oder eine oder mehrere andere Telefonnummern verwendet werden. Neben dem Terminal ist es auch möglich die API von bestimmten Systemen direkt zu verwenden, als Beispiel aus Home Assistant.
Home-Assistant - Benachrichtigung
Vorhab sollte kurz erwähnt werden, dass Home Assistant mit dessen offizieller App bereits eine Möglichkeit für Benachrichtigungen bietet, siehe: Home-Assistant Docker Conbee 2 und Zigbee2MQTT / deCONZ. Signal habe ich, wie hier beschrieben, als eine Alternative getestet. Nachdem ich für Home Assistant auch Docker und eine docker-compose-Datei verwende, habe ich die zuvor erwähnten Zeilen zur docker-compose.yml-Datei von Home-Assistant hinzugefügt.
In Home Assistant bzw. in dessen Konfiguration können vorab verschiedene Profile für verschiedene Telefonnummern angelegt werden: Als Beispiel habe ich ein Profil mit dem Namen "signal" zur Home Assistant - Konfiguration hinzugefügt. Hier die zusätzlichen Zeilen der configuration.yaml - Datei:
...
notify:
- name: signal
platform: signal_messenger
url: "http://signal-api:8080"
number: "+44987654" # the sender
recipients:
- "+44987654"
...
Die Parameter "number" und "recipients" spiegeln erneut die Absender und Empfänger-Telefonnummern wider. Die URL enthält den Namen der Signal-API, laut dem Beispiel: "signal-api"
Das Benachrichtigungsprofil kann dann zum Beispiel in einer Automatisierung verwendet werden:
service: notify.signal
data:
message: >-
Temperatur: {{states('sensor.keller_temperature')}}°C
Luftfeuchtigkeit:{{states('sensor.keller_humidity')}}%
Uptime Kuma - Benachrichtigung
Wer bestimmte Services mit Uptime Kuma überwacht, kann sich auch daraus über Signal benachrichtigen lassen:
Siehe: Webseiten überwachen mit Uptime Kuma.
Signal-Nachrichten aus Grafana: nur über einen Umweg
Grafana bietet Out-of-the-box keine Unterstützung für die Signal-API, siehe: github.com/grafana/grafana/issues/14952. Zudem können die übermittelten Parameter bei Verwendung der Webhook-Benachrichtigung nicht vorgegeben werden, wodurch ein direktes Ansprechen der Signal-api nicht funktioniert. Nachdem ich für Gitea einen einfachen Docker-Container für das Empfangen von Webhooks verwende, kam mir die Idee die Nachrichten aus Grafana an den webhookd-Container zu schicken und dann automatisch mittels curl an die Signal-api weiterzuleiten. Siehe auch: Docker WebHook Daemon: einfacher Hook-Server für Bash-Scripts.
Für das Setup habe ich zu "signal" zusätzlich den "webhookd" -Service hinzugefügt. Hier die zusätzlichen Zeilen für die docker-compose.yml - Datei:
...
signal:
container_name: signal-api
image: bbernhard/signal-cli-rest-api:latest
restart: always
ports:
- "8080:8080"
environment:
MODE: 'normal'
volumes:
- "./signal:/home/.local/share/signal-cli"
webhookd:
hostname: webhookd
image: ncarlier/webhookd:edge-distrib
container_name: webhookd
restart: always
volumes:
- ./webhookd:/scripts
- ./webhookd_tmp:/tmp
environment:
WHD_LISTEN_ADDR: ":80"
WHD_SCRIPTS: /scripts
WHD_HOOK_TIMEOUT: '600'
...
Das Versenden erfolgt auch hier mit curl. Als Basis habe ich ein Beispiel-Bash-Skript angepasst und den Inhalt im Scripts-Ordner mit dem Namen signal.sh abgespeichert:
Inhalt signal.sh-Datei:
#!/bin/sh
# Validate parameters
payload=$1
payload="$(echo "$payload"|tr -d '\n')"
[ -z "$payload" ] && die "missing request payload"
payload_type=$(echo $payload | jq type -r)
[ $? != 0 ] && die "bad body format: expecting JSON"
[ ! $payload_type = "object" ] && die "bad body format: expecting JSON object but having $payload_type"
#extract message:
message=$(echo $payload | jq .message -r)
#send to signal_api
curl -X POST -H "Content-Type: application/json" "http://signal-api:8080/v2/send" -d "{\"message\": \"$message\", \"number\": \"+4398765\", \"recipients\": [\"+43664601911517\"]}"
Die letzte Zeile im Bash-Skript entspricht dem zuvor erwähnten curl-Aufruf.
Damit das Bash-Script gestartet werden kann, habe ich das Ausführen mit chmod +x erlaubt:
chmod +x . signal.sh
In Grafana reicht jetzt ein neuer "Update contact point" mit der URL http://webhookd/signal. "webhookd" ist dabei der Name des webhookd-Containers und "signal" der Name der Bash-Datei ohne .sh
Die Funktion der Bash-Datei beschränkt sich aktuell darauf, dass die übermittelte Nachricht (Message) übertragen wird, was den Einsatz von Templates und Variablen für die Nachricht in Grafana ermöglicht.
Fazit
Die "signal-cli-rest-api" kann relativ einfach aus anderen Systemen mittels POST-Aufruf angesprochen werden. Als Beispiel liefert Home Assistant oder Uptime Kuma eine direkte Unterstützung für die API. Sollte ein System die API offiziell nicht unterstützen, kann die API möglicherweise über den erwähnten Webhook-Daemon verwendet werden, siehe: Docker WebHook Daemon: einfacher Hook-Server für Bash-Scripts.
{{percentage}} % positiv