Application For A Framework For A Multiplatform Bot
Chatbots are tightly integrated into our information life, in all self-respecting social networks and messengers there is support for bots, for their development and use, they provide a convenient API, everything for the convenience of users and programmers. Now, to create a bot in Telegram, you do not even need to know any programming language.
There are services that allow you to design a bot using the web interface. And it’s really good, but more recently we were faced with a problem and was surprised that on this whole wave of chatbot’s popularity, which are now not just a cool feature, but also an income-generating tool – there is practically no answer.
And the question is: what if we want to create more than one bot for one service? For example, we know that Central Asia is sitting in Vkontakte and Telegram, how do we, with minimal effort, write bots working with people both here and there? If suddenly we want to use bots to work with the audience on Facebook, do we really have to develop a new bot from scratch and rewrite all the logic under it or try to understand the new API or library?
- In fact, there are solutions, and there are many, but they all boil down to the fact that you have to host your bot from a service that also provides a platform. That is, as-such a boxed solution is not obtained. Perhaps I’m wrong and did not fully understand what actually is, but the very fact that the first link in Google does not lead to a solution is already alarming. There is also a Botman. This is really a powerful full-fledged developing opensource library with a bunch of chips and comprehensive documentation. And it’s written in PHP.
We do not have anything against PHP, in any case, we do not recognize it publicly, so as not to build unnecessary things, but we do not want to develop it on it at all. We decided to look for something similar to Python, in addition to Python, there is a lot of libraries that allow working with the Telegram Bot API. And we did not find anything, so we soon came to the conclusion that we should write ourselves.
In general, we will provide a small part of the code and using Botovod and explain it in brief.
Spoiler Header
from botovod import Botovod, Message, utils @ utils.convert_to_text def handler_message (agent, chat, text): message = Message () message.text = "I received a message" agent.send_message (chat, message) @ utils.convert_to_images def handler_images (agent, chat, images): message = Message () message.text = "I see a photo" agent.send_message (chat, message) def handler_echo (agent, chat, message): agent.send_message (chat, message) settings = [ { "name": "telegram", "agent": "botovod.agents.telegram", "settings": {"token": "462755273: AzBZBQ7AAnqFEXqZ_P8Z-qvCddmjqTVAYPI", "method": "polling"} }, ] botovod = Botovod (settings) botovod.add_handler (handler_message) botovod.add_handler (handler_images) botovod.add_handler (handler_echo) botovod.start ()
Here we define 3 handlers for incoming messages, each sends something in response. The first one: “we received a message”, the second one: “we see a photo”, the third one will simply send back what he received.
Then we create the bot manager (Botovod) and send it the bot settings, in this for the bot in Telegram.
Then we successively add message handlers.
If a message arrives at the bot, it will go to the first handler who agrees to accept it.
For example, if we were sent audio, then first it will try to accept the first handler, but it will refuse since this is not text. Then he will take the second one, but he will also refuse because this is not a picture, then he will take the third one, which has no limitations, so he will send audio back. Restrictions are imposed as decorators from the utils module.
Now we will try to tell you in detail what’s what:
- There is a bot manager – an object of the Botovod class – the bot name (each has its own unique one), the agent class that will process it and the settings for the bot, is passed to it in the constructor.
- Also in the bot manager added in turn handlers. If a message comes to the bot, the manager will check them in turn until it finds the handler that does not throw the NotPassed exception. The first added handler is checked first, last, respectively, the last one.
- If you are going to use Webhook, then the Bot manager can be connected to the web server. For this, the Bot manager has a listening method that takes the bot name, headers, request body.
- Next, it passes this data to the agent’s parser, which returns the generated message, after this message is pushed through the handlers. In response, the listen method returns a dictionary {“status”: any_code, “headers”: direct (), “body”: “any_text”}, where headers are the response headers, and in the body the response body. Sometimes an instant messenger/social network requires the server to return an object, so we think this behavior is convenient.
We will give an example for bot Vkontakte under the name “vk-bot“, and Botovod will connect to the server Django:
def view (request): response = manager.listen ("vk-bot", request.headers, request.text) return HttpResponse (status = response ["status"], headers = response ["headers"], response ["body"]
A generated message is an object of the Message class. It includes fields:
- text – the text of the message;
- images – list with images;
- audios – list with audio files;
- videos – list with video;
- documents – list with documents;
- locations – a list with places on the map;
- raw – the raw message body or additional information to it (dictionary).
Also, each list of the Message object (images, audios, videos, documents) contains special objects whose classes are inherited from Attachment. The default Attachment class has an url and file_path method, in which agent parsers usually put information about the received file. The list of locations contains the Location objects, in the constructor to which you must pass longitude and latitude (longitude and latitude).
Below is an example of constructing messages in handlers.
def handler (agent, chat, message): out = botovod.Message () image = botovod.Image () image.file_path = "/tmp/1.png" location = botovod.Location () out.images.append (image) out.text = "Here's a photo of what you asked for" agent.send_message (chat, out)
This is still all that is in it, but we hope that someone will be interested in such a decision and someone will want to help with advice, comment, idea, or maybe their own participation in the development. Thank you all for reading!