
Hallo Habr! Lassen Sie mich mich vorstellen: Mein Name ist Sergey Agaltsov und ich bin ein "Programmierer im Leben". Dies bedeutet, dass ich seit langem IT-Manager und von Beruf überhaupt kein Programmierer bin, aber ich benutze die Programmierung ständig, sowohl in meiner Haupttätigkeit als auch als Hobby. Wie einer meiner ehemaligen Chefs oft sagte: "Seryoga! Sie sind wieder in die Programmierung gerutscht!" Ich kann zwar nicht sagen, dass er oder jemand anderes jemals sehr unzufrieden damit war.
Nach dem Erscheinen der Bot-API im TamTam-Messenger habe ich als echter und daher fauler Programmierer zwei Python-Bibliotheken erstellt, um damit zu arbeiten:
- Open Client API (im Folgenden - OAC) - generierte es zunächst mit dem OpenAPI-Generator basierend auf dem API-Schema und passte es dann unter Berücksichtigung der Merkmale des Generators an.
- Die Shell für diesen Client ist TamTamBot (im Folgenden: TTB), was die Arbeit mit OAC vereinfacht.
Es gab also ein bestimmtes TamTam Python SDK.
Ich tat es zuerst "für mich selbst, für die Seele", schlug aber auch vor, dass die TamTam-Community es auf Wunsch verwenden sollte. Aber wie Sie wissen, bleibt keine einzige gute Tat ungestraft - die Leute werden gebeten, einen Schulungsartikel zu schreiben. Und hier bin ich mit diesem Artikel. Darin werde ich Ihnen erklären, wie Sie mit diesen Bibliotheken einen einfachen Bot entwickeln.
Herausforderung
Entwickeln Sie einen Bot, der die Aktionen von Bot-Entwicklern vereinfachen soll. Der Bot sollte im Modus der permanenten Abfrage der staatlichen Bot-API (Long Polling) arbeiten. In diesem Artikel wird der Bot geschult, um die Innenseiten der an ihn gesendeten Nachricht anzuzeigen, und außerdem so konfiguriert, dass er der entwickelten Funktionalität entspricht.
Es versteht sich, dass der Leser Python 3 , git , installiert hat, das mit der PyCharm- Entwicklungsumgebung verbunden ist (die Entwicklungsumgebung kann unterschiedlich sein, aber die Geschichte basiert auf PyCharm). Es ist wünschenswert, die Grundlagen von OOP zu verstehen.
Einen Bot-Token bekommen
Das Token wird durch einen Aufruf an den spezialisierten Bot @PrimeBot erhalten
Wir finden diesen Bot in TamTam, geben den Befehl / create ein und beantworten die Fragen:
- Geben Sie den eindeutigen Kurznamen des Bots in lateinischen Buchstaben ein - dies ist der Benutzername des Bots, unter dem er über @ oder über einen Link des Formulars
https://tt.me/username
verfügbar sein wird. Es gibt keine besonderen Einschränkungen für den Benutzernamen. Insbesondere ist das Wort Bot optional. - Geben Sie einen Namen ein - dies ist der Anzeigename des Bots. Hier können Sie bereits das kyrillische Alphabet verwenden.
Wenn alles korrekt eingegeben wurde, wird der erstellte Bot zu den Kontakten hinzugefügt und im Gegenzug erhalten wir ein Token - eine Folge von Zeichen der Form: HDyDvomx6TfsXkgwfFCUY410fv-vbf4XVjr8JVSUu4c.
Ersteinrichtung
ZeigenErstellen Sie ein Verzeichnis:
mkdir ttBotDevHelper
Gehen Sie dazu:
cd ttBotDevHelper/
Wir initialisieren das Git-Repository:
git init
Laden Sie die erforderlichen Bibliotheken herunter und fügen Sie sie als Submodule von git hinzu:
git submodule add https://github.com/asvbkr/openapi_client.git openapi_client git submodule add https://github.com/asvbkr/TamTamBot.git TamTamBot
Wir öffnen das erstellte Verzeichnis in PyCharm (z. B. im Explorer unter dem Kontextmenü "Ordner als PyCharm-Projekt öffnen") und erstellen eine Datei, die unser Bot enthalten wird - Datei / Neu / Python-Datei. Geben Sie im angezeigten Dialogfeld den Namen ttBotDevHelper ein und beantworten Sie die Frage nach dem Hinzufügen zu git positiv.
Jetzt müssen wir eine virtuelle Umgebung für unser Projekt erstellen.
Um eine virtuelle Umgebung zu erstellen, wählen Sie Datei / Einstellungen und dann den Unterschlüssel Projektinterpreter auf der Registerkarte Projekt. Klicken Sie anschließend rechts auf das Zahnradsymbol und wählen Sie Hinzufügen:

