
Bonjour, Habr! Permettez-moi de me présenter: je m'appelle Sergey Agaltsov et je suis "programmeur dans la vie". Cela signifie que j'ai longtemps été un responsable informatique, et pas du tout un programmeur de profession, mais j'utilise la programmation tout le temps, à la fois dans mon activité principale et comme passe-temps. Comme l'un de mes anciens patrons l'a souvent dit - "Seryoga! Vous vous êtes de nouveau glissé dans la programmation!" Certes, je ne peux pas dire que lui ou quelqu'un d'autre ait jamais été très insatisfait de cela.
Après l'apparition de l' API Bot sur le messager TamTam, j'ai, en tant que vrai, et donc paresseux programmeur, créé 2 bibliothèques Python pour travailler avec:
- API cliente ouverte (ci-après - OAC) - initialement générée à l'aide du générateur OpenAPI basé sur le schéma API, puis adaptée en tenant compte des caractéristiques du générateur;
- le shell de ce client est TamTamBot (ci-après - TTB), ce qui simplifie le travail avec OAC.
Il y avait donc un certain SDK TamTam Python.
Je l'ai fait tout d'abord "pour moi, pour l'âme", mais j'ai également suggéré que la communauté TamTam, si elle le souhaite, l'utilise. Mais, comme vous le savez, aucune bonne action ne reste impunie - les gens ont demandé d'écrire un article de formation. Et me voici avec cet article. Dans ce document, je vais vous dire comment développer un bot simple en utilisant ces bibliothèques.
Défi
Développer un bot conçu pour simplifier les actions des développeurs de bots. Le bot devrait fonctionner dans le mode d'interrogation permanente de l'état bot-api (interrogation longue). Dans cet article, le bot sera formé pour montrer l'intérieur du message qui lui est envoyé, et également configuré pour correspondre aux fonctionnalités développées.
Il est entendu que le lecteur a installé Python 3 , git , connecté à l'environnement de développement PyCharm (l'environnement de développement peut être différent, mais l'histoire sera basée sur PyCharm). Il est souhaitable de comprendre les bases de la POO.
Obtenir un jeton de bot
Le jeton est obtenu via un appel au bot spécialisé @PrimeBot
Nous trouvons ce bot dans TamTam, entrez la commande / create et répondez aux questions:
- Entrez le nom abrégé unique du bot en lettres latines - c'est le nom d'utilisateur du bot par lequel il sera disponible via @ ou par un lien du formulaire
https://tt.me/username
. Il n'y a pas de restrictions spéciales sur le nom d'utilisateur. En particulier, le mot bot est facultatif. - Entrez un nom - c'est le nom d'affichage du bot. Ici, vous pouvez déjà utiliser l'alphabet cyrillique.
Si tout est correctement entré, le bot créé sera ajouté aux contacts et en retour, nous recevrons un jeton - une séquence de caractères de la forme: HDyDvomx6TfsXkgwfFCUY410fv-vbf4XVjr8JVSUu4c.
Configuration initiale
AfficherCréez un répertoire:
mkdir ttBotDevHelper
Allez-y:
cd ttBotDevHelper/
Nous initialisons le dépôt git:
git init
Téléchargez les bibliothèques nécessaires, en les ajoutant comme sous-modules de git:
git submodule add https://github.com/asvbkr/openapi_client.git openapi_client git submodule add https://github.com/asvbkr/TamTamBot.git TamTamBot
Nous ouvrons le répertoire créé dans PyCharm (par exemple, depuis l'explorateur sous le menu contextuel "Ouvrir le dossier en tant que projet PyCharm") et créons un fichier que notre bot contiendra - Fichier / Nouveau / Fichier Python. Dans la boîte de dialogue qui apparaît, entrez le nom - ttBotDevHelper, et répondez positivement à la question de l'ajout à git.
Nous devons maintenant créer un environnement virtuel pour notre projet.
Pour créer un environnement virtuel, sélectionnez Fichier / Paramètres et sélectionnez la sous-clé Project Interpreter dans l'onglet projet. Ensuite, à droite, cliquez sur l'icône d'engrenage et sélectionnez Ajouter:

PyCharm offrira sa propre option d'hébergement.

Il est logique d'être d'accord avec lui.
Après avoir créé l'environnement virtuel, l'écran précédent s'ouvrira, mais il contiendra déjà des informations sur l'environnement créé. Sur cet écran, vous devez installer les packages nécessaires en cliquant sur l'icône "+" à droite et en entrant les noms des packages:
Ensuite, nous ajoutons le fichier .gitignore au projet, à l'exclusion des fichiers qui ne sont pas requis dans git, avec le contenu suivant:
venv/ .idea/ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class *.log *.log.* .env ttb.sqlite3
Ajoutez une variable d'environnement nommée TT_BOT_API_TOKEN
, dans laquelle nous indiquons la valeur du jeton de notre bot reçu de https://tt.me/primebot et redémarrez PyCharm.
(!) Au lieu d'ajouter une variable d'environnement directement à l'environnement du système d'exploitation, PyCharm utilise de manière optimale un fichier spécial .env. Sa configuration sera discutée ci-dessous.
Félicitations, vous pouvez maintenant passer à la partie la plus intéressante - écrire votre bot.
Lancement de bot simple
Ouvrez le fichier ttBotDevHelper.py et écrivez les premières lignes:
Ici, nous créons notre classe de bot basée sur la classe TamTamBot.
PyCharm suggère que la classe BotDevHelper contient des méthodes abstraites qui doivent être implémentées. Appuyez sur Alt-Entrée sur le nom de la classe, sélectionnez "Implémenter des méthodes abstraites", sélectionnez toutes les méthodes (2 d'entre elles) proposées par PyCharm et cliquez sur OK. En conséquence, deux méthodes de propriété vides seront ajoutées: jeton et description. Nous modifions le code résultant comme suit:
La propriété token
renvoie le jeton de notre bot, dont la valeur est tirée de la variable d'environnement TT_BOT_API_TOKEN
. La propriété description
renvoie une description étendue de notre bot, qui sera affichée aux utilisateurs.
Le code à la fin du fichier est nécessaire pour exécuter notre bot en mode d'interrogation d'état.
Je note que la classe de base TamTamBot
implique l'utilisation du serveur web django pour travailler en mode hook web. Mais maintenant, la tâche est plus simple, et nous n'avons pas besoin de django, ce que nous rapportons dans la ligne set_use_django(False)
. Ici, la méthode polling()
est appelée pour l'objet de notre classe, qui assure le fonctionnement dans le mode requis.
Le minimum nécessaire est fait. Ce code fonctionne déjà assez bien. Exécutez-le pour exécuter. Pour ce faire, appuyez sur la combinaison de touches Ctrl-Maj-F10.
Si vous n'avez pas ajouté de variable d'environnement plus tôt, directement au système d'exploitation, une erreur avec le message «No access_token» se produira au démarrage. Pour y remédier, configurez PyCharm pour utiliser le fichier .env.
Montrez commentCréez un fichier texte .env. Son contenu dans notre cas devrait être le suivant:
TT_BOT_API_TOKEN=__
Vous devez maintenant le connecter à la configuration de lancement dans PyCharm:
Nous sélectionnons Exécuter / Modifier la configuration et sur l'onglet EnvFile, nous connectons notre fichier .env:

Cliquez ensuite sur Appliquer.
Après avoir démarré le bot, vous pouvez aller sur TamTam, ouvrir un dialogue avec notre bot et cliquer sur le bouton "Démarrer". Le bot rapportera des informations sur ses super-pouvoirs cachés. Cela signifie que le bot fonctionne. Pendant que le bot fonctionne en mode démo, dans lequel 4 commandes sont disponibles. Vérifiez-les.
Malgré l'opinion prononcée du bot sur sa fraîcheur, il fait timidement allusion au fait que jusqu'à présent, il ne peut rien faire. Lui apprendre tout ce qui est nécessaire à la conquête du monde est notre tâche.
Réception d'un message source et envoi d'un message de réponse avec une représentation interne du message source
Nous bloquerons la méthode receive_text()
, dont le contrôle est transféré lors de l'envoi de texte au chat avec le bot:
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)
L'objet update
de la classe UpdateCmn
, qui est passé à cette méthode, contient diverses informations utiles et, en particulier, tout ce dont nous avons maintenant besoin:
update.message
- un objet contenant le message lui-même;update.link
- lien de réponse prêt à ce message;update.user_id
- identifiant de l'utilisateur qui a envoyé le message.
Pour envoyer un message à partir du bot, nous utilisons la variable self.msg
, qui contient l'objet MessagesApi
qui implémente la fonctionnalité décrite dans la section messages de la description de l' API . Cet objet contient la méthode send_message()
nous avons send_message()
, qui fournit l'envoi de messages. Au minimum, cette méthode doit passer un objet de la classe NewMessageBody
et la destination - l'ID utilisateur, dans notre cas.
À son tour, un objet de la classe NewMessageBody
dans ce cas est créé en transmettant une représentation textuelle de l'objet de message source et un lien de réponse au message source.
Nous redémarrons notre bot et vérifions dans un dialogue avec le bot que le bot génère une réponse à l'un de nos messages contenant la représentation interne de l'objet de message source.
Le code source de cet état est ici .
Ajout d'une nouvelle commande bot avec un paramètre - montrant la représentation interne du message par son identifiant
Lors du développement de robots, il est souvent nécessaire de regarder la représentation interne d'un message en utilisant un ou plusieurs identifiants de message connus (id de message - milieu). Ajoutez cette fonctionnalité à notre bot. Pour ce faire, tout d'abord, nous retirons dans une méthode distincte la fonctionnalité de sortie d'informations sur la représentation interne des messages:
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
Dans cette méthode, nous passons une liste de mid.
Pour obtenir des objets de message, nous utilisons la méthode self.msg.get_messages
, qui renvoie une liste d'objets dans la propriété messages.
De plus, une représentation textuelle de chacun des messages reçus est envoyée à notre dialogue dans des messages séparés. Pour éviter les erreurs, le texte du message généré est tronqué par la constante de la longueur maximale du message - NewMessageBody.MAX_BODY_LENGTH
.
Ajoutez ensuite une méthode qui traite la commande. Appelons cela vmp . Vous pouvez passer la liste médiane à la commande avec un espace.
TTB est conçu pour que le gestionnaire de commandes soit créé en tant que méthode avec le nom cmd_handler_%s
, où% s est le nom de la commande. C'est-à-dire pour la commande vmp, la méthode sera appelée cmd_handler_vmp
. Un objet de la classe UpdateCmn
est transmis au gestionnaire de commandes. De plus, pour une commande, elle peut contenir la propriété cmd_args
, qui contient un dictionnaire de lignes et de mots entrés avec la commande
Le code ressemblera à ceci:
def cmd_handler_vmp(self, update): res = None if not update.this_cmd_response:
Nous redémarrons le bot. Maintenant, si vous tapez une commande dans le dialogue du bot comme: /vmp mid1 mid2
(vous pouvez effectuer leurs vérifications précédentes au milieu), en retour, nous obtenons deux messages avec une représentation interne des objets de message source, pour chacun des mid transmis.
Le code source de cet état est ici .
Modification d'une commande bot pour travailler avec une réponse textuelle
Vous pouvez également essayer de transférer le message à partir d'un autre canal / chat. Mais dans ce cas, seul ce qui est contenu dans le message source en dialogue avec le bot sera affiché. En particulier, lors de l'envoi d'un message, les informations du bouton ne sont pas enregistrées.
Mais que faire si nous voulons voir des informations sur le message d'origine? Dans ce cas, vous devez prendre le milieu du message transféré.
Pour implémenter ce mode, nous modifions la commande vmp de sorte que lorsqu'elle est appelée sans paramètres, elle attend que le message soit transféré, puis prend le milieu du message envoyé et affiche des informations à son sujet.
(!) Pour le bon fonctionnement de cette fonctionnalité, le bot doit être autorisé à lire depuis la source du canal / chat.
Nous modifions le code de commande comme suit:
def cmd_handler_vmp(self, update): res = None if not update.this_cmd_response:
Et depuis avec cette approche, le risque augmente en raison du manque d'accès aux messages, puis dans la méthode view_messages()
nous ajoutons un contrôle de conformité avec le nombre de messages demandés / reçus:
def view_messages(self, update, list_mid, link=None): res = False msgs = self.msg.get_messages(message_ids=list_mid) if msgs:
Nous redémarrons le bot, donnons la commande / vmp, et après que l'invite sur la nécessité du transfert s'affiche, nous transmettons le message à partir du canal / chat. Si le bot a le droit de lire les messages dans ce canal / chat, une représentation textuelle de l'objet de message transféré sera affichée. S'il n'y a pas d'accès, le bot signalera un problème possible et attendra le transfert de la bonne source.
Définition des propriétés du bot
Reste maintenant à apporter du brillant. Fermons la propriété about
, qui renvoie le texte que le robot affiche lorsqu'il commence à fonctionner, ainsi que la commande / start.
@property def about(self): return ' .'
Nous bloquerons la méthode get_commands()
, qui renvoie la liste des commandes de notre bot, qui apparaît dans la boîte de dialogue avec le bot.
def get_commands(self):
Nous remplacerons la propriété main_menu_buttons, qui renvoie une liste de boutons dans le menu principal, invoquée par la commande / menu.
def main_menu_buttons(self):
Nous redémarrons le bot, assurez-vous que tout est en ordre. Félicitations, votre premier bot a été créé et, malgré certains jouets, il a demandé beaucoup de fonctionnalités.
Le code source de cet état est ici .
Le bot de travail @devhelpbot peut être vu ici .
C'est tout pour l'instant. Si le sujet vous intéresse, dans les articles suivants, je peux envisager le développement ultérieur du bot. Par exemple, ajouter des boutons personnalisés (en particulier, Oui / Non) et les traiter, envoyer différents types de contenu (fichiers, photos, etc.), travailler en mode webhook, etc.
Au fait, vous pouvez rapidement poser des questions dans un chat spécial . Dirigez les suggestions / idées là-bas.