W3C

Push API

W3C Working Draft

This version:
http://www.w3.org/TR/2013/WD-push-api-20130815/
Latest published version:
http://www.w3.org/TR/push-api/
Latest editor's draft:
http://dvcs.w3.org/hg/push/raw-file/tip/index.html
Previous version:
http://www.w3.org/TR/2012/WD-push-api-20121018/
Editors:
Bryan Sullivan, AT&T
Eduardo Fullea, Telefonica

Abstract

This specification defines a “Push API” that provides webapps with scripted access to server-sent notifications, for simplicity referred to here as push notifications, as delivered by push services. Push services are a way for application servers to send messages to webapps, whether or not the webapp is active in a browser window.

Push notifications may be delivered via various methods, either via standardized protocols (e.g. Server-Sent Events [SSE], the GSM Short Message Service [GSM-SMS], SIP MESSAGE [RFC3428], or OMA Push [OMA-PUSH]), or via browser-specific methods. The specific method to be used by a webapp is either selected by the user through a push service extension, or by the browser. The Push API is defined to promote compatibility with any delivery method.

Status of This Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document was published by the Web Applications Working Group as a Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-webapps@w3.org with a Subject: prefix of [push-api] (subscribe, archives). All comments are welcome.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

Table of Contents

1. Introduction

This section is non-normative.

As defined here, push services support delivery of application server messages in the following contexts and related use cases:

2. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL in this specification are to be interpreted as described in [RFC2119].

This specification defines conformance criteria that apply to a single product: the user agent that implements the interfaces that it contains.

Implementations that use ECMAScript to implement the APIs defined in this specification must implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [WEBIDL], as this specification uses that specification and terminology.

3. Terminology

The Function interface represents a function in the scripting language being used as defined in [HTML5].

The concepts queue a task and fires a simple event are defined in [HTML5].

The terms event handlers and event handler event types are defined in [HTML5].

The Promise interface, the concepts of a resolver, a resolver's fulfill algorithm and a resolver's reject algorithm are defined in [DOM4].

The term push service extension refers to a browser extension enabling push service configuration for the user, and thereby enabling Push API binding to event delivery via the service.

The term webapp refers to a Web application, i.e. an application implemented using Web technologies, and executing within the context of a Web user agent, e.g. a Web browser or other Web runtime environment.

The term application server refers to the server side of a webapp.

The term push notification refers to an indication to a webapp that there is new information for it from the application server, all or part of which MAY be contained in the push notifications itself.

The term push registration refers to each logical channel aimed at delivering push notifications from an application server to a webapp, which is created by a distinct registration of such webapp via this Push API.

The term push service refers to the mechanisms that allow application servers to send push notifications to webapps.

The term push server refers to a system via which a push service is provided.

4. Security and privacy considerations

User agents must not provide Push API access to webapps without the express permission of the user. User agents must acquire consent for permission through a user interface for each call to the register() method, unless a prearranged trust relationship applies.

User agents may support prearranged trust relationships that do not require such per-request user interfaces.

Permissions that are preserved beyond the current browsing session must be revocable.

5. Push Framework

This section is non-normative.

There are different deployment alternatives to allow application servers to deliver push notifications to webapps. In a typical deployment application servers send a push notification to a Push server, e.g. by a RESTful interface, which in turn sends a push notification to the user agent providing the execution context for the webapp. The user agent then delivers the push notification to the corresponding webapp to which it was addressed.

The push notification MAY include a version number of the latest information available through this push registration, which the webapp may retrieve if not coincident with the latest version it has already retrieved.

The push notification system MUST ensure that the application eventually has the latest version of data on the application server. The push server may lose intermediate notifications or may lose all state, while fulfilling this requirement. In such an event, it will deliver a push-register system message to the application, so that the application may fetch the latest data from the application server.

Example 1
pushRegistrations = null;

function registerPush() {
  navigator.push.register().then(
    function(value) {
      pushRegistrations.push(value);
      registerWithAppServer(value);
    },
    function(reason) {alert("darn! "+ reason );}  
  );
}

function reRegisterPush(pushRegistration) {
  for (reg in pushRegistrations) {
    if (pushRegistrations[reg] == pushRegistration) pushRegistrations.splice(reg,1);
  }
  registerPush();
}

navigator.push.registrations().then(
  function(registrations) { 
    if (registrations.length == 0) registerPush(); // assume at least one needed
    else pushRegistrations = registrations;
  },		 
  function(reason) {alert("darn! "+ reason );}  
);

function registerWithAppServer(pushRegistration) {
   var activate = "http://example.com/push/activate?pushRegistrationId="+
     encodeURIComponent(pushRegistration.pushRegistrationId)+
     "&pushEndpoint="+encodeURIComponent(pushRegistration.pushEndpoint);
   asyncXHR(activate); // send activation request to application server
 };

