WEBアプリでプッシュ通知を実装する
WEBアプリでプッシュ通知を実装する方法を紹介します。
googleが紹介している以下のページを参考にしました。
ウェブアプリへのプッシュ通知の追加 | Web | Google Developers
処理の流れ
以下の流れで実装していきます。
- サイトに対してプッシュ通知の許可をユーザに促す
- 許可した際に取得できる情報(プッシュ通知に必要な情報)を取得し、サーバーのDBなどに保存
- 保存した情報を使ってユーザのブラウザにプッシュ通知を送る
1はクライアント処理、2はクライアント処理とサーバー処理、3はサーバー処理になります。
3のサーバー処理で使用するWEBプッシュライブラリは https://github.com/web-push-libs/web-push-php を使用しています。
プッシュ通知の許可
以下のようなダイアログを表示して、ユーザにプッシュ通知を許可してもらいます。
プッシュ通知の許可をユーザに促すにはService Worker
の登録が必要です。
Service Worker
とはブラウザがWebページとは別にバックグラウンドで実行するためのスクリプトです。
今回のようなプッシュ通知や、オフラインの制御などで使用されます。
そのため、IE11
など、Service Worker
に対応していないブラウザはプッシュ通知は送れないことになります。
対応ブラウザは以下で確認できます。
https://caniuse.com/#feat=serviceworkers
Service Workerの登録
まずはService Worker
のファイルをルートディレクトリに作成します。ファイル名は何でもかまいませんが、ここではservice-worker.js
とします。
ファイルの中身はひとまずは空で問題ありません。
- ルートディレクトリ
- index.html
- service-worker.js
以下のようにページロード時にService Worker
を登録します。
登録したService Worker
の情報をwindow
オブジェクトにsw
という名前で追加しておきます。
window.addEventListener('load', async () => {
if ('serviceWorker' in navigator) {
window.sw = await navigator.serviceWorker.register('/service-worker.js', { scope: '/' });
}
});
アクセス後、Chrome
の場合は以下のように開発者ツールからService Worker
が登録されていることを確認できます。
アプリケーション サーバーキーの入手
以下のサイトからPublic Key
とPrivate Key
を入手します。
https://web-push-codelab.glitch.me/
アカウント登録などは必要なく、ページにアクセスするとPublic Key
とPrivate Key
が表示されていますので、その組み合わせをコピーしてメモしておきます。
これはプッシュ通知を行う際に必要になります。
Private Key
は公開しないようにしてください。
通知許可を促す
まずは以下のファンクションを定義します。
PublicKey
はこのファンクションを使用してUInt8Array
の形式に変換する必要があります。
function urlB64ToUint8Array (base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
先のステップで登録したService Worker
のオブジェクトを使用して、pushManager.subscribe
メソッドを実行します。
ページロード時や、何かしらのボタンを押したときのイベントで実行することになると思います。
パラメータは以下を設定します。
- userVisibleOnly
true
固定- applicationServerKey
UInt8Array
に変換したPublickKey
const appServerKey = PublicKey; // 取得したPublickKey
const applicationServerKey = urlB64ToUint8Array(appServerKey);
const subscription = await window.sw.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey
});
この処理を実行すると、プッシュ通知の許可を求めるダイアログが表示されます。
すでにプッシュ通知を許可されている場合はダイアログは表示されません。
また、ここでは省略していますが、ブロックボタンを押されたり、すでにブロックされているような場合は、Primise
はreject
されるため、実際はcatch
の処理を実装する必要があります。
ブラウザのURLバーのアイコンをクリックすると以下のように通知許可の状態を表示・変更できます。
許可情報を登録
通知が許可されると、変数subscription
にプッシュ通知に必要な情報が設定されます。
以下の3つの情報をサーバーのDBなどに保存します。
- endpoint
- p256dh
- auth
このうち、p256dh
とauth
は、今回使用する https://github.com/web-push-libs/web-push-php で使用できる形式に合わせて変換します。
p256dh
はuserPublicKey
、auth
はuserAuthToken
として登録します。
(サーバー処理で使用するWEBプッシュライブラリによって、必要な情報や形式は変わってくると思います。)
const key = subscription.getKey('p256dh');
const token = subscription.getKey('auth');
const request = {
endpoint: subscription.endpoint,
userPublicKey: btoa(String.fromCharCode.apply(null, new Uint8Array(key))),
userAuthToken: btoa(String.fromCharCode.apply(null, new Uint8Array(token)))
};
プッシュ通知を送信
今回使用するWEBプッシュライブラリ https://github.com/web-push-libs/web-push-php をインストールします。
$ composer require minishlink/web-push
以下の処理を実行すると、プッシュ通知が対象のブラウザに送信されます。
use Minishlink\WebPush\WebPush;
$auth = array(
'VAPID' => array(
'subject' => url, // 自身のWEBサイトのURL('http://localhost'など)
'publicKey' => publicKey, // 取得したPublicKey
'privateKey' => privateKey, // 取得したPrivateKey
),
);
$webPush = new WebPush($auth);
$webPush->sendNotification(
endpoint, // 登録したendpoint
'プッシュ通知のテストです。', // プッシュ通知に表示する文言
userPublicKey, // 登録したuserPublicKey
userAuthToken // 登録したuserAuthToken
);
$webPush->flush();
プッシュ通知を表示する
受け取ったプッシュ通知を表示するにはService Worker
の中身を実装する必要があります。
以下のように実装しておけば、プッシュ通知が表示されるようになります。
service-worker.js
// プッシュ通知を受け取ったときのイベント
self.addEventListener('push', function (event) {
const title = 'プッシュ通知のテスト';
const options = {
body: event.data.text(), // サーバーからのメッセージ
tag: title, // タイトル
icon: 'icon.png', // アイコン
badge: 'icon.png' // アイコン
};
event.waitUntil(self.registration.showNotification(title, options));
});
// プッシュ通知をクリックしたときのイベント
self.addEventListener('notificationclick', function (event) {
event.notification.close();
event.waitUntil(
// プッシュ通知をクリックしたときにブラウザを起動して表示するURL
clients.openWindow('https://localhost/pushtest.html')
);
});
まとめ
以上でプッシュ通知の実装ができました。
プッシュ通知の登録を削除する方法はJavaScript WEBアプリのプッシュ通知の許可を取り消す方法で紹介しています。