Signalbot
Signalbot | |
---|---|
Zweck / Funktion | |
Senden und Empfangen von Nachrichten (Text und Fotos) mit dem freien Messenger Signal | |
Allgemein | |
Typ | Inoffiziell |
Details | |
Dokumentation | Thema |
Support (Forum) | Codeschnipsel |
Modulname | 50_Signalbot.pm |
Ersteller | Adimarantis (Forum /Wiki) |
Wichtig: sofern vorhanden, gilt im Zweifel immer die (englische) Beschreibung in der commandref! |
Das Modul Signalbot ermöglicht den Versand von Nachrichten über den Instant-Messaging-Dienst Signal aus FHEM heraus.
Beschreibung
Beschreibung in Kurzform:
Signalbot stellt eine Schnittstelle von FHEM zum Signal Messenger unter Linux zur Verfügung. Dazu wird das Tool signal-cli im DBus-Daemon Modus verwendet, welches dann letztendlich mit Signal kommuniziert.
Da sich signal-cli noch in der Entwicklung befindet (aktuelle Version 0.7.4) steht leider noch nicht die volle Funktionalität über DBus zur Verfügung, wodurch sich auch Einschränkungen für FHEM ergeben.
Aktuell unterstütze Funktionen aus FHEM:
- Senden und Empfangen von Nachrichten an Gruppen oder Einzelempfänger
- Versenden von einem oder mehreren Attachments (Bilder)
- Einlesen, Speichern und Übersetzen von Gruppennamen (statt base64 Strings)
- Setzen, Empfangen und Übersetzen von Kontaktnamen (statt Telefonnummern)
- Einschränken von Gruppen oder Kontakten auf die FHEM reagieren soll
- Direkte Verknüpfung mit dem Babble Modul zur Interpretation von Befehlen
Die Installation von signal-cli ist aktuell je nach Linux Kenntnissen durchaus anspruchsvoll. Daher gibt es ein Installationsscript welches aktuell für aktuelle Ubuntu und Raspian Distributionen getestet ist (höchstwahrscheinlich aber auch für andere Debian basierte Distributionen funktioniert)
Signalbot ist weitgehend kompatibel mit SiSi, verfolgt aber technisch ein paar andere Ansätze und stellt zusätzliche Funktionalitäten zur Verfügung:
- Signalbot erzeugt keinen eigenen Prozess sondern integriert sich voll in die laufende FHEM Instanz (ist dadurch hoffentlich stabiler und verbraucht auch weniger Speicher)
- Gruppen werden grundsätzlich mit ihren Klarnamen verwendet und können auch nur mit einem vorangestellten "#" (statt "@#") gekennzeichnet werden.
- Kontakte werden soweit möglich auch mit Klarnamen (statt +49....) unterstützt. Diese kommen aus dem internen Adressbuch und können über "setContact" definiert werden, bzw. kommen bei verlinkten Accounts aus dem Adressbuch des Hauptgeräts. Sie können aktuell leider nur über empfangene Nachrichten entschlüsselt werden, da signal-cli die entsprechende Schnittstelle (noch) nicht zur Verfügung stellt. Signalbot lernt diese aber mit der Zeit und kann sie bei Bedarf auch so abspeichern, dass sie auch nach einem FHEM Neustart wieder verfügbar sind
- Die Möglichkeit von Telegrambot in den "send" Befehl eingebetteten Code auszuführen und damit z.B. einen SVG Plot zu erstellen und mit zu verschicken ist verfügbar. Dazu muss der Befehl in runde Klammern eingebettet werden (Beispiele folgen unten).
- Wurde mit und für die aktuelle Version 0.7.4 von signal-cli entwickelt, die auch die neuen "V2" Gruppen unterstützt, ebenso wird die neuste Version (1.2.0) vom Perl Modul Net::DBus benötigt
- Wird aktuell (Jan 2021) noch gewartet (letztes Update für SiSi auf github ist aktuell von August 2018)
Funktionen im Detail
send [@<Recipient1> ... @<RecipientN>] [#<Group1> ... #<GroupN>] [&<Attachment1>; ... &<AttachmentN>] [<Text>]
- Recipient: Nummer mit Ländervorwahl (+49....) oder Kontaktname aus dem internen Adressbuch
- Group: Gruppenname, wie in Signal definiert im Klartext
- Attachment: Dateiname (Pfad für muss für fhem lesbar und absolut oder relativ zum fhem home sein) oder Stream einer Bilddatei (z.B.)SVG
- Text: Die eigentlich Textnachricht, kann Leerzeichen und Umbrüche (mit "\n" oder \0x0a) enthalten
- Sofern ein Recipient, Group oder Attachment Leerzeichen enthält, den ganzen Teilstring in Anführungszeichen setzen: z.B. "@Max Mustermann"
- Wenn ein FHEM Befehl ausgeführt werden soll, dann diesen in runde Klammern setzen z.B. &({plotAsPng('SVG_Aussentemperatur')})
Ein paar Beispiele
send @+498514711 Hallo Signal send #FHEM &/tmp/foto.jpg Ein Bild schicken send "@Mein Freund" Leerzeichen durch Anführungszeichen um den ganzen Teilbefehl send @Joerg #FHEM #Familie Jeder Empfänger, jede Gruppe und Attachments können mehrfach vorkommen send "@({my $var=\"Joerg\";; return $var;;})" Perl Code mit Leerzeichen ausführen send @(define dummy1 dummy) FHEM Befehl ausführen, wird aber nicht gesendet, da kein gültiger Empfänger zurück geliefert wird send @Joerg &({plotAsPng(\'SVG_Aussentemperatur\')}) Einen FHEM SVG Plot verschicken oder send @Joerg "&({plotAsPng('SVG_Aussentemperatur')})" Einen FHEM SVG Plot verschicken send @Joerg Mehrzeilige Ausgabe:\nNeue Zeile send @Joerg Die Aussentemperatur ist [out_temp:temperature] Grad
refreshGroups
Fragt die List der aktuellen Gruppen ab, denen der verknüpfte Account beigetreten ist. Die Liste wird im u.a. Reading joinedGroups sichtbar gemacht.
setContact <Number> <Contactname>
Definiert einen Kontakteintrag im internen Adressbuch. Es kann beim send Befehl dann der ContactName statt der Nummer verwendet werden.
saveContacts
Speichert die interne Kontaktliste in das Reading contactList welches beim Speichern der FHEM Config in fhem.save abgelegt wird und nach einem Neustart wieder zur Verfügung steht (zur Diskussion: immer automatisch so machen wenn neue Kontakte festgelegt werden?)
reinit
Verbindung zum DBus wiederherstellen. Dies sollte nicht nötig sein, außer der signal-cli Service funktionierte nicht richtig und wurde korrigiert. Ich rate hier aber eher zu einem FHEM Neustart.
Attribute im Detail
defaultPeer
Gruppe, Kontaktname oder Nummer an die send eine Nachricht schicken soll, wenn kein Empfänger mit @ oder # definiert wurde.
allowedPeer
Komma getrennte Liste von Gruppen, Kontaktnamen oder Nummern auf die Signalbot reagieren soll (also bei empfangenen Nachrichten Readings aktualisiert). Ist dieses Attribut nicht gesetzt, reagiert Signalbot auf alle Nachrichten.
babblePeer
Komma getrennte Liste von Gruppen, Kontaktnamen oder Nummern auf die Signalbot reagieren soll indem es die Nachricht an das über babbleDev (nicht zu verwechseln mit babbleDevice) definierte Babble Modul schickt. Die Nachrichten werden zuerst (beschränkt auf allowedPeer) normal verarbeitet (also Readings aktualisiert) und nur nach Babble gesendet wenn diese Attribut gesetzt ist.
Der Absender der Nachricht (Gruppe hat Prio über individuellem Absender) wird Babble als $PARM0 übergeben. Dazu in Babble noch das Attribut helpFunc wie folgt setzen
{fhem("set SignalBot send \@$PARM0 $HELP")}
Sollen die rivescript Spracherweiterungen genutzt werden muss außerdem "noChatbot" auf 0 stehen.
Nach dem selben Prinzip können in der Babble Definition auch Antworten spezfisch für Devices angelegt werden, z.B. als Aktion für out-temp -> Temperatur -> draußen -> sagen -> Status:
set SignalBot send @$PARM0 Die Temperatur draußen ist [out_temp:temperature] Grad
Womit die Frage (ohne Fragezeichen!) "Wie ist die Temperatur draußen" entsprechend quittiert wird.
babbleDev
Name des definierten Babble Device.Wird beim Setzen vom babblePeer automatisch mit der ersten "Babble" Device gefüllt sofern vorhanden.
Readings im Detail
contactList | Liste der gespeicherten Kontakt im Format Nummer1=Kontakt1,Nummer2=Kontakt2,... |
joinedGroups | Liste der beigetretenen Gruppen getrennt mit Leerzeichen |
msgAttachment | Attachments (Dateinamen im signal-cli repository) der zuletzt empfangenen Attachments |
msgGroupName | Gruppenname aus der zuletzt eine Nachricht empfangen wurde - leer wenn es eine persönlich Nachricht war |
msgSender | Absender der letzten Nachricht als Nummer oder wenn bekannt als Name |
msgText | Empfangenen Nachricht |
msgTimestamp | Zeitstempel der Nachricht |
prevMsgAttachment | Wie oben, nur enthalten diese Readings die Daten der zuvor empfangenen Nachricht (n-1) |
prevMsgGroupName | |
prevMsgSender | |
prevMsgText | |
prevMsgTimestamp | |
sentMsg | Zuletzt gesendete Nachricht |
sentMsgRecipient | Empfänger der zuletzt gesendeten Nachricht. Enthält zumeist den Namen aus der Empfangsbestätigung und somit bei vielen Empfängern den zuletzt bestätigten Empfang.
Dies muss nicht zwingend auf die zuletzt gesendete Nachricht (sendMsg) passen, wenn mehrere Nachrichten versendet wurden. |
sentMsgTimestamp | Zeitstempel des Empfangs oder "pending" wenn noch keine Bestätigung vorliegt |
Installation
Zur Installation steht das Script "signal_install.sh" zur Verfügung. Dieses befindet sich noch in der Entwicklung und funktioniert nicht zwangsweise in jeder Umgebung. Daher erst einmal ein paar Referenzen zur manuellen Installation von signal-cli :
- Die Wikiseite des Vorgängermoduls SiSi welches grundsätzlich die selben Anforderungen hat
- Quickstart (englisch) für signal-cli
- Anleitung zum "linken" einer Nummer mit signal-cli
- Anleitung zum Übersetzen und Installieren der Libraries für armv7 (Raspberry) da die Distribution nur x86 libraries enthält
- CPAN Seite des Perl Moduls zur DBus Kommunikation
Das Modul und Install Script wird aktuell nicht über "fhem update" verbreitet und muss vom ersten Post der Forum Threads geholt werden.
Vorbereitung:
Modul 50_Signalbot.pm wie üblich ins Verzeichnis "FHEM" der FHEM Installation kopieren.
Das Script "signal_install.sh" ins home Verzeichnis eines beliebigen "sudo"-fähigen Users kopieren.
Am Anfang des Moduls sind einige Informationen und Pfade definiert. Mindestvorrausetzung ist eine Telefonnummer. Es kann eine Festnetznummer oder Mobilfunknummer verwendet werden. Wird Signal schon am Handy benutzt lässt sich die Nummer verknüpfen, was aber den unangenehmen Nebeneffekt hat, dass man dort alle FHEM Nachrichten mitbekommt.
Kontrolliert also bitte vor dem Start des Scripts diese Angaben. Außer bei PHONE=+49xxxxx sollte aber üblicherweise keine Änderung nötig sein.
Das Script hat mehrere Optionen um Teilfunktionen direkt auszuführen, diese sind:
Argument | Bedeutung |
---|---|
system | System für die signal-cli Installation vorbereiten. Es werden per "apt install" fehlende Pakete installiert und Verzeichnisse erstellt.
Muss mindestens einmal erfolgreich gelaufen sein, damit die restliche Installation funktioniert |
install | Installiert signal-cli als System Service. Automatischer Download, Installation und Konfiguration (dbus, systemd) |
register | Registriert die definierte Telefonnummer bei Signal. Dieser Prozess hat seine Tücken und wird unten nochmal eingehend beschrieben |
link | Verknüpfen einer bestehenden Telefonnummer. Dazu muss in Signal über Settings -> Linked Devices -> "plus" ein QR Code abfotografiert werden.
Dieser wird von dieser Routine als Datei in /tmp/qrcode.png abgelegt. D.h. vorher sicherstellen, dass man mit einem Bildbetrachter an diese Datei kommt |
test | Versendet eine Testnachricht auf zwei Arten - direkt mit dem Client (klappt das, ist die Grundregistrierung schon mal erfolgreich) und über Dbus (dann ist auch der System Service korrekt eingerichtet) |
remove | Löscht alle durch "install" installierten Verzeichnisse und Dateien (aber nicht die Pakete die durch "system" installiert wurden) |
join | Ermöglicht einer Gruppe mithilfe eines Einladungslinks beizutreten |
name | Definieren des eigenen Namens und Avatar Bildes |
start | Starten des singal service über systemd bzw. im Container des Dbus daemon and signal-cli Daemon |
Das Script muss unter root Rechten, also mit
sudo ./signal_install.sh
aufgerufen werden. Wenn kein Argument übergeben wird, dann wird automatisch der Ablauf system -> install -> register -> test durchlaufen.
Das Script fragt üblicherweise nach wenn es etwas tut und führt nur notwendige Aktionen durch (kann also bei teilweisen Fehlern problemlos erneut durchlaufen werden).
Es prüft außerdem ab ob es im Container läuft (hier erfolgt ein etwas anderer Ablauf - mehr dazu unten) und prüft auf Betriebssystem und CPU Architektur. Gegebenenfalls bricht es ab, wenn es sich um keine unterstützte Kombination handelt.
Bitte genau auf die Bildschirmausgaben und Fragen achten. Fehlermeldungen im Thread melden damit das Script weiter verbessert werden kann.
Registrierung
Hinweis: Es kann nur eine Nummer registriert sein. Eine bereits bestehende Registrierung (Smartphone) wird dabei aufgehoben. Daher entweder eine Festnetznummer verwenden oder das Script hier abbrechen und mit der Option "link" neu starten, dann wird FHEM als Zweitbenutzer zu einer bestehenden Nummer hinzugefügt. Todo: Beschreibung im Wiki (aktuell bitte Anweisungen im Script folgen),.
Wenn die Systeminstallation erfolgreich abgeschlossen ist, folgt die Registrierung der Nummer. Hier gibt es zwei Optionen:
SMS oder Voice.
Je nachdem wird ein 6-stelliger Aktivierungscode per SMS geschickt oder über einen Telefonanruf (sogar auf Deutsch) diktiert.
Captcha
Signal versucht sich gegen unberechtigte Nutzung des Service (man könnte ja damit quasi SMS/Telefonterror betreiben) zu schützen. Nach gewissen Kriterien (soweit bekannt z.B. Registrierung aus einer VM oder über VPN) wird daher ein Captcha verlangt.
Nur wie funktioniert sowas in der Kommandozeile?
Das Script erkennt diese Abfrage und fragt nach einem Captcha Code. Diesen erlangt man wie folgt:
- Captcha Seite von Signal aufrufen. Dabei ist es wahrscheinlich unerheblich von wo (hab es erfolgreich aus meinem Windows Host gemacht und in meinen Linux VM Guest eingetragen) - schätzungsweise ist es einfach zeitlich begrenzt gültig.
- Im Developermode (F12) und nach erfolgreichem Lösen des Captchas (wenn der Bildschirm leer bleibt, ist es auch erfolgreich gelöst) macht der Browser ein redirect auf signalcaptcha://. Das versteht der Browser aber nicht und macht gar nichts.
- Der String steht aber bei Firefox in der Console (recht einfach zu finden), beim Chrome muss man auf Network gehen, mit Ctrl+R refreshen und dann in der Spalte "Name" nach einem kryptischen String suchen. Das dieser mit signalcaptcha anfängt sieht man erst im Tooltip da der Anfang abgeschnitten wird.
- Diesen String (ohne signalcaptcha://) dann in die Eingabezeile des Scripts einfügen und Return drücken. Jetzt sollte die Registrierung erfolgreich abschließen.
Anbei Screenshots von Firefox und Chrome zum besseren Verständnis.
Unterstützung gesucht: Das Holen des Captchas ist ziemlich umständlich. Suche jemanden der sich mit z.B. mit der Erstellung von Protokoll plugins in Chrome (Abfangen von signalcaptcha:// und Darstellen des Texts in einem Fenster - evtl. mit "Copy" Button) auskennt - oder vielleicht geht sowas ja auch als FHEM Modul?
Einrichtung des Moduls
Siehe Forenthema Neues Modul: Signalbot.
Nachdem alles sauber eingerichtet ist und das Modul im FHEM Directory abgelegt wurde, entweder ein "reload 50_Signalbot" oder besser ein "shutdown restart" von FHEM machen.
Das Modul dann einfach mit
define <name> Signalbot
definiert.
Weitere Attribute sind optional (siehe oben)
Installation im Docker Container
Das Install Script kann auch in einem FHEM Container ausgeführt werden. Diese Funktion ist noch in der Entwicklungsphase (siehe Foren Thread).
Dazu eine interaktive root Shell öffnen und das Script in den Container kopieren (z.B. mit scp).
Dann wie oben beschrieben das Script als root starten.
Im Container wird die Installation des systemd Service ausgelassen und am Anfang ein zusätzliches apt-get update/upgrade ausgeführt (was insbesondere bei einem neuen Container notwendig sein kann).
Sowohl der Dbus daemon und der signal-cli daemon werden vom Script am Ende im Hintergrund gestartet. Dabei wird insbesondere gewartet bis der signal-cli Prozess läuft bevor die Tests durchlaufen werden (das hat in meiner VM durchaus schon mal eine Minute gedauert).
Um Sicherzustellen das die beiden Daemons laufen sollte in den Container Startup ein Aufruf des Scripts mit dem Argument "start".
Dies prüft ob die Daemons laufen und startet die ggf. nach.
Hier noch mein verwendetes docker-compose.yml
version: '2'
services:
fhem:
build: .
restart: always
stdin_open: true
tty: true
ports:
- "8083:8083"
- "7072:7072"
volumes:
- ./fhem/core/:/opt/fhem/
networks:
- fhem-network
#devices:
# - "/dev/ttyUSB0:/dev/ttyUSB0"
environment:
FHEM_UID: 1000
FHEM_GID: 1000
TIMEOUT: 10
RESTART: 1
TELNETPORT: 7072
TZ: Europe/Berlin
networks:
fhem-network:
driver: bridge
Und mein Dockerfile
ARG BASE_IMAGE="fhem/fhem"
ARG BASE_IMAGE_TAG="latest"
FROM ${BASE_IMAGE}:${BASE_IMAGE_TAG}
ARG L_SIGNAL_CLI="0.7.4"
# Install base environment
VOLUME [ "/opt/signal-cli" ]
Im Unterverzeichnis fhem/core liegt das ausgepackte fhem.tar.gz (da kann man auch gleich das Install Script und Signalbot installieren)
Dann mit
docker-compose up -d docker exec -ti fhem-docker_fhem_1 /bin/bash
das Dockerimage erzeugen und root shell starten. Jetzt wird
./signal-install.sh
ausgeführt.
Dann sollte man zum fhem user wechseln und fhem starten können
su - fhem cd /opt/fhem perl fhem.pl fhem.cfg
Das aber noch ohne Gewähr und nur rudimentär getestet. Verbesserungsvorschläge, insbesondere wie man gleich alles in die Config Files einbaut willkommen.
Troubleshooting / FAQ
Anmerkung: Ich gehe hier davon aus, das die Installation mit dem im Script voreingestellten Pfaden/Users durchgeführt wurde. Änderungen auf eigene Gefahr.
Bevor ich hier ein paar typische Probleme und Lösungen aus dem Foren Thread aufliste, bitte folgende Punkte sicherstellen:
- Ich verwende eine unterstütztes Betriebssystem (Raspbian oder Ubuntu) und CPU Architektur (armv7l oder x86)
- Ich habe das neuste Install Script aus dem ersten Post des Foren Threads verwendet
- Ich habe vor der Installation nach besten Wissen und Gewissen Reste einer vorherigen Installation (z.B. auch für SiSi) entfernt (das Repository kann weggesichert werden um eine erneute Registrierung zu vermeiden und dann statt dem Registrierungsschritt in /var/lib/signal-cli kopiert werden
- Ich habe das Install Script gemäß Anleitung vollständig durchlaufen lassen und auf Fehlermeldungen geachtet
Wo finde ich Fehlermeldungen/Logfiles?
- Beim Install Script direkt in der Console - achte auf die Bildschirmausgabe
- Beim Install Script auch in /tmp/signal_install.log - ggf. wegsichern da es bei jedem Durchlauf wieder überschrieben wird.
- Fehler beim Starten und Betrieb des signal-cli service (normale Installation) in /var/log/syslog
- Fehler beim Betrieb in FHEM im normalen FHEM log (ggf. Signalbot mit verbose=5 definieren)
- Im Container, sofern die Daemons mit dem Install Script gestartet wurden, schreiben ihr log in /var/log/dbus.log bzw. signal.log und die Fehlerausgabe in /var/log/dbus.err bzw. signal.err
Probleme bei normaler Installation
Fehler | Lösungsansatz |
---|---|
In FHEM:
Error sending message:org.asamk.Signal.Error.Failure: org.whispersystems.signalservice.api.push.exceptions.NotFoundException: Not found |
signal-cli läuft nicht.
Prüfe ggf. /var/log/syslog für weitere Fehlermeldungen. Führe sudo service signal start aus. |
Bei Starten von signal-cli:
OpenJDK Server VM warning: You have loaded library /tmp/resource17792002454964883349.so which might have disabled stack guard. The VM will try to fix the stack guard now. It's highly recommended that you fix the library with 'execstack -c <libfile>', or link it with '-z noexecstack'. |
Passiert üblicherweise auf dem Raspberry pi. Die Standard Distribution von signal-cli enthält eine x86 library libzkgroup.so die mit armv7l nicht kompatibel ist, welche im jar zkgroup-java-0.7.0.jar enthalten. Da Install Script entfernt diese und legt eine armb7l library nach /usr/lib.
Irgendwo auf dem System vorhandene alte Version können aber versehentlich erwischt werden. Tests:
|
Bei Starten von signal-cli:
Support for new group V2 is disabled, because the required native library dependency is missing: libzkgroup |
Kommt diese Meldung ohne die vorhergehende, dann fehlt die libzkgroup.so komplett. Am Besten den Ordner /opt/signal komplett löschen und mit
sudo ./signal_install.sh install eine Neuinstallation vornehmen (Konfiguration bleibt dabei erhalten) Und/Oder wie oben die Installation der lib.so prüfen. Prüfen ob die lib.so vom system verwendet werden kann: sudo ldconfig -v | grep libzkgroup.so Wenn kein Ergebnis, dann stimmt die Installation der lib.so nicht |
Ich kann an Einzelempfänger senden und empfangen, aber nicht an Gruppen versenden | Du hast wahrscheinlich den vorhergehenden Fehler (libzkgroup) irgendwo, aber er ist dir nicht aufgefallen. Vorgehensweise wie oben. |
Probleme bei Installation im Container
Fehler | Lösungsansatz |
---|---|
org.freedesktop.DBus.Error.Spawn.FileInvalid: Cannot do system-bus activation with no user | Prüfe Datei /usr/share/dbus-1/system-services/org.asamk.Signal.service ob es einen Eintrag
User=signal-cli gibt |
Signal: Error while initializing Dbus:org.freedesktop.DBus.Error.Disconnected: Connection is closed | DBus daemon oder signal-cli daemon laufen nicht. Mit dem Installscript als root
./signal_install.sh start nachstarten. |
Links
- Thread Neues Modul: Signalbot