Telegram bot development using Python

To create a telegram bot in python there are two main libraries: telebot and aiogram. I will use the first one.

In Telegram you need to find the official BotFather bot. We press start and a wall of text appears, we need the /newbot command. We will be asked to come up with a name for our bot, it can be anything. Next we need to come up with a username. Here a little more complicated: you need to come up with a unique name that ends in bot. After that they will congratulate us and give us the address bot, they will offer to add a description and set an avatar, but the most important thing is the token. It allows you to connect to a bot, programming it and, in general, the most important part of it.

It is necessary to create a virtual environment, activate it and install our library.

shell

python3 -m venv venv
source venv/bin/activate
pip install pyTelegramBotAPI

We import the telebot library, create an instance of the TeleBot class and pass our token to the token parameter as a string. I recommend storing the token itself in a separate file, for example creating a config.py file and writing it down there, and then simply import it into the main file.

python

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 @bot.message_handler decorator (not to be confused with @bot.message_handlers) and pass in the commands parameter an array (required) with commands to which the function will respond. The commands can be anything, that is, you can do So: @bot.message_handler(commands=["start", "test", "help", "kak"]) 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 a message parameter, which stores all the message data. And finally the sending itself messages. The send_message method takes the chat id as the first parameter, and the text itself as the second. It can only send text data, there are other methods for sending other types of data. The line bot.polling(non_stop=True) starts himself bot. non_stop=True means that while the code is running, the bot is running. If you now run the code and go to chat with our bot and write /start will display Hello.

python

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 you simply display the message parameter, it will look something like this:

json

{
  '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 to make it easier to read.

All information about the message is collected here. There is a type, id and the text of the message itself, etc., there is also some data about the sender, for example his name, id, the language he uses. And this is not a dictionary as it might seem, but an instance of the Message class. You can verify this by inferring its type.

python

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)

And accordingly, you need to access it not like this: message.get(“chat”).get(“id”), but like message.chat.id. Knowing this, you can write a bot that will greet us by name.

python

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)

This type of button is attached directly to the message itself. When you press the button can trigger an event.

python

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 site", 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 call it markup. This something like a frame on which the button will be attached. Next I create the button itself. I’m already here I use the InlineKeyboardButton class. As the first parameter I pass the text, which will be written on the button. And the second is the event that occurs after the click. In this case it is a link to the website. Next, I add a button to our ‘framework’ using the add() method. When sending a message you must indicate parameter reply_markup and pass our markup into it.

Reply buttons differ from Inline buttons in that they are attached under the user’s keyboard.

Another feature of these buttons is that when you click on them, the text of the button is sent to the chat. Essentially, this is a template with ready-made answer options.

python

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 site")
 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 site":
 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 for creating these buttons is very similar to the previous one. An instance of the ReplyKeyboardMarkup class is created. While creating It is advisable to specify the parameter resize_keyboard=True so that the button is not too large.

Related Content