Что такое dispatcher aiogram
Hide navigation sidebar
Hide table of contents sidebar
Toggle site navigation sidebar
aiogram 3.2.0 documentation
Toggle Light / Dark / Auto color theme
Toggle table of contents sidebar
- Installation
- Migration FAQ (2.x -> 3.0)
- Bot API
Toggle navigation of Bot API
Toggle navigation of Client session
- Use Custom API server
- Base
- aiohttp
- Client session middlewares
Toggle navigation of Types
- Animation
- Audio
- BotCommand
- BotCommandScope
- BotCommandScopeAllChatAdministrators
- BotCommandScopeAllGroupChats
- BotCommandScopeAllPrivateChats
- BotCommandScopeChat
- BotCommandScopeChatAdministrators
- BotCommandScopeChatMember
- BotCommandScopeDefault
- BotDescription
- BotName
- BotShortDescription
- CallbackQuery
- Chat
- ChatAdministratorRights
- ChatInviteLink
- ChatJoinRequest
- ChatLocation
- ChatMember
- ChatMemberAdministrator
- ChatMemberBanned
- ChatMemberLeft
- ChatMemberMember
- ChatMemberOwner
- ChatMemberRestricted
- ChatMemberUpdated
- ChatPermissions
- ChatPhoto
- ChatShared
- Contact
- Dice
- Document
- File
- ForceReply
- ForumTopic
- ForumTopicClosed
- ForumTopicCreated
- ForumTopicEdited
- ForumTopicReopened
- GeneralForumTopicHidden
- GeneralForumTopicUnhidden
- InlineKeyboardButton
- InlineKeyboardMarkup
- InputFile
- InputMedia
- InputMediaAnimation
- InputMediaAudio
- InputMediaDocument
- InputMediaPhoto
- InputMediaVideo
- KeyboardButton
- KeyboardButtonPollType
- KeyboardButtonRequestChat
- KeyboardButtonRequestUser
- Location
- LoginUrl
- MenuButton
- MenuButtonCommands
- MenuButtonDefault
- MenuButtonWebApp
- Message
- MessageAutoDeleteTimerChanged
- MessageEntity
- MessageId
- PhotoSize
- Poll
- PollAnswer
- PollOption
- ProximityAlertTriggered
- ReplyKeyboardMarkup
- ReplyKeyboardRemove
- ResponseParameters
- Story
- SwitchInlineQueryChosenChat
- User
- UserProfilePhotos
- UserShared
- Venue
- Video
- VideoChatEnded
- VideoChatParticipantsInvited
- VideoChatScheduled
- VideoChatStarted
- VideoNote
- Voice
- WebAppData
- WebAppInfo
- WriteAccessAllowed
- ChosenInlineResult
- InlineQuery
- InlineQueryResult
- InlineQueryResultArticle
- InlineQueryResultAudio
- InlineQueryResultCachedAudio
- InlineQueryResultCachedDocument
- InlineQueryResultCachedGif
- InlineQueryResultCachedMpeg4Gif
- InlineQueryResultCachedPhoto
- InlineQueryResultCachedSticker
- InlineQueryResultCachedVideo
- InlineQueryResultCachedVoice
- InlineQueryResultContact
- InlineQueryResultDocument
- InlineQueryResultGame
- InlineQueryResultGif
- InlineQueryResultLocation
- InlineQueryResultMpeg4Gif
- InlineQueryResultPhoto
- InlineQueryResultVenue
- InlineQueryResultVideo
- InlineQueryResultVoice
- InlineQueryResultsButton
- InputContactMessageContent
- InputInvoiceMessageContent
- InputLocationMessageContent
- InputMessageContent
- InputTextMessageContent
- InputVenueMessageContent
- SentWebAppMessage
- InputSticker
- MaskPosition
- Sticker
- StickerSet
- EncryptedCredentials
- EncryptedPassportElement
- PassportData
- PassportElementError
- PassportElementErrorDataField
- PassportElementErrorFile
- PassportElementErrorFiles
- PassportElementErrorFrontSide
- PassportElementErrorReverseSide
- PassportElementErrorSelfie
- PassportElementErrorTranslationFile
- PassportElementErrorTranslationFiles
- PassportElementErrorUnspecified
- PassportFile
- Invoice
- LabeledPrice
- OrderInfo
- PreCheckoutQuery
- ShippingAddress
- ShippingOption
- ShippingQuery
- SuccessfulPayment
- Update
- WebhookInfo
- CallbackGame
- Game
- GameHighScore
Toggle navigation of Methods
- addStickerToSet
- createNewStickerSet
- deleteStickerFromSet
- deleteStickerSet
- getCustomEmojiStickers
- getStickerSet
- sendSticker
- setCustomEmojiStickerSetThumbnail
- setStickerEmojiList
- setStickerKeywords
- setStickerMaskPosition
- setStickerPositionInSet
- setStickerSetThumbnail
- setStickerSetTitle
- uploadStickerFile
- answerCallbackQuery
- approveChatJoinRequest
- banChatMember
- banChatSenderChat
- close
- closeForumTopic
- closeGeneralForumTopic
- copyMessage
- createChatInviteLink
- createForumTopic
- declineChatJoinRequest
- deleteChatPhoto
- deleteChatStickerSet
- deleteForumTopic
- deleteMyCommands
- editChatInviteLink
- editForumTopic
- editGeneralForumTopic
- exportChatInviteLink
- forwardMessage
- getChat
- getChatAdministrators
- getChatMember
- getChatMemberCount
- getChatMenuButton
- getFile
- getForumTopicIconStickers
- getMe
- getMyCommands
- getMyDefaultAdministratorRights
- getMyDescription
- getMyName
- getMyShortDescription
- getUserProfilePhotos
- hideGeneralForumTopic
- leaveChat
- logOut
- pinChatMessage
- promoteChatMember
- reopenForumTopic
- reopenGeneralForumTopic
- restrictChatMember
- revokeChatInviteLink
- sendAnimation
- sendAudio
- sendChatAction
- sendContact
- sendDice
- sendDocument
- sendLocation
- sendMediaGroup
- sendMessage
- sendPhoto
- sendPoll
- sendVenue
- sendVideo
- sendVideoNote
- sendVoice
- setChatAdministratorCustomTitle
- setChatDescription
- setChatMenuButton
- setChatPermissions
- setChatPhoto
- setChatStickerSet
- setChatTitle
- setMyCommands
- setMyDefaultAdministratorRights
- setMyDescription
- setMyName
- setMyShortDescription
- unbanChatMember
- unbanChatSenderChat
- unhideGeneralForumTopic
- unpinAllChatMessages
- unpinAllForumTopicMessages
- unpinAllGeneralForumTopicMessages
- unpinChatMessage
- deleteMessage
- editMessageCaption
- editMessageLiveLocation
- editMessageMedia
- editMessageReplyMarkup
- editMessageText
- stopMessageLiveLocation
- stopPoll
- answerInlineQuery
- answerWebAppQuery
- getGameHighScores
- sendGame
- setGameScore
- answerPreCheckoutQuery
- answerShippingQuery
- createInvoiceLink
- sendInvoice
- deleteWebhook
- getUpdates
- getWebhookInfo
- setWebhook
- setPassportDataErrors
Toggle navigation of Enums
- BotCommandScopeType
- ChatAction
- ChatMemberStatus
- ChatType
- ContentType
- Currency
- DiceEmoji
- EncryptedPassportElement
- InlineQueryResultType
- InputMediaType
- MaskPositionPoint
- MenuButtonType
- MessageEntityType
- ParseMode
- PassportElementErrorType
- PollType
- StickerFormat
- StickerType
- TopicIconColor
- UpdateType
Toggle navigation of Handling events
- Router
- Dispatcher
- Dependency injection
- Filtering events
Toggle navigation of Filtering events
- Command
- ChatMemberUpdated
- Magic filters
- MagicData
- Callback Data Factory & Filter
- Exceptions
Toggle navigation of Finite State Machine
Toggle navigation of Class based handlers
- BaseHandler
- CallbackQueryHandler
- ChosenInlineResultHandler
- ErrorHandler
- InlineQueryHandler
- MessageHandler
- PollHandler
- PreCheckoutQueryHandler
- ShippingQueryHandler
- ChatMemberHandler
Toggle navigation of Utils
Зачем нужен Dispather в Aiogram?
Для чего нужен Dispatcher, если отправка ведётся так: await bot.send_sticker(message.chat.id, stick) ?
А также, для чего открывать файл в двоичном режиме?
- Вопрос задан более двух лет назад
- 4459 просмотров
Комментировать
Решения вопроса 1
Не стоит на столько углубляться на данном этапе изучения библиотеки.
Если коротко Dispatcher принимает все апдейты и обрабатывает их.
Можете отправлять сообщения как вам удобно, хоть await mybot.bot.send_sticker хоть await bot.send_sticker лишь бы импортировали все правильно
Встроенные фильтры в aiogram
F0rzend
Используя aiogram вы получаете множество дополнительных штук, которых нет в других библиотеках, как например встроенные фильтры. Вместо того, чтобы лепить страшную func=lambda message: message.text==»Текст» , как в pyTelegramBotApi, в aiogram вы пропишете просто text=»Текст» . Но это далеко не все. При этом встроенные фильтры постоянно добавляются, но это нигде нормально не освещено (кроме источников), это подтолкнуло меня к написанию данной статьи. Сегодня мы полазим в исходниках aiogram и посмотрим, какие же фильтры у нас есть «из коробки«.
Начнём, как не удивительно, с открытия репозиторий aiogram на github. Не сложно догадаться, что все фильтры находятся в пакете filters. Пара минут поиска приводят нас к aiogram / dispatcher / filters / . Далеко ходить не будем, сразу заглянем в файл __init__.py
В этом файле находятся просто импорты. Но это даёт нам очень важную информацию — всё самое интересное находится в файле .builtin. Таким образом составим небольшой список всех фильтров в текущей версии aiogram 2.10.2 :
Regexp — регулярное выражение для сообщений callback query
IDFilter — фильтр для проверки id чата или пользователя
AdminFilter — проверка на то, является ли пользователь администратором чата
IsReplyFilter — проверяет, что отправленное сообщение является ответом
IsSenderContact — проверяет, что пользователь отправил именно свой контакт
Все стандартные фильтры подключаются на Dispatcher при его инициализации, при помощи приватного метода _setup_filters. Здесь мы можем сразу увидеть к каким из обработчиков применяются фильтры. Например первый подключаемый фильтр — StateFilter, который вы используете для работы с машиной состояний, подключается всем обработчикам кроме errors_handlers, poll_handlers и poll_answer_handlers, а ContentTypeFilter исключительно к сообщениям, которые содержат в update тип Message (т.к. только в нем есть content_type). Это следует из следующих строк:
Дальше мы рассмотрим подробнее каждый из фильтров.
Command фильтры
Все command фильтры применяются исключительно на обработчики message_handler и edited_message_handler.
Может использоваться как аргумент обработчика commands. Т.е. вы можете использовать данный фильтр двумя способами:
@dp.message_handler(commands='myCommand', commands_ignore_caption=False)
from aiogram.dispatcher.filters import Command @dp.message_handler(Command('myCommand', ignore_caption=False)) . . .
Наверное самый часто используемый фильтр — Command. Наверняка все о нём знают, но я уверен, что не все знают о том, на сколько это «крутой» фильтр. Кроме всем известного аргумента commands он принимает prefixes, ignore_case, ignore_mention, ignore_caption.
- prefixes — префиксы команды, т.е. то, с чего команда начинается. Самыми частыми префиксами являются стандартный » / «, а также » ! «.
- ignore_case — игнорировать регистр команды. Проверяется с помощью str.lower() .
- ignore_mention — игнорировать упоминание бота. По умолчанию False. Таким образом, когда бот получает команду с mention другого бота, он её не обрабатывает. Если передать True, в независимости от mention в /command@mention команда попадёт в обработчик, даже если это команда с упоминанием другого бота. Помните, что бот с включенным privacy mode не получит команду с упоминанием другого бота.
- ignore_caption — игнорировать команды, которые написаны под изображением. По умолчанию True.
CommandStart
Этот фильтр, для проверки команды /start . Это фильтр Command, в который передаётся команда ‘start’, а остальные аргументы остаются по умолчанию. Фильтр CommandStart принимает лишь два аргумента:
- deep_link — строка или регулярное выражение, для обработки deep_link.
- encoded — обрабатывать закодированную ссылку deep_link (по умолчанию False).
Пример использования можно взять следующий:
from aiogram import types from aiogram.dispatcher.filters import CommandStart @dp.message_handler(filters.CommandStart(deep_link='deep_link')) async def deep_link(msg: types.Message): await msg.answer('Да, знаем мы такое') @dp.message_handler(filters.CommandStart()) async def command_start_handler(msg: types.Message): await msg.answer(f'Ну привет, хотел чего?')
Кроме обычного ответа на команду /start , этот фильтр также обрабатывает deep_link, для обработки deep_link. Мы ловим с его помощью ссылки с говорящим аргументом ‘ deep_link ‘ (т.е ссылок вида https://t.me/?start=deep_link) .
CommandHelp, CommandPrivacy и CommandSettings
Фильтры CommandHelp, CommandPrivacy и CommandSettings не представляют из себя ничего особо интересного. Это просто фильтр Command с переданной в него командой ‘help’ , ‘ privacy’ или ‘ settings’ соответственно. Особенность этих команд заключается в том, что это глобальные команды, наличие которые добавляет дополнительные кнопки в профиле бота.
ContentTypeFilter
Этот фильтр проверяет тип контента, будь то фото, текст или что-нибудь другое. Должен использоваться исключительно как аргумент content_types. По умолчанию проверяет на текст. Принимает либо строку, либо aiogram.types.ContentTypes (что строкой и является).
Можно придумать много примеров использования, но возьмём самый простой: пусть бот хвалит картиночки.
from aiogram import types from aiogram.dispatcher import filters from app.loader import dp @dp.message_handler(content_types='photo') @dp.message_handler(content_types=types.ContentTypes.PHOTO) async def content_type_example(msg: types.Message): await msg.answer('Красивенько ')
ExceptionsFilter
Фильтр, используемый в error_handlers. Принимает исключение. Работает исключительно в качестве аргумента по ключевому слову exception. Пример использования можно придумать следующий:
from aiogram import types from aiogram.utils import exceptions from loguru import logger from app.loader import dp @dp.errors_handler(exception=exceptions.BotBlocked) async def bot_blocked_error(update: types.Update, exception: exceptions.BotBlocked): logger.exception(f'Bot blocked by user ') return True
Данный обработчик сработает, когда бот словит исключение BotBlocked. Здесь можно, например, удалять пользователя из базы данных, чтобы во время следующей рассылки не тратить время на данного пользователя.
HashTag
Данный фильтр проверяет то, что в сообщении содержится определённый хеш ( # ) или кеш ( $ ) тег. Может использоваться либо как callable, либо как аргументы hashtags и cashtags.
Допустим пусть бот понтуется, если видит в сообщении хештег или один из кештегов: #money или $EUR или $USD.
from aiogram import types from aiogram.dispatcher import filters, FSMContext from app.loader import dp @dp.message_handler(hashtags='money') @dp.message_handler(cashtags=['eur', 'usd']) async def hashtag_example(msg: types.Message): await msg.answer('Ееее, деньги ')
Regexp
Фильтр, проверяющий регулярное выражение. Подключён на большинство обработчиков. Для примера напишем обработчик, который будет обрабатывать ссылку на изображения:
from aiogram import types from aiogram.dispatcher import filters from app.loader import dp IMAGE_REGEXP = r'https://.+?\.(jpg|png|jpeg)' @dp.message_handler(filters.Regexp(IMAGE_REGEXP)) async def regexp_example(msg: types.Message): await msg.answer('Похоже на картинку, не так ли?')
Этот фильтр может использоваться также и как аргумент. Используйте для этого ключевое слово regexp :
@dp.message_handler(regexp=IMAGE_REGEXP) async def regexp_example(msg: types.Message): . . .
RegexpCommandsFilter
Фильтр, проверяющий команду через регулярное выражение. Может использоваться как аргумент regexp_commands (Именно поэтому у меня функция с двумя декораторами, вам стоит использовать один из приведенных вариантов).
Возьмём идентичный пример. Реализуем команду image с несколькими префиксами, которые проверяют ссылку на изображение:
from aiogram import types from aiogram.dispatcher import filters from app.loader import dp IMAGE_REGEXP = r'https://.+?\.(jpg|png|jpeg)' COMMAND_IMAGE_REGEXP = r"/image:" + IMAGE_REGEXP @dp.message_handler(filters.RegexpCommandsFilter([COMMAND_IMAGE_REGEXP])) @dp.message_handler(regexp_commands=[COMMAND_IMAGE_REGEXP]) async def command_regexp_example(msg: types.Message): await msg.answer('По вашей команде докладываю, что данная ссылка является изображением!')
Изначально в фильтре идёт проверка на команду, так что сообщение должно начинаться с косой черты.
StateFilter
Все, кто использовал FSM знакомы с этим фильтром. Этот фильтр проверяет состояние, в котором находится пользователь. Он может использоваться только как аргумент функции state . Для примера опишем 2 обработчика: для присвоения состояния и для его сброса.
from aiogram import types from aiogram.dispatcher import FSMContext from app.loader import dp @dp.message_handler(commands='set_state') async def set_state(msg: types.Message, state: FSMContext): """Присваиваем пользователю состояние для теста""" await state.set_state('example_state') await msg.answer('Состояние установлено') @dp.message_handler(state='example_state') async def state_example(msg: types.Message, state: FSMContext): await msg.answer('Ой всё, иди отсюда') await state.finish()
Text
Ещё один очень популярный фильтр. Он проверяет текст, будь это текст сообщения, или callback_data кнопки. Кроме полной идентичности (equals), данный фильтр также может проверить то, что текст начинается, содержит или заканчивается какой-либо строкой. Вы можете использовать импортированный класс, передавая в него аргументы либо использовать фильтр как аргумент функции. Пройдёмся по аргументам конструктора класса:
- equals — строка, которой текст должен быть идентичен
- contains — строка, которую должен содержаться текст
- startswith — строка, которой текст должен начинаться
- endswith — строка, которой текст должен заканчиваться
- ignore_case — игнорировать регистр текст. Проверяется с помощью str.lower() .
Как я и сказал ранее, данный фильтр может использоваться как аргумент. Для этого используйте text, text_contains, text_startswith или text_endswith.
Рассмотрим следующий пример: допустим нам нужно ругать в чате участника за какую-нибудь фразу:
import asyncio from aiogram import types from aiogram.dispatcher import filters from app.loader import dp FORBIDDEN_PHRASE = [ 'Курс', 'Фигня' ] @dp.message_handler(filters.Text(contains=FORBIDDEN_PHRASE, ignore_case=True)) async def text_example(msg: types.Message): await msg.reply('Сам фигня!')
Таким образом, если сообщение пользователя будет содержать обе строки из списка, бот выскажет ему всё, что о нём думает.
IDFilter
Ещё один фильтр, который заслуживает внимания — фильтр для проверки идентификатора. Он может использоваться как аргумент user_id, chat_id, так и как callable объект IDFilter(user_id=12345789)
Сам фильтр имеет два аргумента:
- user_id — проверяет ID пользователя
- chat_id — проверяет ID чата
Представим, что нам нужно написать обработчик, который будет отвечать на все сообщения в диалоге с админом, если обновление не попало ни в один из обработчиков (для этого расположим обработчик в конце файла). Таким образом в конфигурационном файле у нас есть константа типа List с идентификаторами суперпользователей SUPERUSER_IDS. Пример будет иметь следующий вид:
from aiogram import types from aiogram.dispatcher import filters from app.loader import dp from app.config import SUPERUSER_IDS @dp.message_handler(filters.IDFilter(chat_id=SUPERUSER_IDS)) @dp.message_handler(chat_id=SUPERUSER_IDS) async def id_filter_example(msg: types.Message): await msg.answer('Да, помню тебя, наш человек')
Этот обработчик сработает на сообщение суперпользователя, и только если ни это сообщение не прошло по фильтрам ни в один из предыдущих фильтров.
AdminFilter
Один из любимых фильтров разработчиков чат модераторов. Как понятно из названия проверяет, что запрос прилетел от администратора чата. Может использоваться как callable объект, или аргумент функции.
Допустим мы пишем бота для администрирования чата и нам нужна команда, для изменения изображения чата. Естественно, такую команду не следует доверять обычным пользователям, поэтому пусть ответственность за использование этой команды будет исключительно на плечах администрации чата
from aiogram import types from aiogram.dispatcher import filters from app.loader import dp @dp.message_handler(commands='change_photo', is_chat_admin=True) @dp.message_handler(filters.Command('change_photo'), filters.AdminFilter()) async def chat_admin_example(msg: types.Message): await msg.answer('Не, мне и эта нравится')
Ещё раз хочу вам напомнить, что я использую два декоратора исключительно для демонстрации. Вам стоит выбрать одно из решений. Также обратите внимание, что вперёд я поставил фильтр на команду, потому что AdminFilter делает запрос в API, что требует времени, а значит замедляет работу бота.
Кроме логического типа данных, этот фильтр может также содержать ID чата. В этом случае он будет проверять, что запрос пришёл именно от администратора чата с конкретным идентификатором, а не текущего чата.
Этот фильтр не может быть False.
Если при использовании этого фильтра как callable не передавать аргументы, проверяться будет администрация текущего чата.
IsReplyFilter
Один из простейших фильтров. Он проверит, является ли сообщение или пост в канале ответом. Может использоваться как аргумент is_reply.
Допустим по команде user_id пусть бот возвращает ID пользователя, ответом на сообщение которого была использована команда.
from aiogram import types from aiogram.dispatcher import filters from app.loader import dp @dp.message_handler(is_reply=True, commands='user_id') @dp.message_handler(filters.IsReplyFilter(True), commands='user_id') async def reply_filter_example(msg: types.Message): await msg.answer(msg.reply_to_message.from_user.id)
IsSenderContact
Этот фильтр проверяет, что пользователь отправил именно свой контакт. Может использоваться как callable или как аргумент is_sender_contact. Думаю никому не нужно объяснять, где это необходимо.
from aiogram import types from aiogram.dispatcher import filters from app.loader import dp @dp.message_handler(content_types='contact', is_sender_contact=True) @dp.message_handler(filters.IsSenderContact(True), content_types='contact') async def sender_contact_example(msg: types.Message): await msg.answer('Да, вроде на тебя похож, ладно')
ForwardedMessageFilter
Этот фильтр проверяет, что отправленное сообщение является пересланным. Может использоваться как аргумент is_forwarded или как объект класса.
Пусть бот ругает пользователя, за попытку отправить чужое сообщение:
from aiogram import types from aiogram.dispatcher import filters from app.loader import dp @dp.message_handler(is_forwarded=True) @dp.message_handler(filters.ForwardedMessageFilter(True)) async def forwarded_example(msg: types.Message): await msg.answer('Не пытайся меня обмануть, я же вижу, что это не твоё сообщение')
ChatTypeFilter
Из названия этого фильтра понятно, что он проверяет тип чата. Он может использоваться либо как объект, либо как аргумент chat_type. Принимает либо строку, либо types.ChatType (что тоже является строкой).
Допустим нам нужно, чтобы бот по команде is_pm подтверждал, что команда выполнена в личных сообщениях.
from aiogram import types from aiogram.dispatcher import filters from app.loader import dp @dp.message_handler(chat_type=types.ChatType.PRIVATE, commands='is_pm') @dp.message_handler(chat_type='private', commands='is_pm') @dp.message_handler(filters.ChatTypeFilter(types.ChatType.PRIVATE), commands='is_pm') async def chat_type_example(msg: types.Message): await msg.answer('Да, это личные сообщения')
Итоги
В этой статье мы разобрали абсолютно все фильтры фреймворка aiogram и разобрали примеры их использования, а так же задачи, в которых они могут применяться. Все примеры вы можете найти в моём github репозитории.
Урок 1. Быстрый старт. Эхо-бот
Перед началом убедитесь, что у вас установлен интерпретатор языка Python версии не ниже 3.6 (актуальные версии посмотреть и скачать можно здесь). Первый и второй уроки будут проведены на версии 3.6.4, версия библиотеки aiogram 1.0.4 , проверено на версии 1.1.
Этот пункт можно пропустить, если вы не новичок, и уже всё проверили.
Проверить версию интерпретатора можно следующим образом (справедливо для большинства систем): python —version . Будет возвращено Python 3.6.4 . Если у вас установлено несколько версий интерпретатора, будет необходимо указать версию: python3 —version .
Далее устанавливаем библиотеку командой pip install -U aiogram . Если у вас установлено несколько интерпретаторов (например 2 и 3), то необходимо явно указать версию pip: pip3 install -U aiogram . Если у вас установлено несколько версий 3 (например 3.4, 3.5, 3.6), то обращаемся к необходимому интерпретатору командой -m pip . , то есть в данном случае python3.6 -m pip install -U aiogram . Проверить версию библиотеки можно командой pip freeze | grep aiogram (тут так же не забудьте правильно указать версию pip), вернется aiogram==1.0.4 . Возможно, у вас в Windows не будет работать команда grep , тогда используйте просто команду pip freeze и убедитесь в присутствии aiogram в результате выполнения команды.
Начинаем писать код
Давайте для знакомства с библиотекой создадим бота, который будет приветствовать пользователя и высылать в ответ присланный ему текст. Для этого создадим каталог для нашего бота и сохраним там два файла: bot.py и config.py .
Открываем последний любимым текстовым редактором и записываем туда токен, полученный от @BotFather:
TOKEN = '123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11'
Теперь возьмемся за основной файл — приступаем к редактированию файла bot.py . Для этого импортируем необходимые модули библиотеки aiogram и токен бота, а так же инициализируем объекты бота и диспетчера:
from aiogram import Bot, types from aiogram.dispatcher import Dispatcher from aiogram.utils import executor from config import TOKEN bot = Bot(token=TOKEN) dp = Dispatcher(bot)
Команда, с которой начинается общение пользователя с ботом — /start . Поэтому давайте научим нашего бота реагировать на эту команду. Создаем message_handler и объявляем там функцию ответа:
@dp.message_handler(commands=['start']) async def process_start_command(message: types.Message): await message.reply("Привет!\nНапиши мне что-нибудь!")
Ещё в ботах принято создавать обработчик команды /help — вдруг пользователь заинтересуется возможностями бота.
Вообще, мы могли бы добавить просто help в массив, передаваемый параметру commands , чтобы получилось:
@dp.message_handler(commands=['start', 'help'])
Но зачем приветствовать пользователя снова? Поэтому создадим отдельный message_handler для этой команды:
@dp.message_handler(commands=['help']) async def process_help_command(message: types.Message): await message.reply("Напиши мне что-нибудь, и я отпрпавлю этот текст тебе в ответ!")
Обращу внимание новичка на то, что называть функции можно как угодно — хоть abc , хоть qwerty , однако называя функции понятным языком — process_start_command , process_help_command сразу понятно, какая за что отвечает. Главное, чтобы имена не повторялись. Называть как угодно можно также и имя параметра, покажу дальше.
Итак! Осталось сделать обработку текстового сообщения. Для этого пишем следующее:
@dp.message_handler() async def echo_message(msg: types.Message): await bot.send_message(msg.from_user.id, msg.text)
Объясняю, что мы только что написали:
Если не указывать тип обрабатываемого сообщения, то библиотека по умолчанию делает обработку только текстовых сообщений — то, что нам и нужно. Поэтому скобки на первой строчке остаются пустыми.
Параметр msg это всё то же сообщение, как и в предыдущих пунктах.
В данном случае на последней строчке мы отправляем пользователю сообщение не ответом, а простым сообщением. Для этого мы воспользовались методом send_message и передали в него два обязательных параметра — айди чата, куда отправляем, и сам текст сообщения. Их мы взяли из объекта msg, который является представителем класса Message. Параметр from_user ссылается на ещё один объект — данный параметр имеет класс User. У него есть параметр id — уникальный идентификатор для чатов и каналов в телеграме. Ну и текст полученного сообщения мы получили из поля text.
Финальный штрих
Чтобы получать сообщения от серверов Telegram воспользуемся поллингом (polling. to poll — опрашивать) — постоянным опросом сервера на наличие новых обновлений. Для этого дописываем в bot.py следующее:
if __name__ == '__main__': executor.start_polling(dp)
from aiogram import Bot, types from aiogram.dispatcher import Dispatcher from aiogram.utils import executor from config import TOKEN bot = Bot(token=TOKEN) dp = Dispatcher(bot) @dp.message_handler(commands=['start']) async def process_start_command(message: types.Message): await message.reply("Привет!\nНапиши мне что-нибудь!") @dp.message_handler(commands=['help']) async def process_help_command(message: types.Message): await message.reply("Напиши мне что-нибудь, и я отпрпавлю этот текст тебе в ответ!") @dp.message_handler() async def echo_message(msg: types.Message): await bot.send_message(msg.from_user.id, msg.text) if __name__ == '__main__': executor.start_polling(dp)
Осталось запустить программу. Для этого в командной строке переходим в директорию проекта и пишем
python bot.py
Теперь можно написать нашему боту: