ウェブサイト検索

PHPでウェブプッシュ通知を送信する方法


Web Push APIを使用すると、ウェブブラウザやAPIにプッシュ通知を送信できます。ほとんどのロジックはブラウザ内で発生しますが、通知を生成するためにはサーバーサイドのコンポーネントがまだ必要です。ここでは、PHPを使用してWeb Pushのバックエンドを実装する方法を説明します。

前提条件

このチュートリアルの目的のために、PHPでHTTP APIを作成する基本に精通していると仮定します。ウェブフレームワークを使用していくつかの公開エンドポイントを公開する必要があります。これらは、ブラウザ内のJavaScriptによってデバイスの登録と登録解除のために呼び出されます。

この記事では、ブラウザ側のコードやその動作については触れません。受信したプッシュイベントに応答し、ユーザーに通知を表示するサービスワーカーを作成する必要があります。

高レベルで見ると、Webプッシュのフローは次のようになります:

  1. ブラウザにプッシュサブスクリプションが登録されます。ブラウザはあなたのJavaScriptにユニークなエンドポイントURLを発行します。
  2. あなたのJavaScriptはサブスクリプションデータをサーバーに送信し、それが適用されるユーザーを特定します。
  3. バックエンドがプッシュ通知を送信する必要があるときは、ペイロードを作成し、サブスクリプションデータの一部として報告されたエンドポイントURLに送信します。
  4. ユーザーのブラウザは、ベンダーの通知配信プラットフォームを介してペイロードを受け取ります。あなたのJavaScriptサービスワーカーは、その結果のイベントを処理し、ブラウザの通知APIを使用してユーザーに警告を発します。

ここでは、ステップ1から3のサーバーサイドの実装方法を説明します。

セットアップする

私たちは、minishlinkによるweb-push Packagistパッケージを使用します。これにより、各ブラウザ通知プラットフォームとのやり取りが抽象化されるため、エンドポイントタイプを手動で区別する必要がなくなります。

Composer を使用してプロジェクトにパッケージを追加します:

composer require minishlink/web-push

最新のバージョンを使用するには、gmp、mbstring、curl、および openssl 拡張機能を備えた PHP 7.2 以上が必要です。古い PHP リリースを使用する必要がある場合は、互換性を維持するためにパッケージを以前のバージョンにロックしてください。

ライブラリは、通知を個別にまたはバッチとして送信するためのメソッドを持つコアのWebPushクラスを公開しています。サブスクリプションは、Subscriptionクラスのインスタンスとして表されます。

VAPIDキーの提供

標準準拠のWeb Pushエコシステムへの信頼は、VAPIDキーの使用を通じて強化されます。サーバーはブラウザに対して自らを認証するためにVAPIDキーのペアが必要です。公開鍵はAPIエンドポイントを介して公開されるべきです。

次のweb-pushパッケージを使用して、VAPIDキーセットを生成できます。

use MinishlinkWebPushVAPID;

$keyset = VAPID::createVapidKeys();

// public key - this needs to be accessible via an API endpoint

echo $keyset["publicKey"];

// private key - never expose this!

echo $keyset["privateKey"];

file_put_contents("vapid.json", json_encode($keyset));

システムのキーを生成し、それらを永続的な場所に保存します。クライアントサイドのJavaScriptが公開鍵を取得できるように、APIエンドポイントを追加します。これはブラウザのプッシュサブスクリプションを設定するために使用されます。ユーザーのデバイスは、対応するVAPIDプライベートキーで署名されたプッシュイベントを受け入れます。

プッシュ購読の登録

シーケンスの次のステップは、クライアントからプッシュサブスクリプションリクエストを受け取ることです。ブラウザーが新しいプッシュサブスクリプションを確認したら、あなたのJavaScriptはそのサブスクリプションのエンドポイントURLと関連する認証キーをサーバーに送信する必要があります。これらの詳細をユーザーのIDと一緒に保存しておくことで、後でユーザーに関連付けられたすべてのプッシュ登録デバイスを取得できるようになります。

このステップでは、実装がデータストレージ層やJavaScriptが送信する値に依存するため、コードサンプルは省略します。通常、これはPushSubscriptionオブジェクトのJSON表現になります。サブスクリプションを作成し、既存のものを置き換え、ユーザーが解除する際に削除を要求するための、単純なデータベースに基づくCRUD APIエンドポイントのセットが必要です。

定期購読の準備

クライアントが正常に登録されると、web-pushライブラリを使って通知を送信できるようになります。まず、WebPushクラスのインスタンスを作成します:

use MinishlinkWebPushWebPush;

$webPush = new WebPush([

"VAPID" => [

"subject" => "https://example.com",

"publicKey" => "VAPID_Public_Key_Here",

"privateKey" => "VAPID_Private_Key_Here"

]

]);

通知を送信するたびに、1つのWebPushインスタンスを再利用できます。ライブラリは、以前に生成したVAPIDキーセットで構成する必要があります。キーはBase64としてエンコードされる必要がありますが、ライブラリで生成する場合はこれが自動的に処理されます。

VAPIDのsubjectは、サーバーとその連絡先の詳細を識別するために使用されます。ウェブサイトのURLまたはmailto:メールアドレスリンクを提供できます。

次に、送信先のプッシュサブスクリプションを取得する必要があります。データアクセスシステムを使用して、送信したいユーザーに関連付けられたプッシュエンドポイントのURLを検索します。それぞれのサブスクリプションをSubscriptionインスタンスに変換します:

use MinishlinkWebPushSubscription;

// Get user's push data...

// SELECT * FROM push_subscriptions WHERE user_id = 123456

$subscription = Subscription::create([

"endpoint" => "https://fcm.google.com/...",

"contentEncoding" => "aesgcm",

"authToken" => "<auth token from JavaScript PushSubscription object>"

"keys" => [

"auth" => "<auth token from JavaScript PushSubscription object>",

"p256dh" => "<p256dh token from JavaScript PushSubscription object>"

]

]);

PushSubscription の auth プロパティは、ブラウザサービスによって使用される二つの異なる仕様に対応するために二度繰り返されています。P256DH プロパティは、サブスクリプションに設定される際に提供されるべきもう一つの公開鍵です。

web-pushライブラリは、ChromeとFirefoxのプッシュエンドポイントと互換性があります。現在の標準を満たす他のすべてのWeb Push実装でも動作します。

通知を送信する

では、WebPushとSubscriptionのインスタンスを組み合わせて通知を送信します:

$result = $webPush -> sendOneNotification(

$subscription,

json_encode([

"message" => "Demo notification",

"foo" => "bar"

])

);

sendOneNotification()を呼び出すことで、単一の通知が即座に配信されます。この場合のペイロードは、2つのプロパティを持つJSONエンコードされた配列です。送信するデータと使用するフォーマットはあなた次第です - あなたのJavaScriptクライアントはそのまま受け取り、必要に応じて解釈することができます。

通知を送信すると、操作が成功したかどうかを確認できる結果クラスが返されます。

if ($result -> isSuccess()) {

// all good

}

else {

// something went wrong

error_log($result -> getReason());

// provides raw HTTP response data

error_log($result -> getResponse());

}

エラーが発生した場合は、再試行するか配送をキャンセルするためのアクションを取ることができます。

通知サブスクリプションは、期限切れになることもあります。結果クラスで isSubscriptionExpired() メソッドを呼び出して、これが失敗の理由であるかどうかを判断できます。このシナリオでは、データベースからサブスクリプションを削除し、無効なエンドポイントに他の情報を送信しないようにしてください。

通知のバッチ処理

通知は、1つのメソッド呼び出しでまとめて配信できます。

$webPush -> queueNotification($subscription, ["msg" => "first"]);

$webPush -> queueNotification($subscription, ["msg" => "second"]);

foreach ($webPush -> flush() as $i => $result) {

echo ("Notification $i was " . ($result -> isSuccess() ? "sent" : "not sent"));

}

これは、短期間に大量の通知を送信する予定がある場合に便利です。すべてのペイロードをキューに入れ、web-pushが最適な方法で配信できるようにします。

flush() メソッドに整数を渡すことで、一度に送信される通知の数を制限できます:

$webPush -> flush(100); // send 100 messages

デフォルト値は1000です。

通知オプション

sendOneNotification()およびqueueNotification()は、第3の配列引数として以下のオプションを受け入れます:

  • TTL - ユーザーのデバイスにすぐに通知を送信できない場合、ブラウザの通知プラットフォームが通知を保持する期間を制御します。ユーザーのデバイスがオフラインの場合、プラットフォームはデフォルトで次の4週間配信を試みます。来週には関連性のない通知を送信する場合は、ユーザーが古いコンテンツを見ないようにTTLを調整してください。
  • 緊急度 - 通常、低、または非常に低いを値として受け入れます。一部のプラットフォームでは、通知配信の頻度を調整するためにこれを使用する場合があります。電池セーブモードに入るデバイスは、緊急でない通知の配信を停止することがあります。
  • batchSize - これは上で説明したflush()への引数と同じ効果があります。

WebPushコンストラクタの第二引数を使用して、デフォルトのオプション値を設定できます。

$webPush = new WebPush(["VAPID" => [...]], ["TTL" => 3600]);

要約

web-pushライブラリを使用すると、PHPでWeb Push通知を簡単に送信できます。さまざまなブラウザプラットフォームの上に抽象化層があり、バッチ処理、エラーハンドリング、すべてのWeb Push機能をサポートしています。

Web Pushメカニズムは、自己提供するリモートサーバー側コンポーネントに依存しているため、珍しいブラウザシステムです。これにより、不透明で技術的に感じられることがあります。実際には、シンプルなPHPバックエンドを作成するのは迅速かつ簡単です;フロントエンドの実装は通常、より時間がかかる側面であり、特にサービスワーカー機能を既に使用していない場合はそうなります。

関連記事: