How to send web push notifications with PHP - CloudSavvy IT
Web agency » Digital news » How to send web push notifications with PHP -

How to send web push notifications with PHP -

Web Push API allows you to send push notifications to web browsers and APIs. While most of the logic takes place in the browser, you still need a server-side component to generate your notifications. Here is how to implement a web push backend using PHP.

Preconditions

For the purposes of this tutorial, we'll assume that you know the basics of building HTTP APIs in PHP. You will need to expose a few public endpoints using your web infrastructure. These will be called up by your browser's JavaScript to register and deregister devices.

This article will not cover browser-side code or how it works. You will need to set up a service worker that responds to inbound push events and displays a notification to the user.

At a high level, the web push flow looks like this:

  1. A push subscription is saved in the browser. The browser sends a unique endpoint URL to your JavaScript.
  2. Your JavaScript sends subscription data to your server and identifies the user to which it applies.
  3. When your backend needs to send a push notification, create a payload and send it to the endpoint URL reported as part of the subscription data.
  4. The user's browser will receive the payload through the provider's notification delivery platform. Your JavaScript service worker handles the resulting event and uses the browser notification API to alert the user.

Here is how to implement the server side aspects of steps 1 to 3.

Get configuration

We will use the web-push Packagiste package by minishlink. This disregards interactions with each browser notification platform so you don't have to manually distinguish endpoint types.

Add the package to your project using Composer:

composer require minishlink / web-push

To use the latest version you need PHP 7.2 or higher with the gmp, mbstring, curl, and openssl extensions. If you must use an older version of PHP, lock the package to an older version to maintain compatibility.

The library exposes a kernel WebPush class with methods that allow you to send notifications individually or in batches. The subscriptions are represented by instances of the Subscription classify.

Provide VAPID keys

Confidence in the standards-compliant web push ecosystem is enhanced by the use of VAPID keys. Your server needs a VAPID key pair to be able to authenticate with browsers. The public key must be exposed through an API endpoint.

You can generate a VAPID key ring using the web-push wrap:

use MinishlinkWebPushVAPID;
 
$ keyset = VAPID::createVapidKeys();
 
// public key - this needs to be accessible via an API endpoint
threw out $ keyset["publicKey"];
 
// private key - never expose this!
threw out $ keyset["privateKey"];
 
File_put_contents("vapid.json", json_encode($ keyset));

Generate keys for your system and store them in a persistent location. Add an API endpoint so that your client-side JavaScript can retrieve the public key. This will be used to configure the browser push subscription. The user's device will accept incoming push events if they have been signed using the corresponding VAPID private key.

Registration of push subscriptions

The next step in the sequence is to receive push subscription requests from your customers. After the browser confirms a new push subscription, your JavaScript should send the URL of the subscription endpoint and associated authentication keys to your server. Store these details with the user ID so that you can retrieve any push enrolled devices linked to the user later.

We omit the code samples for this step because the implementation depends on your data storage layer and the values ​​sent by your JavaScript. Typically this will be a JSON representation of a PushSubscription object. You need a simple set of database-based CRUD API endpoints to create a subscription, replace an existing subscription, and request deletion when the user unsubscribes.

Preparation of subscriptions

Once a customer is successfully registered, you can start sending notifications using the web-push library. Start by creating an instance of the WebPush to classify:

use MinishlinkWebPushWebPush;
 
$ webPush = new WebPush([
    "VAPID" => [
        "subject" => "https://example.com",
        "publicKey" => "VAPID_Public_Key_Here",
        "privateKey" => "VAPID_Private_Key_Here"
    ]
]);

You can reuse one WebPush instance every time you send a notification. The library must be configured with the VAPID key ring that you generated earlier. The keys must be Base64 encoded, but this is handled for you if you create them with the library.

VAPID subject is used to identify your server and its contact details. You can provide a website URL or a mailto: email address link.

Then you need to grab the push subscription you are going to send to. Use your data access system to find the push endpoint URLs associated with the user you want to send to. Convert each subscription into one Subscription example:

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" => " token from JavaScript PushSubscription object> "
    "keys" => [
        "auth" => " token from JavaScript PushSubscription object> ",
        "p256dh" => " token from JavaScript PushSubscription object> "
    ]
]);

The auth property of the PushSubscription is repeated twice to deal with two different versions of the specification used by browser services. The P256DH property is another public key that must be provided when set on the subscription.

The web-push The library is compatible with Chrome and Firefox push endpoints. It will also work with any other web push implementation that meets the current standard.

Sending a notification

Now combine your WebPush et Subscription instances to send a notification:

$ result = $ webPush -> sendOneNotification(
    $ subscription,
    json_encode([
        "message" => "Demo notification",
        "foo" => "bar"
    ])
);

Appel sendOneNotification() provides immediate delivery for a single notification. The payload in this case is a JSON encoded array with two properties. It's up to you what data you send and what format you use - your JavaScript client receives it as is and can interpret it as needed.

Sending a notification returns a result class that allows you to check whether the operation was successful:

if ($ result -> isSuccess()) {
    // all good
}
else {
 
    // something went wrong
    error_log($ result -> getReason());
 
    // provides raw HTTP response data
    error_log($ result -> getResponse());
 
}

You can take steps to retry or cancel delivery if an error occurs.

Subscriptions to notifications may also expire. Call the isSubscriptionExpired() on a result class to determine if this is the reason for the failure. You can remove the subscription from your database in this scenario, making sure not to send anything else to a dead endpoint.

Batch notifications

Notifications can be grouped together to be delivered with a single method call:

$ webPush -> tailNotification($ subscription, ["msg" => "first"]);
$ webPush -> tailNotification($ subscription, ["msg" => "second"]);
 
foreach ($ webPush -> flush() as $i => $ result) {
    threw out ("Notification $i was " . ($ result -> isSuccess() ? "feels" : "not sent"));
}

This is useful when you know that you are going to send a large number of notifications in a short period of time. Queue all your payloads and let web-push deliver them optimally.

You can limit the number of notifications sent in one flush() passing an integer to the method:

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

The default is 1000.

Notification options

sendOneNotification() et queueNotification() accept the following options as the third argument of the array:

  • TTL - Controls how long the browser notification platform will keep the notification if it cannot be delivered to the user's device immediately. If the user's device is offline, the platforms will try to deliver it for the next four weeks by default. If you send a notification that won't be relevant next week, adjust the age accordingly so the user doesn't see outdated content.
  • urgency - Accept normal, low ou very-low as values. Some platforms may use it to adjust the frequency of notification delivery. Devices that enter battery saving mode may suspend delivery of non-urgent notifications.
  • batchSize - This has the same effect as the argument from flush() described above.

You can configure the default option values ​​using the second argument of the WebPush manufacturer:

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

In this section:

The web-push The library makes it easy to send web push notifications using PHP. You get a layer of abstraction on top of the different browser platforms that supports batch processing, error handling, and all web push functionality.

The web push mechanism is an unusual browser system because it relies on remote server-side components that you provide yourself. This can make it appear opaque and technical. In practice, creating a simple PHP backend is quick and easy; the front-end implementation is usually the most time-consuming aspect, especially if you're not already using service worker features.

★ ★ ★ ★ ★