Некоторое время назад я запустил бота для постинга в Evernote через джаббер и пообещал открыть исходный код, чтобы показать примеры работы с Evernote API и OAuth.

Код — в конце статьи, а для начала я расскажу о некоторых особенностях работы с Evernote.

Evernote


Для того, чтобы использовать Evernote API, нужно отправить заявку в службу поддержки и получить consumer key. Уже здесь начинаются неожиданности — нигде об этом не написано, но ключи бывают двух видов: для клиентских приложений (с доступом по логину и паролю) и для доступа через веб-авторизацию — OAuth. В письме обязательно уточните, что именно вам нужно.

Важно: все параметры OAuth-доступа (права, срок жизни токена) задаются на стороне сервера, поэтому о них тоже лучше написать сразу. Максимальный срок жизни — 365 дней, бессрочно токены (увы) не выдаются. Права — стандартный набор create/read/update/delete плюс просмотр информации о пользователе и ее изменение.

Через некоторое время придет ответ с парой ключей (consumer key и consumer secret) для доступа на сервер-«песочницу» — sandbox.evernote.com. После того, как приложение будет готово, нужно отправить еще один запрос в саппорт — чтобы ключи работали для основного сервера, — а пока можно свободно пользоваться «песочницей» без боязни что-то сломать.

OAuth


Следующая неожиданность, с которой я столкнулся — отсутствие примеров OAuth-авторизации в документации по API. Безусловно, документация есть и на oauth.net, и на других сервисах, которые используют OAuth (твиттер, например), но без привязки к конкретному сервису разобраться достаточно тяжело.

Итак, схема авторизации:

1. Запрос request token приложением
Полный url запроса выглядит так:
www.evernote.com/oauth?oauth_consumer_key=<consumer key>&oauth_signature=<consumer secret>%26&oauth_signature_method=plaintext
По этой ссылке приложению отдается токен, используемый для генерации ссылки, которую нужно будет отдать пользователю для авторизации

2. Авторизация пользователя
Пользователь должен пройти по сгенерированной ссылке и подтвердить, что он дает Вашему приложению доступ к своему аккаунту.
Ссылка, выдаваемая пользователю:
www.evernote.com/OAuth.action?oauth_callback=<callback url>&oauth_token=<полученный на первом этапе request token>
Очередная неожиданность: параметр oauth_callback (url, куда пользователь будет перенаправлен после подтверждения доступа) в спецификациях oauth указан как необязательный, но он обязателен при запросе к Evernote. Впрочем, вполне достаточно подставить туда слеш для перенаправления на главную страницу EN.

3. Запрос authorization token приложением
После того, как пользователь подтвердил доступ, приложение запрашивает постоянный токен, который позже будет и��пользоваться для авторизации:
www.evernote.com/oauth?oauth_consumer_key=<consumer key>&oauth_signature=<consumer secret>%26&oauth_signature_method=plaintext&oauth_token=<полученный на первом этапе request token>

После этого Вы получаете authorization token и указатель для шарда (конкретного сервера Evernote), который понадобится в дальнейшем при работе с API.

В python есть библиотека для работы с OAuth, но я отказался от ее использования: не стал усложнять процесс, который сводится к генерации ссылок и обработке результатов, тем более что обычная схема OAuth выглядит сложнее, чем использованная в Evernote (вот за это разработчикам EN большое спасибо — практически всё лишнее убрали).

Python и библиотеки


Из библиотек, которых нет в стандартной сборке python, для работы бота требуются sqlite3, xmpp-py и, разумеется, Evernote API (который также включает в себя thrift).

Для работы необходим python 2.6 (из-за использования «with» statements) или python 2.5 с импортом with_statements из модуля __future__.

Исходный код


Хабр не дал мне вставить полтысячи строк кода с хайлайтом, поэтому я выложил весь код целиком на snipt.org. Программист из меня не ахти, но зато it works. :) Пользуйтесь, хабралюди!