# NOTIF-001: Integración de Servicio de Email **Fecha:** 2025-12-05 **Estado:** ✅ COMPLETADO **Prioridad:** P1 ## Resumen Integración completa del servicio de email para notificaciones en GAMILIT. El sistema ahora soporta envío de emails a través de SMTP genérico o SendGrid con retry logic, templates HTML responsive y procesamiento asíncrono. ## Archivos Creados/Modificados ### Archivos Modificados 1. **`/apps/backend/src/modules/mail/mail.service.ts`** (REESCRITO) - Implementación completa con nodemailer - Soporte SMTP y SendGrid - Retry logic con backoff exponencial (3 intentos) - Métodos: `sendEmail()`, `sendNotificationEmail()`, `sendPasswordResetEmail()`, etc. - Verificación de disponibilidad con `isAvailable()` 2. **`/apps/backend/src/modules/notifications/services/notification-queue.service.ts`** - Agregado import de `MailService` - Inyección de `MailService` en constructor - Implementación completa de `sendToChannel('email')` (líneas 354-385) - Manejo de errores y validación de `userEmail` 3. **`/apps/backend/src/modules/notifications/notifications.module.ts`** - Agregado import de `MailModule` - `MailModule` agregado a imports array 4. **`/apps/backend/.env.production.example`** - Sección EMAIL (NOTIF-001) agregada con configuraciones SMTP y SendGrid - Documentación inline sobre prioridades y configuración ### Archivos Creados 5. **`/apps/backend/src/modules/mail/templates/base.template.ts`** (NUEVO) - Template HTML base responsive - Helpers: `baseEmailTemplate()`, `notificationTemplate()`, `featureBoxTemplate()`, `codeBoxTemplate()` - Estilos inline para compatibilidad con clientes de email 6. **`/apps/backend/src/modules/mail/templates/notification.templates.ts`** (NUEVO) - Templates específicos por tipo de notificación: - `achievementUnlockedTemplate()` - `assignmentDueTemplate()` - `assignmentReminderTemplate()` - `newMessageTemplate()` - `levelUpTemplate()` - `systemNotificationTemplate()` 7. **`/apps/backend/src/modules/mail/templates/index.ts`** (NUEVO) - Índice de exports de templates 8. **`/apps/backend/src/modules/mail/README.md`** (NUEVO) - Documentación completa del servicio - Guías de instalación y configuración - Ejemplos de uso - Troubleshooting 9. **`/apps/backend/NOTIF-001-EMAIL-INTEGRATION.md`** (ESTE ARCHIVO) ## Instalación ### 1. Instalar dependencias ```bash cd /home/isem/workspace/projects/gamilit/apps/backend npm install nodemailer npm install --save-dev @types/nodemailer ``` ### 2. Configurar variables de entorno Editar `.env.production` (o crear desde `.env.production.example`): #### Opción A: SMTP Genérico (Gmail, Outlook, etc.) ```env SMTP_HOST=smtp.gmail.com SMTP_PORT=587 SMTP_SECURE=false SMTP_USER=tu-email@gmail.com SMTP_PASS=tu-app-password SMTP_FROM=GAMILIT FRONTEND_URL=http://localhost:3005 ``` **Para Gmail:** 1. Ir a https://myaccount.google.com/apppasswords 2. Generar contraseña de aplicación 3. Usar esa contraseña en `SMTP_PASS` #### Opción B: SendGrid (Recomendado para producción) ```env SENDGRID_API_KEY=SG.xxxxxxxxxxxxxx SMTP_FROM=GAMILIT FRONTEND_URL=https://gamilit.com ``` **Configurar SendGrid:** 1. Crear cuenta en https://sendgrid.com 2. Ir a Settings > API Keys 3. Crear API Key con permisos de "Mail Send" 4. Copiar el key ### 3. Reiniciar backend ```bash npm run build npm run prod # O en desarrollo: npm run dev ``` ## Configuración de Prioridad El servicio usa esta prioridad automáticamente: 1. ✅ Si `SENDGRID_API_KEY` está configurado → **usa SendGrid** 2. ✅ Si `SMTP_HOST`, `SMTP_USER`, `SMTP_PASS` están configurados → **usa SMTP** 3. ⚠️ Si nada está configurado → **modo logging** (emails se loggean, no se envían) ## Uso ### Envío Automático (Sistema de Notificaciones) ```typescript // El email se envía automáticamente si el canal 'email' está incluido await notificationService.create({ userId: 'user-uuid', type: 'assignment', title: 'Nueva tarea asignada', message: 'Tienes una nueva tarea de Matemáticas', channels: ['in_app', 'email', 'push'], data: { userEmail: 'student@example.com', // REQUERIDO para emails actionUrl: 'https://gamilit.com/assignments/123', actionText: 'Ver tarea' } }); ``` ### Uso Directo ```typescript import { MailService } from '@/modules/mail/mail.service'; @Injectable() export class MiServicio { constructor(private readonly mailService: MailService) {} async enviarEmail() { // Verificar disponibilidad if (!this.mailService.isAvailable()) { console.log('Email service no configurado'); return; } // Email genérico await this.mailService.sendEmail( 'user@example.com', 'Asunto', '

