tva
← Insights

Configurar uma Caixa de Correio para o Agente de IA do Seu Projeto

Mais cedo ou mais tarde, o agente de IA específico de projeto que construiu precisa de um endereço de email. O padrão de bot no Telegram que descrevemos em Construir um Assistente de IA Específico de Projeto via Telegram trata do chat em tempo real, mas o email é um canal diferente — notificações de serviços, confirmações de fornecedores, reposições de palavras-passe via OAuth, correspondência de backoffice com pessoas que não estão no Telegram. Pode encaminhar esse email para um endereço pessoal e conviver com o ruído, ou pode dar ao projeto a sua própria caixa de correio num subdomínio dedicado.

Este guia aborda o segundo caminho: uma caixa de correio dedicada num subdomínio de projeto, com DKIM, SPF e DMARC configurados de forma limpa. O padrão usa um fornecedor para DNS (Cloudflare, no nosso caso) e um fornecedor separado para o sistema de email (Opalstack), que é a configuração com que a maioria das operações de pequena escala acaba — DNS onde o domínio apex já se encontra, email no fornecedor que tiver IMAP decente, acesso API razoável e uma reputação que sobrevive aos filtros do Gmail.

Toda a configuração resume-se a quatro chamadas API mais três registos DNS. Com a preparação certa, leva cerca de dez minutos de ponta a ponta. Vamos mostrar as chamadas, a verificação e os pontos de falha que nos apanharam de surpresa da primeira vez.

O que Este Guia Resolve

  • Um subdomínio de projeto (system.example.com) sem infraestrutura de email associada
  • Email a entrar para um endereço específico do projeto a ser rejeitado por não existir registo MX
  • Email a sair do projeto a reprovar nas verificações DKIM no Gmail e a cair no spam
  • Registos SPF e DMARC que existem mas não têm nada para autenticar
  • Um agente de IA que precisa de um canal de email sem passar pela conta pessoal

O que Vai Precisar

  • Um domínio apex que controla, com DNS num fornecedor que expõe uma API (Cloudflare, Route53, DigitalOcean DNS, etc.)
  • Um fornecedor de email que suporte a adição de domínios via API, gere chaves DKIM na criação do domínio e exponha endpoints IMAP/SMTP (Opalstack, Mailcow, Migadu, Fastmail, etc.)
  • Tokens API de ambos os fornecedores, guardados num local a partir do qual possa executar scripts
  • dig, openssl s_client e um interpretador Python para verificação
  • Cerca de quinze minutos

Porquê o Padrão de Fornecedores Separados

O modelo mental predefinido é «um fornecedor para tudo» — alojar o website, o DNS e a caixa de correio no mesmo lugar. Funciona até que qualquer um dos três precise de evoluir de forma independente. Abordámos o critério de decisão para escolher entre serviços integrados e especialistas dedicados em A Decisão de Self-Hosting: Quando o SaaS Custa Mais do que a Sua Própria Infraestrutura, e a mesma lógica aplica-se aqui numa escala mais reduzida.

No nosso caso, o DNS do domínio apex está no Cloudflare porque precisamos da resolução AnyCast, do proxy para os sites públicos e da API para gestão automatizada de registos. O sistema de email está no Opalstack porque o custo por caixa de correio é negligenciável, a reputação do servidor IMAP deles é sólida e a API é das mais limpas no espaço de alojamento de email na UE. Não vamos mudar o DNS para acompanhar o email, nem vamos mudar o email para acompanhar o DNS. O custo de os gerir separadamente resume-se a exactamente três registos DNS e um modelo mental: o fornecedor de DNS informa o mundo para onde vai o email; o fornecedor de email recebe, armazena e assina.

Esta separação é importante operacionalmente porque limita o raio de impacto de uma falha. Uma interrupção no fornecedor de DNS para novas decisões de encaminhamento de email, mas o email já em trânsito para os hosts MX continua a chegar. Uma interrupção no fornecedor de email para a entrega, mas as consultas DNS continuam a resolver. Se tivéssemos empilhado tudo num único fornecedor, ambas as camadas falhariam em simultâneo. A mesma lógica aparece na nossa arquitectura de produção para empilhamento de reverse proxies — separação de responsabilidades, cada camada substituível de forma isolada.

