Bot mit Signal

Aus Debacher-Wiki
Wechseln zu:Navigation, Suche

Bisher fand ich es ganz praktisch jeden Tag über die Telegram API eine Nachricht über den aktuellen Zustand meiner Homematic zu bekommen. Für meine privaten Chats mag ich Telegram aber nicht nutzen. Nach dem Abschied von WhatsApp ist hier meine Wahl auf Wignal gefallen.

Nun liegt es nahe die Benachrichtigungsfunktion auch auf Signal zu übertragen. Signal selber bietet anscheinen keine direkte API wie Telegram, es gibt aber ein Comandline Interface. Da ich über eigene Server im Internet verfüge sollte damit eine entsprechende Funktionalität realisierbar sein, so dass ich neben WhatsApp auch auf Telegram verzichten kann.

Installation

Auf dem Rechner muss eine relativ aktuelle Java-Version vorhanden sein, bei mir ist das openjdk version "11.0.9.1".

Von der Github-Adresse holt man sich die aktuelle Version (aktuell 0.8.1 - März 2021)

wget https://github.com/AsamK/signal-cli/releases/download/v0.8.1/signal-cli-0.8.1.tar.gz

und entpackt diese

tar xvfz Downloads/signal-cli-0.8.1.tar.gz

Für die nächsten Schritte wechselt man in das Unter-Verzeichnis bin

cd signal-cli-0.8.1/bin

Nun braucht man eine Telefonnummer an die man den Account binden kann. Das kann auch eine beliebige Festnetznummer sein, man muss nur ein Gespräch annehmen können. Diese Nummer muss man dann registrieren.

./signal-cli -u +4940xxxxxx register --voice

Über das --voice erreicht man, dass der Aktivierungcode nicht per SMS kommt, sondern per Voice-Roboter. Der Anruf kam sehr schnell und ich war überrascht, dass der Roboter die Ziffern sogar auf Deutsch übermittelt hat. Er wiederholt die Ansage auch ziemlich oft.

Dann muss man die Nummer aktivieren

./signal-cli -u +4940xxxxxx verify yyyyyy

Damit ist der Account aktiv und man kann Nachrichten verschicken:

./signal-cli -u +4940xxxxxxx send -m "Nachricht" +49163yyyyyy

Damit beim Empfänger nicht nur die Telefonnummer auftaucht habe ich dem Account ein Profil erstellt

./signal-cli -u +4940xxxxxx updateProfile --name MailBot

Die Daten speichert die Software übrigens im Homeverzeichnis des Benutzers unter

 .local/share/signal-cli/

Das Verzeichnis besteht dann aus den Unterordnern

  • avatars
  • data

Man kann die Konfigurationsdaten aber auch in ein beliebiges Verzeichnis bringen (hier /opt/signal-cli) und dieses beim Aufruf per --config mit angeben

./signal-cli --config /opt/signal-cli -u +4940xxxxxxx send -m "Nachricht" +49163yyyyyy

Zeilenumbrüche

Etwas gewöhnungsbedürftig ist der Umgang mit Zeilenumbrüchen.

Es geht direkt, wenn die Shell das entsprechend zulässt

signal-cli -u +4940xxxxxx send -m 'foo
bar' +49163yyyyyy

Mittels Shell-Escaping:

signal-cli -u +4940xxxxxx send -m "`echo -e 'foo\nbar'`" +49163yyyyyy

Am einfachsten aber:

echo -e "foo\nbar" | signal-cli -u +4940xxxxxx send +49163yyyyyy

Gruppen

Einer vorhandenen Gruppe kann man über den zugehörigen Einladungslink beitreten mittels:

./signal-cli -u +4940xxxxxx joinGroup --uri https://signal.group/#CjQKIG5nR5mf83bNr6BPder_vorhandene_LinkBJu1xpj8t

als Antwort bekommt man die ID der Gruppe

Joined group "GTAHYc0dieGruppepb/OjMT7/RRNGNorHyw2hsQ0="

