note.com のフォローフィードを作りたい
Google Alert の登録キーワードRSSフィードの応用として、note.com のフォローと同期するフィードを作成したい。note ではクリエーターをフォローすることができるが、自分が記事を読みに行くのはSlackでの通知ありきなので、RSS登録との二重管理が煩雑になっていた。
これを解決するヒントして、はてなブログには「読者になる」で自分が購読リストに入れたユーザー全体でのフィードを生成する機能がある。このフィードさえ購読しておけば、はてなブログの読書登録との同期ができて心地が良い。
note にも同じような機能があれば良いのだけど、見つからなかったので作ることとした。
note.com 非公式APIでクリエーターフォロー一覧を取得
note にはクリエーターごとのRSSフィードが以下の形式で取得できる。
https://note.com/{creator_id}/rss
ユーザーがフォローしているクリエーターIDの一覧が取得できればあとはよしなにフィードを集約すれば実現できそう。フォロークリエータ一覧は note の非公式APIからGET形式で取得できる。
https://note.com/api/v2/creators/{creator_id}/followings?page={page}
フォロー情報はクリエータの公開情報という立て付けなので、特に認証も必要ないようだ。ページごとに取れるフォロークリエーターは12件であり、次のページない場合には data.isLastPage
が true
となるため、そこまで取得する。
あくまで画面表示のために使われているであろうAPIエンドポイントであるため、本来的には利用すべきではないのだろうけれども公式機能がないのだから仕方がない。何度も取得して負荷をかけないように取得結果をGCS上にストアして再利用することでフィード確認処理のたびに取得しないようにしている。
RSSの集約と ETag キャッシュ処理の実装
フォロークリエーターリストが生成できたらあとはRSSフィードを取得するだけではあるが、毎回全てのユーザーに更新を確認しても処理負荷をかけてしまうのでいくつかの戦略によって処理量を削減している。
- RSSフィードの生成結果をGCSに格納しておき生成処理自体をN時間に1回の実行とする
- 上記で生成されたRSSフィードファイル上のエントリを再利用
- クリエーターの RSS を取得する際には ETag 込みの問い合わせで更新有無を確認
- ETag とはHTTP のレスポンスヘッダーで、リソースの特定バージョンを示す識別子のこと
- URLごとの ETag を保存しておき、更新がある場合のみ本文取得
- 更新がない場合には生成済のRSSフィードに含まれていたと仮定
- 当日更新のフィードエントリ数が十分に集まったら処理を中断
要するに言えば成果物やバージョン識別子を保存しておいて、必要な場合のみ note.com に問い合わせるようにしている。また生成するフィードの本文情報などは先に紹介した Google Alert フィード変換と同様に Slack のカード生成ありきのものに縮減している。
Cloud Functions から Google Cloud Storage を使う
各種ファイルについては GCS に保存して、必要に応じて使っている。処理実体が Cloud Functions であるためサービスアカウントの権限管理さえできていればプログラム内での認証処理が特に不要なのが便利。
def __init__( self, bucket_name, blob_name, ttl=timedelta(hours=2), is_refresh=False ): self._blob = storage.Client().get_bucket(bucket_name).blob(blob_name) ... def download_as_string(self) -> str | None: if self.is_exists(): return self._blob.download_as_text() return None
この程度の簡単な記述で指定バケット内の指定ファイルをテキスト(str)として取り扱うことができる。ファイル内容の更新も blob.upload_from_string()
だけだ。
One Fact in One Place のための仕組みを実現するための逆行
以上までで、note.com のフォロークリエーターリストと同期する記事更新RSSフィードを生成できるようになったので、Slackに登録しておけばnote.comのフォローリストと同期して更新を検知することができ、Slackのフィード購読との二重管理をする必要がなくなる。
情報管理をするには「One Fact in One Place」が大事だといわれている。ひとつの事実を複数の場所に置くから不整合が起きたり、N重のメンテナンスが必要になってしまうのだ。その一方で、非公式APIや複数フィードを何度も note 側に読みにいく訳にはいかず、自身のGCSにキャッシュさせることによる N Place への逆行と複雑性が発生しているのが難しい。
昨今では、はてなブログから note に執筆場所を移すブロガーや経営者などが増えてきているように感じる。note 自身がはてなブログのようにフォローユーザーフィード生成を提供してくれればことが足りたのだけど、提供してくれないからこそ課題解決と学習の機会を得られたとも言える。欲を言えば有料記事かどうかのフラグがあるとありがたいのだけどフィードからは難しいようだ。