Comment gérer les notifications Web Push dans les sites Web et les PWA

0
160
RoBird/Shutterstock.com

Notifications push sont monnaie courante sur le Web moderne. Ils vous permettent de communiquer des informations en temps opportun à l'utilisateur, même si votre site n'est pas réellement ouvert. Le navigateur de l'utilisateur gère les événements push entrants et affiche les notifications à l'aide de surfaces d'interface utilisateur système telles que Windows Action Center et Android lockscreen.

La mise en œuvre de Web Push dans votre site ou PWA nécessite la combinaison de deux API de navigateur distinctes. Le code responsable de l'abonnement et de la réception des notifications utilise le composant API Push des service workers. Ce code s'exécute continuellement en arrière-plan et sera invoqué par le navigateur lorsqu'une nouvelle notification doit être traitée.

Lorsqu'un événement est reçu, le service worker doit utiliser l'API de notification pour afficher réellement la notification. Cela crée une alerte visuelle via des interfaces au niveau du système d'exploitation.

Voici un guide complet pour faire fonctionner Web Push sur votre site. Nous supposerons que vous avez déjà un composant côté serveur qui peut enregistrer des abonnements push et envoyer vos alertes.

Le Service Worker

Commençons par le technicien de maintenance. Les techniciens de maintenance ont plusieurs rôles – ils peuvent mettre en cache les données pour une utilisation hors ligne, exécuter des synchronisations périodiques en arrière-plan et agir en tant que gestionnaires de notifications. Les techniciens de maintenance utilisent une architecture événementielle. Une fois enregistré par un site, le navigateur de l'utilisateur appelle le service worker en arrière-plan lorsque les événements auxquels il s'abonne sont générés.

Publicité

Pour Web Push, un événement principal est nécessaire : pousser. Celui-ci reçoit un objet PushEvent qui vous permet d'accéder à la charge utile envoyée depuis le serveur.

self.addEventListener("push", e => {   const payload = JSON.parse(e.data.text());   e.waitUntil(self.registration.showNotification( payload.title, { corps : payload.body, icône : "/icon.png" } ));   });

Le code ci-dessus configure un service worker capable de réagir aux événements push entrants. Il s'attend à ce que le serveur envoie des charges utiles JSON ressemblant à ceci :

{ "title": "Titre text for the notification", "body" :"Ceci est le texte le plus long de la notification." }

Lorsqu'un événement push est reçu, le service worker affiche une notification de navigateur en appelant la fonction showNotification() disponible sur sa propriété self.registration. La fonction’est enveloppée dans un appel waitUntil() afin que le navigateur attende que la notification s'affiche avant de terminer le service worker.

La fonction showNotification() prend deux arguments : le texte du titre de la notification et un objet d'options. Deux options sont transmises dans cet exemple, un corps de texte plus long et une icône à afficher dans la notification. De nombreuses autres options sont disponibles pour vous permettre de configurer des modèles de vibration, des badges personnalisés et des exigences d'interaction. Tous les navigateurs et systèmes d'exploitation ne prennent pas en charge toutes les fonctionnalités exposées par l'API.

Complétez la partie service worker du code en l'enregistrant dans votre code JavaScript principal :

