| id |
type |
title |
provider |
status |
integration_type |
created_at |
updated_at |
simco_version |
tags |
| INT-010 |
Integration |
Email Multi-Provider |
SendGrid/SES/SMTP |
Planificado |
notifications |
2026-01-10 |
2026-01-10 |
4.0.1 |
| email |
| notifications |
| transactional |
| multi-provider |
|
INT-010: Email Multi-Provider
Metadata
| Campo |
Valor |
| Codigo |
INT-010 |
| Proveedor |
SendGrid, AWS SES, SMTP |
| Tipo |
Notificaciones |
| Estado |
Planificado |
| Multi-tenant |
Si |
| Epic Relacionada |
MCH-029 |
| Owner |
Backend Team |
1. Descripcion
Sistema de envio de emails transaccionales con soporte para multiples proveedores y fallback automatico. Incluye templates reutilizables, tracking de entrega y rate limiting por tenant.
Casos de uso principales:
- Emails de bienvenida y verificacion
- Notificaciones de pedidos
- Recordatorios de pago
- Alertas de inventario bajo
- Reportes programados
2. Credenciales Requeridas
Variables de Entorno
| Variable |
Descripcion |
Tipo |
Obligatorio |
EMAIL_PROVIDER |
Proveedor principal (sendgrid/ses/smtp) |
string |
SI |
SENDGRID_API_KEY |
API Key de SendGrid |
string |
SI (si usa SendGrid) |
AWS_SES_REGION |
Region de AWS SES |
string |
SI (si usa SES) |
AWS_SES_ACCESS_KEY |
Access Key para SES |
string |
SI (si usa SES) |
AWS_SES_SECRET_KEY |
Secret Key para SES |
string |
SI (si usa SES) |
SMTP_HOST |
Host del servidor SMTP |
string |
SI (si usa SMTP) |
SMTP_PORT |
Puerto SMTP |
number |
SI (si usa SMTP) |
SMTP_USER |
Usuario SMTP |
string |
SI (si usa SMTP) |
SMTP_PASS |
Password SMTP |
string |
SI (si usa SMTP) |
EMAIL_FROM_ADDRESS |
Email de remitente |
string |
SI |
EMAIL_FROM_NAME |
Nombre de remitente |
string |
SI |
Ejemplo de .env
# Email Configuration
EMAIL_PROVIDER=sendgrid
EMAIL_FROM_ADDRESS=noreply@michangarrito.com
EMAIL_FROM_NAME=MiChangarrito
# SendGrid
SENDGRID_API_KEY=SG.xxxxxxxxxxxxxxxx
# AWS SES (fallback)
AWS_SES_REGION=us-east-1
AWS_SES_ACCESS_KEY=AKIAXXXXXXXXXXXXXXXX
AWS_SES_SECRET_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# SMTP (ultimo recurso)
SMTP_HOST=smtp.mailtrap.io
SMTP_PORT=587
SMTP_USER=xxxxxxxx
SMTP_PASS=xxxxxxxx
3. Endpoints/SDK Utilizados
SendGrid
| Operacion |
Metodo |
Endpoint |
Descripcion |
| Enviar email |
POST |
/v3/mail/send |
Envio simple o con template |
| Templates |
GET |
/v3/templates |
Listar templates |
AWS SES
| Operacion |
SDK Method |
Descripcion |
| Enviar email |
sendEmail() |
Via AWS SDK v3 |
| Enviar raw |
sendRawEmail() |
Con attachments |
SMTP
import * as nodemailer from 'nodemailer';
const transporter = nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: parseInt(process.env.SMTP_PORT),
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
});
4. Rate Limits
| Proveedor |
Limite |
Periodo |
Plan SendGrid |
| SendGrid |
100 |
por segundo |
Pro |
| SendGrid |
40,000 |
por mes |
Free |
| AWS SES |
14 |
por segundo |
Default |
| AWS SES |
50,000 |
por dia |
Verified |
Rate Limiting por Tenant
| Plan MCH |
Emails/hora |
Emails/dia |
| Basic |
100 |
500 |
| Pro |
1,000 |
10,000 |
| Enterprise |
Ilimitado |
Ilimitado |
5. Manejo de Errores
| Codigo |
Descripcion |
Accion |
Retry |
| 400 |
Email invalido |
Validar formato |
NO |
| 401 |
API Key invalida |
Verificar credencial |
NO |
| 429 |
Rate limit |
Esperar + retry |
SI |
| 500 |
Error proveedor |
Fallback a siguiente |
SI |
| 503 |
Servicio no disponible |
Fallback |
SI |
Estrategia de Fallback
const providers = ['sendgrid', 'ses', 'smtp'];
async function sendWithFallback(email: EmailDto) {
for (const provider of providers) {
try {
return await this.send(provider, email);
} catch (error) {
this.logger.warn(`Provider ${provider} failed, trying next`);
continue;
}
}
throw new Error('All email providers failed');
}
6. Templates
Templates Disponibles
| Template |
Descripcion |
Variables |
| welcome |
Bienvenida |
{name} |
| verify_email |
Verificacion |
{name}, {link} |
| order_confirmation |
Pedido confirmado |
{order_id}, {items} |
| payment_reminder |
Recordatorio pago |
{amount}, {due_date} |
| low_inventory |
Alerta inventario |
{product}, {quantity} |
Formato de Template (Handlebars)
<h1>Hola {{name}}</h1>
<p>Tu pedido #{{order_id}} ha sido confirmado.</p>
{{#each items}}
<li>{{this.name}} x {{this.quantity}}</li>
{{/each}}
7. Multi-tenant
Modelo de Credenciales
Almacenamiento
CREATE TABLE messaging.tenant_email_config (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID REFERENCES auth.tenants(id) NOT NULL,
provider VARCHAR(20) NOT NULL, -- sendgrid, ses, smtp
from_address VARCHAR(255) NOT NULL,
from_name VARCHAR(100),
credentials JSONB NOT NULL, -- Encriptado
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(tenant_id)
);
8. Tablas de BD
email_templates
CREATE TABLE messaging.email_templates (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID REFERENCES auth.tenants(id),
key VARCHAR(100) NOT NULL,
name VARCHAR(255) NOT NULL,
subject VARCHAR(255) NOT NULL,
html_content TEXT NOT NULL,
text_content TEXT,
variables JSONB,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(tenant_id, key)
);
email_logs
CREATE TABLE messaging.email_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL,
template_id UUID REFERENCES messaging.email_templates(id),
to_address VARCHAR(255) NOT NULL,
subject VARCHAR(255) NOT NULL,
provider VARCHAR(20) NOT NULL,
provider_message_id VARCHAR(255),
status VARCHAR(20) NOT NULL, -- sent, delivered, opened, clicked, bounced, failed
error_message TEXT,
sent_at TIMESTAMP WITH TIME ZONE,
delivered_at TIMESTAMP WITH TIME ZONE,
opened_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
9. Testing
Modo Sandbox
| Ambiente |
Proveedor |
Comportamiento |
| Development |
Mailtrap |
Emails atrapados, no enviados |
| Staging |
SendGrid Sandbox |
Emails simulados |
| Production |
SendGrid/SES |
Envio real |
Test de Conexion
# Test SendGrid
curl -X POST "https://api.sendgrid.com/v3/mail/send" \
-H "Authorization: Bearer $SENDGRID_API_KEY" \
-H "Content-Type: application/json" \
-d '{"personalizations":[{"to":[{"email":"test@example.com"}]}],"from":{"email":"noreply@michangarrito.com"},"subject":"Test","content":[{"type":"text/plain","value":"Test email"}]}'
10. Monitoreo
Metricas
| Metrica |
Descripcion |
Alerta |
| email_sent_total |
Emails enviados |
- |
| email_failed_total |
Emails fallidos |
> 5% |
| email_delivery_rate |
Tasa de entrega |
< 95% |
| email_bounce_rate |
Tasa de rebote |
> 5% |
11. Referencias
Ultima actualizacion: 2026-01-10
Autor: Backend Team