Ajout de notifications push à une application Web

La messagerie push permet de réengager les utilisateurs de façon simple et efficace. Dans cet atelier de programmation, vous allez apprendre à ajouter des notifications push à votre application Web.

Points abordés

  • Abonnement et désabonnement d'un utilisateur aux messages push
  • Gérer les messages push entrants
  • Comment afficher une notification ?
  • Répondre aux clics sur des notifications

Prérequis

  • Chrome 52 ou version ultérieure
  • Serveur Web pour Chrome ou le serveur de votre choix
  • Un éditeur de texte
  • Connaissances de base en HTML, CSS, JavaScript et en développement Chrome
  • L'exemple de code (voir "Premiers pas")

Télécharger l'exemple de code

Vous avez deux options pour obtenir l'exemple de code dans cet atelier de programmation:

  • Clonez le dépôt Git :
git clone https://github.com/GoogleChrome/push-notifications.git
  • Téléchargez le fichier ZIP:

Télécharger le code source

Si vous téléchargez la source sous forme de fichier ZIP, vous pouvez la décompresser en créant un dossier racine : push-notifications-master.

Installer et vérifier le serveur Web

Vous êtes libre d'utiliser votre propre serveur Web, mais cet atelier de programmation est conçu pour bien fonctionner avec l'application Web Server pour Chrome. Si vous n'avez pas encore installé cette application, vous pouvez la télécharger depuis le Chrome Web Store:

Installer le serveur Web pour Chrome

Après avoir installé l'application Web Server pour Chrome, cliquez sur le raccourci Applications dans la barre de favoris:

Dans la fenêtre "Applications", cliquez sur l'icône Serveur Web:

Cette boîte de dialogue vous permet de configurer le serveur Web local:

Cliquez sur le bouton Choose folder (Choisir un dossier), puis sélectionnez le dossier app dans le dossier push-notifications que vous avez téléchargé. Cela vous permet de diffuser votre travail en cours via l'URL indiquée dans la section URL du ou des serveurs Web de la boîte de dialogue.

Sous Options, cochez la case Afficher automatiquement le fichier index.html comme indiqué ci-dessous:

Ensuite, arrêtez et redémarrez le serveur en faisant glisser le bouton Serveur Web: COMMENCÉ vers la gauche, puis vers la droite.

Cliquez sur l'URL du serveur Web pour accéder à votre site dans votre navigateur Web. La page qui s'affiche doit ressembler à celle-ci : 127.0.0.1:8887 peut s'afficher comme l'adresse :

0-push-lablab.png

Toujours mettre à jour le service worker

Pendant le développement, il est utile de vous assurer que votre service worker est toujours à jour et qu'il dispose des dernières modifications.

Pour configurer cette fonctionnalité dans Chrome, procédez comme suit:

  1. Accédez à l'onglet Push Codelab.
  2. Ouvrez les outils de développement: Ctrl-Maj-I sous Windows et Linux, Cmd-Option-I sous macOS.
  3. Sélectionnez le panneau Application, cliquez sur l'onglet Service Workers (Nœuds de calcul), puis cochez la case Update on Reload (Mettre à jour lors de l'actualisation). Lorsque cette case est cochée, le service worker est mis à jour de manière forcée à chaque actualisation de la page.

Code terminé

Votre répertoire app contient un fichier vide nommé sw.js. Ce fichier sera votre service worker. Pour le moment, il peut rester vide. Vous y ajouterez du code plus tard.

Tout d'abord, vous devez enregistrer ce fichier en tant que service worker.

Votre page app/index.html charge scripts/main.js. Vous enregistrez votre service worker dans ce fichier JavaScript.

Ajoutez le code suivant à scripts/main.js :

if ('serviceWorker' in navigator && 'PushManager' in window) {
  console.log('Service Worker and Push are supported');

  navigator.serviceWorker.register('sw.js')
  .then(function(swReg) {
    console.log('Service Worker is registered', swReg);

    swRegistration = swReg;
  })
  .catch(function(error) {
    console.error('Service Worker Error', error);
  });
} else {
  console.warn('Push messaging is not supported');
  pushButton.textContent = 'Push Not Supported';
}

Ce code vérifie si les service worker et les messages push sont compatibles avec votre navigateur. Si le fichier sw.js est compatible, il enregistrera votre fichier.

Essayer

Pour vérifier vos modifications, actualisez l'onglet Push Codelab dans le navigateur.

Consultez la console dans les outils pour les développeurs Chrome afin d'obtenir un Service Worker is registered message, comme suit:

