PBecker.net

Einrichten eines Telegram Bots auf dem Raspberry Pi

Mehr
8 Jahre 8 Monate her - 6 Jahre 6 Monate her #14 von p.becker
Als Alternative zu WhatsApp bin ich vor kurzem auf Telegram gestoßen. Es bietet als quelloffenes System ähnliche Funktionen wie WhatsApp und dazu noch einige interessanten Erweiterungen. Ein großer Vorteil ist die Möglichkeit mehrere Geräte gleichzeitig unter dem gleichen Benutzerzugang anzumelden.
Hier will ich mich aber mit einer anderen Funktion beschäftigen, den Bots. Telegram Bots sind im Grunde normale Benutzer, die zwar einigen Einschränkungen unterliegen, aber über den Messenger gesteuert werden können. So können Anfragen an Bots gestellt werden und diese können automatisch Anworten oder Bots können über einzelne Benutzer oder Gruppen über Ereignisse informieren. Ich habe mich entschlossen einem Telegram Bot auf meinem Raspberry Pi ein Zuhause zu geben. Die Anmeldung bei Telegram und die Erstellung eines Bots habe ich mir hier gespart, da es dazu jede Menge Anleitungen gibt. Ein schönes Video (allerdings in Englisch) über das Erstellen und programmieren eines Bots gibt es hier: Telegram Bot Tutorial von Patrik Lemke .
Das Ziel ist dem Raspberry Pi als Webserver zu betreiben, der über eine Portweiterleitung aus dem Internet per HTTPS ansprechbar ist. Nur so kann der Bot ohne große Zeitverzögerung auf eingehende Nachrichten reagieren.

Bitte darauf achten, dass alle Variablen - eckige Klammern - durch die entsprechenden Werte ersetzt werden.
Code:
Adresse <input type="text" size="150" name="url" value="https://[Dynamische DNS-Adresse]/[Bot-Token]/[Bot-Skript-Name].php"><br><br> Adresse <input type="text" size="150" name="url" value="https://test.mooo.com/2234323:f3HGJ4fser73-Scae532dvder/testbot.php"><br><br>

Auf dem Raspberry Pi ist ein aktuelles Rasbian (Debian Jessie) installiert.

Damit die Sache funktioniert, ist eine feste IP oder ein DynDNS nötig. Falls eines von beiden schon vorhanden ist - perfekt, anderenfalls kann über die Webseite von afraid.org unter "Subdomains" kostenlos ein Dynamischer DNS-Eintrag angelegt werden. Dazu muss man sich auf der Seite registrieren und eine Domain anlegen. Der Eintrag wird über den DDClient, der auch auf dem Raspberry Pi läuft, aktualisiert.

ddclient
ddclient mit "sudo apt-get install ddclient" installieren. Es muss mindestens die Version 3.8.2 installiert werden. Ältere Versionen unterstützen das freedns Protokoll noch nicht.

Die Konfiguration für den DDClient sieht so aus

Die Datei /etc/ddclient.conf anpassen.

Code:
protocol=freedns use=web, web=checkip.dyndns.com/, web-skip='IP Address' server=freedns.afraid.org login=[Benutzername] password=[Kennwort] [Subdomain]
Die Werte in den eckigen Klammern müssen durch die entsprechenden Daten von afraid.org ersetzt werden.

Der Webserver
Als Webserver habe ich mich für nginx entschieden. Dieser wird zusammen inklusive PHP mit "sudo apt-get install nginx php5-fpm php5-curl" installiert.

Danach muss als erstes ein Zertifikat für den HTTPS-Zugang angelegt werden. Dazu legen wir im Verzeichnis "/etc/nginx" ein Unterverzeichnis "ssl" an und erstellen darin die Schüssel und Zertifikate.
Code:
sudo mkdir /etc/nginx/ssl sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
Bei der Abfrage von "(e.g. server FQDN or YOUR name)" muss zwingend die Subdomain des Dynamischen DNS eingetragen werden, sonst funktioniert das Update des Bots nicht. Alternativ kann hier die feste IP-Adresse, falls vorhanden, eingetragen werden.

