65
65

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

プログラミング大好きベーシックAdvent Calendar 2015

Day 8

Webプッシュ通知にカスタムボタンが実装できるようになったので試してみた

Last updated at Posted at 2015-12-07

昨日は新卒エンジニアのごっちんReactJSを使ってライフゲームを作るという面白い記事を書いてくれました。良い記事ですね。ReactJS→JavaScript→ServiceWorkerというJSつながりで、ServiceWorkerで出来るWebプッシュ通知の話をしたいと思います。

Webプッシュ通知

ServiceWorkerによってブラウザで開いていなくても、プッシュ通知を送ることが出来るようになりました。まるでネイティブアプリみたいですよね。素晴らしい。プッシュ通知そのものについては過去に書いたWebでプッシュ通知するサービスを個人開発で作ってみた+ServiceWorkerPushAPIの実装方法まとめを参考にしてみてください。

このServiceWorker、まだまだ仕様策定中ということもあって、じょじょに機能が追加されていってます(破壊的仕様変更もある)。そして、 Chrome48(ベータ) にてついに通知ダイアログにカスタムボタンを追加できるようになりました!

カスタムボタン

push_custom_buttons.png

PC版のChromeではこんな感じで表示されます。

android-push.png

Android版だとこんな感じ。

今のところ、最大で2つまでボタンが表示できるようです。本体のアクションと合わせると、3つのアクションが定義できることになります。単なる通知メッセージというよりは、インタラクティブな機能になるような予感がしています。

ボタンの表示

カスタムボタンの表示には、プッシュ通知時にタイトルやメッセージと同時にactionsプロパティで定義します。配列で、複数の定義ができます。

serviceworker.js
self.registration.showNotification("プッシュ通知だよ😁", {
  body: "通知メッセージ👐",
  icon: "/icon.png",
  tag: "tag",
  actions: [
    {action: 'action1', title: "ボタンだよ⚡️"},
    {action: 'action2', title: "こっちもボタン🍑"}
  ]
});

アクションの定義

アクションの定義は、単純にnotificationclickのイベントリスナーで行います。渡ってきたeventオブジェクトの中にクリックしたアクション名が入っているので、それで制御をします。簡単ですね!

serviceworker.js
self.addEventListener('notificationclick', function(event) {
  event.notification.close();
  
  if (event.action === 'action1') {
    clients.openWindow("/action1");
  } else if (event.action === 'action2') {
    clients.openWindow("/action2");
  } else {
    clients.openWindow("/");
  }
}, false);

最小構成のサンプル

Webプッシュ通知は、GCMのプッシュ通知サーバを使用しなくても普通にServiceWorkerのメソッドを叩けば通知ダイアログを出せます。なので、デバッグするときとかは、この方法を使うと便利です。

serviceworker.js
if (typeof window !== "undefined") {
    document.addEventListener('DOMContentLoaded', function() {
        navigator.serviceWorker.getRegistration().then(function (r) {
            navigator.serviceWorker.register('/serviceworker.js', { scope: '/' });
        });

        var push = document.getElementById('push');
        push.addEventListener('click', function() {
            navigator.serviceWorker.ready.then(function(sw) {
                return sw.showNotification("プッシュ通知だよ😁", {
                    body: "通知メッセージ👐",
                    icon: "/icon.png",
                    tag: "tag",
                    actions: [
                        {action: 'action1', title: "ボタンだよ⚡️"},
                        {action: 'action2', title: "こっちもボタン🍑"}
                    ]
                });
            });
        });
    });
}

if (typeof window === "undefined") {
    self.addEventListener('notificationclick', function(event) {
        event.notification.close();
        
        if (event.action === 'action1') {
            clients.openWindow("/action1");
        } else {
            clients.openWindow("/");
        }
    }, false);
}
index.html
<!doctype>
<html>
<head>
<script src="/serviceworker.js"></script>
<link rel="manifest" href="/manifest.json">
</head>
<body>
  <button id="push">プッシュ!</button>
</body>
</html>
manifest.json
{
    "name": "SiteNameExample",
    "short_name": "SiteNameExample",
    "start_url": "/",
    "display": "standalone",
    "gcm_sender_id": "プロジェクトID",
    "gcm_user_visible_only": true
}

最後に

Webプッシュ通知は、今やデイリーで3億5千万も通知が送られているそうです。まだまだ発展途上な機能ではありますが、今後Webサービスを作っていく中で外せない選択肢になると思います。実戦投入はまだとしても、どんなことが出来るのかはウォッチしていくのが良いと思います。気軽に使いたい場合は、Webプッシュ通知サービスPushnateをどうぞ。

明日はアプリエンジニアサキさんの出番です。わくてか。

65
65
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
65
65

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?