Notificaciones Push Web
Notificación push web escrita en JavaScript puro sin ninguna biblioteca.

Daniel Gustaw
• 3 min read

Crear Proyecto Vite
pnpm create vite .
Instalar el paquete web-push
.
pnpm add web-push
Generar claves VAPID
pnpm web-push generate-vapid-keys --json > keys.json
También se puede hacer de manera programática mediante:
import fs from 'fs'
import push from 'web-push'
const keys = push.generateVAPIDKeys();
fs.writeFileSync('keys.json', JSON.stringify(keys, null, 2));
Obtener acuerdo sobre notificaciones
En la mayoría de las instrucciones verás Notification.requestPermission()
en este lugar.
Pero se puede simplificar. Podemos usar el método pushManager.subscribe()
descrito en:
- https://developer.mozilla.org/es/docs/Web/API/ServiceWorkerRegistration
- https://developer.mozilla.org/es/docs/Web/API/ServiceWorkerRegistration/pushManager
Para tener acceso a pushManager
debemos registrar el service worker.
Crear service worker
// public/sw.js
self.addEventListener('push', (message) => {
const payload = message.data.json();
console.log(payload);
self.registration
.showNotification(payload.title, {
body: payload.body,
})
.catch(console.error);
});
Ahora puedes registrar el service worker en tu script principal.
// src/main.ts
document.addEventListener('DOMContentLoaded', async () => {
await navigator.serviceWorker.register('sw.js');
})
Suscribirse a las notificaciones push
No podemos suscribirnos a las notificaciones después de cargar la página porque el usuario tiene que activarlo manualmente.
Vamos a crear un botón en main.ts
// src/main.ts
import {setupSubscription} from './subscription.ts'
document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
<div>
<div class="card">
<p>Agree on notifications</p>
<button id="subscribe" type="button">Subscribe</button>
</div>
</div>
`
setupSubscription(document.querySelector<HTMLButtonElement>('#subscribe')!)
y manejar clic en subscription.ts
// src/subscription.ts
export function setupSubscription(subscribeButton: HTMLButtonElement) {
console.log('subscribeButton', subscribeButton);
subscribeButton.addEventListener('click', async () => {
try {
const sw = await navigator.serviceWorker.ready;
const push = await sw.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: '<public vapid key>'
});
console.log(push.toJSON());
// TODO: Send subscription to server
} catch (err) {
console.error(err);
}
})
}
push
objeto impreso en la consola tiene que ser copiado al back-end en el siguiente paso. Hagámoslo manualmente por ahora.
Enviar notificaciones
Ahora vamos a escribir el back-end en Node.js.
import push from 'web-push'
import keys from './keys.json' assert { type: 'json' }
push.setVapidDetails('https://myapp.com', keys.publicKey, keys.privateKey);
// there should be object copied from browser console
let sub: push.PushSubscription = {
"endpoint": "https://jmt17.google.com/fcm/send/eeg8M0Ydr0Y:APA91bE5xr9wV2hLFyMuavOJFCQqqiTybLI30fWd8wOdAMvoITBfSgs-WW4LpUWw7kn7kTb39_ornJgNPb4gCcdh-AW9HEiY2qAP7eSiwpp0dmY__-ef4fcS3RUrAbLbI2hYgphaOjNz",
"expirationTime": null,
"keys": {
"p256dh": "BORNkcqyS0qf43f4Ph058C9pBB0tiLv9JTqjYWAVfLGs472aSlsPt0lNRMdioUU3HOUg4f2lHnog34FNV0Fi_1k",
"auth": "jJwCvDwpVTThRQd5beYWzg"
}
};
const payload = JSON.stringify({
title: "Hello World",
body: "This is your second push notification"
});
push
.sendNotification(sub, payload)
.catch(console.error);
Other articles
You can find interesting also.
![Pulumi - Infraestructura como Código [ Digital Ocean ]](/_astro/f370e14e-6fd0-48ef-b689-02d89d85bfb7_ZzxruJ.png)
Pulumi - Infraestructura como Código [ Digital Ocean ]
Con Pulumi, puedes definir tu infraestructura de TI en un archivo descrito por tu lenguaje de programación favorito. Este artículo muestra cómo hacerlo.

Daniel Gustaw
• 10 min read

Backend REST de Fastify Prisma
Plantilla de TypeScript para API REST de Fastify con autenticación JWT y Prisma.

Daniel Gustaw
• 7 min read

Visualización de una red de correlación dinámica.
Script de Python para visualizar la dinámica de la relación entre instrumentos financieros medidos por correlación.

Daniel Gustaw
• 16 min read