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_textsend_imagesend_audiosend_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_groupdo 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 (
itemsna ordem) - ✅ Sem intercalação: outras mensagens não quebram a sequência do grupo
- ✅ Idempotência por grupo: o mesmo
group_idnã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")
- Número E.164 (
-
items: lista de mensagens a enviar, na ordem desejada. Cada item é umdictcom pelo menos:Campo Tipo Obrigatório Descrição typestring ✅ "text","image","audio"ou"document"textstring para type="text"Conteúdo da mensagem image_path_or_urlouimage_urlstring para type="image"Caminho local, URL ou data URI audio_base64string para type="audio"Áudio em base64 file_pathoudocument_pathstring para type="document"Caminho local, data URI ou identificador document_typestring opcional ex: "pdf","xlsx"
Opcional por item:
idempotency_key→ se não informado, oWhats77gera 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.pysem alterar chamadas existentes. O uso desend_group()é opcional, mas recomendado para fluxos com múltiplas mensagens sequenciais.
🧠 Como Funciona Internamente
-
Whats77.send_*()monta umpayload JSONcontendo:idempotency_key(gerada automaticamente)sender_id,to,text/image_url/document_path/audio_base64priority(defaultpor padrão)
-
Para mensagens individuais, o payload é enviado para:
POST {MANAGER_URL}/enqueue -
Para grupos (
send_group()), o payload é enviado para:POST {MANAGER_URL}/enqueue_group -
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
-
Substitua seu arquivo antigo
whats77.pypelo novo adaptador. -
Adicione no
.envas variáveis do Manager:MANAGER_URL=http://localhost:8000 MANAGER_API_KEY=meu_token_super_seguro SENDER_ID=0
-
Rode seu código existente — nenhuma alteração nas chamadas antigas é necessária.
-
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1f89394dc6d9575e67e25411b92c468ea299704ea03157a9da9a06cc84790345
|
|
| MD5 |
de6435c8332321ea2650f717aaf52907
|
|
| BLAKE2b-256 |
8f31ab8c8d60efeee93a2870181002552f5bedc796cfe2bad92848b8e3098cec
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb9a56f4c79ad28ff209c5fafbd2ba86a62e7ac95bb1f5e59bf27f47a8b67a5d
|
|
| MD5 |
92a1b249c9750a17235e37247699bba9
|
|
| BLAKE2b-256 |
3a1e0f312163d72f50506b1cbce13991437585f862859a9a5dcf9c01bcfc3f26
|