Pular para conteúdo

SEND_HTML_EMAIL - Enviar Email HTML via Gmail

O que é este Node?

O SEND_HTML_EMAIL é o node responsável por enviar emails com formatação HTML rica através da API do Gmail, permitindo templates personalizados, estilos CSS, imagens inline e layouts profissionais.

Por que este Node existe?

Emails profissionais requerem formatação visual para transmitir mensagens de forma eficaz e manter identidade de marca. O SEND_HTML_EMAIL existe para:

  1. Emails profissionais: Criar comunicações visualmente atraentes com branding
  2. Templates personalizados: Usar HTML/CSS para layouts complexos
  3. Melhor engajamento: Emails formatados têm maior taxa de leitura
  4. Flexibilidade total: Controle completo sobre aparência e estrutura

Como funciona internamente?

Quando o SEND_HTML_EMAIL é executado, o sistema:

  1. Valida OAuth2: Verifica credenciais de autenticação
  2. Valida campos: Confirma to, subject e html obrigatórios
  3. Prepara HTML: Monta email com Content-Type: text/html
  4. Codifica: Converte para base64url mantendo formatação HTML
  5. Envia via API: Usa gmail.users.messages.send()
  6. Se erro: Retorna detalhes do erro para diagnóstico
  7. Se sucesso: Retorna messageId, threadId e labelIds

Código interno (gmail-executor.service.ts:269-327):

private async sendEmail(gmail: any, data: GmailNodeData): Promise<any> {
  const emailLines = [
    `To: ${data.to}`,
    `Subject: ${data.subject}`,
    'Content-Type: text/html; charset=utf-8',
    '',
    data.html || data.message  // Prioriza HTML se fornecido
  ];

  const email = emailLines.join('\n');
  const encodedEmail = Buffer.from(email).toString('base64url');

  const response = await gmail.users.messages.send({
    userId: 'me',
    requestBody: {
      raw: encodedEmail
    }
  });

  return {
    messageId: response.data.id,
    threadId: response.data.threadId,
    labelIds: response.data.labelIds
  };
}

Quando você DEVE usar este Node?

Use SEND_HTML_EMAIL sempre que precisar de emails com formatação visual rica:

Casos de uso

  1. Newsletters: "Enviar boletim informativo mensal com layout de marca"
  2. Confirmações de pedido: "Email com logo, tabela de produtos e total formatado"
  3. Convites para eventos: "Convite visual com imagem, data e botão de confirmação"
  4. Relatórios formatados: "Relatório com gráficos, tabelas e cores da empresa"

Quando NÃO usar SEND_HTML_EMAIL

  • Emails simples: Use SEND_EMAIL para mensagens de texto puro
  • Com anexos: Use SEND_WITH_ATTACHMENT se precisar incluir arquivos
  • Responder threads: Use REPLY_TO_EMAIL para manter conversação
  • Alto volume: Use plataformas especializadas (Mailchimp, SendGrid)

Parâmetros Detalhados

html (string, obrigatório)

O que é: Código HTML completo do email, incluindo tags, estilos CSS inline e estrutura do layout.

Padrão: Nenhum (campo obrigatório)

Boas práticas HTML: - Use CSS inline (não externo) - Evite JavaScript (não funciona em emails) - Use tabelas para layout (melhor compatibilidade) - Teste em diferentes clientes de email

Flow completo para testar:

{
  "name": "Teste Email HTML Básico",
  "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 Cliente",
        "parameters": {
          "message": "Qual o nome do cliente?",
          "variable": "nomeCliente"
        }
      }
    },
    {
      "id": "gmail_1",
      "type": "gmail",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Enviar HTML",
        "operation": "send",
        "oauth2": {
          "clientId": "YOUR_CLIENT_ID",
          "clientSecret": "YOUR_SECRET",
          "refreshToken": "YOUR_TOKEN"
        },
        "to": "cliente@example.com",
        "subject": "Bem-vindo à Lumina!",
        "html": "<html><body style='font-family: Arial, sans-serif; background-color: #f4f4f4; padding: 20px;'><div style='max-width: 600px; margin: 0 auto; background-color: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1);'><h1 style='color: #4A90E2; text-align: center;'>Bem-vindo, {{nomeCliente}}!</h1><p style='color: #333; font-size: 16px; line-height: 1.6;'>Estamos muito felizes em tê-lo conosco na <strong>Lumina</strong>.</p><div style='background-color: #4A90E2; color: white; padding: 15px; text-align: center; border-radius: 5px; margin: 20px 0;'><a href='https://lumina.app.br' style='color: white; text-decoration: none; font-weight: bold;'>ACESSAR PLATAFORMA</a></div><p style='color: #666; font-size: 14px;'>Atenciosamente,<br>Equipe Lumina</p></div></body></html>"
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Email HTML enviado para {{nomeCliente}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "input_1" },
    { "source": "input_1", "target": "gmail_1" },
    { "source": "gmail_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: Digite um nome quando solicitado. O email será enviado com formatação HTML completa incluindo cores, botão e layout responsivo.

to (string, obrigatório)

O que é: Endereço de email do destinatário. Idêntico ao SEND_EMAIL, mas o conteúdo será renderizado como HTML.

Flow completo para testar:

{
  "name": "Email HTML para 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": "Lista Emails",
        "parameters": {
          "variable": "destinatarios",
          "value": "gerente@empresa.com, supervisor@empresa.com"
        }
      }
    },
    {
      "id": "gmail_1",
      "type": "gmail",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Enviar Relatório",
        "operation": "send",
        "oauth2": {
          "clientId": "YOUR_CLIENT_ID",
          "clientSecret": "YOUR_SECRET",
          "refreshToken": "YOUR_TOKEN"
        },
        "to": "{{destinatarios}}",
        "subject": "Relatório Semanal de Vendas",
        "html": "<html><body><h2 style='color: #2c3e50;'>Relatório Semanal</h2><table style='width: 100%; border-collapse: collapse;'><tr style='background-color: #3498db; color: white;'><th style='padding: 10px; border: 1px solid #ddd;'>Produto</th><th style='padding: 10px; border: 1px solid #ddd;'>Vendas</th></tr><tr><td style='padding: 10px; border: 1px solid #ddd;'>Produto A</td><td style='padding: 10px; border: 1px solid #ddd;'>150</td></tr><tr><td style='padding: 10px; border: 1px solid #ddd;'>Produto B</td><td style='padding: 10px; border: 1px solid #ddd;'>230</td></tr></table></body></html>"
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Relatório enviado para gestores"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "variable_1" },
    { "source": "variable_1", "target": "gmail_1" },
    { "source": "gmail_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: Execute o flow. Email formatado com tabela HTML será enviado para ambos destinatários.

subject (string, obrigatório)

O que é: Assunto do email. Mesmo comportamento do SEND_EMAIL.

Flow completo para testar:

{
  "name": "Assunto com Emoji",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "gmail_1",
      "type": "gmail",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Email com Emoji",
        "operation": "send",
        "oauth2": {
          "clientId": "YOUR_CLIENT_ID",
          "clientSecret": "YOUR_SECRET",
          "refreshToken": "YOUR_TOKEN"
        },
        "to": "cliente@example.com",
        "subject": "🎉 Promoção Especial - 50% OFF!",
        "html": "<html><body style='text-align: center; padding: 40px;'><h1 style='color: #e74c3c; font-size: 48px;'>🎉 SUPER PROMOÇÃO! 🎉</h1><p style='font-size: 24px; color: #2c3e50;'><strong>50% de desconto</strong> em todos os produtos!</p><p style='color: #7f8c8d;'>Válido até 31/12/2025</p></body></html>"
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Email promocional enviado!"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "gmail_1" },
    { "source": "gmail_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: Execute o flow. Email com subject contendo emoji será enviado normalmente.

Parâmetros

Campo Tipo Obrigatório Descrição
oauth2 object Sim Credenciais OAuth2 (clientId, clientSecret, refreshToken)
operation string Sim Deve ser "send"
to string Sim Email do destinatário
subject string Sim Assunto do email
html string Sim Código HTML do email

Exemplo 1: Newsletter com Template Profissional

Objetivo: Enviar newsletter mensal formatada com logo e seções

JSON para Importar

{
  "name": "Newsletter Mensal",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início Newsletter" }
    },
    {
      "id": "variable_1",
      "type": "variable",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Data Atual",
        "parameters": {
          "variable": "mesAno",
          "value": "{{$now('MMMM/YYYY')}}"
        }
      }
    },
    {
      "id": "gmail_1",
      "type": "gmail",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Enviar Newsletter",
        "operation": "send",
        "oauth2": {
          "clientId": "YOUR_CLIENT_ID",
          "clientSecret": "YOUR_SECRET",
          "refreshToken": "YOUR_TOKEN"
        },
        "to": "assinantes@empresa.com",
        "subject": "📰 Newsletter Lumina - {{mesAno}}",
        "html": "<!DOCTYPE html><html><head><meta charset='UTF-8'><title>Newsletter</title></head><body style='margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f6f6f6;'><table width='100%' cellpadding='0' cellspacing='0' border='0'><tr><td align='center' style='padding: 20px 0;'><table width='600' cellpadding='0' cellspacing='0' border='0' style='background-color: #ffffff; box-shadow: 0 2px 10px rgba(0,0,0,0.1);'><tr><td style='background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 40px; text-align: center;'><h1 style='color: #ffffff; margin: 0; font-size: 32px;'>📰 NEWSLETTER LUMINA</h1><p style='color: #ffffff; margin: 10px 0 0 0;'>{{mesAno}}</p></td></tr><tr><td style='padding: 30px;'><h2 style='color: #333; margin-top: 0;'>Novidades do Mês</h2><p style='color: #666; line-height: 1.6;'>Confira as principais atualizações e novidades da plataforma Lumina neste mês.</p><div style='background-color: #f8f9fa; padding: 20px; border-radius: 8px; margin: 20px 0;'><h3 style='color: #667eea; margin-top: 0;'>✨ Nova Funcionalidade</h3><p style='color: #555;'>Agora você pode enviar emails HTML diretamente dos seus fluxos!</p></div><div style='background-color: #f8f9fa; padding: 20px; border-radius: 8px; margin: 20px 0;'><h3 style='color: #667eea; margin-top: 0;'>🚀 Melhorias</h3><p style='color: #555;'>Performance aprimorada em 40% na execução de fluxos complexos.</p></div><div style='text-align: center; margin: 30px 0;'><a href='https://lumina.app.br' style='display: inline-block; padding: 15px 30px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: #ffffff; text-decoration: none; border-radius: 5px; font-weight: bold;'>ACESSAR PLATAFORMA</a></div></td></tr><tr><td style='background-color: #f8f9fa; padding: 20px; text-align: center;'><p style='color: #999; font-size: 12px; margin: 0;'>© 2025 Lumina - Todos os direitos reservados</p><p style='color: #999; font-size: 12px; margin: 5px 0 0 0;'><a href='#' style='color: #667eea; text-decoration: none;'>Cancelar assinatura</a></p></td></tr></table></td></tr></table></body></html>"
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Sucesso",
        "parameters": {
          "message": "Newsletter 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": "gmail_1" },
    { "source": "gmail_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Newsletter enviada com sucesso!

Exemplo 2: Confirmação de Pedido com Tabela

Objetivo: Enviar confirmação de compra formatada com detalhes do pedido

JSON para Importar

{
  "name": "Confirmação de Pedido HTML",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Novo Pedido" }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Nome Cliente",
        "parameters": {
          "message": "Nome do cliente?",
          "variable": "nomeCliente"
        }
      }
    },
    {
      "id": "email_1",
      "type": "email",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Email Cliente",
        "parameters": {
          "message": "Email do cliente?",
          "variable": "emailCliente"
        }
      }
    },
    {
      "id": "variable_1",
      "type": "variable",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Número Pedido",
        "parameters": {
          "variable": "numeroPedido",
          "value": "{{$random(10000,99999)}}"
        }
      }
    },
    {
      "id": "gmail_1",
      "type": "gmail",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Enviar Confirmação",
        "operation": "send",
        "oauth2": {
          "clientId": "YOUR_CLIENT_ID",
          "clientSecret": "YOUR_SECRET",
          "refreshToken": "YOUR_TOKEN"
        },
        "to": "{{emailCliente}}",
        "subject": "Pedido #{{numeroPedido}} Confirmado - Lumina Store",
        "html": "<!DOCTYPE html><html><head><meta charset='UTF-8'></head><body style='font-family: Arial, sans-serif; background-color: #f4f4f4; padding: 20px;'><div style='max-width: 600px; margin: 0 auto; background-color: white; border-radius: 10px; overflow: hidden; box-shadow: 0 2px 15px rgba(0,0,0,0.1);'><div style='background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%); padding: 30px; text-align: center;'><h1 style='color: white; margin: 0;'>✅ Pedido Confirmado!</h1></div><div style='padding: 30px;'><p style='color: #333; font-size: 16px;'>Olá <strong>{{nomeCliente}}</strong>,</p><p style='color: #666; line-height: 1.6;'>Seu pedido foi confirmado e está sendo preparado para envio.</p><div style='background-color: #f8f9fa; padding: 15px; border-radius: 8px; margin: 20px 0;'><p style='margin: 5px 0; color: #555;'><strong>Número do Pedido:</strong> #{{numeroPedido}}</p><p style='margin: 5px 0; color: #555;'><strong>Data:</strong> {{$now('DD/MM/YYYY')}}</p></div><h3 style='color: #333; border-bottom: 2px solid #6366f1; padding-bottom: 10px;'>Itens do Pedido</h3><table style='width: 100%; border-collapse: collapse; margin: 20px 0;'><thead><tr style='background-color: #f8f9fa;'><th style='padding: 12px; text-align: left; border-bottom: 2px solid #dee2e6;'>Produto</th><th style='padding: 12px; text-align: center; border-bottom: 2px solid #dee2e6;'>Qtd</th><th style='padding: 12px; text-align: right; border-bottom: 2px solid #dee2e6;'>Valor</th></tr></thead><tbody><tr><td style='padding: 12px; border-bottom: 1px solid #dee2e6;'>Notebook Dell Inspiron</td><td style='padding: 12px; text-align: center; border-bottom: 1px solid #dee2e6;'>1</td><td style='padding: 12px; text-align: right; border-bottom: 1px solid #dee2e6;'>R$ 3.499,00</td></tr><tr><td style='padding: 12px; border-bottom: 1px solid #dee2e6;'>Mouse Logitech MX</td><td style='padding: 12px; text-align: center; border-bottom: 1px solid #dee2e6;'>1</td><td style='padding: 12px; text-align: right; border-bottom: 1px solid #dee2e6;'>R$ 249,00</td></tr><tr><td colspan='2' style='padding: 12px; text-align: right; border-top: 2px solid #dee2e6;'><strong>TOTAL</strong></td><td style='padding: 12px; text-align: right; border-top: 2px solid #dee2e6;'><strong style='color: #6366f1; font-size: 18px;'>R$ 3.748,00</strong></td></tr></tbody></table><div style='background-color: #ecfdf5; border-left: 4px solid #10b981; padding: 15px; margin: 20px 0;'><p style='margin: 0; color: #065f46;'><strong>🚚 Previsão de Entrega:</strong> 5-7 dias úteis</p></div><div style='text-align: center; margin: 30px 0;'><a href='https://lumina.app.br/pedido/{{numeroPedido}}' style='display: inline-block; padding: 15px 40px; background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%); color: white; text-decoration: none; border-radius: 8px; font-weight: bold;'>RASTREAR PEDIDO</a></div></div><div style='background-color: #f8f9fa; padding: 20px; text-align: center;'><p style='color: #666; font-size: 14px; margin: 0;'>Precisa de ajuda? Entre em contato: suporte@lumina.app.br</p><p style='color: #999; font-size: 12px; margin: 10px 0 0 0;'>© 2025 Lumina Store - Todos os direitos reservados</p></div></div></body></html>"
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 1100, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "Confirmação enviada para {{emailCliente}}\nPedido: #{{numeroPedido}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1300, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "input_1" },
    { "source": "input_1", "target": "email_1" },
    { "source": "email_1", "target": "variable_1" },
    { "source": "variable_1", "target": "gmail_1" },
    { "source": "gmail_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Nome do cliente?
Usuário: Maria Silva
Sistema: Email do cliente?
Usuário: maria@example.com
Sistema: Confirmação enviada para maria@example.com
Pedido: #74839

Resposta do Node

{
  "success": true,
  "action": "send_html_email",
  "messageId": "18f2b9c4d5e6a7f8",
  "threadId": "18f2b9c4d5e6a7f8",
  "labelIds": ["SENT"],
  "timestamp": "2025-10-12T21:30:00.000Z"
}

Boas Práticas

SIM:

  • Use CSS inline (não arquivos externos)
  • Teste em múltiplos clientes (Gmail, Outlook, Apple Mail)
  • Use tabelas para layout (melhor compatibilidade)
  • Inclua versão texto alternativa
  • Otimize imagens (use CDN ou base64 para pequenas)
  • Use media queries para responsividade

NÃO:

  • Não use JavaScript (não funciona em emails)
  • Não use posicionamento absolute/fixed
  • Não use vídeos ou flash
  • Não carregue fontes externas sem fallback
  • Não crie emails muito pesados (>100kb)

Dicas

💡 Dica 1: Use ferramentas como MJML ou Foundation for Emails para criar templates responsivos

💡 Dica 2: Teste com Litmus ou Email on Acid antes de enviar em massa

💡 Dica 3: Sempre inclua link de "cancelar inscrição" em newsletters

💡 Dica 4: Use width="600" nas tabelas principais (padrão de email)

💡 Dica 5: Salve templates HTML em variáveis para reutilização

Próximo Node

SEND_EMAIL - Versão texto simples → SEND_WITH_ATTACHMENT - Enviar com anexos → GET_EMAILS - Recuperar emails