In this article we are going to build a fully-working Telegram bot for searching news from thousands of sources all over the web.
Telegram is a popular messaging app. It is well-known for its security and efficiency. Apart from being able to send messages to each other, its users can also create bots to automate certain routine tasks.
We will use python-telegram-bot wrapper around the official API. This library significantly simplifies the job of the programmer when writing a bot. It is always easier to learn something new by reading through a couple of examples. Here is one:
This small piece of code creates a bot that recognizes two commands:
Let's go through each line in detail and discuss what this code does.
We start with the main function:
This function sets up all the necessary machinery needed for our bot to work. Particularly, it creates an instance of the Updater class. Note that you need a Telegram token to be able to use Telegram bot API. Check out the official guide on how to create bots here.
Back to the code! The purpose of the Updater is to deliver updates (e.g. messages sent by users) to Dispatcher. When the latter receives an update, it tries to dispatch some of the user-specified callbacks to handle it. Each of those callbacks is managed by some handler.
You can think of a handler as a function to handle an update that is only executed when some condition is met. The condition in question, though, depends on the handler and can be specified by the programmer. In our case, we have two instances of CommandHandler class.
Each of them handles a particular command, supported by our bot - /start and /greet respectively.
Then we call start_polling method.
This will make our bot periodically fetch updates from the Telegram server. This method will internally create two threads: one will poll updates from the Telegram server, the other one will be used by the dispatcher to handle those updates.
The next line makes sure our bot correctly handles various interruption signals (e.g. SIGINT).
This is required when we want our bot to have persistent state. You can learn more about it and other cool library features in their wiki.
Let's now discuss two callback functions that handle bot's commands:
Each of these functions takes two arguments:
Additionally, each of these methods sends a text message back to the user.
You can check out more elaborate examples of Telegram bots in the library's official repo.
Let's now move on to the main topic of our discussion.
Datanews provides API for retrieving and monitoring news from more than a thousand different newspapers, news aggregators and other websites. We collect and process more than 100k news articles a day. Naturally, we provide a flexible and easy-to-use API for querying those articles. For our small project, though, we only need a small part of that API. Particularly, we want our bot to be able to:
These use-cases can be handled by a single end-point - /headlines. You can learn more about the provided API in the official documentation.
Now we can go straight to the implementation of our bot.
First of all, let's define a callback that handles the /start command.
As you can see, the implementation closely resembles our bot example above - we simply return the help information to our user. You can notice that our bot will support four commands. The help_command function implements the first two of them. Let's now discuss the other two.
These functions look very similar. They both use the /headlines API endpoint as discussed earlier (we are using the official Datanews library for Python here). They both delegate their work to a helper _fetch_data. The only difference is in the arguments we pass to the Datanews API: search_command retrieves articles matching a certain query whereas publisher_command fetches all articles as long as they are published by a specific source. Note, however, that in both cases we only get the first 10 most recent articles.
Let's now take a look at the helper that does all the job.
This function simply checks that the user has indeed specified required arguments to the command, fetches the data from the Datanews API and sends it in reverse order to the user. A couple of comments here:
With this out of the way, let's take a look at the main function.
This function is very similar to the one from the example. The only major difference is in the following lines:
The MessageHandler is used to catch messages sent by the user. You can think of it as a CommandHandler on steroids: it processes any messages that satisfy a specified filter. In our case, we want to print help information every time the user sends a text message containing the help word.
That's it. Now you have a fully functional news bot.
Well, that was fun! We discussed the Telegram bot API and its implementation in Python. We also gave a brief overview of Datanews API and built our own news bot that uses it. However, this is only a tip of the iceberg: we can add support for news monitoring and many other cool features to our bot as easy as we just did. Hopefully, I managed to convince you that using Datanews API is not harder than using Telegram bot API for Python.