Caixa de Correio Dedicada, Alias de Reencaminhamento ou Inbox SaaS

Antes de criar seja o que for, escolha o nível de dedicação adequado. As três opções não são equivalentes.

Uma caixa de correio dedicada significa uma inbox real que guarda email, tem credenciais IMAP e consegue tanto enviar como receber. Custo: cerca de um a três euros por mês num fornecedor de email self-hosted, mais o trabalho de configuração via API. É o que o agente de IA usa quando precisa de ler email de verdade — para analisar confirmações de fornecedores, tratar notificações de serviços, manter uma conversa com um interlocutor humano ao longo de várias trocas.

Um alias de reencaminhamento é um endereço virtual que apenas redireciona para uma inbox já existente. Custo: zero, apenas configuração. É a escolha certa quando o agente de IA só precisa de receber num endereço com a marca do projecto, mas a leitura e o processamento efectivos acontecem numa inbox humana que já existe. A contrapartida é não ter acesso IMAP para o agente, não haver filtragem por projecto no destino e não haver um caminho limpo de rollback quando o projecto termina — a limpeza dos aliases acaba por ser esquecida.

Uma inbox SaaS é um serviço como o Postmark, o Mailgun Inbound ou o AWS SES com regras de recepção. Custo: facturação por mensagem mais o trabalho de engenharia para ligar o agente de IA aos receptores de webhook. É a opção certa quando o agente precisa de tratar grandes volumes, encaminhar email por regras de cabeçalho ou desencadear fluxos automatizados em cada mensagem. Para um agente específico de projecto que trata dezenas a centenas de mensagens por mês, isto é excessivo.

Para o caso de uso descrito em o artigo sobre o assistente de IA no Telegram — um operador humano, dois colaboradores de projecto, um bot suportado por Claude — a caixa de correio dedicada é a escolha adequada. O agente tem um endereço real que pode ler via IMAP, enviar via SMTP, e que nasce e morre de forma limpa com o projecto.

Passo 1: Registar o Subdomínio no Sistema de Email

O fornecedor de email tem de saber que o subdomínio do seu projecto é um dos seus domínios antes de aceitar email para ele. Esta é a chamada que também gera o par de chaves DKIM.

POST https://my.mailhost.example/api/v1/domain/create/
Authorization: Token <YOUR_MAIL_API_TOKEN>
Content-Type: application/json

[{"name": "system.example.com"}]

A resposta contém três campos que importam: o UUID do domínio (necessário para a limpeza e para o mapeamento de endereços mais tarde), o state (normalmente PENDING_CREATE durante alguns segundos, depois READY), e um campo dkim_record com um valor TXT completamente formatado, pronto a colar no DNS:

{
  "id": "<DOMAIN_UUID>",
  "state": "PENDING_CREATE",
  "name": "system.example.com",
  "dkim_record": "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4G..."
}

Faça polling até o state mudar para READY e capture o valor de dkim_record. Vai colá-lo textualmente no fornecedor de DNS no passo seguinte. Se a chamada de criação falhar com um erro de invalid hostname, a causa mais comum é que o seu fornecedor de email apenas suporta domínios de segundo nível e rejeita subdomínios de três níveis. Abra um ticket de suporte; na prática ainda não encontrámos um fornecedor que recusasse isto.

Verifique o tamanho da chave DKIM antes de avançar. Um valor de dkim_record com menos de cerca de 250 bytes é uma chave RSA de 1024 bits; as chaves de 2048 bits têm tipicamente entre 380 e 420 bytes. O NIST descontinuou o RSA de 1024 bits em 2013, e o Gmail, Microsoft, Yahoo e AWS SES tratam 2048 bits como a linha de base de 2026 — as chaves de 1024 bits ainda autenticam, mas são interpretadas como um sinal fraco nos filtros de spam empresariais. Se o seu fornecedor permitir escolher o tamanho, opte por 2048; um padrão exclusivo de 1024 bits é um sinal de alerta na escolha do fornecedor.

Passo 2: Configurar os Registos DNS

Três registos, todos criados no seu fornecedor de DNS para o subdomínio do projecto. Nenhum deles pode ser encaminhado pelo edge do Cloudflare — os registos MX e TXT têm de ser DNS-only, e a API do Cloudflare reverterá silenciosamente para DNS-only se definir proxied: true, mas é mais limpo defini-lo explicitamente.

