Pular para o conteúdo principal

Configuração do e-mail

Escolha e configure o provedor de e-mail transacional que o Fluxo usa para o correio de saída, as respostas e os eventos de ciclo de vida.

Comece pela visão geral de auto-hospedagem se você quiser ver antes a arquitetura completa, e combine este guia com o de armazenamento para configurar juntos os uploads e o e-mail.

O Fluxo aceita tanto resend quanto ses como transportes de e-mail transacional. Essa escolha é controlada por EMAIL_TRANSPORT_PROVIDER.

Esta página é deliberadamente neutra quanto ao fornecedor, porque e-mail é uma responsabilidade, não uma marca. O app gera os e-mails do mesmo jeito nos dois casos: o React Email continua produzindo o conteúdo e a escolha do provedor só muda o transporte e o encanamento de entrada em volta dele.

Escolha o seu provedor

Os dois provedores são suportados e ambos convivem bem no código hoje.

  • resend é o padrão e encaixa bem se você quer o caminho de e-mail hospedado mais simples
  • ses é a opção nativa da AWS e encaixa bem se você quer a infraestrutura de e-mail na sua própria conta da AWS

O interruptor principal do transporte é:

.env
EMAIL_TRANSPORT_PROVIDER=resend

ou:

.env
EMAIL_TRANSPORT_PROVIDER=ses

EMAIL_TRANSPORT_PROVIDER controla o e-mail transacional de saída e o domínio de resposta ativo para os e-mails enviados dali em diante. Ele não substitui automaticamente todos os utilitários específicos do Resend que existem no código, como os de audiências e contatos.

Comparação de recursos atual

Esta é a diferença prática entre os dois transportes na implementação atual:

  • os dois aceitam o envio transacional pela mesma API de e-mail do app
  • os dois funcionam com EMAIL_TRANSPORT_PROVIDER
  • os dois convivem com um roteamento de respostas ciente do provedor para o e-mail novo
  • a leitura das respostas recebidas aceita tanto o domínio de entrada do Resend quanto o do SES, o que torna a sobreposição possível
  • o Resend continua com os próprios utilitários de audiências e contatos, à parte do interruptor de transporte
  • neste lançamento, o SES ainda não aceita envios agendados nem etiquetas de provedor

Como o e-mail funciona no Fluxo

Escolha o provedor que escolher, o formato do fluxo no app não muda:

  1. O React Email gera a mensagem de saída dentro do app.
  2. EMAIL_TRANSPORT_PROVIDER seleciona o transporte ativo para os novos envios.
  3. Os novos endereços de resposta são gerados a partir do domínio de entrada do provedor ativo.
  4. As respostas recebidas e os eventos de ciclo de vida são normalizados de volta para a API.
  5. A API transforma as respostas recebidas em mensagens da conversa e registra os eventos de retorno, reclamação e falha para a supressão.

No momento, os roteadores dos dois provedores aceitam os eventos email.delivered mas, de propósito, não os persistem. Não trate essa integração como rastreamento de entrega; se você precisa de confirmação de entrega, use os logs do provedor.

Isso significa que o Resend e o SES podem conviver durante uma migração ou um período de sobreposição:

  • o e-mail de saída novo segue o provedor ativo
  • as cadeias de resposta antigas do Resend podem continuar funcionando pelo caminho de entrada do Resend
  • o SES pode ser ativado e verificado antes de você virar a flag de transporte

Ambiente de e-mail compartilhado

Estas variáveis de ambiente importam qualquer que seja o provedor escolhido:

.env
EMAIL_TRANSPORT_PROVIDER=resend
EMAIL_NOTIFICATION_FROM=support@example.com
EMAIL_MARKETING_FROM=hello@example.com
EMAIL_RESEND_INBOUND_DOMAIN=inbound.example.com
EMAIL_SES_INBOUND_DOMAIN=ses-inbound.example.com

O que elas controlam:

  • EMAIL_TRANSPORT_PROVIDER: seleciona o transporte transacional ativo para o e-mail de saída novo
  • EMAIL_NOTIFICATION_FROM: o endereço do remetente para o e-mail do tipo notificação
  • EMAIL_MARKETING_FROM: o endereço do remetente para o e-mail do tipo marketing
  • EMAIL_RESEND_INBOUND_DOMAIN: o domínio de respostas recebidas usado pelo caminho do Resend
  • EMAIL_SES_INBOUND_DOMAIN: o domínio de respostas recebidas usado pelo caminho do SES

