How to Create a Telebot With Python [Part 2]


Get Right into the Code

author bryan image

Bryan Ho

24th June 2021

instagram icon github icon linkedin icon
email icon
How to Create a telebot with python

Introduction

Welcome back to the 2nd iteration of this 3 part series on building your very own telegram bot! We will be building on the existing knowledge from the previous article about interacting with BotFather, so check it out before proceeding on to better understand the contents of this article.

In this article, I will be sharing some key functions that will cement the foundation of your bot. These functions below help to construct the URLs to execute specific functions. Although the succeeding lines of code are in python, I will extract the logic of the code for others who would like to build a bot in another language. Well, let’s jump right in with python code!

Content Page

  1. Imports and Constants
  2. Receive Updates
  3. Get Chat ID
  4. Get Text Message
  5. Send Message
  6. Bringing It Together
Python and Telegram Bot


import json
import requests
import urllib
                    

Import the packages that will be needed to build this telegram bot. “requests” library allows you to easily make HTTP requests over the web. “json” library helps with parsing JSON type into a Python dictionary type, which makes the data from our HTTP requests python “readable”. I see it as a translator of sorts. But of course, the descriptions were an oversimplification of what these packages can actually do.


# Bot's token for authentication with Telegram API
token = '{your token}’
# Basic URL for created Telegram bot
URL = "https://api.telegram.org/bot{}/".format(token)
                      

This declares some important variables that are used to construct a variety of URLs for the many functions of our telegram bot.


def get_updates():
    url = URL + "getUpdates"
    response = requests.get(url)
    decode_response = response.content.decode("utf8")
    updates = json.loads(decode_response)
    return updates
                    

This function builds the get updates URL, by adding the “getUpdates” behind our base url. In the 3rd line, we send a HTTP GET request and the response is stored in the “response” variable that is then decoded. The decoded response which is stored in the “decoded_response” variable is then parsed (you can think of it as being transformed) from json type into python dictionary type and finally returned as “updates”. Just to clarify, the updates in this case are all the messages that all users have sent to the telegram bot in the past 24 hours.


def get_last_chat_id(updates):
    num_updates = len(updates["result"])
    last_update = num_updates - 1
    chat_id = updates["result"][last_update]["message"]["chat"]["id"]
    return chat_id
                    

This function takes the output of get_Updates (which is the parameter “updates”) and takes the last message that was sent to the telebot, grabs it’s chat ID and returns it. “num_updates” stores the number of messages that were sent to the telegram bot in the last 24 hours. This seems odd, wouldn’t the “num_updates” then be the index of the latest message? Why are we deducting 1 from that number and storing it into “last_update”? This is because the indexing of a dictionary starts from 0 and not 1, as such we need to account for this difference in “counting convention” by deducting 1.

We then traverse the update dictionary as per ["result"][last_update]["message"]["chat"]["id"] that will then reference the chat ID of the last message and return it in the variable “chat_id”. Note that “result” is actually a list and by using the number stored inside “last_update”, you are actually indexing the list.


    {
     "ok":true,
     "result":[
        {
           "update_id":"xxxxx",
           "message":{
              "message_id":10,
              "from":{
                 "id":"xxxxx",
                 "first_name":"bryan",
                 "last_name":"ho"
              },
              "chat":{
                 "id":24860000,
                 "first_name":"bryan",
                 "last_name":"ho",
                 "type":"private"
              },
              "date":1671080423,
              "Text":"last_message!!"
           ]
        }
                      

For pictorial representation, here is the dictionary. FYI I used a JSON beautifier, which is immensely helpful when you want to get a clear representation of a dictionary which has many embedded dictionaries such as the below.


 def get_last_text(updates):
     num_updates = len(updates["result"])
     last_update = num_updates - 1
     text = updates["result"][last_update]["message"]["text"]
     return text
                       

The logic behind get_last_text function is almost identical to that of get_last_chat_id function. Instead of grabbing the chat_id, we are taking the text. This logic can be applied to any field you would like to use such as the “first_name” and “last_name” fields.


def send_message(text, chat_id):
   url = URL + "sendMessage?text={}&chat_id={}".format(text, chat_id)
   get_url(url)
                         

This function sends a message back to a specified user via the telebot by once again building the specific URL with the parameters. It takes in 2 parameters, text which is the message that you would like the telebot to send and the chat_id of the user.


 def main():
     updates = get_updates()
     user_chat_id = get_last_chat_id(updates)
     user_last_text = get_last_text(updates)

     if user_last_text == “\start”:
        send_message(“Welcome to my first bot!”, user_chat_id)

 if __name__ == '__main__':
     main()
                           

Bringing it all together, run these lines of code in your main. If the last message sent to the telegram bot is “\start”, the bot will reply to that user “Welcome to my first bot!”. The if __name__ == ‘__main__’ is a pythonic convention that is used to execute some code only if the file was run directly, and not imported.

And that’s a wrap, you’ve built your very own telegram bot! Of course, this is by no means very functional, but is it the fundamental building block, a canvas, that you can add your own logic and functions to and create your dream bot!

python and telegram pic

Notes About this Bot

  1. The script must be run from your local everytime you want the bot to send and reply messages. You would need to consider a hosting platform to house your code so that the telebot is able to function 24/7. Some free hosting platforms include PythonAnywhere, Google Cloud Platform and Heroku.
  2. The data (the one seen in the browser) from the get_updates() function will be lost after 24 hours. As such, you will not be able to use data analytics tools to analyze your data and drive any necessary insights. One way to circumvent this problem is to set up a database to store the data that you have collected. Some free database platforms include Postgres for SQL Database and mongoDB for NoSQL Database.
  3. There are major problems with the get_updates() function. Firstly, the script throws an error if there are no new updates. Secondly, it returns all the messages that were sent to the bot in the past 24 hours, even the ones that you have already “processed”, which is not efficient and useful. Thirdly, it does not automatically get updates when new messages are sent.
  4. This bot does not utilise 3rd party python packages that can actually make building your telebot much simpler.

Conclusion

Luckily, in the 3rd part of this series, I will be going through some of the problems mentioned above to make our telegram bot more robust and functional. We will explore 3rd party packages in detail, build inline keyboards, message callbacks and more.

Hope this article proved useful to you and if it was, do share it with your friends! Your support means a lot to us! Thank you and stay cool Cucumbers!