SEND_EMAIL - Enviar Email via Gmail
O que é este Node?
O SEND_EMAIL é o node responsável por enviar emails através da API do Gmail utilizando autenticação OAuth2. Permite envio de mensagens de texto simples com validação automática de campos obrigatórios.
Por que este Node existe?
Enviar emails programaticamente é uma necessidade comum em automações de negócio, mas implementar SMTP manualmente é complexo e requer configurações de segurança. O SEND_EMAIL existe para:
- Simplificar envio de emails: Interface simples para enviar emails sem configurar SMTP
- Segurança OAuth2: Usa autenticação moderna do Google sem expor senhas
- Integração nativa Gmail: Emails enviados aparecem na pasta "Enviados" do Gmail
- Rastreabilidade: Retorna IDs de mensagem e thread para referência futura
Como funciona internamente?
Quando o SEND_EMAIL é executado, o sistema:
- Valida OAuth2: Verifica clientId, clientSecret e refreshToken
- Valida campos: Confirma que to, subject e message estão presentes
- Prepara credenciais: Configura o cliente OAuth2 do Google
- Monta email: Cria estrutura MIME com cabeçalhos To, Subject e corpo
- Codifica: Converte email para base64url (formato exigido pela API)
- Envia via API: Chama gmail.users.messages.send()
- Se erro de autenticação: Retorna erro específico de OAuth2
- 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
];
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_EMAIL sempre que precisar de envio simples de emails através do Gmail:
Casos de uso
- Notificações automáticas: "Enviar email quando pedido for aprovado"
- Confirmações: "Enviar comprovante de agendamento por email"
- Alertas: "Notificar administrador quando estoque estiver baixo"
- Comunicação com clientes: "Enviar boas-vindas após cadastro"
Quando NÃO usar SEND_EMAIL
- Emails HTML complexos: Use SEND_HTML_EMAIL para templates elaborados
- Múltiplos anexos: Use SEND_WITH_ATTACHMENT para arquivos
- Responder threads: Use REPLY_TO_EMAIL para manter conversação
- Emails em massa: Use serviços especializados como Mailchimp
Parâmetros Detalhados
oauth2 (objeto, obrigatório)
O que é: Credenciais de autenticação OAuth2 do Google Cloud Console.
Estrutura:
{
clientId: string, // Client ID do projeto Google Cloud
clientSecret: string, // Client Secret do projeto
refreshToken: string, // Token de refresh obtido no fluxo OAuth
accessToken?: string // Token de acesso (opcional, renovado automaticamente)
}
Como obter: 1. Acesse Google Cloud Console 2. Crie projeto > APIs e Serviços > Credenciais 3. Criar credenciais > ID do cliente OAuth 2.0 4. Tipo: Aplicativo da Web 5. Adicione URIs de redirecionamento autorizados 6. Copie Client ID e Client Secret 7. Use OAuth Playground para obter refresh_token
Flow completo para testar:
{
"name": "Teste Gmail OAuth2",
"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": "Testar OAuth",
"operation": "send",
"oauth2": {
"clientId": "YOUR_CLIENT_ID.apps.googleusercontent.com",
"clientSecret": "YOUR_CLIENT_SECRET",
"refreshToken": "YOUR_REFRESH_TOKEN"
},
"to": "teste@example.com",
"subject": "Teste OAuth",
"message": "Email de teste de autenticação"
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Email enviado! ID: {{gmail_1.messageId}}"
}
}
},
{
"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: Configure suas credenciais OAuth2 reais. Ao executar, você deve receber o messageId do email enviado. Caso contrário, verifique se as credenciais estão corretas no Google Cloud Console.
to (string, obrigatório)
O que é: Endereço de email do destinatário. Pode ser um único email ou múltiplos separados por vírgula.
Formatos aceitos:
- Email simples: "usuario@example.com"
- Com nome: "João Silva <joao@example.com>"
- Múltiplos: "user1@example.com, user2@example.com"
Flow completo para testar:
{
"name": "Teste Destinatário Dinâmico",
"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": "Pedir Email",
"parameters": {
"message": "Para qual email deseja enviar?",
"variable": "emailDestino"
}
}
},
{
"id": "gmail_1",
"type": "gmail",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Enviar Email",
"operation": "send",
"oauth2": {
"clientId": "YOUR_CLIENT_ID",
"clientSecret": "YOUR_SECRET",
"refreshToken": "YOUR_TOKEN"
},
"to": "{{emailDestino}}",
"subject": "Email para você",
"message": "Este email foi enviado dinamicamente!"
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Email enviado para {{emailDestino}}"
}
}
},
{
"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 email válido quando solicitado. O sistema enviará o email para o endereço informado.
subject (string, obrigatório)
O que é: Assunto do email que aparecerá na caixa de entrada do destinatário.
Padrão: Nenhum (campo obrigatório)
Flow completo para testar:
{
"name": "Teste Assunto Dinâmico",
"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": "Gerar Número",
"parameters": {
"variable": "numeroPedido",
"value": "{{$random(1000,9999)}}"
}
}
},
{
"id": "gmail_1",
"type": "gmail",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Enviar Pedido",
"operation": "send",
"oauth2": {
"clientId": "YOUR_CLIENT_ID",
"clientSecret": "YOUR_SECRET",
"refreshToken": "YOUR_TOKEN"
},
"to": "cliente@example.com",
"subject": "Confirmação de Pedido #{{numeroPedido}}",
"message": "Seu pedido foi recebido com sucesso!"
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Email enviado: Pedido #{{numeroPedido}}"
}
}
},
{
"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. O email será enviado com assunto contendo um número de pedido aleatório.
message (string, obrigatório se html não fornecido)
O que é: Corpo do email em texto simples. Use este campo para mensagens sem formatação especial.
Padrão: Nenhum
Flow completo para testar:
{
"name": "Teste Mensagem Multilinhas",
"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": "Pedir Nome",
"parameters": {
"message": "Qual seu nome?",
"variable": "nomeCliente"
}
}
},
{
"id": "gmail_1",
"type": "gmail",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Enviar Boas-vindas",
"operation": "send",
"oauth2": {
"clientId": "YOUR_CLIENT_ID",
"clientSecret": "YOUR_SECRET",
"refreshToken": "YOUR_TOKEN"
},
"to": "novocliente@example.com",
"subject": "Bem-vindo!",
"message": "Olá {{nomeCliente}},\n\nSeja muito bem-vindo à nossa plataforma!\n\nEstamos felizes em tê-lo conosco.\n\nAtenciosamente,\nEquipe Lumina"
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Email de boas-vindas 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 seu nome quando solicitado. Um email personalizado será enviado com seu nome na mensagem.
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 |
| message | string | Sim* | Corpo do email em texto (*ou html) |
| html | string | Não | Corpo do email em HTML (alternativa ao message) |
Exemplo 1: Confirmação de Agendamento
Objetivo: Enviar email de confirmação após agendamento de consulta
JSON para Importar
{
"name": "Confirmação de Agendamento",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início do Agendamento" }
},
{
"id": "input_1",
"type": "input",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Nome do Cliente",
"parameters": {
"message": "Qual seu nome completo?",
"variable": "nomeCliente"
}
}
},
{
"id": "email_1",
"type": "email",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Email do Cliente",
"parameters": {
"message": "Qual seu email?",
"variable": "emailCliente"
}
}
},
{
"id": "date_1",
"type": "date",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Data da Consulta",
"parameters": {
"message": "Qual data deseja agendar? (DD/MM/YYYY)",
"variable": "dataConsulta"
}
}
},
{
"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": "Confirmação de Agendamento - Clínica Saúde",
"message": "Olá {{nomeCliente}},\n\nSua consulta foi agendada com sucesso!\n\nData: {{dataConsulta}}\nHorário: 14:00\nLocal: Clínica Saúde - Rua das Flores, 123\n\nPor favor, chegue com 10 minutos de antecedência.\n\nAtenciosamente,\nEquipe Clínica Saúde"
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 1100, "y": 100 },
"data": {
"label": "Sucesso",
"parameters": {
"message": "Perfeito! Enviamos a confirmação para {{emailCliente}}"
}
}
},
{
"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": "date_1" },
{ "source": "date_1", "target": "gmail_1" },
{ "source": "gmail_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Saída esperada:
Sistema: Qual seu nome completo?
Usuário: João Silva
Sistema: Qual seu email?
Usuário: joao@example.com
Sistema: Qual data deseja agendar? (DD/MM/YYYY)
Usuário: 15/10/2025
Sistema: Perfeito! Enviamos a confirmação para joao@example.com
Exemplo 2: Alerta de Estoque Baixo
Objetivo: Notificar automaticamente quando produto atingir estoque mínimo
JSON para Importar
{
"name": "Alerta de Estoque Baixo",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Verificar Estoque" }
},
{
"id": "input_1",
"type": "input",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Nome Produto",
"parameters": {
"message": "Qual produto?",
"variable": "nomeProduto"
}
}
},
{
"id": "number_1",
"type": "number",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Quantidade Atual",
"parameters": {
"message": "Quantidade em estoque?",
"variable": "quantidadeAtual"
}
}
},
{
"id": "condition_1",
"type": "condition",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Estoque Baixo?",
"parameters": {
"condition": "{{quantidadeAtual}} < 10"
}
}
},
{
"id": "gmail_1",
"type": "gmail",
"position": { "x": 900, "y": 50 },
"data": {
"label": "Enviar Alerta",
"operation": "send",
"oauth2": {
"clientId": "YOUR_CLIENT_ID",
"clientSecret": "YOUR_SECRET",
"refreshToken": "YOUR_TOKEN"
},
"to": "gerente@empresa.com",
"subject": "ALERTA: Estoque Baixo - {{nomeProduto}}",
"message": "ATENÇÃO!\n\nO produto {{nomeProduto}} está com estoque baixo.\n\nQuantidade atual: {{quantidadeAtual}} unidades\nQuantidade mínima: 10 unidades\n\nProvidence reposição urgente.\n\nSistema de Gestão de Estoque"
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 1100, "y": 50 },
"data": {
"label": "Alerta Enviado",
"parameters": {
"message": "Alerta de estoque baixo enviado ao gerente!"
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 900, "y": 150 },
"data": {
"label": "Estoque OK",
"parameters": {
"message": "Estoque normal: {{quantidadeAtual}} unidades"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1100, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "number_1" },
{ "source": "number_1", "target": "condition_1" },
{ "source": "condition_1", "target": "gmail_1", "label": "true" },
{ "source": "condition_1", "target": "message_2", "label": "false" },
{ "source": "gmail_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" },
{ "source": "message_2", "target": "end_1" }
]
}
Saída esperada (estoque baixo):
Sistema: Qual produto?
Usuário: Notebook Dell
Sistema: Quantidade em estoque?
Usuário: 5
Sistema: Alerta de estoque baixo enviado ao gerente!
Exemplo 3: Boas-vindas a Novo Cliente
Objetivo: Enviar email de boas-vindas personalizado após cadastro
JSON para Importar
{
"name": "Email de Boas-vindas",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Novo Cadastro" }
},
{
"id": "input_1",
"type": "input",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Nome",
"parameters": {
"message": "Bem-vindo! Qual seu nome?",
"variable": "nomeUsuario"
}
}
},
{
"id": "email_1",
"type": "email",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Email",
"parameters": {
"message": "Qual seu email?",
"variable": "emailUsuario"
}
}
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Gerar Código",
"parameters": {
"variable": "codigoCadastro",
"value": "{{$random(100000,999999)}}"
}
}
},
{
"id": "gmail_1",
"type": "gmail",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Enviar Boas-vindas",
"operation": "send",
"oauth2": {
"clientId": "YOUR_CLIENT_ID",
"clientSecret": "YOUR_SECRET",
"refreshToken": "YOUR_TOKEN"
},
"to": "{{emailUsuario}}",
"subject": "Bem-vindo à Lumina - Cadastro Confirmado!",
"message": "Olá {{nomeUsuario}},\n\nSeja muito bem-vindo à plataforma Lumina!\n\nSeu cadastro foi realizado com sucesso.\nCódigo de cadastro: #{{codigoCadastro}}\n\nAgora você pode:\n✓ Criar fluxos de automação\n✓ Integrar com WhatsApp e Gmail\n✓ Conectar suas ferramentas favoritas\n\nAcesse agora: https://lumina.app.br\n\nPrecisa de ajuda? Responda este email.\n\nAbraços,\nEquipe Lumina"
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 1100, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Cadastro concluído! Código: #{{codigoCadastro}}\nEmail enviado para {{emailUsuario}}"
}
}
},
{
"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: Bem-vindo! Qual seu nome?
Usuário: Maria Santos
Sistema: Qual seu email?
Usuário: maria@example.com
Sistema: Cadastro concluído! Código: #847562
Email enviado para maria@example.com
Resposta do Node
{
"success": true,
"action": "send_email",
"messageId": "18f2b9c4d5e6a7f8",
"threadId": "18f2b9c4d5e6a7f8",
"labelIds": ["SENT"],
"timestamp": "2025-10-12T21:30:00.000Z"
}
Boas Práticas
✅ SIM:
- Use variáveis para personalizar destinatário e conteúdo
- Valide emails antes de enviar com node EMAIL
- Inclua informações de contato no rodapé
- Use assuntos claros e descritivos
- Teste com seu próprio email primeiro
❌ NÃO:
- Não envie emails em massa (use serviços especializados)
- Não exponha credenciais OAuth2 em logs
- Não use para spam ou emails não solicitados
- Não envie informações sensíveis sem criptografia
Dicas
💡 Dica 1: Configure refresh_token com escopo offline para evitar reautenticações constantes
💡 Dica 2: Use o campo html ao invés de message para emails com formatação rica
💡 Dica 3: Armazene messageId retornado para rastrear se email foi lido posteriormente
💡 Dica 4: Combine com CONDITION para enviar emails apenas em situações específicas
💡 Dica 5: Use VARIABLE para gerar códigos únicos antes de enviar emails
Próximo Node
→ SEND_HTML_EMAIL - Enviar emails com formatação HTML → SEND_WITH_ATTACHMENT - Enviar emails com anexos → GET_EMAILS - Recuperar emails da caixa de entrada