Laravel + AngularでWeb Push通知を実装する

2020年04月16日
投稿者:若林 奨太
カテゴリ:Angular, Laravel タグ:, ,

こんにちは。鈴木商店の若林 (@itigoore01) です。
Laravel + AngularでWeb Push通知を実装してみたので、実装方法やハマりどころを紹介していきます。
こんな感じです。

demo capture

対象読者

  • Laravel、Angularをある程度使ったことがある
  • Laravel、AngularでWeb Push通知を実装したい、したいけどできなかった

環境

以下の環境で開発、動作確認をしています。
コマンド、パスなどはご自身の環境に合わせて読みかえてください。

OS: macOS Catalina 10.15.4

デモ

こちらにソースコードがあるので、適当なフォルダにクローンしてください。

make setupが完了したらhttp://localhostをブラウザで開くと確認できます。

実装方法

Laravelのところから読みたい方はこちら
Angularのところから読みたい方はこちら

Laravel

必要なライブラリをインストールする

ライブラリを使ったほうが圧倒的に楽なので、ライブラリをインストールします。
Installationに従ってインストールしてください。

https://github.com/laravel-notification-channels/webpush

注意点として、このライブラリはGMP (GNU Multiple Precision)のphp extensionが必要ですので、各々の環境に合わせてインストールしてください。

Laradockを使って開発している場合は.envファイルの設定を変更することでインストールできます。
GMPと名のつく設定はいくつかありますが、最低限以下の項目をtrueにしてやればOKなはずです。
設定を変更したあとはdocker-compose buildし直すのを忘れずに。

Subscriptionを登録するControllerを実装する

フロントから渡されるPush Subscriptionを登録するコントローラーを実装していきます。

関連ソースコードは以下の通りです。

https://github.com/itigoore01/web-push-notification-example/blob/master/backend/app/Http/Controllers/Api/SubscriptionController.php
https://github.com/itigoore01/web-push-notification-example/blob/master/backend/routes/api.php#L27-L28

ポイントはログインユーザーのSubscriptionを更新すること。
通常、ユーザーIDをリクエストボディで受け取るような作りにしてはいけません。
自分以外のユーザーIDを指定して登録することで、ある人に送信したいプッシュ通知を赤の他人が受け取れてしまうからです。

もちろん、ユーザー認証がそもそも不要な、ブロードキャスト的な通知であれば問題ありません。
例えば不特定多数に新着ブログ投稿を送信するようなケースです。

Notificationを実装する

次にWeb Push用のNotificationクラスを実装していきます。

関連ソースコードは以下の通りです。

https://github.com/itigoore01/web-push-notification-example/blob/master/backend/app/Notifications/WebPush/WebPushMessage.php
https://github.com/itigoore01/web-push-notification-example/blob/master/backend/app/Notifications/MessageSent.php
https://github.com/itigoore01/web-push-notification-example/blob/master/backend/app/Notifications/Reminder.php

ここで重要なポイントです。

まずは以下のNotificationクラスをご覧ください。

コメントにもあるように、WebPushMessageはライブラリのものではなく独自に実装したものを使用しています。
といっても内容はシンプルにnotificationという名前でエンベロープしているだけです。

しかし、これがないとAngular標準のSwPushでは通知を表示してくれません

もちろん自前でServiceWorkerを実装すればこの限りではないですが、SwPushでサクッと試したいときにこれでドハマリしてしまうので注意が必要です。

以上がLaravelでの実装です。

その他

説明をWeb Pushだけに絞りましたが、それ以外にもAPIをCookie認証に変えていたり、サインイン・サインアップ・サインアウトのルーターを追加したり、通知をQueueに溜めてから送ったりと、他にもいろいろしているので、気になる方はソースコードを覗いてみてください。

Angular

必要なライブラリをインストールする

ServiceWorkerを自前で実装するのは手間なので、@angular/pwaという公式のライブラリを利用します。
PWA用のアセットキャッシュなど諸々をやってくれるものですが、その中にプッシュ通知を簡単に実装できるものも含まれています。

参考: Angular 日本語ドキュメンテーション – Service Workerを始める

以下のコマンドで簡単にインストールできます。

Subscriptionをサーバー(Laravel)に登録する

関連ソースコードは以下の通りです。

https://github.com/itigoore01/web-push-notification-example/blob/master/frontend/src/app/core/push/subscription.service.ts
https://github.com/itigoore01/web-push-notification-example/blob/master/frontend/src/app/home/pages/home-page/home-page.component.ts#L95-L142

先にサーバーに投げるためのサービスを実装しておきます。

次に、適当なコンポーネントでSubscriptionを受け取り、先程作成したSubscriptionServiceを使ってサーバーに登録します。
以下はサンプルのHomeComponentにある処理を簡略化したものです。
最低限これだけあれば問題なく動きます。

environment.applicationServerKeyの部分は、Laravelプロジェクトフォルダ直下の.envファイル内にあるVAPID_PUBLIC_KEYの値が入っている必要があります。
GitHubのサンプルではAPIで受け取るようになっていますが、environment.tsに書いてしまってもいいです。
ただしVAPID_PRIVATE_KEYのほうは間違っても書いてはいけませんし、ましてやgitにあげてしまってはいけません。
くれぐれも注意してください。

[2020/04/16 追記]
書き忘れていましたが、ng serveなどのコマンドではSwPush含め、ライブラリが提供してくれるサービスワーカーが機能しないので注意が必要です。 (ng serve --prodでも同様です)
ローカルでの実行は Angular 日本語ドキュメンテーション – Service Workerを始める を参照してください。

以上がAngularでの実装です。

その他

説明をWeb Pushだけに絞りましたが、サインイン・サインアップ画面や、Cookie認証でのAuth Guard実装など、他にもいろいろしているので、気になる方はソースコードを覗いてみてください。

ハマりどころ・注意点まとめ


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です