si (navigator.serviceWorker) { //remplacez par le chemin d'accès à votre fichier de service worker navigator.serviceWorker.register("/sw.js").catch(() => { console.error("Impossible d'enregistrer le service worker.") }); }

Ce code doit s'exécuter à chaque chargement de page. Il s'assure que le navigateur prend en charge les techniciens de maintenance, puis enregistre le fichier de travail. Les navigateurs mettront automatiquement à jour le service worker chaque fois que la copie du serveur présente des différences d'octets par rapport à la version actuellement installée.

Inscription pour les abonnements Push

Vous devez maintenant abonner le navigateur aux notifications push. Le code suivant appartient à votre fichier JavaScript principal, en dehors du service worker.

fonction asynchrone SubscribeToPush() { si (navigator.serviceWorker) {   const reg = wait navigator.serviceWorker.getRegistration();   si (reg && reg.pushManager) {   const subscription = wait reg.pushManager.getSubscription();   si (!abonnement) {   clé const = wait fetch("https://example.com/vapid_key"); const keyData = wait key.text();   const sub = wait reg.pushManager.subscribe({ applicationServerKey : keyData, userVisibleOnly : true });   attendre la récupération("https://example.com/push_subscribe", { méthode : "POST", en-têtes : {"Content-Type" :"application/json"}, corps : JSON.stringify({ endpoint : sub.endpoint, expirationTime : sub.expirationTime, keys : sub.toJSON().keys }) });   }   }   } } Publicité

Appelez ensuite votre fonction pour abonner le navigateur aux notifications push :

wait subscriptionToPush();

Voyons en revue ce que fait le code d'abonnement. Les premières lignes vérifient la présence d'un service worker, récupèrent son enregistrement et détectent la prise en charge des notifications push. pushManager ne sera pas configuré dans les navigateurs qui ne prennent pas en charge Web Push.

L'appel de pushManager.getSubscription() renvoie une promesse qui se résout en un objet décrivant l'abonnement push actuel du navigateur pour votre site. Si cela est déjà défini, nous n'avons pas besoin de réinscrire l'utilisateur.

Le véritable flux d'abonnement commence par la demande d'extraction des clés VAPID du serveur. La spécification VAPID est un mécanisme qui permet au navigateur de vérifier que les événements push proviennent réellement de votre serveur. Vous devez exposer un point de terminaison d'API de serveur qui fournit une clé VAPID. Ceci est donné à la fonction pushManager.subscribe() afin que le navigateur connaisse la clé de confiance. L'option séparée userVisibleOnly indique que nous n'afficherons que les notifications qui s'afficheront visiblement à l'écran.

L'appel pushManager.subscribe() renvoie un objet PushSubscription décrivant votre nouvel abonnement. Ces données sont envoyées au serveur dans une autre requête d'extraction. Dans une vraie application, vous enverriez également l'ID de l'utilisateur actif afin que vous puissiez lier l'abonnement push à son appareil.

Publicité

Votre code côté serveur pour envoyer une notification push à un utilisateur devrait ressembler à ceci :

  1. Interrogez votre magasin de données pour tous les abonnements push liés à l'utilisateur cible.
  2. Envoyez votre charge utile de notification au point de terminaison indiqué par chaque abonnement, en veillant à inclure les clés d'authentification de l'abonnement (clés dans les données envoyées par le navigateur lors de l'abonnement). Signez l'événement avec la même clé VAPID que vous avez envoyée au navigateur.

Le point de terminaison de chaque abonnement référencera la plate-forme de livraison des notifications du fournisseur du navigateur. Cette URL comprend déjà un identifiant unique pour l'abonnement. Lorsque vous envoyez une charge utile au point de terminaison, le processus d'arrière-plan du navigateur recevra éventuellement les données et appellera votre service worker. Pour Chrome sur Android, le processus du navigateur est directement intégré au démon de notification système.

Quand inscrire l'utilisateur ?

Lors de la configuration des flux d'abonnement, n'oubliez pas que l'utilisateur devra accuser réception d'une invite d'autorisation du navigateur avant la fin de l'enregistrement. De nombreux navigateurs masquent ou rejettent automatiquement les demandes d'autorisation non sollicitées ; dans tous les cas, demander à un utilisateur de s'abonner au moment où il atterrit sur votre site peut ne pas donner le résultat souhaité.

Vous obtenez les meilleures chances de réussite de l'inscription en couplant les demandes d'abonnement à une action directe de l'utilisateur. Envisagez de fournir une bannière dans l'application qui explique les avantages de l'activation des notifications et propose un “Activer maintenant” bouton. Vous pouvez vérifier si l'utilisateur est déjà abonné et masquer la bannière avec la fonction pushManager.getSubscription() illustrée ci-dessus.

Cliquer sur le bouton d'activation devrait appeler votre fonction d'abonnement. Le processus peut prendre quelques secondes pendant que le navigateur configure l'enregistrement et que vos appels réseau se terminent. L'affichage d'une flèche de chargement pendant cette période aidera à tenir l'utilisateur informé.

Les utilisateurs devraient également avoir un moyen de se désinscrire. Bien qu'ils puissent révoquer l'autorisation du navigateur à tout moment, certains utilisateurs rechercheront une option dans l'application, surtout s'ils ont installé votre site en tant que PWA.

Voici un simple désabonnement. mise en œuvre :

fonction asynchrone unsubscribePush() {   const reg = wait navigator.serviceWorker.getRegistration(); const subscription = wait reg.pushManager.getSubscription();   si (abonnement) { attendez l'abonnement.unsubscribe(); wait fetch(`https://example.com/push_unsubscribe/${subscription.endpoint}`, {méthode : "DELETE"}); } sinon { //déjà abonné }   } Publicité

L'appel de unsubscribe() sur un PushSubscription annule l'abonnement, ramenant le navigateur à son état par défaut. Votre technicien de maintenance cessera de recevoir des événements push. Le point de terminaison de l'abonnement est envoyé à votre serveur afin que vous puissiez le supprimer de votre magasin de données et éviter d'envoyer des données vers ce qui est maintenant une URL morte.

Gestion des expirations et des renouvellements

Vous avez peut-être remarqué la propriété expirationTime sur l'objet PushSubscription créé par le navigateur. Cela ne sera pas toujours défini ; quand c'est le cas, l'appareil cessera de recevoir des notifications après ce délai.

En pratique, expirationTime n'est actuellement pas utilisé dans les principaux navigateurs. Les jetons produits par Chrome n'expirent qu'une fois désabonnés manuellement, donc expirationTime est toujours nul. Firefox ne définit pas non plus l'expirationTime, mais son service de notification peut remplacer les abonnements pendant leur durée de vie.

Vous pouvez répondre au navigateur qui modifie votre abonnement push actif en implémentant l'événement pushsubscriptionchange dans votre service worker. Malheureusement, il existe deux versions de cet événement : l'implémentation d'origine, actuellement utilisée par Firefox, et la nouvelle v2, qui n'est encore prise en charge par aucun navigateur.

La spécification d'origine présente de sérieux problèmes d'utilisation qui rendent difficile la réponse à l'événement. Lorsque vous recevez un événement v1, le navigateur a supprimé l'abonnement d'origine et vous devez en créer manuellement un nouveau. Le problème est que sans accès à l'abonnement expiré, vous ne pouvez pas émettre de “remplace” demande à votre serveur – vous n'avez aucun moyen d'accéder à l'ancienne URL du point de terminaison.

La spécification v2 résout ce problème en fournissant un événement avec les propriétés oldSubscription et newSubscription. Lorsque vous recevez l'événement, l'ancien abonnement a été annulé mais vous pouvez toujours accéder à ses propriétés. Le nouvel abonnement est maintenant créé pour vous par le navigateur.

Publicité

Voici un exemple d'implémentation de pushsubscriptionchange avec la nouvelle spécification :

self.addEventListener("pushsubscriptionchange", e => { e.waitUntil(async () => { attendre la récupération("https://example.com/push_change", { méthode : “POST”, en-têtes : { "Type de contenu" : "application/json" }, corps : JSON.stringify({ auth: (e.newSubscription.toJSON().keys?.auth || null), point de terminaison : e.newSubscription.endpoint, endpointOld : e.oldSubscription.endpoint, expirationTime : e.newSubscription.expirationTime, p256dh : (e.newSubscription.toJSON().keys? .p256dh || nul) }) }); }); });

Les points de terminaison sont uniques afin que votre serveur puisse rechercher l'ancien abonnement et mettre à jour ses propriétés avec celles du nouvel abonnement. Si vous souhaitez également ajouter la prise en charge de l'ancienne spécification, vous devrez suivre manuellement le point de terminaison d'abonnement actif en dehors de l'API push. Le stocker dans localStorage ou IndexedDB vous permettra d'y accéder dans votre gestionnaire pushsubscriptionchange afin que vous puissiez demander au serveur de remplacer l'abonnement.

La spécification révisée est beaucoup plus facile à mettre en œuvre que son ancienne contrepartie. Même s'il n'est pas encore pris en charge dans les navigateurs, il vaut quand même la peine de l'ajouter à votre service worker. Quelques lignes de code assureront la pérennité de votre traitement push contre les nouvelles versions de navigateur.

Ajout de boutons d'action

Les notifications push peuvent inclure des boutons interactifs qui laisser l'utilisateur prendre des mesures immédiates. Voici un appel showNotification() qui en crée un :

self.registration.showNotification( "Notification avec actions", { corps : "Cette notification a un bouton.", actions : [ { action : "/home", titre : "Aller à l'écran d'accueil", icône : "/home.png" } ] } );

Chaque notification peut inclure plusieurs actions, chacune avec une étiquette, une icône et une action. Cette dernière propriété doit identifier une action que votre application peut lancer en réponse à la pression de l'utilisateur.

Lorsque l'utilisateur appuie sur une action, votre technicien de maintenance reçoit un événement notificationclick :

self.addEventListener("notificationclick", e => { const uri = e.action; const notification = e.notification; notification.close(); clients.openWindow(`${self.location.origin}${action}`); }); Publicité

Nous utilisons la propriété action pour déclarer un URI vers lequel l'utilisateur peut naviguer. Un nouvel onglet s'ouvre sur l'URI lorsque la notification est enfoncée. L'appel de notification.close() garantit que la notification est également rejetée. Sinon, certaines plates-formes obligeront l'utilisateur à le faire glisser manuellement.

Résumé

La mise en œuvre de Web Push peut sembler intimidante si vous n'avez pas travaillé avec les API avant. Plus que les préoccupations techniques, vous devez garder l'expérience utilisateur au premier plan de votre esprit et vous assurer de communiquer pourquoi il vaut la peine d'activer les notifications.

L'abonnement et la désabonnement au push se produisent dans votre application’ 8217;s principal code JavaScript, en utilisant les API navigator.serviceWorker. Le code qui répond aux nouveaux événements push et affiche les notifications du navigateur réside dans le service worker lui-même.

Le Web Push est désormais pris en charge par la plupart des principaux navigateurs Web, Safari étant l'exception la plus importante. N'oubliez pas que les notifications seront rendues différemment dans chaque famille de navigateurs et de systèmes d'exploitation, donc ne supposez pas qu'une fonctionnalité particulière de l'API showNotification() sera universellement disponible.