- PVSM.RU - https://www.pvsm.ru -
Доброго времени суток, уважаемое читатели.
Сегодня пятница, а это значит, что можно отвлечься от серьезных проектов и отдохнуть. Например, прочитав очередную статью для начинающих, посвященную разработке простого twitter-бота на python, уведомляющего о нескольких видах GitHub-активности.
Если вы подозреваете, что ничего нового из этой статьи не узнаете, то можете просто посмотреть код проекта на GitHub [1]. Остальных же приглашаю под кат, чтобы узнать больше про библиотеки для взаимодействия с GitHub API v3 и ознакомиться с процессом написания бота.

Замечу, что на Хабрахабре легко найти руководства по написанию ботов для Twitter ([1] [2], [2] [3], [3] [4], ...) и сложно — по API для GitHub. Это, пожалуй, основная причина появления этой заметки. Кроме того, перед вами всего лишь простой пример использования огромных возможностей, которые нам доступны.
В настоящий момент актуальная версия API — третья (поддержка первых двух была отменена [5] в июне этого года). Для работы с ней посредством python существует как минимум [6] шесть библиотек, которые очень похожи. Я выбирал библиотеку, основываясь на наличии удобной документации и отсутствии большого количества зависимостей. Наиболее приятной показалась github3.py [7].
От Twitter'a требовалось очень немного — нужно было уметь авторизовываться, получать новые упоминания (mentions) и отправлять сообщения. Токен можно было получить вручную (он выдается один раз и не нуждается в обновлении). Поэтому я остановился на библиотеке oauth [8], портированной под третий python.
Предполагалось, что бот будет работать следующим образом:
Структура проекта выглядит следующим образом:

Папка oauth содержит библиотеку для авторизации, в файле twitter.py методы для оправки сообщений и обновления ленты, github.py, по сути, является самим ботом, а в id.dat будет храниться номер последнего обработанного сообщения (на случай каких-то сбоев в работе). Config.py понадобится для хранения ключей и паролей.
Для работы с Twitter API нужно создать свое приложение. Авторизуемся на dev.twitter.com, нажмем «Create an app», заполним форму и создадим приложением. Чтобы отправлять сообщения, нужно включить режим «Read and write» в разделе «Settings». Осталось получить ключи («Create my access token» на вкладке «Details») и можно приступать.
Ссылки на полный код будут в конце статьи, здесь только краткие выдержки.
Сначала научим нашего бота авторизовываться в Twitter, отсылать запросы и сохранять номер последнего сообщения.
HOME_TIMELINE_URL = 'http://api.twitter.com/1/statuses/home_timeline.json'
UPDATE_URL = 'http://api.twitter.com/1/statuses/update.json'
MENTIONS_URL = 'http://api.twitter.com/1/statuses/mentions.json'
FILENAME = 'id.dat' # File with the number of the last solved problem
Для обновления ленты достаточно установить соединение:
def _get_connection(self):
self.connection = http.client.HTTPConnection('twitter.com')
И отправить POST-запрос:
oauth_request = oauth.OAuthRequest.from_consumer_and_token(
self.consumer, token=self.access_token, http_method='POST',
http_url=UPDATE_URL, parameters=params)
oauth_request.sign_request(self.signature_method, self.consumer,
self.access_token)
self.connection.request(oauth_request.http_method, UPDATE_URL,
headers=oauth_request.to_header(),
body=self._to_query_string(params))
А для получения упоминания — GET-запрос:
oauth_request =
oauth.OAuthRequest.from_consumer_and_token(self.consumer,
token=self.access_token, http_method='GET',
http_url=MENTIONS_URL, parameters=params)
oauth_request.sign_request(self.signature_method,
self.consumer, self.access_token)
self.connection.request(oauth_request.http_method,
MENTIONS_URL + '?' + self._to_query_string(params),
headers=oauth_request.to_header())
Для сохранения информации можно воспользоваться библиотекой pickle:
def _save(self, data):
path = os.path.dirname(__file__)
path = os.path.join(path, FILENAME)
log_file = open(path, 'wb')
pickle.dump(data, log_file)
log_file.close()
В принципе, для нашей задачи этого будет достаточно. Теперь создадим файл config.py, в котором будем хранить полученные нами ключи для Twitter API и логин/пароль пользователя GitHub (на случай, если нашему боту это понадобится):
import twitter
secret = twitter.SecretKeys('consumer_key',
'consumer_secret',
'auth_key',
'auth_secret')
LOGIN = 'github_login'
PASSWORD = 'github_password'
И допишем оболочку для их хранения:
class SecretKeys:
keys = {}
def __init__(self, consumer_key, consumer_secret, auth_key, auth_secret):
self.keys = {'consumer_key': consumer_key,
'consumer_secret': consumer_secret,
'auth_key': auth_key,
'auth_secret': auth_secret}
От самого бота требуется немного больше. Он будет загружать список новых сообщений, формировать из них список задач, выполнять задачи и уведомлять об их результатах пользователей.
Для начала нам понадобятся следующие библиотеки:
from github3 import login
import twitter # twitter.py
import time
import os
import pickle
from config import secret, LOGIN, PASSWORD
Номер последнего сообщения будем брать из файла:
def get_data(filename):
with open(filename, 'rb') as file:
return pickle.load(file)
Список новых задач получим от twitter.py:
list_of_problems = api.get_new_mentions(idx)
И будем идти по нему, формируя новые команды:
for problem in list_of_problems:
problem = form_problem(problem)
Функция form_problem() будет искать, что именно хотел от бота пользователь и формировать словарь с параметрами:
if command in commands:
command = commands.index(command)
user = problem['user']['screen_name']
return {'command': command, 'user': user, 'params': params}
Затем нужно будет выполнить каждую из задач:
def solve(problem, gh):
functions = {0: get_last_commit,
1: get_list_of_contributors,
2: get_count_of_open_issues,
3: get_count_of_commits,
4: get_count_of_repos,
5: subscribe_on_commits,
6: help,
7: unsubscribe_from_commits}
return functions[problem['command']](gh, problem['params'],
problem['user'])
Отправить пользователю результаты:
api.post_update('@%s %s.' % (problem['user'], result))
И сделать небольшую паузу:
time.sleep(10)
В принципе, этого достаточно для первой версии. Сами функции полностью основаны на GitHub API и документации к github3.py. Например, вывод последнего коммита в каком-либо репозитории можно реализовать так:
def get_last_commit(gh, params, user):
pattern = 'Last commit in "%s" was "%s" by %s'
repository = gh.repository(params[0], params[1])
last_commit = repository.list_commits()[0]
return pattern % (repository.name, last_commit.commit.message,
last_commit.commit.author.name)
С точки зрения GitHub API [9], это GET-запрос (/repos/:user/:repo/commits), в ответ на который сервер вернет список всех коммитов в репозитории с довольно обширной информацией:

Пожалуй, это все. Для запуска бот нужно просто запустить файл github.py, предварительно заполнив config.py. В настоящий момент GitToTweet поддерживает следующие команды:
get last commit, <user>, <repository>get list of contributors, <user>, <repository>get count of open issues, <user>, <repository>get count of commits, <user>, <repository>get count of repos, <user>, <repository>subscribe me, <user>, <repository>unsubscribe me, <user>, <repository>helpА выглядит это примерно так:
@GitToTweet get last commit, django, django
@%username% The last commit in «django» was «Fixed #18847 — Updated for media examples to use static.example.com. Thanks Jamie Curle…
Исходный код проекта на GitHub:
github.com/valzevul/GitToTweet [1]
Документация по GitHub API v3:
developer.github.com/ [10]
Документация по Twitter API:
dev.twitter.com/docs [11]
Пример работы бота в Twitter можно посмотреть здесь:
twitter.com/GitToTweet [12]
Спасибо за внимание.
Автор: valzevul
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/13724
Ссылки в тексте:
[1] код проекта на GitHub: http://github.com/valzevul/GitToTweet
[2] [1]: http://habrahabr.ru/post/127237/
[3] [2]: http://habrahabr.ru/post/128422/
[4] [3]: http://habrahabr.ru/post/139900/
[5] была отменена: http://developer.github.com/#changes
[6] как минимум: http://developer.github.com/v3/libraries/
[7] github3.py: http://github3py.readthedocs.org/en/latest/index.html
[8] oauth: http://code.google.com/p/oauth/
[9] GitHub API: http://developer.github.com/v3/repos/commits/
[10] developer.github.com/: http://developer.github.com/
[11] dev.twitter.com/docs: http://dev.twitter.com/docs
[12] twitter.com/GitToTweet: http://twitter.com/GitToTweet
Нажмите здесь для печати.