Feedly APIメモ

More than 3 years have passed since last update.

多分現在主流のRSSリーダーであるFeedlyが少し前にようやくAPIを公開してくれたので、オレオレリーダーを作る為の下調べをしてみた。最初戸惑ったが色々API叩いてるうちに大体わかってきたのでメモる。

APIドキュメント: http://developer.feedly.com/v3/


IDの種類と形式


  • userId - user/:userId

  • feedId - feed/:feedUri

  • categoryId - :userId/category/:categoryName


    • 特殊カテゴリ: global.all, global.uncategorized



  • tagId - :userId/tag/:tagName


    • 特殊タグ: global.saved




認証手順


  • 普通のOAuth2.0だが現在はredirect_uriが制限されているためサイト間認証は使えない。


  • http://localhosturn:ietf:wg:oauth:2.0:oobは許可されてるのでローカルアプリで使う分にはとりあえず問題ない。

  • OAuthのプロセス中に出てくるclient_idだのclient_secretだのは全部Sandbox用の固定値を使えばとりあえず自分のアクセストークンを取る分には問題ない。


やってみる



  1. https://cloud.feedly.com/v3/auth/auth?client_id=feedly&redirect_uri=http://localhost&scope=https://cloud.feedly.com/subscriptions&response_type=code&provider=google&migrate=false
    をブラウザで開く。(パラメータは全部固定でOK)

  2. 認証後 http://localhost/?code=XXX&state= に飛ばされるのでアドレスバーから XXX の部分をコピーする。

  3. https://cloud.feedly.com/v3/auth/tokenclient_id=feedly&client_secret=0XP4XQ07VVMDWBKUHTJM4WUQ&grant_type=authorization_code&redirect_uri=http%3A%2F%2Fwww.feedly.com%2Ffeedly.html&code=XXX の最後のXXX部分を先ほど取得したcodeの値で置き換えたものをPOSTする。こんな感じ>$ curl -s -d 'client_id=feedly&client_secret=0XP4XQ07VVMDWBKUHTJM4WUQ&grant_type=authorization_code&redirect_uri=http%3A%2F%2Fwww.feedly.com%2Ffeedly.html&code=XXX' https://cloud.feedly.com/v3/auth/token


  4. おなじみのaccess_tokenとrefresh_tokenがとれるので以降のAPIリクエストにはここで取得したaccess_fokenの値をヘッダに付けて行うようにする。


  5. 使用例はこんな感じ>$ curl -s -H 'Authorization: Bearer ACCESS_TOKEN' https://cloud.feedly.com/v3/profile (ACCESS_TOKENには3で取得したaccess_tokenの値で置き換え)



Profile


  • ユーザプロファイルを取得する

https://cloud.feedly.com/v3/profile

{

"fullName": "Yoshiaki Kawazu",
"locale": "ja",
"picture": "https://lh3.googleusercontent.com/-ECJgMVZ8twg/AAAAAAAAAAI/AAAAAAAAAVM/vdZM4-BFTMs/photo.jpg",
"gender": "male",
"email": "kawazzz@gmail.com",
"google": "107778016735353586604",
"givenName": "Yoshiaki",
"familyName": "Kawazu",
"client": "feedly",
"id": "43d020e7-87a7-4e7f-a8e9-cacb54acd1b5",
"wave": "2013.11",
"windowsLiveConnected": false,
"wordPressConnected": false,
"facebookConnected": false,
"reader": "01581900768824391990",
"evernoteConnected": false,
"pocketConnected": false,
"twitterConnected": false
}


Markers


markers/counts


  • フィードの未読数が取得できる

  • 登録してるfeedが全て取得できるっぽい

  • フィードカテゴリやALLなどの特殊なidのやつも返ってくる

https://cloud.feedly.com/v3/markers/counts

{

"unreadcounts": [
{
"updated": 1394598427423,
"count": 18,
"id": "feed/http://feedproxy.google.com/hatena/b/hotentry"
},
{
"updated": 1394137265230,
"count": 0,
"id": "feed/http://aws.amazon.com/rss/whats-new.rss"
},
{
"updated": 1394599287257,
"count": 24,
"id": "user/43d020e7-87a7-4e7f-a8e9-cacb54acd1b5/category/global.all"
},
{
"updated": 1394599287257,
"count": 0,
"id": "user/43d020e7-87a7-4e7f-a8e9-cacb54acd1b5/category/知り合い"
},
{
"updated": 1394582230100,
"count": 0,
"id": "user/43d020e7-87a7-4e7f-a8e9-cacb54acd1b5/category/エロ"
},
{
"updated": 1394599287257,
"count": 24,
"id": "user/43d020e7-87a7-4e7f-a8e9-cacb54acd1b5/category/global.uncategorized"
}
]
}


Stream


streams/ids


  • ストリームIDにぶら下がったエントリのID一覧を取得する。

  • 取得済みエントリIDはキャッシュしておき新着チェックに使うのが目的のAPIと思われ。


    • コンテンツまで一発で取得したい場合はstreams/contentsを使えば良い。

    • エントリIDからコンテンツを取得するにはentries/:entryIdもしくはentries/.mgetを使う。



  • streamIdに指定できるのはcategoryId feedId tagIdのどれか。


  • streams/:streamId/idsというURLも使えるとドキュメントにあったがクエリで渡しても良い。



    • :streamIdの部分に埋める場合は必ず、ID中の/も含めてURLエンコードしておく必要がある。



https://cloud.feedly.com/v3/streams/ids?streamId=user/43d020e7-87a7-4e7f-a8e9-cacb54acd1b5/category/global.all&count=5

または

https://cloud.feedly.com/v3/streams/user%2F43d020e7-87a7-4e7f-a8e9-cacb54acd1b5%2Fcategory%2Fglobal.all/ids?count=5

{

"ids": [
"vd6/vZ0gPFJR0iUi25Q38MITxKq1RRhf/pxYrAJpSMQ=_144b479e861:7f050e:5f76ba1",
"RkLxQmvOp/nc7DIgnc7qmGmho0aOcNwtk5qewRZKloo=_144b47765db:78700b:57158c7e",
"SzCknK5yCfKi0NrRCLzY3clkPWypMPSgdsVAzzPiIEk=_144b472c945:1f479:3a1395db",
"gHDibUzBXqLZr4i7DfbTJIWTMbq4x72ysmvnyHLsh54=_144b46fc344:768b12:57158c7e",
"gHDibUzBXqLZr4i7DfbTJIWTMbq4x72ysmvnyHLsh54=_144b46fc344:768b11:57158c7e"
],
"continuation": "144b46fc344:768b11:57158c7e"
}


streams/contents


  • ストリームIDにぶら下がったエントリのコンテンツ一覧を取得する。

  • streamIdに指定できるのはcategoryId feedId tagIdのどれか。


  • streams/:streamId/contentsというURLも使えるとドキュメントにあったがクエリで渡しても良い。



    • :streamIdの部分に埋める場合は必ず、ID中の/も含めてURLエンコードしておく必要がある。



https://cloud.feedly.com/v3/streams/contents?streamId=user/43d020e7-87a7-4e7f-a8e9-cacb54acd1b5/category/global.all&count=2

または

https://cloud.feedly.com/v3/streams/user%2F43d020e7-87a7-4e7f-a8e9-cacb54acd1b5%2Fcategory%2Fglobal.all/contents?count=2

{

"items": [
{
"engagementRate": 0.36,
"engagement": 5,
"crawled": 1394598626006,
"author": "jniino",
"summary": {
"direction": "ltr",
"content": "光ネットワークや無線ネットワーク、パケット通信など種類の異なる複数のネットワーク..."
},
"content": {
"direction": "ltr",
"content": "光ネットワークや無線ネットワーク、パケット通信など種類の異なる複数のネットワークの情報を統一的に定義し、上位レイヤから簡単に扱えるようにしたSoftware-Defined Networkingの技術を、NTT、NTTコム、富士通、日立、NECが共同で発表しました。 これにより通信事業者などが広域にわたる複数のネットワークを柔軟に組み合わせて仮想ネットワークを構築しつつ、全体の状況を把握したり、各レイヤのネットワーク装置を連係させることで、要求に応じたネットワークの設計、構築……"
},
"id": "/4r8BU2nbsgJrgfRKK3amXnaOxpprjCJvWjoCKjAPwY=_144b48e42d6:852591:5f76ba1",
"originId": "tag:www.publickey1.jp,2014://2.2804",
"keywords": [
"blog",
"Software-Defined Network",
"ネットワーク"
],
"fingerprint": "9703a9db",
"alternate": [
{
"type": "text/html",
"href": "http://www.publickey1.jp/blog/14/software-defined_networkingnttnttnec.html"
}
],
"title": "Software-Defined Networkingで広域ネットワークを総合的に扱う基本技術を確立。NTT、NTTコム、富士通、日立、NECが共同で発表",
"updated": 1394597056000,
"published": 1394596984000,
"origin": {
"streamId": "feed/http://www.publickey1.jp/atom.xml",
"title": "Publickey",
"htmlUrl": "http://www.publickey1.jp/"
},
"sid": "+d0QLpjFyPQ0+bv2Zs0tZe8M5+yaZXD0xyM5xDZrw6I=",
"visual": {
"url": "none"
},
"unread": true
},
{
"unread": true,
"visual": {
"url": "none"
},
"origin": {
"streamId": "feed/http://kernel.org/kdist/rss.xml",
"title": "Latest Linux Kernel Versions",
"htmlUrl": "http://www.kernel.org"
},
"fingerprint": "1870aafa",
"originId": "kernel.org,linux-next,next-20140311,2014-03-12",
"id": "3n4rP10OBRjEEdn8ddzpt3a6rmsfO/6fqgXkJR2bJ5s=_144b48dda3b:850d01:5f76ba1",
"summary": {
"direction": "ltr",
"content": "<table>\n<tr><th align=\"right\">Version:</th><td><strong>next-20140311</strong> (linux-next)</td></tr>\n<tr><th align=\"right\">Released:</th><td>2014-03-12</td></tr>\n</table>"
},
"crawled": 1394598599227,
"alternate": [
{
"type": "text/html",
"href": "http://www.kernel.org/"
}
],
"title": "next-20140311: linux-next",
"published": 1394595471000
},
],
"continuation": "144b48b3b1f:8441c8:5f76ba1",
"updated": 1394598626006,
"id": "user/43d020e7-87a7-4e7f-a8e9-cacb54acd1b5/category/global.all"
}


まとめ

↑とりあえずこれだけ例を上げとけば普通のRSSリーダは作れそうだな。

最初ALLの内容をどうやって取るのかが分からんくて非常に悩んだ。global.allカテゴリのコンテンツをEntryかStreamから取れば良いまで分かれば後はどうとでもなる。

あとは既読マークとかは Markers に適当にPOSTしとけば良い。