Androidにpush通知する(Chrome ServiceWorkers+Google Cloud Messaging)

軽い気持ちで試したらいろいろと泥沼ってへとへと。
とりあえず、サーバ側のアクションだけでAndroidスマホにpush通知を送れたので一旦終了…。

・メモ
参考にしたサイト
WebアプリからもPush通知が!ChromeのPush通知について - しろかい!
http://shirokai.hatenablog.com/entry/chrome-push-notification
ChromeでW3C Push APIを使ってみた - Qiita
http://qiita.com/tomoyukilabs/items/8fffb4280c1914b6aa3d
ServiceWorkerを使ったPush APIをやってみた - kinjouj.github.io
http://kinjouj.github.io/2015/05/serviceworker-push-api.html
fix demo after subscriptionId goes away by notwaldorf ・ Pull Request #40 ・ PolymerElements/platinum-push-messaging ・ GitHub
https://github.com/PolymerElements/platinum-push-messaging/pull/40/files

・泥沼ポイント
参考にした1件目のサイトが、古い仕様のGCM用だったらしくsubscriptionIdが全然取れなくてドツボ。
4件目のプルリクエスト?のコードを参考に、subscriptionIdを切り出すようにしたけどまだダメ。
2件目・3件目のサイトなどを見て、プロジェクトIDが足りないことに気付く。他人(他プロジェクト)のIDじゃ通らないのは当然。

このあたりで一応通知は通ったんだけど、アイコンが小さかったので大きくしようとしてまたドツボ。
必死にmanifest.jsonを弄って遅延ローディングとか仕込んで…ってやってたけど、よく見たらプッシュ通知のアイコンはservice-worker.jsで指定してた。

ところで、これ何かに使えるかなぁ?
私自身、プッシュ通知って鬱陶しいから基本的にOFFにするタイプで、ONにしてるのはIngressの攻撃通知ぐらい。
まあ、一応使える道具が増えたということで…。

ちなみに、タイトルに「Android」って書いてあるけど、実際はPCのChromeでも使える(PCにもpush通知できる)。
Android以上に使い道に悩むところだけど。


