Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

Web Push Notifications Olga Petrova Software Engineer @ Sencha

Slide 3

Slide 3 text

What You Will Learn • Definition & Concept • Implementation • Framework API • State of Specifications & Browser support

Slide 4

Slide 4 text

Definition & Concept

Slide 5

Slide 5 text

Web Push Notifications Gives web applications the ability to receive messages pushed to them from a server at any time

Slide 6

Slide 6 text

Target Engage users with urgent and relevant notifications and motivate them to return to the application

Slide 7

Slide 7 text

Commercial Value • Increase user engagement • Increase web app value • Replace a native app with a web app

Slide 8

Slide 8 text

Web Push + page/browser is inactive/closed - encryption - message size/count limit - requires display of a notification - active web page + no encryption + no message size/count limit + no notification display required Web Sockets + real-time communication vs

Slide 9

Slide 9 text

Implementation

Slide 10

Slide 10 text

5 Players WebApp Service Worker Browser Push Server App Server

Slide 11

Slide 11 text

Web Push Message Encryption for Web Push Voluntary Application Server Identification for Web Push Push API Specifications Notification API WebApp Service Worker Browser Push Server App Server

Slide 12

Slide 12 text

Round 1: Service Worker Registration WebApp Service Worker Browser Push Server App Server Register ServiceWorkerRegistration Page Load

Slide 13

Slide 13 text

Round 1: ServiceWorker Registration if ('serviceWorker' in navigator) { if ('PushManager' in window) { navigator.serviceWorker.register('ServiceWorker.js').then(function(registration) { //state initializing }); .catch(function() { //error handling }); } else { //error handling } } else { //error handling } WebApp

Slide 14

Slide 14 text

Round 2: Subscription WebApp Service Worker Browser Push Server App Server Subscribe PushSubscription Subscribe push subscription save PushSubscription User is ready to subscribe

Slide 15

Slide 15 text

Round 2: Subscription navigator.serviceWorker.ready.then(function(registration) { registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: urlBase64ToUint8Array('...') }) .then(function(subscription) { // The subscription was successful savePushSubscription(subscription); }) .catch(function(e) { //error handling }); }); WebApp

Slide 16

Slide 16 text

Round 2: Permission Request WebApp Notification.requestPermission().then(function(result) { if (result!== 'granted') { //handle permissions deny } });

Slide 17

Slide 17 text

Round 2: Subscription reg.pushManagerpushManager.subscribe({ userVisibleOnly: true, applicationServerKey: new Uint8Array([...]) }); WebApp

Slide 18

Slide 18 text

Round 2: Subscription Object interface PushSubscription { readonly attribute endpoint; // "https://{push_server_url}/{user_identifier}", function getKey(); //auth - authentication secret //p256dh - key for encrypting messages }; WebApp

Slide 19

Slide 19 text

Round 3: Push Message WebApp Service Worker Browser Push Server App Server push message push message push message Something urgent and relevant happened

Slide 20

Slide 20 text

Round 3: Push Message POST /{user_identifier} HTTP/1.1 Host: {push_server_url} TTL: 15 Content-Type: text/plain;charset=utf8 Content-Length: 36 {encrypted_message} AppServer

Slide 21

Slide 21 text

Round 3: Additional Headers POST /{user_identifier} HTTP/1.1 Host: {push_server_url} Content-Type: text/plain;charset=utf8 Content-Length: 36 Prefer: respond-async TTL: 15 Urgency: high Topic: upd {encrypted_message} AppServer

Slide 22

Slide 22 text

Round 3: Message Encryption POST /{user_identifier} HTTP/1.1 Host: {push_server_url} Content-Type: text/plain;charset=utf8 Content-Length: 36 Prefer: respond-async TTL: 15 Urgency: high Topic: upd {encrypted_message} AppServer

Slide 23

Slide 23 text

Round 3: Encryption Library https://github.com/web-push-libs/web-push AppServer

Slide 24

Slide 24 text

Round 3: Voluntary Identification AppServer POST /{user_identifier} HTTP/1.1 Host: {push_server_url} TTL: 15 Content-Length: 136 Authorization: Bearer eyJ0eXAi... Crypto-Key: p256ecdsa=BA1Hxzy... {encrypted_message}

Slide 25

Slide 25 text

Round 3: Voluntary Identification JWT = { "aud": "https://{push_server_url}", "exp": 1453341205, "sub": "{application_server_email}" } AppServer

Slide 26

Slide 26 text

Round 3: Push Message self.addEventListener('push', function(event) { var data = event.data.json(); event.waitUntil(self.registration.showNotification(data.title, { body: data.body, icon: data.icon, tag: data.tag })); }); ServiceWorker

Slide 27

Slide 27 text

Round 3: Handle Notification self.addEventListener('notificationclick', function(event) { event.notification.close(); event.waitUntil(clients.openWindow('http://mywebsite.com')); }); ServiceWorker

Slide 28

Slide 28 text

Round 3: Notifications with Actions self.registration.showNotification(data.title, { body: data.body, actions: [ { action: 'ok', title: 'Yes' }, { action: 'decline', title: 'No' } ] }); … self.addEventListener('notificationclick', function(event) { if (event.action == 'ok') { // do something } }); ServiceWorker

Slide 29

Slide 29 text

Round 3: Notification Close self.addEventListener('notificationclose', function(event) { //do something }); ServiceWorker

Slide 30

Slide 30 text

Round 3: Handle Notification if (focused) { clients.forEach(function(client){ client.postMessage({ message: data.message }); }); } else { return self.registration.showNotification(data.title, { body: data.message }); } ServiceWorker

Slide 31

Slide 31 text

Round 4: Unsubscription WebApp Service Worker Browser Push Server App Server unsubscribe OK unsubscribe OK remove PushSubscription User wants to unsubscribe

Slide 32

Slide 32 text

Round 4: Unsubscription registration.pushManager.getSubscription().then(function(subscription) { if (subscription) { return subscription.unsubscribe().then(function(successful) { removePushSubscription(subscription); }).catch(function(e) { //error handling }); } }) .catch(function(error) { //error handling }) WebApp

Slide 33

Slide 33 text

Additional Round: Subscription Expiration WebApp Service Worker Browser Push Server App Server Subscription is about to expire

Slide 34

Slide 34 text

Additional Round: Subscription Expiration self.addEventListener('pushsubscriptionchange', function(registration, newSubscription, oldSubscription) { removePushSubscription(oldSubscription); savePushSubscription(newSubscription); }); ServiceWorker

Slide 35

Slide 35 text

Framework API

Slide 36

Slide 36 text

Framework API • PushNotification singleton • Methods: • .subscribe(message, applicationServerKey): Promise • .unsubscribe(): Promise • Events: • beforeNotificationShow(notification, data) • beforeNotificationClose • afterNotificationClose • subscriptionExpired(oldSubscription, newSubscription)

Slide 37

Slide 37 text

State of Specifications & Browser Support

Slide 38

Slide 38 text

State of Specifications Specification State Push API Working draft Notification API Living standard HTTP Web Push Proposed standard Push Message Encryption protocol Internet-draft VAPID protocol Internet-draft

Slide 39

Slide 39 text

Browser Support Browser Desktop Mobile Chrome Yes Yes Firefox Yes Yes Edge Beta Beta Safari Yes No Opera Yes Yes IE No No

Slide 40

Slide 40 text

Next Steps Using Web Push Notifications will push browser vendors to implement this feature. Try it in your apps. Ask me questions: I’ll be at the Sencha Booth #913 Contact me: @tyoushe