| Name | django-whatsapp-api-wrapper JSON |
| Version |
0.9.6
JSON |
| download |
| home_page | None |
| Summary | None |
| upload_time | 2025-11-03 19:48:10 |
| maintainer | None |
| docs_url | None |
| author | Your Name |
| requires_python | <4.0,>=3.11 |
| license | MIT |
| keywords |
|
| VCS |
|
| bugtrack_url |
|
| requirements |
No requirements were recorded.
|
| Travis-CI |
No Travis.
|
| coveralls test coverage |
No coveralls.
|
# django-whatsapp-api-wrapper
> Importante: Esta biblioteca está em desenvolvimento ativo e ainda não possui cobertura de testes automatizados. As APIs podem mudar entre versões menores. Utilize com cautela em produção, valide os fluxos críticos e, se possível, contribua com issues/PRs.
Um wrapper simples para enviar mensagens via WhatsApp Cloud API e expor um endpoint de webhook, pronto para integrar em qualquer projeto Django.
## Instalação
```bash
python -m pip install django-whatsapp-api-wrapper
```
## Configuração (Django)
1) Adicione o app em `INSTALLED_APPS`:
```python
INSTALLED_APPS = [
# ...
"django_whatsapp_api_wrapper",
]
```
2) Inclua as URLs no `urls.py` principal:
```python
from django.urls import path, include
urlpatterns = [
# ...
path("whatsapp-api-wrapper/", include("django_whatsapp_api_wrapper.urls")),
]
```
3) Defina as variáveis de ambiente (ou no seu `.env`):
```bash
WHATSAPP_CLOUD_API_TOKEN=
WHATSAPP_CLOUD_API_PACKAGE_VERSION=0.1.1
WHATSAPP_CLOUD_API_VERSION=v23.0
WHATSAPP_CLOUD_API_PHONE_NUMBER_ID=
WHATSAPP_CLOUD_API_WABA_ID=
WHATSAPP_CLOUD_API_VERIFY_TOKEN=
```
4) Configure a autenticação para as rotas de templates (opcional, mas recomendado):
```python
# settings.py
# Opção 1: Usar Token Authentication do DRF (padrão)
WHATSAPP_API_AUTHENTICATION_CLASSES = [
'rest_framework.authentication.TokenAuthentication',
]
# Opção 2: Usar JWT (se você já tem configurado)
WHATSAPP_API_AUTHENTICATION_CLASSES = [
'rest_framework_simplejwt.authentication.JWTAuthentication',
]
# Opção 3: Usar API Key simples
WHATSAPP_API_AUTHENTICATION_CLASSES = [
'django_whatsapp_api_wrapper.authentication.APIKeyAuthentication',
]
WHATSAPP_API_KEY = "sua_api_key_secreta_aqui"
# Permissões (padrão: IsAuthenticated)
WHATSAPP_API_PERMISSION_CLASSES = [
'rest_framework.permissions.IsAuthenticated',
]
```
**Importante:** Se não configurar a autenticação, as rotas de templates usarão `TokenAuthentication` por padrão. As rotas de mensagens herdam a mesma configuração.
O endpoint de webhook ficará disponível em:
- GET/POST: `/whatsapp-api-wrapper/webhook/`
- Verificação (GET): `/whatsapp-api-wrapper/webhook/?hub.mode=subscribe&hub.verify_token=<TOKEN>&hub.challenge=123`
## Extensibilidade do Webhook
Você pode customizar o processamento do webhook no projeto hospedeiro de duas formas:
- Via setting com handler plugável:
```python
# settings.py
WHATSAPP_WEBHOOK_HANDLER = "meuapp.whatsapp.handle_webhook"
```
```python
# meuapp/whatsapp.py
from django.http import JsonResponse
def handle_webhook(request, payload):
# sua lógica aqui (salvar eventos, acionar tasks, etc)
return JsonResponse({"ok": True})
```
- Via signal `webhook_event_received`:
```python
from django.dispatch import receiver
from django_whatsapp_api_wrapper.signals import webhook_event_received
@receiver(webhook_event_received)
def on_whatsapp_event(sender, payload, request, **kwargs):
# sua lógica aqui
pass
```
## Mensagens
Envio e recebimento de mensagens via Cloud API.
### Envio (Python)
```python
from django_whatsapp_api_wrapper import WhatsApp
from django_whatsapp_api_wrapper.messages import types as WATypes
wp = WhatsApp()
# Texto (construa o objeto e passe o objeto diretamente)
text = WATypes.Text(body="olá do wrapper", preview_url=False)
m_text = wp.build_message(to="551199999999", type="text", data=text)
m_text.send()
# Template
tpl = WATypes.Template(name="opa", language={"code": "pt_BR"}, components=[])
m_tpl = wp.build_message(to="551199999999", type="template", data=tpl)
m_tpl.send()
# Sticker (exemplo com media ID)
stk = WATypes.Sticker(id="MEDIA_ID")
m_stk = wp.build_message(to="551199999999", type="sticker", data=stk)
m_stk.send()
# Imagem por URL
img = WATypes.Image(link="https://exemplo.com/foto.jpg", caption="Legenda")
m_img = wp.build_message(to="551199999999", type="image", data=img)
m_img.send()
```
### Webhook
- Recebe eventos (mensagens/atualizações de status) em `GET/POST /whatsapp-api-wrapper/webhook/`.
- Verificação (GET): `/whatsapp-api-wrapper/webhook/?hub.mode=subscribe&hub.verify_token=<TOKEN>&hub.challenge=123`.
- Personalize via setting `WHATSAPP_WEBHOOK_HANDLER` ou escute o signal `webhook_event_received` (veja seção Extensibilidade do Webhook acima).
---
## Endpoints HTTP de Mensagens (DRF)
Prefixo base: `/whatsapp-api-wrapper/messages/`
**⚠️ Importante:** Todos os endpoints de mensagens requerem autenticação (veja seção Autenticação acima).
1) Enviar mensagem (genérico)
POST `/whatsapp-api-wrapper/messages/send/`
Body (exemplos por tipo):
Texto
```json
{ "to": "551199999999", "type": "text", "text": {"preview_url": false, "body": "Olá!"} }
```
Texto (reply)
```json
{ "to": "551199999999", "type": "text", "context": {"message_id": "wamid.xxx"}, "text": {"body": "Resposta"} }
```
Template
```json
{ "to": "551199999999", "type": "template", "template": {"name": "opa", "language": {"code": "pt_BR"}, "components": []} }
```
Imagem por URL
```json
{ "to": "551199999999", "type": "image", "image": {"link": "https://exemplo.com/foto.jpg", "caption": "Legenda"} }
```
2) Enviar texto
POST `/whatsapp-api-wrapper/messages/text/`
```json
{ "to": "551199999999", "body": "Olá!", "preview_url": false }
```
**Exemplo com curl:**
```bash
curl -X POST \
-H "Authorization: Token seu_token_aqui" \
-H "Content-Type: application/json" \
-d '{"to": "551199999999", "body": "Olá!", "preview_url": false}' \
"$BASE/whatsapp-api-wrapper/messages/text/"
```
3) Responder com texto
POST `/whatsapp-api-wrapper/messages/text/reply/`
```json
{ "to": "551199999999", "reply_to": "wamid.xxx", "body": "Resposta", "preview_url": false }
```
4) Enviar template
POST `/whatsapp-api-wrapper/messages/template/`
```json
{ "to": "551199999999", "name": "opa", "language": {"code": "pt_BR"}, "components": [] }
```
Respostas: mesmas do Graph (inclui `messages[0].id` com prefixo `wamid`).
---
### Mensagens por tipo (Python + HTTP)
Observação: Para todos os tipos abaixo você pode:
- Python: instanciar o objeto em `django_whatsapp_api_wrapper.messages.types` e passar diretamente como `data=<objeto>` no `build_message`.
- HTTP: usar o endpoint genérico `POST /whatsapp-api-wrapper/messages/send/` com `type=<tipo>` e o objeto correspondente no corpo.
- Atalhos existentes: `text/`, `text/reply/`, `template/`.
#### Texto
- Python:
```python
text = WATypes.Text(body="Olá!", preview_url=False)
wp.build_message(to="551199999999", type="text", data=text).send()
```
- HTTP (atalho): `POST /messages/text/`
```json
{ "to": "551199999999", "body": "Olá!", "preview_url": false }
```
- HTTP (genérico): `POST /messages/send/`
```json
{ "to": "551199999999", "type": "text", "text": {"body": "Olá!", "preview_url": false} }
```
#### Texto (reply)
- Python:
```python
text = WATypes.Text(body="Resposta")
wp.build_message(to="551199999999", type="text", data=text).send()
# Para reply via HTTP use context.message_id
```
- HTTP (atalho): `POST /messages/text/reply/`
```json
{ "to": "551199999999", "reply_to": "wamid.xxx", "body": "Resposta", "preview_url": false }
```
- HTTP (genérico): `POST /messages/send/`
```json
{ "to": "551199999999", "type": "text", "context": {"message_id": "wamid.xxx"}, "text": {"body": "Resposta"} }
```
#### Template
- Python:
```python
tpl = WATypes.Template(name="opa", language={"code": "pt_BR"}, components=[])
wp.build_message(to="551199999999", type="template", data=tpl).send()
```
- HTTP (atalho): `POST /messages/template/`
```json
{ "to": "551199999999", "name": "opa", "language": {"code": "pt_BR"}, "components": [] }
```
- HTTP (genérico): `POST /messages/send/`
```json
{ "to": "551199999999", "type": "template", "template": {"name": "opa", "language": {"code": "pt_BR"}, "components": []} }
```
#### Imagem
- Python:
```python
img = WATypes.Image(link="https://exemplo.com/foto.jpg", caption="Legenda")
wp.build_message(to="551199999999", type="image", data=img).send()
```
- HTTP (genérico): `POST /messages/send/`
```json
{ "to": "551199999999", "type": "image", "image": {"link": "https://exemplo.com/foto.jpg", "caption": "Legenda"} }
```
#### Áudio
- Python:
```python
aud = WATypes.Audio(id="MEDIA_ID") # ou link="https://..."
wp.build_message(to="551199999999", type="audio", data=aud).send()
```
- HTTP (genérico): `POST /messages/send/`
```json
{ "to": "551199999999", "type": "audio", "audio": {"id": "MEDIA_ID"} }
```
#### Documento
- Python:
```python
doc = WATypes.Document(link="https://exemplo.com/arquivo.pdf", filename="arquivo.pdf")
wp.build_message(to="551199999999", type="document", data=doc).send()
```
- HTTP (genérico): `POST /messages/send/`
```json
{ "to": "551199999999", "type": "document", "document": {"link": "https://exemplo.com/arquivo.pdf", "filename": "arquivo.pdf"} }
```
#### Vídeo
- Python:
```python
vid = WATypes.Video(id="MEDIA_ID", caption="Demo")
wp.build_message(to="551199999999", type="video", data=vid).send()
```
- HTTP (genérico): `POST /messages/send/`
```json
{ "to": "551199999999", "type": "video", "video": {"id": "MEDIA_ID", "caption": "Demo"} }
```
#### Sticker
- Python:
```python
stk = WATypes.Sticker(id="MEDIA_ID")
wp.build_message(to="551199999999", type="sticker", data=stk).send()
```
- HTTP (genérico): `POST /messages/send/`
```json
{ "to": "551199999999", "type": "sticker", "sticker": {"id": "MEDIA_ID"} }
```
#### Localização
- Python:
```python
loc = WATypes.Location(latitude=-23.56, longitude=-46.63, name="SP", address="Av. Paulista")
wp.build_message(to="551199999999", type="location", data=loc).send()
```
- HTTP (genérico): `POST /messages/send/`
```json
{ "to": "551199999999", "type": "location", "location": {"latitude": -23.56, "longitude": -46.63, "name": "SP", "address": "Av. Paulista"} }
```
#### Contacts
- Python:
```python
contact = WATypes.Contact(name={"formatted_name": "Maria"}, phones=[{"phone": "+551199999999", "type": "CELL"}])
wp.build_message(to="551199999999", type="contacts", data=[contact]).send() # lista de contatos
```
- HTTP (genérico): `POST /messages/send/`
```json
{ "to": "551199999999", "type": "contacts", "contacts": [{ "name": {"formatted_name": "Maria"}, "phones": [{"phone": "+551199999999", "type": "CELL"}] }] }
```
#### Reaction
- Python:
```python
react = WATypes.Reaction(message_id="wamid.xxx", emoji="😀")
wp.build_message(to="551199999999", type="reaction", data=react).send()
```
- HTTP (genérico): `POST /messages/send/`
```json
{ "to": "551199999999", "type": "reaction", "reaction": {"message_id": "wamid.xxx", "emoji": "😀"} }
```
#### Interativo (Reply Buttons)
- Python:
```python
interactive = WATypes.Interactive(
type="button",
header={"type": "text", "text": "Título"},
body={"text": "Mensagem"},
footer={"text": "Rodapé"},
action={"buttons": [{"title": "OK", "id": "ok"}, {"title": "Cancelar", "id": "cancel"}]}
)
wp.build_message(to="551199999999", type="interactive", data=interactive).send()
```
- HTTP (genérico): `POST /messages/send/`
```json
{ "to": "551199999999", "type": "interactive", "interactive": {
"type": "button",
"header": {"type": "text", "text": "Título"},
"body": {"text": "Mensagem"},
"footer": {"text": "Rodapé"},
"action": {"buttons": [
{"type": "reply", "title": "OK", "id": "ok"},
{"type": "reply", "title": "Cancelar", "id": "cancel"}
]}
} }
```
## Autenticação
### Proteção das Rotas de API
Por padrão, todas as rotas de templates (`/templates/`) e mensagens (`/messages/`) são protegidas e requerem autenticação. O webhook permanece público (necessário para o WhatsApp).
### Opções de Autenticação
#### 1. Token Authentication (Padrão)
```python
# settings.py
WHATSAPP_API_AUTHENTICATION_CLASSES = [
'rest_framework.authentication.TokenAuthentication',
]
```
Uso:
```bash
curl -H "Authorization: Token seu_token_aqui" \
"$BASE/whatsapp-api-wrapper/templates/"
```
#### 2. JWT Authentication
```python
# settings.py
WHATSAPP_API_AUTHENTICATION_CLASSES = [
'rest_framework_simplejwt.authentication.JWTAuthentication',
]
```
Uso:
```bash
curl -H "Authorization: Bearer seu_jwt_token" \
"$BASE/whatsapp-api-wrapper/templates/"
```
#### 3. API Key Authentication
```python
# settings.py
WHATSAPP_API_AUTHENTICATION_CLASSES = [
'django_whatsapp_api_wrapper.authentication.APIKeyAuthentication',
]
WHATSAPP_API_KEY = "sua_api_key_secreta"
```
Uso:
```bash
curl -H "X-WhatsApp-API-Key: sua_api_key_secreta" \
"$BASE/whatsapp-api-wrapper/templates/"
```
#### 4. Múltiplas Autenticações
```python
# settings.py
WHATSAPP_API_AUTHENTICATION_CLASSES = [
'rest_framework.authentication.TokenAuthentication',
'django_whatsapp_api_wrapper.authentication.APIKeyAuthentication',
]
```
### Permissões Customizadas
```python
# settings.py
WHATSAPP_API_PERMISSION_CLASSES = [
'rest_framework.permissions.IsAuthenticated',
# ou 'rest_framework.permissions.IsAdminUser',
# ou 'myapp.permissions.CustomPermission',
]
```
## Templates
Endpoints REST (DRF) para gerenciar Message Templates do WhatsApp (proxy para Graph API). Todos os endpoints abaixo partem do prefixo que você incluir no projeto, por exemplo: `.../whatsapp-api-wrapper/`.
**⚠️ Importante:** Todos os endpoints de templates requerem autenticação (veja seção Autenticação acima).
Requisitos de ambiente: `WHATSAPP_CLOUD_API_TOKEN`, `WHATSAPP_CLOUD_API_VERSION`, `WHATSAPP_CLOUD_API_WABA_ID`.
Aqui a documentação OFICIAL:
https://www.postman.com/meta/whatsapp-business-platform/folder/2ksdd2s/whatsapp-cloud-api
### Listar e criar
- GET `GET /templates/?limit=&after=&before=`
- POST `POST /templates/` com payload conforme a Graph API.
Exemplo de criação:
```bash
curl -X POST \
"$BASE/whatsapp-api-wrapper/templates/" \
-H "Content-Type: application/json" \
-d '{
"name": "authentication_code_copy_code_button",
"language": "en_US",
"category": "AUTHENTICATION",
"components": [
{"type": "BODY", "add_security_recommendation": true},
{"type": "FOOTER", "code_expiration_minutes": 10},
{"type": "BUTTONS", "buttons": [{"type": "OTP", "otp_type": "COPY_CODE", "text": "Copy Code"}]}
]
}'
```
### Buscar por ID e editar
- GET `GET /templates/<template_id>/`
- POST `POST /templates/<template_id>/` para editar (mesmo formato do corpo de criação).
### Buscar e excluir por nome
- GET `GET /templates/by-name/?name=<TEMPLATE_NAME>`
- DELETE `DELETE /templates/by-name/?name=<TEMPLATE_NAME>`
### Excluir por ID (hsm_id) e nome
- DELETE `DELETE /templates/delete-by-id/?hsm_id=<HSM_ID>&name=<NAME>`
### Obter namespace
- GET `GET /templates/namespace/`
Notas:
- Os payloads aceitos seguem a documentação oficial de Message Templates da Meta (Graph API). Este wrapper só valida campos básicos e encaminha a requisição.
- As respostas retornadas são as mesmas da Graph API (status code e corpo JSON), para facilitar troubleshooting.
## Notas
- Nome do pacote no PyPI: `django-whatsapp-api-wrapper`
- Nome do módulo/import: `django_whatsapp_api_wrapper`
Raw data
{
"_id": null,
"home_page": null,
"name": "django-whatsapp-api-wrapper",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.11",
"maintainer_email": null,
"keywords": null,
"author": "Your Name",
"author_email": "you@example.com",
"download_url": "https://files.pythonhosted.org/packages/53/ef/215c4738af61941bf6fec80d796f090fb4544850e8c551997712c44cd157/django_whatsapp_api_wrapper-0.9.6.tar.gz",
"platform": null,
"description": "# django-whatsapp-api-wrapper\n\n> Importante: Esta biblioteca est\u00e1 em desenvolvimento ativo e ainda n\u00e3o possui cobertura de testes automatizados. As APIs podem mudar entre vers\u00f5es menores. Utilize com cautela em produ\u00e7\u00e3o, valide os fluxos cr\u00edticos e, se poss\u00edvel, contribua com issues/PRs.\n\nUm wrapper simples para enviar mensagens via WhatsApp Cloud API e expor um endpoint de webhook, pronto para integrar em qualquer projeto Django.\n\n## Instala\u00e7\u00e3o\n\n```bash\npython -m pip install django-whatsapp-api-wrapper\n```\n\n## Configura\u00e7\u00e3o (Django)\n\n1) Adicione o app em `INSTALLED_APPS`:\n\n```python\nINSTALLED_APPS = [\n # ...\n \"django_whatsapp_api_wrapper\",\n]\n```\n\n2) Inclua as URLs no `urls.py` principal:\n\n```python\nfrom django.urls import path, include\n\nurlpatterns = [\n # ...\n path(\"whatsapp-api-wrapper/\", include(\"django_whatsapp_api_wrapper.urls\")),\n]\n```\n\n3) Defina as vari\u00e1veis de ambiente (ou no seu `.env`):\n\n```bash\nWHATSAPP_CLOUD_API_TOKEN=\nWHATSAPP_CLOUD_API_PACKAGE_VERSION=0.1.1\nWHATSAPP_CLOUD_API_VERSION=v23.0\nWHATSAPP_CLOUD_API_PHONE_NUMBER_ID=\nWHATSAPP_CLOUD_API_WABA_ID=\nWHATSAPP_CLOUD_API_VERIFY_TOKEN=\n```\n\n4) Configure a autentica\u00e7\u00e3o para as rotas de templates (opcional, mas recomendado):\n\n```python\n# settings.py\n\n# Op\u00e7\u00e3o 1: Usar Token Authentication do DRF (padr\u00e3o)\nWHATSAPP_API_AUTHENTICATION_CLASSES = [\n 'rest_framework.authentication.TokenAuthentication',\n]\n\n# Op\u00e7\u00e3o 2: Usar JWT (se voc\u00ea j\u00e1 tem configurado)\nWHATSAPP_API_AUTHENTICATION_CLASSES = [\n 'rest_framework_simplejwt.authentication.JWTAuthentication',\n]\n\n# Op\u00e7\u00e3o 3: Usar API Key simples\nWHATSAPP_API_AUTHENTICATION_CLASSES = [\n 'django_whatsapp_api_wrapper.authentication.APIKeyAuthentication',\n]\nWHATSAPP_API_KEY = \"sua_api_key_secreta_aqui\"\n\n# Permiss\u00f5es (padr\u00e3o: IsAuthenticated)\nWHATSAPP_API_PERMISSION_CLASSES = [\n 'rest_framework.permissions.IsAuthenticated',\n]\n```\n\n**Importante:** Se n\u00e3o configurar a autentica\u00e7\u00e3o, as rotas de templates usar\u00e3o `TokenAuthentication` por padr\u00e3o. As rotas de mensagens herdam a mesma configura\u00e7\u00e3o.\n\nO endpoint de webhook ficar\u00e1 dispon\u00edvel em:\n\n- GET/POST: `/whatsapp-api-wrapper/webhook/`\n- Verifica\u00e7\u00e3o (GET): `/whatsapp-api-wrapper/webhook/?hub.mode=subscribe&hub.verify_token=<TOKEN>&hub.challenge=123`\n\n## Extensibilidade do Webhook\n\nVoc\u00ea pode customizar o processamento do webhook no projeto hospedeiro de duas formas:\n\n- Via setting com handler plug\u00e1vel:\n\n```python\n# settings.py\nWHATSAPP_WEBHOOK_HANDLER = \"meuapp.whatsapp.handle_webhook\"\n```\n\n```python\n# meuapp/whatsapp.py\nfrom django.http import JsonResponse\n\ndef handle_webhook(request, payload):\n # sua l\u00f3gica aqui (salvar eventos, acionar tasks, etc)\n return JsonResponse({\"ok\": True})\n```\n\n- Via signal `webhook_event_received`:\n\n```python\nfrom django.dispatch import receiver\nfrom django_whatsapp_api_wrapper.signals import webhook_event_received\n\n@receiver(webhook_event_received)\ndef on_whatsapp_event(sender, payload, request, **kwargs):\n # sua l\u00f3gica aqui\n pass\n```\n\n## Mensagens\n\nEnvio e recebimento de mensagens via Cloud API.\n\n### Envio (Python)\n\n```python\nfrom django_whatsapp_api_wrapper import WhatsApp\nfrom django_whatsapp_api_wrapper.messages import types as WATypes\n\nwp = WhatsApp()\n\n# Texto (construa o objeto e passe o objeto diretamente)\ntext = WATypes.Text(body=\"ol\u00e1 do wrapper\", preview_url=False)\nm_text = wp.build_message(to=\"551199999999\", type=\"text\", data=text)\nm_text.send()\n\n# Template\ntpl = WATypes.Template(name=\"opa\", language={\"code\": \"pt_BR\"}, components=[])\nm_tpl = wp.build_message(to=\"551199999999\", type=\"template\", data=tpl)\nm_tpl.send()\n\n# Sticker (exemplo com media ID)\nstk = WATypes.Sticker(id=\"MEDIA_ID\")\nm_stk = wp.build_message(to=\"551199999999\", type=\"sticker\", data=stk)\nm_stk.send()\n\n# Imagem por URL\nimg = WATypes.Image(link=\"https://exemplo.com/foto.jpg\", caption=\"Legenda\")\nm_img = wp.build_message(to=\"551199999999\", type=\"image\", data=img)\nm_img.send()\n```\n\n### Webhook\n\n- Recebe eventos (mensagens/atualiza\u00e7\u00f5es de status) em `GET/POST /whatsapp-api-wrapper/webhook/`.\n- Verifica\u00e7\u00e3o (GET): `/whatsapp-api-wrapper/webhook/?hub.mode=subscribe&hub.verify_token=<TOKEN>&hub.challenge=123`.\n- Personalize via setting `WHATSAPP_WEBHOOK_HANDLER` ou escute o signal `webhook_event_received` (veja se\u00e7\u00e3o Extensibilidade do Webhook acima).\n\n---\n\n## Endpoints HTTP de Mensagens (DRF)\n\nPrefixo base: `/whatsapp-api-wrapper/messages/`\n\n**\u26a0\ufe0f Importante:** Todos os endpoints de mensagens requerem autentica\u00e7\u00e3o (veja se\u00e7\u00e3o Autentica\u00e7\u00e3o acima).\n\n1) Enviar mensagem (gen\u00e9rico)\n\nPOST `/whatsapp-api-wrapper/messages/send/`\n\nBody (exemplos por tipo):\n\nTexto\n```json\n{ \"to\": \"551199999999\", \"type\": \"text\", \"text\": {\"preview_url\": false, \"body\": \"Ol\u00e1!\"} }\n```\n\nTexto (reply)\n```json\n{ \"to\": \"551199999999\", \"type\": \"text\", \"context\": {\"message_id\": \"wamid.xxx\"}, \"text\": {\"body\": \"Resposta\"} }\n```\n\nTemplate\n```json\n{ \"to\": \"551199999999\", \"type\": \"template\", \"template\": {\"name\": \"opa\", \"language\": {\"code\": \"pt_BR\"}, \"components\": []} }\n```\n\nImagem por URL\n```json\n{ \"to\": \"551199999999\", \"type\": \"image\", \"image\": {\"link\": \"https://exemplo.com/foto.jpg\", \"caption\": \"Legenda\"} }\n```\n\n2) Enviar texto\n\nPOST `/whatsapp-api-wrapper/messages/text/`\n```json\n{ \"to\": \"551199999999\", \"body\": \"Ol\u00e1!\", \"preview_url\": false }\n```\n\n**Exemplo com curl:**\n```bash\ncurl -X POST \\\n -H \"Authorization: Token seu_token_aqui\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"to\": \"551199999999\", \"body\": \"Ol\u00e1!\", \"preview_url\": false}' \\\n \"$BASE/whatsapp-api-wrapper/messages/text/\"\n```\n\n3) Responder com texto\n\nPOST `/whatsapp-api-wrapper/messages/text/reply/`\n```json\n{ \"to\": \"551199999999\", \"reply_to\": \"wamid.xxx\", \"body\": \"Resposta\", \"preview_url\": false }\n```\n\n4) Enviar template\n\nPOST `/whatsapp-api-wrapper/messages/template/`\n```json\n{ \"to\": \"551199999999\", \"name\": \"opa\", \"language\": {\"code\": \"pt_BR\"}, \"components\": [] }\n```\n\nRespostas: mesmas do Graph (inclui `messages[0].id` com prefixo `wamid`).\n\n---\n\n### Mensagens por tipo (Python + HTTP)\n\nObserva\u00e7\u00e3o: Para todos os tipos abaixo voc\u00ea pode:\n- Python: instanciar o objeto em `django_whatsapp_api_wrapper.messages.types` e passar diretamente como `data=<objeto>` no `build_message`.\n- HTTP: usar o endpoint gen\u00e9rico `POST /whatsapp-api-wrapper/messages/send/` com `type=<tipo>` e o objeto correspondente no corpo.\n- Atalhos existentes: `text/`, `text/reply/`, `template/`.\n\n#### Texto\n- Python:\n```python\ntext = WATypes.Text(body=\"Ol\u00e1!\", preview_url=False)\nwp.build_message(to=\"551199999999\", type=\"text\", data=text).send()\n```\n- HTTP (atalho): `POST /messages/text/`\n```json\n{ \"to\": \"551199999999\", \"body\": \"Ol\u00e1!\", \"preview_url\": false }\n```\n- HTTP (gen\u00e9rico): `POST /messages/send/`\n```json\n{ \"to\": \"551199999999\", \"type\": \"text\", \"text\": {\"body\": \"Ol\u00e1!\", \"preview_url\": false} }\n```\n\n#### Texto (reply)\n- Python:\n```python\ntext = WATypes.Text(body=\"Resposta\")\nwp.build_message(to=\"551199999999\", type=\"text\", data=text).send()\n# Para reply via HTTP use context.message_id\n```\n- HTTP (atalho): `POST /messages/text/reply/`\n```json\n{ \"to\": \"551199999999\", \"reply_to\": \"wamid.xxx\", \"body\": \"Resposta\", \"preview_url\": false }\n```\n- HTTP (gen\u00e9rico): `POST /messages/send/`\n```json\n{ \"to\": \"551199999999\", \"type\": \"text\", \"context\": {\"message_id\": \"wamid.xxx\"}, \"text\": {\"body\": \"Resposta\"} }\n```\n\n#### Template\n- Python:\n```python\ntpl = WATypes.Template(name=\"opa\", language={\"code\": \"pt_BR\"}, components=[])\nwp.build_message(to=\"551199999999\", type=\"template\", data=tpl).send()\n```\n- HTTP (atalho): `POST /messages/template/`\n```json\n{ \"to\": \"551199999999\", \"name\": \"opa\", \"language\": {\"code\": \"pt_BR\"}, \"components\": [] }\n```\n- HTTP (gen\u00e9rico): `POST /messages/send/`\n```json\n{ \"to\": \"551199999999\", \"type\": \"template\", \"template\": {\"name\": \"opa\", \"language\": {\"code\": \"pt_BR\"}, \"components\": []} }\n```\n\n#### Imagem\n- Python:\n```python\nimg = WATypes.Image(link=\"https://exemplo.com/foto.jpg\", caption=\"Legenda\")\nwp.build_message(to=\"551199999999\", type=\"image\", data=img).send()\n```\n- HTTP (gen\u00e9rico): `POST /messages/send/`\n```json\n{ \"to\": \"551199999999\", \"type\": \"image\", \"image\": {\"link\": \"https://exemplo.com/foto.jpg\", \"caption\": \"Legenda\"} }\n```\n\n#### \u00c1udio\n- Python:\n```python\naud = WATypes.Audio(id=\"MEDIA_ID\") # ou link=\"https://...\"\nwp.build_message(to=\"551199999999\", type=\"audio\", data=aud).send()\n```\n- HTTP (gen\u00e9rico): `POST /messages/send/`\n```json\n{ \"to\": \"551199999999\", \"type\": \"audio\", \"audio\": {\"id\": \"MEDIA_ID\"} }\n```\n\n#### Documento\n- Python:\n```python\ndoc = WATypes.Document(link=\"https://exemplo.com/arquivo.pdf\", filename=\"arquivo.pdf\")\nwp.build_message(to=\"551199999999\", type=\"document\", data=doc).send()\n```\n- HTTP (gen\u00e9rico): `POST /messages/send/`\n```json\n{ \"to\": \"551199999999\", \"type\": \"document\", \"document\": {\"link\": \"https://exemplo.com/arquivo.pdf\", \"filename\": \"arquivo.pdf\"} }\n```\n\n#### V\u00eddeo\n- Python:\n```python\nvid = WATypes.Video(id=\"MEDIA_ID\", caption=\"Demo\")\nwp.build_message(to=\"551199999999\", type=\"video\", data=vid).send()\n```\n- HTTP (gen\u00e9rico): `POST /messages/send/`\n```json\n{ \"to\": \"551199999999\", \"type\": \"video\", \"video\": {\"id\": \"MEDIA_ID\", \"caption\": \"Demo\"} }\n```\n\n#### Sticker\n- Python:\n```python\nstk = WATypes.Sticker(id=\"MEDIA_ID\")\nwp.build_message(to=\"551199999999\", type=\"sticker\", data=stk).send()\n```\n- HTTP (gen\u00e9rico): `POST /messages/send/`\n```json\n{ \"to\": \"551199999999\", \"type\": \"sticker\", \"sticker\": {\"id\": \"MEDIA_ID\"} }\n```\n\n#### Localiza\u00e7\u00e3o\n- Python:\n```python\nloc = WATypes.Location(latitude=-23.56, longitude=-46.63, name=\"SP\", address=\"Av. Paulista\")\nwp.build_message(to=\"551199999999\", type=\"location\", data=loc).send()\n```\n- HTTP (gen\u00e9rico): `POST /messages/send/`\n```json\n{ \"to\": \"551199999999\", \"type\": \"location\", \"location\": {\"latitude\": -23.56, \"longitude\": -46.63, \"name\": \"SP\", \"address\": \"Av. Paulista\"} }\n```\n\n#### Contacts\n- Python:\n```python\ncontact = WATypes.Contact(name={\"formatted_name\": \"Maria\"}, phones=[{\"phone\": \"+551199999999\", \"type\": \"CELL\"}])\nwp.build_message(to=\"551199999999\", type=\"contacts\", data=[contact]).send() # lista de contatos\n```\n- HTTP (gen\u00e9rico): `POST /messages/send/`\n```json\n{ \"to\": \"551199999999\", \"type\": \"contacts\", \"contacts\": [{ \"name\": {\"formatted_name\": \"Maria\"}, \"phones\": [{\"phone\": \"+551199999999\", \"type\": \"CELL\"}] }] }\n```\n\n#### Reaction\n- Python:\n```python\nreact = WATypes.Reaction(message_id=\"wamid.xxx\", emoji=\"\ud83d\ude00\")\nwp.build_message(to=\"551199999999\", type=\"reaction\", data=react).send()\n```\n- HTTP (gen\u00e9rico): `POST /messages/send/`\n```json\n{ \"to\": \"551199999999\", \"type\": \"reaction\", \"reaction\": {\"message_id\": \"wamid.xxx\", \"emoji\": \"\ud83d\ude00\"} }\n```\n\n#### Interativo (Reply Buttons)\n- Python:\n```python\ninteractive = WATypes.Interactive(\n type=\"button\",\n header={\"type\": \"text\", \"text\": \"T\u00edtulo\"},\n body={\"text\": \"Mensagem\"},\n footer={\"text\": \"Rodap\u00e9\"},\n action={\"buttons\": [{\"title\": \"OK\", \"id\": \"ok\"}, {\"title\": \"Cancelar\", \"id\": \"cancel\"}]}\n)\nwp.build_message(to=\"551199999999\", type=\"interactive\", data=interactive).send()\n```\n- HTTP (gen\u00e9rico): `POST /messages/send/`\n```json\n{ \"to\": \"551199999999\", \"type\": \"interactive\", \"interactive\": {\n \"type\": \"button\",\n \"header\": {\"type\": \"text\", \"text\": \"T\u00edtulo\"},\n \"body\": {\"text\": \"Mensagem\"},\n \"footer\": {\"text\": \"Rodap\u00e9\"},\n \"action\": {\"buttons\": [\n {\"type\": \"reply\", \"title\": \"OK\", \"id\": \"ok\"},\n {\"type\": \"reply\", \"title\": \"Cancelar\", \"id\": \"cancel\"}\n ]}\n} }\n```\n\n## Autentica\u00e7\u00e3o\n\n### Prote\u00e7\u00e3o das Rotas de API\n\nPor padr\u00e3o, todas as rotas de templates (`/templates/`) e mensagens (`/messages/`) s\u00e3o protegidas e requerem autentica\u00e7\u00e3o. O webhook permanece p\u00fablico (necess\u00e1rio para o WhatsApp).\n\n### Op\u00e7\u00f5es de Autentica\u00e7\u00e3o\n\n#### 1. Token Authentication (Padr\u00e3o)\n```python\n# settings.py\nWHATSAPP_API_AUTHENTICATION_CLASSES = [\n 'rest_framework.authentication.TokenAuthentication',\n]\n```\n\nUso:\n```bash\ncurl -H \"Authorization: Token seu_token_aqui\" \\\n \"$BASE/whatsapp-api-wrapper/templates/\"\n```\n\n#### 2. JWT Authentication\n```python\n# settings.py\nWHATSAPP_API_AUTHENTICATION_CLASSES = [\n 'rest_framework_simplejwt.authentication.JWTAuthentication',\n]\n```\n\nUso:\n```bash\ncurl -H \"Authorization: Bearer seu_jwt_token\" \\\n \"$BASE/whatsapp-api-wrapper/templates/\"\n```\n\n#### 3. API Key Authentication\n```python\n# settings.py\nWHATSAPP_API_AUTHENTICATION_CLASSES = [\n 'django_whatsapp_api_wrapper.authentication.APIKeyAuthentication',\n]\nWHATSAPP_API_KEY = \"sua_api_key_secreta\"\n```\n\nUso:\n```bash\ncurl -H \"X-WhatsApp-API-Key: sua_api_key_secreta\" \\\n \"$BASE/whatsapp-api-wrapper/templates/\"\n```\n\n#### 4. M\u00faltiplas Autentica\u00e7\u00f5es\n```python\n# settings.py\nWHATSAPP_API_AUTHENTICATION_CLASSES = [\n 'rest_framework.authentication.TokenAuthentication',\n 'django_whatsapp_api_wrapper.authentication.APIKeyAuthentication',\n]\n```\n\n### Permiss\u00f5es Customizadas\n```python\n# settings.py\nWHATSAPP_API_PERMISSION_CLASSES = [\n 'rest_framework.permissions.IsAuthenticated',\n # ou 'rest_framework.permissions.IsAdminUser',\n # ou 'myapp.permissions.CustomPermission',\n]\n```\n\n## Templates\n\nEndpoints REST (DRF) para gerenciar Message Templates do WhatsApp (proxy para Graph API). Todos os endpoints abaixo partem do prefixo que voc\u00ea incluir no projeto, por exemplo: `.../whatsapp-api-wrapper/`.\n\n**\u26a0\ufe0f Importante:** Todos os endpoints de templates requerem autentica\u00e7\u00e3o (veja se\u00e7\u00e3o Autentica\u00e7\u00e3o acima).\n\nRequisitos de ambiente: `WHATSAPP_CLOUD_API_TOKEN`, `WHATSAPP_CLOUD_API_VERSION`, `WHATSAPP_CLOUD_API_WABA_ID`.\n\nAqui a documenta\u00e7\u00e3o OFICIAL: \n\nhttps://www.postman.com/meta/whatsapp-business-platform/folder/2ksdd2s/whatsapp-cloud-api\n\n### Listar e criar\n\n- GET `GET /templates/?limit=&after=&before=`\n- POST `POST /templates/` com payload conforme a Graph API.\n\nExemplo de cria\u00e7\u00e3o:\n\n```bash\ncurl -X POST \\\n \"$BASE/whatsapp-api-wrapper/templates/\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"authentication_code_copy_code_button\",\n \"language\": \"en_US\",\n \"category\": \"AUTHENTICATION\",\n \"components\": [\n {\"type\": \"BODY\", \"add_security_recommendation\": true},\n {\"type\": \"FOOTER\", \"code_expiration_minutes\": 10},\n {\"type\": \"BUTTONS\", \"buttons\": [{\"type\": \"OTP\", \"otp_type\": \"COPY_CODE\", \"text\": \"Copy Code\"}]}\n ]\n }'\n```\n\n### Buscar por ID e editar\n\n- GET `GET /templates/<template_id>/`\n- POST `POST /templates/<template_id>/` para editar (mesmo formato do corpo de cria\u00e7\u00e3o).\n\n### Buscar e excluir por nome\n\n- GET `GET /templates/by-name/?name=<TEMPLATE_NAME>`\n- DELETE `DELETE /templates/by-name/?name=<TEMPLATE_NAME>`\n\n### Excluir por ID (hsm_id) e nome\n\n- DELETE `DELETE /templates/delete-by-id/?hsm_id=<HSM_ID>&name=<NAME>`\n\n### Obter namespace\n\n- GET `GET /templates/namespace/`\n\nNotas:\n- Os payloads aceitos seguem a documenta\u00e7\u00e3o oficial de Message Templates da Meta (Graph API). Este wrapper s\u00f3 valida campos b\u00e1sicos e encaminha a requisi\u00e7\u00e3o.\n- As respostas retornadas s\u00e3o as mesmas da Graph API (status code e corpo JSON), para facilitar troubleshooting.\n\n## Notas\n\n- Nome do pacote no PyPI: `django-whatsapp-api-wrapper`\n- Nome do m\u00f3dulo/import: `django_whatsapp_api_wrapper`\n",
"bugtrack_url": null,
"license": "MIT",
"summary": null,
"version": "0.9.6",
"project_urls": null,
"split_keywords": [],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "136e4c86579a6619de64b96f57ee8ecbed9883066b433074880cae591cfc81d8",
"md5": "9e3e73c6c72372c4bc4e91d97ad2b7a9",
"sha256": "e57532cf1367e474c04c763200654b34a5bb9bad032f81f889c75174bc1c90e1"
},
"downloads": -1,
"filename": "django_whatsapp_api_wrapper-0.9.6-py3-none-any.whl",
"has_sig": false,
"md5_digest": "9e3e73c6c72372c4bc4e91d97ad2b7a9",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.11",
"size": 61196,
"upload_time": "2025-11-03T19:48:09",
"upload_time_iso_8601": "2025-11-03T19:48:09.144142Z",
"url": "https://files.pythonhosted.org/packages/13/6e/4c86579a6619de64b96f57ee8ecbed9883066b433074880cae591cfc81d8/django_whatsapp_api_wrapper-0.9.6-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "53ef215c4738af61941bf6fec80d796f090fb4544850e8c551997712c44cd157",
"md5": "b499e642bd9babdc3995f484b672ab2c",
"sha256": "8163cf0d9b60824cd45577e29106a792143a5515f96961794307f57efba00303"
},
"downloads": -1,
"filename": "django_whatsapp_api_wrapper-0.9.6.tar.gz",
"has_sig": false,
"md5_digest": "b499e642bd9babdc3995f484b672ab2c",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.11",
"size": 112599,
"upload_time": "2025-11-03T19:48:10",
"upload_time_iso_8601": "2025-11-03T19:48:10.270952Z",
"url": "https://files.pythonhosted.org/packages/53/ef/215c4738af61941bf6fec80d796f090fb4544850e8c551997712c44cd157/django_whatsapp_api_wrapper-0.9.6.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-11-03 19:48:10",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "django-whatsapp-api-wrapper"
}