This article is shared under a Creative Commons Attribution 4.0 International license, BY Troland.

See Github addresses in updates to this serieshere.

This is chapter 9 on how JavaScript works.

Now let’s turn our attention to web push notifications: we’ll look at their construction, explore the process behind sending/receiving notifications, and finally share how we at SessionStack plan to leverage these features to create new product features.

Push notifications are already common on mobile. For some reason, push notifications on the web keep coming, even though most developers are clamoring for it.

An overview of the

Web push notifications allow users to choose when to get timely information from web applications. It aims to re-access interesting, important and timely information for users.

The push service is based on the service worker thread, which was described in detail in the previous article.

In this case, the service worker thread is used because it runs in the background and does not block the rendering of the interface. In the case of push notifications, this is important because it means that the code for push notifications is executed only when the user interacts with the push notification itself.

Notifications and notifications

Push and notification are two different interfaces.

  • Message push – Called when the message push server pushes a message to the service worker thread.
  • Message notification – Service worker threads or scripts in network applications perform operations to display message notifications to users.

Being pushed

There are three steps to implement notification push:

  • Interface – Add client logic for users to subscribe to push service. Write JavaScript code logic in the web application interface to allow users to register for the push message service.
  • Send messages – Implement interface calls on the server side to trigger push messages to user devices.
  • Receive messages – Process push messages once received on the browser side.

Now, let’s elaborate on the process.

Compatibility check

First, you need to check whether the current browser supports push notifications. Two simple checks can be used:

  • detectionnavigatorOn the objectserviceWorkerattribute
  • detectionwindowOn the objectPushManagerattribute

The detection codes are as follows:

if(! ('serviceWorker' in// The current browser does not support server worker threads, disable or hide the interfacereturn; 
}

if(! ('PushManager' inWindow)) {// The current browser does not support push service, disable or hide the interfacereturn; 
}
Copy the code

Register the service worker thread

Now, push notifications are supported. The next step is to register the service worker thread.

You should be familiar with how to register a service worker thread from previous articles.

Request authorization

After the service worker thread is registered, operations related to user subscriptions are performed. This requires the user’s authorization to push messages to them.

The authorized interface is fairly simple but has the disadvantage that the interface accepts a parameter that used to be a callback function but is now a Promise. There is no way to know which version of the interface is supported by the current browser, so compatibility processing is required.

Something like this:

function requestPermission() {
  return new Promise(function(resolve, reject) {
    const permissionResult = Notification.requestPermission(function(result) {// Use callback to handle deprecated interface version resolve(result); });if (permissionResult) {
      permissionResult.then(resolve, reject);
    }
  })
  .then(function(permissionResult) {
    if(permissionResult ! = ='granted') {
      throw new Error('Permission not granted.'); }}); }Copy the code

Call Notification. RequestPermission () will pop up to the users of the following prompts:

Granted, closed, and denied permissions are granted, default, and denied.

It should be noted that when the user clicks the disable button, the web application will not ask the user for authorization again until the user manually enables the change of authorization status. This option is hidden in the Settings panel.

Click the info button at the far left of the address bar to pop up the authorization popup.

Subscribe users via PushManager

Once the service worker threads to register and obtain authorization, can at the time of registration server thread by invoking the registration. The pushManager. The subscribe () to subscribers.

The entire code snippet is as follows (including the registration service worker thread) :

function subscribeUserToPush() {
  return navigator.serviceWorker.register('service-worker.js')
  .then(function(registration) {
    var subscribeOptions = {
      userVisibleOnly: true,
      applicationServerKey: btoa(
        'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U')};return registration.pushManager.subscribe(subscribeOptions);
  })
  .then(function(pushSubscription) {
    console.log('PushSubscription: ', JSON.stringify(pushSubscription));
    return pushSubscription;
  });
}
Copy the code

Registration. PushManager. Subscribe (options) one of the options object parameter, which contains a must or optional parameters:

  • userVisibleOnly: Whether the returned push subscription is visible only to subscribers. Must be set totrueOtherwise it will go wrong (due to historical reasons).
  • applicationServerKey: a Base64 encoded one that contains a public keyDOMStringString orArrayBufferThe push message server is used to authenticate the application server.

The push server needs to generate an application server key pair – the VAPID key pair – that is unique to the push server. They consist of a pair of public and private keys. The private key is stored secretly in the push server, and the public key is used to exchange communication with the client. These keys allow the push service to identify the subscriber’s application server and ensure that it is the same application server that triggers push messages to specified users.

You only need to generate the application private/public key pair once. Access web-push-codelab.glitch.me/ to generate key pairs.

When subscribing to the user, the browser passes the applicationServerKey (public key) to the push service, meaning that the push service binds the application server public key to the user’s PushSubscription.

The process is as follows:

  • The network application is loaded and then calledsubscribePass in the server public key.
  • The browser makes a request to the message push service to generate an endpoint information that is returned to the browser along with the key information.
  • The browser adds the end information to thesubscribe()Promise returnsPushSubscriptionIn the object.

Later, whenever a message needs to be pushed, an authentication header must be sent that contains information about the signature of the application server’s private key.

Whenever the push service receives a request for a push message, it authenticates by looking in the transport header for the public key already bound to the specified end (in step 2).

PushSubscription object

PushSubscription contains everything necessary to push information to a user’s device. It contains the following information:

{
  "endpoint": "https://domain.pushservice.com/some-id"."keys": {
    "p256dh":
"BIPUL12DLfytvTajnryr3PJdAgXS3HGMlLqndGcJGabyhHheJYlNGCeXl1dn18gSJ1WArAPIxr4gK0_dQds4yiI="."auth":"FPssMOQPmLmXWmdSTdbKVw=="}}Copy the code

The endpoint is the address of the push service. POST requests are made to this address when a message needs to be pushed.

The keys object contains the values used to encrypt the information data sent with the push message.

When the user subscribes and the PushSubscription object is returned, you need to save it on the push server. This allows you to store the subscription-related data in the database and then, from now on, send messages to the specified user based on the stored values in the database.

Being pushed

When you need to send messages to users, you first need to have a push message service. You tell the push service (invoked through the interface) what data it needs to push, who the message is being pushed to, and how to send the message under any conditions. Typically, these interface calls are done by the message push server.

Message push service

The push message service is used to receive push message request, verify the request and push the message to the specified user browser.

Please note that you do not control the notification push service – it is a third-party service. The server communicates with the push service only through an interface. Google’s FCM is one of the push messaging services.

The notification push service handles the core transactions. For example, when the browser is offline, push services queue messages and wait until the browser is connected to the Internet before sending their respective messages.

Developers can choose to have the browser use any of the push messaging services.

However, all push services have the same interface, so that different interfaces do not make push implementation more difficult.

The request URL address to process the message push can be obtained from the value of the endpoint property of the PushSubscription object.

Message push interface

The Push message service interface provides a way to send messages to users. This interface is an IETF standard Protocol called the Web Push Protocol, which defines how to invoke the Push message service.

Push messages have to be encrypted. This prevents push notification services from peeking into the data being sent. This is crucial because the client can decide which push service to use (possibly some untrusted and insecure push service).

Notification push parameters:

  • TTL- Defines how long a message will remain in the queue before it is deleted and cannot be transmitted.
  • Priority- Defines the Priority of each message, so that the message push service can only push high-priority messages to save power on the device.
  • Topic- Set the Topic name for push messages so that pending messages can be replaced with the same Topic name, so users do not receive expired messages once the device is activated.

Browser message push event

Whenever a message is sent to the above push service, the message remains in the waiting state until the following conditions occur:

  • Device network.
  • The duration of messages in the queue exceeded the set TTL. Procedure

When the push message service transmits a message to the browser, the browser receives it, decrypts it, and dispatches the push event to the service worker thread.

The browser can still execute the service worker thread even if the web page is not open. The following events occur:

  • The browser decrypts the received push message.
  • The browser wakes up the service worker thread.
  • Received by the service worker threadpushEvents.

Listening for push events is very similar to other event listeners written in JavaScript.

self.addEventListener('push'.function(event) {
  if (event.data) {
    console.log('This push event has data: ', event.data.text());
  } else {
    console.log('This push event has no data.'); }});Copy the code

One thing you need to understand about service worker threads is that their running time cannot be artificially controlled. Only the browser can wake it up and end it.

In the service worker thread, event.waitUntil(Promise) tells the browser that the service worker thread is processing the message until the promise is resolved, and that the browser should not abort the service worker thread if it wants to complete processing of the message.

The following is an example of handling push events:

self.addEventListener('push'.function(event) {
  var promise = self.registration.showNotification('Push notification! ');

  event.waitUntil(promise);
});
Copy the code

Call self. Registration. ShowNotification popup a notification to the user () and returns a promise, once the notification show complete parsing is complete.

You can visually set the showNotification(title, options) method to suit your needs. The title argument is a string and options is an object similar to the following:

{
  "/ /": "Visual options"."body": "<String>"."icon": "<URL String>"."image": "<URL String>"."badge": "<URL String>"."vibrate": "<Array of Integers>"."sound": "<URL String>"."dir": "<String of 'auto' | 'ltr' | 'rtl'>"."/ /": Behavioral options."tag": "<String>"."data": "<Anything>"."requireInteraction": "<boolean>"."renotify": "<Boolean>"."silent": "<Boolean>"."/ /": "Visual and behavioral options"."actions": "<Array of Strings>"."/ /": "Information options. No visual effects."."timestamp": "<Long>"
}
Copy the code

You can see more details about each option here.

Push notifications are a great way to inform users when they want to share urgent, important and pressing information.

The resources

  • Developers.google.com/web/fundame…
  • Developers.google.com/web/fundame…
  • Developers.google.com/web/fundame…
  • Developers.google.com/web/fundame…

The following are my own extensions.

Notify the processing

The service worker thread can handle this with code similar to the following:

self.addEventListener('notificationclick'.function(event) {
  console.log('[Service Worker] Notification click Received.');
  
  event.notification.close();

  event.waitUntil(clients.openWindow('https://developers.google.com/web/'));
});
Copy the code

conclusion

Nodejs can use the libraries here to build push servers.

The conditions required to make a web message push are:

  • Message push server (invokes the message push service and generates the VAPID public and private key pairs).
  • Check the compatibility of the browser, obtain authorization, use the public key generated by the push server, generate a subscription object, and save the subscription object to the push server.
  • Message push service (third-party service).

Here’s a flow chart:

Make an advertisement ^.. ^

Toutiao is hiring! Send resume to [email protected], you can take the fast internal push channel, long-term effective! The JD of the international PGC department is as follows: c.xiumi.us/board/v5/2H… , can also be pushed inside other departments!

See Github addresses in updates to this serieshere.