ServiceWorkerを使ったPush APIをやってみた

2015-05-17T00:00:00+09:00 JavaScript

公式ドラフトドキュメント?: http://www.w3.org/TR/push-api/

参考1: http://updates.html5rocks.com/2015/03/push-notificatons-on-the-open-web

参考2: http://qiita.com/tomoyukilabs/items/8fffb4280c1914b6aa3d

前から気になってたServiceWorkerを使ってPush APIを実装するっていうのが話題になってた気がするので、ざっくりと参考を読みつつやってみた

その前に

以前にChrome Extensionで使えるchrome.gcmっていうのがあるネタを書いたけど、今回はこれをChrome Extensionではなく普通のWebアプリケーションから使える基盤的な仕組みみたいなのっぽい

必要なのを揃える

GoogleのPush Messagingサービスを使うので、まず必要なのが

  • Cloud Messaging for Chromeを有効にする
  • Cloud Messaging for Androidを有効にする
  • Google APIsのAPI Key
  • Google APIsのプロジェクト識別番号

の4つが最低限でも必要っぽいので取得しておく。上記で書いたchrome.gcmのネタ中にも多分書いてるはずなので省略(APIへのアクセス権の設定項目)

manifest.json

※Chrome Extensionのmanifest.jsonでは無い

Push Notification APIを使う際に必要となる情報を定義したJSONファイル

{
  "name": "sample",
  "short_name": "sample",
  "start_url": "http://localhost:8000/index.html",
  "display": "standalone",
  "gcm_sender_id": "上記で取得したGoogle APIsプロジェクトのプロジェクト番号",
  "gcm_user_visible_only": true
}

これに関するリファレンスがちょっとどこにあるのか分かってないので省略

index.html

<!DOCTYPE html>
<html>
  <head>
    <link rel="manifest" href="manifest.json" />
  </head>
  <body>
    <div id="subscription"></div><p />
    <button class="js-push-button">register</button>
    <script src="main.js"></script>
  </body>
</html>

上記で書いたmanifest.jsonを<link rel=“manifest”>で読み込む。んまぁあとはJSをダラっと書くだけ

main.js

window.addEventListener("load", function() {
  var el = document.querySelector(".js-push-button");
  el.addEventListener("click", function() {
    subscribe();
  });

  // 指定したスクリプトをServiceWorkerとしてインストール
  navigator.serviceWorker.register("push.js").then(function() {
    if (Notification.permission === "denied") {
      throw new "Notification is denied";
    }

    navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
      serviceWorkerRegistration.pushManager
        .getSubscription()
        .then(function(subscription) {
            // subscribeされてなければnullになる
            if (!subscription) {
              return;
            }

            el.disabled = true;
            renderSubscription(subscription);
        });
    });
  });
}, false);

function subscribe() {
  navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
    serviceWorkerRegistration.pushManager.subscribe().then(function(subscription) {
      var el = document.querySelector(".js-push-button");
      el.disabled = true;
      renderSubscription(subscription);
    });
  });
}

function renderSubscription(subscription) {
  document.querySelector('#subscription').innerHTML = subscription.subscriptionId;
}

push.js

self.addEventListener("install", function() {
  console.log("install");
}, false);

self.addEventListener("push", function(event) {
  event.waitUntil(
    self.registration.showNotification(
      "title",
      {
        "body": "body"
      }
    )
  );
}, false);

registerされた時点でinstallイベントが発生してプッシュ通知を受信したらpushイベントが起きるみたいな感じ。他にもなんかイベントあるみたいですけど今回はパス(追記するかと)

でとりあえず今までの流れを確認すると

まず作成したHTMLにアクセスした時点でchrome://serviceworker-internalsを見ると

んな感じになってる。でregisterボタンを押すと

※Subscription IDは削ってるのでこのIDをやっても出来ません

っていうようにSubscription IDが表示される。おそらくは一度subscribeしているとgetSubscriptionで取れるようになってると思うのでリロードするとボタンを押さなくても表示されるかと

んまぁこのSubscription IDを使ってリクエストを送信すれば通知ができるって訳

send.sh

#!/bin/sh

ID="上記のSubscription ID"
KEY="Google Consoleで取得したGoogle Apis Key"


curl \
    -H "Content-Type:application/json" \
    -H "Authorization: key=$KEY" \
    -d "{ \"registration_ids\": [\"$ID\"] }" \
    https://android.googleapis.com/gcm/send

を実行すると

みたいにデスクトップ通知が出るようになる。何やら通知をクリックした時のイベントがどうたらとかもあるらしい

まぁざっくり書きましたが現状でもまだ策定中な所もあるようだし実装もまだできてなくて制限が一部あるんですが

  • pushを受信したらshowNotificationしないといけないらしい
  • データを現時点では受信出来ない(Chrome拡張のchrome.gcmはデータを受信することは可能)
  • もしサービスに導入するならHTTPS環境にデプロイしないと出来ない(海外のHTML5のスペシャリストな人の記事では受信したらサーバーに通知情報をとりに行くみたいな事しているようなケースもある模様)

他にも色々あるらしいので、詳しい事は上記の参考URLを見た方が良いかと

んまぁとりあえず今後色々出来る事が増えると思うので分かった事なりを書いたり追記したりするとは思うって事で

npmだけでディレクトリを監視してテストを自動実行させる方法 Google AppEngineでGoogle Analytics Core Reporting API