function gotPush(message) {
  if (message.version == null) {
    var reset = "http://example.com/push/reset?pushRegistrationId="+
      encodeURIComponent(pushRegistration.pushRegistrationId)+
     "&pushEndpoint="+encodeURIComponent(pushRegistration.pushEndpoint);
    asyncXHR(reset); // send reset request to application server
  }
  else {
    if (message.version > last_version) {
      var getdata = "http://example.com/push/get?pushRegistrationId="+
      encodeURIComponent(pushRegistration.pushRegistrationId)+
      "&last="+last_version+"&current="+message.version;
      gotdata = function(data) {
        // handle retrieved data
      }
      asyncXHR(getdata, gotdata); // send data retrieval request to app server
    }
  }
}

if (navigator.hasPendingMessages("push")) {
  // do any special pre-processing before push messages are delivered
}

last_version = null; // initialize last message version
navigator.setMessageHandler("push", gotPush);
navigator.setMessageHandler("push-register", reRegisterPush);

/* Hypothetical end-to-end flow
  +--------+           +--------+             +--------+           +--------+
  | webapp |           |  user  |             |  push  |           |  app   |
  |        |           | agent  |             | server |           | server |
  +--------+           +--------+             +--------+           +--------+
      |                    |                      |                     |
      |-----register------>|                      |                     |
      |                    |                      |                     |
      |              (user accepts)               |                     |
      |                    |                      |                     |
      |                    |<-setup push service->|                     |
      |                    |                      |                     |
      |<---success---------|                      |                     |
      |                    |                      |                     |
      |<--activate service with PushService attributes----------------->|
      |                    |                      |                     |
      |                    |                      |<--push notification-|
      |                    |                      |   per service API   |
      |                    |                      |                     |
      |                    |             (match to user agent)          |
      |                    |                      |                     |
      |                    |<--push notification--|                     |
      |                    | per service protocol |                     |
      |                    |                      |                     |
      |            (match to webapp)              |                     |
      |                    |                      |                     |
      |<---system message--|                      |                     |
      |                    |                      |                     |
*/

7. PushManager Interface

The PushManager interface defines the operations that enable webapps to establish access to push services.

interface PushManager {
    Promise register ();
    Promise unregister (DOMString pushRegistrationId);
    Promise registrations ();
};

7.1 Methods

register
This method allows a webapp to create a new push registration to receive push notifications. It returns a Promise that will allow the caller to be notified about the result of the operation.
No parameters.
Return type: Promise
registrations
This method allows a webapp to retrieve the list of its active push registrations. It returns a Promise that will allow the caller to be notified about the result of the operation.
No parameters.
Return type: Promise
unregister
This method allows a webapp to unregister a specific push registration. It returns a Promise that will allow the caller to be notified about the result of the operation.
ParameterTypeNullableOptionalDescription
pushRegistrationIdDOMString Identifies the push registration that the webapp requests to unregister
Return type: Promise

7.2 Steps

The register method when invoked MUST run the following steps:

  1. Let promise be a new Promise object and resolver its associated resolver.
  2. Return promise and continue the following steps asynchronously.
  3. Ask the user whether it allows the requesting webapp to activate the reception of push notifications, unless a prearranged trust relationship applies or the user has already granted permission explicitly to this webapp.
  4. If not granted, run the following sub-steps and terminate these steps:
    1. Let error be a new DOMError object whose name is "AbortError".
    2. Invoke resolver's reject algorithm with error as the value argument.
  5. Make a request to the system to create a new push registration for the requesting webapp.
  6. If there is an error invoke resolver's reject algorithm with no arguments and terminate these steps.
  7. When the request has been completed run the following sub-steps:
    1. Let pushRegistration be a new PushRegistration object providing the details of the push registration.
    2. Invoke resolver's fulfill algorithm with pushRegistration as the value argument.

The unregister method when invoked MUST run the following steps:

  1. Let promise be a new Promise object and resolver its associated resolver.
  2. Return promise and continue the following steps asynchronously.
  3. Check that the pushRegistrationId attribute relates to an active push registration of the requesting webapp or alternatively that the requesting webapp has permission to deactivate such push registration.
  4. If none of them is fulfilled, run the following sub-steps and terminate these steps:
    1. Let error be a new DOMError object whose name is " NoModificationAllowedError".
    2. Invoke resolver's reject algorithm algorithm with error as the value argument.
  5. Make a request to the system to deactivate the push registration identified by the pushRegistrationId attribute.
  6. If there is an error invoke resolver's reject algorithm with no arguments and terminate these steps.
  7. When the request has been completed invoke resolver's fulfill algorithm with a DOMString set to the value of the pushRegistrationId attribute as the value argument.