Mesmo que você pretenda usar só um provedor, vale entender os dois domínios: a leitura de entrada aceita ambos e a sobreposição é um estado suportado.

Configuração do Resend

Hoje o Resend é o transporte padrão do app. É uma boa escolha se você quer um provedor hospedado simples sem montar de cara a infraestrutura do SES.

O que configurar

Defina as variáveis de ambiente próprias do Resend:

.env
EMAIL_TRANSPORT_PROVIDER=resend
RESEND_API_KEY=re_...
RESEND_WEBHOOK_SECRET=whsec_...
EMAIL_RESEND_INBOUND_DOMAIN=inbound.example.com
EMAIL_NOTIFICATION_FROM=support@example.com
EMAIL_MARKETING_FROM=hello@example.com

O que o app espera do Resend

Para o caminho do Resend, o Fluxo espera:

  • uma chave de API válida para os envios transacionais de saída
  • um domínio de remetente verificado para os endereços from que você usar
  • um domínio de entrada para tratar as respostas
  • entrega de webhooks para as rotas de webhook do Resend que já existem

O que se espera dos webhooks

O caminho legado do Resend é mantido justamente para que possa continuar atendendo:

  • as respostas a tópicos antigos enviados pelo Resend
  • os eventos de ciclo de vida do Resend durante os períodos de sobreposição

Se você mantiver o Resend ativo enquanto avalia o SES, ainda não remova a configuração de entrada dele.

Configuração do SES

O SES é a opção nativa da AWS e o caminho recomendado se você quer que toda a stack de e-mail fique na sua própria conta da AWS.

Por que escolher o SES

O SES encaixa muito bem com a auto-hospedagem porque dá ao Fluxo todas as peças de que ele precisa:

  • envio transacional de saída
  • tratamento das respostas recebidas
  • webhooks de entrega, retorno, reclamação e falha (a entrega é aceita mas não é persistida)
  • infraestrutura que roda na sua conta da AWS em vez de em um SaaS de e-mail à parte

Caminho de configuração recomendado

O módulo do SES fica em infra/aws/ses-email-setup.

Ele provisiona:

  • as identidades e a configuração do SES
  • um domínio de respostas recebidas
  • um bucket do S3 para o e-mail recebido bruto
  • o encanamento de SNS e SQS
  • pequenas funções Lambda de ponte escritas em TypeScript
  • credenciais do IAM para o envio de saída com o SES

Passo 1: preencha as variáveis do Terraform

Entre no módulo:

cd infra/aws/ses-email-setup

Copie o arquivo de variáveis de exemplo:

cp terraform.tfvars.example terraform.dev.tfvars

Depois preencha os valores próprios do seu ambiente:

terraform.dev.tfvars
aws_region           = "us-east-1"
environment          = "dev"
sender_domain        = "example.com"
inbound_domain       = "ses-inbound.example.com"
inbound_bucket_name  = "fluxo-dev-ses-example"
api_webhook_base_url = "https://api.example.com"
ses_webhook_secret   = "replace-me"
route53_zone_id      = "Z1234567890"

Passo 2: instale as dependências e faça o deploy

O módulo compila as lambdas de ponte a partir do monorepo com bun build, então garanta que as dependências estejam instaladas na raiz do repositório:

bun install

Depois inicialize e aplique:

terraform init
terraform apply -var-file="terraform.dev.tfvars"

Passo 3: confirme o DNS e a saúde da identidade do SES

Não avance enquanto a identidade de remetente e o domínio de entrada não estiverem saudáveis.

Se você usa a automação do Route53, o Terraform pode criar os registros por você. Caso contrário, será preciso adicionar as saídas na mão.

No mínimo, verifique:

  • o registro de verificação do remetente do SES
  • os registros DKIM
  • os registros MAIL FROM
  • o registro MX de entrada do seu domínio de respostas do SES

Passo 4: configure o ambiente de execução do SES

Defina as variáveis de ambiente próprias do SES:

.env
EMAIL_TRANSPORT_PROVIDER=resend
EMAIL_NOTIFICATION_FROM=support@example.com
EMAIL_MARKETING_FROM=hello@example.com
EMAIL_RESEND_INBOUND_DOMAIN=inbound.example.com
EMAIL_SES_INBOUND_DOMAIN=ses-inbound.example.com
SES_REGION=us-east-1
SES_ACCESS_KEY_ID=AKIA...
SES_SECRET_ACCESS_KEY=...
SES_CONFIGURATION_SET=fluxo-email-dev
SES_WEBHOOK_SECRET=replace-me

