Esta traducción está incompleta. Por favor, ayuda a traducir este artículo del inglés.

La API de Notificaciones permite a una página web enviar notificaciones que se mostrarán fuera de la web al nivel del sistema. Esto permite a las aplicaciones web enviar información al usuario aunque estas estén de fondo.

Nota: This feature is available in Web Workers.

Para comenzar, tenemos que saber que son las notificaciones y cómo se muestran. En la imagen de abajo se puede ver un ejemplo de notificaciones en android.

El sistema de notificaciones variará según el navegador y la plataforma en la que estemos, pero no esto no va a suponer ningún problema. La API de notificaciones esta escrita de manera que sea compatible con la gran mayoría de sistemas.

Ejemplos

Un ejemplo claro de uso de notificaciones web puede ser un mail basado en web o una aplicación IRC que nos notificará cada vez que nos llegue un nuevo mensaje, aunque nostotros estemos fuera de la aplicación. Un ejemplo de esto lo podemos ver en Slack.

Hemos escrito un par de ejemplos del mundo real para dar una idea más clara de como podemos usar las notificaciones web:

  • Lista de pendientes: Esto es una app sencilla que almacena las tareas pendientes localmente usando IndexedDB y avisa al usuario cuándo hay que realizar las tareas mediante notificaciones. Descarga el código, o echa un vistazo al ejemplo en tiempo real.
  • Emogotchi: Una parodia absurda de Tamagotchi, en la que tienes que mantener a tu Emo miserable o perderás el juego. Esto usa las notificaciones del sistema para indicarte cómo lo estás haciendo y para quejarse de ti, TODO EL RATO. Descarga el código de Emogotchi, o echa un vistazo a la versión en tiempo real.

.

Pidiendo permiso

Antes de que una app pueda lanzar una notificación, el usuario tiene que darle permiso para ello. Esto es un requisito común cuándo una API intenta interactuar con algo fuera de una página web — al menos una vez, el usuario tendrá que permitir a la aplicación mostrar notificaciones, de esta forma, el usuario decide que aplicaciones le pueden mostrar notificaciones y cuales no.

Comprobando el permiso actual

Puedes comprobar si ya tienes permiso comprobando la propiedad Notification.permission de sólo lectura. Esta puede tener uno de los siguientes valores:

default
No se le ha pedido permiso al usuario aún, por lo que la app no tiene permisos.
granted
El usuario ha permitido las notificaciones de la app.
denied
El usuario ha denegado las notificaciones de la app.

Obteniendo permiso

Si la aplicación aún no tiene permiso para mostrar notificaciones, tendremos que hacer uso de Notification.requestPermission() para pedir permiso al usuario. En su manera más simple, tal y como se usa en la Demo de Emogotchi (código fuente), sólo tenemos que incluir lo siguiente:

Notification.requestPermission().then(function(result) {
  console.log(result);
});

Esto usa la versión promise del método, que está soportada en las versiones recientes (p.ej. Firefox 47). Si quieres soportar versiones más antiguas tendrás que usar la versión de callback, que es la siguiente:

Notification.requestPermission();

La versión de callback acepta de forma opcional una función callback que será ejecutada cuándo el usuario responda a si quiere notificaciones o no (tal y como se ve en el segundo else ... if abajo). Por lo general, pedirás permiso para mostrar notificaciones una vez que hayas inicializado la app, y antes de lanzar una notificación. Si quieres ser muy cuidadoso puedes usar lo siguiente (ver To-do List Notifications):

function notifyMe() {
  // Comprobamos si el navegador soporta las notificaciones
  if (!("Notification" in window)) {
    alert("Este navegador no soporta las notificaciones del sistema");
  }

  // Comprobamos si ya nos habían dado permiso
  else if (Notification.permission === "granted") {
    // Si esta correcto lanzamos la notificación
    var notification = new Notification("Holiwis :D");
  }

  // Si no, tendremos que pedir permiso al usuario
  else if (Notification.permission !== 'denied') {
    Notification.requestPermission(function (permission) {
      // Si el usuario acepta, lanzamos la notificación
      if (permission === "granted") {
        var notification = new Notification("Gracias majo!");
      }
    });
  }

  // Finalmente, si el usuario te ha denegado el permiso y 
  // quieres ser respetuoso no hay necesidad molestar más.
}

Nota: Antes de la versión 37, Chrome no te deja llamar a Notification.requestPermission() en manejador de eventos load (ver problema 274284).

Permisos en Firefox OS manifest

Ten en cuenta que mientras la API de Notificaciones no este privileged o certified, deberías de seguir inculyendo una entrada en tu archivo manifest.webapp cuándo vayas a usarlo en una app en Firefox OS:

"permissions": {
  "desktop-notification": {
    "description": "Needed for creating system notifications."
  }
},
"messages": [{"notification": "path/to/your/index.html"}]

