Developing a Telegram Bot in Python
To create a Telegram bot in Python, there are two main libraries: telebot and aiogram. I will be using the first one.
How to Create a Bot in Telegram?
In Telegram, you need to find the official bot called BotFather. Click “Start,” and a wall of text will appear; we need
the command /newbot
. We will be asked to come up with a name for our bot, which can be anything. Next, we need to come
up with a username. This is a bit more complicated: it must be a unique name that ends with “bot.” After that, we will
be congratulated, given the bot’s address, offered to add a description, and set an avatar, but the most important part
is the token. It allows us to connect to the bot, program it, and is essentially the most crucial part.
Installing Telebot
We need to create a virtual environment, activate it, and install our library.
python3 -m venv venv
source venv/bin/activate
pip install pyTelegramBotAPI
Writing Your First Bot
We import the telebot library, create an instance of the TeleBot class, and pass our token as a string to the
token parameter. I recommend storing the token in a separate file, for example, creating a file called config.py
and writing it there, then simply importing it into the main file.
import telebot
from config import TOKEN
bot = telebot.TeleBot(TOKEN)
@bot.message_handler(commands=["start"])
def hello(message):
bot.send_message(message.chat.id, "Hello")
bot.polling(non_stop=True)
We use the decorator @bot.message_handler
(not to be confused with @bot.message_handlers) and pass an array
(mandatory) of commands that the function will respond to in the commands
parameter. The commands can be anything, so
you can do something like:
@bot.message_handler(commands=["start", "test", "help", "how"])
, etc. If this parameter is not specified, the function
will trigger on any text. Next comes our function. The name can be anything, but it must always accept the message
parameter, which contains all the data about the message. Finally, we send the message. The send_message
method takes
the chat ID as the first parameter and the text as the second. It can only send text data; other types of data require
different methods. The line bot.polling(non_stop=True)
starts the bot itself. non_stop=True means that as long as
the code is running, the bot is running too. If we run the code now and go to the chat with our bot and type /start
,
we will receive Hello
.
What is the message Parameter?
import telebot
from config import TOKEN
bot = telebot.TeleBot(TOKEN)
@bot.message_handler(commands=["start"])
def hello(message):
print(message)
bot.polling(non_stop=True)
If we simply print the message parameter, it will look something like this:
{
'content_type': 'text',
'id': 8,
'message_id': 8,
'from_user': {
'id': 0,
'is_bot': False,
'first_name': '_',
'username': '_',
'last_name': '_',
'language_code': 'ru',
'can_join_groups': None,
'can_read_all_group_messages': None,
'supports_inline_queries': None,
'is_premium': None,
'added_to_attachment_menu': None,
'can_connect_to_business': None
},
'date': _,
'chat': {
'id': _,
'type': 'private',
'title': None,
'username': '_',
'first_name': '_',
'last_name': '_',
'is_forum': None,
'max_reaction_count': None,
'photo': None,
'bio': None,
'join_to_send_messages': None,
'join_by_request': None,
'has_private_forwards': None,
'has_restricted_voice_and_video_messages': None,
'description': None,
'invite_link': None,
'pinned_message': None,
'permissions': None,
'slow_mode_delay': None,
'message_auto_delete_time': None,
'has_protected_content': None,
'sticker_set_name': None,
'can_set_sticker_set': None,
'linked_chat_id': None,
'location': None,
'active_usernames': None,
'emoji_status_custom_emoji_id': None,
'has_hidden_members': None,
'has_aggressive_anti_spam_enabled': None,
'emoji_status_expiration_date': None,
'available_reactions': None,
'accent_color_id': None,
'background_custom_emoji_id': None,
'profile_accent_color_id': None,
'profile_background_custom_emoji_id': None,
'has_visible_history': None,
'unrestrict_boost_count': None,
'custom_emoji_sticker_set_name': None,
'business_intro': None,
'business_location': None,
'business_opening_hours': None,
'personal_chat': None,
'birthdate': None
},
'sender_chat': None,
'is_automatic_forward': None,
'reply_to_message': None,
'via_bot': None,
'edit_date': None,
'has_protected_content': None,
'media_group_id': None,
'author_signature': None,
'text': '/kak',
'entities': [
<telebot.types.MessageEntity
object
at
0x7f7d0dbd1390>
],
'caption_entities': None,
'audio': None,
'document': None,
'photo': None,
'sticker': None,
'video': None,
'video_note': None,
'voice': None,
'caption': None,
'contact': None,
'location': None,
'venue': None,
'animation': None,
'dice': None,
'new_chat_members': None,
'left_chat_member': None,
'new_chat_title': None,
'new_chat_photo': None,
'delete_chat_photo': None,
'group_chat_created': None,
'supergroup_chat_created': None,
'channel_chat_created': None,
'migrate_to_chat_id': None,
'migrate_from_chat_id': None,
'pinned_message': None,
'invoice': None,
'successful_payment': None,
'connected_website': None,
'reply_markup': None,
'message_thread_id': None,
'is_topic_message': None,
'chat_background_set': None,
'forum_topic_created': None,
'forum_topic_closed': None,
'forum_topic_reopened': None,
'has_media_spoiler': None,
'forum_topic_edited': None,
'general_forum_topic_hidden': None,
'general_forum_topic_unhidden': None,
'write_access_allowed': None,
'users_shared': None,
'chat_shared': None,
'story': None,
'external_reply': None,
'quote': None,
'link_preview_options': None,
'giveaway_created': None,
'giveaway': None,
'giveaway_winners': None,
'giveaway_completed': None,
'forward_origin': None,
'boost_added': None,
'sender_boost_count': None,
'reply_to_story': None,
'sender_business_bot': None,
'business_connection_id': None,
'is_from_offline': None,
'effect_id': None,
'show_caption_above_media': None,
'json': {
'message_id': 8,
'from': {
'id': _,
'is_bot': False,
'first_name': '_',
'last_name': '_',
'username': '_',
'language_code': 'ru'
},
'chat': {
'id': _,
'first_name': '_',
'last_name': '_',
'username': '_',
'type': 'private'
},
'date': _,
'text': '/kak',
'entities': [
{
'offset': 0,
'length': 4,
'type': 'bot_command'
}
]
}
}
*This piece of code has been formatted for better readability.
Here, all the information about the message is collected. There is the type, ID, and the text of the message, etc. There is also some data about the sender, such as their name, ID, and the language they are using. And this is not a dictionary, as it might seem, but an instance of the Message class. You can verify this by printing its type.
import telebot
from config import TOKEN
bot = telebot.TeleBot(TOKEN)
@bot.message_handler(commands=["start"])
def hello(message):
print(type(message))
# <class 'telebot.types.Message'>
bot.polling(non_stop=True)
Accordingly, you should access it not like this: message.get(“chat”).get(“id”), but like this: message.chat.id
.
Knowing this, we can write a bot that greets us by name.
import telebot
from config import TOKEN
bot = telebot.TeleBot(TOKEN)
@bot.message_handler(commands=["start"])
def hello(message):
bot.send_message(message.chat.id, f"Hello, {message.from_user.first_name}")
bot.polling(non_stop=True)
Adding Buttons
Inline Button
This type of button is attached directly to the message itself. When the button is pressed, some event can be triggered.
import telebot
from telebot import types
from config import TOKEN
bot = telebot.TeleBot(TOKEN)
@bot.message_handler(commands=["start"])
def start(message):
markup = types.InlineKeyboardMarkup()
button = types.InlineKeyboardButton(text="Our Website", url="https://it-teh.com/ru/")
markup.add(button)
bot.send_message(message.chat.id, text=f"Hello, {message.from_user.first_name}", reply_markup=markup)
bot.polling(non_stop=True)
Here, I create an instance of the InlineKeyboardMarkup class and name it markup
. This is something like a
framework to which the button will be attached. Next, I create the button itself. Here, I use the
InlineKeyboardButton class. The first parameter is the text that will be displayed on the button, and the second is
the event that occurs after pressing it. In this case, it is a link to the website. Then, I add the button to our
‘framework’ using the add() method. When sending the message, it is necessary to specify the reply_markup
parameter and pass our markup to it.
Keyboard Button
Reply buttons differ from Inline buttons in that they are attached below the user’s keyboard.
Another feature of these buttons is that when pressed, the text of the button is sent to the chat. Essentially, this is a template with ready-made response options.
import telebot
from telebot import types
from config import TOKEN
bot = telebot.TeleBot(TOKEN)
@bot.message_handler(commands=["start"])
def start(message):
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
button1 = types.KeyboardButton("Our Website")
button2 = types.KeyboardButton("Hello")
markup.add(button1, button2)
bot.send_message(message.chat.id,
text=f"Hello, {message.from_user.first_name}",
reply_markup=markup)
@bot.message_handler(content_types=["text"])
def text(m):
if m.text == "Our Website":
bot.send_message(m.chat.id, text="Our website: https://it-teh.com/ru")
if m.text == "Hello":
bot.send_message(m.chat.id, text="Hello again, "
f"{m.from_user.first_name}")
The method of creating these buttons is very similar to the previous one. An instance of the ReplyKeyboardMarkup class is created. When creating it, it is advisable to specify the resize_keyboard=True parameter so that the button is not too large.
Related Content
If you are interested in this topic, please contact us.