Saltar a contenido

Configuración de email

Cómo configurar el envío de emails transaccionales (invitaciones, recordatorios de evaluación, reset de contraseña, etc.).

Modelo de dos niveles

TenantEmailSettings (configuración del tenant)
    │
    │ Si está deshabilitado o falla
    ▼
PlatformEmailSettings (fallback global del SystemAdmin)
    │
    │ Si tampoco está habilitado
    ▼
Email NO se envía (queda en log)

Cada tenant decide: - Usar el SMTP global del SystemAdmin (sin setup técnico de su lado, más rápido) - Configurar su propio proveedor (más control, dirección remitente propia, mejor entregabilidad)

Proveedores soportados

Cuatro opciones (EmailProvider enum):

Proveedor Cuándo conviene
UseFallback Default. Usa el SMTP global de plataforma sin configurar nada
Smtp SMTP corporativo (Office 365 con SMTP Auth, SendGrid SMTP, Mailgun SMTP, servidor propio)
MicrosoftOAuth Microsoft 365 con OAuth (sin password — cliente Azure AD con Mail.Send)
GoogleOAuth Google Workspace con OAuth (refresh token)

Configuración a nivel tenant

Email del tenant (menú lateral, rol TenantAdmin).

A) UseFallback (default)

Sin configuración. Tu tenant usa el SMTP global. La dirección remitente es la que configuró el SystemAdmin (ej. noreply@eval360pro.com).

Pros: cero setup. Contras: no se ve "tuyo".

B) SMTP

Campos:

Campo Detalle
Host ej. smtp.office365.com, smtp.sendgrid.net, smtp.gmail.com
Puerto 587 (STARTTLS) o 465 (SSL/TLS)
SSL/TLS Habilitar para 465; STARTTLS automático en 587
Username Usuario SMTP
Password Contraseña o app-password
From address Email remitente (puede requerir verificación en proveedor)
From display name Nombre visible (ej. "Equipo de RR.HH. Acme")

Click Enviar prueba → ingresar email destinatario → si llega, está OK.

La contraseña se guarda encriptada (AES-256) en DB. Solo se descifra en runtime.

C) Microsoft Graph (OAuth)

Pre-requisito: tener una app registration en Azure AD con permiso Mail.Send de tipo Application (no delegated), con admin consent.

Campos:

Campo Detalle
Tenant ID (Azure) GUID del tenant Azure AD
Client ID App ID de la app registration
Client Secret Secret generado en la app registration
User ID UPN o GUID del buzón emisor (ej. noreply@acme.com)
From display name Nombre visible

Botón Enviar prueba valida el flujo OAuth + envío.

El client secret se guarda encriptado.

D) Gmail OAuth

Pre-requisito: tener una OAuth app en Google Cloud Console con scope https://www.googleapis.com/auth/gmail.send, y haber obtenido un refresh token vía OAuth dance (suele ser un script one-shot que el admin corre).

Campos:

Campo Detalle
Client ID OAuth client ID de Google Cloud
Client Secret OAuth client secret
Refresh Token Token de refresh obtenido en el OAuth dance inicial
From address Email remitente (debe ser el del usuario que autorizó)
From display name Nombre visible

Botón Enviar prueba.

Client secret y refresh token se guardan encriptados.

Configuración a nivel plataforma (SystemAdmin)

Email plataforma (fallback) — solo SystemAdmin.

Mismo formulario que un tenant tendría, pero el scope es global: - Habilitado / deshabilitado - From address, display name - Host, puerto, SSL - Usuario, contraseña

Si está deshabilitado y un tenant no tiene SMTP propio, los emails fallan (queda en log de Serilog como EMAIL_FAIL).

Recomendación: configurar el fallback de plataforma con un SMTP confiable (SendGrid, Mailgun) para que los tenants nuevos (que aún no configuraron nada) sigan recibiendo emails.

Plantillas de email

Las plantillas (qué dice cada email) se gestionan aparte:

  • TenantAdmin / HRManagerPlantillas de email → personalizar para su tenant
  • SystemAdminPlantillas email (plataforma) → editar el default global

Ver Quickstart TenantAdmin — sección 5 para el editor en detalle.

Eventos donde se dispara email

Evento Plantilla Destinatarios
Crear empleado con cuenta invitation El nuevo empleado
Abrir un ciclo de evaluación cycle-opened Todos los evaluadores con al menos una evaluación pendiente
Recordatorio manual antes del deadline deadline-reminder Evaluadores con evaluaciones aún no enviadas
Cerrar ciclo / publicar resultados results-published Los subjects (los evaluados)
Crear/aprobar plan de desarrollo plan-assigned El empleado del plan
Solicitar reset de contraseña password-reset El usuario que lo solicitó

Encriptación de secretos

Todas las contraseñas, secrets y refresh tokens (de SMTP, Microsoft Graph, Gmail) se almacenan cifrados con AES-256-CBC.

La clave maestra (Email.MasterKey) se carga desde appsettings.Production.json o variables de entorno. No se commitea en el repo. Si esa clave cambia, los secretos guardados antes dejan de poder descifrarse y hay que re-ingresarlos.

Generar una key nueva (32 bytes en base64):

[Convert]::ToBase64String([System.Security.Cryptography.RandomNumberGenerator]::GetBytes(32))

Troubleshooting

Problema Causa típica
Test de SMTP devuelve "Authentication failed" Usuario o contraseña mal · cuenta requiere app-password (Office 365 con MFA) · SMTP Auth deshabilitado en el tenant
Test de Microsoft Graph devuelve 403 Permiso Mail.Send no tiene admin consent · User ID no existe o no tiene mailbox
Test de Gmail devuelve "invalid_grant" Refresh token expirado o revocado por Google · re-hacer OAuth dance
Emails no llegan pero el test dice OK Spam folder · email remitente sin SPF/DKIM/DMARC · IP del SMTP en blacklist
Error "Email:MasterKey debe ser de 32 bytes" La clave maestra en appsettings tiene el largo equivocado al decodificar base64. Generar de nuevo