PyCharm bietet eine eigene Unterkunftsmöglichkeit an.

Es macht Sinn, ihm zuzustimmen.
Nach dem Erstellen der virtuellen Umgebung wird der vorherige Bildschirm geöffnet, der jedoch bereits Informationen zur erstellten Umgebung enthält. Auf diesem Bildschirm müssen Sie die erforderlichen Pakete installieren, indem Sie rechts auf das Symbol "+" klicken und die Paketnamen eingeben:
Anschließend fügen wir dem Projekt die .gitignore-Datei mit folgenden Inhalten hinzu, mit Ausnahme der Dateien, die in git nicht benötigt werden:
venv/ .idea/ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class *.log *.log.* .env ttb.sqlite3
Fügen Sie eine Umgebungsvariable mit dem Namen TT_BOT_API_TOKEN
, in der wir den Wert des Tokens unseres Bots angeben, das von https://tt.me/primebot empfangen wurde, und starten Sie PyCharm neu.
(!) Anstatt eine Umgebungsvariable direkt zur Betriebssystemumgebung hinzuzufügen, verwendet PyCharm optimalerweise eine spezielle .env-Datei. Die Konfiguration wird unten erläutert.
Herzlichen Glückwunsch, jetzt können Sie mit dem interessantesten Teil fortfahren - dem Schreiben Ihres Bots.
Einfacher Bot-Start
Öffnen Sie die Datei ttBotDevHelper.py und schreiben Sie die ersten Zeilen:
Hier erstellen wir unsere Bot-Klasse basierend auf der TamTamBot-Klasse.
PyCharm schlägt vor, dass die BotDevHelper-Klasse abstrakte Methoden enthält, die implementiert werden müssen. Drücken Sie die Alt-Eingabetaste für den Klassennamen, wählen Sie "Abstrakte Methoden implementieren", wählen Sie alle von PyCharm vorgeschlagenen Methoden (2 davon) aus und klicken Sie auf OK. Infolgedessen werden zwei leere Eigenschaftsmethoden hinzugefügt: Token und Beschreibung. Wir ändern den resultierenden Code wie folgt:
Die token
Eigenschaft gibt das Token unseres Bots zurück, dessen Wert aus der Umgebungsvariablen TT_BOT_API_TOKEN
. Die description
Eigenschaft gibt eine erweiterte Beschreibung unseres Bots zurück, die den Benutzern angezeigt wird.
Der Code am Ende der Datei wird benötigt, um unseren Bot im Statusabfragemodus auszuführen.
Ich TamTamBot
fest, dass die Basisklasse TamTamBot
die Verwendung des Django-Webservers für die Arbeit im Web-Hook-Modus beinhaltet. Aber jetzt ist die Aufgabe einfacher und wir brauchen kein Django, was wir in der set_use_django(False)
. Hier wird die polling()
-Methode für das Objekt unserer Klasse aufgerufen, wodurch der Betrieb im erforderlichen Modus sichergestellt wird.
Das notwendige Minimum ist erledigt. Dieser Code funktioniert bereits ziemlich gut. Führen Sie es aus, um zu laufen. Drücken Sie dazu die Tastenkombination Strg-Umschalt-F10.
Wenn Sie zuvor keine Umgebungsvariable direkt zum Betriebssystem hinzugefügt haben, tritt beim Start ein Fehler mit der Meldung "Kein Zugriffstoken" auf. Um dies zu beheben, konfigurieren Sie PyCharm für die Verwendung der ENV-Datei.
Zeigen Sie wieErstellen Sie eine .env-Textdatei. Sein Inhalt sollte in unserem Fall wie folgt sein:
TT_BOT_API_TOKEN=__
Jetzt müssen Sie es mit der Startkonfiguration in PyCharm verbinden:
Wir wählen Konfiguration ausführen / bearbeiten und verbinden auf der Registerkarte EnvFile unsere .env-Datei:

