Google Cloud Messaging for Chromeキター! これでChrome Extensionに対してサーバからプッシュ通知ができるよ!
- グーグル、「Chrome」でプッシュ通知を可能に–「Google Cloud Messaging for Chrome」発表 – CNET Japan
- Chromium Blog: Building efficient apps and extensions with push messaging
- Google Cloud Messaging for Chrome – Google Chrome
もともとGCM (Google Cloud Messaging) はAndroid向けのテクノロジーで、C2DM (Android Cloud to Device Messaging) の後釜のようなものである。アプリをインストールしたユーザに対してサーバ側からメッセージをプッシュできるというものだ。それと同じようなものが、今回、Google Chromeでも使えるようになったというわけだ。
GCM for Chromeを使うと、任意のユーザに対して任意のメッセージを送ることができる。定形のダイアログやバッジとして表示されるわけではなく、Chrome拡張は「メッセージの受信」イベントを開発者の好きなようにハンドルすることができる。
なお、使い勝手はなんとなく似ているものの、メッセージ送信の方法もAndroid用のものとは違うし、GCM for Android用のサーバサイドライブラリも使えないので、Androidな人は要注意。
面白そうなのでさっそく試してみた。何カ所か面倒なところがあったけれど、ほぼ「最短」で試すための手順をまとめておく。この記事はちょっと長いけど、長いのはアクセストークンの取得の箇所だけ。既存のChrome Extensionに組み込んでちょっと試すだけなら、60分くらいで終わると思う。
- Google APIs Consoleでアプリを登録
- 拡張を作成
- Chrome Web Storeにアップロードし、テスター限定でpublishする
- アクセストークンを取得
- 送信してみる
- 今後開発をしやすいように、拡張のキーを取得する
Google APIs Consoleでプロジェクトを登録
まず、Google APIsにプロジェクトを登録し、「このプロジェクトでGCM for Chromeを使うよ」という手続きをしなければならない。Google APIs Consoleにアクセスしよう。
Google APIs Console https://code.google.com/apis/console/
プロジェクトを新規作成、もしくはすでにあるプロジェクトにGCMを追加する。新規作成する場合は、左上のメニューから “Create…” を選択して、適当な名前を入れればOK。
“Services” タブを開いて、 “Google Cloud Messaging for Chrome” をオンにする。これを初めてオンにする場合は利用規約を読んで同意する必要がある。
拡張を実装
拡張の作り方についてはGetting Startedあたりを見ればいいということで省略。
manifest.jsonに “pushMessaging” パーミッションを追加する。
"permissions" : ["pushMessaging"]
という具合に記述する。
次に、channelIdを取得するコードを追加する。channelIdというのは、送信相手を指定するためのIDである。
とりあえず、取得できたchannelIdをalertするだけならこんな感じになる。
chrome.pushMessaging.getChannelId(false, function (response){ alert("channelId=" + response.channelId); });
chrome.pushMessaging.getChannelIdで取得。第2引数としてコールバック関数を渡し、channelIdプロパティを取得すればOK。この時点で、とりあえずchannnelIdの取得だけでもテストしておくと良い。
実際は、取得したchannelIdをサーバに送信して保存するなどの処理が必要になると思う。
さらに、「メッセージの受信 」のイベントをハンドルする。GCM for Chromeでは、受け取ったメッセージが定形のポップアップやバッジとして表示されるわけではなく、どう取り扱うかは拡張の開発者にゆだねられている。ポップアップやバッジを実装したり、裏で何らかの情報をサーバに取りにいったり、受け取ったメッセージをローカルストレージに保存したり……そのへんは適宜実装する。
この例では、メッセージのペイロードをただalertするだけにしておいた。
chrome.pushMessaging.onMessage.addListener(function (message) { alert("GCM message: " + message.payload ); });
ここを実際にテストするには、アクセストークンを取ったりChrome Web Storeにアップロードしたりと色々面倒だけど、とりあえず実装しておく。
データの流れはだいたいこんな具合になる。
Chrome Web Storeにアップロードし、テスター限定でpublishする
実際にChrome Web Storeに登録されているアプリに対してしかGCMによる通知はできない。いきなり公開してしまうのもよろしくないので、「テスターのみにpublishする」という機能を使ってこっそりと試してみる。
Developer Dashboard – Chrome Web Store
にアクセスする。”Add new item” ボタンを押し、作った拡張をzipで固めたものをアップロード。”Publish to test accounts” を押せば、自分だけがChrome Web Store経由でインストールできるようになる。実際にWeb Storeからインストールする。
アクセストークンを取得
これでようやく送信テストの準備が整った。アクセストークンを取得してメッセージを送ってみる。うまくいけば、送ったメッセージがダイアログに表示される。
最初に開いたGoogle APIs Consoleにアクセスし、”API Access” タブを開く。
“Create an OAuth 2.0 client ID…” という青いボタンを押す。
“Create Client ID” というダイアログに “Your site or hostname (more options)” という箇所があるのでクリック。
“Authorized Redirect URIs” というテキストエリアに
https://developers.google.com/oauthplayground
と書く。
“Create client ID” を押すと、アクセストークンの取得に必要な “Client ID” と “Client Secret” が発行される。
そしたら、
にアクセスする。右上の歯車アイコンをクリックして
“Use your own OAuth credentials” をチェックすると、”OAuth Client ID” と “OAuth Client secret” のフィールドが現れる。ここに、Google APIs Consoleで取得したClient IDとClient Secretを入れる。
左の “Step 1″ というセクションで、APIを選ぶ。現時点でGCM for Chromeはリストに入っていないので、リストの下のテキストボックスに
https://www.googleapis.com/auth/gcm_for_chrome
と入力し、Authorize APIsを押す。
その後、パーミッション確認画面に移動するので “Allow access” を押す。
その後ふたたびOAuth2 Playgroundに戻ってくるので、”Exchange authorization code for tokens” を押してRefresh tokenをゲット。
このRefresh tokenを使って、アクセストークンをもらいに行く。
アクセストークンを得るには、こんなPOSTリクエストをすればいい。
POST /o/oauth2/token HTTP/1.1 Host: accounts.google.com Content-Type: application/x-www-form-urlencoded client_id=○○○○○○○ client_secret=○○○○○○○ refresh_token=○○○○○○○○ grant_type=refresh_token
コマンドラインからcurlでやる場合はこんな感じ。
curl https://accounts.google.com/o/oauth2/token \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'client_id=○○○○○○' \ -d 'client_secret=○○○○○○' \ -d 'grant_type=refresh_token' \ -d 'refresh_token=○○○○○○'
成功すると、こんなレスポンスが得られる。わーいアクセストークンゲットだよ!
期限が切れちゃったらまた同じ手順で発行してもらえばOK。
{ "access_token" : "○○○○○○○○", "token_type" : "Bearer", "expires_in" : 3600 }
これで、メッセージを送信できるようになる。
メッセージ送信には、次のようなリクエストを送信すればよい。”channelId” の部分には、拡張の中で “chrome.pushMessaging.getChannelId” で得られた文字列を入れる。
POST /gcm_for_chrome/v1/messages Host: www.googleapis.com Content-Type: application/json Authorization: Bearer [アクセストークン] { 'channelId': '○○○○○○○', 'subchannelId': '0', 'payload': 'Hello GCM!' }
curlでさくっと試すなら、送信データを “data.json” とかいうテキストに書き込んで保存して
{ "channelId":"○○○○○", "subchannelId":"0", "payload":"Hello GCM!" }
コマンドラインからこんな具合にcurlコマンドを打ってやてば簡単。
curl https://www.googleapis.com/gcm_for_chrome/v1/messages -H "Content-Type: application/json" -H "Authorization: Bearer アクセストークン" -d @data.txt
うまくいけば、開発中の拡張のインストールされたChromeに “Hello GCM!” っていうダイアログが出るはず。
GCM for Androidとの相違
ちなみに、Android向けのGCMではペイロードをkey-value形式で送れるようになっているが、GCM for Chromeでは、ペイロードは文字列1本という形になっている。複雑なデータを送りたい場合は、JSON文字列にして送って拡張の側でパースするなどの工夫が必要。
また、GCM for Androidではできた「複数宛先への同時送信」「Collapse Keyによってメッセージをまとめる」などの機能もfor Chromeには無いので注意。一応、subchannelIdを使うとメッセージをまとめたり優先順位をつけたりすることはできる。
今後開発をしやすいように、拡張のキーを取得する
ここまでは、Chrome Web Storeにアップロードしたパッケージを使ってGCMを試してみた。でも、できれば毎回アップロードせずに、ローカルで試したいので、今後ローカルでさくさく開発ができるようにする。
いったんChrome Web Storeにアップロードした拡張からマニフェストのキーを取得し、ローカルで開発中のmanifest.jsonに貼りつけると、ローカルでも受信テストができるようになる。
(Chrome Developer Advocateの@agektmrさんからいいことを教えていただいたので、2013年5月12日19時ごろ追記)
Chrome Web Storeから配布されてている拡張のマニフェストのキーは、
chrome.runtime.getManifest().key
で取得できる (ローカルで実行すると undefined が返ってくる)。キーを取得するコードを仕込んでからChrome Web Storeにアップロードし、いったんインストールする。それを実行して取得したキーを、ローカルのmanifest.jsonに
"key":"XXXXXXX"
という具合に書き加える。すると、ローカルからロードした拡張でもGCMのメッセージを受け取れるようになり、さくさく開発できるようになる。
参考: chrome.runtime – Google Chrome
(↓こういう方法でもkeyは取れる)
インストールされた拡張のIDを調べる。chrome://extensions/を開くと、”ID:XXXXX” という文字列が見つかる。それがその拡張のIDである。
そしたら、拡張のインストールされているディレクトリを開く。
Mac OS Xなら
~/Library/Application\ Support/Google/Chrome/Default/Extensions/拡張ID
Windowsなら
C:\Documents and Settings\ユーザ名\Local Settings\Application Data\Google\Chrome\User Data\Default\Extensions\拡張ID
その中にあるmanifest.jsonを開くと、 “key”:”XXXXXX” という箇所があるので、それをコピーし、開発中の拡張のmanifest.jsonに貼付ける。それをリロードすると、送信テストができるようになる。
なお、”key” 属性はChrome Web Storeから付与されるものであり、自分で書き加えたkeyがmanifest.jsonに含まれた状態でアップロードするとエラーになる。リリースする際やベータテスターに配る場合は、key属性を消してからアップロードしなければいけない。
読んでおくと良さそうな資料
- Google Cloud Messaging for Chrome – Google Chrome
- chrome.pushMessaging – Google Chrome
- API Reference for GCM service – Google Chrome