django-whatsapp-api-wrapper


Namedjango-whatsapp-api-wrapper JSON
Version 0.9.6 PyPI version JSON
download
home_pageNone
SummaryNone
upload_time2025-11-03 19:48:10
maintainerNone
docs_urlNone
authorYour Name
requires_python<4.0,>=3.11
licenseMIT
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"
}
        
Elapsed time: 4.78304s