Come gestire le notifiche push Web in siti Web e PWA

0
554
RoBird/Shutterstock.com

Le notifiche push sono una vista comune nel Web moderno. Ti consentono di comunicare informazioni tempestive all'utente, anche se il tuo sito non è effettivamente aperto. Il browser dell'utente gestisce gli eventi push in arrivo e visualizza le notifiche utilizzando le superfici dell'interfaccia utente del sistema come il Centro operativo di Windows e la schermata di blocco di Android.

L'implementazione di Web Push nel tuo sito o PWA richiede la combinazione di due distinte API del browser. Il codice responsabile della sottoscrizione e della ricezione delle notifiche utilizza il componente Push API dei service worker. Questo codice viene eseguito continuamente in background e verrà richiamato dal browser quando è necessario gestire una nuova notifica.

Quando viene ricevuto un evento, l'operatore del servizio deve utilizzare l'API di notifica per visualizzare effettivamente la notifica. Questo crea un avviso visivo tramite interfacce a livello di sistema operativo.

Ecco una guida completa per far funzionare Web Push sul tuo sito. Partiamo dal presupposto che tu abbia già un componente lato server in grado di registrare gli abbonamenti push e inviare i tuoi avvisi.

The Service Worker

Cominciamo con l'addetto ai servizi. I service worker hanno più ruoli – possono memorizzare nella cache i dati per l'utilizzo offline, eseguire sincronizzazioni periodiche in background e agire come gestori delle notifiche. I service worker utilizzano un'architettura basata sugli eventi. Una volta registrato da un sito, il browser dell'utente richiamerà l'operatore di servizio in background quando vengono generati gli eventi a cui si iscrive.

Annuncio

Per Web Push, è necessario un evento principale: spingere. Questo riceve un oggetto PushEvent che ti consente di accedere al payload inviato dal server.

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

Il codice sopra configura un service worker in grado di reagire agli eventi push in arrivo. Si aspetta che il server invii payload JSON con questo aspetto:

{ "title": "Testo del titolo per la notifica", "body": "Questo è il testo più lungo della notifica." }

Quando viene ricevuto un evento push, l'operatore del servizio visualizza una notifica del browser chiamando la funzione showNotification() disponibile sulla sua proprietà self.registration. La funzione è racchiusa in una chiamata waitUntil() in modo che il browser attenda la visualizzazione della notifica prima di terminare l'operatore del servizio.

La funzione showNotification() accetta due argomenti: il testo del titolo della notifica e un oggetto options. In questo esempio vengono passate due opzioni, un testo più lungo e un'icona da visualizzare nella notifica. Sono disponibili molte altre opzioni che consentono di impostare modelli di vibrazione, badge personalizzati e requisiti di interazione. Non tutti i browser e i sistemi operativi supportano tutte le funzionalità esposte dall'API.

Completa il lato service worker del codice registrandolo nuovamente nel tuo JavaScript principale:

