Codelab: Compila un servidor de notificaciones push

Karla Gómez
Kate Jeffreys

En este codelab, te mostraremos, paso a paso, cómo compilar un servidor de notificaciones push. Al final del codelab, tendrás un servidor con las siguientes características:

  • Realiza un seguimiento de las suscripciones a notificaciones push (es decir, el servidor crea un registro de base de datos nuevo cuando un cliente habilita las notificaciones push y borra un registro de la base de datos existente cuando un cliente las inhabilita).
  • Envía una notificación push a un solo cliente
  • Envía una notificación push a todos los clientes suscritos

Este codelab se enfoca en ayudarte a aprender mediante la práctica y no habla mucho de conceptos. Consulta ¿Cómo funcionan las notificaciones push? para obtener más información sobre sus conceptos.

El código de cliente de este codelab ya está completo. Solo implementarás el servidor en este codelab. Si quieres aprender a implementar un cliente de notificaciones push, consulta Codelab: Compila un cliente de notificaciones push.

Consulta push-notifications-server-codelab-complete (fuente) para ver el código completo.

Compatibilidad del navegador

Se sabe que este codelab funciona con las siguientes combinaciones de sistema operativo y navegador:

  • Windows: Chrome y Edge
  • macOS: Chrome y Firefox
  • Android: Chrome y Firefox

Se sabe que este codelab no funciona con los siguientes sistemas operativos (o combinaciones de sistema operativo y navegador):

  • macOS: Brave, Edge y Safari
  • iOS

Pila de aplicaciones

  • El servidor se basa en Express.js.
  • La biblioteca web-push de Node.js se encarga de toda la lógica de las notificaciones push.
  • Los datos de suscripción se escriben en un archivo JSON con lowdb.

No es necesario que uses ninguna de estas tecnologías para implementar notificaciones push. Elegimos estas tecnologías porque proporcionan una experiencia confiable de codelabs.

Configuración

Obtén una copia editable del código

El editor de código que ves a la derecha de estas instrucciones se denominará la IU de Glitch a lo largo de este codelab.

  1. Haz clic en Remix to Edit para que el proyecto sea editable.

Configura la autenticación

Para que las notificaciones push funcionen, debes configurar tu servidor y cliente con claves de autenticación. Consulta Firma las solicitudes de protocolo push web para conocer los motivos.

  1. Haz clic en Tools y, luego, en Terminal para abrir la terminal de Glitch.
  2. En la terminal, ejecuta npx web-push generate-vapid-keys. Copia la clave privada y los valores de la clave pública.
  3. Abre .env y actualiza VAPID_PUBLIC_KEY y VAPID_PRIVATE_KEY. Establece VAPID_SUBJECT en mailto:test@test.test. Todos estos valores deben estar entre comillas dobles. Después de realizar las actualizaciones, tu archivo .env debería ser similar al siguiente:
VAPID_PUBLIC_KEY="BKiwTvD9HA…"
VAPID_PRIVATE_KEY="4mXG9jBUaU…"
VAPID_SUBJECT="mailto:test@test.test"
  1. Cierra la terminal de Glitch.
  1. Abre public/index.js.
  2. Reemplaza VAPID_PUBLIC_KEY_VALUE_HERE por el valor de tu clave pública.

Administrar las suscripciones

Tu cliente controla la mayor parte del proceso de suscripción. Las tareas principales que debe hacer tu servidor son guardar nuevas suscripciones a notificaciones push y borrar suscripciones antiguas. Estas suscripciones te permiten enviar mensajes a los clientes en el futuro. Consulta Suscribe al cliente a las notificaciones push para obtener más contexto sobre el proceso de suscripción.

Guardar nueva información de la suscripción

  1. Para obtener una vista previa del sitio, presiona Ver app. Luego, presiona Pantalla completa pantalla completa.
  1. Haz clic en Registrar service worker en la pestaña de la app. En el cuadro de estado, deberías ver un mensaje similar a este:
Service worker registered. Scope: https://desert-cactus-sunset.glitch.me/
  1. En la pestaña de la app, haz clic en Suscribirse a notificaciones push. Es probable que tu navegador o sistema operativo te pregunten si quieres permitir que el sitio web te envíe notificaciones push. Haz clic en Allow (o en la frase equivalente que use tu navegador o SO). En el cuadro de estado, deberías ver un mensaje similar a este:
Service worker subscribed to push.  Endpoint: https://fcm.googleapis.com/fcm/send/…
  1. Para volver a tu código, haz clic en View Source en la IU de Glitch.
  2. Para abrir los registros de Glitch, haz clic en Tools y, luego, en Logs. Deberías ver /add-subscription seguido de algunos datos. /add-subscription es la URL a la que el cliente envía una solicitud POST cuando desea suscribirse a notificaciones push. Los datos que se muestran a continuación son la información de suscripción del cliente que debes guardar.
  3. Abre server.js.
  4. Actualiza la lógica del controlador de ruta /add-subscription con el siguiente código:
app.post('/add-subscription', (request, response) => {
  console.log('/add-subscription');
  console.log(request.body);
  console.log(`Subscribing ${request.body.endpoint}`);
  db.get('subscriptions')
    .push(request.body)
    .write();
  response.sendStatus(200);
});

Borrar información de suscripción anterior

  1. Regresa a la pestaña de la app.
  2. Haz clic en Anular la suscripción a envío.
  3. Vuelve a revisar los registros de fallas. Deberías ver /remove-subscription seguido de la información de suscripción del cliente.
  4. Actualiza la lógica del controlador de ruta /remove-subscription con el siguiente código:
app.post('/remove-subscription', (request, response) => {
  console.log('/remove-subscription');
  console.log(request.body);
  console.log(`Unsubscribing ${request.body.endpoint}`);
  db.get('subscriptions')
    .remove({endpoint: request.body.endpoint})
    .write();
  response.sendStatus(200);
});

Envíe notificaciones

Como se explica en Enviar un mensaje push, tu servidor no envía realmente los mensajes push directamente a los clientes. sino que se basa en un servicio de envío para hacerlo. En pocas palabras, tu servidor inicia el proceso de envío de mensajes a los clientes realizando solicitudes de servicio web (solicitudes de protocolo push web) a un servicio web (el servicio de envío) que pertenece al proveedor del navegador que usa tu usuario.

  1. Actualiza la lógica del controlador de ruta /notify-me con el siguiente código:
app.post('/notify-me', (request, response) => {
  console.log('/notify-me');
  console.log(request.body);
  console.log(`Notifying ${request.body.endpoint}`);
  const subscription = 
      db.get('subscriptions').find({endpoint: request.body.endpoint}).value();
  sendNotifications([subscription]);
  response.sendStatus(200);
});
  1. Actualiza la función sendNotifications() con el siguiente código:
function sendNotifications(subscriptions) {
  // TODO
  // Create the notification content.
  const notification = JSON.stringify({
    title: "Hello, Notifications!",
    options: {
      body: `ID: ${Math.floor(Math.random() * 100)}`
    }
  });
  // Customize how the push service should attempt to deliver the push message.
  // And provide authentication information.
  const options = {
    TTL: 10000,
    vapidDetails: vapidDetails
  };
  // Send a push message to each client specified in the subscriptions array.
  subscriptions.forEach(subscription => {
    const endpoint = subscription.endpoint;
    const id = endpoint.substr((endpoint.length - 8), endpoint.length);
    webpush.sendNotification(subscription, notification, options)
      .then(result => {
        console.log(`Endpoint ID: ${id}`);
        console.log(`Result: ${result.statusCode}`);
      })
      .catch(error => {
        console.log(`Endpoint ID: ${id}`);
        console.log(`Error: ${error} `);
      });
  });
}
  1. Actualiza la lógica del controlador de ruta /notify-all con el siguiente código:
app.post('/notify-all', (request, response) => {
  console.log('/notify-all');
  response.sendStatus(200);
  console.log('Notifying all subscribers');
  const subscriptions =
      db.get('subscriptions').cloneDeep().value();
  if (subscriptions.length > 0) {
    sendNotifications(subscriptions);
    response.sendStatus(200);
  } else {
    response.sendStatus(409);
  }
});
  1. Regresa a la pestaña de la app.
  2. Haz clic en Anular la suscripción a las notificaciones push y, luego, vuelve a hacer clic en Suscribirse para enviar notificaciones. Esto solo es necesario porque, como se mencionó antes, Glitch reinicia el proyecto cada vez que editas el código y este se configura para borrar la base de datos al inicio.
  3. Haz clic en Notificarme. Deberías recibir una notificación push. El título debe ser Hello, Notifications!, y el cuerpo debe ser ID: <ID>, en el que <ID> es un número al azar.
  4. Abre tu app en otros navegadores o dispositivos, intenta suscribirlos a las notificaciones push y, luego, haz clic en el botón Notificar a todos. Deberías recibir la misma notificación en todos los dispositivos suscritos (es decir, el ID en el cuerpo de la notificación push debe ser el mismo).

Próximos pasos