How to Create and Deploy a Telegram Bot using Python?

Introduction or Why You Should Try a Bot

(you may skip it if you already know what to do with your bot)

Bots are everywhere. It seems that only yesterday we did not even know about their existence; now we can barely imagine our life without them. They’ve become widely popular among numerous active users of messengers since they have various scopes of use – from entertaining content including step-by-step games and collecting bonus points in restaurants, to keeping a diet plan, tracking deliveries, and even making payments for different services.

Why are they so popular? What’s their secret? I think the more relevant question is why they are more convenient than an app. And there are a few reasons.

1) Minimalistic and simple design.
Well, the bot simply cannot have colorful design. But beyond any doubts, in comparison to numerous apps with different design when you have to remember where and what to tap, bot is more universal and easy; it offers a simple communication via texts.

2) Bot has minimum of advertising and focuses on the users’ needs.
You do not have to install hundreds of apps for each service if you can receive all necessary assistance from a bot. This is particularly useful for restaurants and shops. Clients are rarely eager to install apps from a bunch of places they’ve visited. Due to this, business owners miss clients’ feedback and lose communication with them. If each of these places had their own bot available in different messengers, it would be more convenient and friendly to users. Nobody likes to fill up the storage of their phones with unnecessary apps that will be used once or twice. However, clients need to engage with the service owners and they will appreciate doing this through their favorite messenger.

3) No need for signing up, authorization, and constant relogin
Using a bot, user passes authorization only once when the bot is added to the chat. Client can use the bot as much as it is necessary, and when there is no need in it anymore, user just blocks the bot. That’s all, easy! No password resets anymore.

No need to remember passwords or logins used. Adding bot to the site or app increases the number of the user audience as it makes communication with clients and providing them with the assistance much easier and user-friendly.

So, we described main advantages of the bots and now you must be willing to create your own bot. Let’s move on to the practice. But first, we’ll take a look at issues that must be addressed in the pre-development stage.

Nuances of Telegram Bot Development

When we’ve already determined reasons for creating the bot, now it’s time to think on how we plan to organize the development process and what tools we will need. Further, we will demonstrate in practice how to create your first bot and how to teach it to turn our message inside out.

In this part, we are planning how to build the application and what development tools to use. Further, we’ll show how to build your first Telegram bot and will teach it to turn our message backwards.
Since it is the manual for beginners, we will run the server with a single endpoint that will receive our telegram messages and will make an answer.

For that, we will use the following tools:

  • bottle – for our server; a simple and lightweight WSGI micro web-framework
  • requests – for sending requests to telegram. request lib does not need to be overrepresented. It is universally used throughout the world in a variety of projects.
    Note: you have to install these tools on your computer. We will need them later. For that, open your bash console and install it via pip
pip install bottle requests  
  • ngrok – this is an app which provides us with public URLs for our interaction with Telegram WebHook throughout the development phase (look for info on WebHook below). It is useful, as Telegram will not be able to make a connection with our local server because we cannot specify our local address in the Telegram API configuration.
    You should download ngrok from the official site and put the installed app in the folder with the project.

How About to Create Your First Bot?

If you are keen on this, explore this part where we will provide a detailed Telegram bot development tutorial.

First things first. You need to register on Telegram (obviously). I recommend to use Telegram web client for testing the basic concepts.

Open Telegram app, search for @BotFather and start the chat. Send /newbot command and follow the instructions. After completing the initial steps, you’ll get —

Wells, that’s actually it. At the moment the bot is 100% passive.

You need to initialize a conversation with your bot. Open search and type in the name of your bot. Start a conversation by clicking on /start button. Type in something like “Hello”. This message is important as it’s the first update your bot is going to receive.

If it’s your first experience with building APIs, you can easily get the idea using your web browser. Open a new tab in your browser and use the Telegram api URL –

https://api.telegram.org/bot<token>/getUpdates