Os dois registos MX indicam aos remetentes onde entregar o email. A maioria dos fornecedores de email usa dois ou mais hosts MX com prioridade igual para distribuição de carga por round-robin:

POST https://api.dnsprovider.example/zones/<ZONE_ID>/dns_records

{"type":"MX","name":"system.example.com",
 "content":"mx1.de.mailhost.example","priority":10,
 "ttl":3600,"proxied":false}

{"type":"MX","name":"system.example.com",
 "content":"mx2.de.mailhost.example","priority":10,
 "ttl":3600,"proxied":false}

O registo TXT DKIM usa o valor de dkim_record do Passo 1, colocado em dkim._domainkey.<subdomínio>:

{"type":"TXT",
 "name":"dkim._domainkey.system.example.com",
 "content":"v=DKIM1; k=rsa; p=MIGfMA0G...",
 "ttl":3600,"proxied":false}

Se a chave pública DKIM tiver mais de 255 bytes (o que acontece com chaves RSA de 2048 bits), terá de a dividir em múltiplos segmentos entre aspas: "segmento1" "segmento2". A maioria dos fornecedores de DNS trata a divisão automaticamente na sua API; se o seu não o fizer, a divisão terá de ser feita da sua parte.

SPF e DMARC são registos que define uma vez, no próprio subdomínio e em _dmarc.<subdomínio>. O SPF informa os receptores quais os IPs autorizados a enviar por este domínio; o DMARC diz-lhes o que fazer quando o SPF ou o DKIM falham:

{"type":"TXT","name":"system.example.com",
 "content":"v=spf1 include:spf.mailhost.example ~all",
 "ttl":3600,"proxied":false}

{"type":"TXT","name":"_dmarc.system.example.com",
 "content":"v=DMARC1; p=none; rua=mailto:[email protected]; aspf=r; adkim=r",
 "ttl":3600,"proxied":false}

Comece o DMARC com p=none. Este é o modo de monitorização — os receptores enviam relatórios agregados para o endereço rua, mas nenhum email é rejeitado com base na política. A implementação padrão consiste em duas a seis semanas com p=none até os relatórios agregados mostrarem pelo menos 98% de conformidade para email legítimo, seguida de uma progressão gradual via tag pct= — por exemplo p=quarantine; pct=25 durante duas semanas, depois pct=75, depois pct=100, e por fim p=reject. Saltar a progressão e ir directamente para p=reject num domínio completamente novo é uma forma segura de descartar o seu próprio email legítimo antes de ter validado o caminho de assinatura DKIM.

Passo 3: Criar a Caixa de Correio e o Mapeamento de Endereço

O modelo de dados do fornecedor de email tem normalmente dois recursos separados: um mailuser (a conta IMAP com credenciais e quota) e um endereço (a cadeia local@domínio que encaminha email para um mailuser). São separados porque o mesmo mailuser pode ser o destino de vários endereços diferentes no mesmo domínio ou em domínios diferentes.

Gere uma palavra-passe forte e crie o mailuser. A convenção de nomenclatura varia consoante o fornecedor; o padrão comum é <local>_<domínio-com-underscores>. Atenção ao limite de comprimento — a maioria dos fornecedores limita os nomes de mailuser a 32 caracteres, o que é fácil de ultrapassar com um subdomínio mais longo:

import secrets, string
alphabet = string.ascii_letters + string.digits + "!@#%^&*-_=+"
password = ''.join(secrets.choice(alphabet) for _ in range(32))

# Depois:
POST /api/v1/mailuser/create/
[{"name": "bot_system_example_com",
  "imap_server": "<IMAP_SERVER_UUID>",
  "password": password}]

Quando o mailuser estiver READY, crie o mapeamento de endereço que liga local@subdomínio ao mesmo:

POST /api/v1/address/create/
[{"source": "[email protected]",
  "destinations": ["<MAILUSER_UUID>"],
  "forwards": []}]

O array forwards serve para endereços externos adicionais que recebam uma cópia. Deixe-o vazio a não ser que queira efectivamente reencaminhar a caixa de correio para uma inbox humana em paralelo — o que é um padrão útil durante a fase de transição do projecto, mas confuso a longo prazo.

