Внимание! Пакеты
python-telegram-bot
версии 13.x будут придерживаться многопоточной парадигмы программирования (*на данный момент актуальна версия 13.15). Пакеты версий 20.x и новее предоставляют чистый асинхронный Python интерфейс для Telegram Bot API. Дополнительно смотрите основные изменения в пакетеpython-telegram-bot
версии 20.x.
В материале рассматривается создание и использование различных декораторов для python-telegram-bot
в стиле библиотеки pyTelegramBotAPI
.
Handler
как декораторы для функций обратного вызова;Handler
как декораторы для функций обратного вызова.Представленный ниже декоратор позволяет зарегистрировать функцию в качестве обработчика команд в стиле библиотеки pyTelegramBotAPI
.
def command_handler(command): def decorator(func): handler = CommandHandler(command, func) application.add_handler(handler) return func return decorator
Теперь просто необходимо добавить декоратор @command_handler(command)
поверх функции-обработчика:
# использование в версии 13.x @command_handler("hello") def hello(update, context): context.bot.send_message(chat_id=update.effective_chat.id, text="Hello world!") # использование в версии 20.x @command_handler("hello") async def hello(update, context): await context.bot.send_message(chat_id=update.effective_chat.id, text="Hello world!")
Примечание. Можно изменить этот декоратор, чтобы зарегистрировать обработчик любого типа. Также обратите внимание, что
python-telegram-bot
намеренно не предоставляет такую функциональность из коробки по двум причинам:
Этот декоратор позволяет ограничить доступ обработчика только к указанным user_id
, перечисленным в списке LIST_OF_ADMINS
.
Пример для python-telegram-bot
версии 13.x:
from functools import wraps LIST_OF_ADMINS = [12345678, 87654321] def restricted(func): @wraps(func) def wrapped(update, context, *args, **kwargs): user_id = update.effective_user.id if user_id not in LIST_OF_ADMINS: print(f"Несанкционированный доступ запрещен для {user_id}.") return return func(update, context, *args, **kwargs) return wrapped
Пример для python-telegram-bot
версии 20.x:
from functools import wraps LIST_OF_ADMINS = [12345678, 87654321] def restricted(func): @wraps(func) async def wrapped(update, context, *args, **kwargs): user_id = update.effective_user.id if user_id not in LIST_OF_ADMINS: print(f"Несанкционированный доступ запрещен для {user_id}.") return return await func(update, context, *args, **kwargs) return wrapped
Теперь нужно просто добавить декоратор @restricted
поверх объявления функции-обработчика. Функции-обработчик сработает только в том случае, если user_id
находится в LIST_OF_ADMINS
:
# использование в версии 13.x @restricted def my_handler(update, context): # функции-обработчик сработает только в том случае, # если `user_id` находится в `LIST_OF_ADMINS`. pass # использование в версии 20.x @restricted async def my_handler(update, context): pass
Следующий параметризованный декоратор позволяет сигнализировать о различных действиях в зависимости от типа ответа бота. Таким образом, у пользователей будет такая же обратная связь от бота, как и от реального человека.
Код для версии 13.x:
from functools import wraps def send_action(action): """Отправляет "действие" во время обработки команды.""" def decorator(func): @wraps(func) def command_func(update, context, *args, **kwargs): chat_id = update.effective_message.chat_id context.bot.send_chat_action(chat_id=chat_id, action=action) return func(update, context, *args, **kwargs) return command_func return decorator
Код для версии 20.x:
from functools import wraps def send_action(action): """Отправляет "действие" во время обработки команды.""" def decorator(func): @wraps(func) async def command_func(update, context, *args, **kwargs): chat_id = update.effective_message.chat_id await context.bot.send_chat_action(chat_id=chat_id, action=action) return await func(update, context, *args, **kwargs) return command_func return decorator
Можно декорировать функции обратных вызовов обработчиков напрямую с помощью @send_action(ChatAction. Action)
или создавать псевдонимы и декорировать их (более читабельно).
# определяем псевдонимы send_typing_action = send_action(ChatAction.TYPING) send_upload_video_action = send_action(ChatAction.UPLOAD_VIDEO) send_upload_photo_action = send_action(ChatAction.UPLOAD_PHOTO)
С приведенными выше псевдонимами следующие декораторы эквивалентны:
# пользователь увидит анимацию ввода, # пока бот обрабатывает запрос. # код для версии 13.x @send_typing_action def my_handler(update, context): pass # эквивалентно # код для версии 13.x @send_action(ChatAction.TYPING) def my_handler(update, context): pass
telegram.constants.ChatAction
.Класс telegram.constants.ChatAction
представляет собой вспомогательный класс для предоставления констант для различных "действий" в чате telegram.Bot.send_chat_action()
.
ChatAction.CHOOSE_STICKER
- бот выбирает стикер.ChatAction.FIND_LOCATION
- бот выбирает местоположение.ChatAction.RECORD_VIDEO
- бот записывает видео.ChatAction.RECORD_VIDEO_NOTE
- бот записывает видеозапись.ChatAction.RECORD_VOICE
- бот записывает голосовое сообщение.ChatAction.TYPING
- бот набирает текст.ChatAction.UPLOAD_DOCUMENT
- бот загружает документ.ChatAction.UPLOAD_PHOTO
- бот загружает фото.ChatAction.UPLOAD_VIDEO
- бот загружает видео.ChatAction.UPLOAD_VIDEO_NOTE
- бот загружает видеозаметку.ChatAction.UPLOAD_VOICE
- бот загружает голосовое сообщение.