Skip to main content

Facilitador para uso da API WhatsApp (ZAPI)

Project description

Whats77

Versão: 1.0.0
Compatibilidade: Retrocompatível com versões 0.1.x
Backend: Whats77 Manager (FastAPI + Redis + Z-API)


📘 Visão Geral

O Whats77 é um facilitador para o envio de mensagens via WhatsApp através da Z-API, agora totalmente integrado ao Whats77 Manager — um orquestrador que cuida de cadência, idempotência, retentativas automáticas e segurança via API Key.

Com esta nova integração, suas automações não precisam mais chamar a Z-API diretamente.
Basta chamar os mesmos métodos:

  • send_text
  • send_image
  • send_audio
  • send_document

e o Manager fará todo o controle de fila e envio.

🆕 Além disso, o Whats77 agora suporta envio estruturado em grupo via:

  • send_group(...) → usa o endpoint /enqueue_group do Manager, garantindo ordem e idempotência por grupo.

🧱 Arquitetura do Manager

whats77_manager/
├── apps/
│   ├── manager_api.py     # FastAPI: /enqueue, /enqueue_group, /status, /health
│   ├── worker.py          # Worker: consome fila e dispara via Z-API
│   ├── rate_limiter.py    # Controle de cadência (Redis)
│   ├── scheduler.py       # Retentativas e backoff exponencial
│   ├── storage.py         # Idempotência, grupos e DLQ
│   ├── models.py          # Schemas (MessageJob, GroupMessageRequest, SendResult)
│   └── zapi_client/
│       ├── whats77.py     # Cliente HTTP direto na Z-API
│       └── senders.py     # Multi-instâncias Z-API
└── .env

O Manager atua como intermediário:

  • ✅ Controla limites e cadência
  • ✅ Evita envios duplicados (idempotência)
  • ✅ Distribui mensagens entre múltiplas instâncias Z-API
  • ✅ Tenta novamente em caso de falha temporária
  • 🔒 Requer API Key (X-API-Key) para autenticação
  • 📦 Garante ordem e isolamento em grupos de mensagens (/enqueue_group)

⚙️ Configuração

Arquivo .env

Crie um arquivo .env na raiz do seu projeto:

MANAGER_URL=http://localhost:8000
MANAGER_API_KEY=meu_token_super_seguro
SENDER_ID=0

🔁 Compatibilidade: Se as variáveis acima não existirem, o código tenta usar: INSTANCE_ID, TOKEN, SECURITY_TOKEN (modo legado).


Configuração Manual

from whats77 import Whats77

# Inicialização manual (sem .env)
whatsapp = Whats77(
    manager_url="http://localhost:8000",
    manager_api_key="meu_token_super_seguro",
    sender_id="0",
)

🚀 Uso Rápido

Inicializar

from whats77 import Whats77

whatsapp = Whats77()  # carrega credenciais do .env

Enviar Texto

whatsapp.send_text(
    phone_number="+5511999999999",
    message="Olá! Esta mensagem foi enviada pelo Whats77 Manager."
)

Enviar Imagem

Aceita URL, data URI ou caminho local (automaticamente convertido para base64):

whatsapp.send_image(
    phone_number="+5511999999999",
    image_path_or_url="/tmp/imagem.jpg",
    caption="Segue imagem de teste",
)

⚙️ Parâmetros:

  • view_once (opcional, compatível; ignorado pelo Manager)
  • is_base64 (opcional; mantido por compatibilidade)

Enviar Documento

Também aceita caminho local ou data URI:

whatsapp.send_document(
    phone_number="+5511999999999",
    file_path="/tmp/relatorio.pdf",
    document_type="pdf",
    caption="Segue o relatório.",
)

Enviar Áudio

from whats77 import Whats77

# converter áudio em base64
base64_audio = Whats77.parse_to_base64("/tmp/audio.mp3")

