Redouane Niboucha · 7 min read · Updated may 2024 · Application Programming Interfaces
Step up your coding game with AI-powered Code Explainer. Get insights like never before!
Automation is becoming more and more popular every day, and so, popular services and applications nowadays often offer an interface for programmatic use, this interface is what we call an API, or Application Programming Interface, examples of applications offering an API include Google Drive, Google Search and Github.
An API is a set of endpoints any programmer can use to communicate with a service without having to try imitating a user using the application, which is often not possible because of captchas becoming more and more widely used.
When a popular application offers an API, programmers usually write easy-to-use libraries (which act as an abstraction layer to the API, often called wrappers), for a programmer who wants to communicate with the application instead of reading the reference about the API endpoints, it’s more straightforward to just download a library in their programming language of choice, and read its documentation, which is often more idiomatic, and faster to get used to.
In this tutorial, we will see how to write a Telegram Bot in Python, a bot is a user controlled by code, writing a bot can have many applications, for example; automatically responding to client requests.
Telegram offers two APIs, one for creating bots, and one for creating clients, we will be using the first one, documentation for the Bot API can be found here.
We will be using the popular python-telegram-bot
wrapper to ease the work for us:
pip3 install python-telegram-bot
Now, we will need to get an API Key to communicate with the Telegram API, to get one, we need to manually contact @BotFather on Telegram, like so:
We get a list of commands when we start the discussion; we create the bot with the /newbot
command, once it's created, we obtain a token to communicate with the bot (in our case, it's hidden in red).
Now we can start writing our bot in Python:
import telegramimport telegram.extimport refrom random import randintimport logginglogging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')# The API Key we received for our botAPI_KEY = "<INSERT_API_KEY_HERE>"# Create an updater object with our API Keyupdater = telegram.ext.Updater(API_KEY)# Retrieve the dispatcher, which will be used to add handlersdispatcher = updater.dispatcher
Notice we added logging in the beginning of the script, and we set the logging level to DEBUG
, this will help us understand what's going on with the bot, whether it's running, messages we get from our users, etc. If you're not familiar with logging in Python, check this tutorial.
The dispatcher is the object that will dispatch requests to their handlers, we need to add a conversation handler to it, to describe the way our bot will reply to messages.
The Telegram API allows defining the bot as a finite-state machine, we can handle different events, and change states according to the input of the user, or the type of actions.
For this tutorial, we'll be building the following FSM:
Execution begins at Start, Welcome will ask the user whether he wants to answer a question, if the response is yes or y, it will send the question, and switch state to Correct if the response is correct. Otherwise, it will loop on Question, each time generating a different question.
Once the response is correct, it'll ask the user if he found the tutorial helpful and go to the end state, which is the final one.
Defining our states:
# Our states, as integersWELCOME = 0QUESTION = 1CANCEL = 2CORRECT = 3
Now, let's define our handlers:
# The entry functiondef start(update_obj, context): # send the question, and show the keyboard markup (suggested answers) update_obj.message.reply_text("Hello there, do you want to answer a question? (Yes/No)", reply_markup=telegram.ReplyKeyboardMarkup([['Yes', 'No']], one_time_keyboard=True) ) # go to the WELCOME state return WELCOME# helper function, generates new numbers and sends the questiondef randomize_numbers(update_obj, context): # store the numbers in the context context.user_data['rand_x'], context.user_data['rand_y'] = randint(0,1000), randint(0, 1000) # send the question update_obj.message.reply_text(f"Calculate {context.user_data['rand_x']}+{context.user_data['rand_y']}")# in the WELCOME state, check if the user wants to answer a questiondef welcome(update_obj, context): if update_obj.message.text.lower() in ['yes', 'y']: # send question, and go to the QUESTION state randomize_numbers(update_obj, context) return QUESTION else: # go to the CANCEL state return CANCEL# in the QUESTION statedef question(update_obj, context): # expected solution solution = int(context.user_data['rand_x']) + int(context.user_data['rand_y']) # check if the solution was correct if solution == int(update_obj.message.text): # correct answer, ask the user if he found tutorial helpful, and go to the CORRECT state update_obj.message.reply_text("Correct answer!") update_obj.message.reply_text("Was this tutorial helpful to you?") return CORRECT else: # wrong answer, reply, send a new question, and loop on the QUESTION state update_obj.message.reply_text("Wrong answer :'(") # send another random numbers calculation randomize_numbers(update_obj, context) return QUESTION# in the CORRECT statedef correct(update_obj, context): if update_obj.message.text.lower() in ['yes', 'y']: update_obj.message.reply_text("Glad it was useful! ^^") else: update_obj.message.reply_text("You must be a programming wizard already!") # get the user's first name first_name = update_obj.message.from_user['first_name'] update_obj.message.reply_text(f"See you {first_name}!, bye") return telegram.ext.ConversationHandler.ENDdef cancel(update_obj, context): # get the user's first name first_name = update_obj.message.from_user['first_name'] update_obj.message.reply_text( f"Okay, no question for you then, take care, {first_name}!", reply_markup=telegram.ReplyKeyboardRemove() ) return telegram.ext.ConversationHandler.END
Each function represents a state, now that we defined our handlers, let's add them to our dispatcher, creating a ConversationHandler
:
# a regular expression that matches yes or noyes_no_regex = re.compile(r'^(yes|no|y|n)$', re.IGNORECASE)# Create our ConversationHandler, with only one statehandler = telegram.ext.ConversationHandler( entry_points=[telegram.ext.CommandHandler('start', start)], states={ WELCOME: [telegram.ext.MessageHandler(telegram.ext.Filters.regex(yes_no_regex), welcome)], QUESTION: [telegram.ext.MessageHandler(telegram.ext.Filters.regex(r'^\d+$'), question)], CANCEL: [telegram.ext.MessageHandler(telegram.ext.Filters.regex(yes_no_regex), cancel)], CORRECT: [telegram.ext.MessageHandler(telegram.ext.Filters.regex(yes_no_regex), correct)], }, fallbacks=[telegram.ext.CommandHandler('cancel', cancel)], )# add the handler to the dispatcherdispatcher.add_handler(handler)
A ConversationHandler
is an object that handles conversations, its definition is straightforward, we simply specify the state to start with, by supplying a CommandHandler for the start command.
For other states, we create a MessageHandler
for each one, that takes two arguments; a regular expression filter describing what user input should look like to get to each state, and the functions (handlers) defined previously.
Now, we can wait to communicate with users; we just need to call these two methods:
# start polling for updates from Telegramupdater.start_polling()# block until a signal (like one sent by CTRL+C) is sentupdater.idle()
Going back to the Telegram app, let's test our bot:
Note that you can start the conversation with /start
command.
Conclusion
Telegram offers a very convenient API for developers, allowing them to extend its use beyond end-to-end communication. We've seen through this tutorial how it can be used to implement a bot with multiple states.
I advise you to learn more about the API features it offers, how to handle images and files sent from users, payments, and much more.
Writing Telegram bots was fun, wasn't it? You can use natural language processing and build an AI model for a question-answering chatbot. In fact, check this tutorial where we made a conversational AI chatbot!
Check the full code here.
Learn also: How to Make Facebook Messenger Bot in Python.
Happy Coding ♥
Ready for more? Dive deeper into coding with our AI-powered Code Explainer. Don't miss it!
View Full Code Understand My Code
Sharing is caring!
Read Also
Comment panel
Got a coding query or need some guidance before you comment? Check out this Python Code Assistant for expert advice and handy tips. It's like having a coding tutor right in your fingertips!