QiitaのユーザーフィードをRSS化するサービスを公開しました。

![Screen Shot 2017-11-04 at 18.30.58.png](https://qiita-image-store.s3.amazonaws.com/0/75633/1207d74a-4663-6e00-263e-610ea8613aa8.png)

Qiita Feed Gen is now available!
https://qiita-feed-gen.potato4d.me/

みなさま普段の技術系の情報収集には何を用いているでしょうか。
私は界隈人のTwitterと、大量にフォローしているGitHubのPrivateフィードのRSSを主に利用しています。

特にGitHubのフィードについては、プッシュ通知のSaaSであるPush7を利用し、followingのstar通知などを携帯から閲覧できるようにしており、情報収集に非常に役立てています。

そんな中、毎日一度は追っている、QiitaのユーザーフィードもRSSで追跡したいというモチベーションがでました。
しかしながら、現状はQiitaはユーザーフィードのRSSを(公式には)提供していないようでしたので、Qiita APIを利用してRSSを生成するサービスを、 Node.js にて開発してみましたので、ご紹介します。

## ToC

- レポジトリのご紹介
- Qiita Feed Genの使い方
- 技術仕様及びナレッジ

## レポジトリのご紹介

本サービスのソースコードは全てGitHubにて公開されています。
シンプルなNodeアプリケーションやQiita APIをaxiosで叩くサンプルとしてよろしければご活用ください。

https://github.com/potato4d/qiita-feed-gen

## Qiita Feed Genの使い方

### Personal Access Tokenの発行

Qiita Feed Genでは、利用のためにPersonal Access Tokenを必要とします。
これは、あなたのQiitaアカウントに紐づく、一意のトークンであり、本サービスにおいてはQiita(without Qiita:Team)のRead権限のみを許可するだけで利用することができます。

また、Personal Access Tokenは、URLのクエリ文字列上およびキャッシュストア内以外に保持、利用することはありません。

アクセストークンは、 https://qiita.com/settings/applications より「個人用アクセストークン」で発行が可能です。

![Screen Shot 2017-11-04 at 18.34.29.png](https://qiita-image-store.s3.amazonaws.com/0/75633/8259ae4b-0ec0-b308-ba96-8762abaec8e4.png)

一度作成した後、ページを離れると、二度と閲覧ができなくなりますので、忘れずにクリップボードにコピーしておきましょう。

### Qiita Feed Genでの登録

次に、アクセストークンを保持した状態で https://qiita-feed-gen.potato4d.me にアクセスし、ユーザーIDのあなたのIDを、アクセストークンに先程コピーしたトークンを貼り付け、「フィードを生成する」をクリックすることで生成が完了します。

この処理は、ただ単に 
https://qiita-feed-gen.potato4d.me/feed/:user_id.atom?token=:token 形式のURLのリンクを生成しているのみであるため、URLをそのまま入力してアクセスすることでも発行が可能です。

![Screen Shot 2017-11-04 at 20.50.46.png](https://qiita-image-store.s3.amazonaws.com/0/75633/7fa986cc-3f6d-7cbf-51b0-ee5d9deaff74.png)

発行が完了すると、このような結果となります。

### RSSの購読

後は生成したフィードのURLを任意のRSSリーダーに食わせることによってフィードの購読が可能となります。

## 技術仕様及びナレッジ

最後に、Qiita Feed Genの開発にあたって得られた知見を幾つかご紹介します。

### Qiita APIについて

Qiitaは、公式にAPIを提供しており、以下のドキュメントを参考に自由に叩くことが可能となっております。
https://qiita.com/api/v2/docs

APIのリクエスト制限については、デフォルトでは1時間ごとに一つのIPで60リクエストまで。トークンを利用することで、一つのユーザーごとで1時間辺り1,000リクエストまで許容しています。
今回の場合、60では不足することは間違いないですし、1,000リクエストであっても一人のトークンを利用していると容易に突破すると推測されるため、利用者に発行してもらう形としました。

### Qiitaフィードの仕様

Qiitaのフィードは、基本的に自分がフォローしているものについての情報が流れます。
このフィードに流れる情報は公式ブログに明示されており、以下の情報が流れる仕様となっています。

http://blog.qiita.com/post/25425802941/feed-feature

- タグ
    - タグに紐づく新規投稿
- ユーザー
    - 新規投稿
    - ユーザーのフォロー
    - タグのフォロー
    - 記事に対してのいいね
    - 記事に対してのコメント

と、このように非常に多くの情報を参照しますが、Qiita APIにおいては、これらは全て別のエンドポイントでそれぞれのリソースが割り当てられているので、結合して一つのフィードを作成する必要があります。

とはいえ、全てを追跡した場合、膨大なリクエスト数となり、今回のQiita Feed Genでは、ひとまずは主に閲覧したいであろう「タグへの新規投稿」に限定して取得を行うこととしました。
サーバーの負荷、及びAPIのリクエスト制限の様子を見ながら、可能であれば「ユーザーの新規投稿」をサポートする予定です。

サポート範囲は、後述するRSS生成時のリクエスト数にダイレクトに関わってきます。

### HTTPリクエストの並列化とAPI制限とキャッシュについて

今回、RSSのフィードを生成するにあたって、一番ネックとなったのはやはりレスポンス速度とAPI制限というところでした。
個人で少し叩く程度であれば問題ありませんが、RSSフィードを生成するとなるとやはり不安要素はあります。

HTTPリクエストが直列であると、RSSの生成に非常に時間がかかるため、全てのリクエストは今回axiosをPromise.allでラップする形で並列化しています。
Qiita APIがhttp/1.1ですので、ある程度限界はあるかもしれませんが、最低限並列で処理を行っています。

また、一度に相当数のリクエストを送信する可能性があるため、サーバー側でのキャッシュを行うことを検討しています。
RSSとしての情報の整合性などを取るために、現在クローラの平均的な頻度などを調査しているところではありますが、キャッシュなしではAPI制限が非常に重くなっております。

この初期バージョンでは実装していない「フォローユーザーの新規投稿」ですが、基本的にフォローしているユーザーの数だけリクエスト数が増えることとなります。また、記事へのいいねやコメントも実装するとなると、フォローユーザー*機能数のリクエストが必要となります。

例えば、タグ新規投稿・ユーザーの新規投稿・ユーザーのいいね・ユーザーのコメントを、20タグをフォローしていてかつ30ユーザーをフォローしている状態で取得する。
という場合、一回のクロールにてAPI制限1,000のうち、自分のフォローユーザー及びタグの取得で2, タグの投稿一覧で20, フォローユーザーそれぞれ3回づつで90。と、計112リクエストが必要となります。
少し調査をしてみたところ、60~70のユーザーをフォローしている人もざらであるため、一度300ほどのリクエストが送られる可能性もあります。

これは勿論Qiitaサービスへのリクエスト数としても非常に多くなり健全ではないですし、そこまでリアルタイム性が必要なフィードでもないはずですので、これを25分間のExpireとして設定することを考えています。

そうすると、複数のRSSリーダーの利用時、大量のユーザーフォロー時にも耐えうる構成となるため、これが実現でき次第ユーザーの新規投稿のサポートを行う予定です。

あるいは、現状でもpublic APIではないようですが、トップページからアクセスが行われている tracks APIはありますので、それらが解放された時はそちらに切り替える予定です。

## おわりに

Qiitaを利用した情報収集の手法としてRSSを用いるという一つの提案として、また、開発にあたってQiita APIやQiitaフィード周りの仕様についてご紹介する機会として本記事を書きましたが、最終的にはサービスは使ってもらってナンボではありますので、よろしければご利用いただけると非常にありがたいです。