Will man die später noch einmal ermitteln, so kann man sich die Eigenschaften der Gruppe abfragen mittels:

./signal-cli -u +4940xxxxxx listGroups -d

der Parameter -d steht für detailliert und ist zur Ermittlung der ID nicht unbedingt notwendig.

Nun kann man eine Nachricht an die Gruppe verschicken:

./signal-cli -u +4940xxxxxx send -g GTAHYc0dieGruppepb/OjMT7/RRNGNorHyw2hsQ0= -m "Nachricht für die Gruppe"

mail2signal

Bei Telegram ist die API mit den Bots recht praktisch. Etwas Ähnliches wollte ich auch mit Signal realisieren. Ziel ist, dass für jede Mail, die bei einer bestimmten Mailadresse eingeht, eine Signal-Nachricht ausgelöst wird. Diese Nachricht soll dann aber nur den Absender und den Betreff beinhalten. Eine vollständige Mail würde einfach den Rahmen sprengen.

Ich habe mir zur Nutzung das signal_cli nach /opt installiert und dorthin auch das Konfigurationsverzeichnis kopiert. Die Ausführungsrechte für das signal_cli habe ich für alle Benutzer freigegeben und die Konfigurationsdateien nobody.vmail übereignet.

Das folgende Script habe ich dann unter dem Namen mail2signal.pl nach /usr/lib/dovecot/sieve-execute/ gelegt.

#!/usr/bin/perl
use Encode;

$tmp_posting = "/tmp/post2signal.$$";
$tmp_signal = "/tmp/signal.$$";

open (INLIST, "cat >>".$tmp_posting." -|") || die "Foo. $!\n";
sleep(2);
close(INLIST);

open (DATAFILE, "<".$tmp_posting) || die "Bar. $!\n";
open (OUTFILE,  ">".$tmp_signal)  || die "Baz. $!\n";

while($line = <DATAFILE>) {
    chop($line);
    # leere Zeile bedeutet Ende des Headers
    last if ($line =~ /^\s*$/);	  
    # Das + Zeichen verringert die gefräßigkeit, so dass das erste : Zeichen gilt   
    ($head,$text) = $line =~ /(.+?):\s+(.+)/;
    if ($text ne "") {
      if ($head eq "Subject") {
       $text=decode("MIME-Header", $text);
       $text=encode("UTF-8", $text);     
      }
      $Headers{$head} = $text;
    }
}

# das Signal-Posting erzeugen
print OUTFILE "Neue Mail von: $Headers{'From'}\n\n";
print OUTFILE "$Headers{'Subject'}\n";

print OUTFILE "\nBitte beachten\n";

close (OUTFILE);
system("export LANG=de_DE.UTF-8; /usr/bin/cat $tmp_signal | /opt/signal-cli-0.8.1/bin/signal-cli --config /opt/signal-cli  -u +4940xxxxxx send -g GTAHYc0dieGruppepb/OjMT7/RRNGNorHyw2hsQ0=");
unlink($tmp_posting);
unlink($tmp_signal);


Aufgerufen wird das Script dann durch die /etc/aliases mittels

mailbot: "| /usr/lib/dovecot/sieve-execute/mail2signal.pl"

Wobei mailbot dann ein lokaler Account ist, der um den Wert von myhostname zu einer vollständigen Mailadresse erweitert werden muss, damit der Account auch von außen erreicbar wird.

Viel Zeit hat mich der Umgang mit dem Umlauten im Betreff gekostet. Zwar gibt es in Perl schöne Funkionen zum Codieren und decodieren, ich habe aber erst nach einiger Zeit mitbekommen, dass die Umgebungsvariable LANG für den Benutzer nobody wohl nicht gesetzt ist. Daher ist der entsprechende Befehl mit im system-Aufruf.


ToDo

Nun will ich mir noch ein entsprechendes Tool schreiben, wo dass ich über den Aufruf einer URL Signal Nachrichten erzeugen kann.

Links