AndreyMelnikov.MyBlog # мой блог: IT-марафон.

Все мои посты

Питонячий Телеграм-Бот, Yandex-API и диплой на Heroku.

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

Итак, попалось мне как-то одно тестовое задание, где требовалось написать телеграм-бота с возможностью обрабатывать запросы пользователя в виде текста с частичным упоминанием географических адресов. В ответ пользователь должен получить полный структурированный адрес географического объекта. На этом задание конечно не исчерпывалось, но остальное я опишу возможно в другой раз :)

Чтобы написать бота, я использовал питонячую библиотеку python-telegram-bot. Там все достаточно понятно. Есть официальная документация и масса примеров в сети. Если коротко описать процесс создания самого бота, то для этого необходимо:

  • Создать и зарегистрировать своего бота.
    Для этого в сервисе телеграм необходимо отправить Боту-Отцу (@BotFather) команду /newbot.
    Дать боту имя (name) и имя пользователя (username).
    В ответ Папа-Бот вышлет уникальный API-ключ (TOKEN) для вашего бота. Данный ключ является идентификатором для доступа и управления ботом. Его нужно сохранить и держать в тайне, иначе бота могут угнать! (Не размещать в коде в публичном доступе на открытых ресурсах, например).

  • Собственно, написать код (логику работы нашего бота), используя любую подходящую библиотечку для телеграм:) В коде мы используем полученный ранее API ключ, для взаимодействия с сервером телеграм.
    Структура каталога нашего бота в общем случае должна содержать следующие файлы: __init.py__ - необходим, чтобы Python рассматривал каталог, как содержащий пакеты для корректного импорта.
    main.py – сам код (логика) бота.
    config.py – указываем наши токены, которые потом импортируются в mian.py.
    Вот так, если упрощенно представить на схеме, все и происходит:

  • Запустить главный файл main.py на исполнение, и писать запросы нашему боту в телеграм-сервисе.

Создав бота, пришло время дать ему дополнительный функционал. Поскольку цель состоит в том, чтобы бот взаимодействовал с API геокодера, отвечая на запросы пользователя полным адресом географического объекта. Для данной цели подходит API от Yandex. Для бесплатного использования необходимо зарегистрироваться. При регистрации указать некоммерческое использование и после этого нам будет доступно 25000 запросов к API в сутки.
В ответ мы получим также API ключ, который необходимо использовать в коде бота для взаимодействия с Yandex геокодером.
Yandex геокодер использует прямое и обратное геокодирование. То есть, умеет отвечать полным адресом на текстовый запрос или координаты, и наоборот - отправлять координаты по указанному адресу. В коде бота достаточно описать функцию обработчик для запросов пользователя, которая будет формировать запрос, затем парсить ответ от Yandex и выводить ответ пользователю в телеграм-клиент. На официальной странице API Yandex геокодера все достаточно понятно описано.

И вот когда бот написан и отлажен, пришло время дать ему онлайн-доступность. Потому, что до сих пор он работал только при условии запущенного main.py файла на локальном компьютере с доступом в интернет. Для бесплатного хостинга подобных проектов подходит сервис Heroku и созданный в нем активный аккаунт. Кроме того нам понадобится Heroku Command Line Interface (CLI) , который можно скачать тут, а также Git.

Добавим в директорию нашего бота еще пару файлов Procfile и requirements.txt:

Procfile – текстовый, но без расширения. Для этого необходимо использовать сохранение через Notepad++ (опция All-typs (.))
Содержание файла:

worker: python main.py

requirements.txt – обычный текстовый.
Содержание файла:

appdirs==1.4.3
certifi==2018.1.18
Cython==0.23
Django==1.10.6
docutils==0.13.1
packaging==16.8
pipenv==11.8.0
psutil==5.0.1
pyowm==2.8.0
Pygments==2.2.0
pyparsing==2.2.0
pyTelegramBotAPI==3.6.1
python-telegram-bot==13.0.0
requests==2.13.0
six==1.10.0
virtualenv==15.1.0
virtualenv-clone==0.3.0

Это необходимые компоненты для виртуального окружения на сервере. Конечно, всего этого нам сейчас и не нужно, но пусть будет:) Главное, чтобы необходимые нам библиотеки и фреймворки были нужной версии. После того, как оба файла добавлены в каталог с ботом, необходимо запушить все на гитхаб в отдельный репозиторий, предварительно удалив из кода API токены (помним про безопасность).
Теперь у нас всё готово для загрузки бота на Heroku.
Вернем токены обратно в наш код и приступим к диплою. Из терминала (командной строки - в моем случае это Git bash):

  • Логинемся.
     $ heroku login
    

    Нажимаем любую клавишу, переходим в браузер, подтверждаем вход.

  • Создаем проект.
    $ heroku create
    

    Имя будет создано автоматически. Можно также это сделать из-под браузера.

  • Клонируем каталог с созданным проектом к себе. В данном каталоге должны быть файлы из нашего репозитория с телеграм-ботом.
    $ heroku git:clone -a hidden-mountain-ххххх
    
  • Переходим в каталог:
    $ cd hidden-mountain-ххххх
    
  • И делаем привычную связку команд для Git: add-commit-push.
    $ git add .
    $ git commit -am "my-deploy"
    $ git push heroku master
    

    После чего несколько минут будут устанавливаться указанные в requirements.txt компонеты. По завершении процесса, будет запущен main.py файл как указано в Procfile. После чего бот должен стать доступным. Если этого не происходит можно сделать команду:

    $ heroku ps:scale worker=1
    

    Для отладки ошибок можно использовать логирование (именно этот режим позволил мне отловить ошибку импорта из каталога, который я удалил. И из-за этого мой бот не запускался удаленно.):

    $ heroku logs
    

Готово! Теперь проверяем бота - он должен работать в удаленном режиме.
Правда тут стоит сделать оговорку. Обычный бесплатный аккаунт на heroku дает вам 550 dyno часов в месяц. При достижении данного лимита, ваше приложение будет автоматически деактивировано. Информацию о текущем состоянии использования часов, можно посмотреть в настройках учетной записи. Нажмите на свой аватар в правом верхнем углу сайта и выберите Account settings, перейдите во вкладку Billing, а затем в раздел Free Dyno Usage.

Назад к списку постов