developerIMAPemail-apiwebhooks

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.

October 22, 2025·7 min de leitura·Reusable.Email
Como Receber Email Programaticamente: IMAP, Webhooks, e APIs de Email

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:

  1. Sua aplicação conecta ao servidor IMAP em intervalos regulares (ex., a cada 30 segundos)
  2. Recupera novas mensagens desde a última verificação
  3. Processa o conteúdo (extrai anexos, analisa corpo, valida remetente)
  4. Marca como processado (deleta, move para pasta, marca como lido)
  5. 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:

  1. Você registra uma URL webhook na configuração do seu provedor de email
  2. Quando um email chega, o provedor envia um POST HTTP para sua URL
  3. Sua aplicação recebe a carga útil JSON contendo o email
  4. 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:

  1. Você autentica com a API usando uma chave de API
  2. Você faz chamadas REST como GET /api/emails/inbox
  3. A API retorna emails como JSON
  4. 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 →