Данная статья является логическим продолжением истории о создании бота для Telegram, там мы разработали простого, но бесполезного пока, Telegram-бота и научили его разговаривать. Пришло время добавить ему более интересных функций.
Мы научимся получать уведомления от сервиса GitHub, взаимодействовать с GitHub API и Telegram API, напишем бота для передачи всех оповещений о новых коммитах GitHub репозитория в Telegram чат. Как показывает опыт работы нашей команды, это позволяет получать максимально оперативные сведения о работе над проектом в Telegram мессенджере и структурировать процесс разработки проектов. Начнем с этапа получения и обработки оповещений от GitHub.
Для того, чтобы получать все обновления от GitHub, нам понадобятся две вещи: настроить GitHub таким образом, чтобы он посылал вашему серверу информацию об обновлениях, а также написать и запустить серверное приложение, который эту информацию будет получать и обрабатывать.
Что такое API
API (Application Program Interface) - это интерфейс программирования приложений, специальный набор инструкций для взаимодействия сторонних разработчиков с вашим ресурсом. Сегодня многие крупные проекты имеют свои API, предоставляющие удобный механизм создания внешних приложений для сторонних разработчиков.
GitHub API
С GitHub API можно взаимодействовать посредством GET, POST запросов, даже через браузер. Для примера вы можете запросить информацию о пользователе. Подставьте вместо n0str свой GitHub-логин и пройдите по данному адресу в браузере:
https://api.github.com/users/n0str
GitHub ответит вам в формате JSON, который представляет из себя достаточно удобный способ представления информации в виде списков. JSON, ввиду своей универсальности, получил широкое распостранение, а его поддержка реализована в виде библиотек практически для каждого языка программирования. В ответе вы увидите свой логин, ссылки на аватарку, информацию профиля, количество репозиториев и прочие данные.
{
"login":"n0str",
"id":988885,
"avatar_url":"https://avatars.githubusercontent.com/u/988885?v=3",
"gravatar_id":"",
"url":"https://api.github.com/users/n0str",
"html_url":"https://github.com/n0str",
"type":"User",
"site_admin":false,
"name":"Menshikov Alexander",
"public_repos":9,
"public_gists":14,
"followers":12,
"following":20,
"created_at":"2011-08-18T14:54:56Z",
"updated_at":"2015-12-23T17:54:08Z"
}
Мы не будем касаться вопросов работы с git; если вы не знаете как это делать, можете почитать заметки об этом:
Настраиваем прокси
Чтобы получать сообщения от GitHub, нужно сконфигурировать свой собственный сервер. Вы можете прочесть о настройке прокси в статье Простой веб-сервер с использованием Python и Flask.
В качестве прокси, будем использовать бесплатную программу ngrok. Ее главная задача - держать постоянное соединение и передавать вам всю полученную от сервера GitHub информацию. Запустите ее командой, передав в качестве параметра любой свободный порт:
./ngrok http 4567
Полученный ответ будет содержать несколько строк, среди которых вы найдете нечто подобное:
Forwarding http://ddabef45.ngrok.io -> 127.0.0.1:4567
Адрес http://ddabef45.ngrok.io нам понадобится позже.
Создаем локальный веб-сервер
Осталось поднять веб-сервер, который будет получать всю информацию по порту 4567. Воспользуемся кодом из предыдущей статьи о создании веб-сервера на Python Flask, слегка его модифицировав:
from flask import Flask, request, abort
from json import loads
app = Flask(__name__)
@app.route("/", methods=['POST'])
def index():
try:
payload = loads(request.data)
print payload["repository"]["name"]
except:
abort(400)
return "Ok!"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=4567)
Данный код проверяет, действительно ли вам передали POST запрос. Содержимое запроса можно сконвертировать в обычный массив с помощью библиотеки JSON и ее метода loads. В результате, в переменной payload окажется массив с информацией, а на экран будет выведено название репозитория.
GitHub Webhooks
Webhooks - это технология, работающая следующим образом: вы выбираете информация о каких событиях вам понадобятся, вводите адрес вашего веб-сервера и получаете от Github'а все сообщения в реальном времени. Для того, чтобы настроить Webhooks, перейдите в ваш репозиторий, выберите вкладку Settings и переключитесь на экран Webhooks & services.
После нажатия на кнопку Add webhook, потребуется ввести адрес своего сервера, который мы получили ранее (http://ddabef45.ngrok.io), в поле Payload URL и выбрать тип данных (JSON или urlencoded). В данной статье будем придерживаться формата JSON.
Проверка работы
Для проверки запустите сервер командой:
python server.py
Если все правильно сделано, осталось лишь выполнить команду git commit, затем команду git push и посмотреть результаты. В терминале, в котором вы запускали Flask сервер, отобразится имя репозитория (codex) и появится строка, отображающая POST запрос с HTTP кодом успеха (200).
Чтобы при экспериментировании с приложением вам не приходилось постоянно совершать одни и те же действия над репозиторием, можно воспользоваться встроенной в GitHub функцией повторной отправки сообщения по Payload URL. На странице Webhooks & Services кликните по соответствующему Webhook.
Откроется окно с информацией о вашем Webhook и его оповещениям. Кликнув по конкретному оповещению, вы откроете его содержание, среди которого можно видеть кнопку Redeliver. Клик по ней приводит к посылке повторного оповещения вашему веб-серверу.
Извлекаем полезные данные
Внесем немного изменений в код, чтобы вывести информацию о пользователе, который выполнил push запрос, количестве коммитов в запросе и название ветки репозитория, куда они были загружены. Код примет следующий вид:
from flask import Flask, request, abort
from json import loads
app = Flask(__name__)
@app.route("/", methods=['POST'])
def index():
try:
payload = loads(request.data)
# This code is new if request.headers.get('X-GitHub-Event') == "push":
print "%s push %d commits to %s" \
% (payload["pusher"]["name"], len(payload["commits"]), payload["ref"])
# -->
except:
abort(400)
return "Ok!"
if __name__ == "__main__":
# This code is new app.debug = True
# -->
app.run(host="0.0.0.0", port=4567)
А в терминале вы сможете увидеть строку приблизительно следующего содержания:
n0str push 1 commits to refs/heads/master
Также, вы могли заметить в коде строчку:
app.debug = True
Она позволяет вам получить дополнительную информацию об ошибках, в случае, если код написан неверно, или некоторые элементы массива оказались недоступны.
В следующей статье вы научите программу анализировать полученные от GitHub данные и посылать уведомления в ваш Telegram-чат.