Obtenir les clés de serveur d'applications

Pour travailler avec cet atelier de programmation, vous devez générer des clés de serveur d'applications. Pour ce faire, accédez au site Web associé sur le site web-push-codelab.glitch.me.

Vous pouvez générer une paire de clés publique et privée.

Push-codelab-04-companion.png

Copiez votre clé publique dans scripts/main.js en remplaçant la valeur <Your Public Key>:

const applicationServerPublicKey = '<Your Public Key>';

Important: Vous ne devez jamais placer votre clé privée dans votre application Web.

Code terminé

Pour le moment, le bouton Activer est désactivé et ne peut pas être sélectionné. En effet, nous vous recommandons de désactiver le bouton "Push" par défaut et de l'activer après avoir vérifié que la messagerie push est compatible avec le navigateur et que vous pouvez vérifier si l'utilisateur est actuellement abonné à la messagerie.

Vous devrez créer deux fonctions dans scripts/main.js :

  • initializeUI, pour vérifier si l'utilisateur est actuellement abonné
  • updateBtn, pour activer votre bouton et modifier le texte selon que l'utilisateur est abonné ou non

Ajoutez une fonction initializeUI à main.js comme suit:

function initializeUI() {
  // Set the initial subscription value
  swRegistration.pushManager.getSubscription()
  .then(function(subscription) {
    isSubscribed = !(subscription === null);

    if (isSubscribed) {
      console.log('User IS subscribed.');
    } else {
      console.log('User is NOT subscribed.');
    }

    updateBtn();
  });
}

Votre nouvelle méthode utilise le swRegistration de l'étape précédente, obtient la propriété pushManager à partir de celle-ci et appelle getSubscription() sur celle-ci.

pushManager. getSubscription() renvoie une promesse qui se résout avec l'abonnement actuel, le cas échéant. Sinon, elle renvoie null. Vous pouvez ainsi vérifier si l'utilisateur est déjà abonné, définir la valeur de isSubscribed, puis appeler updateBtn() pour mettre à jour le bouton.

Ajoutez la fonction updateBtn() à main.js:

function updateBtn() {
  if (isSubscribed) {
    pushButton.textContent = 'Disable Push Messaging';
  } else {
    pushButton.textContent = 'Enable Push Messaging';
  }

  pushButton.disabled = false;
}

Cette fonction active le bouton et modifie le texte du bouton en fonction du niveau d'abonnement de l'utilisateur.

La dernière chose à faire est d'appeler initializeUI() lorsque votre service worker est enregistré dans main.js :

navigator.serviceWorker.register('sw.js')
.then(function(swReg) {
  console.log('Service Worker is registered', swReg);

  swRegistration = swReg;
  initializeUI();
})

Essayer

Actualisez l'onglet Push Codelab. Vous devriez voir que le bouton Enable Push Messaging (Activer le message Push) est désormais activé. Vous pouvez cliquer dessus. Le User is NOT subscribed devrait s'afficher dans la console.

À mesure que vous progressez dans cet atelier de programmation, le texte du bouton devrait changer lorsque vous vous abonnez ou que vous vous désabonnez.

Code terminé

Pour le moment, le bouton Activer la messagerie push n'a aucune incidence. Résolvons à présent ce problème.

Dans la fonction initializeUI(), ajoutez un écouteur de clics pour votre bouton:

function initializeUI() {
  pushButton.addEventListener('click', function() {
    pushButton.disabled = true;
    if (isSubscribed) {
      // TODO: Unsubscribe user
    } else {
      subscribeUser();
    }
  });

  // Set the initial subscription value
  swRegistration.pushManager.getSubscription()
  .then(function(subscription) {
    isSubscribed = !(subscription === null);

    updateSubscriptionOnServer(subscription);

    if (isSubscribed) {
      console.log('User IS subscribed.');
    } else {
      console.log('User is NOT subscribed.');
    }

    updateBtn();
  });
}

Lorsque l'utilisateur clique sur le bouton, vous pouvez le désactiver pour vous assurer que l'utilisateur ne peut pas le cliquer une seconde fois, car l'abonnement aux messages push peut prendre un certain temps.

Appelez ensuite subscribeUser() si l'utilisateur n'est pas abonné. Pour ce faire, vous devez coller le code suivant dans scripts/main.js :

function subscribeUser() {
  const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
  swRegistration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: applicationServerKey
  })
  .then(function(subscription) {
    console.log('User is subscribed.');

    updateSubscriptionOnServer(subscription);

    isSubscribed = true;

    updateBtn();
  })
  .catch(function(error) {
    console.error('Failed to subscribe the user: ', error);
    updateBtn();
  });
}

Examinons la façon dont ce code fonctionne et comment il s'abonne à l'utilisateur pour les messages push.

Pour commencer, vous devez convertir la clé publique du serveur d'application en base64 sécurisée pour l'URL en UInt8Array, car il s'agit de l'entrée attendue de l'appel subscribe(). La fonction urlB64ToUint8Array() se trouve en haut de scripts/main.js.

Une fois la valeur convertie, vous appelez la méthode subscribe() sur le service worker (pushManager), en transmettant la clé publique de votre serveur d'applications et la valeur userVisibleOnly: true.

const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
swRegistration.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: applicationServerKey
})

Le paramètre userVisibleOnly vous garantit d'afficher une notification chaque fois qu'un message push est envoyé. Actuellement, cette valeur est obligatoire et doit être définie sur "true".

Le fait d'appeler subscribe() renvoie une promesse qui se résout après les étapes suivantes:

  1. L'utilisateur a autorisé l'affichage des notifications.
  2. Le navigateur a envoyé une requête réseau à un service d'envoi pour obtenir les données nécessaires à la génération d'un PushSubscription.

La promesse de subscribe() sera résolue avec un PushSubscription si ces étapes ont abouti. Si l'utilisateur ne donne pas son autorisation ou en cas de problème d'abonnement, la promesse sera rejetée avec une erreur. Vous obtenez la chaîne de promesses suivante dans votre atelier de programmation:

swRegistration.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: applicationServerKey
})
.then(function(subscription) {
  console.log('User is subscribed.');

  updateSubscriptionOnServer(subscription);

  isSubscribed = true;

  updateBtn();

})
.catch(function(err) {
  console.log('Failed to subscribe the user: ', err);
  updateBtn();
});

Ainsi, vous souscrivez un abonnement et vous considérez l'utilisateur comme abonné, ou vous détectez une erreur et vous le consignez dans la console. Dans les deux cas, vous appelez updateBtn() pour vous assurer que le bouton est réactivé et qu'il comporte le texte approprié.

Dans une application réelle, la fonction updateSubscriptionOnServer() vous permet d'envoyer les données d'abonnement à un backend. Toutefois, pour l'atelier de programmation, vous devez simplement afficher l'abonnement dans votre interface utilisateur. Ajoutez la fonction suivante à scripts/main.js :

function updateSubscriptionOnServer(subscription) {
  // TODO: Send subscription to application server

  const subscriptionJson = document.querySelector('.js-subscription-json');
  const subscriptionDetails =
    document.querySelector('.js-subscription-details');

  if (subscription) {
    subscriptionJson.textContent = JSON.stringify(subscription);
    subscriptionDetails.classList.remove('is-invisible');
  } else {
    subscriptionDetails.classList.add('is-invisible');
  }
}

Essayer

Accédez à l'onglet Push codelab, actualisez la page et cliquez sur le bouton. Une invite d'autorisation semblable à celle-ci doit s'afficher:

Si vous accordez l'autorisation, User is subscribed devrait être connecté à la console. Le texte de ce bouton est remplacé par Désactiver la messagerie push. Vous pouvez alors consulter l'abonnement au format JSON en bas de la page.

Code terminé

L'utilisateur ne parvient pas à traiter une demande que s'il bloque la demande d'autorisation. Cette opération nécessite une attention particulière, car si l'utilisateur bloque l'autorisation, votre application Web ne pourra pas afficher à nouveau l'invite d'autorisation et ne pourra pas s'abonner. Vous devez au moins désactiver le bouton d'activation pour que l'utilisateur sache qu'il ne peut pas être utilisé.

L'emplacement évident de ce scénario est la fonction updateBtn(). Il vous suffit de vérifier la valeur Notification.permission, comme suit:

function updateBtn() {
  if (Notification.permission === 'denied') {
    pushButton.textContent = 'Push Messaging Blocked';
    pushButton.disabled = true;
    updateSubscriptionOnServer(null);
    return;
  }

  if (isSubscribed) {
    pushButton.textContent = 'Disable Push Messaging';
  } else {
    pushButton.textContent = 'Enable Push Messaging';
  }

  pushButton.disabled = false;
}

Vous savez que si l'autorisation est denied, l'utilisateur ne peut pas s'abonner et vous ne pouvez rien faire de plus. Il est donc préférable de désactiver définitivement le bouton.

Essayer

