今では多くのサイトで実現しているPush機能。
ググって見つけたサイトなんて一見さん目的なのに、「許可する」にするなんてしないでしょ。
どれぐらいの人が活用しているのだろうか。
子供とか知らずにクリックしそうで消えて欲しい機能の1つ。
ユーザにとって邪魔でも技術的には興味がある。
また子供との偽LINEの通知の仕組みに使いたいと思ってたんだよね。
手段には大きく分けて二種類あるようだ。
比較項目 | Firebase Cloud Messaging (FCM)を使う | Web Push APIを直接使う |
---|---|---|
実装の複雑さ | 比較的簡単(SDKが提供されている) | やや複雑(低レベルAPIを直接扱う) |
複数環境 | ◎(Web, Android, iOS等を統一APIで対応) | △(各プラットフォーム別に実装が必要) |
信頼性・安定性 | ◎(Googleのインフラを利用) | ○(ブラウザの実装に依存) |
スケーラビリティ | ◎(大量の通知を効率的に処理) | △(自前で仕組みを構築する必要あり) |
分析機能 | ◎(開封率等の分析が可能) | ×(自前で実装が必要) |
独立性 | ×(Googleサービスに依存) | ◎(特定サービスに依存しない) |
プライバシー | △(Googleサーバーを経由) | ○(サードパーティを経由しない) |
コスト | △(大規模利用では有料の可能性) | ◎(基本的に無料) |
追加機能 | ◎(トピック購読、ターゲティング等) | △(自前で実装が必要) |
適している用途 | 大規模サービス、複数プラットフォーム | 小規模サービス、独立性重視、シンプル |
Firebase Cloud Messaging (FCM) を使うのが一般的っぽいけど、仕組みを理解したいので、Web Push APIを直接使用して実装してみる。
FCMを使わない場合(Web Push APIを直接使用)
そもそも構造が分からなかったので、PlantUMLでLLMに書いてもらった。
- 事前通知フェーズ
- 初期登録フェーズ
- 通知フェーズ
があるらしい。
ソースコード構成は次のようになり大量だ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/your_web_root/ ├── index.html # メインのHTMLファイル ├── main.js # クライアント側のJavaScript ├── service-worker.js # Service Workerの実装 ├── icon.png # 通知用アイコン ├── badge.png # 通知用バッジ ├── get-vapid-public-key.php # 公開鍵を提供するPHP ├── save-subscription.php # 購読情報を保存するPHP ├── generate-vapid-keys.php # VAPID鍵を生成するPHP ├── send-notification.php # 通知を送信するPHP ├── composer.json # Composerの設定ファイル ├── vendor/ # Composerの依存ライブラリ ├── keys/ # VAPID鍵を保存するディレクトリ │ ├── public_key.txt # 公開鍵 │ └── private_key.txt # 秘密鍵 └── subscriptions/ # 購読情報を保存するディレクトリ └── [hash].json # 各ユーザーの購読情報 |
ソースコードは最後にリンクしている。
事前準備フェーズ(VAPID鍵の生成)
APID鍵は、プッシュサービス(Google/Mozilla等)に対して、通知を送信するサーバーが正当な送信者であることを証明する役割をもつ。
Composerをインストール
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ composer init --name="your-name/web-push-demo" --description="Web Push Notification Demo" --author="Your Name $ composer require minishlink/web-push ... - Installing guzzlehttp/guzzle (7.9.3): Extracting archive - Installing minishlink/web-push (v9.0.2): Extracting archive 7 package suggestions were added by new dependencies, use `composer suggest` to see details. Generating autoload files 8 packages you are using are looking for funding. Use the `composer fund` command to find out more! No security vulnerability advisories found. Using version ^9.0 for minishlink/web-push |
これで「composer.json」と「composer.lock」が作成され「vendor/autoload.php」が正しく生成される。
次に、VAPID鍵を生成するために「generate-vapid-keys.php」 を実行する。
1 2 3 4 5 6 |
% php generate-vapid-keys.php VAPID鍵が生成され、保存されました。 公開鍵: BODVnmstj<中略>GU4rJWmmrtzc70z_Cg-_2ooeKcBxhPmb7qvi6LhDfg3qfas 秘密鍵: zTX88oUlq<中略>_vm9E8BfHrZU1KxGT7FpUw |
これにより「keys」ディレクトリが作成され、その中に「public_key.txt」と「private_key.txt」が生成される。
最後に「keys」と「subscriptions」ディレクトリに書き込み権限を付与しておく。
1 |
% chmod 755 keys subscriptions |
ディレクトリのパーミッション設定
「keys」と「subscriptions」ディレクトリに書き込み権限を付与する。
1 |
chmod 755 keys subscriptions |
動作確認
ユーザ視点の作業は簡単だ。
- ブラウザで
index.html
にアクセス - 「通知を許可する」ボタンをクリックして通知を許可
- 「subscriptions」ディレクトリにJSONファイルが作成されていることを確認
- 「send-notification.php」を実行して通知が届くか確認:
1 2 3 |
% php send-notification.php {"status":"completed","success":1,"failure":0} |
覚えておくこと
通知の設定が無効になっていたり、キャッシュが溜まっており、非常に苦労したので備忘録。
まずは通知の有効化になっているか確認する
Windowsの通知設定
- Windowsの設定 → システム → 通知とアクション
- 「アプリやその他の送信者からの通知を取得する」がオンになっているか確認
- Chromeの通知が許可されているか確認
Chromeの通知設定
- Chromeの設定 → プライバシーとセキュリティ → サイトの設定 → 通知
- 通知の送信をサイトに許可するがオンになっているか確認
- 「サイトURL」 が許可リストに入っているか確認
Service Workerキャッシュをクリアする方法
方法1: ブラウザの開発者ツールから
- F12 で開発者ツールを開く
- Application タブ → Service Workers
- 該当のService Workerの Unregister をクリック
- ページを リロード
方法2: ブラウザの設定から
- Ctrl+Shift+Delete でブラウザデータを削除
- キャッシュされた画像とファイル をチェック
- データを削除
方法3: プライベートモードで確認
- Ctrl+Shift+N でシークレットウィンドウを開く
- そこでサイトにアクセスして動作確認
おわりに
何とか動いたが、Chromeがタスクバーにないと通知を受け取る事ができない。
5年前から動かしたかったので、動く仕組みができて嬉しい。
これも100の作ってみたかった一つだ。残りの99個は知らないけれど。
ソースコード
LLMで書いたサンプルだから公開しなくても良いかもだけど、設定方法等を忘れそうなので置いておく。
