В этом руководстве мы создадим простого бота Telegram с помощью python-telegram-bot и развернем его в Heroku с помощью реестра контейнеров Heroku и Docker.

Весь исходный код доступен в репозитории Github.

Команды

У нашего бота есть 2 команды: /start и /random.

  • Команда /start приветствует наших новых пользователей
  • Команда /random отправляет случайное число пользователю

Бот

У нашего скрипта есть 2 режима работы: разработка (локальная) и продакшн (Heroku). Он определяется с помощью переменной env MODE с двумя возможными значениями: dev, prod. Если вы не укажете РЕЖИМ, вы получите сообщение об ошибке регистратора , и сценарий завершится.

Не менее важна env variableTOKEN. Вы можете получить его в системе Telegram Bot под названием BotFather.

Вот изображение-пример вашего возможного диалога с BotFather.

ВАЖНО: никому не сообщайте свой ТОКЕН бота, не размещайте его в общедоступном репозитории Github и т. д.!

Если вас интересует переменная env PORT, вы можете просто не устанавливать ее, 8443 - это нормальный номер порта для Heroku.

HEROKU_APP_NAME - это имя вашего приложения, которое вы создали в Heroku.

Теперь пора поговорить о самом коде.

Прежде всего, нам нужно инициализировать наш Updater с помощью TOKEN.

Затем нам нужно добавить обработчики команд, мы собираемся использовать класс CommandHandler из пакета telegram.ext. Он принимает два обязательных аргумента:

  • command - строка или список строк, которые должен прослушивать этот обработчик
  • callback - функция обратного вызова для этого обработчика

В нашем примере, если пользователь отправляет /start сообщение, оно будет перехвачено start_hanlder, /random сообщение будет перехвачено random_handler; все остальные сообщения будут игнорироваться.

Местный

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

MODE=dev; TOKEN=<your TOKEN from BotFather>; python bot.py

Если вы используете PyCharm для разработки Python, вы можете использовать окно Run / Debug Configurations.

После запуска bot.py с использованием предпочитаемого вами варианта вы получите

2018–12–14 15:12:21,500 — root — INFO — Starting bot

Если вы зайдете к своему боту в Telegram и нажмете кнопку Start, вы получите

2018–12–14 15:12:36,617 — root — INFO — User <user_id> started bot

И если вы наберете команду /random, вы получите

2018–12–14 15:12:38,238 — root — INFO — User <user_id> randomed number 2

Heroku

У вас должна быть учетная запись Heroku.

Чтобы запустить своего бота в Heroku, вам необходимо выполнить следующие шаги:

  • создайте учетную запись или используйте существующую.
  • создать приложение (помните про HEROKU_APP_NAME)

  • укажите переменные среды на вкладке Настройки вашего приложения.

Для развертывания в Heroku я предпочитаю Heroku Container Registry. Таким образом, вам необходимо установить и запустить Докер.

Руководство по Docker можно найти здесь.

Ссылки для установки:

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

Это образец Dockerfile для создания образа и его отправки в Реестр контейнеров Heroku.

Перейдите в каталог, в который вы поместили bot.py, Dockerfile, и выполните следующие шаги:

  • Загрузите Heroku CLI здесь
  • Войти

heroku container:login

  • Создайте и разместите изображение

heroku container:push --app <HEROKU_APP_NAME> web

  • Создать новую версию

heroku container:release --app <HEROKU_APP_NAME> web

  • Посмотреть журналы

heroku logs --tail --app <HEROKU_APP_NAME>

Через некоторое время вы сможете увидеть журналы своего бота.

И да, это могло быть абсолютно БЕСПЛАТНО.

Наконец-то

Итак, в этом руководстве мы создали простой Telegram Bot с использованием Python и развернули его на Heroku с помощью Реестр контейнеров Heroku и Docker.

P.S. Бот уже запущен, вы можете проверить его здесь.

У меня лично только одна проблема с бесплатным планом на Heroku. Ваше приложение отключается после 30 минут бездействия. Это приводит к тому, что состояние, в котором находился ваш бот, не будет сохранено, и попытка ответить на старое сообщение ни к чему не приведет.

Есть 2 возможных решения этой проблемы:

  • Используйте план следующего уровня на Heroku (требуется $)
  • Используйте настойчивость в python-telegram-bot. Сейчас он находится в разработке, но, думаю, скоро будет выпущен.


Спасибо за внимание к теме, смело оставляйте свои вопросы в комментариях для обсуждения.