понедельник, 14 марта 2016 г.

python-telegram-bot и Google App Engine


Захотелось поднять бота Telegram, но сразу в среде не требующей много внимания и не на рабочих серверах. Поднимать для него отдельные виртуальные машины, или искать дополнительный хостинг тоже не очень хотелось. Решил остановиться на облачных ресурсах Heroku, Google App Engine, Amazon и т.д. Программист из меня никакой, поэтому настройка окружения заняла много времени. Остановился на GAE, поскольку на нем хоть что то запустилось сразу. 

В GAE сразу запустился простой бот - спасибо Yukuku за подробную инструкцию. Но сразу же захотелось использовать клавиатурные подсказки, еще какие то фичи, наиболее логичным было использовать https://github.com/python-telegram-bot/python-telegram-bot для разработки бота. И вот тут начались проблемы, поскольку для этого решения требуется множество различных библиотек, которые цепочкой завязаны друг на друга. Мне не помогло решение от S. Hwang - либо описание несколько устарело (там ссылка на видео инструкцию) либо у меня руки не оттуда растут. Собственно у меня получилось запустить простого эхо-бота скопировав все недостающие библиотеки в корень проекта.

Поскольку потратил много времени на решение задачи, опишу здесь примерно процедуру, вдруг еще какому нубу потребуется. Я решил эту задачу неграмотно, но это единственный способ как я смог это сделать.
1. Создание бота
2. Создание и настройка тестового проекта
3. Установка (копирование) всех недостающих библиотек
3.1. Вариант для ленивых
3.2. Полный вариант

1. Создание бота

Процесс создания бота неоднократно описан. Можно пройти до 17-го шага в этом описании или по моему переводу:
  • Обратитесь к боту @botfather https://telegram.me/botfather  с командой /newbot Убедитесь что говорите именно с нужным botfather, а не с пользователем с похожим ником.
  • @botfather ответит Alright, a new bot. How are we going to call it? Please choose a name for your bot.
  • Введите имя которое придумали (yournamebot)
  • @botfather ответит Good. Now let's choose a username for your bot. It must end in `bot`. Like this, for example: TetrisBot or tetris_bot.
  • Введите любое уникальное имя бота. В конце должно присутствовать "bot". (YourNameBot)
  • Done! Congratulations on your new bot. You will find it at telegram.me/YourNameBot. You can now add a description, about section and profile picture for your bot, see /help for a list of commands.  Use this token to access the HTTP API: 201682768:AAE9p_yr7I7Hx_alotofsybols  For a description of the Bot API, see this page: https://core.telegram.org/bots/api
  • Выпишите себе тот API key что получили.

2. Создание и настройка тестового проекта 

  • Желательно чтобы project name и project id совпадали (меньше путаницы)
  • Сразу можно скачать и установить Google App Engine SDK , а можно и не скачивать. Можно скачать PyCharm версию про (для начала триальную).  Одно другому не мешает. Для простоты поднятия тестового бота Вы можете просто скачать все библиотеки в этом архиве

3.1.  Установка из моего архива.

Если Вы решили просто скопировать файлы из архива (предупреждаю - библиотеки часто обновляются, версии в архиве скорее всего устарели, ну и там много лишнего):
  • распакуйте архив.
  • Измените файл app.yaml - application: yourbotname - укажите имя своего проекта в GAE.
  • Измените файл main.py - PasteYourTokenHere и PasteYourGAEProjectNameHere, укажите token полученный от  @botfather и имя проекта в GAE.
  • Запустите Google App Engine SDK
  • Add Existing Application
  • Проект появится в списке проектов
  • Запустите Deploy
  • потребуется авторизация на GAE, и проект должен будет запуститься
  • Заходим по ссылке https://PasteYourGAEProjectNameHere.appspot.com/set_webhook
  • должны получить webhook setup ok.
Можно посмотреть логи чтобы понять что не так (если что то не так) 

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

3.2. Самостоятельная установка.

Вариант которым пришлось воспользоваться мне - чуть более длинный. По идее должен был заработать virtualenv из видеоинструкции, но у меня не заработал.
  • Запускаем Google App Engine SDK
  • Создаем в нем новый проект  New Application с наименованием нашего проекта в GAE. 
В app.yaml нужно дописать в конец:
- name: ssl
  version: "2.7"
Или другую актуальную версию библиотеки с https://cloud.google.com/appengine/docs/python/tools/libraries27

В main.py записать основной код, например:
#!/usr/bin/env python
import sys
import os
sys.path.append(os.path.join(os.path.abspath('.'), 'venv/Lib/site-packages'))
import telegram
from flask import Flask, request
app = Flask(__name__)
global bot
bot = telegram.Bot(token='PasteYourTokenHere')
@app.route('/HOOK', methods=['POST'])
def webhook_handler():
    if request.method == "POST":
        # retrieve the message in JSON and then transform it to Telegram object
        update = telegram.Update.de_json(request.get_json(force=True))
        chat_id = update.message.chat.id
        # Telegram understands UTF-8, so encode text for unicode compatibility
        text = update.message.text.encode('utf-8')
        # repeat the same message back (echo)
        bot.sendMessage(chat_id=chat_id, text=text)
    return 'ok'
@app.route('/set_webhook', methods=['GET', 'POST'])
def set_webhook():
    s = bot.setWebhook('https://PasteYourGAEProjectNameHere.appspot.com/HOOK')
    if s:
        return "webhook setup ok"
    else:
        return "webhook setup failed"
@app.route('/')
def index():
    return '.'

Подправив PasteYourGAEProjectNameHere и PasteYourTokenHere
создать текстовый файл requirements.txt   со следующим содержимым:
Flask>=0.10.1
python-telegram-bot>=2.5
Дальше в терминале перейти в папку с проектом, и установить библиотеки командой
pip install -t lib -r requirements.txt
Вот тут я уверен что я не прав, но ничего поделать не могу. Команда создаст папку lib и установит туда кучу библиотек. 
Если сейчас сделать Deploy в Google App Engine SDK, то в логах запущенного instance мы увидим ImportError: No module named telegram
Я смог с этим справиться только копируя все необходимые библиотеки в корень папки проекта (
А именно папки:
  • werkzeug
  • telegram
  • markupsafe
  • jinja2
  • future
  • flask
  • и файл itsdangerous.py
Теперь после Deploy можно зайти на https://PasteYourGAEProjectNameHere.appspot.com/set_webhook и мы должны увидеть webhook setup ok

Бот должен заработать.