Vous avez déjà accordé une autorisation pour votre application Web à l'étape précédente. Vous devez donc cliquer sur l'icône i dans la barre d'adresse et modifier l'autorisation Notifications sur Utiliser le paramètre général par défaut (Demander).

Une fois ce paramètre modifié, actualisez la page, cliquez sur Activer le message push, puis sélectionnez Bloquer dans la boîte de dialogue d'autorisation. Le bouton est désactivé et affiche le message Push Messages bloqués.

Vous pouvez désormais vous abonner à l'utilisateur en prenant soin des scénarios d'autorisation possibles.

Code terminé

Avant d'apprendre à envoyer un message push à partir de votre backend, vous devez réfléchir à ce qui se passera lorsqu'un utilisateur abonné recevra un message push.

Lorsque vous déclenchez un message push, le navigateur reçoit le message push, détermine l'objet du déploiement pour le service worker, l'active, puis envoie un événement "push". Vous devez écouter cet événement et afficher une notification si vous le souhaitez.

Ajoutez le code suivant au fichier sw.js :

self.addEventListener('push', function(event) {
  console.log('[Service Worker] Push Received.');
  console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);

  const title = 'Push Codelab';
  const options = {
    body: 'Yay it works.',
    icon: 'images/icon.png',
    badge: 'images/badge.png'
  };

  event.waitUntil(self.registration.showNotification(title, options));
});

Examinons ce code. Vous écoutez push événements dans votre service worker en ajoutant un écouteur d'événements:

self.addEventListener('push', ... );