When you open this URL in your web browser, you make a request to Telegram server, that responds back with JSON. Response resembles Python dictionary. You should see something like this:

{"ok":true,"result":[{"update_id":523349956,
"message":{"message_id":51,"from":{"id":303262877,"first_name":"YourName"},"chat":{"id":303262877,"first_name":"YourName","type":"private"},"date":1486829360,"text":"Hello"}}]}

If you open bots documentation and check /sendMessage method section you’ll notice that this method requires 2 additional parameters chat_id and text. In a browser search bar you can chain parameters using ? for the first one and & for all the consequent. Send message would look like this –

/sendMessage?chat_id=303262877&text=test

Try to get the reply from your bot by substituting chat_id with one you get by calling /getUpdates. In my case it is 303262877. Text parameter is up to you. The request should look like this

https://api.telegram.org/bot<your-token>/sendMessage?chat_id=&text=<your-text>

WebHook

(You can skip this part if you’re familiar with WebHook)

To put it short, a WebHook is an API concept that grows in popularity. The concept of a WebHook is simple. A WebHook is an HTTP callback: an HTTP POST that occurs when something happens; a simple event-notification via HTTP POST.

To explain a bit more, sometimes an interaction between apps online requires immediate response to the event, while solutions for constant and continuous connections are mostly cumbersome, exacting and hard to support. In this case, the best and the easiest solution is immediate callback via HTTP (most often POST).

In other words, this solution ensures response to any event inside the one app by means of sending HTTP POST request to other connected app in order to inform it or to make it respond.

This exact concept is called WebHook. It is widely used for:

  • receiving data in real time
  • receiving data and passing it on
  • processing data and giving something in return

Seems that it is the best solution for interaction of the Telegram client (Telegram app) with our project.

Coding Part

At last, we start the most practical part where you will be able to develop a Telegram bot.

Main task: teach our bot to turn our message backwards

Firstly, create a folder for our bot project.

Secondly, create bot.py file to make a bottle server.

Next, we develop bot.py

from bottle import run, post


@post('/')  # our python function based endpoint
def main():  
    return 


if __name__ == '__main__':  
    run(host='localhost', port=8080, debug=True)

Let’s try to start our server. For this, open bash in your bot folder.

python bot.py  

In the result, you should see something like this:

Then, open a new tab. In the next tab, we will start ngrok

./ngrok http <our_server_port>

./ngrok http 8080

After, you’ll see something like this:

Now, let’s set WebHook.

https://api.telegram.org/bot<your_token>/setWebHook?url=https://<your_ngrok_url.ngrok.io/

  • Note: to find ngrok URL, you have to launch ngrok. Then, on the screen similar to the one below, you’ll find URL (it is highlighted on our screenshot). This URL you use in the link for setting WebHook.

Response to following the link should be like:

{"ok":true,"result":true,"description":"Webhook was set"}

Let’s check if you succeeded in setting up WebHook. Follow this link using your token:

https://api.telegram.org/bot<your_token>/getWebhookInfo

If everything is right, you’ll see the same ngrok address value in front of URL key that you specified when configuring.

Congrats, it’s alive!

Now, we need to implement a message request/response mechanism.
Basically, our endpoint gets data in json format. So, normally, you’ll see data message.

from bottle import run, post, request as bottle_request  # <--- we add bottle request

@post('/')
def main():  
    data = bottle_request.json  # <--- extract all request data
    print(data)

    return 


if __name__ == '__main__':  
    run(host='localhost', port=8080, debug=True)

It should be something like that in your console tab where the server is launched.

{'update_id': <integer>, 'message': {'message_id': <integer>, 'from': {'id': <your telegram id>, 'is_bot': False, 'first_name': '<your telegram name>', 'last_name': '<...>', 'username': '<...>', 'language_code': 'en-En'}, 'chat': {'id': <integer chat id>, 'first_name': '<...>', 'last_name': '<...>', 'username': '<...>', 'type': 'private'}, 'date': 1535022558, 'text': '1'}}

