PUSHERでWebhookを行ってみる

PUSHERWebHookができるという記事がブログで紹介されてますよ!と会社で教えてもらったので、試してみました。
先日試してみたwebsocket版の通知とは異なってWebHookなのでユーザが設定する任意のURLに対してPUSHリクエストがあったことをHTTPのPOSTで通知する仕組みになります。
(下の図の赤字で書いたWeb Hookの部分)
f:id:hideack:20120205220755p:image
ですので、PUSH通知できる対象はブラウザ等では無く、Webサーバ上で稼働する任意のアプリケーションが通知対象となります。


利用方法はとても簡単でPUSHERのコントロールパネルにWebHooksという項目があるので選択をするとWebHookを有効にするためのチェックボックスとフックする先のURLを指定する欄があるのでURLを指定します。
f:id:hideack:20120205221444p:image


そうすると、PUSHERのAPIを通してWebアプリケーションからPUSH通知が走った場合に、設定したURLへ対してPOSTリクエストが行われます。(同時にWebsocketで接続中のWebブラウザへも通知が行われる)
こうすることによって、フック先のWebアプリケーション側でもPUSH通知が走ったことを検出することができます。
PUSH通知をされた側のWebアプリケーションは、このままでは本当に真のPUSH通知元(=PUSHER)からのPOSTリクエストかどうかを判定することができませんが、PUSHERから通知されたリクエストには、

  • X-Pusher-Key
  • X-Pusher-Signature

という二つのHTTPヘッダが付いていて、PUSH通知内容(POSTリクエストの内容)に対するHMAC SHA256が付いているので、この内容がPUSHER APIの秘密鍵から作られるSHA256のメッセージダイジェストの内容と一致するかを確認することでPUSHERから通知されたことを確認することができます。


以下、ドキュメントに掲載されているサンプルのままですが、読めばシンプルで分かりやすいと思います。

<?php
  $app_key = $_SERVER['X-Pusher-Key'];
  $webhook_signature = $_SERVER['X-Pusher-Signature'];
  $body = http_get_request_body();

  $expected_signature = hash_hmac( 'sha256', $body, $app_secret, false );

  if($webhook_signature == $expected_signature) {
    $payload = json_decode($body);
    foreach($payload['events'] as &$event) {
      // do something with the event
    }

    header("Status: 200 OK");
  }
  else {
    header("Status: 401 Not authenticated");
  }
?>

参考

Pusher WebHooks Documentation | Pusher
http://pusher.com/docs/webhooks