/ tuesdaytooling

Tooling Tuesday: pyTelegramBot

Send and receive messages using a bot on Telegram...but you can do so much more with just a little Python code.

So what is Telegram?

Telegram is a messaging service that offers private, encrypted, self destructing(!) messages between peers.

Signing up for an account is free, and available across many platforms. If you would like to try out the code in this blog post, then you will need to sign up for a free account.

So what are we doing with it?

Using a cool Python library we are going to take our first steps in using a bot to automate a task.

So what do I do first?

Screenshot-from-2019-09-01-20-05-09
Before we get into the code, we need to open Telegram and pay a visit to The Botfather....
The Telegram app should now open, and you will be talking to the Botfather, asking it to create a new bot using the command /newbot
Screenshot-from-2019-09-01-20-35-29
The Botfather will then ask you a series of questions, answer them and at the end you will get an API key for your bot which you really need to keep safe as we will use it later! You will also see a URL for the bot click on the link, and in the new conversation click on < START > to start the bot.

With the bot started we can move on to using the Python library.

So what is the Python Library?

pyTelegramBotAPI is the library that we shall be using and to install it we need to use pip.

For Linux / Mac users

sudo pip3 install pyTelegramBotAPI

For Windows users

pip3.exe install pyTelegramBotAPI

The library was created by Frank Wang and it is there to make using the Telegram API easier for Python coders.

I want to do something!

Peek-2019-09-01-22-18
Lets write a quick "Hello World" app that will post a message from the bot when we say hello.

import telebot

bot = telebot.TeleBot("YOUR API KEY HERE")
def handle_messages(messages):
	for message in messages:
		bot.reply_to(message, 'Hi')

bot.set_update_listener(handle_messages)
bot.polling()

I import the library and then create an object bot that will use the API KEY to make a secure connection.
Then I create a function to handle messages. The bot will respond to any message it receives by repeating the message and then saying "Hi".
A listener will then "listen" for a message and respond. The last line is "polling" and this will keep the bot looking for new messages.

Save and run this code, and then go into Telegram and start talking to the bot.

I want do something a little more...interesting

Peek-2019-09-01-21-44
Let's reuse some code from my wttr blog post. This code will get the weather on demand! All I need to do is send the bot the command /weather.

import telebot
import requests

bot = telebot.TeleBot("YOUR API KEY HERE")
@bot.message_handler(func=lambda msg: msg.text is not None and '/weather' in msg.text)
def send_welcome(message):
    blackpool = requests.get('https://wttr.in/Blackpool?format=3')
    bot.reply_to(message, 'The weather today is...'+blackpool.text)

bot.set_update_listener(handle_messages)
bot.polling()

The first two lines are the imports for telebot and the requests library, then we create the connection for our API KEY to Telegram. But for the next line we create a "message_handler" that will look for messages which contain the string "/weather". If the message is a None Type (it contains nothing, no data of any type) then it will not trigger anything.
If the message contains "/weather" then it will trigger the weather script. This will create a variable, in this case blackpool (you can change this...unless you live there) and then I use the requests library to get the weather data from wttr.in.
I then instruct the bot to reply with the weather details.

Save and run the code! Now ask the bot what the weather is like using /weather.

Honestly Les I don't want to do weather..Can I post images?

Sure! But you will need your chat ID which can be found by first sending a message to your bot. Anything!

Then visit this link, but replace the API KEY bit with your bot's API key.
https://api.telegram.org/bot>>APIKEY<</getUpdates

This will give you a string of JSON, which contains lots of data, I've redacted the JSON a little to protect my details.

{"ok":true,"result":[{"update_id":NUMBER,
"message":{"message_id":NIMBER,"from":{"id":887379084,"is_bot":false,"first_name":"Les","last_name":"Pounder","language_code":"en"},"chat":{"id":887379084,"first_name":"Les","last_name":"Pounder","type":"private"},"date":NUMBER,"text":"Hello Krusty"}}]}

You will see a section like this...

"chat":{"id":887379084,

That is your chat ID, and it is needed to post a message and images!

So what did I build with this?

krusty

I built a Krusty the Clown bot...obvs!

krusty
Just send it hey hey and it will respond with a random quote, and a stock image.

from random import choice
import telebot
TOKEN = "API KEY"
chatid = "Your chat id"
tb = telebot.TeleBot(TOKEN)

quotes = ["A GREAT MAN ONCE OBSERVED: ‘90% OF SUCCESS IS SHOWING UP ON TIME.’ SORRY I’M FOUR HOURS LATE...",
    "PUT FIVE THOUSAND BUCKS ON THE LAKERS. HIRE KENNY G TO PLAY FOR ME IN THE ELEVATOR. MY HOUSE IS DIRTY, BUY ME A CLEAN ONE.", 
    "THERE ARE ONLY TWO RULES IN TV: DON’T SWEAR, AND DON’T WHIP IT OUT. IT’S NOT ROCKET SCIENCE!"]

@tb.message_handler(func=lambda msg: msg.text is not None and 'hey hey' in msg.text)
def send_welcome(message):
    photo = open('Krusty.png', 'rb')
    tb.send_photo(chatid, photo)
    tb.send_message(chatid, choice(quotes))

while True:
    try:
        tb.polling()
    except KeyboardInterrupt:
        print("EXIT")
        break
    except Exception:
        time.sleep(15)

So I import the random library and use the choice function from it. I then create a list of quotes.
Using the Telegram message handler to react to the phrase hey hey I create a function that will send an photo by opening the image of Krusty that I have on the computer. This is then sent to the chat using tb.send_photo and then the random quote is sent using tb.send_message.

Can I do anything else with it?

Why yes!! I used it with GPIO Zero to control LEDs on my Raspberry Pi 4.
I show you how to do this, and send live system information from a running Raspberry Pi server in Linux Format magazine issue 256

Happy Hacking!

Did you enjoy this?
Want to buy me a cup of coffee?