Gotify: Schicke dir selbst Nachrichten aufs Handy!

Selbst im kleinsten Homelab darf ein Benachrichtigungsserver nicht fehlen. Daher möchte ich dir heute den Docker-Container Gotify samt seiner praktischen App für mobile Geräte vorstellen. Und eines gleich vorweg: Gotify ist so flexibel gestaltet worden, dass du sogar mit einfachen Shell-Skripten eigene Pushmessages von deinen Anwendungen verschicken kannst.

Und da programmieren nicht jedermanns Sache ist, habe ich den Beitrag extra um ein kleines Bash-Skript für die Gotify-API erweitert. So kann ich dir nämlich kurz und knapp zeigen, wie man in Shell-Skripten mit REST-APIs redet. Außerdem bekommst du noch eine Docker-Compose-Datei, damit du direkt loslegen kannst. Beginnen möchte ich den Artikel aber mit einer kurzen Vorstellung von Gotify.

Was kann Gotify alle so?

YouTube

Mit dem Laden des Videos akzeptieren Sie die Datenschutzerklärung von YouTube.
Mehr erfahren

Video laden

© Raspberry Pi Cloud – Dennis Schröder

Nicht besonders viel, wenn man ehrlich ist. Die Anwendung macht es dir einfach möglich, Push-Messages auf dem Handy oder im Browser deines Desktop-PCs zu erhalten. Damit diese Benachrichtigungen auch wirklich in Echtzeit bei dir ankommen, greift Gotify auf eine bidirektionale Web-Socket-Verbindung zurück. Das finde ich besonders spannend.

Darüber hinaus verfügt die Anwendung noch über ein intuitives Web-Interface zum Management der Nutzer, Clients und Nachrichtenkanäle. Auch ein eigenes Kommandozeilenprogramm kann man bei Bedarf noch auf Linux-Servern installiert werden. Alles in einem ist Gotify ein simpler, aber absolut zuverlässiger Benachrichtigungsserver samt App.

Der kleine Container erledigt bei mir seinen Job tadellos und das seit inzwischen fast 2 Monaten. Wissen sollte man aber noch, dass man die Batterieoptimierung für die Smartphone-App deaktivieren sollte. Ansonsten wird die stete Web-Socket-Verbindung zum Server und dessen REST-API gerne mal getrennt. Ein Bug ist das aber nicht, sondern ein Feature der Akkuverbrauch-Optimierung von Android.

Docker-Compose.yml für Gotify:

Ich lege für jedes neue Docker-Deployment einen eigenen Ordner auf dem Hostsystem an. Darin enthalten ist die Docker-Compose-Datei und alle persistenten Daten des Containers werden ebenfalls in einem Unterordner darin gespeichert. Docker selbst lässt sich je nach Betriebssystem entweder per offiziellen Skript oder Paketverwaltung installieren.

Darauf eingehen möchte ich an dieser Stelle aber nicht weiter. Viel mehr möchte ich noch ein paar Punkte zum Code sagen. Hier wird nämlich der Port 8090 des Docker-Hosts via HTTP exposed. Falls du die Kommunikation hingegen verschlüsselt haben möchtest, muss der Code noch um die SSL-Environment-Variablen erweitert werden. Mehr dazu, erfährst du in der offiziellen Doku.

Die folgenden Zeilen kannst du einfach via Copy & Paste verwenden:

version: "3"

services:
  app:
    image: gotify/server
    container_name: gotify
    restart: always
    ports:
      - 8090:80
    environment:
      - TZ=Europe/Berlin
      - GOTIFY_REGISTRATION=false
    volumes:
      - ./data:/app/data

Wie man ein Skript für Gotify schreibt:

Ich selbst bin kein besonders versierter Programmierer und so war ich der Meinung, dass es recht schwer sein müsste, erfolgreich eine Nachricht an eine REST-API zu übermitteln. Dem ist aber gar nicht so. Im Prinzip reicht dafür sogar eine einzelne Zeile Code mit dem Kommandozeilen-Programm curl:

 curl "https://dein-gotify-server.de/message?token=eiEIei" -F "title=Überschrift" -F "message=News" -F "priority=8"

Natürlich möchte man in der Praxis noch prüfen, ob die Übertragung tatsächlich stattgefunden hat. Dafür muss man den Statuscode der REST-API bei der Datenübermittlung abgreifen und anschließend auswerten. Hierbei gilt, dass eine 200 das Ziel der Bemühungen ist. Der Curl-Befehl aus dem obigen Beispiel muss daher noch etwas modifiziert werden:

curl --silent --output /dev/null -w "%{http_code}" -X POST \
  	"https://dein-gotify-server.de/message?token=eiEIei" \
  	-F "title=Überschrift" -F "message=News" -F "priority=8"	

Nun erhalten wir als Standardausgabe den Statuscode der API zurück. Auswerten lässt sich das Ganze jetzt anhand von ein paar gezielten Anweisungen, wie mit den unterschiedlichen Rückgabewerten umgegangen werden soll. Das kann man in Bash ganz einfach mit einer If- oder Case-Anweisung erledigen. Und wie das Ganze in der Praxis ausschaut, soll das folgende Code-Beispiel vermitteln:

#!/bin/bash

# Variablen

# Priorität der Nachricht:
priority='8'

# Zeige alle Updates an:
apt_updates=$(apt list --upgradable |& grep -Ev '^(Listing|WARNING|Auflistung)')

# Zeige an, wie viele Updates davon sofort installiert werden können. Es gibt ja auch noch zurückgehaltene Aktualisierungen.
apt_quantity_updates=$(/usr/lib/update-notifier/apt-check --human-readable |& grep -Ev '^(Zum|To)')

# Text der Nachricht:
pushmessage=$(echo -e "${apt_quantity_updates}${apt_updates}")

# Title der Nachricht, in diesem Fall der Hostname des Servers:
tile=$(hostname -s)

# Log-Ordner und Log-Verzeichnis:
logdirectory='/var/log/gotify'
logfile='/var/log/gotify/logfile.log'

# URL des Gotify-Dienstes inklusive des Tokens:
API='https://dein-gotify-server.de/message?token=eiEIei'

# HTTP Status Code der REST-API:
HTTP200="200"
HTTP400="400"
HTTP401="401"
HTTP403="403"
HTTP404="404"

# Prüfe, ob der Ordner für die Logs vorhanden ist und wenn nicht, dann erstelle ihn:
if [ ! -d $logdirectory ];

then

	mkdir $logdirectory

fi

# Prüfe, ob das Logfile bereits existiert und wenn nicht, dann lege es initial an:
if [ ! -e $logfile ];

then

	touch $logfile

fi

# Übermittle die Pushmessage nur, wenn es Updates gibt. Darin eingeschlossen sind auch zurückgehaltene! 
if [ -n "${apt_updates}"  ]; 

then

	# Curl Kommando an die Gotify-Api
	GETSTATUS(){
  	curl --silent --output /dev/null -w "%{http_code}" -X POST \
  	"$API" \
  	-F "title=${tile}" -F "message=${pushmessage}" -F "priority=${priority}"
 	}	

 	STATUSCHECK=$(GETSTATUS)

 	if [ "$STATUSCHECK" == "$HTTP200" ]; then

	echo "$(date "+%d-%m-%Y %H:%M:%S"): Die Pushmessage wurde erfolgreich übermittelt" | tee $logfile

 	elif [ "$STATUSCHECK" == "$HTTP400" ]; then

    	echo "$(date "+%d-%m-%Y %H:%M:%S"): Die Pushmessage wurde nicht erfolgreich übertragen. Der API-Fehlercode lautet: Bad Request" | tee $logfile

 	elif [ "$STATUSCHECK" == "$HTTP401" ]; then

    	echo "$(date "+%d-%m-%Y %H:%M:%S"): Die Pushmessage konnte nicht übermittelt werden. Der API-Fehlercode lautet: Unauthorized Error - Invalid Token" | tee $logfile
 	
        elif [ "$STATUSCHECK" == "$HTTP403" ]; then

    	echo "$(date "+%d-%m-%Y %H:%M:%S"): Die Pushmessage konnte nicht erfolgreich übergeben werden. Der API-Fehlercode lautet: Forbidden" | tee $lofile

 	elif [ "$STATUSCHECK" == "$HTTP404" ]; then

    	echo "$(date "+%d-%m-%Y %H:%M:%S"): Die Pushmessage konnte nicht übertragen werden. Der API-Fehlercode lautet: API URL Not Found" | tee $logfile
	fi

fi

Von Fabian Wüst

Er ist leidenschaftlicher Open-Source-Benutzer und ein begeisterter Technologie-Enthusiast. Als kreativer Kopf hinter Homelabtopia bringt Fabian hier seine umfangreiche Erfahrung als Linux-Admin ein. Um sicherzustellen, dass du aus seinen Beiträgen den größtmöglichen Nutzen ziehen kannst, führt er ausgiebige Tests durch und errichtet dafür immense Setups.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert