Files
wallabicher/web/backend/services/webPush.js

80 lines
2.5 KiB
JavaScript

import webpush from 'web-push';
import { readFileSync, writeFileSync, existsSync } from 'fs';
import { PATHS, VAPID_CONTACT } from '../config/constants.js';
import { readJSON, writeJSON } from '../utils/fileUtils.js';
let vapidKeys = null;
// Inicializar VAPID keys para Web Push
export function initVAPIDKeys() {
try {
if (existsSync(PATHS.VAPID_KEYS)) {
vapidKeys = JSON.parse(readFileSync(PATHS.VAPID_KEYS, 'utf8'));
console.log('✅ VAPID keys cargadas desde archivo');
} else {
// Generar nuevas VAPID keys
vapidKeys = webpush.generateVAPIDKeys();
writeFileSync(PATHS.VAPID_KEYS, JSON.stringify(vapidKeys, null, 2), 'utf8');
console.log('✅ Nuevas VAPID keys generadas y guardadas');
}
// Configurar web-push con las VAPID keys
webpush.setVapidDetails(
VAPID_CONTACT,
vapidKeys.publicKey,
vapidKeys.privateKey
);
} catch (error) {
console.error('Error inicializando VAPID keys:', error.message);
}
}
// Obtener clave pública VAPID
export function getPublicKey() {
if (!vapidKeys || !vapidKeys.publicKey) {
throw new Error('VAPID keys no están configuradas');
}
return vapidKeys.publicKey;
}
// Obtener suscripciones push guardadas
export function getPushSubscriptions() {
return readJSON(PATHS.PUSH_SUBSCRIPTIONS, []);
}
// Guardar suscripciones push
export function savePushSubscriptions(subscriptions) {
return writeJSON(PATHS.PUSH_SUBSCRIPTIONS, subscriptions);
}
// Enviar notificación push a todas las suscripciones
export async function sendPushNotifications(notificationData) {
const subscriptions = getPushSubscriptions();
if (subscriptions.length === 0) {
return;
}
const payload = JSON.stringify(notificationData);
const promises = subscriptions.map(async (subscription) => {
try {
await webpush.sendNotification(subscription, payload);
console.log('✅ Notificación push enviada');
} catch (error) {
console.error('Error enviando notificación push:', error);
// Si la suscripción es inválida (404, 410), eliminarla
if (error.statusCode === 404 || error.statusCode === 410) {
const updatedSubscriptions = getPushSubscriptions().filter(
sub => sub.endpoint !== subscription.endpoint
);
savePushSubscriptions(updatedSubscriptions);
console.log(`Suscripción inválida eliminada. Total: ${updatedSubscriptions.length}`);
}
}
});
await Promise.allSettled(promises);
}