Разработка телеграм бота на Python

Для создания телеграм бота на языке python есть две основных библиотеки: это telebot и aiogram. Я буду использовать первую.

В телеграме необходимо найти официального бота BotFather. Жмем старт и вылезает стена текста, нам нужна команда /newbot. Нас попросят придумать имя для нашего бота, оно может быть любым. Далее нам нужно придумать имя пользователя. Тут немного сложнее: нужно придумать уникальное имя которое заканчивается на bot. После этого нас поздравят, дадут адрес бота, предложат добавить описание и установить аватарку, но самое главное это токен. Он позволяет подключаться к боту, программировать его и, в целом, самая важная его часть.

Необходимо создать виртуальное окружение, активировать его и установить нашу библиотеку.

shell

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

Импортируем библиотеку telebot, создаем экземпляр класса TeleBot и в параметр token передаем наш токен в виде строки. Сам токен я рекомендую хранить в отдельном файле, например создать файл config.py и записать его уже туда, а потом просто импортировать в основной файл.

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, "Привет")

bot.polling(non_stop=True)

Мы используем декоратор @bot.message_handler(не путать с @bot.message_handlers) и в параметр commands передаем массив (обязательно) с командами на которые будет реагировать функция. Команды могут быть любыми, то есть можно сделать так: @bot.message_handler(commands=["start", "test", "help", "kak"]) и т.д. Если данный параметр не указывать, функция будет срабатывать на любой текст. Далее идет наша функция. Имя может быть любым, но она всегда должна принимать параметр message в котором хранятся все данные о сообщении. И наконец сама отправка сообщения. Метод send_message первым параметром принимает id чата, а вторым сам текст. Он способен отправлять только текстовые данные, для отправки других типов данных есть другие методы. Строка bot.polling(non_stop=True) запускает самого бота. non_stop=True означает что пока работает код, работает и бот. Если сейчас запустить код и перейти в чат с нашим ботом и написать /start нам выведется Привет.

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)

Если просто вывести параметр message, то будет примерно это:

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'
      }
    ]
  }
}

*Данный кусок кода был отформатирован для более удобного чтения.

Тут собрана вся информация о сообщении. Есть тип, id и сам текст сообщения и т.д, также есть некоторый данные о самом отправителе, например его имя, id, язык который он использует. И это не словарь как может показаться, а экземпляр класса Message. В это можно убедится если вывести его тип.

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)

И соответственно обращаться к нему надо не так: message.get(“chat”).get(“id”), а так message.chat.id. Зная это можно написать бота, который будет приветствовать нас по имени.

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"Привет, {message.from_user.first_name}")

bot.polling(non_stop=True)

Данный вид кнопок крепится непосредственно к самому сообщению. При нажатии на кнопку может вызываться какое-либо событие.

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="Наш сайт", url="https://it-teh.com/ru/")
    markup.add(button)
    bot.send_message(message.chat.id, text=f"Привет, {message.from_user.first_name}", reply_markup=markup)


bot.polling(non_stop=True)

Здесь я создаю экземпляр класса InlineKeyboardMarkup и называю его markup. Это что-то вроде каркаса, на который будет крепиться кнопка. Дальше я создаю саму кнопку. Тут я уже использую класс InlineKeyboardButton. Первым параметром передаю текст, который будет написан на кнопке. А вторым событие происходящие после нажатия. В данном случае это ссылка на сайт. Далее добавляю кнопку на наш ‘каркас’ c помощью метода add(). При отправке сообщения необходимо указать параметр reply_markup и в него передать наш markup.

Reply кнопки отличаются от Inline тем, что они крепятся под клавиатуру пользователя.

Еще особенность этих кнопок то, что при нажатии на них текст кнопки отправляется в чат. По сути это шаблон с готовыми вариантами ответа.

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("Наш сайт")
    button2 = types.KeyboardButton("Привет")
    markup.add(button1, button2)
    bot.send_message(message.chat.id,
                     text=f"Привет, {message.from_user.first_name}",
                     reply_markup=markup)


@bot.message_handler(content_types=["text"])
def text(m):
    if m.text == "Наш сайт":
        bot.send_message(m.chat.id, text="Наш сайт: https://it-teh.com/ru")
    if m.text == "Привет":
        bot.send_message(m.chat.id, text="Еще раз привет, "
                                         f"{m.from_user.first_name}")

Способ создание данных кнопок очень похож на предыдущий. Создается экземпляр класса ReplyKeyboardMarkup. При создании желательно указать параметр resize_keyboard=True что бы кнопка не была слишком большой.

Похожее