Jetzt muss noch die Konfiguration von nginx angepasst werden.
Als erstes die Datei /etc/nginx/sites-available/default. Diese Zeilen müssen angepasst werden.
Code:
# Kommentar am Anfang der Zeilen setzen um den unverschlüsselten Zugang (HTTP) zum Webserver zu verhindern # listen 80 default_server; # listen [::]:80 default_server; # Kommentar am Anfang der Zeilen entfernen um den verschüsselten Zugang (HTTPS) zum Webserver zu ermöglichen listen 443 ssl default_server; listen [::]:443 ssl default_server; # Diese Zeilen müssen neu eingefügt werden. Sie verweisen auf das Zertifikat und den privaten Schlüssel ssl_certificate /etc/nginx/ssl/nginx.crt; ssl_certificate_key /etc/nginx/ssl/nginx.key; # Hier [b]muss[/] der Name der Dynamischen DNS oder die Feste IP eingetragen werden, die für das Zertifikat verwendet wurde server_name [Dynamischer DNS-Name oder Feste IP] #Aus dem PHP-Abschnitt müssen einzelne Zeilen auskommentiert werden, damit er so aussieht # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # location ~ \.php$ { include snippets/fastcgi-php.conf; # With php5-cgi alone: # fastcgi_pass 127.0.0.1:9000; # With php5-fpm: fastcgi_pass unix:/var/run/php5-fpm.sock; }

Jetzt muss nginx mit "sudo systemctl restart nginx.service" neu gestartet werden.

Nun fehlt noch die Portweiterleitung des HTTPS-Ports (443) zur IP des Raspberry Pis. Dazu bitte die Beschreibung des jeweiligen Routers zu Rate ziehen. Bitte darauf achten, dass wirklich der Port 443 aus dem Internet zum Port 443 auf dem Raspi weitergeleitet wird. Eine Port-Umleitung von z.B. Port 10000 (Internet) nach Port 443 (Raspi) wird von Telegram aktuell nicht unterstützt. Danach sollte der Webserver unter der Dynamischen DNS-Adresse mit dem Protokoll HTTPS ansprechbar sein.

Der Bot
Falls noch nicht geschehen sollte spätestens jetzt ein Bot erstellt werden. Bitte dazu die vorhandenen Tutorials benutzen.
Der BotFather gibt beim Erstellen des Bots ein Token zurück. Diese Token wird benötigt um auf die Bot API, also auf die Programmierschnittstelle, zuzugreifen. Zuerst erstellen wir ein Unterverzeichnis mit dem Namen des Tokens auf unserem Webserver. Da das Token sehr komplex ist, ist es unwahrscheinlich, dass jemand anderes als unser Bot darauf zugreift.
Code:
sudo mkdir /var/www/html/[Bot-Token]
Darin legen wir das Bot-Skript an, welches jedesmal aufgerufen wird, wenn jemand eine Nachricht an den Bot schickt.
Code:
vi testbot.php
Inhalt von testbot.php. Das PHP Skript empfängt die Textnachricht, die an den Bot geschickt wird und gibt sie wieder zurück.
Code:
<?php $botToken = "[Bot-Token]"; $website = "https://api.telegram.org/bot" . $botToken; $update = file_get_contents("php://input"); $updateArray = json_decode($update, TRUE); $text=""; $chatId=""; if (isset($updateArray["type"])) { $chatId = $updateArray["chat_id"]; $text = $updateArray["text"]; } else { $chatId = $updateArray["message"]["chat"]["id"]; $text = $updateArray["message"]["text"]; } $reply = "Antwort: " . $text; file_get_contents($website . "/sendmessage?chat_id=" . $chatId . "&text=" . $reply); ?>
Jetzt muss dem Bot noch mitgeteilt werden welches Skript er aufrufen soll. Damit das mit dem selbstsignierten Zertifikat funktioniert, das wir für den Webserver angelegt haben, muss das Zertifikat des öffentlichen Schlüssels mit hochgeladen werden. Dazu habe ich ein kleines HTLM Formular benutzt, in dem der Bot-Token eingeben und das Zertifikat ausgewählt werden kann. Bitte die eckigen Klammern durch die entsprechende Werte ersetzen.
Dieses HTML Skript wir nur einmal benötigt und kann im obersten Verzeichnis des Werbservers anelegt und sollte später (aus Sicherheitsgründen) wieder geschlöscht werden.
Code:
sudo vi /var/www/html/uploadcert.html
Code:
<html> <head> <title>Upload Cert</title> <meta charset="UTF-8"> </head> <body> <form method="post" action="https://api.telegram.org/bot[Bot-Token]/setwebhook" name="submit" enctype="multipart/form-data"> Adresse <input type="text" size="150" name="url" value="https://[Dynamische DNS-Adresse]/[Bot-Token]/[Bot-Skript-Name].php"><br><br> Public Key Zertifikat <input type="file" name="certificate"><br /><br /> <input type="submit" name="submit" value="Submit"> </form> </body> </html>
Das Zertifikat des öffentlichen Schlüssels (/etc/nginx/ssl/nginx.crt) muss vor dem Aufruf des Formulars vom Raspi auf den Rechner heruntergeladen werden von wo der Aufruf erfolgt. Dazu kann z.B. unter Windows WinSCP verwendet werden.
Nach dem Absenden des Formulars, sollte eine Bestätigung des Bots im Browser-Fenster angezeigt werden.
Letzte Änderung: 6 Jahre 6 Monate her von p.becker.