The registrations method when invoked MUST run the following steps:

  1. Let promise be a new Promise object and resolver its associated resolver.
  2. Return promise and continue the following steps asynchronously.
  3. Retrieve the list of push registration associated to the requesting webapp
  4. If there is an error invoke resolver's reject algorithm algorithm with no arguments and terminate these steps.
  5. When the request has been completed run the following sub-steps:
    1. Let pushRegistrations be a new array containing a PushRegistration object per active push registration associated to the requesting webapp. A length of zero for pushRegistrations indicates that there are no registrations.
    2. Invoke resolver's fulfill algorithm algorithm with pushRegistrations as the value argument.

8. PushRegistration Interface

The PushRegistration interface contains information about a specific channel used by a webapp to receive push notifications.

interface PushRegistration {
    readonly    attribute DOMString pushEndpoint;
    readonly    attribute DOMString pushRegistrationId;
};

8.1 Attributes

pushEndpoint of type DOMString, readonly
It MUST return the absolute URL exposed by the push server where the application server can send push notifications to this webapp
pushRegistrationId of type DOMString, readonly
It MUST return a univocal identifier of this push registration in the push server. It is used by the application server to indicate the target of the push notifications that it submits to the push server.

9. PushMessage Interface

The PushMessage interface represents a System Message related to a received push notification.

interface PushMessage {
    readonly    attribute DOMString           pushRegistrationId;
    readonly    attribute unsigned long long? version;
};

9.1 Attributes

pushRegistrationId of type DOMString, readonly
MUST return the identifier of the push registration to which this System Message is related.
version of type unsigned long long, readonly , nullable
MUST return an identifier of the latest version of the content available through this push registration. If it is different from the last version the webapp is aware of it signals that it has new content to be retrieved from the application server. The version is an integer value that is incremented when new content is available through a push registration. So higher values of version indicate newer content. Note that the push server may just notify of the latest version if multiple notification requests have been recieved from the application server before the push server is ready to send a notification. Thus a notification for each version may not be received by the user agent and in turn by the webapp. This attribute MUST return null when the push server has lost track of the state, in order to indicate the webapp that it should ask the application server and restore local state.

10. PushRegisterMessage Interface

The PushRegisterMessage interface represents a System Message related to a push registration that is no longer valid and thus needs to be created again by the webapp by means of a new invocation of the register method.

interface PushRegisterMessage {
    readonly    attribute DOMString pushRegistrationId;
};

10.1 Attributes

pushRegistrationId of type DOMString, readonly
MUST return the identifier of the push registration to which this System Message is related.

11. System Messages

A webapp that wants to be able to make use of the capabilities provided by this API needs to be registered to the following System Messages:

name type description
push PushMessage Incoming push notification
push-register PushRegisterMessage Request to register a specific push registration

Upon receiving a push notification from the push server the User agent MUST run the following steps:

Upon any event that makes a push registration no longer valid, e.g. push server database failure, the User agent MUST run the following steps:

If a push notification or an indication about a push registration being no longer valid is received and the webapp is not active in a browser window, the User agent must invoke the webapp if possible, and deliver the push notification to it. Examples of cases in which webapps should be invokable include:

A. Acknowledgements

The editors would like to express their gratitude to the Mozilla and Telefónica Digital teams implementing the Firefox OS Push Notification solution and specially to Doug Turner, Nikhil Marathe, Fernando R. Sela, Guillermo López, Antonio Amaya, José Manuel Cantera and Albert Crespell, for their technical guidance, implementation work and support.

B. References

B.1 Normative references

[GSM-SMS]
Richard Burbidge. Technical realization of the Short Message Service (SMS). URL: http://www.3gpp.org/ftp/Specs/html-info/23040.htm
[HTML5]
Robin Berjon et al. HTML5. 17 December 2012. W3C Candidate Recommendation. URL: http://www.w3.org/TR/html5/
[OMA-PUSH]
Open Mobile Alliance. OMA Push Version 2.3. URL: http://www.openmobilealliance.org/Technical/release_program/push_v2_3.aspx
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Internet RFC 2119. URL: http://www.ietf.org/rfc/rfc2119.txt
[RFC3428]
B. Campbell; Ed; J. Rosenberg et al. Session Initiation Protocol (SIP) Extension for Instant Messaging (RFC 3428). December 2002. RFC. URL: http://www.ietf.org/rfc/rfc3428.txt
[SSE]
Ian Hickson. Server-Sent Events. 11 December 2012. W3C Candidate Recommendation. URL: http://www.w3.org/TR/eventsource/
[WEBIDL]
Cameron McCormack. Web IDL. 19 April 2012. W3C Candidate Recommendation. URL: http://www.w3.org/TR/WebIDL/

B.2 Informative references

[DOM4]
Anne van Kesteren; Aryeh Gregor; Lachlan Hunt; Ms2ger. DOM4. 6 December 2012. W3C Working Draft. URL: http://www.w3.org/TR/dom/