(Si vous n'avez jamais joué avec les nœuds de calcul Web, self est probablement nouveau. Dans un fichier de service worker, self fait référence au service worker lui-même.

Lorsqu'un message push est reçu, l'écouteur d'événements est appelé, et vous créez une notification en appelant showNotification() sur la propriété registration du service worker. showNotification() nécessite un élément title. Vous pouvez également lui donner un objet options pour définir un corps de message, une icône et un badge. (Le badge n'est utilisé sur Android qu'au moment de la rédaction de ce document.)

const title = 'Push Codelab';
const options = {
  body: 'Yay it works.',
  icon: 'images/icon.png',
  badge: 'images/badge.png'
};
self.registration.showNotification(title, options);

La dernière chose à retenir concernant le traitement des événements push est event.waitUntil(). Cette méthode permet d'activer le navigateur afin de maintenir votre service worker actif en attendant que la promesse transmise soit résolue.

Pour faciliter la compréhension du code ci-dessus, vous pouvez le réécrire comme suit:

const notificationPromise = self.registration.showNotification(title, options);
event.waitUntil(notificationPromise);

Maintenant que vous avez passé l'événement "push", passons à un événement push.

Essayer

Grâce à la gestion des événements push dans le service worker, vous pouvez déclencher un événement factice fictif afin de tester ce qui se passe lorsqu'un message est reçu.

Dans votre application Web, abonnez-vous aux messages push et assurez-vous que User IS subscribed s'affiche dans la console. Dans le panneau Application des outils de développement, sous l'onglet Service Workers (Nœuds de calcul), cliquez sur le bouton Push:

Une fois que vous avez cliqué sur Push, une notification de ce type s'affiche:

Remarque: Si cette étape ne fonctionne pas, essayez d'annuler l'enregistrement du service worker à l'aide du lien Annuler l'enregistrement dans le panneau de l'application DevTools, puis attendez que le service worker soit arrêté, puis actualisez la page.

Code terminé

Si vous cliquez sur l'une de ces notifications, vous ne remarquerez rien. Vous pouvez gérer les clics sur les notifications en écoutant les événements notificationclick dans votre service worker.

Commencez par ajouter un écouteur notificationclick dans sw.js :

self.addEventListener('notificationclick', function(event) {
  console.log('[Service Worker] Notification click received.');

  event.notification.close();

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

Lorsque l'utilisateur clique sur la notification, l'écouteur d'événements notificationclick est appelé.

Le code ferme d'abord la notification sur laquelle l'utilisateur a cliqué:

event.notification.close();

Une nouvelle fenêtre ou un autre onglet s'ouvre et chargent l'URL https://developers.google.com/web. N'hésitez pas à modifier ce paramètre.

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

event.waitUntil() s'assure que le navigateur ne met pas fin au service worker avant l'affichage de la nouvelle fenêtre ou du nouvel onglet.

Essayer

Essayez de déclencher de nouveau un message push dans les outils de développement, puis cliquez sur la notification. Vous verrez alors la notification se fermer et un nouvel onglet s'ouvrira.

Vous avez vu que votre application Web pouvait afficher une notification à l'aide des outils de développement et vous avez appris à fermer la notification en un clic. L'étape suivante consiste à envoyer un message Push.

Normalement, il faudrait envoyer un abonnement d'une page Web à un backend. Le backend déclenche ensuite un message push en effectuant un appel d'API vers le point de terminaison de l'abonnement.

Cela n'est pas concerné par cet atelier de programmation, mais vous pouvez utiliser le site associé (web-push-codelab.glitch.me) pour déclencher un message push réel. Collez l'abonnement en bas de votre page:

Ensuite, collez ce contenu dans le site associé de la zone de texte Abonnement à envoyer:

Sous Texte à envoyer, ajoutez la chaîne que vous souhaitez envoyer avec le message push.

Cliquez sur le bouton Envoyer un message push.

Vous devriez ensuite recevoir un message push. Le texte que vous avez utilisé sera enregistré dans la console.

Vous pourrez ainsi tester l'envoi et la réception de données, et manipuler les notifications en conséquence.

L'application associée n'est qu'un serveur de nœuds qui utilise la bibliothèque Web-push pour envoyer des messages. Nous vous conseillons de consulter l'organisation Web-push-libs sur GitHub pour découvrir les bibliothèques disponibles pour envoyer des messages push en votre nom. Cette opération permet de gérer de nombreux détails susceptibles de déclencher des messages push.

Vous pouvez consulter l'ensemble du code du site associé sur cette page.

Code terminé

Ce qu'il manque, c'est la possibilité de désabonner un utilisateur. Pour ce faire, vous devez appeler unsubscribe() sur un PushSubscription.

Revenez au fichier scripts/main.js et modifiez l'écouteur de clics pushButton dans initializeUI() comme suit:

pushButton.addEventListener('click', function() {
  pushButton.disabled = true;
  if (isSubscribed) {
    unsubscribeUser();
  } else {
    subscribeUser();
  }
});

Notez que vous allez maintenant appeler une nouvelle fonction unsubscribeUser(). Dans cette fonction, vous obtenez l'abonnement actuel et appelez unsubscribe(). Ajoutez le code suivant à scripts/main.js :

function unsubscribeUser() {
  swRegistration.pushManager.getSubscription()
  .then(function(subscription) {
    if (subscription) {
      return subscription.unsubscribe();
    }
  })
  .catch(function(error) {
    console.log('Error unsubscribing', error);
  })
  .then(function() {
    updateSubscriptionOnServer(null);

    console.log('User is unsubscribed.');
    isSubscribed = false;

    updateBtn();
  });
}

Examinons cette fonction plus en détail.

Commencez par obtenir l'abonnement actuel en appelant getSubscription() :

swRegistration.pushManager.getSubscription()

Cela renvoie une promesse qui se résout avec PushSubscription s'il en existe une. Sinon, il renvoie null. S'il existe un abonnement, vous appelez unsubscribe() sur ce service, ce qui rend la PushSubscription non valide.

swRegistration.pushManager.getSubscription()
.then(function(subscription) {
  if (subscription) {
    // TODO: Tell application server to delete subscription
    return subscription.unsubscribe();
  }
})
.catch(function(error) {
  console.log('Error unsubscribing', error);
})

Le fait d'appeler unsubscribe() renvoie une promesse, car l'opération peut prendre un certain temps. Vous renvoyez cette promesse afin que le prochain then() de la chaîne attend que unsubscribe() se termine. Vous allez également ajouter un gestionnaire catch dans le cas où l'appel de unsubscribe() générerait une erreur. Vous pourrez ensuite mettre à jour votre interface utilisateur.

.then(function() {
  updateSubscriptionOnServer(null);

  console.log('User is unsubscribed.');
  isSubscribed = false;

  updateBtn();
})

Essayer

Vous devriez pouvoir appuyer sur Enable Push Messaging (Activer la messagerie push) ou Disable Push Messaging (Désactiver la messagerie push) dans votre application Web. Les journaux indiqueront alors à l'utilisateur s'il est abonné ou non.

Félicitations, vous avez terminé cet atelier de programmation !

Cet atelier de programmation vous explique comment ajouter des notifications push à votre application Web. Si vous souhaitez en savoir plus sur les fonctionnalités des notifications Web, consultez ces documents.

Si vous souhaitez déployer des notifications push sur votre site, vous pouvez ajouter des navigateurs plus anciens ou non conformes utilisant GCM. Consultez cette page pour en savoir plus.

Complément d'informations

Articles de blog pertinents