Pular para conteúdo

SES_SEND_EMAIL - Enviar Email via AWS SES

O que é este Node?

O SES_SEND_EMAIL é o node responsável por enviar emails transacionais e de marketing através do Amazon Simple Email Service (SES) com suporte a destinatários múltiplos, cópia (CC/BCC) e conteúdo HTML/texto.

Por que este Node existe?

Enviar emails profissionais requer infraestrutura confiável e verificada. O SES_SEND_EMAIL existe para:

  1. Email transacional: Confirmações de pedido, recuperação de senha, notificações
  2. Alta deliverability: AWS SES tem reputação excelente para entrega de emails
  3. Custo baixo: $0.10 por 1.000 emails enviados (muito mais barato que serviços tradicionais)
  4. Escalabilidade: Suporta de 1 até milhões de emails por dia
  5. Rastreamento: Integração com SNS para bounce/complaint handling
  6. Flexibilidade: Conteúdo HTML rico ou texto simples

Como funciona internamente?

Quando o SES_SEND_EMAIL é executado, o sistema:

  1. Valida credenciais: Verifica accessKeyId, secretAccessKey e region
  2. Cria cliente SES: Inicializa SDK da AWS com credenciais
  3. Valida remetente: Email "from" deve estar verificado no SES (sandbox ou production)
  4. Monta destinatários: Processa arrays de ToAddresses, CcAddresses, BccAddresses
  5. Prepara conteúdo: Formata Subject, Body (HTML e/ou texto)
  6. Envia email: Chama sendEmail() da API SES
  7. Retorna messageId: ID único para rastreamento da mensagem
  8. Se erro: Lança exceção com detalhes (email não verificado, limite atingido, etc.)

Código interno (aws-executors.service.ts:384-412):

case 'sendEmail':
  const sendResult = await ses.sendEmail({
    Source: data.fromEmail,
    Destination: {
      ToAddresses: data.toEmails,
      CcAddresses: data.ccEmails || [],
      BccAddresses: data.bccEmails || [],
    },
    Message: {
      Subject: {
        Data: data.subject,
        Charset: 'UTF-8',
      },
      Body: {
        Text: data.textBody ? {
          Data: data.textBody,
          Charset: 'UTF-8',
        } : undefined,
        Html: data.htmlBody ? {
          Data: data.htmlBody,
          Charset: 'UTF-8',
        } : undefined,
      },
    },
  }).promise();
  return {
    success: true,
    messageId: sendResult.MessageId,
  };

Quando você DEVE usar este Node?

Use SES_SEND_EMAIL sempre que precisar de envio de emails profissionais:

Casos de uso

  1. Email transacional: "Seu pedido #12345 foi confirmado!"
  2. Recuperação de senha: "Clique aqui para redefinir sua senha"
  3. Notificações: "Você tem uma nova mensagem"
  4. Confirmações: "Obrigado por se cadastrar!"
  5. Alertas: "Pagamento vencendo em 3 dias"
  6. Relatórios: "Seu relatório mensal está pronto"
  7. Marketing simples: Newsletter personalizada para cliente

Quando NÃO usar SES_SEND_EMAIL

  • Email marketing em massa: Use SES_SEND_TEMPLATE para campanhas com templates
  • Newsletters complexas: Use Mailchimp, SendGrid ou outros serviços especializados
  • Emails com anexos grandes: SES limita tamanho total (10MB incluindo headers)
  • Emails não verificados: Em sandbox, só pode enviar para emails verificados

Verificação de Domínio/Email

Modo Sandbox (padrão)

Quando você cria conta AWS, seu SES começa em sandbox mode:

  • Só pode enviar para emails verificados
  • Limite de 200 emails/dia
  • Limite de 1 email/segundo
  • Ideal para desenvolvimento e testes

Para verificar email de teste: 1. Acesse AWS Console → SES → Email Addresses 2. Clique "Verify a New Email Address" 3. Digite email e clique "Verify" 4. Abra email e clique no link de confirmação

Modo Production

Para enviar para qualquer email:

  1. Solicite saída do sandbox: AWS Console → SES → Sending Statistics → Request Production Access
  2. Preencha formulário: Explique seu caso de uso (não mencione marketing spam)
  3. Aguarde aprovação: Geralmente 24-48 horas
  4. Novos limites: 50.000 emails/dia inicialmente (aumenta automaticamente)

Recomendado: Verificar domínio completo - Verifica todos emails do domínio de uma vez - Adicione registros TXT, DKIM e SPF no DNS - Melhora deliverability e reputação

Limites de Envio

Modo Emails/dia Taxa Destinatários
Sandbox 200 1/segundo Apenas verificados
Production (inicial) 50.000 14/segundo Qualquer email
Production (crescente) Até 1M+ Até 1000/segundo Qualquer email

Dica: Limites aumentam automaticamente conforme você mantém boa reputação (baixo bounce/complaint rate).

Parâmetros Detalhados

accessKeyId (string, obrigatório)

O que é: Chave de acesso IAM da AWS com permissões SES.

Como obter: 1. AWS Console → IAM → Users → Create User 2. Attach policy: AmazonSESFullAccess ou custom policy 3. Security credentials → Create access key 4. Copie Access Key ID

Flow completo para testar:

{
  "name": "Teste SES - Access Key",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "ses_1",
      "type": "aws_ses",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Enviar Email",
        "parameters": {
          "operation": "sendEmail",
          "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
          "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
          "region": "us-east-1",
          "fromEmail": "sender@exemplo.com",
          "toEmails": ["destinatario@exemplo.com"],
          "subject": "Teste AWS SES",
          "textBody": "Este é um email de teste."
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Email enviado! ID: {{messageId}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "ses_1" },
    { "source": "ses_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: Substitua credenciais reais. Se inválidas, retorna erro de autenticação.

secretAccessKey (string, obrigatório)

O que é: Chave secreta correspondente ao accessKeyId.

Segurança: - NUNCA exponha em código ou repositórios - Use variáveis de ambiente ou AWS Secrets Manager - Rotacione periodicamente (a cada 90 dias)

region (string, obrigatório)

O que é: Região AWS onde seu SES está configurado.

Regiões suportadas: - us-east-1 (Norte da Virgínia) - Mais comum - us-west-2 (Oregon) - eu-west-1 (Irlanda) - sa-east-1 (São Paulo) - Brasil - Ver lista completa: https://docs.aws.amazon.com/general/latest/gr/ses.html

Dica: Escolha região mais próxima dos seus usuários para menor latência.

fromEmail (string, obrigatório)

O que é: Email do remetente (deve estar verificado no SES).

Formatos aceitos: - sender@exemplo.com - Nome Empresa <sender@exemplo.com>

Flow completo para testar:

{
  "name": "Teste SES - From Email com Nome",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "ses_1",
      "type": "aws_ses",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Enviar com Nome",
        "parameters": {
          "operation": "sendEmail",
          "accessKeyId": "SUA_ACCESS_KEY",
          "secretAccessKey": "SUA_SECRET_KEY",
          "region": "us-east-1",
          "fromEmail": "Equipe Lumina <noreply@lumina.app.br>",
          "toEmails": ["cliente@exemplo.com"],
          "subject": "Bem-vindo à Lumina!",
          "htmlBody": "<h1>Olá!</h1><p>Obrigado por se cadastrar.</p>"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Email enviado de 'Equipe Lumina'"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "ses_1" },
    { "source": "ses_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: Cliente receberá email com remetente "Equipe Lumina" ao invés de só o endereço.

toEmails (array, obrigatório)

O que é: Lista de emails destinatários (campo "Para").

Formato: ["email1@exemplo.com", "email2@exemplo.com"]

Limite: Até 50 destinatários por email (soma de TO + CC + BCC)

Flow completo para testar:

{
  "name": "Teste SES - Múltiplos Destinatários",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "ses_1",
      "type": "aws_ses",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Enviar para Equipe",
        "parameters": {
          "operation": "sendEmail",
          "accessKeyId": "SUA_ACCESS_KEY",
          "secretAccessKey": "SUA_SECRET_KEY",
          "region": "us-east-1",
          "fromEmail": "sistema@empresa.com",
          "toEmails": ["gerente@empresa.com", "diretor@empresa.com", "ceo@empresa.com"],
          "subject": "Relatório Mensal - Janeiro 2025",
          "textBody": "Segue relatório em anexo."
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Email enviado para 3 pessoas da equipe"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "ses_1" },
    { "source": "ses_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: Todos destinatários receberão o email e verão os outros destinatários no campo "Para".

ccEmails (array, opcional)

O que é: Lista de emails em cópia (CC - Carbon Copy).

Quando usar: Para pessoas que devem acompanhar mas não são destinatários principais.

Padrão: [] (vazio)

bccEmails (array, opcional)

O que é: Lista de emails em cópia oculta (BCC - Blind Carbon Copy).

Quando usar: Para enviar cópia sem revelar destinatário aos outros.

Padrão: [] (vazio)

Exemplo de uso CC/BCC:

{
  "toEmails": ["cliente@empresa.com"],
  "ccEmails": ["gerente@empresa.com"],
  "bccEmails": ["arquivo@empresa.com"]
}

Cliente vê: Para: cliente@, CC: gerente@ Gerente vê: Para: cliente@, CC: gerente@ Arquivo vê: Para: cliente@, CC: gerente@ (mas outros não sabem que arquivo@ recebeu)

subject (string, obrigatório)

O que é: Assunto do email.

Boas práticas: - Até 60 caracteres (melhor visualização mobile) - Claro e objetivo - Evite CAPS LOCK (parece spam) - Personalize com variáveis: "Olá {{nome}}, seu pedido chegou!"

textBody (string, opcional)

O que é: Conteúdo do email em texto simples (plain text).

Quando usar: - Clientes de email antigos que não suportam HTML - Fallback quando HTML não renderiza - Melhor deliverability (menos chance de spam)

Recomendação: Sempre envie textBody E htmlBody juntos.

htmlBody (string, opcional)

O que é: Conteúdo do email em HTML.

Recursos suportados: - Tags HTML: <h1>, <p>, <strong>, <a>, <img>, etc. - CSS inline: <p style="color: blue;"> - Imagens externas: <img src="https://...">

Limitações: - Não use CSS externo (<link>) - Evite JavaScript (será removido) - Teste em múltiplos clientes de email

Flow completo para testar:

{
  "name": "Teste SES - Email HTML Rico",
  "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 Cliente",
        "parameters": {
          "variables": {
            "cliente_nome": "José Roberto",
            "pedido_numero": "12345",
            "pedido_valor": "R$ 299,90"
          }
        }
      }
    },
    {
      "id": "ses_1",
      "type": "aws_ses",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Enviar Confirmação",
        "parameters": {
          "operation": "sendEmail",
          "accessKeyId": "SUA_ACCESS_KEY",
          "secretAccessKey": "SUA_SECRET_KEY",
          "region": "us-east-1",
          "fromEmail": "vendas@empresa.com",
          "toEmails": ["{{cliente_email}}"],
          "subject": "Pedido #{{pedido_numero}} Confirmado!",
          "textBody": "Olá {{cliente_nome}},\n\nSeu pedido #{{pedido_numero}} no valor de {{pedido_valor}} foi confirmado!\n\nObrigado pela compra.",
          "htmlBody": "<html><body style='font-family: Arial, sans-serif;'><h1 style='color: #28a745;'>Pedido Confirmado!</h1><p>Olá <strong>{{cliente_nome}}</strong>,</p><p>Seu pedido <strong>#{{pedido_numero}}</strong> no valor de <strong>{{pedido_valor}}</strong> foi confirmado com sucesso!</p><p>Entraremos em contato em breve.</p><hr><p style='color: #666; font-size: 12px;'>Equipe Vendas</p></body></html>"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Email de confirmação enviado para {{cliente_nome}}"
        }
      }
    },
    {
      "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: Cliente recebe email formatado com cores, negrito e estrutura profissional.

Parâmetros

Campo Tipo Obrigatório Descrição
operation string Sim Deve ser "sendEmail"
accessKeyId string Sim AWS Access Key ID
secretAccessKey string Sim AWS Secret Access Key
region string Sim Região AWS (ex: us-east-1)
fromEmail string Sim Email remetente verificado
toEmails array Sim Lista de destinatários
ccEmails array Não Lista de emails em cópia
bccEmails array Não Lista de emails em cópia oculta
subject string Sim Assunto do email
textBody string Não Conteúdo em texto simples
htmlBody string Não Conteúdo em HTML

Nota: Pelo menos um entre textBody ou htmlBody é obrigatório.

Exemplo 1: Confirmação de Cadastro

Objetivo: Enviar email de boas-vindas após cadastro

JSON para Importar

{
  "name": "Confirmação de Cadastro",
  "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": "Nome",
        "parameters": {
          "message": "Qual é o seu nome?",
          "variable": "nome"
        }
      }
    },
    {
      "id": "email_1",
      "type": "email",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Email",
        "parameters": {
          "message": "Qual é o seu email?",
          "variable": "email"
        }
      }
    },
    {
      "id": "ses_1",
      "type": "aws_ses",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Enviar Boas-vindas",
        "parameters": {
          "operation": "sendEmail",
          "accessKeyId": "SUA_ACCESS_KEY",
          "secretAccessKey": "SUA_SECRET_KEY",
          "region": "us-east-1",
          "fromEmail": "noreply@lumina.app.br",
          "toEmails": ["{{email}}"],
          "subject": "Bem-vindo à Lumina, {{nome}}!",
          "textBody": "Olá {{nome}},\n\nObrigado por se cadastrar na Lumina!\n\nEstamos felizes em ter você conosco.\n\nEquipe Lumina",
          "htmlBody": "<html><body><h1>Bem-vindo à Lumina!</h1><p>Olá <strong>{{nome}}</strong>,</p><p>Obrigado por se cadastrar! Estamos felizes em ter você conosco.</p><p>Explore nossos recursos e comece a criar flows incríveis.</p><br><p>Equipe Lumina</p></body></html>"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Cadastro concluído! Enviamos um email para {{email}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1100, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "input_1" },
    { "source": "input_1", "target": "email_1" },
    { "source": "email_1", "target": "ses_1" },
    { "source": "ses_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Qual é o seu nome?
Usuário: Maria Silva
Sistema: Qual é o seu email?
Usuário: maria@exemplo.com
Sistema: Cadastro concluído! Enviamos um email para maria@exemplo.com

[Email recebido por maria@exemplo.com]
Assunto: Bem-vindo à Lumina, Maria Silva!
Corpo: Olá Maria Silva, Obrigado por se cadastrar...

Exemplo 2: Recuperação de Senha

Objetivo: Enviar link de reset de senha

JSON para Importar

{
  "name": "Recuperação de Senha",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "email_1",
      "type": "email",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Email Cadastrado",
        "parameters": {
          "message": "Digite o email cadastrado:",
          "variable": "email_recuperacao"
        }
      }
    },
    {
      "id": "variable_1",
      "type": "variable",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Gerar Token",
        "parameters": {
          "variables": {
            "reset_token": "abc123xyz789",
            "reset_link": "https://app.lumina.com.br/reset?token=abc123xyz789"
          }
        }
      }
    },
    {
      "id": "ses_1",
      "type": "aws_ses",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Enviar Link Reset",
        "parameters": {
          "operation": "sendEmail",
          "accessKeyId": "SUA_ACCESS_KEY",
          "secretAccessKey": "SUA_SECRET_KEY",
          "region": "us-east-1",
          "fromEmail": "security@lumina.app.br",
          "toEmails": ["{{email_recuperacao}}"],
          "subject": "Redefinição de Senha - Lumina",
          "textBody": "Você solicitou redefinição de senha.\n\nClique no link: {{reset_link}}\n\nO link expira em 1 hora.\n\nSe não foi você, ignore este email.",
          "htmlBody": "<html><body><h2>Redefinição de Senha</h2><p>Você solicitou redefinição de senha.</p><p><a href='{{reset_link}}' style='background: #007bff; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;'>Redefinir Senha</a></p><p>O link expira em <strong>1 hora</strong>.</p><p style='color: #999; font-size: 12px;'>Se não foi você, ignore este email.</p></body></html>"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Email de recuperação enviado para {{email_recuperacao}}. Verifique sua caixa de entrada."
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1100, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "email_1" },
    { "source": "email_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: Digite o email cadastrado:
Usuário: user@exemplo.com
Sistema: Email de recuperação enviado para user@exemplo.com. Verifique sua caixa de entrada.

[Email recebido]
Assunto: Redefinição de Senha - Lumina
Corpo: Botão azul "Redefinir Senha" com link

Exemplo 3: Notificação de Pedido com Cópia para Equipe

Objetivo: Enviar confirmação para cliente e cópia para gerente

JSON para Importar

{
  "name": "Notificação de Pedido",
  "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",
        "parameters": {
          "variables": {
            "cliente_nome": "Carlos Santos",
            "cliente_email": "carlos@empresa.com",
            "pedido_id": "PED-2025-001",
            "pedido_total": "R$ 1.499,90",
            "pedido_itens": "3 produtos"
          }
        }
      }
    },
    {
      "id": "ses_1",
      "type": "aws_ses",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Notificar Pedido",
        "parameters": {
          "operation": "sendEmail",
          "accessKeyId": "SUA_ACCESS_KEY",
          "secretAccessKey": "SUA_SECRET_KEY",
          "region": "us-east-1",
          "fromEmail": "vendas@loja.com.br",
          "toEmails": ["{{cliente_email}}"],
          "ccEmails": ["gerente@loja.com.br"],
          "bccEmails": ["arquivo@loja.com.br"],
          "subject": "Pedido {{pedido_id}} Recebido!",
          "textBody": "Olá {{cliente_nome}},\n\nRecebemos seu pedido {{pedido_id}}!\n\nTotal: {{pedido_total}}\nItens: {{pedido_itens}}\n\nObrigado pela compra!",
          "htmlBody": "<html><body style='font-family: Arial;'><h1 style='color: green;'>Pedido Recebido!</h1><p>Olá <strong>{{cliente_nome}}</strong>,</p><div style='background: #f5f5f5; padding: 15px; border-radius: 8px;'><p><strong>Pedido:</strong> {{pedido_id}}</p><p><strong>Total:</strong> {{pedido_total}}</p><p><strong>Itens:</strong> {{pedido_itens}}</p></div><p>Entraremos em contato para confirmar a entrega.</p><p>Obrigado pela compra!</p></body></html>"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Pedido {{pedido_id}} confirmado! Email enviado para cliente e gerente."
        }
      }
    },
    {
      "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: Pedido PED-2025-001 confirmado! Email enviado para cliente e gerente.

[carlos@empresa.com recebe]
Para: carlos@empresa.com
CC: gerente@loja.com.br
Assunto: Pedido PED-2025-001 Recebido!

[gerente@loja.com.br recebe o mesmo]
[arquivo@loja.com.br recebe sem aparecer para outros]

Resposta do Node

{
  "success": true,
  "messageId": "0100018d8e8a7c9e-a1b2c3d4-5678-90ab-cdef-1234567890ab-000000"
}

messageId: ID único da AWS para rastrear o email. Use para: - Consultar status de entrega - Rastrear bounces/complaints via SNS - Debugging e logs

Bounce e Complaint Handling

O que é Bounce?

Email "devolvido" porque: - Email não existe (hard bounce) - Caixa cheia (soft bounce) - Servidor destino rejeitou

O que é Complaint?

Destinatário marcou como spam.

Como configurar notificações:

  1. Crie SNS Topic:

    AWS Console → SNS → Create Topic
    Nome: ses-bounces
    

  2. Configure SES para notificar:

    SES → Email Addresses → [seu email] → Notifications
    Bounces: [selecione seu topic SNS]
    Complaints: [selecione seu topic SNS]
    

  3. Subscribe ao topic:

  4. Email: Receba notificações por email
  5. HTTPS: Webhook para seu sistema
  6. Lambda: Processe automaticamente

  7. Remova emails problemáticos:

  8. Hard bounces: Remova da lista imediatamente
  9. Complaints: Remova e não envie mais
  10. Manter baixo bounce/complaint rate é crucial para reputação

Métricas recomendadas:

  • Bounce rate: < 5%
  • Complaint rate: < 0.1%
  • Acima disso, AWS pode suspender sua conta!

Boas Práticas

SIM:

  • Sempre envie textBody E htmlBody juntos
  • Verifique domínio completo (não apenas emails individuais)
  • Use CSS inline no HTML (não <link>)
  • Personalize assunto e conteúdo com variáveis
  • Configure bounce/complaint handling com SNS
  • Monitore métricas de deliverability no SES Console
  • Use "noreply@" ou "no-reply@" para emails automáticos
  • Adicione link de unsubscribe em emails marketing
  • Teste emails em múltiplos clientes (Gmail, Outlook, Apple Mail)

NÃO:

  • Não envie de email não verificado (erro garantido)
  • Não use CAPS LOCK no assunto (parece spam)
  • Não compre listas de emails (viola termos AWS e leis)
  • Não ignore bounces/complaints (prejudica reputação)
  • Não envie marketing para quem não autorizou (LGPD/GDPR)
  • Não exponha credenciais AWS no código
  • Não use JavaScript em HTML (será removido)
  • Não envie anexos muito grandes (limite 10MB total)

Dicas

💡 Deliverability: Emails com "Reply-To" configurado têm melhor taxa de entrega

💡 Custo: $0.10 por 1.000 emails = 10.000 emails por $1.00 (muito barato!)

💡 Teste primeiro: Use modo sandbox para testar completamente antes de pedir production access

💡 Reputação é tudo: Mantenha bounce < 5% e complaint < 0.1% para melhor deliverability

💡 Personalize sempre: Emails com nome do destinatário têm 26% mais taxa de abertura

💡 Horário ideal: Emails transacionais envie imediatamente. Marketing: teste A/B diferentes horários

💡 Mobile first: 60%+ emails são lidos em mobile - teste responsividade

Próximo Node

SES_SEND_TEMPLATE - Enviar email com template pré-definido → SNS_SEND_SMS - Enviar SMS via AWS SNS