一応、gitリポジトリ(https://github.com/shun91/chrome-push-notification/、コミット8158627ed380fa623a82740e32aa5fb1cb2a3755)との差分。

diff --git a/SubscriptionRegister.php b/SubscriptionRegister.php
index 8a54d94..bd9b86b 100644
--- a/SubscriptionRegister.php
+++ b/SubscriptionRegister.php
@@ -5,12 +5,12 @@
*/

// subscriptionIdとendpointを保存するファイルのパス
-define("FILE_NAME", "");
+define("FILE_NAME", "subscriptions.cgi");

// subscriptionIdとendpointを登録.
function registSubscription($subscriptionId, $endpoint){
// テキストファイルに追記.
- file_put_contents(FILE_NAME, $subscriptionId.','.$endpoint."\n", FILE_APPEND|LOCK_EX);
+ file_put_contents(FILE_NAME, "curl --header \"Authorization: key=<<APIキー>>\" --header Content-Type:\"application/json\" ".$endpoint." -d \"{\\\"registration_ids\\\":[\\\"".$subscriptionId."\\\"]}\"\n", LOCK_EX);
}

function main(){
diff --git a/index.html b/index.html
index 5b4306a..9c6e1a1 100644
--- a/index.html
+++ b/index.html
@@ -20,8 +20,19 @@ limitations under the License.
<title>Chrome プッシュ通知 サンプル</title>

<!-- Include manifest file in the page -->
- <link rel="manifest" href="manifest.json">
-
+ <!-- link rel="manifest" href="manifest.json" -->
+ <script src="/js/jquery-1.11.1.min.js" id="firstscript"></script>
+ <script type="text/javascript">
+ var sNew = document.createElement("script");
+ sNew.async = true;
+ sNew.src = "main.js?" + (new Date().getTime());
+ var s0 = document.getElementById('firstscript');
+ s0.parentNode.insertBefore(sNew, s0);
+ var lNew = document.createElement("link");
+ lNew.rel="manifest";
+ lNew.href="manifest.json?" + (new Date().getTime());
+ s0.parentNode.insertBefore(lNew, s0);
+ </script>
</head>

<body>
@@ -29,6 +40,6 @@ limitations under the License.
<button class="js-push-button" disabled>プッシュ通知を受信する</button>
<div class="js-curl-command"></div>

- <script src="main.js"></script>
+ <!-- script src="main.js" /script -->
</body>
</html>
diff --git a/main.js b/main.js
index ca3851f..d3d6ca6 100644
--- a/main.js
+++ b/main.js
@@ -1,6 +1,6 @@
'use strict';

-var API_KEY = '';
+var API_KEY = '<<APIキー>>';

var curlCommandDiv = document.querySelector('.js-curl-command');
var isPushEnabled = false;
@@ -13,20 +13,36 @@ function sendSubscriptionToServer(subscription) {
// 以下のコメントアウトを外すと,SubscriptionRegister.phpを利用して
// subscription.subscriptionIdとsubscription.endpointをテキストファイルに書き込む.

- // $.ajax({
- // type: "POST",
- // url: "SubscriptionRegister.php",
- // data: 'subscription_id='+ subscription.subscriptionId +'&endpoint='+ subscription.endpoint,
- // success: function() {
- // console.log('registed!');
- // }
- // });
+ var subscriptionId = subscription.subscriptionId;
+ var endpoint = subscription.endpoint;
+ if (subscription && !subscription.subscriptionId){
+ var endpointSections = endpoint.split('/');
+ subscriptionId = endpointSections[endpointSections.length - 1];
+ endpoint = endpoint.replace('/' + subscriptionId,'');
+ }
+
+ $.ajax({
+ type: "POST",
+ url: "SubscriptionRegister.php",
+ data: 'subscription_id='+ subscriptionId +'&endpoint='+ endpoint,
+ success: function() {
+ console.log('registed!');
+ },
+ error: function(){
+ console.log('error!!!!');
+ }
+ });
}

function showCurlCommand(subscription) {
// The curl command to trigger a push message straight from GCM
var subscriptionId = subscription.subscriptionId;
var endpoint = subscription.endpoint;
+ if (subscription && !subscription.subscriptionId){
+ var endpointSections = endpoint.split('/');
+ subscriptionId = endpointSections[endpointSections.length - 1];
+ endpoint = endpoint.replace('/' + subscriptionId,'');
+ }
var curlCommand = '<h2>下記コマンドを端末上で叩くとプッシュ通知を送信できる</h2><p>curl --header "Authorization: key=' + API_KEY +
'" --header Content-Type:"application/json" ' + endpoint +
' -d "{\\"registration_ids\\":[\\"' + subscriptionId + '\\"]}"</p>';
@@ -85,7 +101,7 @@ function subscribe() {
pushButton.disabled = true;

navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
- serviceWorkerRegistration.pushManager.subscribe()
+ serviceWorkerRegistration.pushManager.subscribe({userVisibleOnly:true})
.then(function(subscription) {
// The subscription was successful
isPushEnabled = true;
@@ -181,7 +197,7 @@ window.addEventListener('load', function() {
// Check that service workers are supported, if so, progressively
// enhance and add push messaging support, otherwise continue without it.
if ('serviceWorker' in navigator) {
- navigator.serviceWorker.register('./service-worker.js')
+ navigator.serviceWorker.register('./service-worker.js?' + (new Date().getTime()))
.then(initialiseState);
} else {
}
diff --git a/manifest.json b/manifest.json
index f9a5577..09b5070 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,12 +1,12 @@
{
- "name": "Chrome プッシュ通知",
- "short_name": "Chrome プッシュ通知",
+ "name": "MCRN Android Push Notifier",
+ "short_name": "MCRN push",
"icons": [{
- "src": "/chrome-push-notification/images/icon.png",
- "sizes": "192x192"
+ "src": "/pushicon.png",
+ "sizes": "192x192",
+ "type": "image/png"
}],
- "start_url": "/chrome-push-notification/",
+ "start_url": "/",
"display": "standalone",
- "gcm_sender_id": "928986754054",
- "gcm_user_visible_only": true
+ "gcm_sender_id": "<<プロジェクトのID>>"
}
diff --git a/service-worker.js b/service-worker.js
index a68a7fb..e603d24 100644
--- a/service-worker.js
+++ b/service-worker.js
@@ -3,9 +3,9 @@
self.addEventListener('push', function(event) {
console.log('Received a push message', event);

- var title = 'Chrome プッシュ通知';
- var body = 'プッシュ通知の本文.';
- var icon = '/chrome-push-notification/images/icon.png';
+ var title = 'MCRN';
+ var body = '現在' + (new Date()).toString() + 'です。';
+ var icon = '/pushicon.png';
var tag = 'tag';

event.waitUntil(
@@ -31,11 +31,11 @@ self.addEventListener('notificationclick', function(event) {
}).then(function(clientList) {
for (var i = 0; i < clientList.length; i++) {
var client = clientList[i];
- if (client.url == '/chrome-push-notification/' && 'focus' in client)
+ if (client.url == '/' && 'focus' in client)
return client.focus();
}
if (clients.openWindow)
- return clients.openWindow('/chrome-push-notification/');
+ return clients.openWindow('/');
}));

});