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
Markdown
# 📦 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/)