Klicken Sie dann auf Übernehmen.
Nachdem Sie den Bot gestartet haben, können Sie zu TamTam gehen, einen Dialog mit unserem Bot öffnen und auf die Schaltfläche "Start" klicken. Der Bot meldet Informationen über seine verborgenen Superkräfte. Dies bedeutet, dass der Bot arbeitet. Während der Bot im Demo-Modus arbeitet, stehen 4 Befehle zur Verfügung. Schau sie dir einfach an.
Trotz der ausgesprochenen Meinung des Bots über seine Coolness deutet er schüchtern an, dass er bisher nichts tun kann. Ihm alles beizubringen, was für die Eroberung der Welt notwendig ist, ist unsere Aufgabe.
Empfangen einer Quellnachricht und Senden einer Antwortnachricht mit einer internen Darstellung der Quellnachricht
Wir werden die Methode receive_text()
blockieren, deren Kontrolle beim Senden von Text an den Chat mit dem Bot übertragen wird:
def receive_text(self, update): res = self.msg.send_message(NewMessageBody(f' : {update.message}', link=update.link), user_id=update.user_id) return bool(res)
Das update
Objekt der UpdateCmn
Klasse, das an diese Methode übergeben wird, enthält verschiedene nützliche Informationen und insbesondere alles, was wir jetzt benötigen:
update.message
- ein Objekt, das die Nachricht selbst enthält;update.link
- fertiger Antwortlink zu dieser Nachricht;update.user_id
- Kennung des Benutzers, der die Nachricht gesendet hat.
Um eine Nachricht vom Bot zu senden, verwenden wir die Variable self.msg
, die das MessagesApi
Objekt enthält, das die im Abschnitt Nachrichten der API-Beschreibung beschriebenen Funktionen implementiert. Dieses Objekt enthält die von uns send_message()
Methode send_message()
, mit der Nachrichten gesendet werden können. Dieser Methode muss mindestens ein Objekt der NewMessageBody
Klasse und das Ziel übergeben werden - in unserem Fall die Benutzer-ID.
In diesem Fall wird wiederum ein Objekt der NewMessageBody
Klasse erstellt, indem eine Textdarstellung des NewMessageBody
und ein Antwortlink zur NewMessageBody
übertragen werden.
Wir starten unseren Bot neu und überprüfen in einem Dialog mit dem Bot, ob der Bot eine Antwort auf eine unserer Nachrichten generiert, die die interne Darstellung des Quellnachrichtenobjekts enthält.
Der Quellcode für diesen Status ist hier .
Hinzufügen eines neuen Bot-Befehls mit einem Parameter - Zeigt die interne Darstellung der Nachricht anhand ihrer Kennung an
Bei der Entwicklung von Bots ist es häufig erforderlich, die interne Darstellung einer Nachricht anhand einer oder mehrerer bekannter Nachrichtenkennungen (Nachrichten-ID - Mitte) zu überprüfen. Fügen Sie diese Funktionalität unserem Bot hinzu. Dazu nehmen wir zunächst in einer separaten Methode die Funktionalität der Ausgabe von Informationen über die interne Darstellung von Nachrichten heraus:
def view_messages(self, update, list_mid, link=None): res = False msgs = self.msg.get_messages(message_ids=list_mid) if msgs: for msg in msgs.messages: r = self.msg.send_message(NewMessageBody(f' {msg.body.mid}:\n`{msg}`'[:NewMessageBody.MAX_BODY_LENGTH], link=link), user_id=update.user_id) res = res or r return res
Bei dieser Methode übergeben wir eine Liste von mid.
Um Nachrichtenobjekte self.msg.get_messages
, verwenden wir die Methode self.msg.get_messages
, die eine Liste von Objekten in der Eigenschaft messages zurückgibt.
Ferner wird eine Textdarstellung jeder der empfangenen Nachrichten in separaten Nachrichten an unseren Dialog gesendet. Um Fehler zu vermeiden, wird der Text der generierten Nachricht durch die Konstante der maximalen Nachrichtenlänge - NewMessageBody.MAX_BODY_LENGTH
- NewMessageBody.MAX_BODY_LENGTH
.
Fügen Sie dann eine Methode hinzu, die den Befehl verarbeitet. Nennen wir es vmp . Sie können die Mittelliste mit einem Leerzeichen an den Befehl übergeben.
TTB ist so konzipiert, dass der Befehlshandler als Methode mit dem Namen cmd_handler_%s
, wobei% s der Name des Befehls ist. Das heißt, Für den Befehl vmp heißt die Methode cmd_handler_vmp
. Ein Objekt der UpdateCmn
Klasse wird an den Befehlshandler übergeben. Darüber hinaus kann ein Befehl die Eigenschaft cmd_args
enthalten, die ein Wörterbuch mit Zeilen und Wörtern enthält, die mit dem Befehl eingegeben wurden
Der Code sieht folgendermaßen aus:
def cmd_handler_vmp(self, update): res = None if not update.this_cmd_response:
Wir starten den Bot neu. Wenn Sie nun im Dialog des Bots einen Befehl wie /vmp mid1 mid2
(Sie können die vorherigen Überprüfungen in der Mitte durchführen), erhalten wir im Gegenzug zwei Nachrichten mit einer internen Darstellung der /vmp mid1 mid2
für jede der übertragenen Mitten.
Der Quellcode für diesen Status ist hier .
Änderung eines Bot-Befehls zum Arbeiten mit einer Textantwort
Sie können auch versuchen, die Nachricht von einem anderen Kanal / Chat weiterzuleiten. In diesem Fall wird jedoch nur angezeigt, was in der Quellnachricht im Dialog mit dem Bot enthalten ist. Insbesondere beim Senden einer Nachricht werden die Schaltflächeninformationen nicht gespeichert.
Aber was ist, wenn wir Informationen über die ursprüngliche Nachricht sehen möchten? In diesem Fall müssen Sie die Mitte der weitergeleiteten Nachricht übernehmen.
Um diesen Modus zu implementieren, ändern wir den Befehl vmp so, dass beim Aufruf ohne Parameter erwartet wird, dass die Nachricht weitergeleitet wird. Danach nimmt er die Mitte der gesendeten Nachricht und zeigt Informationen dazu an.
(!) Für den korrekten Betrieb dieser Funktionalität muss dem Bot die Berechtigung zum Lesen aus der Kanal- / Chat-Quelle erteilt werden.
Wir ändern den Befehlscode wie folgt:
def cmd_handler_vmp(self, update): res = None if not update.this_cmd_response:
Und seitdem Bei diesem Ansatz steigt das Risiko aufgrund des fehlenden Zugriffs auf Nachrichten. Anschließend fügen wir in der Methode view_messages()
eine Überprüfung der Übereinstimmung mit der Anzahl der angeforderten / empfangenen Nachrichten hinzu:
def view_messages(self, update, list_mid, link=None): res = False msgs = self.msg.get_messages(message_ids=list_mid) if msgs:
Wir starten den Bot neu, geben den Befehl / vmp ein und nachdem die Eingabeaufforderung über die Notwendigkeit der Weiterleitung angezeigt wurde, leiten wir die Nachricht vom Kanal / Chat weiter. Wenn der Bot das Recht hat, Nachrichten in diesem Kanal / Chat zu lesen, wird eine Textdarstellung des weitergeleiteten Nachrichtenobjekts angezeigt. Wenn kein Zugriff besteht, meldet der Bot ein mögliches Problem und wartet auf die Weiterleitung von der richtigen Quelle.
Bot-Eigenschaften einstellen
Jetzt bleibt es Glanz zu bringen. Schließen wir die about
Eigenschaft, die den Text zurückgibt, den der Bot anzeigt, wenn er zu arbeiten beginnt, sowie den Befehl / start.
@property def about(self): return ' .'
Wir blockieren die Methode get_commands()
, die die Liste der Befehle unseres Bots zurückgibt, die im Dialogfeld mit dem Bot angezeigt wird.
def get_commands(self):
Deaktivieren Sie die Eigenschaft main_menu_buttons, die die Liste der Schaltflächen im Hauptmenü zurückgibt, die mit dem Befehl / menu aufgerufen werden.
def main_menu_buttons(self):
Wir starten den Bot neu und stellen sicher, dass alles in Ordnung ist. Herzlichen Glückwunsch, Ihr erster Bot wurde erstellt und hat trotz einiger Spielzeuge eine gewisse Funktionalität gefordert.
Der Quellcode für diesen Status ist hier .
Der funktionierende @ devhelpbot-Bot ist hier zu sehen.
Das ist alles für jetzt. Wenn das Thema von Interesse ist, kann ich in den folgenden Artikeln die Weiterentwicklung des Bots betrachten. Fügen Sie beispielsweise benutzerdefinierte Schaltflächen hinzu (insbesondere Ja / Nein) und verarbeiten Sie diese, senden Sie verschiedene Arten von Inhalten (Dateien, Fotos usw.), arbeiten Sie im Webhook-Modus usw.
Übrigens können Sie in einem speziellen Chat schnell Fragen stellen. Direkte Vorschläge / Ideen dort.