whatsapp.send_audio(
    phone_number="+5511999999999",
    base64_audio=base64_audio,
)

📦 Envio Estruturado em Grupo (novo)

O Whats77 suporta o envio de múltiplas mensagens em sequência para o mesmo contato (ou grupo) como um pacote lógico, usando o endpoint /enqueue_group do Manager.

Benefícios:

  • Ordem garantida: as mensagens são enviadas na sequência definida (items na ordem)
  • Sem intercalação: outras mensagens não quebram a sequência do grupo
  • Idempotência por grupo: o mesmo group_id não gera reenvios duplicados
  • Mesmas regras de segurança: rate limiting, retentativas e DLQ continuam valendo

Método: send_group(...)

Assinatura:

send_group(
    phone_number_or_group: str,
    items: list[dict],
    group_id: str | None = None,
    priority: str | None = None,
) -> None

Parâmetros

  • phone_number_or_group:

    • Número E.164 ("5511999999999", "+5511999999999")
    • Ou ID de grupo WhatsApp ("120363287726811196-group")
  • items: lista de mensagens a enviar, na ordem desejada. Cada item é um dict com pelo menos:

    Campo Tipo Obrigatório Descrição
    type string "text", "image", "audio" ou "document"
    text string para type="text" Conteúdo da mensagem
    image_path_or_url ou image_url string para type="image" Caminho local, URL ou data URI
    audio_base64 string para type="audio" Áudio em base64
    file_path ou document_path string para type="document" Caminho local, data URI ou identificador
    document_type string opcional ex: "pdf", "xlsx"

Opcional por item:

  • idempotency_key → se não informado, o Whats77 gera automaticamente.
  • image_caption, caption, etc.

Exemplo: texto + 2 imagens + PDF

from whats77 import Whats77

whatsapp = Whats77()

whatsapp.send_group(
    phone_number_or_group="5599999999999",
    group_id="relatorio-mensal-2025-01",
    items=[
        {
            "type": "text",
            "text": "Olá! Segue o relatório mensal de Janeiro/2025.",
        },
        {
            "type": "image",
            "image_path_or_url": "/app/graficos/vendas-jan.png",
            "image_caption": "Gráfico de vendas do mês",
        },
        {
            "type": "image",
            "image_path_or_url": "/app/graficos/crescimento-jan.png",
            "image_caption": "Crescimento comparativo",
        },
        {
            "type": "document",
            "file_path": "/app/docs/relatorio-jan-2025.pdf",
            "document_type": "pdf",
            "caption": "Relatório completo em PDF",
        },
    ],
)

Se você não passar group_id, o Whats77 gera um automaticamente no formato:

group:<destinatario>:<uuid_curto>

🔢 Normalização de Números e IDs de Grupo

from whats77 import Whats77

# Telefone "cru" → E.164 BR
n = Whats77.normalize_phone_number("11999999999")
print(n)  # 5511999999999

print(Whats77.is_valid_whatsapp_number("5511999999999"))
# True

IDs de Grupo do WhatsApp

O adaptador também aceita IDs de grupo no formato:

120363287726811196-group

Comportamento:

  • normalize_phone_number("120363287726811196-group") → mantém exatamente o valor.
  • is_valid_whatsapp_number("120363287726811196-group")True.

Ou seja, você pode usar o mesmo objeto Whats77 para enviar:

  • Para números individuais (send_text, send_group, etc.)
  • Para grupos (send_text, send_group, etc.) passando o ID do grupo.

🔐 Autenticação

Todas as requisições enviadas ao Manager contêm:

X-API-Key: <sua_chave>
Content-Type: application/json

Se a chave for inválida ou ausente:

{"detail": "Invalid or missing API key"}

🧩 Compatibilidade com o Código Antigo

