ThePush API enables sending of apush message to a web application via apush service. Anapplication server can send apush message at any time, even when a web application oruser agent is inactive. Thepush service ensures reliable and efficient delivery to theuser agent.Push messages are delivered to aService Worker that runs in the origin of the web application, which can use the information in the message to update local state or display a notification to the user.
This specification is designed for use with theweb push protocol, which describes how anapplication server oruser agent interacts with apush service.
The Push API allows a web application to communicate with auser agent asynchronously. This allows anapplication server to provide theuser agent with time-sensitive information whenever that information becomes known, rather than waiting for a user to open the web application.
As defined here,push services support delivery ofpush messages at any time.
In particular, apush message will be delivered to the web application even if that web application is not currently active in a browser window: this relates to use cases in which the user may close the web application, but still benefits from the web application being able to be restarted when apush message is received. For example, apush message might be used to inform the user of an incoming WebRTC call.
Apush message can also be sent when theuser agent is temporarily offline. In support of this, thepush service stores messages for theuser agent until theuser agent becomes available. This supports use cases where a web application learns of changes that occur while a user is offline and ensures that theuser agent can be provided with relevant information in a timely fashion.Push messages are stored by thepush service until theuser agent becomes reachable and the message can be delivered.
The Push API will also ensure reliable delivery of push messages while auser agent is actively using a web application, for instance if a user is actively using the web application or the web application is in active communication with anapplication server through an active worker, frame, or background window. This is not the primary use case for the Push API. A web application might choose to use the Push API for infrequent messages to avoid having to maintain constant communications with theapplication server.
Push messaging is best suited to occasions where there is not already an active communications channel established between theuser agent and the web application. Sendingpush messages requires considerably more resources when compared with more direct methods of communication such as the [[Fetch|Fetch API]] or [[WebSockets]].Push messages usually have higher latency than direct communications and they can also be subject to restrictions on use. Mostpush services limit the size and quantity ofpush messages that can be sent.
Theweb push protocol [[RFC8030]] describes a protocol that enables communication between auser agent orapplication server and apush service. Alternative protocols could be used in place of this protocol, but this specification assumes the use of this protocol; alternative protocols are expected to provide compatible semantics.
TheContent-Encoding HTTP header, described in Section 8.4 of [[RFC9110]], indicates the content coding applied to the payload of apush message.
The termapplication server refers to server-side components of a web application.
Apush message is data sent to a web application from anapplication server.
Apush message is delivered to the [=service worker registration/active worker=] associated with thepush subscription to which the message was submitted. If the service worker is not currently running, the worker is started to enable delivery.
Adeclarative push message is a [=push message=] whose data is a JSON document that is understood by the user agent. A user agent opportunistically parses each incoming [=push message=] to determine if it is a [=declarative push message=] using the [=declarative push message parser=].
A [=declarative push message=] allows for the creation and display of a notification without the involvement of a service worker. Nevertheless, a service worker can still be involved if desired by the [=application server=]. In such a scenario the declarative nature of the [=push message=] serves as a backup in case the service worker was evicted due to storage pressure, for instance. And also provides a more object-oriented approach to transmitting notification data.
{ "web_push": 8030, "notification": { "title": "Ada emailed ‘London’", "lang": "en-US", "dir": "ltr", "body": "Did you hear about the tube strikes?", "navigate": "https://email.example/message/12" } }A [=declarative push message=] has the following members:
web_push (required)An integer that must be 8030. Used to disambiguate a [=declarative push message=] from other JSON documents.
notification (required) A JSON object consisting of the following members, all analogous to Notifications API features, though sometimes with a slightly stricter type. Apart fromtitle all members are derived from the {{NotificationOptions}} dictionary and to be maintained in tandem. [[NOTIFICATIONS]]
title (required)A string.
dir "auto", "ltr", or "rtl".
langA string that holds a language tag.
bodyA string.
navigate (required)A string that holds a URL.
tagA string.
imageA string that holds a URL.
iconA string that holds a URL.
badgeA string that holds a URL.
vibrateAn array of [=/32-bit unsigned integers=].
timestampA [=/64-bit unsigned integer=].
renotifyA boolean.
silentA boolean.
requireInteractionA boolean.
This is not namedrequire_interaction for consistency with the {{NotificationOptions}} dictionary.
dataAny JSON value.
actionsAn array of JSON objects consisting of the following members, all derived from the {{NotificationAction}} dictionary and to be maintained in tandem.
action (required)A string.
title (required)A string.
navigate (required)A string that holds a URL.
iconA string that holds a URL.
mutable A boolean. When true causes apush event to be dispatched to a service worker (if any) containing the {{Notification}} object described by thedeclarative push message.
Adeclarative push message parser result is a [=/tuple=] consisting of anotification (a [=/notification=]) and amutable (a boolean).
Thedeclarative push message parser given a [=/byte sequence=]bytes, [=/origin=]origin, [=/URL=]baseURL, and {{EpochTimeStamp}}fallbackTimestamp runs these steps. They return failure or a [=/declarative push message parser result=].
Letmessage be the result of [=parse JSON bytes to an Infra value|parsing JSON bytes to an Infra value=] givenbytes. If that throws an exception, then return failure.
Ifmessage is not a [=/map=], then return failure.
Ifmessage["`web_push`"] does not [=map/exist=] or is not 8030, then return failure.
Ifmessage["`notification`"] does not [=map/exist=], then return failure.
LetnotificationInput bemessage["`notification`"].
IfnotificationInput is not a [=/map=], then return failure.
IfnotificationInput["`title`"] does not [=map/exist=] or is not a string, then return failure.
IfnotificationInput["`navigate`"] does not [=map/exist=] or is not a string, then return failure.
LetnotificationTitle benotificationInput["`title`"].
LetnotificationOptions be a {{NotificationOptions}} dictionary.
IfnotificationInput["`dir`"] [=map/exists=] and is "`auto`", "`ltr`", or "`rtl`", then setnotificationOptions["{{NotificationOptions/dir}}"] tonotificationInput["`dir`"].
IfnotificationInput["`lang`"] [=map/exists=] and is a string, then setnotificationOptions["{{NotificationOptions/lang}}"] tonotificationInput["`lang`"].
IfnotificationInput["`body`"] [=map/exists=] and is a string, then setnotificationOptions["{{NotificationOptions/body}}"] tonotificationInput["`body`"].
SetnotificationOptions["{{NotificationOptions/navigate}}"] tonotificationInput["`navigate`"], [=string/converted=].
IfnotificationInput["`tag`"] [=map/exists=] and is a string, then setnotificationOptions["{{NotificationOptions/tag}}"] tonotificationInput["`tag`"].
IfnotificationInput["`image`"] [=map/exists=] and is a string, then setnotificationOptions["{{NotificationOptions/image}}"] tonotificationInput["`image`"], [=string/converted=].
IfnotificationInput["`icon`"] [=map/exists=] and is a string, then setnotificationOptions["{{NotificationOptions/icon}}"] tonotificationInput["`icon`"], [=string/converted=].
IfnotificationInput["`badge`"] [=map/exists=] and is a string, then setnotificationOptions["{{NotificationOptions/badge}}"] tonotificationInput["`badge`"], [=string/converted=].
IfnotificationInput["`vibrate`"] [=map/exists=] and is a [=/list=] of which each [=list/item=] is a [=/32-bit unsigned integer=], then setnotificationOptions["{{NotificationOptions/vibrate}}"] tonotificationInput["`vibrate`"].
IfnotificationInput["`timestamp`"] [=map/exists=] and is a [=/64-bit unsigned integer=], then setnotificationOptions["{{NotificationOptions/timestamp}}"] tonotificationInput["`timestamp`"].
IfnotificationInput["`renotify`"] [=map/exists=] and is a boolean, then setnotificationOptions["{{NotificationOptions/renotify}}"] tonotificationInput["`renotify`"].
IfnotificationInput["`silent`"] [=map/exists=] and is a boolean, then setnotificationOptions["{{NotificationOptions/silent}}"] tonotificationInput["`silent`"].
IfnotificationInput["`requireInteraction`"] [=map/exists=] and is a boolean, then setnotificationOptions["{{NotificationOptions/requireInteraction}}"] tonotificationInput["`requireInteraction`"].
IfnotificationInput["`data`"] [=map/exists=], then setnotificationOptions["{{NotificationOptions/data}}"] to the result of runningconvert an Infra value to a JSON-compatible JavaScript value givennotificationInput["`data`"].
IfnotificationInput["`actions`"] [=map/exists=] and is a [=/list=]:
LetnotificationActions be « ».
[=list/For each=]actionInput ofnotificationInput["`actions`"]:
IfactionInput["`action`"] does not [=map/exist=] or is not a string, then [=iteration/continue=].
IfactionInput["`title`"] does not [=map/exist=] or is not a string, then [=iteration/continue=].
IfactionInput["`navigate`"] does not [=map/exist=] or is not a string, then [=iteration/continue=].
LetactionNavigate beactionInput["`navigate`"], [=string/converted=].
LetnotificationAction be the {{NotificationAction}} dictionary «[ "{{NotificationAction/action}}" →actionInput["`action`"], "{{NotificationAction/title}}" →actionInput["`title`"], "{{NotificationAction/navigate}}" →actionNavigate ]».
IfactionInput["`icon`"] [=map/exists=] and is a string, then setnotificationAction["{{NotificationAction/icon}}"] toactionInput["`icon`"], [=string/converted=].
[=list/Append=]notificationAction tonotificationActions.
SetnotificationOptions["{{NotificationOptions/actions}}"] tonotificationActions.
Letnotification be the result ofcreating a notification givennotificationTitle,notificationOptions,origin,baseURL, andfallbackTimestamp. If this throws an exception, then return failure.
Ifnotification's [=notification/navigation URL=] is null, then return failure.
If the [=notification action/navigation URL=] of any [=/notification action=] ofnotification's [=notification/actions=] is null, then return failure.
Letmutable be false.
Ifmessage["`mutable`"] [=map/exists=] andmessage["`mutable`"] is a boolean, then setmutable tomessage["`mutable`"].
Return (notification,mutable).
Apush subscription is a message delivery context established between theuser agent and thepush service on behalf of a web application.
A [=push subscription=] has an associatedscope, which is a [=/URL=].
A [=push subscription=] is considered to have awindow-accessible scope when its [=push subscription/scope=]'s [=url/path=] is a [=/list=] of [=list/size=] 1 and [=push subscription/scope=]'s [=url/path=][0] is the empty string.
I.e., the [=url/path=] component of the [=/URL=] serializes as "`/`".
Apush subscription has an associatedpush endpoint. It MUST be the absolute URL exposed by thepush service where theapplication server can sendpush messages to. Apush endpoint MUST uniquely identify thepush subscription.
Apush subscription MAY have an associatedsubscription expiration time. When set, it MUST be the time, in milliseconds since 00:00:00 UTC on 1 January 1970, at which the subscription will bedeactivated. Theuser agent SHOULD attempt torefresh the push subscription before the subscription expires.
Apush subscription has internal slots for a P-256ECDH key pair and an authentication secret in accordance with [[RFC8291]]. These slots MUST be populated when creating thepush subscription.
If theuser agent has to change the keys of a [=push subscription=] for any reason and the [=push subscription=]'s [=associated service worker registration=] is non-null, it MUST [=refresh=] the [=push subscription=].
Tocreate a push subscription, given an {{PushSubscriptionOptionsInit}} |optionsDictionary:PushSubscriptionOptionsInit|:
A [=push subscription=]'sassociated service worker registration is the [=service worker registration=] whose [=service worker registration/scope URL=] [=URL/equals=] the [=push subscription=]'s [=push subscription/scope=], if any; otherwise null.
A [=push subscription=]'s [=associated service worker registration=] can only be null when it has a [=push subscription/window-accessible scope=].
And vice versa, a [=service worker registration=]'sassociated push subscription is the [=push subscription=] whose [=push subscription/scope=] [=URL/equals=] the [=service worker registration=]'s [=service worker registration/scope URL=], if any; otherwise null.
Auser agent orpush service MAY choose torefresh apush subscription whose [=associated service worker registration=] is non-null at any time, for example because it has reached a certain age.
When this happens, theuser agent MUST run the steps tocreate a push subscription given thePushSubscriptionOptions that were provided for creating the currentpush subscription, and set the new [=push subscription=]'s [=push subscription/scope=] to the original subscription's [=push subscription/scope=]. The newpush subscription MUST have a key pair that's different from the original subscription.
When successful,user agent then MUSTfire the "`pushsubscriptionchange`" event with theservice worker registration associated with thepush subscription as |registration|, a {{PushSubscription}} instance representing the initialpush subscription as |oldSubscription| and a {{PushSubscription}} instance representing the newpush subscription as |newSubscription|.
To allow for time to propagate changes toapplication servers, auser agent MAY continue to accept messages for an oldpush subscription for a brief time after a refresh. Once messages have been received for a refreshedpush subscription, any oldpush subscriptions MUST bedeactivated.
If theuser agent is not able to refresh thepush subscription, it SHOULD periodically retry the refresh. When thepush subscription can no longer be used, for example because it has expired, theuser agent MUSTfire the "`pushsubscriptionchange`" event with theservice worker registration associated with thepush subscription as |registration|, a {{PushSubscription}} instance representing the deactivatingpush subscription as |oldSubscription| and `null` as the |newSubscription|.
When apush subscription isdeactivated, both theuser agent and thepush service MUST delete any stored copies of its details. Subsequentpush messages for thispush subscription MUST NOT be delivered.
Apush subscription without a [=push subscription/window-accessible scope=] MUST bedeactivated when its associatedservice worker registration is unregistered, though apush subscription MAY bedeactivated earlier.
Apush subscription without a [=push subscription/window-accessible scope=] is removed whenservice worker registration is cleared.
The termpush service refers to a system that allowsapplication servers to sendpush messages to a web application. A push service serves thepush endpoint orendpoints for thepush subscriptions it serves.
Theuser agent connects to thepush service used to createpush subscriptions.User agents MAY limit the choice ofpush services available. Reasons for doing so include performance-related concerns such as service availability (including whether services are blocked by firewalls in specific countries, or networks at workplaces and the like), reliability, impact on battery lifetime, and agreements to steer metadata to, or away from, specificpush services.
The Push API is a [=powerful feature=] identified by the [=powerful feature/name=]"push".
For integration with the [[[Permissions]]] specification, this specification defines the {{PushPermissionDescriptor}} [=powerful feature/permission descriptor type=].
dictionary PushPermissionDescriptor : PermissionDescriptor { boolean userVisibleOnly = false; };TheuserVisibleOnly has the same semantics as {{PushSubscriptionOptionsInit/userVisibleOnly}}.
`{name: "push", userVisibleOnly: false}` is [=PermissionDescriptor/stronger than=] `{name: "push", userVisibleOnly: true}`.
The contents of apush message are encrypted [[RFC8291]]. However, thepush service is still exposed to the metadata of messages sent by anapplication server to auser agent over apush subscription. This includes the timing, frequency, and size of messages. Other than changingpush services, which user agents may disallow, the only known mitigation is to increase the apparent message size by padding.
There is no guarantee that apush message was sent by anapplication server having the same origin as the web application. Theapplication server is able to share the details necessary to use apush subscription with a third party at its own discretion.
The following requirements are intended to protect the privacy and security of the user as far as possible, and subject to meeting that goal, to protect the integrity of theapplication server's communication with the user.
The Push API may have to wake up the Service Worker associated with theservice worker registration in order to run the developer-provided event handlers. This can cause resource usage, such as network traffic, that theuser agent SHOULD attribute to the web application that created thepush subscription.
Theuser agent MAY consider thePushSubscriptionOptions when acquiring permission or determining the permission status.
When a permission is revoked, theuser agent MAYfire the "`pushsubscriptionchange`" event for subscriptions created with that permission, with theservice worker registration associated with thepush subscription as |registration|, a {{PushSubscription}} instance representing thepush subscription as |oldSubscription|, and `null` as |newSubscription|. Theuser agent MUSTdeactivate the affected subscriptions in parallel.
Thepush endpoint MUST NOT expose information about the user to be derived by actors other than thepush service, such as the user's device, identity or location. See the Privacy Considerations in [[RFC8030]] for the exact requirements.
Thepush endpoint of adeactivatedpush subscription MUST NOT be reused for a newpush subscription. This prevents the creation of a persistent identifier that the user cannot remove. This also prevents reuse of the details of onepush subscription to sendpush messages to anotherpush subscription.
Apush message is sent from anapplication server to a web application as follows:
This overall framework allowsapplication servers to activate aService Worker in response to events at theapplication server. Information about those events can be included in thepush message, which allows the web application to react appropriately to those events, potentially without needing to initiate network requests.
The following code and diagram illustrate a hypothetical use of the push API.
// https://example.com/serviceworker.js this.onpush = event => { console.log(event.data); // From here we can write the data to IndexedDB, send it to any open // windows, display a notification, etc. } // https://example.com/webapp.js // inside an async function... try { const serviceWorkerRegistration = await navigator.serviceWorker.register( "serviceworker.js" ); const pushSubscription = await serviceWorkerRegistration.pushManager.subscribe(); // The push subscription details needed by the application // server are now available, and can be sent to it using, // for example, an XMLHttpRequest. console.log(pushSubscription.endpoint); console.log(pushSubscription.getKey("p256dh")); console.log(pushSubscription.getKey("auth")); } catch (err) { // In a production environment it might make sense to // also report information about errors back to the // application server. console.log(error); }
The fields included in the {{PushSubscription}} is all the information needed for anapplication server to send apush message. Push services that are compatible with the Push API provide apush endpoint that conforms to theweb push protocol. These parameters and attributes include:
This specifications extends the {{Window}} and {{ServiceWorkerRegistration}} objects through the {{PushManagerAttribute}} mixin. [[HTML]] [[SERVICE-WORKERS]]
[SecureContext] interface mixin PushManagerAttribute { readonly attribute PushManager pushManager; }; Window includes PushManagerAttribute; ServiceWorkerRegistration includes PushManagerAttribute;{{Window}} and {{ServiceWorkerRegistration}} objects have an associated {{PushManager}} object.
ThepushManager getter steps are to return [=this=]'s associated {{PushManager}} object.
On a {{Window}} object the {{PushManager}}'s [=PushManager/service worker registration=] is null.
On a {{ServiceWorkerRegistration}} object the {{PushManager}}'s [=PushManager/service worker registration=] is theservice worker registration represented by the {{ServiceWorkerRegistration}} object.
The {{PushManager}} interface defines the operations to accesspush services.
[Exposed=(Window,Worker), SecureContext] interface PushManager { [SameObject] static readonly attribute FrozenArray<DOMString> supportedContentEncodings; Promise<PushSubscription> subscribe(optional PushSubscriptionOptionsInit options = {}); Promise<PushSubscription?> getSubscription(); Promise<PermissionState> permissionState(optional PushSubscriptionOptionsInit options = {}); };A {{PushManager}} has an associatedservice worker registration which is null or aservice worker registration.
ThesupportedContentEncodings attribute exposes the sequence of supported content codings that can be used to encrypt the payload of apush message. A content coding is indicated using theContent-Encoding header field when requesting the sending of apush message from thepush service.
User agents MUST support the `aes128gcm` content coding defined in [[RFC8291]], and MAY support content codings defined in previous versions of the draft for compatibility reasons.
Thesubscribe() method steps are:
Document's [=Document/URL=].ThegetSubscription() method steps are:
Document's [=Document/URL=].ThepermissionState() method when invoked MUST run the following steps:
Permission to use the push service can be persistent, that is, it does not need to be reconfirmed for subsequent subscriptions if a valid permission exists.
If there is a need to ask for permission, it needs to be done by invoking the {{PushManager/subscribe()}} method.
[Exposed=(Window,Worker), SecureContext] interface PushSubscriptionOptions { readonly attribute boolean userVisibleOnly; [SameObject] readonly attribute ArrayBuffer? applicationServerKey; };TheuserVisibleOnly attribute, when getting, returns the value it was initialized with.
TheapplicationServerKey attribute, when getting, returns the value it was initialized with.
If present, the value of {{PushSubscriptionOptions/applicationServerKey}} MUST include a point on the P-256 elliptic curve [[DSS]], encoded in the uncompressed form described in [[ANSI-X9-62]] Annex A (that is, 65 octets, starting with an 0x04 octet). When provided as a {{DOMString}}, the value MUST be encoded using the base64url encoding [[RFC7515]].
User agents MAY reject a subscription attempt when {{PushSubscriptionOptions/applicationServerKey}} is not present and thepush service requires one for operational reasons.
The {{PushSubscriptionOptions/applicationServerKey}} MUST be a different value to the one used for message encryption [[RFC8291]].
dictionary PushSubscriptionOptionsInit { boolean userVisibleOnly = false; (BufferSource or DOMString)? applicationServerKey = null; };TheuserVisibleOnly member, when set to `true`, indicates that thepush subscription will only be used forpush messages whose effect is made visible to the user, for example by displaying a Web Notification. [[NOTIFICATIONS]]
APushSubscriptionOptionsInit represents additional options associated with apush subscription. Theuser agent MAY consider these options when requestingexpress permission from the user. When an option is considered, theuser agent SHOULD enforce it on incomingpush messages.
These options are optional, anduser agents MAY choose to support only a subset of them. Auser agent MUST NOT expose options that it does not support.
Once set, options for apush subscription cannot change. A pre-existingpush subscription can be unsubscribed, via {{PushSubscription/unsubscribe}}, to create apush subscription with new options.
TheapplicationServerKey member is used by theuser agent when establishing apush subscription with apush service. The {{PushSubscriptionOptions/applicationServerKey}} option includes an elliptic curve public key for anapplication server. This is the key that theapplication server will use to authenticate itself when sendingpush messages to thispush subscription as defined in [[RFC8292]]; thepush service will reject anypush message unless the corresponding private key is used to generate an authentication token.
A {{PushSubscription}} object represents apush subscription.
[Exposed=(Window,Worker), SecureContext] interface PushSubscription { readonly attribute USVString endpoint; readonly attribute EpochTimeStamp? expirationTime; [SameObject] readonly attribute PushSubscriptionOptions options; ArrayBuffer? getKey(PushEncryptionKeyName name); Promise<boolean> unsubscribe(); PushSubscriptionJSON toJSON(); }; dictionary PushSubscriptionJSON { USVString endpoint; EpochTimeStamp? expirationTime = null; record<DOMString, USVString> keys; };Whengetting the `endpoint` attribute, theuser agent MUST return thepush endpoint associated with thepush subscription. Theuser agent MUST use a serialization method that does not contain input-dependent branches (that is, one that is constant time).
Whengetting the `expirationTime` attribute, theuser agent MUST return thesubscription expiration time associated with thepush subscription if there is one, or `null` otherwise.
When getting theoptions attribute, theuser agent MUST return aPushSubscriptionOptions object representing the options associated with thepush subscription.
ThegetKey() method retrieves keying material that can be used for encrypting and authenticating messages. When {{PushSubscription/getKey()}} is invoked the following process is followed:
Keys named {{PushEncryptionKeyName/"p256dh"}} and {{PushEncryptionKeyName/"auth"}} MUST be supported, and their values MUST correspond to those necessary for the user agent to decrypt received push messages in accordance with [[RFC8291]].
Theunsubscribe() method when invoked MUST run the following steps:
If theuser agent failed to request thepush service todeactivate thepush subscription, for example because of network failures, it SHOULD retry the request to thepush service for a reasonable amount of time.
ThetoJSON() method when invoked MUST run the following steps:
APushSubscriptionJSON dictionary represents theJSON type of a {{PushSubscription}}. In ECMAScript this can be converted into a JSON string through the `JSON`.{{JSON/stringify()}} function.
Thekeys record contains an entry for each of the supported {{PushEncryptionKeyName}} entries to the URL-safe base64 encoded representation [[RFC4648]] of its value.
Note that the options to a {{PushSubscription}} are not serialized.
Encryption keys used forpush message encryption are provided to a web application through the {{PushSubscription/getKey()}} method or the serializer of {{PushSubscription}}. Each key is named using a value from the {{PushEncryptionKeyName}} enumeration.
enum PushEncryptionKeyName { "p256dh", "auth" };Thep256dh value is used to retrieve the P-256 ECDH Diffie-Hellman public key described in [[RFC8291]].
Theauth value is used to retrieve the authentication secret described in [[RFC8291]].
[Exposed=ServiceWorker, SecureContext] interface PushMessageData { ArrayBuffer arrayBuffer(); Blob blob(); Uint8Array bytes(); any json(); USVString text(); };{{PushMessageData}} objects have an associatedbytes (a [=byte sequence=]), which is set on creation.
ThearrayBuffer() method steps are to return an {{ArrayBuffer}} whose contents are [=this=]'s [=bytes=]. Exceptions thrown during the creation of the {{ArrayBuffer}} object are re-thrown.
Theblob() method steps are to return a new {{Blob}} object whose contents are [=this=]'s [=bytes=].
Thebytes() method steps are to return a new {{Uint8Array}} backed by a {{ArrayBuffer}} whose contents are [=this=]'s [=bytes=]. Exceptions thrown during the creation of the {{ArrayBuffer}} object are re-thrown.
Thejson() method steps are to return the result of [=parse JSON bytes to a JavaScript value|parsing JSON bytes to a JavaScript value=] given [=this=]'s [=bytes=].
Thetext() method steps are to return the result of runningUTF-8 decode on [=this=]'s [=bytes=].
Toextract a byte sequence from |object|, run these steps:
The Service Worker specification defines a {{ServiceWorkerGlobalScope}} interface [[SERVICE-WORKERS]], which this specification extends.
[Exposed=ServiceWorker, SecureContext] partial interface ServiceWorkerGlobalScope { attribute EventHandler onpush; attribute EventHandler onpushsubscriptionchange; };Theonpush attribute is anevent handler IDL attribute whose correspondingevent handler event type is "`push`". The "`push`" event indicates that apush message has been received for apush subscription.
Theonpushsubscriptionchange attribute is anevent handler IDL attribute whose correspondingevent handler event type is "`pushsubscriptionchange`".
[Exposed=ServiceWorker, SecureContext] interface PushEvent : ExtendableEvent { constructor(DOMString type, optional PushEventInit eventInitDict = {}); readonly attribute PushMessageData? data; readonly attribute Notification? notification; }; dictionary PushEventInit : ExtendableEventInit { PushMessageDataInit? data = null; Notification? notification = null; }; typedef (BufferSource or USVString) PushMessageDataInit;When aconstructor of thePushEvent interface, or of an interface that inherits from thePushEvent interface, is invoked, the usualevent constructing steps are extended to include the following steps:
Thedata attribute must return the value it was initialized with.
Thenotification attribute must return the value it was initialized with.
When theuser agent receives apush message from thepush service, it MUST run the following steps.
Let |subscription| be the activepush subscription corresponding to thepush message.
Let |registration| be |subscription|'s [=push subscription/associated service worker registration=].
Let |bytes| be null.
If thepush message contains a payload:
Decrypt thepush message's payload using the private key from the key pair associated with |subscription| and the process described in [[RFC8291]]. Set |bytes| to the resulting [=/byte sequence=].
If thepush message payload could not be decrypted for any reason, then [=acknowledge a push message|acknowledge=] thepush message and abort these steps.
A `push` event is not fired for apush message that was not successfully decrypted using the key pair associated with thepush subscription.
If |bytes| is non-null:
Let |baseURL| be |subscription|'s [=push subscription/scope=].
Let |origin| be |baseURL|'s [=url/origin=].
Let |fallbackTimestamp| be [=current coarsened wall time=].
Let |declarativeResult| be the result of running the [=/declarative push message parser=] given |bytes|, |origin|, |baseURL|, and |fallbackTimestamp|.
If |declarativeResult| is not failure:
Let |notification| be |declarativeResult|'s [=declarative push message parser result/notification=].
Set |notification|'s [=notification/service worker registration=] to |registration|.
Let |notificationShown| be false.
If |declarativeResult|'s [=declarative push message parser result/mutable=] is true and |registration| is non-null:
Let |result| be the result of [=fire a push event|firing a push event=] given |registration|, null, and a new {{Notification}} object representing |notification|.
If |result| is not failure, then set |notificationShown| to |result|'s [=push event result/notification shown=].
If |notificationShown| is false, then run the [=notification show steps=] given |notification|.
[=acknowledge a push message|Acknowledge=] thepush message and abort these steps.
If |registration| is null, then abort these steps.
Let |data| be a new {{PushMessageData}} object whose [=PushMessageData/bytes=] is |bytes| if |bytes| is non-null; otherwise null.
Let |result| be the result of [=fire a push event|firing a push event=] given |registration|, |data|, and null.
Ifresult is failure and the samepush message has been delivered to aservice worker registration multiple times unsuccessfully, then [=acknowledge a push message|acknowledge=] thepush message.
Ifresult is not failure, then [=acknowledge a push message|acknowledge=] thepush message.
Apush event result is a [=/tuple=] consisting of anotification shown (a [=/boolean=]).
Tofire a push event given a [=/service worker registration=] |registration|, {{PushMessageData}} object or null |data|, and a [=/notification=] or null |notification|, run these steps. They return failure or a [=/push event result=].
Let |notificationResult| be null.
Set |registration|'s [=service worker registration/has shownotification() been successfully invoked|has `showNotification()` been successfully invoked=] to false.
Fire a functional event named "`push`" usingPushEvent on |registration| with the following properties:
Then run the following steps in parallel, with |dispatchedEvent|:
Wait for all of the promises in the [=ExtendableEvent/extend lifetime promises=] of |dispatchedEvent| to resolve.
If they do not resolve successfully, then set |notificationResult| to failure.
Otherwise, set |notificationResult| to |registration|'s [=service worker registration/has shownotification() been successfully invoked|has `showNotification()` been successfully invoked=].
Wait for |notificationResult| to be non-null.
If |notificationResult| is failure, then return failure.
[=/Assert=]: |notificationResult| is a [=/boolean=].
Return (|notificationResult|).
Toacknowledge a push message given apush messagepushMessage means to acknowledge the receipt ofpushMessage according to [[RFC8030]].
Acknowledging thepush message causes thepush service to stop delivering the message and to report success to theapplication server. This prevents the samepush message from being retried by thepush service indefinitely.
Acknowledging also means that anapplication server could incorrectly receive a delivery receipt indicating successful delivery of thepush message. Therefore, multiple rejections SHOULD be permitted before acknowledging; allowing at least three attempts is recommended.
Thepushsubscriptionchange event indicates a change in apush subscription that was triggered outside of the application's control, for example because it has been refreshed, revoked or lost.
Tofire the "`pushsubscriptionchange`" event given aservice worker registration of |registration|, |newSubscription| and |oldSubscription|, theuser agent mustfire a functional event named "`pushsubscriptionchange`" usingPushSubscriptionChangeEvent on |registration| with the following properties:
Consider using a more reliable synchronization mechanism such as [[WEB-BACKGROUND-SYNC]] when sending the details of the newpush subscription to yourapplication server. The user might be subject to unreliable network conditions that could cause a fetch to fail.
[Exposed=ServiceWorker, SecureContext] interface PushSubscriptionChangeEvent : ExtendableEvent { constructor(DOMString type, optional PushSubscriptionChangeEventInit eventInitDict = {}); readonly attribute PushSubscription? newSubscription; readonly attribute PushSubscription? oldSubscription; };ThenewSubscription attribute, when getting, returns the value it was initialized to.
TheoldSubscription attribute, when getting, returns the value it was initialized to.
dictionary PushSubscriptionChangeEventInit : ExtendableEventInit { PushSubscription newSubscription = null; PushSubscription oldSubscription = null; };ThenewSubscription member details thepush subscription that is valid per invocation of thepushsubscriptionchange event. The value will be `null` when no newpush subscription could be established, for example because the web application has lostexpress permission.
TheoldSubscription member details thepush subscription that SHOULD NOT be used anymore. The value will be `null` when theuser agent is not able to provide the full set of details, for example because of partial database corruption.
ThePush API does not provide any means itself to present data it receives from a [=push service=]. Instead, thePush API relies on other APIs – primarily the [[[NOTIFICATIONS]]] – to present received information to an end user. As such, there are no accessibility requirements for thePush API itself. However, specifications such as [[NOTIFICATIONS]] provide guidance how to present notifications in an accessible manner.
Further, presenting an accessible interface might depend on transferring more information than a push message can convey. Push messages are best suited to carrying small amounts of content or identifiers. Any larger resources need to be fetched from servers.
This specification defines conformance criteria that apply to a single product: theuser agent that implements the interfaces that it contains.
The editors would like to express their gratitude to the Mozilla and Telefónica Digital teams implementing the Firefox OS Push message solution, as well as to the following people who provided significant technical input to this document: Antonio Amaya, Miguel García Arribas, Ben Bangert, Kit Cambridge, José Manuel Cantera, JR Conlin, Albert Crespell, Matt Gaunt, Phil Jenvey, Guillermo López, Nikhil Marathe, John Mellor, Pınar Özlen, Fernando R. Sela, Shijun Sun and Doug Turner.