Telebot using Python

Telebot using Python

In this article, we will build a Telegram Bot using Python, which will send cat 😺 photos and cat facts. For this, I will be using pytelegrambotapi library.

Setting our Bot

First, we will need a Telegram account, if you don't have one you can create one easily. In telegram, search for BotFather. It will look as shown in the image.

BotFather

Then we have to send start and then follow the instructions given by BotFather. In short, /start > /newbot > name for bot > username for Bot(unique). After this, BotFather will provide Token to access our bot. Format of AUTH token will be like this 1111111111:AAA_A_aaaaaaaaaaaaaaaaaaa_aaaaaaaaa.

Steps to build the bot:

Now we move to our code. First we will create a virtual environment using venv.

💡 Note: You can use other options too.

If you know this part feel free to skip⏩.

Setting Virtual environment:

In terminal, open your directory and enter following command.

python -m venv venv

To Activate your virtual environment:

venv\Scripts\activate

Terminal will look like this..

(venv) (project_path)

Dependencies required:

You can find whole code and requirement here.

pyTelegramBotAPI==3.7.9
python-dotenv==0.17.1
requests==2.25.1

Code

Finally, create a python file to write our script. First, let's import requirements. For now, we will just import telebot and incoming parts, we will import others as when required.

purrrfect_bot.py

import telebot
import os
from dotenv import load_dotenv

Now we will store our token in a variable. For this, create a file .env in the same directory. And store the token in the AUTH_TOKEN variable.

.env

AUTH_TOKEN = 'YOUR_TOKEN'

Now, we have to load this Token in our main file.

purrrfect_bot.py

load_dotenv()
token = os.getenv('AUT_TOKEN')

After this, we will create the instance of our bot and start polling the messages.

purrrfect_bot.py

bot = telebot.TeleBot(token) # creating a instance

def main():
    bot.polling() # looking for message

if __name__ == '__main__':
    main()

To check our bot, we will set one message handler such that whenever we send /greet (command) or /start, the reply should be "Hello, how are you?".

purrrfect_bot.py

@bot.message_handler(commands = ['greet','start'])
def greet(message):
    msg = ''' Hello, how are you? '''
    bot.reply_to(message, msg)

In above part, whenever we will send command greet or start to our bot, greet function will run.

reply_to method send reply to /start or /greet i.e. to the message.

To check our code, we will run code in terminal

python <main_file_name.py>

Try sending /start or /greet to the bot, it should reply "Hello, how are you?" start function

But if we don't want to reply to message then we can use send_message method.

purrrfect_bot.py

@bot.message_handler(commands = ['greet','start'])
def greet(message):
    msg = ''' Hello, how are you? '''
    bot.send_message(message.chat.id, msg)

To use send_message, we will require the id of the sender. We can get this id from the message itself i.e. message.chat.id.

After running, we will get message without reply.

start function without reply

Now, if a user sends anything other than commands, the bot will not reply with anything. For this, we can set message_handler with the function that will send the same message back to the user. For more information, see the documentation.

@bot.message_handler(func=lambda m: True)
def repeat(message):
    bot.send_message(message.chat.id, message.text)

repeat the message

💡 Note: It will work with only text/emojis and not with stickers or any other type of media.

API

So our main aim is to send cat images and facts whenever the user sends a command. To get the cat images and cat facts, we will be using two Public API.

{
    "id": 35,
    "url": "https://i.thatcopy.pw/cat/UJzx759.jpg",
    "webpurl": "https://i.thatcopy.pw/cat-webp/UJzx759.webp",
    "x": 47.55,
    "y": 60.05
}
{
    "status": {
        "verified": true,
        "sentCount": 1
    },
    "type": "cat",
    "deleted": false,
    "_id": "591f9890d369931519ce353d",
    "__v": 0,
    "text": "The domestic cat is the only species able to hold its tail vertically while walking. You can also learn about your cat's present state of mind by observing the posture of his tail.",
    "source": "api",
    "updatedAt": "2020-08-23T20:20:01.611Z",
    "createdAt": "2018-01-04T01:10:54.673Z",
    "used": false,
    "user": "5a9ac18c7478810ea6c06381"
}

Both the output are in JSON format. In the first API, We will use a url for sending the image or webpurl to send the cat sticker😸. And in the second API, we will use text to send the facts.

To make GET request to API, we will use request module.

purrrfect_bot.py

import telebot
import os
from dotenv import load_dotenv
import request

We will write functions to get the image URL and facts.

purrrfect_bot.py

def get_url():
    contents = requests.get('https://thatcopy.pw/catapi/rest/').json()
    image_url = contents['url']
    return image_url

def get_fact():
    contents = requests.get('https://cat-fact.herokuapp.com/facts/random?animal_type=cat&amount=1').json()
    fact = contents['text']
    if len(fact) < 10:
        return get_fact()
    return fact

Note that the get method is used to make a GET request. As our response is in JSON form, request.json() will convert in the dictionary. Hence, we can access it as key-value pair i.e. content['url'] and contents['text'].

If statement is used to not send the facts whose length is less than 10.

Now we have to set commands for which bot will send image or fact.

purrrfect_bot.py

@bot.message_handler(commands = ['meow'])
def meow(message):
    url = get_url()
    bot.send_photo(message.chat.id, url)

@bot.message_handler(commands = ['fact'])
def fact(message):
    fact = get_fact()
    bot.send_message(message.chat.id, fact)

In my case, /meow will send the image, and /fact will send the fact. In the get_url function change, url to webpurl, and in the meow function, use send_sticker instead of send_photo to send_sticker in place of the image.

💡 Note: Make sure these message handlers are placed above repeat. Otherwise, the bot will send a command in reply.

To get more help about what commands have to be used, we can also edit our /start message.

purrrfect_bot.py

@bot.message_handler(commands = ['greet','start'])
def greet(message):
    msg = ''' Hello, how are you? 
Send /meow to get a cat image.
Send /fact to get random Cat Fact.'''
    bot.send_message(message.chat.id, msg)

meow and fact function

Now, if we want images or facts on just meow or fact i.e. without '/' (text).

We can add regex to the same function. We can stack two decorators on the same function. After editing, the code will look like this

purrrfect_bot.py

@bot.message_handler(commands = ['meow'])
@bot.message_handler(regexp=r'meow')
def meow(message):
    url = get_url()
    bot.send_photo(message.chat.id, url)

@bot.message_handler(commands = ['fact'])
@bot.message_handler(regexp=r'fact')
def fact(message):
    fact = get_fact()
        bot.send_message(message.chat.id, fact)

meow and facts function with regex

So, our bot is ready and sending us happiness in form of photos. You can customize it as you want and have fun with it. Feel free to give feedback or to ask any doubt..

Repository link: https://github.com/PoojaGhodmode/CatBot

References: