Что такое dispatcher aiogram
Перейти к содержимому

Что такое dispatcher aiogram

  • автор:

Dispatcher

It will process incoming updates: messages, edited messages, channel posts, edited channel posts, inline queries, chosen inline results, callback queries, shipping queries, pre-checkout queries.

You can skip old incoming updates from queue. This method is not recommended for using in production.

Note that the webhook will be deleted!

async process_updates ( updates , fast : bool = True ) [source] 

Process list of updates

updates

fast

Process single update object

update

async reset_webhook ( check = True ) → bool [source] 

check – check before deleting

async start_polling ( timeout = 20 , relax = 0.1 , limit = None , reset_webhook = None , fast : bool = True , error_sleep : int = 5 , allowed_updates : Optional [ List [ str ] ] = None ) [source] 

timeout

relax

limit

reset_webhook

fast

error_sleep

allowed_updates

Break long-polling process.

Wait for the long-polling to close

Check if polling is enabled

register_message_handler ( callback , * custom_filters , commands = None , regexp = None , content_types = None , state = None , run_task = None , ** kwargs ) [source] 

Register handler for message

callback

commands – list of commands

regexp – REGEXP

content_types – List of content types.

custom_filters – list of custom filters

kwargs

state

message_handler ( * custom_filters , commands = None , regexp = None , content_types = None , state = None , run_task = None , ** kwargs ) [source] 

Decorator for message handler

Simple commands handler:

Filter messages by regular expression:

Filter messages by command regular expression:

Filter by content type:

Filter by custom function:

Use multiple filters:

Register multiple filters set for one handler:

This handler will be called if the message starts with ‘/command’ OR is some emoji

By default content_type is ContentType.TEXT

commands – list of commands

regexp – REGEXP

content_types – List of content types.

custom_filters – list of custom filters

kwargs

state

run_task – run callback in task (no wait results)

register_edited_message_handler ( callback , * custom_filters , commands = None , regexp = None , content_types = None , state = None , run_task = None , ** kwargs ) [source] 

Register handler for edited message

callback

commands – list of commands

regexp – REGEXP

content_types – List of content types.

state

custom_filters – list of custom filters

run_task – run callback in task (no wait results)

kwargs

edited_message_handler ( * custom_filters , commands = None , regexp = None , content_types = None , state = None , run_task = None , ** kwargs ) [source] 

Decorator for edited message handler

You can use combination of different handlers

commands – list of commands

regexp – REGEXP

content_types – List of content types.

state

custom_filters – list of custom filters

run_task – run callback in task (no wait results)

kwargs

register_channel_post_handler ( callback , * custom_filters , commands = None , regexp = None , content_types = None , state = None , run_task = None , ** kwargs ) [source] 

Register handler for channel post

callback

commands – list of commands

regexp – REGEXP

content_types – List of content types.

state

custom_filters – list of custom filters

run_task – run callback in task (no wait results)

kwargs

channel_post_handler ( * custom_filters , commands = None , regexp = None , content_types = None , state = None , run_task = None , ** kwargs ) [source] 

Decorator for channel post handler

commands – list of commands

regexp – REGEXP

content_types – List of content types.

state

custom_filters – list of custom filters

run_task – run callback in task (no wait results)

kwargs

register_edited_channel_post_handler ( callback , * custom_filters , commands = None , regexp = None , content_types = None , state = None , run_task = None , ** kwargs ) [source] 

Register handler for edited channel post

callback

commands – list of commands

regexp – REGEXP

content_types – List of content types.

state

custom_filters – list of custom filters

run_task – run callback in task (no wait results)

kwargs

edited_channel_post_handler ( * custom_filters , commands = None , regexp = None , content_types = None , state = None , run_task = None , ** kwargs ) [source] 

Decorator for edited channel post handler

commands – list of commands

regexp – REGEXP

content_types – List of content types.

custom_filters – list of custom filters

state

run_task – run callback in task (no wait results)

kwargs

register_inline_handler ( callback , * custom_filters , state = None , run_task = None , ** kwargs ) [source] 

Register handler for inline query

callback

custom_filters – list of custom filters

state

run_task – run callback in task (no wait results)

kwargs

inline_handler ( * custom_filters , state = None , run_task = None , ** kwargs ) [source] 

Decorator for inline query handler

state

custom_filters – list of custom filters

run_task – run callback in task (no wait results)

kwargs

register_chosen_inline_handler ( callback , * custom_filters , state = None , run_task = None , ** kwargs ) [source] 

Register handler for chosen inline query

callback

state

custom_filters

run_task – run callback in task (no wait results)

kwargs

chosen_inline_handler ( * custom_filters , state = None , run_task = None , ** kwargs ) [source] 

Decorator for chosen inline query handler

state

custom_filters

run_task – run callback in task (no wait results)

kwargs

register_callback_query_handler ( callback , * custom_filters , state = None , run_task = None , ** kwargs ) [source] 

Register handler for callback query

callback

state

custom_filters

run_task – run callback in task (no wait results)

kwargs

Decorator for callback query handler

state

custom_filters

run_task – run callback in task (no wait results)

kwargs

Register handler for shipping query

callback

state

custom_filters

run_task – run callback in task (no wait results)

kwargs

Decorator for shipping query handler

state

custom_filters

run_task – run callback in task (no wait results)

kwargs

Register handler for pre-checkout query

callback

state

custom_filters

run_task – run callback in task (no wait results)

kwargs

Decorator for pre-checkout query handler

state

custom_filters

run_task – run callback in task (no wait results)

kwargs

Register handler for poll

callback

custom_filters

run_task – run callback in task (no wait results)

kwargs

Decorator for poll handler

custom_filters

run_task – run callback in task (no wait results)

kwargs

Register handler for poll_answer

callback

custom_filters

run_task – run callback in task (no wait results)

kwargs

Decorator for poll_answer handler

custom_filters

run_task – run callback in task (no wait results)

kwargs

Register handler for my_chat_member

callback

custom_filters

run_task – run callback in task (no wait results)

kwargs

Decorator for my_chat_member handler

custom_filters

run_task – run callback in task (no wait results)

kwargs

Register handler for chat_member

callback

custom_filters

run_task – run callback in task (no wait results)

kwargs

Decorator for chat_member handler

custom_filters

run_task – run callback in task (no wait results)

kwargs

Register handler for chat_join_request

callback

custom_filters

run_task – run callback in task (no wait results)

kwargs

Decorator for chat_join_request handler

custom_filters

run_task – run callback in task (no wait results)

kwargs

Register handler for errors

callback

exception – you can make handler for specific errors type

run_task – run callback in task (no wait results)

Decorator for errors handler

exception – you can make handler for specific errors type

run_task – run callback in task (no wait results)

current_state ( * , chat : Optional [ Union [ str , int ] ] = None , user : Optional [ Union [ str , int ] ] = None ) → FSMContext [source] 

Get current state for user in chat as context

chat

user

async throttle ( key , * , rate = None , user_id = None , chat_id = None , no_error = None ) → bool [source] 

Execute throttling manager. Returns True if limit has not exceeded otherwise raises ThrottleError or returns False

key – key in storage

rate – limit (by default is equal to default rate limit)

user_id – user id

chat_id – chat id

no_error – return boolean value instead of raising error

async check_key ( key , chat_id = None , user_id = None ) [source] 

Get information about key in bucket

key

chat_id

user_id

async release_key ( key , chat_id = None , user_id = None ) [source] 

Release blocked key

key

chat_id

user_id

Execute handler as task and return None. Use this decorator for slow handlers (with timeouts)

func

throttled ( on_throttled : Optional [ Callable ] = None , key = None , rate = None , user_id = None , chat_id = None ) [source] 

Meta-decorator for throttling. Invokes on_throttled if the handler was throttled.

on_throttled – the callable object that should be either a function or return a coroutine

key – key in storage

rate – limit (by default is equal to default rate limit)

user_id – user id

chat_id – chat id

bind_filter ( callback : Union [ Callable , AbstractFilter ] , validator : Optional [ Callable ] = None , event_handlers : Optional [ List [ Handler ] ] = None , exclude_event_handlers : Optional [ Iterable [ Handler ] ] = None ) [source] 

callback – callable or subclass of AbstractFilter

validator – custom validator.

event_handlers – list of instances of Handler

exclude_event_handlers – list of excluded event handlers ( Handler )

Знакомство с aiogram¶

Автор этой книги убеждён, что помимо теории должна быть и практика. Чтобы максимально упростить повторение приведённого далее кода, пришлось пойти на использование подходов, пригодных только для локальной разработки и обучения.

Так, например, во всех или почти во всех главах токен бота будет указываться прямо в исходных текстах. Это плохой подход, поскольку может привести к раскрытию токена, если вы забудете его удалить перед заливкой кода в публичный репозиторий (например, GitHub).

Или иногда в качестве хранилищ данных будут использоваться структуры, расположенные исключительно в оперативной памяти (словари, списки. ). В действительности такие объекты нежелательны, поскольку остановка бота приведёт безвозвратной потере данных.

Также механизмом получения апдейтов от Telegram выбран поллинг, поскольку он гарантированно работает в подавляющем большинстве окружений и подходит практически всем разработчикам.

Важно помнить, что автор ставит перед собой цель объяснить именно работу с Telegram Bot API при помощи aiogram, а не вообще весь Computer Science во всём его многообразии.

Терминология¶

Чтобы разговаривать в одних и тех же понятиях, введём некоторые термины, дабы в дальнейшем не путаться:

  • ЛС — личные сообщения, в контексте бота это диалог один-на-один с пользователем, а не группа/канал.
  • Чат — общее название для ЛС, групп, супергрупп и каналов.
  • Апдейт — любое событие из этого списка: сообщение, редактирование сообщения, колбэк, инлайн-запрос, платёж, добавление бота в группу и т.д.
  • Хэндлер — асинхронная функция, которая получает от диспетчера/роутера очередной апдейт и обрабатывает его.
  • Диспетчер — объект, занимающийся получением апдейтов от Telegram с последующим выбором хэндлера для обработки принятого апдейта.
  • Роутер — аналогично диспетчеру, но отвечает за подмножество множества хэндлеров. Можно сказать, что диспетчер — это корневой роутер.
  • Фильтр — выражение, которое обычно возвращает True или False и влияет на то, будет вызван хэндлер или нет.
  • Мидлварь — прослойка, которая вклинивается в обработку апдейтов.

Установка¶

Для начала давайте создадим каталог для бота, организуем там virtual environment (далее venv) и установим библиотеку aiogram.
Проверим, что установлен Python версии 3.9 (если вы знаете, что установлен 3.9 и выше, можете пропустить этот раздел):

Теперь создадим файл requirements.txt , в котором укажем используемую нами версию aiogram. Также нам понадобится библиотека python-dotenv для файлов конфигурации.

О версиях aiogram

В этой главе используется aiogram 3.x, перед началом работы рекомендую заглянуть в канал релизов библиотеки и проверить наличие более новой версии. Подойдёт любая более новая, начинающаяся с цифры 3, поскольку aiogram 2.x более рассматриваться не будет и считается устаревшим.

Обратите внимание на префикс «venv» в терминале. Он указывает, что мы находимся в виртуальном окружении с именем «venv». Проверим, что внутри venv вызов команды python указывает на всё тот же Python 3.9:

Последней командой deactivate мы вышли из venv, чтобы он нам не мешал.

Если для написания ботов вы используете PyCharm, рекомендую также установить сторонний плагин Pydantic для поддержки автодополнения кода в телеграмных объектах.

Первый бот¶

Давайте создадим файл bot.py с базовым шаблоном бота на aiogram:

Первое, на что нужно обратить внимание: aiogram — асинхронная библиотека, поэтому ваши хэндлеры тоже должны быть асинхронными, а перед вызовами методов API нужно ставить ключевое слово await, т.к. эти вызовы возвращают корутины.

Асинхронное программирование в Python

Не стоит пренебрегать официальной документацией!
Прекрасный туториал по asyncio доступен на сайте Python.

Если вы в прошлом работали с какой-то другой библиотекой для Telegram, например, pyTelegramBotAPI, то концепция хэндлеров (обработчиков событий) вам сразу станет понятна, разница лишь в том, что в aiogram хэндлерами управляет диспетчер.
Диспетчер регистрирует функции-обработчики, дополнительно ограничивая перечень вызывающих их событий через фильтры. После получения очередного апдейта (события от Telegram), диспетчер выберет нужную функцию обработки, подходящую по всем фильтрам, например, «обработка сообщений, являющихся изображениями, в чате с ID икс и с длиной подписи игрек». Если две функции имеют одинаковые по логике фильтры, то будет вызвана та, что зарегистрирована раньше.

Чтобы зарегистрировать функцию как обработчик сообщений, нужно сделать одно из двух действий:
1. Навесить на неё декоратор, как в примере выше. С различными типами декораторов мы познакомимся позднее.
2. Напрямую вызвать метод регистрации у диспетчера или роутера.

Рассмотрим следующий код:

Давайте запустим с ним бота:
Команда /test2 не работает

Хэндлер cmd_test2 не сработает, т.к. диспетчер о нём не знает. Исправим эту ошибку и отдельно зарегистрируем функцию:

Снова запустим бота:
Обе команды работают

Синтаксический сахар¶

Для того чтобы сделать код чище и читабельнее, aiogram расширяет возможности стандартных объектов Telegram. Например, вместо bot.send_message(. ) можно написать message.answer(. ) или message.reply(. ) . В последних двух случаях не нужно подставлять chat_id , подразумевается, что он такой же, как и в исходном сообщении.
Разница между answer и reply простая: первый метод просто отправляет сообщение в тот же чат, второй делает «ответ» на сообщение из message :

Разница между message.answer() и message.reply()

Более того, для большинства типов сообщений есть вспомогательные методы вида «answer_» или «reply_«, например:

что значит ‘message: types.Message’ ?

Python является интерпретируемым языком с сильной, но динамической типизацией, поэтому встроенная проверка типов, как, например, в C++ или Java, отсутствует. Однако начиная с версии 3.5 в языке появилась поддержка подсказок типов, благодаря которой различные чекеры и IDE вроде PyCharm анализируют типы используемых значений и подсказывают программисту, если он передаёт что-то не то. В данном случае подсказка types.Message соообщает PyCharm-у, что переменная message имеет тип Message , описанный в модуле types библиотеки aiogram (см. импорты в начале кода). Благодаря этому IDE может на лету подсказывать атрибуты и функции.

При вызове команды /dice бот отправит в тот же чат игральный кубик. Разумеется, если его надо отправить в какой-то другой чат, то придётся по-старинке вызывать await bot.send_dice(. ) . Но объект bot (экземпляр класса Bot) может быть недоступен в области видимости конкретной функции. В aiogram 3.x объект бота, которому пришёл апдейт, неявно прокидывается в хэндлер и его можно достать как аргумент bot . Предположим, вы хотите по команде /dice отправлять кубик не в тот же чат, а в канал с ID -100123456789. Перепишем предыдущую функцию:

Передача доп. параметров¶

Иногда при запуске бота может потребоваться передать одно или несколько дополнительных значений. Это может быть объект конфигурации, список администраторов группы, отметка времени и что угодно ещё. Для этого достаточно передать параметры как дополнительные именованные (!) аргументы функции start_polling(. ) (для вебхуков есть аналогичный способ). В хэндлерах для получения этих значений достаточно указать их как те же аргументы. Более того, изменение таких объектов в одних хэндлерах влияют на их содержимое в других. Рассмотрим на примере:

Теперь список mylist можно читать и писать в разных хэндлерах. Существует также ещё один вариант, более подходящий в других ситуациях. Речь, конечно же, о мидлварях, про которые подробно рассказывается в соответствующей главе.

Аргумент mylist может быть изменён между вызовами

Файлы конфигурации¶

Чтобы не хранить токен прямо в коде (вдруг вы захотите залить своего бота в публичный репозиторий?) можно вынести подобные данные в отдельный конфигурационный файл. Существует хорошее и адекватное мнение, что для прода достаточно переменных окружения, однако в рамках этой книги мы будем пользоваться отдельными файлами .env , чтобы немного упростить себе жизнь и сэкономить читателям время на разворачивание демонстрационного проекта.

Итак, создадим рядом с bot.py отдельный файл config_reader.py со следующим содержимым

Теперь немного отредактируем наш bot.py :

