> ## Documentation Index
> Fetch the complete documentation index at: https://docs.jelou.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# WhatsApp: modelos e campanhas

> Administre modelos HSM aprovados pela Meta e envie campanhas em massa de WhatsApp para listas de destinatários CSV pela CLI da Jelou.

A CLI cobre a superfície de saída do WhatsApp: **modelos** (mensagens HSM
reutilizáveis que a Meta precisa aprovar para envio fora da janela de 24 horas)
e **campanhas** (envios em massa para listas de destinatários usando um modelo
aprovado).

<Note>
  O `--bot-id` que estes comandos pedem é o `referenceId` que aparece em
  `jelou channels list --type Whatsapp`.
</Note>

## `jelou channels testers`

Antes de conectar um número real do WhatsApp Business, você pode usar o
sandbox compartilhado da Jelou para testar o envio e o recebimento de
mensagens com o seu próprio telefone.

| Subcomando                                             | Descrição                                         |
| ------------------------------------------------------ | ------------------------------------------------- |
| `testers list <channel-id>`                            | Lista os números de telefone liberados no sandbox |
| `testers add <channel-id> --phone <telefone>`          | Libera um número de telefone no sandbox           |
| `testers remove <channel-id> --phone <telefone> --yes` | Remove um número de telefone do sandbox           |

```bash theme={null}
jelou channels testers list channel-id-xyz
jelou channels testers add channel-id-xyz --phone +14155550100
jelou channels testers remove channel-id-xyz --phone +14155550100 --yes
```

<Note>
  `<channel-id>` é o id do canal, não o `--bot-id`/`referenceId` usado por
  `template` e `campaign`. Só tem efeito em canais sandbox: depois que você
  conecta um número real do WhatsApp Business, a lista de testers deixa de ser
  necessária. O telefone deve estar no formato E.164 (`+14155550100`).
</Note>

## `jelou template`

| Subcomando                        | Descrição                                          |
| --------------------------------- | -------------------------------------------------- |
| `list --bot-id <id>`              | Lista modelos (filtros: estado, tipo, categoria)   |
| `get <id> --bot-id <id>`          | Mostra um modelo com seu corpo e parâmetros        |
| `validate <arquivo>`              | Valida um payload de modelo localmente             |
| `create --bot-id <id> …`          | Cria (e opcionalmente envia para a Meta) um modelo |
| `update <id> --bot-id <id> …`     | Atualiza um modelo APPROVED ou REJECTED            |
| `delete <id> --bot-id <id> --yes` | Exclui um modelo                                   |
| `upload-media <arquivo>`          | Sobe uma imagem/vídeo para o CDN e retorna sua URL |

```bash theme={null}
jelou template list --bot-id bot-abc123 --status APPROVED --category UTILITY --type text
jelou template create --bot-id bot-abc123 \
  --display-name "Confirmación de orden" \
  --element-name order_confirmation \
  --template "Hola {{1}}, tu orden {{2}} está lista." \
  --language es --category UTILITY --type text
jelou template create --bot-id bot-abc123 ... --draft   # salvar sem enviar para a Meta
jelou template create --bot-id bot-abc123 --from-file ./template.json   # payload completo em JSON
jelou template upload-media ./header.png
```

Categorias: `UTILITY`, `MARKETING`, `AUTHENTICATION`. Estados: `APPROVED`,
`PENDING`, `REJECTED`. Tipos de conteúdo (`--type`): `text` (padrão), `IMAGE`,
`VIDEO`, `DOCUMENT`, `CAROUSEL`. Use `--header` para adicionar um cabeçalho de
texto e `{{1}}`, `{{2}}`, … como marcadores no corpo. Assim como em
`campaign create`, `--from-file` aceita o caminho de um JSON com o payload
completo do modelo em vez de passar cada flag separadamente.

<Warning>
  Só é possível editar modelos `APPROVED` ou `REJECTED`; os `PENDING` estão
  bloqueados. Os modelos sem `--draft` vão para a Meta imediatamente e a cota de
  aprovação é finita por empresa (as rejeições contam). A Meta antepõe um prefixo
  aleatório de 4 caracteres ao `elementName` — use o `elementName` retornado
  (com prefixo) nas campanhas.
