UNPKG

backend-mcp

Version:

Generador automático de backends con Node.js, Express, Prisma y módulos configurables. Servidor MCP compatible con npx para agentes IA. Soporta PostgreSQL, MySQL, MongoDB y SQLite.

728 lines (607 loc) 18.7 kB
# 📦 Módulo notifications **Versión:** 1.0.0 **Categoría:** communication **Descripción:** Sistema completo de notificaciones multi-canal con soporte para push, email, SMS, in-app y webhooks ## 📊 Estado del Módulo | Componente | Estado | |------------|--------| | Script de inicialización | ✅ Disponible | | Templates | ❌ Faltante | | Ejemplos | ❌ Faltante | ## 🔗 Dependencias ### Requeridas - `database` ### Opcionales - `auth` - `logging` - `cache` - `websockets` - `email` - `queue` ## 📖 Documentación Completa # Notifications Module Multi-channel notification system for MCP Backend framework supporting email, SMS, push notifications, and webhooks. ## Features - ✅ Email notifications (SMTP, SendGrid, AWS SES) - ✅ SMS notifications (Twilio, AWS SNS) - ✅ Push notifications (Firebase, Apple Push, Web Push) - ✅ Webhook notifications - ✅ In-app notifications - ✅ Notification templates and personalization - ✅ Delivery tracking and analytics - ✅ Retry mechanisms and failure handling - ✅ Rate limiting and throttling - ✅ Notification preferences and subscriptions ## Installation This module is automatically installed when using the MCP Backend Generator. ## Configuration ### Environment Variables **General Configuration:** - `NOTIFICATIONS_ENABLED` (optional) - Enable notifications (default: true) - `NOTIFICATIONS_QUEUE_ENABLED` (optional) - Enable queue processing (default: true) - `NOTIFICATIONS_RETRY_ATTEMPTS` (optional) - Max retry attempts (default: 3) - `NOTIFICATIONS_RETRY_DELAY` (optional) - Retry delay in ms (default: 5000) **Email Configuration:** - `EMAIL_PROVIDER` (optional) - Email provider: smtp|sendgrid|ses (default: smtp) - `EMAIL_FROM_ADDRESS` (required) - Default sender email - `EMAIL_FROM_NAME` (optional) - Default sender name **SMTP Configuration:** - `SMTP_HOST` (required if using SMTP) - SMTP server host - `SMTP_PORT` (optional) - SMTP server port (default: 587) - `SMTP_SECURE` (optional) - Use TLS (default: true) - `SMTP_USER` (required if using SMTP) - SMTP username - `SMTP_PASSWORD` (required if using SMTP) - SMTP password **SendGrid Configuration:** - `SENDGRID_API_KEY` (required if using SendGrid) - SendGrid API key - `SENDGRID_TEMPLATE_ID` (optional) - Default template ID **AWS SES Configuration:** - `AWS_SES_REGION` (required if using SES) - AWS region - `AWS_SES_ACCESS_KEY_ID` (required if using SES) - AWS access key - `AWS_SES_SECRET_ACCESS_KEY` (required if using SES) - AWS secret key **SMS Configuration:** - `SMS_PROVIDER` (optional) - SMS provider: twilio|sns (default: twilio) - `TWILIO_ACCOUNT_SID` (required if using Twilio) - Twilio account SID - `TWILIO_AUTH_TOKEN` (required if using Twilio) - Twilio auth token - `TWILIO_PHONE_NUMBER` (required if using Twilio) - Twilio phone number **Push Notifications:** - `FIREBASE_PROJECT_ID` (required for Firebase) - Firebase project ID - `FIREBASE_PRIVATE_KEY` (required for Firebase) - Firebase private key - `FIREBASE_CLIENT_EMAIL` (required for Firebase) - Firebase client email - `APNS_KEY_ID` (required for Apple Push) - Apple Push key ID - `APNS_TEAM_ID` (required for Apple Push) - Apple Push team ID - `APNS_PRIVATE_KEY` (required for Apple Push) - Apple Push private key **Webhook Configuration:** - `WEBHOOK_TIMEOUT` (optional) - Webhook timeout in ms (default: 10000) - `WEBHOOK_RETRY_ATTEMPTS` (optional) - Webhook retry attempts (default: 3) ### Configuration File ```typescript // src/config/notifications.ts export const notificationsConfig = { enabled: process.env.NOTIFICATIONS_ENABLED !== 'false', queueEnabled: process.env.NOTIFICATIONS_QUEUE_ENABLED !== 'false', retryAttempts: parseInt(process.env.NOTIFICATIONS_RETRY_ATTEMPTS || '3'), retryDelay: parseInt(process.env.NOTIFICATIONS_RETRY_DELAY || '5000'), email: { provider: process.env.EMAIL_PROVIDER || 'smtp', fromAddress: process.env.EMAIL_FROM_ADDRESS, fromName: process.env.EMAIL_FROM_NAME || 'MCP Backend', smtp: { host: process.env.SMTP_HOST, port: parseInt(process.env.SMTP_PORT || '587'), secure: process.env.SMTP_SECURE !== 'false', auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASSWORD } }, sendgrid: { apiKey: process.env.SENDGRID_API_KEY, templateId: process.env.SENDGRID_TEMPLATE_ID }, ses: { region: process.env.AWS_SES_REGION, accessKeyId: process.env.AWS_SES_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SES_SECRET_ACCESS_KEY } }, sms: { provider: process.env.SMS_PROVIDER || 'twilio', twilio: { accountSid: process.env.TWILIO_ACCOUNT_SID, authToken: process.env.TWILIO_AUTH_TOKEN, phoneNumber: process.env.TWILIO_PHONE_NUMBER } }, push: { firebase: { projectId: process.env.FIREBASE_PROJECT_ID, privateKey: process.env.FIREBASE_PRIVATE_KEY, clientEmail: process.env.FIREBASE_CLIENT_EMAIL }, apns: { keyId: process.env.APNS_KEY_ID, teamId: process.env.APNS_TEAM_ID, privateKey: process.env.APNS_PRIVATE_KEY } }, webhook: { timeout: parseInt(process.env.WEBHOOK_TIMEOUT || '10000'), retryAttempts: parseInt(process.env.WEBHOOK_RETRY_ATTEMPTS || '3') } }; ``` ## Usage ### Basic Notification Sending ```typescript import { notificationService } from './services/notification'; // Send email notification await notificationService.sendEmail({ to: 'user@example.com', subject: 'Welcome to our platform!', template: 'welcome', data: { userName: 'John Doe', activationLink: 'https://example.com/activate/123' } }); // Send SMS notification await notificationService.sendSMS({ to: '+1234567890', message: 'Your verification code is: 123456' }); // Send push notification await notificationService.sendPush({ to: 'device_token_123', title: 'New Message', body: 'You have received a new message', data: { messageId: '123', type: 'chat' } }); // Send webhook notification await notificationService.sendWebhook({ url: 'https://api.example.com/webhook', method: 'POST', headers: { 'Authorization': 'Bearer token123', 'Content-Type': 'application/json' }, data: { event: 'user.created', userId: '123', timestamp: new Date().toISOString() } }); ``` ### Template-Based Notifications ```typescript // Define email templates const emailTemplates = { welcome: { subject: 'Welcome to {{appName}}!', html: ` <h1>Welcome {{userName}}!</h1> <p>Thank you for joining {{appName}}.</p> <a href="{{activationLink}}">Activate your account</a> `, text: ` Welcome {{userName}}! Thank you for joining {{appName}}. Activate your account: {{activationLink}} ` }, passwordReset: { subject: 'Reset your password', html: ` <h1>Password Reset Request</h1> <p>Click the link below to reset your password:</p> <a href="{{resetLink}}">Reset Password</a> <p>This link expires in {{expirationTime}} minutes.</p> `, text: ` Password Reset Request Click the link below to reset your password: {{resetLink}} This link expires in {{expirationTime}} minutes. ` } }; // Send templated email await notificationService.sendEmail({ to: 'user@example.com', template: 'welcome', data: { userName: 'John Doe', appName: 'MCP Backend', activationLink: 'https://example.com/activate/123' } }); // Send templated SMS const smsTemplates = { verification: 'Your {{appName}} verification code is: {{code}}', reminder: 'Hi {{userName}}, you have {{count}} pending notifications.' }; await notificationService.sendSMS({ to: '+1234567890', template: 'verification', data: { appName: 'MCP Backend', code: '123456' } }); ``` ### Bulk Notifications ```typescript // Send bulk emails await notificationService.sendBulkEmail({ recipients: [ { email: 'user1@example.com', data: { userName: 'User 1' } }, { email: 'user2@example.com', data: { userName: 'User 2' } }, { email: 'user3@example.com', data: { userName: 'User 3' } } ], template: 'newsletter', data: { newsletterTitle: 'Monthly Update', unsubscribeLink: 'https://example.com/unsubscribe' } }); // Send bulk push notifications await notificationService.sendBulkPush({ tokens: ['token1', 'token2', 'token3'], title: 'App Update Available', body: 'A new version of the app is available for download', data: { type: 'app_update', version: '2.1.0' } }); ``` ### Notification Preferences ```typescript import { preferencesService } from './services/preferences'; // Set user notification preferences await preferencesService.setPreferences('user123', { email: { marketing: false, transactional: true, security: true }, sms: { marketing: false, transactional: true, security: true }, push: { marketing: true, transactional: true, security: true } }); // Get user preferences const preferences = await preferencesService.getPreferences('user123'); // Send notification respecting preferences await notificationService.sendNotification({ userId: 'user123', type: 'marketing', channels: ['email', 'push'], template: 'newsletter', data: { content: 'Newsletter content' } }); ``` ### Scheduled Notifications ```typescript import { schedulerService } from './services/scheduler'; // Schedule a notification const scheduledNotification = await schedulerService.schedule({ userId: 'user123', type: 'reminder', channels: ['email'], template: 'appointment_reminder', data: { appointmentDate: '2023-12-15T10:00:00Z', doctorName: 'Dr. Smith' }, scheduledFor: new Date('2023-12-14T18:00:00Z') // Send 16 hours before }); // Schedule recurring notification await schedulerService.scheduleRecurring({ userId: 'user123', type: 'weekly_report', channels: ['email'], template: 'weekly_report', cron: '0 9 * * 1', // Every Monday at 9 AM data: { reportType: 'weekly' } }); // Cancel scheduled notification await schedulerService.cancel(scheduledNotification.id); ``` ### Notification Tracking ```typescript import { trackingService } from './services/tracking'; // Send notification with tracking const notification = await notificationService.sendEmail({ to: 'user@example.com', subject: 'Important Update', template: 'update', data: { updateInfo: 'New features available' }, tracking: { enabled: true, trackOpens: true, trackClicks: true } }); // Get notification status const status = await trackingService.getStatus(notification.id); console.log(status); // { // id: 'notif_123', // status: 'delivered', // sentAt: '2023-12-01T10:00:00Z', // deliveredAt: '2023-12-01T10:00:05Z', // openedAt: '2023-12-01T10:15:00Z', // clickedAt: '2023-12-01T10:16:00Z', // attempts: 1, // channel: 'email' // } // Get delivery analytics const analytics = await trackingService.getAnalytics({ userId: 'user123', dateFrom: '2023-12-01', dateTo: '2023-12-31' }); console.log(analytics); // { // sent: 150, // delivered: 145, // opened: 89, // clicked: 23, // bounced: 3, // failed: 2, // deliveryRate: 0.967, // openRate: 0.614, // clickRate: 0.259 // } ``` ### Queue Processing ```typescript import { queueService } from './services/queue'; // Add notification to queue await queueService.add('email', { to: 'user@example.com', subject: 'Queued Email', template: 'queued', data: { message: 'This email was queued' } }, { priority: 'high', delay: 5000, // Send after 5 seconds attempts: 3 }); // Process queue with workers queueService.process('email', async (job) => { const { data } = job; try { await notificationService.sendEmail(data); console.log(`Email sent to ${data.to}`); } catch (error) { console.error(`Failed to send email to ${data.to}:`, error); throw error; // Will trigger retry } }); // Monitor queue status const queueStats = await queueService.getStats('email'); console.log(queueStats); // { // waiting: 5, // active: 2, // completed: 150, // failed: 3, // delayed: 1 // } ``` ### Rate Limiting ```typescript import { rateLimitService } from './services/rateLimit'; // Configure rate limits rateLimitService.setLimits({ email: { perUser: { count: 10, window: '1h' }, global: { count: 1000, window: '1h' } }, sms: { perUser: { count: 5, window: '1h' }, global: { count: 500, window: '1h' } }, push: { perUser: { count: 50, window: '1h' }, global: { count: 10000, window: '1h' } } }); // Check rate limit before sending const canSend = await rateLimitService.checkLimit('email', 'user123'); if (canSend) { await notificationService.sendEmail(emailData); } else { console.log('Rate limit exceeded for user123'); } ``` ### Webhook Handlers ```typescript import { webhookService } from './services/webhook'; import express from 'express'; const app = express(); // Handle email delivery webhooks (SendGrid) app.post('/webhooks/sendgrid', express.json(), async (req, res) => { const events = req.body; for (const event of events) { await webhookService.handleEmailEvent({ provider: 'sendgrid', eventType: event.event, messageId: event.sg_message_id, email: event.email, timestamp: new Date(event.timestamp * 1000), reason: event.reason }); } res.status(200).send('OK'); }); // Handle SMS delivery webhooks (Twilio) app.post('/webhooks/twilio', express.urlencoded({ extended: true }), async (req, res) => { await webhookService.handleSMSEvent({ provider: 'twilio', eventType: req.body.MessageStatus, messageId: req.body.MessageSid, phoneNumber: req.body.To, timestamp: new Date(), errorCode: req.body.ErrorCode }); res.status(200).send('OK'); }); ``` ### In-App Notifications ```typescript import { inAppService } from './services/inApp'; // Create in-app notification await inAppService.create({ userId: 'user123', title: 'New Feature Available', message: 'Check out our new dashboard feature!', type: 'info', actionUrl: '/dashboard/new-feature', expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000) // 7 days }); // Get user's in-app notifications const notifications = await inAppService.getForUser('user123', { unreadOnly: true, limit: 10 }); // Mark notification as read await inAppService.markAsRead('notification123'); // Mark all notifications as read for user await inAppService.markAllAsRead('user123'); // Delete notification await inAppService.delete('notification123'); ``` ### Real-time Notifications (WebSocket) ```typescript import { realtimeService } from './services/realtime'; import { Server } from 'socket.io'; // Initialize WebSocket server const io = new Server(server); realtimeService.initialize(io); // Send real-time notification await realtimeService.sendToUser('user123', { type: 'notification', title: 'New Message', message: 'You have received a new message', data: { messageId: '123', senderId: 'user456' } }); // Send to multiple users await realtimeService.sendToUsers(['user123', 'user456'], { type: 'announcement', title: 'System Maintenance', message: 'Scheduled maintenance will begin in 30 minutes' }); // Send to room/channel await realtimeService.sendToRoom('chat:room123', { type: 'message', data: { messageId: '123', content: 'Hello everyone!', senderId: 'user123' } }); ``` ## Testing ```typescript // tests/notifications.test.ts import { notificationService } from '../src/services/notification'; import { mockEmailProvider } from '../src/providers/email/mock'; describe('Notification Service', () => { beforeEach(() => { // Use mock providers for testing notificationService.setEmailProvider(mockEmailProvider); }); it('should send email notification', async () => { const result = await notificationService.sendEmail({ to: 'test@example.com', subject: 'Test Email', template: 'test', data: { name: 'Test User' } }); expect(result.success).toBe(true); expect(result.messageId).toBeDefined(); }); it('should respect user preferences', async () => { await preferencesService.setPreferences('user123', { email: { marketing: false } }); const result = await notificationService.sendNotification({ userId: 'user123', type: 'marketing', channels: ['email'], template: 'newsletter', data: {} }); expect(result.sent).toBe(false); expect(result.reason).toBe('user_preferences'); }); it('should handle delivery failures', async () => { mockEmailProvider.setShouldFail(true); const result = await notificationService.sendEmail({ to: 'test@example.com', subject: 'Test Email', template: 'test', data: {} }); expect(result.success).toBe(false); expect(result.error).toBeDefined(); }); }); ``` ```bash npm test -- notifications ``` ## Dependencies - nodemailer (SMTP email) - @sendgrid/mail (SendGrid) - aws-sdk (AWS SES/SNS) - twilio (SMS) - firebase-admin (Push notifications) - node-apn (Apple Push) - web-push (Web Push) - bull (Queue processing) - socket.io (Real-time notifications) - handlebars (Template engine) ## Integration - Integrates with auth module for user-based notifications - Uses database module for storing preferences and tracking - Integrates with logging module for audit trails - Works with monitoring module for delivery analytics ## Error Handling - `NotificationDeliveryError`: Failed to deliver notification - `TemplateNotFoundError`: Template not found - `RateLimitExceededError`: Rate limit exceeded - `InvalidRecipientError`: Invalid recipient address - `ProviderConfigurationError`: Provider not configured - `WebhookVerificationError`: Webhook verification failed ## Best Practices 1. **Template Management**: Use version-controlled templates 2. **Rate Limiting**: Implement appropriate rate limits 3. **Error Handling**: Always handle delivery failures gracefully 4. **User Preferences**: Respect user notification preferences 5. **Testing**: Test with mock providers in development 6. **Monitoring**: Track delivery rates and performance 7. **Security**: Validate webhook signatures 8. **Compliance**: Follow email marketing regulations (CAN-SPAM, GDPR) ## License MIT ## 🔗 Enlaces - [Volver al índice de módulos](./README.md) - [Documentación principal](../README.md) - [Código fuente](../../modules/notifications/)