Contenido HTML

' ); // Email de notificación con template await this.mailService.sendNotificationEmail( 'user@example.com', 'Título', 'Mensaje', 'https://gamilit.com/link', 'Ver más' ); } } ``` ## Templates Disponibles ```typescript import { achievementUnlockedTemplate, assignmentDueTemplate, assignmentReminderTemplate, newMessageTemplate, levelUpTemplate, systemNotificationTemplate } from '@/modules/mail/templates'; ``` Ver `/apps/backend/src/modules/mail/README.md` para ejemplos completos. ## Características Implementadas ✅ **SMTP Genérico** - Soporta Gmail, Outlook, servidores propios ✅ **SendGrid** - Integración via API Key (SMTP relay) ✅ **Retry Logic** - 3 intentos con backoff exponencial (1s, 3s, 9s) ✅ **Templates HTML** - Responsive con estilos inline ✅ **Graceful Degradation** - Si no hay config, loggea en lugar de fallar ✅ **Integración Automática** - Con NotificationQueueService ✅ **Procesamiento Asíncrono** - Cola con reintentos ✅ **Logging Completo** - Todos los envíos se registran ✅ **Templates Específicos** - Por tipo de notificación ## Testing ### Sin configuración (modo logging) Los emails se loggearán en consola: ``` [MailService] Email service initialized with SMTP [MailService] [MOCK EMAIL] To: user@example.com | Subject: Nueva tarea ``` ### Con configuración SMTP/SendGrid ``` [MailService] Email service initialized with SendGrid [MailService] Email sent successfully to user@example.com: ``` ### Testing con servicio temporal Servicios recomendados para testing: - [Mailtrap](https://mailtrap.io/) - SMTP de testing - [Ethereal Email](https://ethereal.email/) - SMTP temporal ## Datos Requeridos Para envío de emails, la notificación DEBE incluir en `data`: ```typescript { data: { userEmail: 'user@example.com', // ⚠️ REQUERIDO actionUrl: 'https://...', // Opcional actionText: 'Ver más' // Opcional } } ``` ## Flujo de Procesamiento ``` 1. Crear notificación con canal 'email' ↓ 2. NotificationService la guarda en DB ↓ 3. NotificationService encola en NotificationQueue ↓ 4. Worker (cron) procesa cola periódicamente ↓ 5. NotificationQueueService.sendToChannel('email') ↓ 6. MailService.sendNotificationEmail() con retry ↓ 7. Resultado se registra en notification_logs ``` ## Verificación ### 1. Verificar instalación de dependencias ```bash npm list nodemailer ``` Debe mostrar: `nodemailer@X.X.X` ### 2. Verificar configuración Al iniciar el backend, debe aparecer uno de estos logs: ``` [MailService] Email service initialized with SendGrid [MailService] Email service initialized with SMTP [MailService] SMTP credentials not configured. Emails will be logged only. ``` ### 3. Probar envío Crear una notificación con canal email desde el frontend o API. ## Solución de Problemas ### Emails no se envían 1. ✅ Verificar variables de entorno configuradas 2. ✅ Revisar logs: `[MailService]` 3. ✅ Verificar que `notification.data.userEmail` existe 4. ✅ Verificar credenciales SMTP/SendGrid ### Error: "Invalid login" - Gmail: Usar App Password, no contraseña normal - Verificar `SMTP_USER` y `SMTP_PASS` ### Emails van a spam - Configurar SPF, DKIM, DMARC en dominio - Usar servicio profesional (SendGrid) - Verificar dominio del remitente ## Seguridad ⚠️ **IMPORTANTE:** - NO hardcodear credenciales en código - Usar variables de entorno - En producción: `chmod 600 .env.production` - Rotar API keys periódicamente - Usar SendGrid en producción (más confiable) ## Próximos Pasos ### Configuración Inmediata 1. ✅ Instalar nodemailer: `npm install nodemailer @types/nodemailer` 2. ✅ Configurar variables de entorno (SMTP o SendGrid) 3. ✅ Reiniciar backend 4. ✅ Probar enviando una notificación ### Mejoras Futuras (Opcional) - [ ] Soporte para attachments - [ ] Templates con Handlebars/Pug - [ ] Internacionalización (i18n) - [ ] Rate limiting por destinatario - [ ] Dashboard de analytics - [ ] Testing automatizado con Jest ## Referencias - **Documentación completa:** `/apps/backend/src/modules/mail/README.md` - **Templates:** `/apps/backend/src/modules/mail/templates/` - **Variables de entorno:** `/apps/backend/.env.production.example` ## Contacto Para soporte o preguntas, contactar al equipo de desarrollo Backend. --- **Estado:** ✅ COMPLETADO **Última actualización:** 2025-12-05