More detailed information on the parameters you may find in the official documentation of Telegram.

Now, we have to extract chat_id and text in order to turn our message backwards and send the answer.

from bottle import (  
    run, post, response, request as bottle_request
)


def get_chat_id(data):  
    """
    Method to extract chat id from telegram request.
    """
    chat_id = data['message']['chat']['id']

    return chat_id


def get_message(data):  
    """
    Method to extract message id from telegram request.
    """
    message_text = data['message']['text']
    return message_text


def change_text_message(text):  
    """
    To turn our message backwards.
    """
    return text[::-1]


@post('/')
def main():  
    data = bottle_request.json
    answer_data = prepare_data_for_answer(data)

    return response  # status 200 OK by default

Now, we’ve already prepared the answer. Let’s send it to Telegram bot.

import requests  
from bottle import (  
    run, post, response, request as bottle_request
)

BOT_URL = 'https://api.telegram.org/bot<YOUR_TOKEN>/' # <--- add your telegram token here; it should be like https://api.telegram.org/bot12345678:SOMErAn2dom/


def get_chat_id(data):  
    """
    Method to extract chat id from telegram request.
    """
    chat_id = data['message']['chat']['id']

    return chat_id

def get_message(data):  
    """
    Method to extract message id from telegram request.
    """
    message_text = data['message']['text']

    return message_text

def send_message(prepared_data):  
    """
    Prepared data should be json which includes at least `chat_id` and `text`
    """ 
    message_url = BOT_URL + 'sendMessage'
    requests.post(message_url, json=prepared_data)  # don't forget to make import requests lib

def change_text_message(text):  
    """
    To enable turning our message inside out
    """
    return text[::-1]

def prepare_data_for_answer(data):  
    answer = change_text_message(get_message(data))

    json_data = {
        "chat_id": get_chat_id(data),
        "text": answer,
    }

    return json_data

@post('/')
def main():  
    data = bottle_request.json

    answer_data = prepare_data_for_answer(data)
    send_message(answer_data)  # <--- function for sending answer

    return response  # status 200 OK by default

if __name__ == '__main__':  
    run(host='localhost', port=8080, debug=True)

After all preparations and coding, if everything works, let’s try to chat with our bot.

Now, let’s make our code more readable and implement OOP structure.

import requests  
from bottle import Bottle, response, request as bottle_request


class BotHandlerMixin:  
    BOT_URL = None

    def get_chat_id(self, data):
        """
        Method to extract chat id from telegram request.
        """
        chat_id = data['message']['chat']['id']

        return chat_id

    def get_message(self, data):
        """
        Method to extract message id from telegram request.
        """
        message_text = data['message']['text']

        return message_text

    def send_message(self, prepared_data):
        """
        Prepared data should be json which includes at least `chat_id` and `text`
        """       
        message_url = self.BOT_URL + 'sendMessage'
        requests.post(message_url, json=prepared_data)


class TelegramBot(BotHandlerMixin, Bottle):  
    BOT_URL = 'https://api.telegram.org/bot000000000:aaaaaaaaaaaaaaaaaaaaaaaaaa/'

    def __init__(self, *args, **kwargs):
        super(TelegramBot, self).__init__()
        self.route('/', callback=self.post_handler, method="POST")

    def change_text_message(self, text):
        return text[::-1]

    def prepare_data_for_answer(self, data):
        message = self.get_message(data)
        answer = self.change_text_message(message)
        chat_id = self.get_chat_id(data)
        json_data = {
            "chat_id": chat_id,
            "text": answer,
        }

        return json_data

    def post_handler(self):
        data = bottle_request.json
        answer_data = self.prepare_data_for_answer(data)
        self.send_message(answer_data)

        return response


if __name__ == '__main__':  
    app = TelegramBot()
    app.run(host='localhost', port=8080)

That’s pretty much it. Now you have a working Telegram bot that can even spell “racecar” backwards. Congrats!

Comments