Passo 4: Verificar a Configuração de Ponta a Ponta

Quatro verificações, por ordem. Não salte o loopback interno — é o único teste que confirma que o encaminhamento de entrada chega efectivamente à caixa de correio.

Propagação DNS. Os fornecedores com AnyCast de nível Cloudflare propagam normalmente em bem menos de um minuto. Faça loop até ambos os registos aparecerem:

for i in $(seq 1 36); do
  mx=$(dig +short system.example.com MX)
  dkim=$(dig +short dkim._domainkey.system.example.com TXT)
  if [ -n "$mx" ] && [ -n "$dkim" ]; then break; fi
  sleep 5
done
echo "MX: $mx"
echo "DKIM: $dkim"

Login IMAP. Confirme que as credenciais funcionam e que a caixa de correio tem efectivamente uma inbox associada:

openssl s_client -crlf -connect imap.mailhost.example:993 -quiet
a1 LOGIN bot_system_example_com <password>
a2 SELECT INBOX

Resposta esperada: a1 OK Logged in seguido do SELECT a confirmar EXISTS 0 numa caixa de correio nova.

Loopback interno. O melhor teste de ponta a ponta: enviar um email do novo endereço para si próprio e verificar que chega ao IMAP. Isto valida o caminho completo — autenticação SMTP, assinatura DKIM, resolução MX, aceitação do email, entrega na caixa de correio, visibilidade IMAP — sem depender do filtro de spam de qualquer fornecedor externo:

import smtplib, ssl, imaplib, time
from email.message import EmailMessage

msg = EmailMessage()
msg["From"] = "[email protected]"
msg["To"]   = "[email protected]"
msg["Subject"] = "loopback test"
msg.set_content("hello self")

with smtplib.SMTP("smtp.mailhost.example", 587) as s:
    s.starttls(context=ssl.create_default_context())
    s.login("bot_system_example_com", "<password>")
    s.send_message(msg)

time.sleep(10)
imap = imaplib.IMAP4_SSL("imap.mailhost.example", 993)
imap.login("bot_system_example_com", "<password>")
imap.select("INBOX")
typ, search = imap.search(None, "ALL")
print("inbox count:", len(search[0].split()))

Nos cabeçalhos do email entregue, procure a linha Authentication-Results. Uma configuração correcta mostra spf=pass com o smtp.mailfrom correcto e um cabeçalho DKIM-Signature com d=<o seu subdomínio> e s=dkim. Se estes estiverem presentes, toda a cadeia funciona; a única variável restante é a forma como os receptores externos o avaliam, o que os relatórios DMARC lhe irão dizer nos dias seguintes.

Envio externo. Envie um email para um endereço externo que possa verificar — um Gmail pessoal, uma inbox de trabalho separada, algo fora do sistema. Confirme que fica na caixa de entrada, não no spam. Se ficar no spam logo no primeiro envio a partir de um domínio novo, a causa mais comum é a ausência de reputação do domínio remetente; o aquecimento é gradual, mas um único email de teste deve passar sem problemas porque o receptor avalia o DKIM e o SPF pelos seus próprios méritos, e não pelo volume de envio histórico.

Armadilhas Comuns

O limite de 32 caracteres no nome do mailuser apanha-nos sempre que o subdomínio mais a parte local é mais longo do que o esperado. backoffice_dashboard_system_example_com tem trinta e nove caracteres e é rejeitado; bo_dashboard_system_example_com cabe com trinta e um. Escolha abreviações conscientemente em vez de deixar que a API as imponha a meio da implementação.

A armadilha do proxy do Cloudflare. A interface do Cloudflare permite activar o proxy com nuvem laranja em qualquer registo. Para A/AAAA numa origem web, quase sempre o quer activo. Para registos MX, está sempre desactivado — o Cloudflare não faz proxy de email. A armadilha surge quando activa o proxy em massa via script e inclui acidentalmente os registos MX. O Cloudflare descarta silenciosamente a flag de proxy para tipos não suportados, pelo que parece ter funcionado, mas acaba a perder minutos a perceber porque é que não há nada de errado.

