Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

昨日は新卒エンジニアのごっちん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をどうぞ。

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

zaru
basicinc
マーケティングとテクノロジーで社会のあらゆる問題を解決する集団
https://tech.basicinc.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away