Módulo SMTP – Agendamento de Visitas
Glossário
- SMTP (Simple Mail Transfer Protocol): protocolo para envio de e-mail entre servidores.
- TCP: protocolo que garante que os dados cheguem completos, na ordem certa e sem erros entre dois dispositivos.
- TLS: protocolo que criptografa e protege a comunicação sobre o TCP, garantindo segurança e integridade dos dados.
- Socket: um ponto de conexão entre dois computadores na rede que permite enviar e receber dados.
- HELO/EHLO: comandos de identificação;
EHLOpede extensões (STARTTLS, AUTH, etc.). - STARTTLS: comando que solicita upgrade da conexão para TLS sobre a mesma socket.
- SMTPS: TLS direto (porta 465).
- AUTH PLAIN / AUTH LOGIN: métodos de autenticação (base64).
- MIME: Multipurpose Internet Mail Extensions — formato para mensagens com várias partes (text, html, attachments).
- multipart/alternative: partes alternativas (por ex., plain text e HTML).
- multipart/mixed: estrutura que pode conter alternativas + anexos.
- CRLF:
\r\n— fim de linha no SMTP (obrigatório). - dot-stuffing: duplicar leading
.em linhas do corpo antes de enviar (por RFC). - Message-ID: identificador único do e-mail.
- SPF/DKIM/DMARC: mecanismos para autenticação de e-mail (evitam spoofing e melhoram entrega).
- Base64: codificação usada para anexos binários em SMTP.
- Rate limiting: limitar número de requisições por IP/endpoint para mitigar abuso.
- Whitelist / Blacklist: IPs explicitamente permitidos/negados.
Descrição
O módulo de Agendamento implementa um sistema de envio de e-mails baseado no protocolo SMTP sem depender de bibliotecas externas. Ele garante que tanto o cliente quanto a equipe interna recebam confirmações e notificações sobre o agendamento. A implementação usa net/tls para abrir sockets TCP/TLS e implementa manualmente os comandos SMTP, autenticação (PLAIN/LOGIN) e construção de mensagens MIME (texto, HTML, anexos).
Objetivo
- Enviar confirmação de agendamento ao usuário (cliente) e notificar a imobiliária.
- Implementar validações e proteção contra abuso (rate limit, blacklist/whitelist, bloqueio de domínios temporários).
- Registrar logs de auditoria para rastreabilidade.
Estrutura de arquivos
-
agendamentoController.js → Valida entrada HTTP, normaliza dados, permite integração com mapaService para buscar detalhes do imóvel e chama serviços.
-
agendamentoRoute.js → Define middlewares (headers de segurança, validação de content-type e payload size), rotas: /send, /schedule, /:id, /agendar, /property-notification.
-
agendamentoService.js → Implementa SMTP client, validações de anexos, construção MIME, rate limiting, blacklist/whitelist.
Configuração do Servidor SMTP
Antes de rodar o módulo, é necessário configurar as variáveis de ambiente:
- SMTP_HOST=mail.example.com
- SMTP_PORT=587
- SMTP_SECURE=false
- SMTP_USER=usuario
- SMTP_PASS=senha
- SMTP_HELO=localhost
- MAIL_FROM_EMPRESA=noreply@ex.com
- MAIL_TO_EMPRESA=agendamentos@...
- NODE_ENV=development|production
Explicação sobre variáveis de ambiente
- SMTP_HOST — Endereço do servidor SMTP (ex: smtp.gmail.com).
- SMTP_PORT — Porta do servidor (587 para TLS, 465 para SSL).
- SMTP_SECURE — Define se a conexão deve usar SSL/TLS.
- SMTP_USER — E-mail usado para autenticação.
- SMTP_PASS — Senha ou token de acesso do e-mail. A senha é gerada por meio da autenticação de dois fatores.
- SMTP_HELO — Valor usado em EHLO/HELO. Default é "localhost".
- MAIL_FROM_EMPRESA — E-mail obrigatório para envios automáticos (sendScheduleConfirmation).
- MAIL_TO_EMPRESA — E-mail interno opcional; default é "agendamentos@imobiliaria-bortone.com.br".
- NODE_ENV — Define o ambiente da aplicação e controla a exposição de detalhes de erro (development ou production).
Observação: Nunca commitar credenciais no repositório.
Fluxo de Envio de E-mails
- Requisição HTTP chega no controller (ex.: /schedule).
- Controller valida e normaliza input (regex de e-mail, tamanhos, trims).
- Controller aplica lógica específica (ex.: busca imovel por ID via mapaService e mescla endereço).
- Verificação de segurança, Controller checa rate limit: agendamentoService.checkRateLimit(clientIP, route):
- Limite de 5 agendamentos por minuto por IP.
- Bloqueio de IPs em blacklist.
- Bloqueio de domínios suspeitos (ex: Mailinator, TempMail).
- Controller chama agendamentoService.sendScheduleConfirmation({ appointment }).
- sendScheduleConfirmation monta textos e HTML (usuário e empresa), cria SMTPClient com host/port/secure/user/pass/helo.
- SMTPClient.send() abre socket (plain TCP ou TLS), aguarda banner (220), envia EHLO, verifica STARTTLS e, se disponível + desejado, faz upgrade TLS.
- Autentica (AUTH PLAIN ou AUTH LOGIN) se user/pass informados.
- Realiza a troca de comandos SMTP (
EHLO/HELO,AUTH,MAIL FROM,RCPT TO,DATA,QUIT). - Constrói mensagem MIME via buildMime(...), aplica dot-stuffing, escreve o corpo e finaliza com .\r\n.
- Construção da mensagem MIME:
- Apenas texto OU
- Texto + HTML (multipart/alternative) OU
- Texto + HTML + Anexos (multipart/mixed).
- Lê a resposta (250) e encerra com QUIT.
- Envio da mensagem e retorno da resposta JSON para o cliente.
Requisições
Rota POST /schedule
Recebe dados de agendamento, aplica rate limit, busca dados do imóvel (se id) e envia 2 e-mails (usuário + empresa).
{
"name": "Tiago Rodrigues",
"email": "tiago@example.com",
"phone": "11999999999",
"propertyId": "123",
"propertyAddress": "Rua das Flores, 100",
"notes": "Prefiro horário da manhã",
"visitPeriod": "Manhã"
}
Resposta sucesso (200)
{ "success": true, "message": "Agendamento confirmado e e-mails enviados com sucesso" }
Resposta erro (400)
{ "error": "Erro ao processar agendamento"}
Rota POST /send
Envio direto de e-mail (teste).
{
"host": "smtp.servidor.com",
"port": 587,
"secure": false,
"user": "usuario",
"pass": "senha",
"from": "noreply@imobiliaria.com",
"to": "cliente@example.com",
"subject": "Teste",
"text": "Mensagem em texto",
"html": "<b>Mensagem HTML</b>",
"attachments": [
{ "filename": "doc.pdf", "contentBase64": "JVBERi0x...", "contentType": "application/pdf" }
]
}
Resposta sucesso (200)
{ "success": true, "message": "Email enviado com sucesso", "data": { "ok": true, "message": "Enviado" } }
Validações
- E-mail → Regex robusta + bloqueio de domínios temporários.
- Porta SMTP → Deve estar entre 1 e 65535.
- Secure (TLS) → Obrigatoriamente booleano.
- Subject → Máximo 200 caracteres.
- Texto → Máximo 10.000 caracteres.
- HTML → Máximo 20.000 caracteres.
- Anexos →
- Tamanho máx. 10MB.
- Tipos permitidos:
.jpeg, .png, .gif, .webp, .pdf, .txt, .doc, .docx, .xls, .xlsx. - Nome máx. 255 caracteres (sem caracteres perigosos como
<, >, :, /, \\).
Montagem de mensagem por meio do MIME
A função buildMime() implementa a construção de e-mail para três cenários:
- Apenas texto (sem HTML, sem anexos)
Content-Type: text/plain; charset="utf-8"- Corpo: texto truncado para
LIMITS.textBody.
- Texto + HTML (sem anexos)
Content-Type: multipart/alternative; boundary="alt_..."- Parte 1:
text/plain - Parte 2:
text/html - Fecha
-alt_...--
-
Com anexos
Content-Type: multipart/mixed; boundary="mix_..."- Primeiro part:
multipart/alternative(se houver HTML) outext/plain -
Em seguida: cada anexo com:
--mix_... Content-Type: <contentType>; name="filename" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="filename" <base64 content> -
Fecha
-mix_...--
Observações técnicas:
- Headers importantes: sempre incluir From, To, Cc (opcional), Subject, Date, Message-ID e MIME-Version: 1.0.
- Dot-stuffing: se uma linha do corpo começar com ., duplicar o ponto (. → ..) antes de enviar.
- Fim de linha: todas as linhas devem terminar com \r\n (CRLF), como exige o padrão SMTP.
- Encoding: Anexos → base64 Texto e HTML → 7bit (UTF-8). Se o conteúdo tiver caracteres especiais, pode usar quoted-printable.
Segurança
- Uso de TLS/SSL para conexão segura com o servidor SMTP.
- Armazenamento seguro de credenciais via variáveis de ambiente.
- Proteção contra spam: limite de disparos por evento configurado no sistema.
- Rate limitingde 5 requisições/minuto por IP.
- Whitelist de IPs:
127.0.0.1,::1. - Blacklist dinâmica, IPs suspeitos podem ser bloqueados temporariamente.
- Limite de tamanho de payload e anexos.
- Logs de auditoria, todas as requisições logadas com IP, User-Agent, rota e horário.
- Headers de segurança:
X-Content-Type-Options,X-Frame-Options,X-XSS-Protection,Content-Security-Policy. - Sanitização, uma prevenção contra injeção de headers e XSS em e-mails HTML.
Exemplo de uso no Frontend
Ao finalizar o agendamento no frontend:
- O usuário preenche os dados do agendamento.
- O frontend envia a requisição ao backend.
- O backend dispara os e-mails configurados.
- O cliente recebe a confirmação diretamente na caixa de entrada.
- A imobiliária recebe o e-mail de solicitação de agendamento do cliente
Limitações
- Implementar SMTP por conta própria exige atenção e manutenção.
- Não possui fila de envio automática. Se o serviço cair, os e-mails podem ser perdidos.
- Anexos grandes ficam na memória como base64