Bitte Anmelden um der Konversation beizutreten.

  • Anonymous
  • Besucher
  • Besucher
6 Jahre 6 Monate her #26 von Anonymous
Kann es sein, dass die Anleitung nicht mehr wegen den Selbsterstellen Zertifikat funktioniert?
Muss man jetzt eine Domain haben und ein echtes Zertifikat erstellen z.B. mit Let's Encrypt oder StartSSL?

Bitte Anmelden um der Konversation beizutreten.

Mehr
6 Jahre 6 Monate her #27 von p.becker
Nein. Ich habe noch einmal einen Webserver nach Anleitung aufgesetzt. Hat mit dem selbsterstellten Zertifikat funktioniert. Die Anleitung habe ich noch einmal ergänzt. Ich hoffe dass jetzt ein paar Stolpersteine raus sind.

Bitte Anmelden um der Konversation beizutreten.

  • Anonymous
  • Besucher
  • Besucher
6 Jahre 4 Monate her #30 von Anonymous
Der Fehler lag bei mir.
Ich war mit einem Router unterwegs, der das Mobilfunknetz nutzt. Da ist wohl seitens der Provider keine Weiterleitung möglich, selbst wenn man es im Router einstellt.

Noch ein paar Anmerkungen:
Vorweg - ich benutze Xubuntu und hat mit Hilfe deiner Anleitung am Ende funktioniert. An dieser Stelle noch einmal ein großes Dankeschön

Als ich es jetzt noch einmal probiert hatte, konnte ich php5-fpm und php5-curl nicht auflösen. Erst mit sudo apt-get install php-fpm php-curl installierte er es und dann sah ich, dass er php7.1-fpm und php7.1-curl wollte - kann aber auch an Xubuntu liegen.
Für die PHP-Funktion utf8_decode hatte noch die Erweiterung php-xml gefehlt (falls man die benutzen möchte, damit man auch im Code Umlaute verwenden kann ;) )
Und vllt noch erwähnenswert - bei php7.1-fpm stand in der php.ini display_errors = Off, wodurch keine Fehler angezeigt wurden :)

Bitte Anmelden um der Konversation beizutreten.

Ladezeit der Seite: 0.424 Sekunden
Powered by Kunena Forum
Diese Webseite benutzt Cookies zur Authentisierung, Navigation und für andere Funktionen. Mit der Nutzung dieser Webseite stimmen Sie zu, dass Cookies auf Ihrem Gerät abgelegt werden. Weitere Hinweise zur Nutzung von Cookies auf dieser Seite finden Sie in der "Datenschutzerklärung".