se (navigator.serviceWorker) { //sostituisci con il percorso del file del tuo service worker navigator.serviceWorker.register("/sw.js").catch(() => { console.error("Impossibile registrare l'addetto all'assistenza.") }); }

Questo codice dovrebbe essere eseguito a ogni caricamento di pagina. Si assicura che il browser supporti i service worker e quindi registri il file worker. I browser aggiorneranno automaticamente l'addetto al servizio ogni volta che la copia del server presenta differenze di byte rispetto alla versione attualmente installata.

Registrazione per abbonamenti push

Ora è necessario abbonarsi al browser per le notifiche push. Il seguente codice appartiene al tuo file JavaScript principale, al di fuori del service worker.

funzione asincrona subscribeToPush() { se (navigator.serviceWorker) {   const reg = attendi navigator.serviceWorker.getRegistration();   se (reg && reg.pushManager) {   const sottoscrizione = attendi reg.pushManager.getSubscription();   se (!abbonamento) {   const key = wait fetch("https://example.com/vapid_key"); const keyData = wait key.text();   const sub = attendi reg.pushManager.subscribe({ applicationServerKey: keyData, userVisibleOnly: true });   attendi recupero("https://example.com/push_subscribe", { metodo: "POST", intestazioni: {"Content-Type": "application/json"}, corpo: JSON.stringify({ endpoint: sub.endpoint, scadenzaTime: sub.expirationTime, chiavi: sub.toJSON().keys }) });   }   }   } } Pubblicità

Quindi chiama la tua funzione per iscrivere il browser alle notifiche push:

wait subscribeToPush();

Esaminiamo cosa sta facendo il codice di abbonamento. Le prime righe controllano la presenza di un addetto al servizio, recuperano la sua registrazione e rilevano il supporto per le notifiche push. pushManager non sarà impostato nei browser che non supportano il Web Push.

La chiamata a pushManager.getSubscription() restituisce una promessa che si risolve in un oggetto che descrive l'abbonamento push corrente del browser per il tuo sito. Se questo è già impostato, non è necessario ripetere l'iscrizione dell'utente.

Il vero flusso di sottoscrizione inizia con la richiesta di recupero delle chiavi VAPID del server. La specifica VAPID è un meccanismo che consente al browser di verificare che gli eventi push provengano effettivamente dal tuo server. Dovresti esporre un endpoint dell'API del server che fornisce una chiave VAPID. Questo è dato alla funzione pushManager.subscribe() in modo che il browser conosca la chiave per fidarsi. L'opzione userVisibleOnly separata indica che verranno visualizzate solo le notifiche che vengono visualizzate in modo visibile sullo schermo.

La chiamata pushManager.subscribe() restituisce un oggetto PushSubscription che descrive la nuova sottoscrizione. Questi dati vengono inviati al server in un'altra richiesta di recupero. In un'app reale, invierai anche l'ID dell'utente attivo in modo da poter collegare l'abbonamento push al suo dispositivo.

Pubblicità

Il tuo codice lato server per l'invio di una notifica push a un utente dovrebbe essere simile a questo:

  1. Interroga il tuo archivio dati per tutte le iscrizioni push collegate all'utente di destinazione.
  2. Invia il tuo payload di notifica all'endpoint indicato da ogni abbonamento, assicurandoti di includere le chiavi di autenticazione dell'abbonamento (chiavi nei dati inviati dal browser al momento della sottoscrizione). Firma l'evento con la stessa chiave VAPID che hai inviato al browser.

L'endpoint di ogni sottoscrizione farà riferimento alla piattaforma di consegna delle notifiche del fornitore del browser. Questo URL include già un identificatore univoco per l'abbonamento. Quando invii un payload all'endpoint, il processo in background del browser riceverà i dati e richiamerà il tuo service worker. Per Chrome su Android, il processo del browser è direttamente integrato con il demone di notifica del sistema.

Quando iscrivere l'utente?

Quando si impostano i flussi di sottoscrizione, ricordare che l'utente dovrà accettare una richiesta di autorizzazione del browser prima del completamento della registrazione. Molti browser nascondono o rifiutano automaticamente le richieste di autorizzazione non richieste; in ogni caso, chiedere a un utente di iscriversi nel momento in cui arriva sul tuo sito potrebbe non fornire il risultato che desideri.

Ottieni le migliori possibilità di successo della registrazione associando le richieste di sottoscrizione a un'azione diretta dell'utente. Valuta la possibilità di fornire un banner in-app che spieghi i vantaggi dell'attivazione delle notifiche e offra un'opzione “Abilita ora” pulsante. Puoi controllare se l'utente è già iscritto e nascondere il banner con la funzione pushManager.getSubscription() mostrata sopra.

Facendo clic sul pulsante di abilitazione dovrebbe richiamare la funzione di abbonamento. Il processo potrebbe richiedere alcuni secondi mentre il browser imposta la registrazione e le chiamate di rete vengono completate. La visualizzazione di uno spinner di caricamento durante questo periodo aiuterà a tenere informato l'utente.

Agli utenti dovrebbe anche essere dato un modo per annullare l'iscrizione. Sebbene possano revocare l'autorizzazione del browser in qualsiasi momento, alcuni utenti cercheranno un'opzione in-app, soprattutto se hanno installato il tuo sito come PWA.

Ecco una semplice cancellazione implementazione:

funzione asincrona annulla iscrizionePush() {   const reg = attendi navigator.serviceWorker.getRegistration(); const sottoscrizione = attendi reg.pushManager.getSubscription();   se (abbonamento) { attendere la sottoscrizione.unsubscribe(); wait fetch(`https://example.com/push_unsubscribe/${subscription.endpoint}`, {metodo: "DELETE"}); } altrimenti { //già iscritto }   } Pubblicità

La chiamata di unsubscribe() su una PushSubscription annulla l'abbonamento, riportando il browser al suo stato predefinito. Il tuo addetto all'assistenza smetterà di ricevere eventi push. L'endpoint dell'abbonamento viene inviato al tuo server in modo che tu possa rimuoverlo dal tuo archivio dati ed evitare di inviare dati a quello che ora è un URL morto.

Gestione di scadenze e rinnovi

Potresti aver notato la proprietà scadenzaTime sull'oggetto PushSubscription creato dal browser. Questo non sarà sempre impostato; quando lo è, il dispositivo smetterà di ricevere notifiche dopo questo tempo.

In pratica, scadutiTime non è attualmente utilizzato nei principali browser. I token prodotti da Chrome non scadono fino a quando non vengono annullati manualmente, quindi l'ora di scadenza è sempre nulla. Firefox non imposta neanche l'ora di scadenza, ma il suo servizio di notifica può sostituire gli abbonamenti durante la loro vita.

Puoi rispondere al browser modificando la tua sottoscrizione push attiva implementando l'evento pushsubscriptionchange nel tuo service worker. Sfortunatamente ci sono due versioni di questo evento: l'implementazione originale, attualmente utilizzata da Firefox, e la nuova v2, non ancora supportata in nessun browser.

Le specifiche originali hanno seri problemi di usabilità che rendono difficile rispondere all'evento. Quando ricevi un evento v1, il browser ha eliminato l'abbonamento originale e devi crearne uno nuovo manualmente. Il problema è che senza l'accesso all'abbonamento scaduto non è possibile emettere un “sostituire” richiesta al tuo server – non hai modo di accedere al vecchio URL dell'endpoint.

La specifica v2 risolve questo problema fornendo un evento con proprietà oldSubscription e newSubscription. Quando ricevi l'evento, il vecchio abbonamento è stato annullato ma puoi ancora accedere alle sue proprietà. La nuova sottoscrizione è ora creata per te dal browser.

Pubblicità

Ecco un esempio di implementazione di pushsubscriptionchange con la nuova specifica:

self.addEventListener("pushsubscriptionchange", e => { e.waitUntil(asincrono () => { attendi recupero("https://example.com/push_change", { metodo: "POST", intestazioni: { "Tipo di contenuto": "application/json" }, corpo: JSON.stringify({ auth: (e.newSubscription.toJSON().keys?.auth || null), endpoint: e.newSubscription.endpoint, endpointOld: e.oldSubscription.endpoint, scadenzaTime: e.newSubscription.expirationTime, p256dh: (e.newSubscription.toJSON().keys? .p256dh || null) }) }); }); });

Gli endpoint sono univoci, quindi il tuo server può cercare il vecchio abbonamento e aggiornare le sue proprietà con quelle del nuovo abbonamento. Se desideri aggiungere il supporto anche per la vecchia specifica, dovrai monitorare manualmente l'endpoint di sottoscrizione attivo al di fuori dell'API push. Memorizzazione in localStorage o IndexedDB ti consentirà di accedervi all'interno del tuo gestore pushsubscriptionchange in modo da poter chiedere al server di sostituire l'abbonamento.

La specifica rivista è molto più facile da implementare rispetto alla sua controparte precedente. Anche se non è ancora supportato nei browser, vale comunque la pena aggiungerlo al tuo addetto all'assistenza. Alcune righe di codice renderanno la tua gestione push a prova di futuro rispetto alle nuove versioni del browser.

Aggiunta di pulsanti di azione

Le notifiche push possono includere pulsanti interattivi che consentire all'utente di intraprendere azioni immediate. Ecco una chiamata showNotification() che ne crea una:

self.registration.showNotifica( "Notifica con azioni", { body: "Questa notifica ha un pulsante.", azioni: [ { azione: "/home", titolo: "Vai alla schermata Home", icona: "/home.png" } ] } );

Ogni notifica può includere più azioni, ciascuna con un'etichetta, un'icona e un'azione. Quest'ultima proprietà dovrebbe identificare un'azione che la tua app può avviare in risposta alla pressione dell'utente.

Quando l'utente tocca un'azione, l'operatore dell'assistenza riceve un evento Notificationclick:

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

Stiamo utilizzando la proprietà action per dichiarare un URI a cui l'utente può navigare. Una nuova scheda viene aperta nell'URI quando viene premuta la notifica. La chiamata a Notification.close() garantisce che anche la notifica venga ignorata. In caso contrario, alcune piattaforme costringeranno l'utente a rimuoverlo manualmente.

Riepilogo

L'implementazione di Web Push può sembrare scoraggiante se non hai lavorato con il relativo API prima. Oltre alle preoccupazioni tecniche, dovresti tenere l'esperienza dell'utente in prima linea nella tua mente e assicurarti di comunicare perché vale la pena abilitare le notifiche.

L'iscrizione e l'annullamento dell'iscrizione al push si verificano nella tua applicazione Il codice JavaScript principale di 8217, utilizzando le API navigator.serviceWorker. Il codice che risponde ai nuovi eventi push e visualizza le notifiche del browser risiede nell'operatore stesso.

Web Push è ora supportato dalla maggior parte dei principali browser Web, con Safari come eccezione principale. Ricorda che le notifiche verranno visualizzate in modo diverso in ogni browser e famiglia di sistemi operativi, quindi non dare per scontato che una particolare funzionalità dell'API showNotification() sarà universalmente disponibile.