Наконец, создадим файл .env (с точкой в начале), где опишем токен бота:

Если всё сделано правильно, то при запуске python-dotenv подгрузит переменные из файла .env , pydantic их провалидирует и объект бота успешно создастся с нужным токеном.

На этом мы закончим знакомство с библиотекой, а в следующих главах рассмотрим другие «фишки» aiogram и Telegram Bot API.

Name already in use

aiogram / aiogram / dispatcher / dispatcher.py /

  • Go to file T
  • Go to line L
  • Go to definition R
  • Copy path
  • Copy permalink
  • Open with Desktop
  • View raw
  • Copy raw contents Copy raw contents

Copy raw contents

Copy raw contents

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

[AIOGram | Python] Урок 1. Вступление. Простой бот

Привет! Как-то захотел я сделать своего бота в телеграме. Ну, знаете. Есть свой канал, пара чатов, знаю Python. Но скажу честно, первые попытки были заброшены. Оказалось, что в разработке ботов не было единого подхода, а найти хороший фреймворк оказалось сложнее, чем казалось. Или я не особо внимательный. Но в начале 2021 я нашел свой идеал. Это AIOGram.

А теперь я решил совместить приятное с полезным, так что буду писать какие-то нововведения для бота параллельно документируя их для сайта. Такая себе коллаборация с самим собой для получения побочных продуктов)

AIOGram быстрый старт

Создаём простой проект в PyCharm, ждём завершения и открываем main.py. Его содержимое нас не интересует, так что удаляем. Вместо этого пишем:

Дабы почувствовать всю прелесть разработки в PyCharm – используем Context Action для импорта фреймрворка. Ставим указатель на aiogram и нажимаем Alt + Enter, и выбираем Install Package.

Если что-то не получилось, то необходимые библиотеки можно установить через Python Packages.

В будущем мы создадим файлик requirements.txt, в котором будут прописаны все необходимые библиотеки для автоматической установки. А токен и другие важные переменные вынесем в .env файл. Но для простоты эти шаги пока опустим.

Далее пишем следующее:

Переменная с токеном должна содержать токен вашего бота, который можно получить в специальном боте @BotFather при создании своего.

Так и пишите в телеге @BotFather

Как вы могли заметить, мы создали объект бота, которому передали токен. Теперь сообщения отправленные боту будут приходить нашему боту на aiogram. Dispatcher это своего рода диспетчер, которые будет выполнять множество задач по взаимодействию с ботом. В т.ч. получение сообщений.

А polling не даст завершить работу бота пока приложение активно.

Запустить можно уже, но интереса никакого. Предлагаю добавить эхо функцию.

Т.е. теперь dispatcher для любого полученного сообщения будет выполнять функцию echo. Если что-то не особо понятно, то полный код будет в конце статьи.

Проверим? Нажимаем Ctrl +Shift + F10 для запуска скрипта.

И вправду эхо

Расширяем функционал

Кстати, message_handler не только текст принимает. А любые сообщения, плюс мы можем указывать свои фильтры. Вроде сообщений от админа, личные, группа и т.д. Поддерживает он и команды. Например, эта функция будет срабатывать только при вводе команды /start. Только разместите её выше, чем echo, это важно. В ином случае сообщение перехватит эхо и до этой функции /start не дойдёт.

Уже интереснее

Добавим ещё аналогичную help, но ради интереса пропишем её ниже, чем echo:

Неа, не получилось

Как видите, старт так и срабатывает, а вот help нет. Как я и говорил. Обрабатывать мы можем только одну функцию за раз, и если какой-то обработчик соответствует, то дальнейшие будут отброшены.

Именно поэтому, когда мы пишем /start не срабатывает echo. И именно поэтому не сработал help. Потому что echo собирает все сообщения, которые не /start. Переместим help куда-то выше и попробуем снова.

Прекрасно!

Кстати, можно указать ещё и фильтр на тип сообщения. Стикер, аудио, файл. А можно даже прописывать особые состояния, благодаря которым бот будет ожидать от пользователя конкретных действий. И, конечно же, мы всё это попробуем дальше. А пока вы можете прописать набор каких-то команд и насладиться своим собственным ботом (пока активна IDE, как только выключите, то и бот отвечать перестанет)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *