En esta publicación, aprenderá cómo implementar notificaciones push usando JavaScript siguiendo las mejores prácticas de nivel de producción. Una de las mejores cosas es que también proporcionaré una estructura de carpetas para que puedas configurar tu proyecto fácilmente.
La configuración de notificaciones automáticas en una aplicación del mundo real requiere una planificación cuidadosa. Le mostraré cómo crear esta función en una aplicación Node.js profesional. Cubriremos partes importantes como cómo organizar tu código, mantener todo seguro y asegurarnos de que funcione bien incluso a medida que tu aplicación crece.
Para comenzar, necesita una biblioteca que le ayude a enviar notificaciones automáticas desde su servidor Node.js. La biblioteca web-push proporciona herramientas para enviar notificaciones y administrar las claves necesarias.
Primero, configuremos la estructura del proyecto para mantener una base de código limpia y escalable:
/notification-service ├── /config │ ├── default.js │ └── production.js ├── /controllers │ └── notificationController.js ├── /models │ └── user.js ├── /routes │ └── notificationRoutes.js ├── /services │ ├── notificationService.js │ ├── subscriptionService.js │ └── webPushService.js ├── /utils │ └── errorHandler.js ├── /tests │ └── notification.test.js ├── app.js ├── package.json ├── .env └── README.md
Antes de profundizar en la implementación, asegúrese de tener instalados los siguientes paquetes de NPM:
bash npm install express mongoose web-push dotenv supertest
Crear archivos de configuración para diferentes entornos (por ejemplo, desarrollo, producción). Estos archivos almacenan configuraciones específicas del entorno.
// /config/default.js module.exports = { server: { port: 3000, env: 'development' }, pushNotifications: { publicVapidKey: process.env.VAPID_PUBLIC_KEY, privateVapidKey: process.env.VAPID_PRIVATE_KEY, gcmApiKey: process.env.GCM_API_KEY }, db: { uri: process.env.MONGO_URI } };
// /config/production.js module.exports = { server: { port: process.env.PORT || 3000, env: 'production' }, // Same structure as default, with production-specific values };
Utiliza Mongoose para definir tu esquema de usuario y suscripciones de notificaciones.
// /models/user.js const mongoose = require('mongoose'); const subscriptionSchema = new mongoose.Schema({ endpoint: String, keys: { p256dh: String, auth: String } }); const userSchema = new mongoose.Schema({ email: { type: String, required: true, unique: true }, subscriptions: [subscriptionSchema], preferences: { pushNotifications: { type: Boolean, default: true } } }); module.exports = mongoose.model('User', userSchema);
Modularizar la lógica para manejar notificaciones en servicios.
// /services/webPushService.js const webPush = require('web-push'); const config = require('config'); webPush.setVapidDetails( 'mailto:[email protected]', config.get('pushNotifications.publicVapidKey'), config.get('pushNotifications.privateVapidKey') ); module.exports = { sendNotification: async (subscription, payload) => { try { await webPush.sendNotification(subscription, JSON.stringify(payload)); } catch (error) { console.error('Error sending notification', error); } } };
// /services/notificationService.js const User = require('../models/user'); const webPushService = require('./webPushService'); module.exports = { sendPushNotifications: async (userId, payload) => { const user = await User.findById(userId); if (user && user.preferences.pushNotifications) { user.subscriptions.forEach(subscription => { webPushService.sendNotification(subscription, payload); }); } } };
Manejar rutas API e integrar servicios.
// /controllers/notificationController.js const notificationService = require('../services/notificationService'); exports.sendNotification = async (req, res, next) => { try { const { userId, title, body } = req.body; const payload = { title, body }; await notificationService.sendPushNotifications(userId, payload); res.status(200).json({ message: 'Notification sent successfully' }); } catch (error) { next(error); } };
Configura rutas para tu API.
// /routes/notificationRoutes.js const express = require('express'); const router = express.Router(); const notificationController = require('../controllers/notificationController'); router.post('/send', notificationController.sendNotification); module.exports = router;
Centraliza el manejo de errores para garantizar que la aplicación no falle.
// /utils/errorHandler.js module.exports = (err, req, res, next) => { console.error(err.stack); res.status(500).send({ error: 'Something went wrong!' }); };
Inicializa la aplicación y conéctate a la base de datos.
// app.js const express = require('express'); const mongoose = require('mongoose'); const config = require('config'); const notificationRoutes = require('./routes/notificationRoutes'); const errorHandler = require('./utils/errorHandler'); const app = express(); app.use(express.json()); app.use('/api/notifications', notificationRoutes); app.use(errorHandler); mongoose.connect(config.get('db.uri'), { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => console.log('MongoDB connected...')) .catch(err => console.error('MongoDB connection error:', err)); const PORT = config.get('server.port'); app.listen(PORT, () => console.log(`Server running in ${config.get('server.env')} mode on port ${PORT}`));
Escriba pruebas para garantizar que su servicio funcione como se espera en diversas condiciones.
// /tests/notification.test.js const request = require('supertest'); const app = require('../app'); describe('Notification API', () => { it('should send a notification', async () => { const res = await request(app) .post('/api/notifications/send') .send({ userId: 'someUserId', title: 'Test', body: 'This is a test' }); expect(res.statusCode).toEqual(200); expect(res.body.message).toBe('Notification sent successfully'); }); });
Esta configuración de nivel de producción garantiza que su sistema de notificaciones push sea escalable, seguro y mantenible. El código está organizado para permitir pruebas, implementación y monitoreo sencillos, siguiendo las mejores prácticas de la industria. Si tiene más preguntas o necesita detalles de implementación específicos, ¡no dude en preguntar!
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3