@lionchat/mcp-server 1.15.0 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/instructions.md +12 -1
- package/dist/docs/prompts/create_flow_brainstorm.json +1 -1
- package/dist/docs/prompts/customer_health.json +1 -1
- package/dist/docs/prompts/productivity_report.json +1 -1
- package/dist/docs/prompts/quality_audit.json +1 -1
- package/dist/docs/prompts/stuck_leads.json +1 -1
- package/dist/docs/prompts/team_load_balance.json +1 -1
- package/dist/docs/prompts/weekly_recap.json +1 -1
- package/dist/docs/prompts/whatsapp_template_usage.json +1 -1
- package/dist/docs/resources/api-conventions.md +20 -1
- package/dist/docs/resources/best-practices.md +9 -3
- package/dist/docs/resources/conversation-flows.md +12 -0
- package/dist/docs/resources/data-model.md +87 -20
- package/dist/docs/resources/filtros-e-relatorios.md +7 -2
- package/dist/docs/resources/flowbuilder-design-guide.md +179 -32
- package/dist/docs/resources/flowbuilder-patterns.md +20 -5
- package/dist/docs/resources/formularios-publicos.md +110 -28
- package/dist/docs/resources/glossary.md +26 -1
- package/dist/docs/resources/kanban-deep-dive.md +19 -1
- package/dist/docs/resources/reports-guide.md +108 -10
- package/dist/docs/resources/troubleshooting.md +110 -1
- package/dist/tools.js +179 -38
- package/dist/tools.js.map +1 -1
- package/endpoints.json +3343 -42
- package/package.json +1 -1
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Tudo sobre os Formulários Públicos do LionChat (captação estilo Typeform/Typebot): link público,
|
|
4
4
|
caixa de WhatsApp vinculada, desenho dos blocos, publicação, respostas, funil, simulador e
|
|
5
|
-
integração com fluxos. Atualizado em
|
|
5
|
+
integração com fluxos. Atualizado em 21/08/2026 (v4.10.228 + commits de 21/08 na elvislion: título
|
|
6
|
+
público, aba Preenchimentos — entram com o próximo deploy do app depois de 21/08/2026).
|
|
6
7
|
|
|
7
8
|
## O que é
|
|
8
9
|
|
|
@@ -51,16 +52,21 @@ caixa de WhatsApp vinculada e (opcionalmente) dispara um fluxo do FlowBuilder no
|
|
|
51
52
|
| `lionchat_lead_forms_responses_show` | `GET /lead_forms/:id/responses/:rid` | Detalhe de uma resposta, com o que a pessoa respondeu |
|
|
52
53
|
| `lionchat_lead_forms_test_run` | `POST /lead_forms/:lead_form_id/test_runs` | Simulador: roda o RASCUNHO no motor real, sem deixar rastro. Qualquer agente da conta |
|
|
53
54
|
| `lionchat_lead_forms_check_embed` | `POST /lead_forms/check_embed` | Confere se um site aceita ser exibido em iframe (bloco Página externa). Admin-only |
|
|
55
|
+
| `lionchat_contacts_form_entries_list` | `GET /contacts/:contact_id/form_entries` | Tudo que UMA PESSOA preencheu, das 4 origens (nosso formulário, Meta, Webhook Universal, Fluxo). Qualquer agente |
|
|
56
|
+
| `lionchat_contacts_form_entries_show` | `GET /contacts/:contact_id/form_entries/:source/:id` | Detalhe de um preenchimento a partir do contato. Qualquer agente |
|
|
54
57
|
|
|
55
|
-
**Imagens não
|
|
56
|
-
máximo 5 MB,
|
|
57
|
-
|
|
58
|
+
**Imagens não sobem pelo conector.** A rota `POST /lead_forms/:id/media` (admin, multipart `file`,
|
|
59
|
+
só `image/*`, máximo 5 MB, devolve `{blob_id, url}`) existe, mas upload de arquivo não passa pelo MCP
|
|
60
|
+
— chamada pelo conector ela volta 422 `invalid_file_type`. Suba a imagem no editor do painel e
|
|
61
|
+
referencie o `blob_id` (o `show` traz `media_urls` com todos os ids do acervo: imagem de bloco,
|
|
62
|
+
imagem de opção e a foto do chat). **Imagem subida e não referenciada em até 1 hora é apagada** na
|
|
63
|
+
próxima varredura (todo `update`/`publish` roda a varredura).
|
|
58
64
|
|
|
59
65
|
## Campos do formulário
|
|
60
66
|
|
|
61
67
|
| Campo | Tipo | Observação |
|
|
62
68
|
|---|---|---|
|
|
63
|
-
| `name` | string | **Obrigatório
|
|
69
|
+
| `name` | string | **Obrigatório.** Nome INTERNO (lista do painel). O que o lead vê na aba do navegador e no link compartilhado é `settings.public_title`; vazio, cai no `name` |
|
|
64
70
|
| `display_mode` | string | `cards` (padrão) ou `chat` |
|
|
65
71
|
| `active` | boolean | Formulário inativo devolve 404 na página pública |
|
|
66
72
|
| `inbox_id` | integer | Caixa de WhatsApp vinculada. Obrigatória para publicar. Ver regras abaixo |
|
|
@@ -94,6 +100,14 @@ ou `null` — a caixa resolvida), e `published_inbox_id` (a caixa que está NA F
|
|
|
94
100
|
| `button_label` | string — rótulo do botão da página pública | — |
|
|
95
101
|
| `resume` | booleano — continuar de onde parou entre visitas | `true` |
|
|
96
102
|
| `chat_avatar` | id numérico de blob já subido (`media`) — foto redonda ao lado dos balões, só no formato `chat`. O público recebe `chat_avatar_url` resolvida (nunca o id) | — |
|
|
103
|
+
| `public_title` | string, até 100 caracteres — título que o LEAD vê (aba do navegador, link compartilhado). Vazio = usa o `name`. O endpoint público devolve `display_title` (nunca o `name` cru) | — (21/08 — entra com o próximo deploy do app depois de 21/08/2026) |
|
|
104
|
+
|
|
105
|
+
**No `update`, `settings` SUBSTITUI o objeto inteiro** (assim como `form_data`): não há merge. Mande
|
|
106
|
+
todas as chaves que quer manter — um `settings: {theme: "dark"}` apaga cor, avatar, título público,
|
|
107
|
+
`resume` e `abandon_minutes`. E apagar `chat_avatar` custa o arquivo: a varredura de imagens roda
|
|
108
|
+
logo após o salvamento e purga o que não está mais referenciado em `form_data`, na foto publicada ou
|
|
109
|
+
em `settings.chat_avatar` (só upload com menos de 1 hora escapa). O mesmo vale pra `image` de bloco
|
|
110
|
+
ou de opção que sair do `form_data`.
|
|
97
111
|
|
|
98
112
|
## Ciclo de vida
|
|
99
113
|
|
|
@@ -208,8 +222,16 @@ renderiza e não dá erro.
|
|
|
208
222
|
**`options`** (do `choice`): `[{ "id": "abc123", "label": "Sim", "image": "" }]`.
|
|
209
223
|
|
|
210
224
|
**`branches`** (do `condition`): lista avaliada em ordem; nenhum ramo casando cai no handle `else`.
|
|
211
|
-
|
|
212
|
-
|
|
225
|
+
Cada ramo: `{ "id": "b1", "label": "Sim", "source_node_id": "<id da pergunta/escolha/consulta/IA>",
|
|
226
|
+
"operator": "equals", "value": "...", "path": "" }`. `id` é estável (a aresta `cond_<id>` aponta
|
|
227
|
+
pra ele); `label` é o rótulo do fio no desenho (vazio = número). Operadores: `equals`, `not_equals`,
|
|
228
|
+
`contains`, `filled`, `not_filled`, `greater_than`, `less_than` (os dois últimos só numéricos;
|
|
229
|
+
`filled`/`not_filled` ignoram `value`). Fonte Escolha compara pelo **id da opção**, não pelo texto;
|
|
230
|
+
resposta múltipla: `equals` exige exatamente aquela opção, `contains` = inclui. Fonte `api_request`
|
|
231
|
+
exige `path` (caminho dentro da resposta, ex.: `localidade`); fonte `ai` compara o texto/categoria
|
|
232
|
+
direto. **Ramificar por variável** (`{{var.*}}`): o motor aceita `source_variable: "<nome>"` no
|
|
233
|
+
ramo (tem precedência sobre `source_node_id`), mas o dialog de Condição do editor **não conhece a
|
|
234
|
+
chave e a descarta ao salvar o bloco pela tela** — use só em formulário mantido pela API.
|
|
213
235
|
|
|
214
236
|
**`items`** (do `action`) — o formato novo, uma LISTA de ações `[{key, config}]`:
|
|
215
237
|
|
|
@@ -357,6 +379,7 @@ mesmo que exista — é proteção, não defeito.
|
|
|
357
379
|
| Respostas por chamada do simulador | 60 |
|
|
358
380
|
| Altura da Página externa | 240..1200 px |
|
|
359
381
|
| Conferência de embed | 5 s por salto, até 3 redirecionamentos |
|
|
382
|
+
| Lista de preenchimentos do contato | 250 por origem (lead_form / meta_lead / webhook), sem paginação; `meta.truncated` avisa |
|
|
360
383
|
|
|
361
384
|
## Simulador (`lionchat_lead_forms_test_run`)
|
|
362
385
|
|
|
@@ -366,39 +389,90 @@ exige admin. O estado do teste vive em quem chama: cada chamada reproduz o teste
|
|
|
366
389
|
da lista de respostas.
|
|
367
390
|
|
|
368
391
|
- Body: `{answers: [{node_id, value}]}` — até 60 itens; vazio = começa do início. Item cujo
|
|
369
|
-
`node_id` não é o bloco atual PARA a reprodução ali (devolve o bloco onde parou).
|
|
392
|
+
`node_id` não é o bloco atual PARA a reprodução ali (devolve o bloco onde parou). `value: null`
|
|
393
|
+
avança bloco sem resposta (`start`, `message`, `embed`).
|
|
370
394
|
- Resposta 200: `{block, log, answers, variables, form}` — `block` é o mesmo envelope da página
|
|
371
|
-
pública; `log` é o caminho percorrido (`[{node_id, type, label, answer
|
|
372
|
-
mostra variável criada, ações executadas
|
|
373
|
-
|
|
374
|
-
|
|
395
|
+
pública; `log` é o caminho percorrido (`[{node_id, type, label, answer?, detail?}]` — `detail`
|
|
396
|
+
mostra variável criada, ações executadas e o rumo das condições; `answer`/`detail` só aparecem
|
|
397
|
+
quando existem); `form.name` é o nome interno.
|
|
398
|
+
- 422: `{error: "invalid_value", reason}` (uma resposta reprovada — `reason` é o código:
|
|
399
|
+
`required`, `invalid_email`, `invalid_phone`, `invalid_cpf`, `invalid_option`, `value_too_long`…)
|
|
400
|
+
ou `{error: "test_run_failed", reason}`.
|
|
401
|
+
|
|
402
|
+
**O que o simulador NÃO faz (e como isso aparece):**
|
|
403
|
+
|
|
404
|
+
| Bloco | No simulador |
|
|
405
|
+
|---|---|
|
|
406
|
+
| Consulta externa (`api_request`) e IA (`ai`) | **Não executam** (o job de efeito é desligado no modo de teste). Ao chegar neles a resposta volta `block: {node_id, type: "wait"}` e a reprodução para ali — itens seguintes são ignorados e `detail` desses blocos fica vazio. Pra testar o que vem depois, use a página pública (link identificado/aba anônima). |
|
|
407
|
+
| Agendamento (`booking`) | `value: ""` segue por `no_booking` (só se o bloco não for obrigatório). Pra simular "agendou", mande o id de um agendamento **já existente** da conta — o simulador pela API não cria reserva. (No painel, o simulador embute a página real: uma reserva feita ali é de verdade e fica no banco.) |
|
|
408
|
+
| Envio de arquivo (`file_upload`) obrigatório | Não tem como passar (o valor precisa ser um arquivo anexado à resposta de teste, que não existe): 422 `invalid_value`. Só com `required: false` e `value: ""`. |
|
|
409
|
+
| Envio de WhatsApp, etiqueta, pixel, marco | Aparecem no `log` como reservados (`detail` lista as ações), mas nada é enviado/gravado. |
|
|
375
410
|
|
|
376
411
|
## Respostas e funil
|
|
377
412
|
|
|
378
|
-
**`lionchat_lead_forms_stats`** (`days` opcional) devolve
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
413
|
+
**`lionchat_lead_forms_stats`** (`days` opcional, default 30, máximo 90) devolve
|
|
414
|
+
`views` (contador de VIDA INTEIRA do formulário — não obedece `days`), `starts`/`completed`/
|
|
415
|
+
`abandoned` da janela, `completion_rate` (% inteiro = completed/starts), `funnel` por bloco e
|
|
416
|
+
`milestones`. O funil lista os blocos que a pessoa vê (`start`, `question`, `choice`, `message`,
|
|
417
|
+
`booking`, `embed`, `end`), na ordem do desenho **publicado**; acima de 50.000 respostas na janela
|
|
418
|
+
sai parcial. **`milestones` hoje só enxerga bloco de Ações no formato antigo (`action_type:
|
|
419
|
+
"milestone"`)** — marco configurado em `items` (formato atual do editor) não aparece aqui; aparece
|
|
420
|
+
em `responses_show.milestones`.
|
|
382
421
|
|
|
383
422
|
**`lionchat_lead_forms_responses_list`** aceita `status` (`in_progress`, `completed`,
|
|
384
|
-
`abandoned`), `days` e `page
|
|
385
|
-
current_node_label, answered_count, created_at, completed_at}
|
|
386
|
-
`{id: null, name, phone, pending: true}`** — é
|
|
387
|
-
três momentos); nome e telefone saem do que a
|
|
423
|
+
`abandoned`), `days` e `page` (até 10.000). A lista nunca traz as respostas em si — só `{id, status,
|
|
424
|
+
contact, current_node_label, answered_count, created_at, completed_at}` e `meta: {current_page,
|
|
425
|
+
per_page: 25, total_count}`. **`contact` pode vir `{id: null, name, phone, pending: true}`** — é
|
|
426
|
+
quem ainda está preenchendo (o contato só nasce nos três momentos); nome e telefone saem do que a
|
|
427
|
+
pessoa já digitou. `answered_count` conta todas as chaves de `answers`, inclusive as sintéticas.
|
|
388
428
|
|
|
389
429
|
**`lionchat_lead_forms_responses_show`** traz o conteúdo:
|
|
390
430
|
|
|
391
|
-
- `
|
|
392
|
-
|
|
431
|
+
- `status`, `contact` (mesmo shape da lista), `current_node_label`, `started_at`, `completed_at`,
|
|
432
|
+
`abandoned_at`, `created_at`.
|
|
433
|
+
- `answers`: `[{label, value_label, at, download_url?}]`, ordenado por `at`. **Atenção:**
|
|
434
|
+
(1) o bloco de Ações grava entradas SINTÉTICAS com chave `"<node_id>::<n>"` e o fim degradado
|
|
435
|
+
(beco sem saída/teto de passos) grava `"_walk_ended"` — nem toda chave é id de bloco;
|
|
436
|
+
(2) no bloco de **Agendamento `value_label` é o id da reserva, não a data** (a aba Preenchimentos
|
|
437
|
+
do contato mostra a data); (3) envio de WhatsApp pulado por falta de telefone aparece como
|
|
438
|
+
entrada vazia do bloco de mensagem.
|
|
393
439
|
- `conversation`: `{id, display_id}` ou `null` — a conversa aberta na caixa vinculada.
|
|
394
|
-
- `milestones`: os marcos atingidos.
|
|
395
|
-
- `effects`: resultado de consulta/IA — `{node_id, label, state, error, status,
|
|
396
|
-
`url_short` é esquema + host + caminho, sem a query; corpo, cabeçalhos e prompt
|
|
440
|
+
- `milestones`: os marcos atingidos (`[{node_id, name, at}]`).
|
|
441
|
+
- `effects`: resultado de consulta/IA — `{node_id, label, state: pending|done|error, error, status,
|
|
442
|
+
url_short, at}`. `url_short` é esquema + host + caminho, sem a query; corpo, cabeçalhos e prompt
|
|
443
|
+
nunca saem.
|
|
397
444
|
- `utm_params`: de onde o lead veio.
|
|
398
445
|
|
|
399
|
-
Motivos de erro em `effects`: `http_<código
|
|
400
|
-
|
|
401
|
-
`
|
|
446
|
+
Motivos de erro em `effects.error`: `invalid_method`, `invalid_url`, `http_<código>` (`http_0` =
|
|
447
|
+
falha de transporte sem código), `timeout`, `ssrf_blocked`, `result_too_large`, `stale`,
|
|
448
|
+
`effect_failed` (exceção no job), `effect_runs_exceeded` (laço: 20 execuções), `budget_exceeded`,
|
|
449
|
+
`no_ai_key`, `ai_error`. (Os motivos `busy` e `unresolved_variable`, citados antes, não existem no
|
|
450
|
+
código.)
|
|
451
|
+
|
|
452
|
+
## Preenchimentos do contato (`lionchat_contacts_form_entries_list` / `_show`) — 21/08 (entra com o próximo deploy do app depois de 21/08/2026)
|
|
453
|
+
|
|
454
|
+
A aba "Preenchimentos" da ficha junta, numa lista só ordenada por data, tudo que a pessoa preencheu
|
|
455
|
+
ou que entrou por ela, de QUATRO origens: nosso formulário público (`source: lead_form`),
|
|
456
|
+
formulário de anúncio do Meta (`meta_lead`), Webhook Universal (`custom_webhook`) e o webhook que o
|
|
457
|
+
FlowBuilder cria pro gatilho de um fluxo (`flow`, com o nome do fluxo). É a única rota que responde
|
|
458
|
+
"o que esta PESSOA preencheu" — as outras são por formulário/integração, e duas delas são só de
|
|
459
|
+
administrador; esta é liberada a qualquer agente.
|
|
460
|
+
|
|
461
|
+
- **Lista**: `{payload: [{source, id, title, status, at, count, conversation}], meta: {total,
|
|
462
|
+
truncated}}`. `id` é o id do registro NA ORIGEM — só identifica junto com `source`. `status` é
|
|
463
|
+
`in_progress|completed|abandoned` no nosso formulário e `received` nas demais. `count` = respostas
|
|
464
|
+
(nosso) ou campos vinculados e gravados (de fora). `conversation` só existe em `lead_form`. Sem
|
|
465
|
+
paginação de propósito; teto de 250 por origem — estourou, `truncated: true`. Só entram eventos
|
|
466
|
+
do Meta/webhook com status processado.
|
|
467
|
+
- **Detalhe** (`source` + `id` da mesma linha): nosso formulário devolve `answers` (`[{label,
|
|
468
|
+
value, at, download_url?, images?}]` — pergunta/resposta legíveis, na ordem; Escolha com opção
|
|
469
|
+
ilustrada traz `images`, e opção sem texto vem com `value` vazio; Agendamento mostra a DATA),
|
|
470
|
+
`written` (`[{scope: contact|conversation, label, value}]` — o que AQUELE preenchimento gravou) e
|
|
471
|
+
`utm`. Meta/webhook/fluxo devolvem SÓ `fields: [{label, value}]` — os campos que foram vinculados a
|
|
472
|
+
atributos daqui e realmente gravados, com o rótulo daqui; nunca o payload cru. `fields: []` = o
|
|
473
|
+
evento não gravou nada. Origem fora da lista ou registro de outro contato = 404.
|
|
474
|
+
- A lista **não traz o `lead_form_id`** da resposta: pra chegar em `lionchat_lead_forms_responses_show`
|
|
475
|
+
a partir dela, ache o formulário pelo `title` em `lionchat_lead_forms_list`.
|
|
402
476
|
|
|
403
477
|
## Conferência de iframe (`lionchat_lead_forms_check_embed`)
|
|
404
478
|
|
|
@@ -497,3 +571,11 @@ agendar (com `required: true` essa saída deixa de existir). O tipo de evento ve
|
|
|
497
571
|
- **Não há tool de rewind**: o "Voltar e corrigir" é da página pública (o lead corrige a própria
|
|
498
572
|
resposta; telefone corrigido reencaminha a mensagem pro número certo). Pela API de dashboard,
|
|
499
573
|
respostas são somente leitura.
|
|
574
|
+
- **`settings` no `update` também SUBSTITUI o objeto inteiro** — e sem `chat_avatar` o arquivo da
|
|
575
|
+
foto é apagado pela varredura. Leia com `show`, altere e mande completo.
|
|
576
|
+
- **Imagem que some do `form_data` é apagada de verdade** logo após o salvamento (só sobrevive se
|
|
577
|
+
ainda estiver na foto publicada ou tiver menos de 1 hora).
|
|
578
|
+
- **O simulador não roda consulta nem IA**: parou em `block.type: "wait"` = chegou num desses
|
|
579
|
+
blocos. Teste o trecho seguinte pela página pública.
|
|
580
|
+
- **`stats.views` é de vida inteira** (ignora `days`); `stats.milestones` não vê marco em `items`.
|
|
581
|
+
- **`name` é interno; `settings.public_title` é o que o lead vê** (vazio = cai no `name`).
|
|
@@ -74,6 +74,15 @@ Glossário completo de termos, status codes, enums e conceitos da plataforma. Us
|
|
|
74
74
|
de WhatsApp — oficial e QR Code). A bolha mostra o selo "Encaminhada"
|
|
75
75
|
- `content_attributes.frequently_forwarded`: `true` = encaminhada MUITAS vezes (o "encaminhada com
|
|
76
76
|
frequência" do WhatsApp). Útil pra responder "essa mensagem foi encaminhada?" sem chutar
|
|
77
|
+
- `content_attributes.edited`: `true` = o CLIENTE editou a mensagem no WhatsApp (`edited_at` traz
|
|
78
|
+
quando). O `content` já é o texto novo; a versão anterior não fica guardada. Vale nos dois canais
|
|
79
|
+
de WhatsApp (QR Code desde 18/07/2026; oficial desde 21/08/2026 — entra com o próximo deploy do
|
|
80
|
+
app depois de 21/08/2026; antes a edição virava um balão VAZIO novo, contado como mensagem nova).
|
|
81
|
+
- `content_attributes.deleted`: `true` = mensagem APAGADA ("apagar para todos"), pelo cliente ou
|
|
82
|
+
pela empresa no celular (convivência). O `content` vira `"⛔ Esta mensagem foi excluída"` seguido
|
|
83
|
+
do texto original (a equipe continua vendo o que foi dito); os anexos são removidos. Ao resumir
|
|
84
|
+
uma conversa, trate como apagada — não cite o texto como se ainda estivesse de pé. (No canal
|
|
85
|
+
oficial, desde 21/08/2026 — entra com o próximo deploy do app depois de 21/08/2026.)
|
|
77
86
|
|
|
78
87
|
## Attachment (Anexo)
|
|
79
88
|
|
|
@@ -296,6 +305,18 @@ comportamento intencional.
|
|
|
296
305
|
- `role`: `agent` (atendente) ou `administrator` (admin/dono)
|
|
297
306
|
- `availability`: `online`, `busy`, `offline`
|
|
298
307
|
- `permissions`: array de strings com permissões granulares
|
|
308
|
+
- `replacing`: `true` em `lionchat_agents_list` por até 30 min enquanto uma substituição
|
|
309
|
+
(`lionchat_agents_replace`) transfere a carteira desse agente pro novo — ele está SAINDO; não
|
|
310
|
+
atribua nada a ele
|
|
311
|
+
|
|
312
|
+
### Agente de SUPORTE (SupportAccessGrant) — não é agente da conta
|
|
313
|
+
|
|
314
|
+
Quem entra na conta por **acesso de suporte** (operador da plataforma) aparece como administrador,
|
|
315
|
+
mas **não é membro da equipe**: `lionchat_agents_list` não o lista (escopo `regular_users`), ele
|
|
316
|
+
não ocupa vaga do plano, não pode ser substituído (`agents_replace` recusa) e, desde 17/08/2026,
|
|
317
|
+
a IA também o ignora — não atribui conversa a ele, não agenda mensagem no nome dele, não o menciona
|
|
318
|
+
em alerta nem o conta como "disponível". Exceção deliberada: se alguém o atribuir à mão como
|
|
319
|
+
responsável, ele segue valendo como responsável.
|
|
299
320
|
|
|
300
321
|
## AutomationRule (Regra de automação)
|
|
301
322
|
|
|
@@ -309,7 +330,11 @@ comportamento intencional.
|
|
|
309
330
|
- `booking_event_type_id`: FK pro tipo de evento (ex: "Demo 30min")
|
|
310
331
|
- `attendee_email`, `attendee_name`, `attendee_phone`
|
|
311
332
|
- `start_time`, `end_time`: ISO 8601
|
|
312
|
-
- `status`: `
|
|
333
|
+
- `status`: `confirmed`, `cancelled`, `completed` — mas **só muda quando o cancelamento/conclusão
|
|
334
|
+
vem pelo link do paciente ou pela IA**. Quem conclui/cancela pela Agenda mexe na TAREFA
|
|
335
|
+
(`account_tasks.status`: `pending`/`completed`/`cancelled`/`snoozed`), e o booking fica
|
|
336
|
+
`confirmed`. Pra saber se um agendamento aconteceu, leia a tarefa (`lionchat_tasks_show`), não o
|
|
337
|
+
booking.
|
|
313
338
|
|
|
314
339
|
**A IA agenda EXCLUSIVAMENTE por agenda de Booking (15/08/2026).** Não existe mais agendamento
|
|
315
340
|
avulso/direto pela IA — ela consulta as agendas liberadas, respeita os dias em que a agenda não
|
|
@@ -48,6 +48,17 @@ Stages NÃO são tabela separada. São armazenadas como jsonb dentro do Funnel:
|
|
|
48
48
|
}
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
**Etapa que não existe no funil (desde 19/08/2026):**
|
|
52
|
+
- `kanban_items_create`/`_update`/`_move` com `funnel_stage` que o funil não tem **não falha e não
|
|
53
|
+
some**: o card é REDIRECIONADO — pro destino gravado quando a etapa foi apagada, senão pra etapa
|
|
54
|
+
da mesma posição, senão pra primeira. **Confira o `funnel_stage` da resposta**: pode ser diferente
|
|
55
|
+
do que você mandou. Leia `funnels_show` antes e use o slug exato.
|
|
56
|
+
- `funnels_update` que tira do `stages` uma etapa com card responde **422 `STAGE_HAS_ITEMS`** com
|
|
57
|
+
`stages: {"<slug>": <quantos cards>}`. Primeiro mova os cards com `lionchat_funnels_create_2`
|
|
58
|
+
(`POST /funnels/{id}/migrate_stage`, `from_stage`, `to_stage` ou `to_funnel_id`) e só então
|
|
59
|
+
reenvie o funil sem a etapa. Não existe parâmetro de destino no `update` de propósito.
|
|
60
|
+
- Funil apagado continua sendo erro (o card não é criado).
|
|
61
|
+
|
|
51
62
|
### KanbanConfig (Configuração Global do Kanban) — CRÍTICO
|
|
52
63
|
|
|
53
64
|
**Tabela separada do Funnel.** 1:1 com a conta. Guarda configurações que valem pra TODOS os funis. Tem 5 campos jsonb importantes:
|
|
@@ -245,6 +256,11 @@ Log automático de eventos do card:
|
|
|
245
256
|
|
|
246
257
|
Tipos comuns: `created`, `stage_changed`, `agent_assigned`, `agent_removed`, `note_added`, `value_changed`, `priority_changed`, `archived`.
|
|
247
258
|
|
|
259
|
+
Quem fez: `by_user_id`/`user` traz a pessoa; ação de automação ou flow vem com o nome da regra/fluxo;
|
|
260
|
+
ação da IA (desde 21/08/2026 — entra com o próximo deploy do app depois de 21/08/2026) vem como
|
|
261
|
+
`"IA: <nome do assistente>"` com `id` nulo — antes saía sem autor. Ao explicar um histórico de card,
|
|
262
|
+
use esse campo pra dizer se foi gente, automação ou IA.
|
|
263
|
+
|
|
248
264
|
## Checklist (tarefas dentro do card)
|
|
249
265
|
|
|
250
266
|
Array plano de itens. Cada item pode (opcionalmente) pertencer a um grupo via `group_id` +
|
|
@@ -580,7 +596,9 @@ Cada card pode receber atributos custom de 3 origens diferentes. **A escolha do
|
|
|
580
596
|
## Diagnóstico: "Card sumiu do funil"
|
|
581
597
|
|
|
582
598
|
1. Está arquivado? `archived = true` em algum nível?
|
|
583
|
-
2. Etapa atual existe ainda?
|
|
599
|
+
2. Etapa atual existe ainda? Desde 19/08/2026 card em etapa inexistente é redirecionado na
|
|
600
|
+
gravação (e os 621 antigos foram movidos pra primeira etapa) — se ainda sumiu, filtre por
|
|
601
|
+
`funnel_stage` com o slug que aparece em `kanban_items_show` e compare com `funnels_show`.
|
|
584
602
|
3. `position` está faltando? (cards sem position vão pro fim)
|
|
585
603
|
4. Está em outro funil? (mover entre funis muda `funnel_id`)
|
|
586
604
|
|
|
@@ -153,6 +153,7 @@ conversa antiga que NÃO aparece no relatório de hoje (régua antiga por criaç
|
|
|
153
153
|
| "retrospectiva do ano" | `lionchat_reports_list_15` |
|
|
154
154
|
| "satisfação", "CSAT", "nota dos clientes" | `lionchat_csat_metrics` |
|
|
155
155
|
| "SLA", "cumprimento de prazo" (se a conta tiver Enterprise) | `lionchat_sla_metrics` |
|
|
156
|
+
| "quantos agendamentos", "taxa de comparecimento", "agendamentos por tipo/atendente" | `lionchat_booking_reports` (ver "Agendamentos" no fim deste guia) |
|
|
156
157
|
|
|
157
158
|
---
|
|
158
159
|
|
|
@@ -330,6 +331,11 @@ Retorna:
|
|
|
330
331
|
|
|
331
332
|
**Filtros aceitos (expostos na tool desde 2026-07-24):** `inbox_id`, `team_id`, `sla_policy_id`, `label_list[]`, `assigned_agent_id`, `since`/`until` (unix segundos).
|
|
332
333
|
|
|
334
|
+
Latência de detecção: o prazo é conferido a cada 5 min, e desde 21/08/2026 (entra com o próximo
|
|
335
|
+
deploy do app depois de 21/08/2026) as conferências saem espalhadas em até 2 min dentro do ciclo —
|
|
336
|
+
um estouro pode aparecer em `sla_list`/`sla_metrics` até ~7 min depois do horário-limite. Não é
|
|
337
|
+
defeito; não conclua "o SLA não está rodando" por isso.
|
|
338
|
+
|
|
333
339
|
## Padrões de interpretação
|
|
334
340
|
|
|
335
341
|
### Comparando períodos
|
|
@@ -555,7 +561,7 @@ nenhum `reports_*` responde; aqui é `funnel_stages` + `date_basis: closed` + `s
|
|
|
555
561
|
|
|
556
562
|
Não é consulta livre: escolha um `widget_type` e preencha **só os campos daquele tipo**.
|
|
557
563
|
|
|
558
|
-
### Os
|
|
564
|
+
### Os 9 tipos de bloco
|
|
559
565
|
|
|
560
566
|
| Tipo | Campos | Recurso exigido |
|
|
561
567
|
|---|---|---|
|
|
@@ -563,13 +569,26 @@ Não é consulta livre: escolha um `widget_type` e preencha **só os campos daqu
|
|
|
563
569
|
| `entity_ranking` | `dimension` (agent/inbox/team/label) · `metric` (conversations, resolutions, avg_first_response_time, avg_resolution_time) · `time_range` | — |
|
|
564
570
|
| `csat_summary` | `time_range` | — |
|
|
565
571
|
| `sla_summary` | `time_range` | `sla` (Enterprise) |
|
|
566
|
-
| `funnel_stages` | `funnel_id` · `date_basis` (created/moved/closed/any) · `status` (all/open/won/lost) · `time_range` | `kanban_board` |
|
|
572
|
+
| `funnel_stages` | `funnel_id` · `date_basis` (created/moved/closed/any) · `status` (all/open/won/lost) · `measure` (count padrão / value = soma do valor dos cards) · `time_range` | `kanban_board` |
|
|
573
|
+
| `stage_entries` | `funnel_id` · `measure` (count/value) · `time_range` — quantos cards DISTINTOS ENTRARAM em cada etapa no período (histórico desde 12/07/2026) | `kanban_board` |
|
|
574
|
+
| `calls_report` | `dimension` (agent/inbox) · `scope_type` (só `inbox`, opcional — recorte por caixa, desde 27/08/2026) + `scope_id` · `time_range` — ligações / atendidas / não atendidas / não concluídas / tempo total / tempo médio | — |
|
|
567
575
|
| `lead_origin` | `time_range` | `liontrack` |
|
|
568
576
|
| `agent_report` | `dimension` (agent/team/inbox) · `scope_type`+`scope_id` · `columns[]` · `time_range` | — |
|
|
569
577
|
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
578
|
+
`stage_entries`, `calls_report`, `measure`, `today`/`yesterday` e os metadados `title`/`width`/`height`
|
|
579
|
+
são commits de 21/08/2026 (entram com o próximo deploy do app depois de 21/08/2026); `custom` em
|
|
580
|
+
todos os tipos está no ar desde 19/08/2026.
|
|
581
|
+
|
|
582
|
+
**`time_range`:** `today`, `yesterday` (desde 21/08 — o menor período era 7 dias), `last_7_days`,
|
|
583
|
+
`last_30_days`, `this_month`, `last_month` e `custom` (com `from`/`to`, **em qualquer tipo** desde
|
|
584
|
+
19/08/2026). **A janela `custom` não pode passar de 92 dias** — o teto é da janela, não do tipo;
|
|
585
|
+
"esse ano" é recusado com a explicação. `today`/`yesterday` resolvem no fuso do `timezone_offset`
|
|
586
|
+
enviado — mande o da conta.
|
|
587
|
+
|
|
588
|
+
**Metadados do bloco (irmãos de `widget_type`, fora dos params):** `title` (nome que a pessoa dá ao
|
|
589
|
+
bloco, até 80 caracteres; vazio = o painel mostra o rótulo do tipo), `width` (1 a 4 colunas; padrão
|
|
590
|
+
2) e `height` (`normal` | `tall`). Preencha `title` em todo bloco que você criar — quatro blocos de
|
|
591
|
+
funil sem nome chegam indistinguíveis pra quem lê depois.
|
|
573
592
|
|
|
574
593
|
**Colunas do `agent_report`:** `leads`, `atendidos`, `resolvidas`, `abertas`, `pendentes`, `adiadas`,
|
|
575
594
|
`label_count` (exige `label_id`) e `conversao` (exige `denominator` e `numerator`, que é **lista de
|
|
@@ -586,13 +605,19 @@ IDs de etiqueta**, nunca nome de métrica).
|
|
|
586
605
|
|
|
587
606
|
### Armadilhas que fazem o bloco sair errado
|
|
588
607
|
|
|
589
|
-
1. **`scope_type`/`scope_id` têm sentido
|
|
590
|
-
|
|
591
|
-
|
|
608
|
+
1. **`scope_type`/`scope_id` têm sentido DIFERENTE por tipo — e, no `agent_report`, por VALOR
|
|
609
|
+
(desde 27/08/2026).** No `conversations_timeseries` = "o gráfico é só daquela entidade". No
|
|
610
|
+
`agent_report`: `team`/`agent` = "mostre só as linhas de quem é dessa equipe/agente" (contando o
|
|
611
|
+
trabalho da pessoa na conta INTEIRA); `inbox` = recorte de CAIXA (membros da caixa, contando SÓ
|
|
612
|
+
o que fizeram naquela caixa — é o desenho de "relatório por médico/unidade"). `inbox` +
|
|
613
|
+
`dimension: team` é RECUSADO com motivo. No `calls_report`, `scope_type: inbox` conta só as
|
|
614
|
+
ligações daquela caixa — **ligação sem caixa fica de fora** (VTCall ~90% e Zenvia 100% das
|
|
615
|
+
ligações não têm caixa; LionCalls e Wavoip têm em 100%). Confundir troca a conta inteira.
|
|
592
616
|
2. **Campo fora da lista é descartado em silêncio.** Se um valor "não fez efeito", provavelmente o
|
|
593
617
|
nome do campo está errado.
|
|
594
|
-
3. **Sempre envie `timezone_offset` em HORAS
|
|
595
|
-
|
|
618
|
+
3. **Sempre envie `timezone_offset` em HORAS, derivado do fuso DA CONTA** (`account_show.timezone`;
|
|
619
|
+
Brasília = `-3`, Cuiabá/Campo Grande/Manaus = `-4`). Sem ele o cálculo é em UTC e o número não
|
|
620
|
+
bate com o que o cliente vê na tela.
|
|
596
621
|
4. **`update` substitui a lista de blocos inteira.** Leia com `list`, altere o array, devolva
|
|
597
622
|
completo — e preserve o `id` de cada bloco que já existia.
|
|
598
623
|
5. **`list` não pagina.** Se a resposta vier com aviso de corte, **não** use aquela lista para montar
|
|
@@ -669,6 +694,22 @@ Colunas: Ligações · Atendidas · Não atendidas · **Não concluídas** · Te
|
|
|
669
694
|
Não a esconda ao resumir por pessoa.
|
|
670
695
|
- A tabela lista só quem teve ligação no período — atendente ausente da tabela fez zero.
|
|
671
696
|
|
|
697
|
+
### Agendamentos (`lionchat_booking_reports`) — 2026-08-19
|
|
698
|
+
|
|
699
|
+
`GET /api/v2/accounts/{id}/booking_reports` — a aba Relatórios > Agendamentos. Unidade = o
|
|
700
|
+
AGENDAMENTO (Booking). Params: `since`/`until` (datas; padrão 30 dias pra trás E 30 pra frente,
|
|
701
|
+
porque agenda tem futuro), `event_type_id`, `user_id` (responsável da tarefa), `status`
|
|
702
|
+
(`pending` | `completed` | `cancelled` | `snoozed`), `group_by` (`day` | `week` | `month`).
|
|
703
|
+
Resposta: `totals` (`total`, `pending`, `completed`, `cancelled`, `snoozed`, `attendance_rate`),
|
|
704
|
+
`timeline`, `by_event_type`, `by_agent`, `by_origin`.
|
|
705
|
+
|
|
706
|
+
- **`attendance_rate` = concluídos / (concluídos + cancelados)**, em %. Pendentes ficam FORA do
|
|
707
|
+
denominador (ainda não aconteceram). Não recalcule com o total.
|
|
708
|
+
- A SITUAÇÃO vem da tarefa da Agenda (`account_tasks.status`), não de `bookings.status` — quem
|
|
709
|
+
conclui/cancela pela Agenda deixa o booking parado em "confirmado". Ler `bookings_*` direto pra
|
|
710
|
+
contar "concluídos" dá zero.
|
|
711
|
+
- `snoozed` (adiado) aparece separado de `pending` de propósito.
|
|
712
|
+
|
|
672
713
|
### Faturamento (`measure`)
|
|
673
714
|
|
|
674
715
|
`measure: 'value'` faz `funnel_stages`/`stage_entries` somarem o VALOR dos cards em vez de contar.
|
|
@@ -676,3 +717,60 @@ Combinado com `status: 'won'` + `date_basis: 'closed'`, dá o faturamento ganho
|
|
|
676
717
|
|
|
677
718
|
**Cuidado ao escrever**: se os cards do cliente têm valor padrão (todos com o mesmo número), a soma
|
|
678
719
|
não é faturamento — é o padrão multiplicado. Se todos os valores forem idênticos, desconfie e diga.
|
|
720
|
+
|
|
721
|
+
## Avisos — o resumo diário nativo no WhatsApp (2026-08-27)
|
|
722
|
+
|
|
723
|
+
O caso da seção anterior ("me traz o relatório todo dia") virou **funcionalidade nativa**: a aba
|
|
724
|
+
**Relatórios > Avisos** manda, todo dia no horário escolhido, o resumo em texto de um relatório
|
|
725
|
+
personalizado num grupo/conversa de **WhatsApp QR**, com o texto escrito pela IA da conta. Ferramentas
|
|
726
|
+
`lionchat_report_alerts_*` (criar, editar, listar, excluir, enviar agora, histórico, prévia). Só
|
|
727
|
+
administrador; teto de 10 por conta.
|
|
728
|
+
|
|
729
|
+
### O fluxo seguro (aprendido em produção, 27/08)
|
|
730
|
+
|
|
731
|
+
1. **Crie DESLIGADO** (`enabled: false`) — aviso criado ligado DENTRO da janela do dia
|
|
732
|
+
(`send_hour` até +3h, fuso da conta) dispara no próximo tick de hora, e o grupo do cliente
|
|
733
|
+
recebe sem ninguém ter validado.
|
|
734
|
+
2. **Rode a prévia** (`report_alerts_preview` → token → `report_alerts_preview_status`): mesmo
|
|
735
|
+
motor do envio, sem mandar nada. Mostre o texto pra pessoa aprovar.
|
|
736
|
+
3. **Só então ligue** (`report_alerts_update` com `enabled: true`).
|
|
737
|
+
|
|
738
|
+
### Regras do texto (a IA do Aviso NÃO é a IA do chat)
|
|
739
|
+
|
|
740
|
+
- A conferência de números **reprova qualquer número que não exista no relatório** — a IA nunca
|
|
741
|
+
calcula, soma nem inventa percentual. Reprovou = sai o texto padrão do sistema (fiel, bloco a
|
|
742
|
+
bloco). **Percentual confiável = bloco `stage_conversion` no relatório** (o motor calcula).
|
|
743
|
+
- Prompt que pede pra **renomear/reorganizar seções já fez a IA trocar rótulos de números** (caso
|
|
744
|
+
real: "Novos leads: 9" com o número do bloco de atendentes). O prompt que funciona: *"mantenha os
|
|
745
|
+
títulos e TODOS os números exatamente como estão, não renomeie seções, não calcule nada, inclua
|
|
746
|
+
TODOS os blocos"*.
|
|
747
|
+
- Teto do texto: 60.000 caracteres (o do WhatsApp) — relatório inteiro cabe.
|
|
748
|
+
- A mensagem entra na conversa como **mensagem de sistema**: automações e fluxos ativos naquela
|
|
749
|
+
conversa reagem a ela; não conta como resposta de atendente, não mexe em SLA nem apaga o
|
|
750
|
+
"cliente aguardando".
|
|
751
|
+
|
|
752
|
+
### Diagnóstico ("o grupo não recebeu")
|
|
753
|
+
|
|
754
|
+
`report_alerts_deliveries` é o histórico (90 dias, texto congelado de cada envio):
|
|
755
|
+
`sent` = saiu, aguardando recibo · `confirmed` = **entregue com recibo do canal** (o selo verde só
|
|
756
|
+
existe com evidência) · `send_failed` = recusado (motivo em `error_message`; caixa desconectada é o
|
|
757
|
+
clássico) · `skipped_late` = não saiu no horário (janela de 3h estourada; tenta amanhã) · `error` =
|
|
758
|
+
falhou antes do envio. `test_mode: true` = disparo manual. Na lista, `next_send_on` diz o próximo
|
|
759
|
+
envio previsto e `last_delivery_status`/`last_error` resumem o último.
|
|
760
|
+
|
|
761
|
+
### Bloco `stage_conversion` — percentual entre etapas (entra com o próximo deploy pós-27/08)
|
|
762
|
+
|
|
763
|
+
`widget_type: 'stage_conversion'`: conversão calculada PELO MOTOR — cards **distintos** que entraram
|
|
764
|
+
nas etapas de `numerator_stage_ids` ÷ os que entraram nas de `denominator_stage_ids`, na janela
|
|
765
|
+
(mesma fonte histórica do `stage_entries`). Ex. real: Consulta Agendada ÷ (Novos Leads + Agendamento
|
|
766
|
+
Pendente). Card que passou por duas etapas do denominador conta UMA vez (somar deflaria a taxa).
|
|
767
|
+
`chart_type: 'number'`; shape scalar (value = %, total = base; total 0 = "sem dados"). Os ids de
|
|
768
|
+
etapa são as CHAVES do hash `stages` do `lionchat_funnels_show`. Janela curta pode passar de 100%
|
|
769
|
+
(agendou hoje um lead que entrou ontem) — é verdade do dado, explique em vez de esconder.
|
|
770
|
+
|
|
771
|
+
### Recorte por caixa nos blocos de tabela (2026-08-26, já no ar)
|
|
772
|
+
|
|
773
|
+
Em `agent_report` e `calls_report`, `scope_type: 'inbox'` + `scope_id` recorta **de verdade** pela
|
|
774
|
+
caixa: membros da caixa contando SÓ o que fizeram nela (era o defeito dos relatórios por médico
|
|
775
|
+
saírem iguais). `'agent'`/`'team'` seguem sendo recorte de PESSOAS (trabalho na conta inteira);
|
|
776
|
+
`'inbox'` + `dimension: 'team'` é recusado. E `lead_origin` passou a respeitar `time_range`.
|
|
@@ -173,7 +173,9 @@ Feature flag específica (ex: `feature_kanban`, `feature_captain`) está OFF.
|
|
|
173
173
|
- `"private must be boolean"` — true/false, não string
|
|
174
174
|
|
|
175
175
|
### KanbanItem
|
|
176
|
-
- `"
|
|
176
|
+
- `"STAGE_HAS_ITEMS"` (no `funnels_update`) — você tentou remover uma etapa que ainda tem card;
|
|
177
|
+
`stages` na resposta diz quantos. Mova com `migrate_stage` antes. (Card criado em etapa
|
|
178
|
+
inexistente NÃO dá erro: é redirecionado — confira o `funnel_stage` devolvido.)
|
|
177
179
|
- `"conversation_display_id must exist"` — conversa não existe ou foi deletada
|
|
178
180
|
- `"position must be a positive integer"` — não pode ser negativo
|
|
179
181
|
|
|
@@ -418,6 +420,18 @@ pelo painel de suporte — só volta no botão Retomar), `cancelled` (encerrada
|
|
|
418
420
|
Enquanto uma importação está viva, o repescador de mensagens da sessão fica fora do caminho, de
|
|
419
421
|
propósito. Pausar, retomar e cancelar são ações do painel de suporte — não existem no MCP.
|
|
420
422
|
|
|
423
|
+
**A mídia vem DEPOIS do texto (desde 19-20/08/2026).** O import grava as conversas só com o texto
|
|
424
|
+
(779 conversas em ~3 min num caso real) e busca os arquivos em segundo plano, numa fila por caixa
|
|
425
|
+
com poucas vagas na instalação inteira — pode levar horas (o dono aceitou "até 24 h, contanto que
|
|
426
|
+
não atrapalhe nada"). Enquanto isso a mensagem carrega `content_attributes.media_failed` com
|
|
427
|
+
`retryable: true` (bolha âmbar "mídia chegando"); quando o arquivo chega, o selo some e o anexo
|
|
428
|
+
aparece; se o WhatsApp já apagou o arquivo (tudo com mais de ~2 semanas), o selo vira
|
|
429
|
+
`retryable: false` (vermelho, definitivo — não há repesca). `lionchat_inboxes_waha_import_status`
|
|
430
|
+
responde "ainda está chegando?": `media_pending` (arquivos na fila desta caixa; 0 = tudo pedido),
|
|
431
|
+
`media_swept_at`/`media_swept_count` (varredura final que recolocou órfãos na fila). `status:
|
|
432
|
+
completed` com `media_pending > 0` é normal — texto pronto, fotos a caminho. Conversa de histórico
|
|
433
|
+
NÃO é repescada pelo vigia de mensagens, de propósito.
|
|
434
|
+
|
|
421
435
|
### "Editei o evento no Google Calendar e não sincronizou"
|
|
422
436
|
Auto-cura desde 2026-06-09: o vigia horário re-arma o "watch" morto de conexões saudáveis
|
|
423
437
|
sozinho (sem reconectar a conta). Se persistir >1h, aí sim investigar a conexão
|
|
@@ -498,6 +512,15 @@ recusado; brasileiro com 55 e 12-13 dígitos é aceito mesmo no formato antigo s
|
|
|
498
512
|
sem erro de telefone); no import do KANBAN, telefone inválido cria o card SEM contato e SEM
|
|
499
513
|
conversa, em silêncio — comportamento diferente do import de contatos.
|
|
500
514
|
|
|
515
|
+
**Complementos de 19/08:** telefone PREENCHIDO e inválido **recusa a linha inteira** — o contato não
|
|
516
|
+
nasce (antes ele nascia mudo, sem telefone). Coluna de telefone **vazia** continua criando o contato
|
|
517
|
+
(lista de nome + e-mail é uso legítimo). **Linha totalmente vazia não é erro**: é pulada e contada em
|
|
518
|
+
`blank_rows` no resultado — planilha de 300 linhas com 2 preenchidas deixa de gerar 298 "Nome é
|
|
519
|
+
obrigatório". Telefone em notação científica do Excel (`9,88888E+12`) recebe mensagem própria
|
|
520
|
+
("formate a coluna como texto"), não "confira o DDI". No `contacts_import_validate`, o número da
|
|
521
|
+
linha no relatório é a posição REAL no arquivo (linhas vazias contam na numeração, não no total
|
|
522
|
+
conferido).
|
|
523
|
+
|
|
501
524
|
## "A caixa oficial parou de disparar / de receber" — avisos automáticos da Meta (18/08)
|
|
502
525
|
|
|
503
526
|
Duas famílias de chaves novas em `additional_attributes` da caixa `Channel::Whatsapp`
|
|
@@ -512,6 +535,15 @@ Duas famílias de chaves novas em `additional_attributes` da caixa `Channel::Wha
|
|
|
512
535
|
e `reauthorization_required` vira `true` SOZINHO. Com `reauthorization_required: true` a caixa
|
|
513
536
|
fica MUDA (descarta o que chega) até reconectar. A ausência dessas chaves NÃO prova que a caixa
|
|
514
537
|
está conectada (caixa antiga só ganha o aviso após reinscrição).
|
|
538
|
+
- **Registro do número incompleto** (20/08): `whatsapp_registration_error` (texto, a frase da
|
|
539
|
+
própria Meta — ex.: verificação em duas etapas ligada num número que veio de outra plataforma).
|
|
540
|
+
A caixa foi criada e **continua recebendo**; só o registro do número não terminou. É diferente de
|
|
541
|
+
`reauthorization_required` (esse emudece a caixa). Orientação: resolver do lado da Meta e clicar
|
|
542
|
+
em "Concluir registro" na caixa; a chave some quando o registro passa. Conectar uma caixa oficial
|
|
543
|
+
é ação de administrador e respeita o teto de caixas do plano (402 antes de abrir a janela da Meta).
|
|
544
|
+
- Reconectar uma caixa em convivência pelo botão volta a pedir o histórico de 180 dias sozinho
|
|
545
|
+
(19/08); é um tiro único por onboarding — se a Meta recusar fora da janela de 24 h, não há
|
|
546
|
+
repetição.
|
|
515
547
|
|
|
516
548
|
## "O filtro de etiqueta 'não está presente' mente" — NUNCA mentiu pela API
|
|
517
549
|
|
|
@@ -521,6 +553,20 @@ Se alguma anotação antiga disser que esse filtro mente por API, está errada.
|
|
|
521
553
|
verdade nos filtros: data FIXA com `is_greater_than`/`is_less_than` passou a cortar o dia no fuso
|
|
522
554
|
da CONTA (ver resource `filtros-e-relatorios`).
|
|
523
555
|
|
|
556
|
+
## "Mapeei o campo da integração pro atributo da conversa e nada foi gravado" (Meta Lead / Webhook Universal)
|
|
557
|
+
|
|
558
|
+
ATENÇÃO (26/08/2026): atributo de conversa mapeado existe SÓ no Meta Lead e no Webhook Universal.
|
|
559
|
+
Nos 9 gateways de pagamento a opção "salvar também na conversa" foi REMOVIDA (existiu de 21 a
|
|
560
|
+
26/08) — o backend ignora `conversation_attribute_keys` se estiver gravada; os gateways gravam os
|
|
561
|
+
dados da compra automaticamente no CONTATO, como sempre.
|
|
562
|
+
|
|
563
|
+
Três causas, nesta ordem: (1) o evento não abriu conversa — atributo de conversa só existe na
|
|
564
|
+
conversa que a automação/fluxo mapeado cria (contato sozinho não tem onde gravar); (2) a chave é
|
|
565
|
+
reservada (`imported_from`, `type`, `captain_*`... — lista em `api-conventions`) e foi recusada;
|
|
566
|
+
(3) o valor não é do TIPO do atributo (texto num campo de Número, data em formato estranho) e foi
|
|
567
|
+
descartado — o log do servidor tem `[IntegrationAttributes] ... tipo_invalido=[...]`.
|
|
568
|
+
Gravar por integração é silencioso: não espere automação nem webhook de saída reagindo ao atributo.
|
|
569
|
+
|
|
524
570
|
## Quando reportar pro suporte
|
|
525
571
|
|
|
526
572
|
Reporte se:
|
|
@@ -533,3 +579,66 @@ NÃO precisa reportar:
|
|
|
533
579
|
- 4xx (você fez algo errado)
|
|
534
580
|
- Rate limit (esperado)
|
|
535
581
|
- 404 de recurso deletado
|
|
582
|
+
|
|
583
|
+
## Conector REMOTO "conecta e desconecta" a cada ~6 minutos (Claude Code / VS Code / Codex ligados direto)
|
|
584
|
+
|
|
585
|
+
Vale SÓ para o conector remoto (`mcp.lionchat.com.br`). O conector local (npm, stdio) não tem canal de rede.
|
|
586
|
+
Sintoma: `/mcp` alterna connected/disconnected a cada ~6 min; nenhuma chamada falha.
|
|
587
|
+
Causa (21/08/2026): o cliente segura um canal GET esperando avisos do servidor; o Cloudflare derruba
|
|
588
|
+
qualquer resposta que fique 125 s sem um byte (Proxy Read Timeout). Quem usa pela claude.ai/ChatGPT não
|
|
589
|
+
abre esse canal e nunca vê isso.
|
|
590
|
+
Correção (v1.15.1): o servidor manda um `ping` a cada 30 s enquanto o canal está aberto.
|
|
591
|
+
Interruptor: `MCP_KEEPALIVE_INTERVAL_MS` (0 = desligado). Detalhe: `docs/plans/mcp-keepalive-cloudflare/`.
|
|
592
|
+
|
|
593
|
+
## "O grupo não recebeu o resumo diário" (Avisos de relatório) — 27/08
|
|
594
|
+
|
|
595
|
+
Diagnóstico em 2 passos: `lionchat_report_alerts_list` (colunas `last_delivery_status`/`last_error`
|
|
596
|
+
resumem o último dia; `next_send_on` diz o próximo) e `lionchat_report_alerts_deliveries` (histórico
|
|
597
|
+
de 90 dias com o TEXTO congelado de cada envio). Leitura dos status: `confirmed` = entregue COM
|
|
598
|
+
recibo do canal; `sent` = saiu e o recibo ainda não veio (reconfere sozinho em ~15 min); `send_failed`
|
|
599
|
+
= o canal recusou (motivo em `error_message` — caixa desconectada é o clássico: mande reconectar o
|
|
600
|
+
WhatsApp QR); `skipped_late` = não saiu na janela de 3h (sistema congestionado; tenta amanhã — não é
|
|
601
|
+
preciso fazer nada); `error` = falhou antes de enviar (ex.: 'conta suspensa', 'a conversa de destino
|
|
602
|
+
não existe mais', 'nenhum bloco do relatório pôde ser calculado'). Aviso criado hoje DEPOIS do
|
|
603
|
+
horário não dispara hoje (primeiro envio é amanhã) — não é defeito.
|
|
604
|
+
|
|
605
|
+
## "A prévia do Aviso fica em pending pra sempre" — 27/08
|
|
606
|
+
|
|
607
|
+
`report_alerts_preview_status` devolve `pending` enquanto o job (fila de baixa prioridade) não roda —
|
|
608
|
+
normalmente 5-60 s, até ~2-3 min com a plataforma cheia. Espere 5-10 s entre leituras; NUNCA dispare
|
|
609
|
+
outra prévia por impaciência (cada rodada com IA gasta a chave OpenAI da conta). O resultado expira
|
|
610
|
+
5 min depois de pronto: `pending` que virou `error: token inválido` = token errado/expirado, rode a
|
|
611
|
+
prévia de novo. Token tem 32 caracteres hex — confira que guardou o valor INTEIRO.
|
|
612
|
+
|
|
613
|
+
## "Mandei mensagem numa conversa cheia de histórico e a Meta recusou (131047)" — 26/08
|
|
614
|
+
|
|
615
|
+
Conversa que só tem mensagens IMPORTADAS de histórico NÃO tem janela de 24h aberta — para a Meta,
|
|
616
|
+
aquele contato nunca escreveu pela conexão oficial (a mensagem existe no painel porque a importação a
|
|
617
|
+
copiou do celular). O envio de texto livre é recusado mesmo com a fala do cliente visível na tela.
|
|
618
|
+
Saída: modelo aprovado (template) ou esperar o cliente escrever de verdade pela caixa oficial.
|
|
619
|
+
|
|
620
|
+
## "Adicionei etiqueta e as antigas sumiram" — CORRIGIDO em 24/08
|
|
621
|
+
|
|
622
|
+
Era defeito real (o segundo bloco "Adicionar etiqueta" do mesmo fluxo apagava as do primeiro, e
|
|
623
|
+
salvar status/prioridade apagava etiqueta posta por outro no meio do caminho). Hoje ADICIONAR SOMA,
|
|
624
|
+
em todos os caminhos (fluxo, IA, API, ações em massa). Se um cliente relatar isso em versão antiga
|
|
625
|
+
(whitelabel atrasado), é a versão — não oriente gambiarra de "reaplicar etiqueta".
|
|
626
|
+
|
|
627
|
+
## "Os leads do Meta chegam só com id de campanha, sem nome" — 25/08
|
|
628
|
+
|
|
629
|
+
Nome de campanha/conjunto/anúncio exige o **token de ANÚNCIOS** (é outro token, de CONTA — o login
|
|
630
|
+
da página não basta). Diagnóstico: `lionchat_meta_lead_validate_token` (sem corpo testa o salvo) diz
|
|
631
|
+
se o token é válido, de qual app e se alcança anúncio de verdade. Gravar/trocar:
|
|
632
|
+
`lionchat_meta_lead_ads_token` — ao gravar, o servidor reprocessa retroativamente os leads que
|
|
633
|
+
ficaram sem nome. E desde 25/08 o CONECTAR exige escolha: `meta_lead_create` com `page_ids` (sem
|
|
634
|
+
ele TODAS as páginas do login entram — caso real de 25 páginas numa conta); pra limpar excesso
|
|
635
|
+
antigo, `lionchat_meta_lead_bulk_destroy`.
|
|
636
|
+
|
|
637
|
+
## "Atualizei a chave da caixa oficial pelo update e ela parou de receber" — 26/08
|
|
638
|
+
|
|
639
|
+
`inboxes_update` com `channel.provider_config` SUBSTITUI o objeto inteiro: mandar só o campo
|
|
640
|
+
alterado APAGA `webhook_verify_token` e a marca `source` em silêncio — a caixa para de receber
|
|
641
|
+
webhook da Meta. Regra: leia a caixa antes (`inboxes_show`), reenvie o `provider_config` COMPLETO
|
|
642
|
+
com o campo trocado. Os três campos da conexão manual (`phone_number_id`, `business_account_id`,
|
|
643
|
+
`api_key`) são validados JUNTOS na Meta a cada gravação — 422 "Invalid Credentials" significa que
|
|
644
|
+
algum dos três está errado ou a chave venceu (não salve campo a campo).
|