この記事は、pubsubhubbub.appspot.com で Subscribe した時の挙動について書く。
pubsubhubbub.appspot.com は PubSubHubbub Core 0.4 と Permanent subscriptions を除く PubSubHubbub Core 0.3 に従っている。
PubSubHubbub とは、Subscriber 側から見た場合は Webhook である。現在は W3C によって WebSub として公開されている。WebSub は PubSubHubbub Core 0.4 と概ね同じだと思われる (あまり読み込んでいない)。
仕様を正確に翻訳したものではない。実装する際には元の仕様を参照することをおすすめする。
参照: 2. Definitions
購読を登録するとき、次のような流れとなる。
参照: 5. Subscribing and Unsubscribing
以下のパラメータを Content-Type: application/x-www-form-urlencoded
で POST する。
subscribe
あるいは unsubscribe
のいずれかの値をとる。hub.mode
が unsubscribe
の場合は無視される。既に有効な Subscription がある場合、Hub は Subscription を更新する。Subscription の確認に失敗した場合は、以前の購読状態を継続する。
参照: 5.1. Subscriber Sends Subscription Request
Hub は HTTP 202 Accepted
によって、Subscription Request が検証され、確認されることを示す。エラーが発生した場合、Hub は 4xx または 5xx を返す。
参照: 5.1.2. Subscription Response Details
Subscription Request が正しいものかを確認するため、Hub は Subscriber Callback URL に以下のクエリパラメータとともに GET リクエストを送信する。
hub.mode
が subscribe
の場合、REQUIRED となる。Hub によって決定された購読の有効な時間 (秒) を表す。参照: 5.3. Hub Verifies Intent of the Subscriber
リクエストされた内容が正しい場合、Subscriber は hub.challenge
の値をレスポンスボディに含め、2xx を返す。リクエストされた内容が正しくない場合、Subscriber は 404 を返す。
その他のステータスコードを返した場合、またはレスポンスボディが hub.challenge
の値と異なる場合、確認は失敗する。
参照: 5.3.1. Verification Details
コンテンツが更新された時、Hub は Subscriber Callback URL に POST リクエストを送信する。
リクエストを受け取ったとき、Subscriber は 2xx を返さなければならない。それ以外のステータスコードを返した場合、通知は失敗したとみなされる (リダイレクトも機能しない)。2xx のレスポンスはあくまで正常に通知を受け取ったことを表すのみであり、通知の内容が正しいことを示すものではない。
リクエストには、RFC5988 に規定される Link Header が付与される。rel=hub
には Hub の URL を、rel=self
には Topic の URL が指定される。
Subscription Request に hub.secret
を含めた場合、Hub はペイロードの HMAC 署名をヘッダに付与する。署名は 40 バイトの 16 進数表示の SHA-1 である。ヘッダの形式は次のようになる。
X-Hub-Signature: sha1=<signature>
これにより、通知の内容が第三者に偽造されたものではないことを確認できる。
8. Authenticated Content Distribution
参照: 4. Atom Details
以下のパラメータが追加される。
sync
あるいは async
のいずれの値をとる。参考: 6.1. Subscriber Sends Subscription Request
以下のクエリパラメータが追加される。
以下のパラメータが変更される。
参照: 6.2. Hub Verifies Intent of the Subscriber
注意: pubsubhubbub.appspot.com では非対応である。
hub.lease_seconds
が経過する前に、Hub は自動的に Subscription の確認を行う。
参照: 6.3 Automatic Subscription Refresh
筆者が自分の環境で確認したものである。仕様に定められた挙動ではないため、将来的に変更される可能性もある。
送信先は https://pubsubhubbub.appspot.com/subscribe
である。
hub.verify
が sync
の場合、正常に Subscription Request が受理されたときは 204 No Content を返す。
PubSubHubbub Core 0.3 の 6.3 Automatic Subscription Refresh には対応しない。Subscriber は hub.lease_seconds が経過する前に再び Subscription Request を行う必要がある。
pubsubhubbub.appspot.com は PubSubHubbub Core 0.4 に加えて PubSubHubbub Core 0.3 も参照するが、Permanent Subscription には非対応であるため、実用上は hub.verify_token
が追加されることにだけ注意すれば良いと思われる。大抵の場合は hub.verify
を sync
として問題ないであろう。
PubSubHubbub Core 0.3 では更新通知のメッセージ形式が Atom または RSS と規定されているが、PubSubHubbub Core 0.4 および WebSub では撤廃されている。これにより、より汎用性の高いプロトコルを目指したと思われる。
また、新しいバージョンでは hub.verify_token
も撤廃されている。このプロパティによって Verification Request を検証できるというメリットがあったが、これは Subscriber Callback URL に独自のクエリパラメータを付与することで代替できる。あるいは、第三者によって意図しない Subscription を登録されたとしても、更新通知を処理するかどうかは変わらず Subscriber の判断によるため、仕様から削除されたのかもしれない。
Automatic Subscription Refresh の撤廃は、より簡単な Webhook の登録を目指すという観点からは悪手であろう。一方、PubSubHubbub はそもそも RSS や Atom フィードのリアルタイム化を目指したものであること (Wikipedia を参照のこと) を踏まえれば妥当であるともいえる。もし Subscriber が Subscription の更新を忘れてしまったとしても、最新の更新情報は元のリソースを参照することで簡単に取得できるからである。
YouTube Data API v3 について調べていたのだが、Search: list (100 Units/Request) をむやみに叩くとすぐに制限 (10,000 Units/Day) に達してしまう。特定のチャンネルのアップデートを素早く受け取るために、PubSubHubbub をサポートしていた。