</Warning>

### Atualizar um modelo

`jelou template update` só aceita flags discretas: `--display-name`,
`--template`, `--header`, `--footer`, `--media-url` e `--draft`. A CLI busca
o estado atual do modelo, aplica somente os overrides indicados e faz um
PATCH do payload completo — você não precisa repetir os campos que não
mudam.

```bash theme={null}
jelou template update template-id-xyz --bot-id bot-abc123 \
  --template "Olá {{1}}, seu pedido {{2}} já foi enviado." \
  --footer "Equipe de suporte"
jelou template update template-id-xyz --bot-id bot-abc123 \
  --footer "Novo footer" --draft   # salva sem reenviar para a Meta
```

### Header com media

```bash theme={null}
URL=$(jelou template upload-media ./banner.png --json | jq -r '.url')
jelou template create --bot-id bot-abc123 \
  --display-name "Oferta semanal" --element-name weekly_offer \
  --template "Esta semana: {{1}} con {{2}}% de descuento" \
  --media-url "$URL" --category MARKETING
```

## `jelou campaign`

| Subcomando                     | Descrição                                                                                     |
| ------------------------------ | --------------------------------------------------------------------------------------------- |
| `list`                         | Lista campanhas (filtros: bot, estado, tipo, nome do modelo, elementName, intervalo de datas) |
| `get <id>`                     | Detalhe de uma campanha (destinatários e agenda)                                              |
| `create --from-file <arquivo>` | Cria uma campanha em massa a partir de um JSON + CSV local                                    |
| `cancel <id>`                  | Para uma campanha SCHEDULED ou IN\_PROGRESS                                                   |
| `reschedule <id> --at <iso>`   | Reagenda ou revive uma campanha cancelada                                                     |

```bash theme={null}
jelou campaign list --bot-id bot-abc123 --status SCHEDULED --json
jelou campaign list --type text --name "Confirmação de pedido" --element-name xy12_order_confirmation
jelou campaign create --from-file ./campaign.json --json
jelou campaign cancel campaign-id-xyz
jelou campaign reschedule campaign-id-xyz --at "2026-06-20T15:30:00-05:00"
jelou campaign reschedule campaign-id-xyz --at "2026-07-01T09:00:00-05:00" --revive
```

`--type` filtra por tipo de campanha (`text`, `carousel`, …), `--name` pelo
nome de exibição do modelo, e `--element-name` pelo seu `elementName`.

Estados: `SCHEDULED` → `IN_PROGRESS` → `COMPLETED`; `CANCELLED` é terminal
exceto se você usar `--revive`.

<Warning>
  `--start-at` e `--end-at` filtram pela data de **criação** da campanha
  (`createdAt`), não pela data programada de envio (`scheduledAt`). Se você
  está procurando "campanhas agendadas para a próxima semana", esses filtros
  não servem para isso: eles retornam as campanhas criadas nesse intervalo,
  independentemente de quando estejam programadas para enviar.
</Warning>

### Estrutura do arquivo de campanha

```json campaign.json theme={null}
{
  "campaignName": "Blast de temporada",
  "botId": "bot-abc123",
  "elementName": "xy12_holiday_offer",
  "language": "es",
  "csvPath": "./destinatarios.csv",
  "date": "2026-06-15T10:00:00-05:00",
  "params": [
    { "param": 1, "column": "nombre" },
    { "param": 2, "column": "descuento" }
  ]
}
```

```csv destinatarios.csv theme={null}
phone_number,nombre,descuento
+14155550100,Alicia,20
+14155550101,Bruno,30
```

O CSV inclui uma coluna de telefones no formato E.164. O mapeamento de parâmetros
é explícito: `{ "param": <n>, "column": "<coluna>" }`. Use o campo `date`
para agendar (omita-o para envio imediato).

<Warning>
  Uma campanha consome créditos reais ao ser despachada. Revise a contagem de
  destinatários e o custo antes de criá-la. Um mapeamento de parâmetros errado
  envia o texto literal do marcador (`Hola {{1}}`) para milhares de pessoas —
  verifique antes. Cancelar uma campanha `IN_PROGRESS` produz um envio parcial.
</Warning>
