Einführung in Telegram-Bots: Nachrichten und Dateien aus dem Terminal senden
Für Telegram gibt es sogenannte Bots – letztlich sind das einfach Nutzer-Accounts für Programme/Roboter statt Menschen. Diese Konten lassen sich dann per API/Schnittstelle ansprechen und ganz „normal“ in Telegram nutzen.
Ihr könnt also beispielsweise Umfragen für Terminvereinbarungen in eine Telegram-Gruppe einbauen, eigene Clients schustern, von der Kommandozeile aus Dateien, Fotos oder Text senden, Nachrichten als Telegram-Messages anzeigen und so weiter. Das Schicke daran: Den Bot erstellt Ihr ganz simpel über das Telegram-Standard-Konto Botfather im Dialog. Wir zeigen Euch Schritt für Schritt, wie Ihr einen Bot erstellt und von der Kommandozeile aus Texte und Dateien sendet. Vorwissen wird nicht benötigt.
[UPDATE] Im zweiten Teile zeigen wir Euch, wie Ihr Nachrichten im Terminal empfangen könnt.
[UPDATE 2] Da der Artikel schon was älter ist: Stand September 2017 funktioniert das Vorgehen für Telegram-Bots immer noch. Wenn irgendetwas nicht funktioniert, kontrolliert die Anführungszeichen!
Natürlich gibt es auch fertige Telegram-Bots, für Hundebilder und sowas, hier geht es aber darum, eigene Bots zu erstellen:
1. Botfather integrieren
Fügt zunächst den „Nutzer“ @botfather hinzu – über die Suchfunktion oder den Link auf der Homepage.
2. Telegram-Bot erstellen
Um Euren Bot zu erstellen, sendet dem neuen Nutzer Botfather einfach die Nachrichten
/newbot
und vergebt anschließend auf Nachfrage Nutzer- und Bot-Namen – letztere müssen auf bot enden. Zum Abschluss bekommt Ihr den sogenannten Token, eine längere Zeichenkette, die Euren Bot eindeutig identifiziert. Am besten kopiert Ihr Euch den Token-Code direkt. Optional könnt Ihr noch eine About-Seite, ein Nutzerbild für den Bot etc. einrichten – sendet einfach im Telegram-Client Befehle wie /setuserpic, /help und so weiter. Nicht vergessen: Ihr müsst den Bot jetzt starten und eine erste Nachricht versenden, sonst funktioniert der nächste Schritt nicht.
3. ID des Chats herausfinden
Um eine Nachricht an einen Telegram-Chat oder eine Telegram-Gruppe zu senden, benögtigt Ihr die entsprechende Chat-ID, die Ihr über folgendes Kommando bekommt:
curl -X POST https://api.telegram.org/bot123456:abcde1234ABCDE/getUpdates
Zunächst: 123456:abcde1234ABCDE müsst Ihr natürlich durch Euren Token-Code ersetzen – das vorangestellte „bot“ muss aber bleiben. Das Linux-Standard-Werkzeug curl dient lediglich dazu, eine HTTP-Anfrage an Telegram abzusetzen. Unter Windows müsst Ihr zunächst curl für Windows installieren. Übrigens: cURL steht für „see url“, aber egal. Das Ergebnis dieser Anfrage ist etwas in der Art:
{"ok":true,"result":[{"update_id":638422092,
"message":{"message_id":9,"from":{"id":268963852,"first_name":"Gizlog"},"chat":{"id":268963852,"first_name":"Gizlog"},"date":1437389925,"text":"c"}},{"update_id":638422093,
Wichtig ist hier die ID des Chats, in diesem Beispiel also 268963852. Anmerkung: Natürlich könnt Ihr Euren neuen Bot wie jeden anderen Account einer Gruppe hinzufügen – dann taucht beim obigen Ergebnis auch die ID des Gruppen-Chats auf, den Ihr nutzen könnt, um in die Gruppe zu posten. Falls keine Chats erscheinen: Postet eine Nachricht in den gewünschten Chat – ohne Nachrichten gibt es natürlich auch keine Updates!
4. Nachrichten und Dateien an Telegram senden
Auch zum Senden von Nachrichten nutzen wir wieder curl:
curl -X POST 'https://api.telegram.org/bot123456:abcde1234ABCDE/sendMessage?chat_id=-4194264&text="texty text"'
Ihr seht schon, es ist wieder dasselbe Konstrukt wie oben, aber mit der Methode/dem Befehl „sendMessage“ und daran angefügt, abgetrennt per ?, zunüchst die Chat-ID und dann mit & abgetrennt der zu sendende Text. Und schon landet die Nachricht „texty text“ in Eurem Telegram-Account, abgesandt von „Nutzer“ TutoBot in unserem Beispiel. Das Senden von Dateien und Fotos ist dann selbsterklärend:
curl -X POST "https://api.telegram.org/bot123456:abcde1234ABCDE/sendDocument" -F chat_id=-419426123 -F document="@/home/mirco/misto.txt"
Die Methode heißt nun sendDocument – allerdings muss die HTTP-Anfrage im Format „multipart/form-data“ gesendet werden, weshalb Chat-ID und Dokumentenpfad separad via F-Parameter an den curl-Befehl angehängt werden. In diesem Beispiel wird die Datei misto.txt an unseren Tutonaut-eigenen Gruppen-Chat gesendet (der Strich gehört zur Gruppen-Chat-ID!). Denkt an das @ vor dem Dokumentenpfad. Der Foto-Befehl ist komplett analog:
curl -X POST "https://api.telegram.org/bot123456:abcde1234ABCDE/sendPhoto" -F chat_id=-4194264 -F photo="@/home/mirco/rathaus.jpg"
Telegram-Bots produktiv nutzen
Bis hierher ist das ganze freilich nur Spielerei – wie geht’s weiter? Zum einen könntet Ihr Telegram natürlich auch über Programmiersprachen ansprechen und ganze Programmlogiken darum herum stricken. Aber schon auf der Kommandozeile geht noch einiges: Statt eines fixen Texts könnt Ihr natürlich auch eine Variable einsetzen, also statt „texty text“ etwa „$text“ – und diese Variable ließe sich über Skript oder Nutzeranfragen ganz einfach besetzen. Ein Super-Simpel-Beispiel wäre ein Mini-Skript wie:
echo "Gib die Nachricht ein:" &&
read text &&
curl -X POST "https://api.telegram.org/bot123456:abcde1234ABCDE/sendMessage?chat_id=-4194264&text=$text"
Wenn Ihr das etwa als Alias oder Skript abspeichert und dann aufruft, wird zunächst „Gib die Nachricht ein“ ausgegeben, dann gebt Ihr eben die Nachricht ein und per Return wird der eingegebene Text an Telegram gesendet. Soweit einfach mal als Einstieg.
Wenn was unklar ist, einfach fragen, „dumme“ Fragen gibt es bei so einem Thema eh nicht. Und was macht Ihr mit Bots? Oder würdet Ihr gerne machen? Was haltet Ihr überhaupt davon?
Wir haben mittlerweile übrigens eine ganze Reihe von Telegram-Artikeln, etwa zu einem schicken CLI-Client.
Seit dem Update auf Bot API Version 6.7 vom 21.04.23 funktioniert mein Curl Aufruf unter Windows nicht mehr. Auch der Wechsel auf die aktuellste Curl Version 8.0.1_7 hat nichts gebracht. Bei mir bricht er bei TLS Handshake ab („Recv failure: Connection was reset“). Hat jemand eine Idee was man da machen kann?
Etwas wirklich Konkretes kann ich dazu leider nicht beisteuern, aber vielleicht in eine Richtung zeigen. Zunächst: Just getestet, mein alter curl-Aufruf im Terminal funktioniert nach wie vor. Und da auch die Release Notes nichts in der Richtung sagen, dürfte es zumindest nicht an der neuen API-Version liegen.
Sofern an Einstellungen rund um Proxies, Firewalls und dergleichen nichts geändert wurde, würde ich es zunächst mal mit einem System-Update und -Neustart versuchen – alles, was mit Verifizierung zu tun hat kann an allen möglichen Kleinigkeiten scheitern. Bestätigen könnte das ein Versuch auf einem anderen System, zum Beispiel einen virtuellen Linux.
Ansonsten bleibt Dir nichts anderes übrig, als mit allen Informationen nach Hilfe zu suchen, zum Beispiel bei Stackoverflow. Die abgekürzte Fehlermeldung mit TLS-Hinweis gibt nicht genug her.
Hallo :)
Sehr guter Artikel und schön erklärt. Ich bin neu auf dem Gebiet und habe eine Frage. Ist es möglich einen Telegramm Gruppenchat auslesen zu lassen und bestimmte Texte daraus automatisch ändern zu lassen, zum Beispiel wenn es sich immer die gleiche Textzeile handelt und dann in einen anderen Gruppenchat weiterleiten zu lassen. Sozusagen alles automatisiert ?
Das geht auf jeden Fall. Einerseits könnte man das mit Python oder sonst einer Programmiersprache in schön machen – wenn man denn eine beherrscht. Und wenn es eine echte App werden soll, müsste das auch sein, zumal das dann auch irgendwie online ablaufen sollte.
Andererseits ginge das auch über den Terminal – für kleinere Zwecke sollte das genügen. Oben im Artikel steht ja, wie man den Text senden kann. Im zweiten Teil steht, wie man Text auslesen kann. Insofern fehlt nur der Teil in der Mitte – und Texte lassen sich auf der Kommandozeile ganz wunderbar mit sed verarbeiten. Workflow wäre also:
Das ist sicherlich nicht die eleganteste Lösung, aber tendenziell einfacher, als „mal eben“ eine richtige Programmiersprache zu lernen. sed dürfte schon nicht jedem sofort gefallen ;) Die sed-Syntax ist zwar im Grunde ziemlich simpel, aber man muss sich mal mit regulären Ausdrücken befassen, um die gesuchten Muster im Text automatisch erfassen und verändern zu können. Falls Dir Regex nichts sagen: Hier haben wir einen Einstieg, und ein wenig mehr zu sed hier (Muster über mehrere Zeilen suchen) oder direkt im Terminal:
Der Aufwand für das ganze Vorhaben dürfte recht überschaubar sein – zuzüglich der Regex-Lernerei! Wenn Du dann am Ende, keine Ahnung, vielleicht Lobeshymnen auf den FC Köln automatisch auf den BVB ummünzen und in einem anderen Chat posten möchtest … – ginge.
Hallo
wie muss ich die URL gestalten das es mir die Nachrichten ohne Benachrichtigung sendet
irgendwie mit disable_notification muss es gehen.
Danke im Voraus
Moin ,
IOS , will meine nummer bestätigen, leider finde ich im Messenger kein Option nummer teilen
Hallo Mirco,
ich versuche mit folgendem Befehl das letzte (neueste) Foto aus dem Kamera Ordner (/var/lib/hkcam/data) über Telegram zu versenden:
curl -X POST „https://api.telegram.org/bot123456:abcde1234ABCDE/sendDocument“ -F chat_id=-4194264 -F document=“@$(ls -rt1 /var/lib/hkcam/data | tail -1)“
Leider bekomme ich ständig folgende Fehlermeldung:
curl: (26) couldn’t open file „902511643.jpg“
Folgender Befehl funktioniert, also liegt es nicht an der Datei:
curl -X POST „https://api.telegram.org/bot123456:abcde1234ABCDE/sendDocument“ -F chat_id=-4194264 -F document=“@/var/lib/hkcam/data/902511643.jpg“
Muss am Befehl etwas angepasst werden, oder kennst du einen Work-Around?
Danke und Gruß, Mathias
Ich habe es mal kurz mit einer vereinfachten Variante versucht, hier funktioniert folgende Schreibweise für den document=-Teil:
Heißt: Dein ls-Befehl gibt lediglich den Dateinamen aus, aber nicht samt Pfad! Du kannst den Pfad (hier eben /d/tmp/) manuell angeben oder versuch es mit
Durch das $PWD bekommst Du den kompletten Pfad. Wie genau das am besten bei Dir passt, musst Du testen. Man könnte auch über den find-Befehl gehen oder sonstwas.
Hallo,
Ich möchte das bestimmte Informationen aus meiner Webseite an meinen jeweiligen Angestellten auf telegram automatisch weitergeleitet werden, wie kann ich das machen. Ein bot habe ich bereits erfolgreich erstellt. Lg
Hallo kann man per bot auch einen Telegramm Kanal auslesen und automatisch zum Beispiel auf einem Blog Spiegeln?
Ich betreibe einen Telegramm kanal wo ich Reiseberichte und Fotos teile. Ich würde den aber gerne auf meiner Website den nicht Telegramm Nutzern zugänglich machen!
Website basiert auf WordPress in der aktuellen Version.
Wie das Auslesen im Terminal geht, steht im zweiten Teil des Artikels. Dann hätte man die Inhalte schon mal lokal und von dort bekommt man sie auch wieder in WordPress gespielt, zum Beispiel über dessen CLI-Client. Das ist aber sicherlich mit etwas Frickelei verbunden.
Da fällt mir ein, ich hatte mal eine Artikel dazu geschrieben, wie das mit IFTTT funktioniert – ist eine Zeit lang her, wäre aber vielleicht einen Versuch wert. (Auch wenn die kostenlose Version von IFTTT mittlerweile recht beschränkt ist.)
Andere Lösungen habe ich spontan nicht gefunden, die vielen WordPress-Plugins scheinen auch keine Hilfe.
Hallo Mirco
Weist du wie man ein bot erstellt der von einem Kanal die Datei automatisch kopiert und in einem neuen Kanal postet ?
Ich habe mit einem Freund 2 Kanäle, mein Kumpel postet was in seinem Kanal und wir wollen das ein bot das direkt kopiert vom Kumpel Kanal und automatisch in mein Kanal postet. Wäre sowas möglich ?
Es gibt die Methode forwardMessage, damit sollte sich das machen lassen – also irgendwie in der Art: Erst Nachrichten (samt IDs) per getUpdates abrufen, dann per forwardMessage unter Angabe der ID weiterleiten. Wie genau, weiß ich aber gerade nicht.
Alternativ ginge es natürlich „manuell“ per Skript: Nachrichten wie in Teil 2 beschrieben abholen, Dateien wie bei Stackoverflow beschrieben herunterladen und wie oben beschrieben senden – verpackt in eine Endlosschleife. Wenn man ein NAS oder sonst einen Rechner immer am Netz oder einen echten Server hat versteht sich … Das wäre aber wohl nur sinnvoll, wenn eben nicht die ganze Nachricht weitergeleitet werden soll, sondern zum Beispiel nur bestimmte Dateien. Oder mehrere Dateien als Archiv. Oder Dateien vorher in ein anderes Format konvertiert werden sollen. Oder oder oder …
Alternativ gibt es auch fertige Forwarding-Bots, die das übernehmen – allerdings können dann natürlich Dritte mitlesen! Und da es da meist keinen Hersteller gibt, verzichte ich mal auf Links ;) Tendenziell müsste das auch mit IFTTT gehen; die Variante Telegram-Nachricht an WordPress habe ich früher mal beschrieben. Natürlich kann dann auch IFTTT mitlesen, aber das ist zumindest ein etablierter Anbieter. Nachteil: Die Nachrichten müssen ein Trigger-Wort und „/ifttt“ enthalten, was es vermutlich etwas unpraktisch machen dürfte …
Hallo, bei
curl -X POST https://api.telegram.org/bot123456:abcde1234ABCDE/getUpdates
kommt bei mir folgendes raus.
{„ok“:true,“result“:[]}
Keine Ahnung was mein Fehler ist oder was ich tun soll, mache dies das erste mal.
Hoffe mir kann jemand helfen, danke.
Hi Rico,
Bin auch ein absoluter Neuling und hatte das selbe Problem. Habe dann in den Chat nochmal hallo geschrieben und die Seite nochmal aufgerufen mit dem gewünschte Ergebnis.
Hoffe das hilft dir.
Lg
Hallo Mirco,
vielen Dank für dein Tutorial.
Soweit funktioniert alles.
Was ich allerdings leider nicht hin bekomme ist, der sendMessage Methode in reply_markup etwas mitzugeben.
Also z.B. ein forcereply. Ich schaffe es offensichtlich leider nicht den forcereply Typen korrekt anzugeben.
curl -d text=’TEST‘ -d chat_id=XXXX -d forcereply(force_reply=true)
Wenn ich nur curl -d text=’TEST‘ -d chat_id=XXXX schicke, funktionierts.
Wenn ich dann noch das -d forcereply(force_reply=true) anhänge, bekomme ich in Telegram nur die Nachricht, ohne die Reply Funktion.
Hast du oder jemand anderes eine Idee, wie ich den forcereply Typen korrekt einbaue?
Okay, da musste ich ein wenig suchen – die API-Nutzung via schlichter Kommandozeile ist irgendwie nicht so toll dokumentiert, nutzt vermutlich kaum jemand ;) Was bei Dir noch fehlt ist der Part „reply_markup“, in dem wiederum „force_reply“ genutzt werden kann, also im Sinne von:
Allerdings muss der force_reply-Part URI-kodiert werden:
Der ganze Teil sieht dann so aus:
Ein kompletter Link folglich:
Das Kodieren kannst Du online erledigen lassen.
Hallo Marco,
du warst nicht der erste, den ich gefragt habe aber der Einzige, der mir diese Frage korrekt beantworten konnte.
Vielen Dank und RESPEKT dafür!
Ich hatte noch kurz Probleme mit den ‚ in deiner Antwort. Aber wenn ich die einfach weg lasse, klappt es tatsächlich.
Auch dein Link für das Kodieren ist hilfreich.
Darf ich dich nach deiner/einer Quelle für deine Hilfe fragen?
Ich würde mich freuen, wenn ich mich da evt. nach weiterem Wissenswerten umschauen könnte.
Viele Grüße
Christian
Hi Christian,
schön, dass es klappt! Und ja, Anführungszeichen sind nahezu immer eine Option für Fehler, die wanken leider teils von Shell zu Shell (ich nutze unter Windows die Bash aus Git for Windows statt cmd).
Was mich letztlich auf die Antwort gebracht hat war der schlichte Hinweis in einer Stackoverflow-Frage: You need to encode the markup text too. Da geht es zwar um Google Apps Script, aber für Shell-Skript/HTTP ließ sich dann entsprechend ableiten. Allgmein findet man deutlich mehr Infos zu derlei Dingen, wenn man mit JavaScript, Python oder sonst einer Skript-/Programmiersprache arbeitet.
Ganz generell ist Stackoverflow die mit Abstand beste Seite für derlei Fragen, es gibt wohl kaum einen Entwickler, der noch ohne die Seite arbeiten könnte ;)
Grüßend,
Mirco