O que significam no SES:

  • EMAIL_SES_INBOUND_DOMAIN: o domínio de respostas recebidas gerenciado pelo SES
  • SES_REGION: a região da AWS usada para o envio de saída com o SES
  • SES_ACCESS_KEY_ID e SES_SECRET_ACCESS_KEY: as credenciais usadas para os envios de saída
  • SES_CONFIGURATION_SET: o conjunto de configuração do SES criado pelo Terraform
  • SES_WEBHOOK_SECRET: o segredo compartilhado com que as requisições de webhook da ponte são assinadas

Guarde as chaves do provedor e os segredos de webhook no gerenciador de segredos do seu deploy, não em um .env versionado. Prefira roles de carga de trabalho a chaves estáticas do SES quando o seu runtime permitir, gire as credenciais de longa duração e mantenha ativa a janela de carimbo de tempo e antirreplay da ponte. Além disso, as contas do SES precisam sair do modo sandbox e ter limites de envio suficientes antes de ir para produção.

Passo 5: entenda a ponte de webhooks

O caminho do SES usa pequenas funções de ponte serverless que normalizam o e-mail recebido e os eventos de ciclo de vida antes de chegarem à API.

Essas pontes escrevem de volta em:

  • /ses/webhooks/inbound
  • /ses/webhooks/events

As requisições incluem estes cabeçalhos:

  • x-fluxo-timestamp
  • x-fluxo-signature
  • x-fluxo-event

A assinatura é um HMAC-SHA256 sobre:

<timestamp>.<raw-json-body>

Você não precisa construir isso se usar o módulo do Terraform, mas é útil saber na hora de depurar o tráfego de webhooks.

Passo 6: implante o SES com segurança

O caminho de implantação limpo é:

  1. Deixe primeiro EMAIL_TRANSPORT_PROVIDER=resend.
  2. Faça o deploy da infraestrutura do SES e verifique o DNS e as identidades.
  3. Confirme que os endpoints de webhook do SES são alcançáveis a partir do seu host público de API.
  4. Teste em homologação o e-mail de saída, as respostas recebidas e os eventos de ciclo de vida.
  5. Mude para EMAIL_TRANSPORT_PROVIDER=ses só quando o SES estiver saudável.
  6. Mantenha ativo o caminho de entrada do Resend durante a janela de sobreposição para que as cadeias de resposta antigas continuem funcionando.

Se você faz um deploy do zero apenas com SES, pode mudar direto para ses assim que as identidades, os webhooks e o fluxo de entrada estiverem totalmente verificados.

Lista de verificação

Escolha o provedor que escolher, confirme que tudo isto funciona:

  • um e-mail transacional é enviado com sucesso
  • o domínio do remetente está verificado e o provedor o aceita
  • as respostas voltam para a conversa certa
  • os eventos de retorno, reclamação e falha chegam à API e atualizam o estado de supressão
  • um evento de entrega é visível nos logs do provedor (o Fluxo não o guarda)
  • os segredos não aparecem nos logs e a retenção do e-mail recebido bruto bate com a sua política de privacidade

No caso específico do SES, confirme também:

  • que /ses/webhooks/inbound está recebendo as cargas normalizadas da ponte
  • que /ses/webhooks/events está recebendo eventos de entrega, retorno, reclamação e falha; só o retorno, a reclamação e a falha alteram o estado do Fluxo
  • que as cadeias de resposta antigas do Resend continuam funcionando se você migrar aos poucos

Quando escolher cada provedor

Escolha resend se você quer:

  • o caminho de configuração mais rápido
  • um transporte de e-mail totalmente hospedado
  • ficar alinhado à configuração padrão do app

Escolha ses se você quer:

  • a stack de e-mail na sua própria conta da AWS
  • mais uma peça de infraestrutura auto-hospedável
  • respostas recebidas e eventos de ciclo de vida sem depender a longo prazo de um SaaS de e-mail à parte

Se estiver em dúvida, comece com o Resend, mantenha limpas as variáveis de ambiente comuns do e-mail e acrescente o SES quando estiver pronto para assumir a infraestrutura você mesmo.

Esta página foi útil?

Abra uma issue de documentação já preenchida para que a equipe possa agir.