Nota: Cuándo una aplicación es instalada, no deberías de necesitar explicitly request permission, pero vas a seguir necesitando los permisos y las entradas de texto de arriba para poder lanzar las notificaciones.

Creando una notificación

Crear una notificación es fácil, simplemente usa el constructor Notification. Este constructor espera un titulo que mostrar en la notificación y otras opciones para mejorar la notificación, como un icon o un texto body.

Por ejemplo, en el Ejemplo de Emogotchi tenemos dos funciones que pueden ser llamadas cuándo hay que lanzar una notificación; el uso de una u otra depende de si queremos establecer el contenido de la notificación, o si queremos una notificación con contenido aleatorio:

function spawnNotification(theBody,theIcon,theTitle) {
  var options = {
      body: theBody,
      icon: theIcon
  }
  var n = new Notification(theTitle,options);
  setTimeout(n.close.bind(n), 5000); 
}

function randomNotification() {
  var randomQuote = quoteChooser();
  var options = {
      body: randomQuote,
      icon: 'img/sad_head.png',
  }

  var n = new Notification('Emogotchi says',options);
  setTimeout(n.close.bind(n), 5000); 
}

Cerrando las notificaciones

Firefox y Safari cierran las notificaciones automáticamente tras cierto tiempo (unos 4 segundos). Esto también puede suceder a nivel de sistema operativo (en Windows duran 7 segundos por defecto). En cambio, en algunos navegadores no se cierran automáticamente, como en Chrome, por ejemplo. Para asegurarnos de que las notificaciones se cierran en todos los navegadores, al final de las funciones de arriba, llamamos a la función {domxref("Notification.close")}}  dentro de setTimeout() para cerrar la notificación tras 5 segundos. Date cuenta también del uso que hacemos de bind() para asegurarnos de que la función close() esta asociada a la notificación.

setTimeout(n.close.bind(n), 5000);

Nota: Cuándo recibes un evento "close", no hay ninguna garantía de que haya sido el usuario quién ha cerrado la notificación. Esto coincide con la especificación que dice: "Cuándo una notificación es cerrada, sea por la misma plataforma o por el usuario, se deben lanzar los pasos de cierre para la misma".

Eventos de Notificación

Las especificaciones de la API de notificaciones listan dos eventos que pueden ser lanzados en la instancia Notification:

click
Lanzado cuándo el usuario hace click en la notificación.
error
Lanzado cuándo algo falla en la notificación; habitualmente es porque la notificación no se ha podido mostrar por algún motivo.

Estos eventos se pueden segir usando los manejadores onclick y onerror. Como Notification también hereda de EventTarget, es posible usar el método addEventListener() en ella.

Tambiñen hay otros dos eventos que estaban listados en la especificación, pero que han sido eliminados recientemente. Estos puede que sigan funcionando en los navegadores por ahora, pero deberían de tratarse como obsoletos y evitar su uso:

close
Lanzado cuándo la notificación se cierra.
show
Lanzado cuándo la notificación se muestra al usuario.

Reemplazando notificaciones existentes

Normalmente los usuario no quieren recibir muchas notificaciones en poco tiempo — por ejemplo, una aplicación de mensajería que te notifica por cada mensaje que te llega, y te llegan un montón. Para evitar el spam de notificaciones, se puede modificar la cola de notificaciones, reemplazando una o varias notificaciones pendientes, por una nueva notificación.

Para hacer esto, se puede añadir una etiqueta a cualquier nueva notificación. Si ya hay una notificación con la misma etiqueta y aún no se ha mostrado, la nueva reemplazará a la anterior. Si la notificación con la misma etiqueta ya ha sido mostrada, se cerrará la anterior y se mostrará la nueva.

Ejemplo de etiquta

Teniendo el siguiente código HTML:

<button>Notifícame!</button>

Es posible controlar múltiples notificaciones de la siguiente forma:

window.addEventListener('load', function () {
  // Primero, comprobamos si tenemos permiso para lanzar notificaciones
  // Si no lo tenemos, lo pedimos
  if (window.Notification && Notification.permission !== "granted") {
    Notification.requestPermission(function (status) {
      if (Notification.permission !== status) {
        Notification.permission = status;
      }
    });
  }

  var button = document.getElementsByTagName('button')[0];

  button.addEventListener('click', function () {
    // Si el usuario ha dado permiso
    // le intentamos enviar 10 notificaciones
    if (window.Notification && Notification.permission === "granted") {
      var i = 0;
      // Usamos un inteval porque algunos navegadores (Firefox incluído) bloquean las notificaciones si se envían demasiadas en cierto tiempo.
      var interval = window.setInterval(function () {
        // Gracias a la etiqueta, deberíamos de ver sólo la notificación "Holiws! 9"
        var n = new Notification("Holiwis! " + i, {tag: 'soManyNotification'});
        if (i++ == 9) {
          window.clearInterval(interval);
        }
      }, 200);
    }

    // Si el usuario no ha dicho si quiere notificaciones
    // Nota: en Chrome no estamos seguros de si la propiedad permission
    // esta asignada, por lo que es inseguro comprobar el valor "default".
    else if (window.Notification && Notification.permission !== "denied") {
      Notification.requestPermission(function (status) {
        // Si el usuario acepta
        if (status === "granted") {
          var i = 0;
          // Usamos un inteval porque algunos navegadores (Firefox incluído) bloquean las notificaciones si se envían demasiadas en cierto tiempo.
          var interval = window.setInterval(function () {
          // Gracias a la etiqueta, deberíamos de ver sólo la notificación "Holiws! 9" var n = new Notification("Holiwis! " + i, {tag: 'soManyNotification'}); 
            if (i++ == 9) {
              window.clearInterval(interval);
            }
          }, 200);
        }

        // Otherwise, we can fallback to a regular modal alert
        else {
          alert("Hi!");
        }
      });
    }

    // If the user refuses to get notified
    else {
      // We can fallback to a regular modal alert
      alert("Hi!");
    }
  });
});

Comprueba el ejemplo en directo abajo:

Receiving notification of clicks on app notifications

When a user clicks on a notification generated by an app, you will be notified of this event in two different ways, depending on the circumstance:

  1. A click event if your app has not closed or been put in the background between the time you create the notification and the time the user clicks on it.
  2. A system message otherwise.

See this code snippet for an example of how to deal with this.

Especificaciones

Especificación Estado Comentario
Notifications API Living Standard Living standard

Compatibilidad de navegadores

Feature Chrome Edge Firefox (Gecko) Internet Explorer Opera Safari
Basic support 5webkit[1]
22
(Yes) 4.0 moz[2]
22
No support 25 6[3]
icon 5webkit[1]
22
(Yes) 4.0 moz[2]
22
No support 25 No support
Available in workers (Yes) (Yes) 41.0 (41.0) ? ? ?
silent 43.0 No support No support No support No support No support
noscreen, sticky No support No support No support No support No support No support
sound No support No support No support No support No support No support
renotify 50.0 No support No support No support No support No support
Promise-based Notification.requestPermission() 46.0 (Yes) 47.0 (47.0) ? 40 No support
vibrate, actions 53.0 No support     39  
badge 53.0 No support     39  
image 55.0 No support     ?  
Feature Android Android Webview Edge Firefox Mobile (Gecko) Firefox OS IE Mobile Opera Mobile Safari Mobile Chrome for Android
Basic support ?

(Yes)

(Yes) 4.0moz[2]
22
1.0.1moz[2]
1.2
No support ? No support

(Yes)

icon ? (Yes) (Yes) 4.0moz[2]
22
1.0.1moz[2]
1.2
No support ? No support (Yes)
Available in workers ? (Yes) (Yes) 41.0 (41.0) ? ? ? ? (Yes)
silent No support 43.0 No support No support No support No support No support No support 43.0
noscreen, sticky No support No support No support No support No support No support No support No support No support
sound No support (Yes) No support No support No support No support No support No support (Yes)
renotify No support 50.0 No support No support No support No support No support No support No support
Promise-based Notification.requestPermission() ? ? (Yes) 47.0 (47.0) ? ? ? ? ?
vibrate, actions No support 53.0 No support       39   53.0
badge No support 53.0 No support       39   53.0
image No support No support No support       ?   55.0

[1] Before Chrome 22, the support for notification followed an old prefixed version of the specification and used the navigator.webkitNotifications object to instantiate a new notification.

Before Chrome 32, Notification.permission was not supported.

Before Chrome 42, service worker additions were not supported.

Starting in Chrome 49, notifications do not work in incognito mode.

[2] Prior to Firefox 22 (Firefox OS <1.2), the instantiation of a new notification must be done with the navigator.mozNotification object through its createNotification method.

Prior to Firefox 22 (Firefox OS <1.2), the Notification was displayed when calling the show method and supported only the click and close events.

Nick Desaulniers wrote a Notification shim to cover both newer and older implementations.

One particular Firefox OS issue is that you can pass a path to an icon to use in the notification, but if the app is packaged you cannot use a relative path like /my_icon.png. You also can't use window.location.origin + "/my_icon.png" because window.location.origin is null in packaged apps. The manifest origin field fixes this, but it is only available in Firefox OS 1.1+. A potential solution for supporting Firefox OS <1.1 is to pass an absolute URL to an externally hosted version of the icon. This is less than ideal as the notification is displayed immediately without the icon, then the icon is fetched, but it works on all versions of Firefox OS.

When using notifications in a Firefox OS app, be sure to add the desktop-notification permission in your manifest file. Notifications can be used at any permission level, hosted or above:

"permissions": { "desktop-notification": {} }

[3] Safari started to support notification with Safari 6, but only on Mac OSX 10.8+ (Mountain Lion).

Ver también

Etiquetas y colaboradores del documento

Etiquetas: 
 Colaboradores en esta página: IXTRUnai
 Última actualización por: IXTRUnai,