Função / Comportamento Mantida? Observações
send_text() Idêntica
send_image() Aceita caminho local / URL / data URI
send_audio() Idêntica
send_document() Aceita caminho local / data URI
send_group() 🆕 Novo método para envio sequencial em grupo
parse_to_base64() Utilitária igual
normalize_phone_number() / is_valid_whatsapp_number() Agora também aceitam IDs de grupo (*-group)
Parâmetro is_base64 Mantido por compatibilidade
Campos instance_id, token ⚙️ Opcional / legado Usados só se MANAGER_URL não for configurada
Base URL API direta Z-API ❌ Não usada — o Manager cuida dos envios

Você pode substituir seu módulo antigo pelo novo whats77.py sem alterar chamadas existentes. O uso de send_group() é opcional, mas recomendado para fluxos com múltiplas mensagens sequenciais.


🧠 Como Funciona Internamente

  1. Whats77.send_*() monta um payload JSON contendo:

    • idempotency_key (gerada automaticamente)
    • sender_id, to, text/image_url/document_path/audio_base64
    • priority (default por padrão)
  2. Para mensagens individuais, o payload é enviado para:

    POST {MANAGER_URL}/enqueue
    
  3. Para grupos (send_group()), o payload é enviado para:

    POST {MANAGER_URL}/enqueue_group
    
  4. O Manager:

    • Valida X-API-Key

    • Enfileira no Redis (outbox, retry, dlq, etc.)

    • O worker processa e dispara via Z-API respeitando:

      • Rate limiting
      • Retentativas com backoff exponencial
      • Horário de silêncio (quiet hours)

🧾 Resposta de Exemplo do Manager

Mensagens individuais (/enqueue):

{
  "queued": true,
  "queue": "queue:outbox:default",
  "idempotent": false
}

Grupos (/enqueue_group):

{
  "queued": true,
  "queue": "queue:outbox:default",
  "group_id": "relatorio-mensal-2025-01",
  "items_queued": 4,
  "items_skipped": 0,
  "total_items": 4
}

🧰 Dependências

Biblioteca Versão mínima
requests 2.0.0
python-dotenv 0.21.0

Instale com:

pip install requests python-dotenv

🏁 Migração Rápida

  1. Substitua seu arquivo antigo whats77.py pelo novo adaptador.

  2. Adicione no .env as variáveis do Manager:

    MANAGER_URL=http://localhost:8000
    MANAGER_API_KEY=meu_token_super_seguro
    SENDER_ID=0
    
  3. Rode seu código existente — nenhuma alteração nas chamadas antigas é necessária.

  4. Para fluxos com várias mensagens sequenciais (relatórios, campanhas, etc.), comece a usar send_group() para ter ordem garantida e idempotência por grupo.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

whats77-0.1.7.tar.gz (15.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

whats77-0.1.7-py3-none-any.whl (11.7 kB view details)

Uploaded Python 3

File details

Details for the file whats77-0.1.7.tar.gz.

File metadata

  • Download URL: whats77-0.1.7.tar.gz
  • Upload date:
  • Size: 15.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for whats77-0.1.7.tar.gz
Algorithm Hash digest
SHA256 1f89394dc6d9575e67e25411b92c468ea299704ea03157a9da9a06cc84790345
MD5 de6435c8332321ea2650f717aaf52907
BLAKE2b-256 8f31ab8c8d60efeee93a2870181002552f5bedc796cfe2bad92848b8e3098cec

See more details on using hashes here.

File details

Details for the file whats77-0.1.7-py3-none-any.whl.

File metadata

  • Download URL: whats77-0.1.7-py3-none-any.whl
  • Upload date:
  • Size: 11.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for whats77-0.1.7-py3-none-any.whl
Algorithm Hash digest
SHA256 eb9a56f4c79ad28ff209c5fafbd2ba86a62e7ac95bb1f5e59bf27f47a8b67a5d
MD5 92a1b249c9750a17235e37247699bba9
BLAKE2b-256 3a1e0f312163d72f50506b1cbce13991437585f862859a9a5dcf9c01bcfc3f26

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page