Greylisting no primeiro email a entrar. Os sistemas de email por vezes aplicam greylisting à primeira mensagem de um remetente desconhecido — resposta temporária 4xx, pedindo ao remetente para tentar novamente passados alguns minutos. O Gmail tenta novamente de forma automática. Se o primeiro teste de entrada parecer falhar, aguarde quinze minutos antes de concluir que está avariado.

O limite de consultas DNS do SPF. O SPF tem um limite rígido de dez consultas DNS durante a avaliação (RFC 7208 §4.6.4). Um único include:spf.mailhost.example conta como uma consulta, mesmo que esse include resolva internamente para dezenas de IPs. Só atinge o limite se começar a encadear múltiplos remetentes — por exemplo, adicionando depois include:_spf.resend.com para uma pipeline de marketing. Planeie o registo SPF para a lista de remetentes a longo prazo, não apenas para o primeiro.

dkim_privkey vazio no lado do fornecedor de email. Alguns fornecedores expõem um endpoint de criação de domínio que tem sucesso mas não gera efectivamente a chave DKIM, exigindo uma chamada separada de «activar DKIM». Verifique que o campo dkim_record na sua resposta de criação não está vazio antes de avançar. Se estiver vazio, consulte a documentação do fornecedor para a chamada secundária.

Monitorização ingénua da implementação. Se gerir dezenas de domínios, um registo DKIM com problemas ou um destino de relatório DMARC expirado não aparecerá na monitorização de rotina a menos que verifique activamente. A nossa rotina de verificação mensal de saúde para serviços self-hosted inclui um passo de auditoria de registos de email exactamente por esta razão.

Ignorar o MTA-STS quando disponível. O MTA-STS publica uma política que obriga os remetentes a usar TLS para os seus hosts MX e a validar o certificado. O Gmail, o Microsoft 365 e o Yahoo verificam-no; a adopção a nível da internet ainda está abaixo de um por cento, pelo que uma política válida é um pequeno sinal de reputação. A contrapartida é operacional: uma política que aponte para hosts MX que falhem na verificação do certificado TLS bloqueia email legítimo a entrar. Se o seu fornecedor disponibilizar MTA-STS, active-o depois de o DKIM e o DMARC estarem estáveis.

Caminho de Rollback

Se a verificação falhar ou decidir que o projecto afinal não precisa de caixa de correio própria, a limpeza é idempotente e demora cinco minutos:

  1. POST /api/v1/address/delete/ com o UUID do endereço
  2. POST /api/v1/mailuser/delete/ com o UUID do mailuser
  3. POST /api/v1/domain/delete/ com o UUID do domínio no sistema de email (isto também elimina as chaves DKIM)
  4. DELETE /zones/<zone>/dns_records/<id> para cada um dos três registos DNS

A ordem é importante porque alguns fornecedores recusam eliminar o domínio enquanto ainda tiver endereços associados. A ordem inversa também lhe dá um ponto sensato para parar e inspeccionar — se o Passo 1 falhar porque há email na caixa de correio que se esqueceu, ainda não quebrou o encaminhamento a nível DNS.

Deixar os registos SPF e DMARC no subdomínio após um rollback é inofensivo. Não autenticam nada, mas também informam os receptores futuros de que este subdomínio explicitamente não envia email legítimo — o que representa um pequeno benefício anti-spoofing. Tratamo-los como activos por defeito uma vez que existam. Este tipo de raciocínio de «resíduo seguro» é a mesma lógica que aplicamos à recuperação de desastres em serviços self-hosted: o padrão de limpeza pós-remoção é tão importante quanto o padrão de instalação.

Conclusão

Uma caixa de correio específica de projecto não é infraestrutura; é um pequeno primitivo operacional que permite a um agente de IA — ou a qualquer outro processo automatizado — tornar-se um participante de pleno direito em fluxos de trabalho baseados em email. O padrão das quatro chamadas API acima é facilmente portável entre fornecedores de email; os registos DNS são portáveis entre fornecedores de DNS. O que vale a pena fazer bem é o limite entre os dois sistemas: que registo vive onde, como são os modos de falha, e como verificar de ponta a ponta sem depender do comportamento do filtro de spam de qualquer terceiro externo.

Se quiser ajuda a arquitectar uma stack específica de projecto — agente no Telegram, caixa de correio, ingestão de documentos, o pacote completo — a tva pode ajudar.


Artigos Relacionados

Artigos relacionados