Вебхуки
С простым ботом наконец-то разобрались, теперь будем осваивать различные “плюшки”. Первая из них и, пожалуй, самая главная, — вебхуки.
А в чём, собственно, разница?
(Следующий абзац был написан в 2015-2016г., библиотеки с того момента много обновлялись, поэтому в некоторых случаях использовать Long Polling будет не хуже, чем вебхуки).
Давайте для начала разберемся, как боты принимают сообщения. Первый и наиболее простой вариант заключается в периодическом опросе серверов Telegram на предмет наличия новой информации. Всё это осуществляется через т.н. Long Polling, т.е. открывается соединение на непродолжительное время и все обновления тут же прилетают боту. Просто, но не очень надежно. Во-первых, серверы Telegram периодически начинают возвращать ошибку 504 (Gateway Timeout), из-за чего некоторые боты впадают в ступор. Даже pyTelegramBotAPI, используемый мной, не всегда может пережить такое. Во-вторых, если одновременно запущено несколько ботов, вероятность столкнуться с ошибками возрастает. Это вдвойне обидно, если сами боты используются не очень часто.
Вебхуки работают несколько иначе. Устанавливая вебхук, вы как бы говорите серверам Telegram: “Слышь, если кто мне напишет, стукни сюда — (ссылка)”. Отпадает необходимость периодически самому опрашивать серверы, тем самым, исчезает неприятная причина падений ботов. Однако за это приходится платить необходимостью установки полноценного веб-сервера на ту машину, на которой планируется запускать ботов. Что ещё неприятно, надо иметь собственный SSL-сертификат, т.к. вебхуки в телеграме работают только по HTTPS. К счастью, в один прекрасный день появилась поддержка самоподписанных сертификатов. Вот об их применении я и расскажу.
Создаем сертификат
Повторюсь: я не считаю себя супер-мега-крутым специалистом в айти, возможно, я что-то делаю неправильно, тем не менее, это работает и выглядит вполне прилично. Ладно, приступим.
Для начала, установим пакет openssl (для Linux):
sudo apt-get install openssl
Затем сгенерируем приватный ключ:
openssl genrsa -out webhook_pkey.pem 2048
Теперь, внимание, генерируем самоподписанный сертификат вот этой вот длинной командой:
openssl req -new -x509 -days 3650 -key webhook_pkey.pem -out webhook_cert.pem
Нам предложат ввести некоторую информацию о себе: двухбуквенный код страны, имя организации и т.д. Если не хотите ничего вводить, ставьте точку. НО! ВАЖНО! Когда дойдете до предложения ввести Common Name, следует написать IP адрес сервера, на котором будет запущен бот.
Генерация сертификата
В результате получим файлы webhook_cert.pem и webhook_pkey.pem , положим их в какой-нибудь пустой каталог, в котором потом будем создавать бота. Сертификаты готовы, теперь займемся ботом. Чтобы не сильно загружать себе мозги, напишем простого echo-bot’а из урока №1, только теперь с использованием сертификата.
Наш вишнёвый сервер
Выше я упомянул необходимость наличия веб-сервера, для работы с вебхуками. Те, кто умело владеет Apache или Nginx, можете дальше не читать. Лично я никак не мог (и не могу до сих пор) понять, как обрабатывать входящие сообщения от этих серверов в Python. Поэтому, было принято простое и довольно эффективное решение — используем веб-фреймворк CherryPy. Это не самый простой фреймворк по сравнению, например, с Flask, но мы будем использовать именно его.
Итак, установим CherryPy простой командой python3 -m pip install cherrypy
Новый старый бот
Перейдем в каталог с нашими сертификатами и создадим файлы bot.py и config.py . В последнем создадим переменную token , в которую передадим токен нашего бота. Открываем bot.py .
Импортируем 2 библиотеки, зададим необходимые константы и создадим экземпляр бота:
Обратите внимание, что Telegram поддерживает всего 4 различных порта при работе с самоподписанными сертификатами. Теоретически, это означает, что на одной машине может быть запущено не больше 4 ботов на вебхуках. Практически, это поправимо, но об этом — в следующий раз.
Создадим класс, реализующий экземпляр веб-сервера. Это, в принципе, стандартный код, который от бота к боту сильно меняться не будет:
Посмотрите на название функции: index . Это, по сути, обозначает последнюю часть URL. Поясню на примере: если бы мы хотели получать обновления на адрес 80.100.95.20/webhooksbot , то функцию выше мы бы назвали webhooksbot . index — это аналог отсутствия какой-либо дополнительной маршрутизации. Зачем менять это значение на другое, рассказано здесь 12, сейчас это не нужно.
Итак, что мы видим в коде выше? Принимаем входящие запросы по URL наш.ip.адрес/ , получаем содержимое и прогоняем через набор хэндлеров. Кстати, о них. Т.к. мы реализуем простейших echo-бот, хэндлер нам нужен всего один:
Внимательный читатель всё же заметит одно отличие, о котором я говорить не буду 😉 Заодно ещё один повод открыть документацию.
Далее, отправим серверу наш самоподписанный сертификат и “обратный адрес”, по которому просим сообщать обо всех новых сообщениях:
Наконец, укажем настройки нашего сервера и запустим его!
Обратите внимание на последнюю строку. Наш сервер в качестве “корня” будет прослушивать адрес вида “ip-адрес/токен_бота”, относительно которого index — это и есть этот адрес. Может, немного криво пояснил, но позднее вам всё станет предельно ясно, сейчас не нужно загромождать голову лишней информацией.
Запустим бота и напишем ему парочку сообщений. Затем посмотрим в окно терминала:
Лог сервера
Если код статуса равен 200 (OK), значит, всё в порядке и бот получил сообщения от сервера.
Telegram бот через webhook
Я тогда давно написал статью про создание Telegram бота, и обещал дополнить её описанием настройки работы через webhook, но так и не дополнил. Вот только сейчас дошли руки.
Что это такое
Как пишут в документации, общаться с серверами Telegram бот может двумя способами:
-
— pull: ваш бот постоянно дёргает сервер Telegram и проверяет есть ли новые сообщения; — push: по мере поступления новых сообщений сервер Telegram отправляет их вашему боту.
Разницу можно изобразить следующим образом:
Очевидно, что второй способ ( setWebhook ) рациональнее для всех участников процесса. Однако в нём присутствует неявная сложность: кто-то должен принимать сообщения от Telegram на стороне бота, то есть необходим веб-сервер или его эквивалент.
Как настроить
Что нужно сделать:
- Заиметь доменное имя для сервера и получить на него сертификат (например, от Let’s Encrypt). Документация также говорит, что в случае самоподписанного сертификата можно обойтись и просто IP адресом, но этого я не пробовал;
- Запилить серверную часть на стороне бота (куда будет ломиться Telegram);
- Зарегистрировать адрес серверной части в Telegram (зацепить webhook на endpoint), чтобы Telegram знал, куда ломиться с сообщениями.
Сертификат
С доменом и сертификатом просто. Домен у меня уже был, а сертификат я получил по этой инструкции.
Вариант с самоподписанным сертификатом на прямой IP адрес я оставляю вам на самостоятельное изучение.
Серверная часть
Серверная часть чуть посложнее. Я переделал текущую реализацию бота на pyTelegramBotAPI, используя пример для AIOHTTP.
Ставим необходимые пакеты:
И сокращённо код бота теперь такой:
Что здесь происходит: мы запускаем мини-веб-сервер, который слушает порт 8443 и отвечает на запросы через определённый endpoint, который образован токеном бота. Токен используется здесь как достаточно уникальный идентификатор, чтобы какой-нибудь мимокрокодил из интернета не навызывал бота и не натворил дел. Полный адрес endpoint’а будет выглядеть вот так: https://YOUR.DOMAIN:8443/YOUR-TOKEN/ .
Обратите также внимание на отличия от стандартного примера из репозитория:
- в качестве файла сертификата указан fullchain.pem , а не cert.pem ;
- удалён код снятия и установки webhook’а.
Так как бота я запускаю не из-под root’а, сервис начал валиться с такой ошибкой:
То есть, у пользователя, из-под которого выполняется скрипт, нет доступа к /etc/letsencrypt/ , чтобы открыть файл сертификата. Я попытался дать доступ к каталогу для новой группы, включив в неё этого пользователя:
Но он один фиг не мог открыть файлы оттуда, даже простой ls выдавал ошибку доступа. В общем, или мои познания Linux полный отстой, или одно из двух. Пришлось тупо назначить его владельцем:
Тогда сервис запустился нормально.
Регистрация
Теперь осталось самое, как оказалось, сложное — зарегистрировать endpoint бота в Telegram. Сложности возникли потому, что я сначала неправильно понял принцип составления endpoint’а, а также из-за проблем с проверкой сертификата.
Для установки/регистрации webhook’а нужно выполнить следующий HTTP запрос (можно просто открыть этот URL в браузере):
Пока я экспериментировал и разбирался с форматом endpoint’а, Telegram возвращал мне нормальный результат:
Но потом я его видимо задолбал, и он стал возвращать мне следующее:
Но оказалось, что это ни на что не влияет, и webhook нормально устанавливается, так что можно даже не дожидаться таймаута, а просто отменять запрос через пару секунд.
Проверить статус webhook’а можно таким запросом:
Если всё нормально, должно вернуть такое:
Как видим, в поле url стоит наш endpoint.
Однако, мне оно сейчас возвращает такое:
Что указывает на некие проблемы с сертификатом. При этом бот работает нормально, то есть эта ошибка ни на что не влияет. Однако, если вместо fullchain.pem оставить cert.pem (как было указано в примере), то бот работать перестанет.
Стоит также отметить, что если вы установили webhook, то опрос Telegram через getUpdates работать больше будет. Чтобы снять webhook, надо отправить тот же самый запрос, что и для установки, но на этот раз без параметра url :
Ну и всё, не так уж и сложно. Если бы в документации (и сторонних манулах из интернетов) была указана такая простая вещь, что для webhook’а всего-то нужен лишь веб-сервер на стороне бота, я бы это сделал уже сто лет назад. Конечно, продвинутым чувакам это скорее всего было очевидно сразу, но мнe — нет.
Асинхронный телеграм-бот с вебхуками на Heroku
Посредством этой статьи я поделюсь своим опытом разработки телеграм-бота для большого количества пользователей: разберу свои ошибки и шаги для их решения.
Одной из моих рабочих задач как программиста была автоматизация проведения викторины. Конечно, уже существуют специализированные бесплатные приложения, заточенные под эти задачи, но нужно было такое, в котором не было бы ничего лишнего, оно было всегда под рукой и такое привычное, чтобы не нужно было с ним разбираться. Выбор пал на телеграм бота и для того, чтобы он справлялся с большей нагрузкой было принято решение использовать асинхронную библиотеку aiogram.
Начнём с создания эхо бота на aiogram, тут нет ничего сложного, возьмём пример из документации:
Однако преимущество aiogram над python-telegram-bot и pyTelegramBotAPI в том, что он асинхронный, а значит может обрабатывать несколько запросов почти единовременно. Стандартная база данных sqlite отлично подходит для несложных проектов и уже входит в стандартную библиотеку питона, поэтому для начала я решил использовать её.
Через несколько часов работы приложение было написано, и мы с коллегами решили протестировать на себе его работоспособность. Бот запускался с использование технологии long polling, и запускался он на локальном компьютере. Для небольшого количества человек этого вполне достаточно: 3-4 человека в секунду бот выдерживает без особых проблем.
Но, к сожалению или к счастью, во время проведения викторины боту посыпалось бОльшее количество запросов, на которое мы не рассчитывали, в связи с чем посыпались ошибки не обрабатываемые ошибки, связанные с одновременным постоянным запросом новых сообщений у сервера и обработкой уже полученных.
Решением этой проблемы стал переход на вебхуки. И, для обеспечения бесперебойной работы, разместим его на удалённом сервере. Отличным решением для этого является heroku: здесь можно управлять запуском приложения как с компьютера, так и с мобильного приложения, отслеживать логи и, что является наиболее важным для нас, настраивать вебхуки.
Алгоритм, для реализации эхо бота в данном случае занимает больше времени, но он достаточно прост:
2) На странице Personal создаём новое приложение
Выбираем имя нашего приложения (у меня это «aiogram-echo-bot-webhook» — запомним его, оно нам ещё понадобится!), меняем сервер на Europe и нажимаем кнопку «create app»
Отлично, мы подготовили контейнер для нашего приложения! Передать туда код самого приложения можно несколькими способами, например через Heroku CLI или через GitHub. Разберём деплой через гитхаб, так как при любой возможности лучше использовать контроль версий 🙂
Перед деплоем на Heroku хорошо бы переписать наше приложение на вебхуки:
Что здесь происходит?
TOKEN, HEROKU_APP_NAME – мы считываем из переменных окружения, которые скоро добавим в наш проект.
WEBHOOK_HOST – доменное имя нашего приложения
WEBHOOK_PATH – часть пути, на который мы будем принимать запросы. Его следует придумать таким, чтобы не было возможности его угадать, во избежание фальсификации запросов. В нашем случае используется токен бота, так как его, также, следует держать в секрете.
WEBHOOK_URL – полный url адрес, на который будут принимать запросы.
WEBAPP_HOST – хост нашего приложения, оставляем локальный.
WEBAPP_PORT – порт, на котором работает наше приложение, так же считывается с переменных окружения, которое предоставляет Heroku, его мы не заполняем.
Асинхронная функция on_startup устанавливает вебхук для нашего телеграм бота, на который будут отсылаться уведомления о получении новых сообщений. И on_shutdown, наоборот, удаляет этот вебхук при выключении.
Далее мы переключаем вывод логов только на вывод только чисто информативной информации. И, собственно, запускаем наш диспетчер, при этом при запуске опускаются все сообщения, которые были получены в то время, когда бот не работал, что указано в параметре «skip_updates».
Почти всё готово, но чтобы дать инструкции Heroku, как именно развернуть наше приложение, нужно создать файл «Procfile» и вставляем туда следующий код:
Здесь: web – значит, что наше приложение будет web приложением, а то, что идёт после «:» это строка, которую необходимо выполнить в первую очередь. Запустить наш файл main.py с помощью питона.
И ещё один файл, который необходим для запуска, это requirements.txt, в котором мы указываем все зависимости нашего проекта. Его создаём, выполнив команду pip freeze > requirements.txt .
Также можно указать, какую конкретную версию питона использовать: для этого создадим файл «runtime.txt» и впишем туда версию питона по шаблону «python-3.9.7»
Теперь подготовим переменные среды на Heroku: для этого переходим на вкладку «Settings» и жмём кнопку «Reveal Config Vars»
Здесь добавляем два поля:
BOT_TOKEN – токен, полученный у BotFather
HEROKU_APP_NAME – имя приложения созданного на heroku, которое мы с вами запоминали.
Кликаем на кнопку «connect».
Для того, чтобы наше приложение обновлялось каждый раз, как мы заливаем новые изменения в ветку «master», можем нажать кнопку «Enable Automatic Deploys»
В первый раз, всё-таки придётся деплоить самим, для этого нажимаем кнопку ниже:
И дожидаемся окончания деплоя. При положительном результате, вывод будет, примерно таким:
Также можно посмотреть логи в верху окна кнопка «More»->«View logs»:
Переходим в наш бот и отправляем ему пару сообщений, если бот отвечает, значит всё в порядке, если нет, то переходим в логи и смотрим, в чём может быть ошибка.
На этом можно было бы остановиться, эхо-бот готов, но в реальном проекте нам понадобится сохранять различные данные из приложения. Для этого нужна база данных, как и в прошлый раз мы можем воспользоваться стандартной sqlite, но так как мы используем асинхронную библиотеку, то и запросы в бд должны быть асинхронными. Поэтому устанавливаем библиотеку databases для sqlite: pip install databases[sqlite] .
Разобьём код по модулям и подключимся к базе данных: создаём файл config.py и выносим туда все переменные (WEBHOOK_HOST, WEBHOOK_PATH и т.д.).
И ещё один модуль «db.py», в котором пишем следующий код:
И дополняем модуль main.py:
Здесь мы после получения сообщения сохраняем его в базу данных, и затем просто возвращаем все сообщения, полученные от этого пользователя.
Не забываем обновить requirements.txt
Пушим всё на гитхаб, процесс сборки можно посмотреть на вкладке «Activity»
Проверяем в боте: отправляем пару сообщений, бот возвращает нам список сохранённых в базу.
Казалось бы, всё хорошо, но вдруг произошла непредвиденная ошибка и приложение необходимо перезапустить: зайдём на вкладку «Resources»
Нажимаем на карандаш, жмём переключатель, для выключения приложения и подтверждаем «confirm».
Вновь включаем таким же способом и пробуем отправить боту сообщения:
Ужас, мы потеряли все данные! Но почему, ведь они хранятся в базе данных? Это происходит потому, что деплой происходит в изолированных контейнерах и при каждом новом запуске создаётся новый контейнер, а как мы помним исходный файл с бд у нас был пустым.
В нашем случае данные нужны будут и после выключения, поэтому нам нужна изолированная от приложения база данных. К счастью на Heroku, помимо множества приложений, можно бесплатно развернуть и базу данных, например postgres.
Переходим в «elements»
Выбираем «Heroku Postgres»
Выбираем бесплатный план и вводим имя приложения, для которого подключаем бд, для того чтобы потом мы могли считывать строку подключения с переменных среды:
Переходим в переменные среды нашего приложения и видим, что там появился ключ «DATABASE_URL», который мы и будем использовать для подключения.
Для подключения к бд postgresql, установим пакет databases[postgresql]: pip install databases[postgresql] . Создаём исходные таблицы, но синтаксис создания таблицы немного поменяется:
Вновь обновляем requirements.txt и пушим на гит.
Дожидаемся окончания деплоя, если приложение не запущено, то запускаем его и отправляем проверочные сообщения боту:
Получаем сообщения, всё отлично! Как и в прошлый раз возникает непредвиденная ситуация, из-за которой приходится перезапускать приложение. Перезапускаем, отправляем ещё одно сообщение и …
Видим, что все данные сохранились в бд!
Вот всё и готово! А дальше всё зависит только от ваших предпочтений: для чего и под какие задачи разработать функционал бота, но вы можете быть уверенны, что его производительность будет на высоте, а данные надёжно сохранены.
Telegram API: наглядный разбор с примерами
Для любого бизнеса важно установить канал общения с клиентами. Но сделать это не так просто. Психология людей такова, что они не хотят захламлять память своего смартфона новым фирменным приложением из того места, которое они посетили. Совсем другое дело — чат-бот. Ненавязчивый и дружелюбный. А кроме того — со всеми необходимыми фишками: рекламными акциями, скидками и быстрым заказом. И уведомления в одном единственном удобном мессенджере. Почему бы его не реализовать в своем бизнесе? Тем более, что это не так сложно, как вы думаете.
«Купи мне истребитель». Сбор средств для Воздушных Сил ВСУ
Сегодня мы поговорим о ботах и их API ( telegram api ) на базе популярного мессенджера Telegram.
Содержание
Telegram Bot API и Telegram API
Все началось с того, что Николай Дуров совместно с командой программистов создал криптографический протокол. Его движок задействовал комбинацию симметричного шифрования AES , протокол Диффи-Хеллмана для обмена ключами шифрования между клиентами и ряд хеш-функций. На основе этого протокола был построен MTProto — механизм, позволяющий пользователям сегодня использовать Telegram-мессенджеры.
На данный момент есть два основных инструмента API, с помощью которых можно задействовать сервисы Telegram — Telegram Bot API и Telegram API . Первый служит для разработки чат-ботов, второй позволяет делать полностью кастомные Telegram-клиенты. Разработчикам также доступна открытая библиотека TDLib (Telegram Database Library), с помощью которой можно создавать свою версию мессенджера с уникальными опциями (как например, Telegram X, построенный именно на TDLib). Telegram Bot API является надстройкой над Telegram API , поэтому пользоваться Bot API можно без знаний о механизме используемого протокола MTProto .
Для его работы задействован промежуточный сервер с HTTPS-интерфейсом, который шифрует трафик и обеспечивает связь с Telegram API. Bot API позволяет легко создавать программы, которые используют интерфейс Telegram для выполнения кода на локальном сервере. Пользователи могут взаимодействовать с ботами, отправляя им сообщения, команды и встроенные запросы.
Принцип работы любого бота заключается в том, что он перманентно направляет запросы на сервер и регулярно получает обновления. Получать их можно двумя способами. Во-первых, можно использовать вебхуки, когда сервер делает обратный вызов на указанный URL. А во-вторых, можно просто « забрасывать » запросами Telegram, получая постоянные ответы.
Обратите внимание — получать уведомления о новых сообщениях в боте и других событиях вы можете всего один раз. Поэтому, если данные чата представляются вам очень важными, то придется самостоятельно сохранять список чатов и историю старых сообщений. Если вы случайно сотрете/потеряете эту информацию, то вы ее больше никак не восстановите.
В отличие от Bot API, где получать обновление можно только один раз, в Telegram API это ограничение можно обойти, если использовать несколько клиентов. В таком случае бот будет получать все обновления на каждом из запущенных клиентов. Также в Bot API нет возможности рассылки сообщений всем юзерам одновременно.
На GitHub ( https://github.com/tdlib/telegram-bot-api ) можно найти исходники сервера Bot API. Развернув такой сервер вы получите HTTP URL с возможностью организации работы через вебхуки. Также сможете загружать файлы (до двух терабайт) на локальный сервер. Сервер Bot API имеет возможность настройки порта и локального IP-адреса для вебхука, а также поддерживает до 100000 одновременных подключений — более чем достаточно для большинства задач.
BotFather: быстрый Start
Чтобы приступить к созданию собственного бота, необходимо получить токен для авторизации и подключения через API. Делается это при помощи служебного бота. Введите в поиске Telegram его имя — BotFather. Далее следует выбрать команду /newbot и дать имя боту.
Затем BotFather спросит вас имя, которое обязательно должно заканчиваться на bot , например, shop_serge_bot . Далее для бота будет сгенерирован уникальный токен, который будет выглядеть примерно так — 2093336709:AAGiH64Ec1R8r222sM9IywvlIGFkb7wFqyo .
Всего можно генерировать не более 20 ботов на одного пользователя. Управление ботами также происходит через меню команд служебного бота BotFather. Например, если вам потребуется настроить какой-то из ваших ботов, вы должны перейти по командам / mybots и затем нажать на кнопку Edit Bot . Здесь вы сможете настроить имя — Edit Name и указать описание — Edit Description .
Настраивая description для бота вы задаете текст, который будет показываться пользователям под сообщением « Что может делать этот бот? » когда они его будут подключать. В профиле бота также будут показаны сведения, которые вы задали в поле « About » (команда Edit About). В меню команд имеется возможность установить аватар — BotPic .
В меню настроек BotSettings включается режим встроенных запросов (по умолчанию эта опция отключена). Когда встроенные запросы активированы, пользователи могут вызвать вашего бота, просто введя имя пользователя в поле для ввода текста в любом чате, группе или канале.
Если Telegram использовать в коммерческих целях, чат-бот можно вооружить средствами для приема платежей. Стоит обратить внимание, что сам Telegram не занимается проведением транзакций, он лишь дает возможность подключить услуги длинного списка провайдеров.
В их числе такие платежные системы, как Stripe, YooMoney, Сбербанк, PayMaster, PSB, Tranzzo, Payme, CLICK, LiqPay, Portmone, Paymega, ECOMMPAY и др. Разумеется, чтобы использовать эти платежные системы, нужно быть юридическим лицом.
aiogram — асинхронная библиотека
Реализовывать свой проект удобнее при помощи библиотек, таких как aiogram — это, пожалуй, лучшая стабильная асинхронная библиотека для Python ( https://pypi.org/project/aiogram/ ).
Относительно асинхронности нужно сказать несколько слов. Python — язык однопоточный, и любые команды в нем выполняются только после того, как завершилось выполнение предыдущей команды. Однако в случае с ботом программе необходимо отвечать на множество сообщений и делать это очень быстро. Можно, конечно, плодить множество потоков выполнений, но такой вариант чаще всего неприемлем, и альтернативой выступает асинхронная реализация задачи.
Когда в потоке выполнения команды возникает какая-то пауза, например, работает функция и у нее при этом есть какой-то таймаут ожидания, мы получаем участок времени, который не занят решением алгоритма. Асинхронность в aiogram позволяет заполнить эти промежутки, ускоряя работу нашего бота и быстро отвечая на сообщения. Устанавливается эта библиотека следующей командой :
pip install -U aiogram.
Создаем эхо-бот
Перед тем как начать разбираться с Telegram-ботами, попробуйте создать простенький эхо-бот, который будет возвращать все поступающие сообщения. Это поможет понять механизм работы и разобраться с его функциями.
Создаем конфигурационный файл config.py и указываем в нем значение, сгенерированное ботом BotFather. Приступаем к написанию кода самого чат-бота.
Для начала импортируем конфигурацию и систему логирования. Затем подключаем все необходимые модули из aiogram . Указываем уровень логирования, а затем инициализируем бота, создав две переменные — Bot и Dispatcher .
Первая отвечает за прямой доступ к методам API и обеспечивает общее взаимодействие с ботом. Вторая, Dispatcher — простой обработчик событий. Мы обращаемся к этому обработчику событий и вызываем декоратор message_handler , который будет вызываться тогда, когда приходит событие о новом сообщении.
В данном случае обрабатываются все входящие сообщения, которые бот может читать. Тут важно понимать, что даже команды, написанные через слеш для бота — самые обычные сообщения. С точки зрения бота любое взаимодействие является сообщением.
Как уже говорилось ранее, обработка событий в Telegram может происходить двумя способами — long polling , когда мы со своей стороны постоянно запрашиваем сервер, а второй вариант — более мощное и быстрое решение вебхук . Реализация long polling на Linux имеет большой минус — бот часто зависает и его приходится постоянно перезапускать.
В случае с webhook бот загружается на сервер, у бота появляется API с url-адресом, сервер Teleram посылает нашему боту сообщения, как только они появляются. По сути, бот на вебхуках постоянно не работает, а включается лишь тогда, когда получает запрос с сервера. Этот метод предпочтительнее, он быстрее, но для тестов обычно используется long polling .
Если вы делаете бота, который работает с деньгами или какой-то конфиденциальной информацией, то параметр skip_updates лучше устанавливать в значение Falsе — тогда обработчик не будет пропускать старые события и будет обрабатывать их в любом случае. Если этого не делать, существует вероятность, что какая-нибудь важная транзакция может потеряться и возникнет потенциальная угроза безопасности (или коллизия).
Оформление: кнопки и текст
Все сообщения в Telegram можно форматировать, используя различные варианты оформления текста — жирный, курсив и т.д. В Bot API разметка сообщений может создаваться в HTML и Markdown. Для удобства в ботах применяются кнопки, которые ставят под сообщениями. Их называют инлайн-клавиатурой или инлайн-кнопками, и они бывают разных видов.
Например, URL button — простая кнопка со ссылкой на какой-то веб-ресурс. Вариант кнопки Callback запрашивает обновление. Она может применяться, скажем, для уведомлений или предупреждений (с окном notification или окном alert ). Кнопка для перехода в режим инлайн может открывать меню для выбора чата.
Другой тип кнопок — клавиатурный. Он дают возможность использовать подсказки бота. Например, они могут содержать наиболее частые запросы, ожидаемые от пользователя ( « как к вам проехать » , « время работы » и т.д.)
Один из примеров такой клавиатуры — бот в кафе для дистанционного принятия заказов:
Инструмент для оформления текста выбирается аргументом функции parse_mode .
Когда текст всех сообщений одинаково оформлен, это удобно — при этом можно сразу передать нужный тип Bot . Если все-таки для какого-то сообщения разметка не понадобится, то в этом месте ставится пустое значение parse_mode=»» .
Используя модуль markdown из aiogram.utils по ходу текста можно менять форматирование. Тип форматирования определяется функцией с дописанной к ней букве h , которая означает поддержку HTML.
Учим бот-модерации
Как видите, эхо-бот, код которого написан выше, отвечает нам теми же сообщениями, которые мы отсылаем. Однако, если мы добавим бот в какую-нибудь тестовую группу, то возвращать текстовые сообщения он уже не будет. Причина этого очевидна — боты Telegram не имеют доступа к сообщениям в групповых чатах. Чтобы изменить это, необходимо снова вернуться к меню BotFather и разделе меню Group Privacy выбрать Turn OFF .
Теперь, если проверить, можно увидеть, что бот стал дублировать сообщения, то есть он их видит. Следовательно, мы можем теперь сделать нашего чат-бота администратором группы и научить его удалять нежелательные сообщения в группе или даже банить пользователей. Права для администрирования в группе назначаются точно так же, как и для любого пользователя группы.
Отредактируем код нашего бота. Если в тексте сообщения содержатся плохие (матерные) слова, наш бот-админ их автоматически распознает и удалит. Для этого вместо нашей echo функции ставим фильтр:
Теперь, если перезапустить бот, он будет читать сообщения в группе и удалять нежелательные слова. Таким образом, можно делать проверку лексики на наличие нецензурных слов и нежелательных ссылок.
Кстати, аналогичным образом можно удалять надоедливые информационные сообщения о том, что к чату присоединился какой-то пользователь. В этом случае код будет практически идентичным. Мы вызываем тот же декоратор message_handler , только указываем в аргументах content_types в значении new_chat_memebers .
Мы это сделали, чтобы функция обрабатывала сообщения только каких-то конкретных типов, в данном случае — сервисные сообщения. Также бывают еще текстовые сообщения, медиасообщения, голосовые и пр.
Даем возможность бана в группе
Помимо основного кода нам понадобится сделать файл filters.py , который поместим рядом с главным файлом нашего бота:
В коде бота мы его импортируем:
Также необходимо в конфигурационном файле config.py указать id чата ( GROUP_ID ).
Все пользователи Telegram имеют свой id . Он постоянный, и поэтому по нему можно идентифицировать чаты. Если вдруг вы не знаете id , вы можете воспользоваться ботом @username_to_id_bot , который покажет это значение.
В токене бота первая часть — это его id . Например, токен 110301514:AмHdqTcvCG1vGWDxfyeDfSAs0K5PALDsaw принадлежит боту с id 110301514 . В Bot API перед id супергрупп и каналов добавляется -100 (например, id 1322414430 превращается в -1001322414430 ).
Заключение
Как видите, сложного ничего нет и все трудности при разработке чат-ботов сводятся к тому, чтобы найти оптимальный API и библиотеку под Python, C#, PHP и другие языки программирования. Сегодня это явный тренд, чат-боты могут создавать воронки продаж не хуже опытных менеджеров, а кроме того берут на себя массу функций, требовавших ранее человеческих ресурсов, — запись на прием к врачу, продажа билетов и так далее.
Более сложные боты обладают искусственным интеллектом и умеют использовать нейронные сети. Возможности таких чат-ботов ограничены только вашей фантазией, но об этом — в следующий раз. А пока посмотрите дополнительное видео по технике создания ботов на JavaScript для Telegram API :