Feedly APIメモ

  • 152
    いいね
  • 2
    コメント
この記事は最終更新日から1年以上が経過しています。

多分現在主流の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しとけば良い。