Como Receber Email Programaticamente: IMAP, Webhooks, e APIs de Email
Três abordagens para receber email em sua aplicação: IMAP polling, webhooks de email, e APIs de polling. Aqui estão as trade-offs e quando usar cada uma.

Quando você precisa que sua aplicação receba e processe email, existem três abordagens principais. Cada uma tem trade-offs diferentes em termos de latência, complexidade, e confiabilidade.
Abordagem 1: IMAP Polling
IMAP (Internet Message Access Protocol) é o protocolo padrão para leitura de email. Você se conecta a um servidor IMAP, recupera mensagens, marca-as como lidas, e se desconecta.
Como funciona:
- Sua aplicação conecta ao servidor IMAP em intervalos regulares (ex., a cada 30 segundos)
- Recupera novas mensagens desde a última verificação
- Processa o conteúdo (extrai anexos, analisa corpo, valida remetente)
- Marca como processado (deleta, move para pasta, marca como lido)
- Se desconecta
Configuração IMAP comum:
Host: imap.reusable.email
Port: 993
Encryption: SSL/TLS
Autenticação: Username + Password
Exemplo em Python usando IMAP com IDLE:
import imaplib
import email
from email.header import decode_header
import time
def connect_to_imap(host, username, password):
"""Conecta ao servidor IMAP"""
mail = imaplib.IMAP4_SSL(host, 993)
mail.login(username, password)
return mail
def idle_mode(mail):
"""Usa IDLE para receber notificações push quase-reais"""
mail.select('INBOX')
# Enviar comando IDLE
mail.idle()
print("Listening for new emails...")
# Block e aguarde por novos emails
while True:
try:
# Aguarda até 30 minutos por nova atividade
responses = mail.idle_check(timeout=1800)
if responses:
print(f"Nova atividade detectada: {responses}")
# Processar novas mensagens
mail.idle_done()
status, messages = mail.search(None, 'UNSEEN')
if messages[0]:
for msg_id in messages[0].split():
process_message(mail, msg_id)
# Retomar IDLE
mail.idle()
except Exception as e:
print(f"Erro em IDLE: {e}")
break
mail.idle_done()
def process_message(mail, msg_id):
"""Processa uma mensagem de email individual"""
status, msg_data = mail.fetch(msg_id, '(RFC822)')
for response_part in msg_data:
if isinstance(response_part, tuple):
msg = email.message_from_bytes(response_part[1])
# Extrai informação básica
from_ = msg.get('From')
subject = msg.get('Subject')
body = msg.get_payload(decode=True).decode()
print(f"De: {from_}")
print(f"Assunto: {subject}")
print(f"Corpo: {body[:100]}...")
# Marca como lido
mail.store(msg_id, '+FLAGS', '\\Seen')
def polling_mode(mail, interval=30):
"""Polling tradicional - verifica em intervalos"""
mail.select('INBOX')
while True:
try:
# Procura por emails não lidos
status, messages = mail.search(None, 'UNSEEN')
if messages[0]:
for msg_id in messages[0].split():
process_message(mail, msg_id)
print(f"Próxima verificação em {interval}s...")
time.sleep(interval)
except Exception as e:
print(f"Erro no polling: {e}")
time.sleep(interval)
# Uso
mail = connect_to_imap('imap.reusable.email', '[email protected]', 'sua-senha')
# Opção 1: IDLE (quase-real-time)
# idle_mode(mail)
# Opção 2: Polling tradicional
polling_mode(mail, interval=30)
Prós:
- Simples de implementar — IMAP é bem documentado e suportado
- Confiável — você controla a lógica de retry
- Sem dependência externa — apenas IMAP padrão
- Funciona com qualquer provedor de email com suporte IMAP
- IDLE oferece notificação quase-real-time com latência baixa
- Você consegue gerenciar estado (marca como lido, deleta, move para pasta)
Contras:
- Latência — polling requer espera entre verificações
- Overhead — cada verificação é uma nova conexão (a menos que você mantenha a conexão aberta)
- Complexidade de erro — você precisa lidar com timeouts, reconexões, sincronização de estado
- Escalabilidade — muitas conexões IMAP abertas consomem recursos do servidor
Melhor para:
- Aplicações que processam email assincronamente
- Quando você controla o servidor de email
- Quando latência de minutos é aceitável
- Pipelines de testes de CI/CD
Abordagem 2: Webhooks
Webhooks invertem o modelo. Em vez de sua aplicação fazer pull do email, o provedor de email faz push para sua aplicação via HTTP.
Como funciona:
- Você registra uma URL webhook na configuração do seu provedor de email
- Quando um email chega, o provedor envia um POST HTTP para sua URL
- Sua aplicação recebe a carga útil JSON contendo o email
- Você processa e retorna uma resposta 2xx para confirmar
Configuração típica:
{
"event": "email.received",
"timestamp": "2025-10-22T14:30:45Z",
"from": "[email protected]",
"to": "[email protected]",
"subject": "Novo email",
"body": "Conteúdo do email",
"attachments": [
{
"filename": "documento.pdf",
"content_type": "application/pdf",
"size": 12345,
"url": "https://api.provider.com/attachments/abc123"
}
]
}
Exemplo em Python com Flask:
from flask import Flask, request
import hmac
import hashlib
app = Flask(__name__)
WEBHOOK_SECRET = 'seu-webhook-secret-do-provedor'
def verify_webhook_signature(payload_str, signature):
"""Verifica que o webhook vem do provedor de email"""
computed = hmac.new(
WEBHOOK_SECRET.encode(),
payload_str.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(computed, signature)
@app.route('/webhooks/email', methods=['POST'])
def handle_email_webhook():
# Verificar autenticação
signature = request.headers.get('X-Webhook-Signature')
if not verify_webhook_signature(request.get_data(as_text=True), signature):
return {'error': 'Invalid signature'}, 401
# Extrair dados
data = request.json
email_from = data.get('from')
subject = data.get('subject')
body = data.get('body')
attachments = data.get('attachments', [])
print(f"Novo email de {email_from}: {subject}")
# Processar attachments
for attachment in attachments:
# Download do arquivo se necessário
attachment_url = attachment.get('url')
filename = attachment.get('filename')
print(f" Attachment: {filename}")
# Sua lógica de aplicação aqui
process_incoming_email(email_from, subject, body)
# Retornar sucesso
return {'status': 'received'}, 200
def process_incoming_email(from_addr, subject, body):
"""Processa o email recebido"""
# Salva em banco de dados, envia notificação, executa ação, etc.
pass
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Prós:
- Latência baixa — entrega quase instantânea
- Escalável — o provedor gerencia conexões
- Simples — você apenas recebe um POST HTTP
- Sem polling — você não precisa verificar continuamente
- Acesso a metadados — o provedor fornece informação estruturada
Contras:
- Dependência do provedor — você está preso à sua implementação de webhook
- Confiabilidade — você precisa lidar com retries se sua URL falhar
- Gerenciamento de estado — você precisa rastrear o que foi processado
- Segurança — você precisa validar que o webhook vem do provedor real (usar assinaturas HMAC)
- Não funciona com todos os provedores — webhooks são um extra
Melhor para:
- Processamento em tempo real
- Aplicações que precisam de baixa latência
- Quando seu provedor oferece webhooks confiáveis
- Aplicações modernas baseadas em eventos
Abordagem 3: Email API
Alguns provedores oferecem APIs REST propriedárias para acessar email programaticamente.
Como funciona:
- Você autentica com a API usando uma chave de API
- Você faz chamadas REST como
GET /api/emails/inbox - A API retorna emails como JSON
- Você processa de forma similar ao polling IMAP
Exemplo:
import requests
import json
API_BASE = 'https://api.provider.com/v1'
API_KEY = 'seu-api-key'
def get_inbox_emails(limit=10):
"""Recupera emails via API REST"""
response = requests.get(
f'{API_BASE}/emails/inbox',
headers={'Authorization': f'Bearer {API_KEY}'},
params={'limit': limit}
)
return response.json()
def process_email(email_id):
"""Recupera detalhe de email específico"""
response = requests.get(
f'{API_BASE}/emails/{email_id}',
headers={'Authorization': f'Bearer {API_KEY}'}
)
return response.json()
def mark_as_read(email_id):
"""Marca email como lido"""
response = requests.patch(
f'{API_BASE}/emails/{email_id}',
headers={'Authorization': f'Bearer {API_KEY}'},
json={'read': True}
)
return response.json()
# Uso
emails = get_inbox_emails()
for email in emails['items']:
print(f"De: {email['from']}, Assunto: {email['subject']}")
detail = process_email(email['id'])
# Processar
mark_as_read(email['id'])
Prós:
- Moderno — JSON estruturado, fácil de integrar
- Sem protocolo IMAP complexo — apenas REST padrão
- Acesso a metadados ricos — pode incluir análise de spam, classificação, etc.
- Escalável — provedores gerenciam infraestrutura
Contras:
- Propriedade — cada provedor tem sua própria API
- Latência de polling — ainda requer verificação periódica (a menos que tenha webhooks também)
- Custo — APIs REST às vezes requerem pagamento por request
- Taxa limitada — chamadas de API são freqüentemente limitadas
Melhor para:
- Quando o provedor oferece uma API bem documentada
- Integração com sistemas modernos
- Quando você quer evitar complexidade IMAP
Comparação
| Fator | IMAP Polling | Webhooks | API REST |
|---|---|---|---|
| Latência | Minutos (polling) / Segundos (IDLE) | Millisegundos | Minutos (polling) |
| Complexidade | Média | Baixa | Baixa |
| Confiabilidade | Alta | Dependente do provedor | Alta |
| Escalabilidade | Limitada | Alta | Média |
| Implementação | IMAP bem conhecido | HTTP simples | HTTP simples |
| Sem dependências | Sim | Não | Não |
| Funciona com qualquer provedor | Sim (maioria) | Não (provedor específico) | Não (provedor específico) |
Recomendação
Use IMAP se:
- Você controla o servidor de email
- Você precisa de confiabilidade acima de latência
- Seu provedor não oferece webhooks
- Você quer evitar dependências externas
Use Webhooks se:
- Seu provedor oferece webhooks confiáveis
- Você precisa de latência baixa
- Você está construindo uma aplicação moderna em tempo real
- Você pode lidar com retry logic se o webhook falhar
Use API REST se:
- Seu provedor oferece uma API bem documentada
- Você prefere abstrações modernas sobre protocolos históricos
- A taxa limitada de API é aceitável para seu volume
- Você quer evitar gerenciar conexões IMAP
Para a maioria das aplicações, uma combinação funciona melhor: webhooks para eventos em tempo real quando disponível, com IMAP polling como fallback para casos em que webhooks falham ou precisam de resync.
Try it free
Get a disposable inbox in seconds
No sign-up required. Just visit an address and it's live. Works with any domain on reusable.email.
Open your inbox →

