Для работы с Bot API есть четыре популярные Python-библиотеки:
Поработаем с python-telegram-bot. Это популярная библиотека с удобным интерфейсом: методы классов совпадают с названиями методов Bot API.
В python-telegram-bot все методы Bot API вызываются как методы различных классов библиотеки.
Библиотека разделена на три пакета:
- telegram — основной пакет, содержит все методы Bot API, перенесённые на Python.
- telegram.ext — вспомогательный пакет, он содержит методы-обёртки для стандартных методов Bot API, позволяет упростить код и убирает рутинные операции «под капот», примерно так же, как это происходит во фреймворках.
- telegram.utils — пакет для продвинутой работы с библиотекой, позволяет переопределять и расширять библиотеку.
Пакеты python-telegram-bot импортируются в код под именем telegram
(это неожиданно, но это так):
import telegram
# Здесь будет код Телеграм-бота
Или так:
PYTHONimport telegram.ext
# Здесь будет код Телеграм-бота
Bot API vs PEP8
В официальной документации Bot API все методы описаны в camelCase, но это не питонично, поэтому разработчики библиотеки python-telegram-bot продублировали названия методов в snake_case.
Это значит, что метод sendMessage
может быть вызван двумя способами:
telegram.Bot.sendMessage
,telegram.Bot.send_message
.
Результат будет одинаков, но лучше соблюдать PEP8 и писать в стиле snake_case.
Библиотека
Для стандартных задач в библиотеке python-telegram-bot есть готовые решения:
- отправка/получение сообщений;
- обработка «команд» — сообщений со слешем, вроде
/start
или/help
; - создание кнопок;
- запись в базу (долговременное хранение сообщений).
Решение всех этих задач реализовано на классах.
Создайте новый проект в директории /tg_bot, установите виртуальное окружение и библиотеку python-telegram-bot.
mkdir tg_bot # Создаём директорию
cd tg_bot # Переходим в эту директорию
python3 -m venv venv # Создаём виртуальное окружение
. venv/bin/activate # Активируем виртуальное окружение
# Для Windows команда source venv/Scripts/activate
pip3 install python-telegram-bot # Устанавливаем библиотеку
Класс Bot()
Этот класс реализует методы API, связанные с отправкой, редактированием, пересылкой или удалением сообщений и прочими активными действиями бота, не связанными с получением и обработкой входящих сообщений. Полная информация о классе Bot()
есть в документации.
Например, на основе класса Bot()
можно написать бота-администратора, который будет удалять из группового чата сообщения с неприличными словами и отправлять уведомления авторам этих постов.
В начале работы создаётся экземпляр класса Bot()
и в него передаётся токен. После этого можно вызывать методы класса:
from telegram import Bot
bot = Bot(token='<token>')
# Отправка сообщения
chat_id = 123456
text = 'Вам телеграмма!'
bot.send_message(chat_id, text)
Из соображений безопасности токен следует хранить в переменных окружения, но для начала работы поставьте токен прямо в код.
Запустите программу:
- подставьте в код
chat_id
своего аккаунта, - подставьте в код свой токен,
- отправьте сообщение.
Класс Updater()
Этот класс предназначен для получения и обработки входящих сообщений.
При создании объекта класса Updater
в него передаётся токен, точно так же, как и в Bot
:
from telegram.ext import Updater
updater = Updater(token='<token>')
Экземпляры классов Bot
и Updater
принимают на вход токен Телеграм-бота и могут делать запросы от имени его аккаунта. Фактически экземпляры классов Bot
и Updater
— это экземпляры бота.
Обработка входящих сообщений
Сообщения в Telegram делятся на типы: есть простые текстовые сообщения, есть сообщения-картинки, сообщения-стикеры, сообщения-файлы. Каждый тип можно обрабатывать по-разному: например, текстовые сообщения можно парсить и отвечать на них текстовым сообщением, полученные картинки и файлы сохранять или пересылать, а на стикеры отвечать стикерами.
Настроим бота так, чтобы он отправлял приветствие каждый раз, когда получит любое текстовое сообщение. Для этого нам нужно создать обработчик. Такой обработчик создаётся с помощью класса MessageHandler
.
Handler — общеупотребимый в программировании термин, он как раз и означает «обработчик».
У объекта Updater есть атрибут dispatcher
(«диспетчер» или «распределитель»). Именно он распределяет сообщения, которые приходят от пользователей, по разным обработчикам.
Для обработки сообщений:
- Посредством диспетчера регистрируется класс-обработчик (для примера выбран обработчик
MessageHandler
):updater.dispatcher.add_handler(MessageHandler(...))
. - В обработчик передаются два параметра:
updater.dispatcher.add_handler(MessageHandler(Filters.text, say_hi))
Filters.text
— фильтр, выбирающий из обновлений сообщения определённого типа (в приведённом примере будут выбраны только текстовые сообщения).say_hi()
— функция, которая будет обрабатывать выбранные сообщения.В функцию передаются два аргумента:update
— это обновление, которое пришло с сервера. В этом объекте есть само сообщение, информация о чате и много других полезных данных.context
— в этом объекте хранится информация о боте, а также другая опциональная информация.Эти аргументы передаются неявно: в коде обработчика описывать эти аргументы не нужно, но вызываемая функция должна ожидать их:say_hi(update, context)
.- С помощью этой функции мы будем отвечать в чат текстом «Привет, я бот». При отправке обязательно нужно указать идентификатор чата
chat_id
. Его можно получить из объектаupdate
и сохранить, например, в переменнуюchat
.
from telegram.ext import Updater, Filters, MessageHandler
updater = Updater(token='<token>')
def say_hi(update, context):
# Получаем информацию о чате и сохраняем в переменную chat
chat = update.effective_chat
# В ответ на любое текстовое сообщение будет отправлен ответ 'Привет, я бот'
context.bot.send_message(chat_id=chat.id, text='Привет, я бот')
# Регистрируется обработчик MessageHandler;
# из всех полученных сообщений он будет выбирать только текстовые сообщения
# и передавать их в функцию say_hi()
updater.dispatcher.add_handler(MessageHandler(Filters.text, say_hi))
# Метод start_polling() запускает процесс polling,
# приложение начнёт отправлять регулярные запросы для получения обновлений.
updater.start_polling()
Метод start_polling
отправляет регулярные запросы к серверу Telegram и проверяет обновления. По умолчанию запросы отправляются каждые 10 секунд. Периодичность опроса можно изменить, передав методу именованный параметр poll_interval
и указав нужный интервал запросов (в секундах, float
):
updater.start_polling(poll_interval=20.0)
Прервать выполнение программы можно комбинацией клавиш Ctrl + C
.
Класс Filters()
Класс Filters()
может отфильтровывать сообщения по типу:
Filters.text
,Filters.photo
,Filters.video
.- можно фильтровать по ID или имени отправителя, по типу чата (личный чат или канал) или по множеству других признаков.
Если требуется обработать все сообщения — применяют Filters.all
. Документация по фильтрам.
Обработчики в python-telegram-bot
В библиотеке python-telegram-bot есть множество готовых обработчиков для разных задач.
Эти обработчики связывают список отфильтрованных по какому-то признаку сообщений с функцией, которая должна этот список обработать.
Приведённый в примере обработчик MessageHandler фильтрует полученные сообщения (выбирает только текстовые), сохраняет их в объект Update
— и они обрабатываются в функции say_hi()
.
...
updater.dispatcher.add_handler(MessageHandler(Filters.text, say_hi))
...
Чтобы посмотреть, в каком виде полученные сообщения хранятся в объекте Update
:
- отправьте своему боту несколько сообщений;
- измените код функции
say_hi()
так, чтобы она вывела на печать объектUpdate
, полученный в первом аргументе; - запустите этот код в редакторе.
MessageHandler — один из самых популярных и универсальных обработчиков в библиотеке, ведь чаще всего работа идёт именно с сообщениями.Обработчик CommandHandler более специализирован: он предназначен для обработки команд — сообщений, начинающихся со слеша /
. Самые распространённые команды — /start
, /help
: скорее всего, вы их уже использовали при общении с ботами.
CommandHandler выбирает из обновлений сообщения с командами, сохраняет их в объект Update
и обрабатывает эти сообщения в функции, указанной вторым аргументом в обработчике.
from telegram.ext import Updater, CommandHandler
updater = Updater(token='<token>')
def wake_up(update, context):
# В ответ на команду будет отправлено сообщение 'Спасибо, что включили меня'
chat = update.effective_chat
context.bot.send_message(chat_id=chat.id, text='Спасибо, что включили меня')
# Регистрируется обработчик CommandHandler;
# он будет отфильтровывать только сообщения с содержимым '/start'
# и передавать их в функцию wake_up()
updater.dispatcher.add_handler(CommandHandler('start', wake_up))
updater.start_polling()
Обработать команды можно и через универсальный MessageHandler, отфильтровав сообщения через Filters
, но CommandHandler упростит эту задачу.
Библиотека содержит и множество других обработчиков для различных ситуаций.
Благодарю за статью, все очень хорошо обьяснили, все более понятно стало. 👍🏻👍🏻👍🏻