SES_SEND_TEMPLATE - Enviar Email com Template
O que é este Node?
O SES_SEND_TEMPLATE é o node responsável por enviar emails usando templates HTML pré-definidos no AWS SES com substituição dinâmica de variáveis, ideal para campanhas de marketing e emails transacionais padronizados.
Por que este Node existe?
Templates de email permitem reutilização e consistência. O SES_SEND_TEMPLATE existe para:
- Reutilização: Crie template uma vez, use milhares de vezes
- Consistência visual: Garante marca uniforme em todos emails
- Personalização em massa: Substitua variáveis como {{nome}}, {{pedido}}, etc.
- Governança: Equipe de marketing controla templates, devs só enviam dados
- Performance: Templates são pré-compilados pela AWS (envio mais rápido)
- Versionamento: AWS mantém histórico de versões de templates
- Campanhas de marketing: Envie 10.000 emails personalizados com um template
Como funciona internamente?
Quando o SES_SEND_TEMPLATE é executado, o sistema:
- Valida credenciais: Verifica accessKeyId, secretAccessKey e region
- Cria cliente SES: Inicializa SDK da AWS
- Valida template: Verifica se templateName existe no SES
- Valida remetente: Email "from" deve estar verificado
- Prepara templateData: Converte objeto de variáveis em JSON string
- Substitui variáveis: AWS processa {{variavel}} no template com valores fornecidos
- Envia email: Chama sendTemplatedEmail() da API SES
- Retorna messageId: ID único para rastreamento
- Se erro: Template não existe, variável faltando, limite atingido, etc.
Código interno (aws-executors.service.ts:414-426):
case 'sendTemplatedEmail':
const templateResult = await ses.sendTemplatedEmail({
Source: data.fromEmail,
Destination: {
ToAddresses: data.toEmails,
},
Template: data.templateName,
TemplateData: JSON.stringify(data.templateData),
}).promise();
return {
success: true,
messageId: templateResult.MessageId,
};
Quando você DEVE usar este Node?
Use SES_SEND_TEMPLATE sempre que precisar de emails padronizados com dados dinâmicos:
Casos de uso
- Newsletters: "Olá {{nome}}, confira as novidades de {{mes}}"
- Confirmações de pedido: Template padrão com {{pedido_numero}}, {{total}}, {{itens}}
- Emails de boas-vindas: Mesmo design para todos novos usuários
- Relatórios mensais: Template com {{metricas}}, {{grafico}}, {{periodo}}
- Campanhas promocionais: "{{nome}}, aproveite {{desconto}}% OFF em {{categoria}}"
- Lembretes: "{{nome}}, você tem {{quantidade}} itens no carrinho"
- Notificações de evento: "{{nome}}, seu evento {{evento_nome}} é amanhã"
Quando NÃO usar SES_SEND_TEMPLATE
- Email único customizado: Use SES_SEND_EMAIL para mensagens únicas
- Template muda frequentemente: Se HTML muda toda hora, não compensa criar template
- Precisa anexos: Templates SES não suportam anexos (use sendEmail)
- Email muito simples: "Obrigado!" não precisa de template
Como criar Templates no AWS SES
Método 1: AWS Console (Interface Gráfica)
- Acesse SES Console: https://console.aws.amazon.com/ses/
- Email Templates: Sidebar → Configuration → Email templates
- Create template: Clique em "Create template"
- Preencha:
- Template name:
confirmacao-pedido - Subject:
Pedido {{pedido_numero}} Confirmado! - HTML part:
<html> <body> <h1>Olá {{nome}}!</h1> <p>Seu pedido <strong>{{pedido_numero}}</strong> foi confirmado.</p> <p>Total: {{total}}</p> <p>Itens: {{itens}}</p> </body> </html> - Text part:
Olá {{nome}}! Seu pedido {{pedido_numero}} foi confirmado. Total: {{total}} Itens: {{itens}} - Create template: Salvar
Método 2: AWS CLI (Linha de Comando)
Crie arquivo template.json:
{
"Template": {
"TemplateName": "confirmacao-pedido",
"SubjectPart": "Pedido {{pedido_numero}} Confirmado!",
"TextPart": "Olá {{nome}}!\n\nSeu pedido {{pedido_numero}} foi confirmado.\nTotal: {{total}}",
"HtmlPart": "<html><body><h1>Olá {{nome}}!</h1><p>Seu pedido <strong>{{pedido_numero}}</strong> foi confirmado.</p><p>Total: {{total}}</p></body></html>"
}
}
Execute:
aws ses create-template --cli-input-json file://template.json --region us-east-1
Método 3: Via API (Programático)
import AWS from 'aws-sdk';
const ses = new AWS.SES({ region: 'us-east-1' });
await ses.createTemplate({
Template: {
TemplateName: 'confirmacao-pedido',
SubjectPart: 'Pedido {{pedido_numero}} Confirmado!',
HtmlPart: '<html>...</html>',
TextPart: 'Olá {{nome}}...'
}
}).promise();
Variáveis em Templates
Sintaxe
Use {{variavel}} no Subject, HtmlPart e TextPart:
<h1>Olá {{nome}}!</h1>
<p>Você ganhou {{pontos}} pontos!</p>
<p>Seu saldo é: R$ {{saldo}}</p>
No Flow, envie dados:
{
"templateData": {
"nome": "José Roberto",
"pontos": "150",
"saldo": "1.299,90"
}
}
Resultado final:
<h1>Olá José Roberto!</h1>
<p>Você ganhou 150 pontos!</p>
<p>Seu saldo é: R$ 1.299,90</p>
Variável faltando?
Se template tem {{email}} mas você não enviou no templateData:
- AWS deixa literal: "{{email}}" aparece no email
- Recomendação: Sempre envie todas variáveis ou use valores default
Valores default no template:
AWS SES não suporta defaults nativamente. Solução: envie sempre:
{
"templateData": {
"nome": "{{nome}}",
"sobrenome": "{{sobrenome || 'Não informado'}}"
}
}
Melhor: Garanta valores no flow antes de enviar:
{
"variable": {
"nome": "{{nome || 'Cliente'}}",
"sobrenome": "{{sobrenome || ''}}"
}
}
Parâmetros Detalhados
accessKeyId (string, obrigatório)
O que é: Chave de acesso IAM da AWS com permissões SES.
Mesmas instruções de SES_SEND_EMAIL - veja documentação anterior.
secretAccessKey (string, obrigatório)
O que é: Chave secreta correspondente ao accessKeyId.
Segurança: Nunca exponha em código.
region (string, obrigatório)
O que é: Região AWS onde template foi criado.
Importante: Template deve existir na MESMA região que você está enviando.
Regiões comuns:
- us-east-1 (Norte da Virgínia)
- us-west-2 (Oregon)
- eu-west-1 (Irlanda)
- sa-east-1 (São Paulo)
fromEmail (string, obrigatório)
O que é: Email do remetente (deve estar verificado no SES).
Formatos:
- sender@exemplo.com
- Equipe Vendas <vendas@exemplo.com>
toEmails (array, obrigatório)
O que é: Lista de emails destinatários.
Formato: ["email1@exemplo.com", "email2@exemplo.com"]
Limite: Até 50 destinatários
Flow completo para testar:
{
"name": "Teste SES Template - Múltiplos Destinatários",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Dados Newsletter",
"parameters": {
"variables": {
"mes": "Janeiro",
"destaque": "50% OFF em todos os produtos",
"link": "https://loja.com.br/promo"
}
}
}
},
{
"id": "ses_1",
"type": "aws_ses",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Enviar Newsletter",
"parameters": {
"operation": "sendTemplatedEmail",
"accessKeyId": "SUA_ACCESS_KEY",
"secretAccessKey": "SUA_SECRET_KEY",
"region": "us-east-1",
"fromEmail": "newsletter@loja.com.br",
"toEmails": ["cliente1@exemplo.com", "cliente2@exemplo.com", "cliente3@exemplo.com"],
"templateName": "newsletter-mensal",
"templateData": {
"mes": "{{mes}}",
"destaque": "{{destaque}}",
"link": "{{link}}"
}
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Newsletter de {{mes}} enviada para 3 clientes!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "variable_1" },
{ "source": "variable_1", "target": "ses_1" },
{ "source": "ses_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Todos 3 clientes recebem email personalizado com dados de Janeiro.
templateName (string, obrigatório)
O que é: Nome do template criado no SES.
Onde encontrar: - AWS Console → SES → Email templates - Lista todos templates disponíveis
Erro comum:
Template 'nome-errado' does not exist
Solução: Certifique que template foi criado na mesma região.
Flow completo para testar:
{
"name": "Teste SES Template - Nome Template",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "input_1",
"type": "input",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Qual Template?",
"parameters": {
"message": "Digite o nome do template (ex: boas-vindas):",
"variable": "template_escolhido"
}
}
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Dados",
"parameters": {
"variables": {
"nome": "José Roberto",
"empresa": "Lumina"
}
}
}
},
{
"id": "ses_1",
"type": "aws_ses",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Enviar com Template",
"parameters": {
"operation": "sendTemplatedEmail",
"accessKeyId": "SUA_ACCESS_KEY",
"secretAccessKey": "SUA_SECRET_KEY",
"region": "us-east-1",
"fromEmail": "noreply@lumina.app.br",
"toEmails": ["teste@exemplo.com"],
"templateName": "{{template_escolhido}}",
"templateData": {
"nome": "{{nome}}",
"empresa": "{{empresa}}"
}
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Email enviado usando template: {{template_escolhido}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1100, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "variable_1" },
{ "source": "variable_1", "target": "ses_1" },
{ "source": "ses_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Digite "boas-vindas" e sistema usa esse template. Digite nome inexistente e retorna erro.
templateData (object, obrigatório)
O que é: Objeto com variáveis que serão substituídas no template.
Formato:
{
"templateData": {
"variavel1": "valor1",
"variavel2": "valor2",
"numero": "123",
"preco": "R$ 99,90"
}
}
Importante:
- Todos valores devem ser STRINGS (mesmo números)
- Nome deve corresponder exatamente ao {{variavel}} no template
- Não enviar variável = ela aparece literal no email
Exemplo:
Template tem:
<p>Olá {{nome}}! Você tem {{mensagens}} novas mensagens.</p>
Envie:
{
"templateData": {
"nome": "Maria",
"mensagens": "5"
}
}
Resultado:
<p>Olá Maria! Você tem 5 novas mensagens.</p>
Flow completo para testar variáveis complexas:
{
"name": "Teste SES Template - Variáveis Complexas",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Dados Pedido Completo",
"parameters": {
"variables": {
"cliente_nome": "José Roberto Silva",
"cliente_email": "jose@empresa.com",
"pedido_numero": "PED-2025-12345",
"pedido_data": "15/01/2025",
"pedido_status": "Confirmado",
"item1_nome": "Mouse Gamer",
"item1_qtd": "2",
"item1_preco": "R$ 150,00",
"item2_nome": "Teclado Mecânico",
"item2_qtd": "1",
"item2_preco": "R$ 450,00",
"subtotal": "R$ 750,00",
"frete": "R$ 25,00",
"total": "R$ 775,00",
"link_rastreamento": "https://rastreio.com/PED-2025-12345"
}
}
}
},
{
"id": "ses_1",
"type": "aws_ses",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Enviar Pedido Detalhado",
"parameters": {
"operation": "sendTemplatedEmail",
"accessKeyId": "SUA_ACCESS_KEY",
"secretAccessKey": "SUA_SECRET_KEY",
"region": "us-east-1",
"fromEmail": "vendas@loja.com.br",
"toEmails": ["{{cliente_email}}"],
"templateName": "confirmacao-pedido-detalhado",
"templateData": {
"cliente_nome": "{{cliente_nome}}",
"pedido_numero": "{{pedido_numero}}",
"pedido_data": "{{pedido_data}}",
"pedido_status": "{{pedido_status}}",
"item1_nome": "{{item1_nome}}",
"item1_qtd": "{{item1_qtd}}",
"item1_preco": "{{item1_preco}}",
"item2_nome": "{{item2_nome}}",
"item2_qtd": "{{item2_qtd}}",
"item2_preco": "{{item2_preco}}",
"subtotal": "{{subtotal}}",
"frete": "{{frete}}",
"total": "{{total}}",
"link_rastreamento": "{{link_rastreamento}}"
}
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Confirmação enviada para {{cliente_nome}} ({{pedido_numero}})"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "variable_1" },
{ "source": "variable_1", "target": "ses_1" },
{ "source": "ses_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Email enviado com todos detalhes do pedido formatados no template.
Parâmetros
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| operation | string | Sim | Deve ser "sendTemplatedEmail" |
| accessKeyId | string | Sim | AWS Access Key ID |
| secretAccessKey | string | Sim | AWS Secret Access Key |
| region | string | Sim | Região AWS do template |
| fromEmail | string | Sim | Email remetente verificado |
| toEmails | array | Sim | Lista de destinatários |
| templateName | string | Sim | Nome do template no SES |
| templateData | object | Sim | Variáveis do template |
Exemplo 1: Newsletter Mensal
Objetivo: Enviar newsletter usando template padrão
Pré-requisito: Criar template "newsletter-mensal" no SES Console:
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
.header { background: #007bff; color: white; padding: 20px; }
.content { padding: 20px; }
.destaque { background: #fffacd; padding: 15px; border-left: 4px solid #ffd700; }
.footer { background: #f8f9fa; padding: 10px; text-align: center; color: #666; }
</style>
</head>
<body>
<div class="header">
<h1>Newsletter {{mes}}</h1>
</div>
<div class="content">
<p>Olá {{nome}}!</p>
<div class="destaque">
<h2>📢 Destaque do mês:</h2>
<p>{{destaque}}</p>
<a href="{{link}}" style="background: #28a745; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;">Ver Promoção</a>
</div>
<p>Não perca essas ofertas incríveis!</p>
</div>
<div class="footer">
<p>Você está recebendo porque se inscreveu em nossa newsletter.</p>
<a href="{{link_unsubscribe}}">Cancelar inscrição</a>
</div>
</body>
</html>
JSON para Importar
{
"name": "Newsletter Mensal",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Dados Newsletter",
"parameters": {
"variables": {
"mes": "Janeiro 2025",
"nome": "José Roberto",
"destaque": "Super Sale: 60% OFF em Eletrônicos!",
"link": "https://loja.com.br/sale",
"link_unsubscribe": "https://loja.com.br/unsubscribe?email=jose@exemplo.com"
}
}
}
},
{
"id": "ses_1",
"type": "aws_ses",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Enviar Newsletter",
"parameters": {
"operation": "sendTemplatedEmail",
"accessKeyId": "SUA_ACCESS_KEY",
"secretAccessKey": "SUA_SECRET_KEY",
"region": "us-east-1",
"fromEmail": "Marketing <newsletter@loja.com.br>",
"toEmails": ["jose@exemplo.com"],
"templateName": "newsletter-mensal",
"templateData": {
"mes": "{{mes}}",
"nome": "{{nome}}",
"destaque": "{{destaque}}",
"link": "{{link}}",
"link_unsubscribe": "{{link_unsubscribe}}"
}
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Newsletter de {{mes}} enviada com sucesso!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "variable_1" },
{ "source": "variable_1", "target": "ses_1" },
{ "source": "ses_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Saída esperada:
Sistema: Newsletter de Janeiro 2025 enviada com sucesso!
[Email recebido]
Assunto: Newsletter Janeiro 2025
Corpo: Design bonito com header azul, destaque amarelo, botão verde "Ver Promoção"
Exemplo 2: Confirmação de Cadastro com Template
Objetivo: Usar template para emails de boas-vindas
Template "boas-vindas" no SES:
Subject: Bem-vindo à {{empresa}}, {{nome}}!
HtmlPart:
<html>
<body style="font-family: Arial;">
<h1 style="color: #28a745;">🎉 Bem-vindo à {{empresa}}!</h1>
<p>Olá <strong>{{nome}}</strong>,</p>
<p>Estamos muito felizes em ter você conosco!</p>
<h3>Próximos passos:</h3>
<ol>
<li>Complete seu perfil: <a href="{{link_perfil}}">Clique aqui</a></li>
<li>Conheça nossos recursos</li>
<li>Comece a usar!</li>
</ol>
<p>Se tiver dúvidas, responda este email.</p>
<p>Abraços,<br>Equipe {{empresa}}</p>
</body>
</html>
JSON para Importar
{
"name": "Cadastro com Template",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "message_1",
"type": "message",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Boas-vindas",
"parameters": {
"message": "Bem-vindo! Vamos criar sua conta."
}
}
},
{
"id": "input_1",
"type": "input",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Nome",
"parameters": {
"message": "Qual é o seu nome completo?",
"variable": "nome"
}
}
},
{
"id": "email_1",
"type": "email",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Email",
"parameters": {
"message": "Qual é o seu email?",
"variable": "email"
}
}
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Preparar Dados",
"parameters": {
"variables": {
"empresa": "Lumina",
"link_perfil": "https://lumina.app.br/perfil"
}
}
}
},
{
"id": "ses_1",
"type": "aws_ses",
"position": { "x": 1100, "y": 100 },
"data": {
"label": "Enviar Boas-vindas",
"parameters": {
"operation": "sendTemplatedEmail",
"accessKeyId": "SUA_ACCESS_KEY",
"secretAccessKey": "SUA_SECRET_KEY",
"region": "us-east-1",
"fromEmail": "Equipe Lumina <noreply@lumina.app.br>",
"toEmails": ["{{email}}"],
"templateName": "boas-vindas",
"templateData": {
"nome": "{{nome}}",
"empresa": "{{empresa}}",
"link_perfil": "{{link_perfil}}"
}
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 1300, "y": 100 },
"data": {
"label": "Finalizar",
"parameters": {
"message": "Cadastro concluído, {{nome}}! Enviamos instruções para {{email}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1500, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "input_1" },
{ "source": "input_1", "target": "email_1" },
{ "source": "email_1", "target": "variable_1" },
{ "source": "variable_1", "target": "ses_1" },
{ "source": "ses_1", "target": "message_2" },
{ "source": "message_2", "target": "end_1" }
]
}
Saída esperada:
Sistema: Bem-vindo! Vamos criar sua conta.
Sistema: Qual é o seu nome completo?
Usuário: Maria Souza
Sistema: Qual é o seu email?
Usuário: maria@exemplo.com
Sistema: Cadastro concluído, Maria Souza! Enviamos instruções para maria@exemplo.com
[Email recebido]
Assunto: Bem-vindo à Lumina, Maria Souza!
Corpo: Template formatado com lista de próximos passos e links
Exemplo 3: Campanha Marketing em Massa
Objetivo: Enviar promoção personalizada para lista de clientes
JSON para Importar
{
"name": "Campanha Black Friday",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Lista Clientes",
"parameters": {
"variables": {
"clientes": [
{"nome": "João Silva", "email": "joao@exemplo.com", "cupom": "JOAO50"},
{"nome": "Ana Costa", "email": "ana@exemplo.com", "cupom": "ANA50"},
{"nome": "Pedro Lima", "email": "pedro@exemplo.com", "cupom": "PEDRO50"}
]
}
}
}
},
{
"id": "loop_1",
"type": "loop",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Para Cada Cliente",
"parameters": {
"array": "{{clientes}}",
"itemVariable": "cliente"
}
}
},
{
"id": "ses_1",
"type": "aws_ses",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Enviar Promoção",
"parameters": {
"operation": "sendTemplatedEmail",
"accessKeyId": "SUA_ACCESS_KEY",
"secretAccessKey": "SUA_SECRET_KEY",
"region": "us-east-1",
"fromEmail": "Promoções <promo@loja.com.br>",
"toEmails": ["{{cliente.email}}"],
"templateName": "black-friday",
"templateData": {
"nome": "{{cliente.nome}}",
"cupom": "{{cliente.cupom}}",
"desconto": "50",
"validade": "30/11/2025",
"link": "https://loja.com.br/bf?cupom={{cliente.cupom}}"
}
}
}
},
{
"id": "delay_1",
"type": "delay",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Aguardar 1s",
"parameters": {
"duration": 1000
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 1100, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Campanha Black Friday enviada para todos os clientes!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1300, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "variable_1" },
{ "source": "variable_1", "target": "loop_1" },
{ "source": "loop_1", "target": "ses_1" },
{ "source": "ses_1", "target": "delay_1" },
{ "source": "delay_1", "target": "loop_1" },
{ "source": "loop_1", "target": "message_1", "condition": "loop_end" },
{ "source": "message_1", "target": "end_1" }
]
}
Saída esperada:
Sistema: Campanha Black Friday enviada para todos os clientes!
[João recebe]
Assunto: João Silva, 50% OFF exclusivo para você!
Cupom: JOAO50
[Ana recebe]
Assunto: Ana Costa, 50% OFF exclusivo para você!
Cupom: ANA50
[Pedro recebe]
Assunto: Pedro Lima, 50% OFF exclusivo para você!
Cupom: PEDRO50
Nota: Delay de 1s entre envios para respeitar limites do SES (14 emails/segundo em production).
Resposta do Node
{
"success": true,
"messageId": "0100018d8e8a7c9e-a1b2c3d4-5678-90ab-cdef-1234567890ab-000000"
}
messageId: ID único para rastreamento (mesmo uso de SES_SEND_EMAIL).
Gerenciar Templates SES
Listar templates existentes:
aws ses list-templates --region us-east-1
Ver detalhes de um template:
aws ses get-template --template-name nome-template --region us-east-1
Atualizar template:
aws ses update-template --cli-input-json file://template-atualizado.json
Deletar template:
aws ses delete-template --template-name nome-template --region us-east-1
Versionamento de Templates
AWS não mantém versões automaticamente. Recomendações:
- Nomear com versão:
confirmacao-pedido-v2,confirmacao-pedido-v3 - Backup em Git: Salve HTMLs dos templates no repositório
- Documentar mudanças: README explicando cada versão
- Testar antes de atualizar: Use template de teste primeiro
Boas Práticas
✅ SIM:
- Crie templates reutilizáveis e genéricos
- Use nomes descritivos:
confirmacao-pedido, nãotemplate1 - Sempre inclua TextPart e HtmlPart no template
- Teste template com dados de exemplo antes de usar em produção
- Documente todas variáveis necessárias (crie README ou comentário)
- Use CSS inline (não
<link>externo) - Adicione link de unsubscribe em emails de marketing
- Mantenha backup dos templates em repositório Git
- Use variáveis para tudo que muda: datas, nomes, valores
- Versionamento:
newsletter-v1,newsletter-v2se mudar muito
❌ NÃO:
- Não crie template para cada email único (perde o propósito)
- Não use JavaScript em templates (AWS remove)
- Não esqueça de enviar TODAS as variáveis no templateData
- Não hardcode dados que mudam (use variáveis)
- Não use templates sem testar antes
- Não delete templates em uso (pode quebrar flows ativos)
- Não crie templates em região diferente de onde vai enviar
- Não envie templateData com tipos errados (só strings)
Dicas
💡 Teste variáveis: Crie template de teste com todas variáveis visíveis para debug
💡 Fallback: Se variável pode estar vazia, ajuste HTML para não quebrar layout
💡 Performance: Templates são pré-compilados - 30% mais rápido que sendEmail com HTML inline
💡 Custo: Mesmo custo de sendEmail ($0.10/1000 emails)
💡 Limite de templates: 10.000 templates por conta AWS (mais que suficiente)
💡 Organização: Use prefixos: trans- para transacionais, mkt- para marketing
💡 Aprovação: Marketing aprova template, devs só enviam dados (separação de responsabilidades)
💡 A/B Testing: Crie 2 templates diferentes e alterne para testar qual converte melhor
Próximo Node
→ SES_SEND_EMAIL - Enviar email sem template → SES_VERIFY_EMAIL - Verificar email no SES → SNS_PUBLISH - Publicar mensagem no SNS