@lionchat/mcp-server 1.19.1 → 1.20.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 +18 -4
- package/dist/docs/resources/assinatura-eletronica.md +75 -0
- package/dist/docs/resources/best-practices.md +26 -10
- package/dist/docs/resources/data-model.md +17 -0
- package/dist/docs/resources/filtros-e-relatorios.md +39 -1
- package/dist/docs/resources/flowbuilder-design-guide.md +54 -11
- package/dist/docs/resources/formularios-publicos.md +28 -1
- package/dist/docs/resources/glossary.md +72 -2
- package/dist/docs/resources/troubleshooting.md +45 -4
- package/dist/resources.js +6 -0
- package/dist/resources.js.map +1 -1
- package/dist/tools.js +62 -13
- package/dist/tools.js.map +1 -1
- package/endpoints.json +495 -22
- package/package.json +1 -1
|
@@ -19,9 +19,11 @@ Comprovado em produção (24/07): a sessão que dizia "não há função de list
|
|
|
19
19
|
kanban_items, funnels, flows, flow_tools, campaigns, macros, automation_rules, agents, teams,
|
|
20
20
|
inboxes, labels, canned_responses, reports, sla, csat, captain_assistants, captain_documents,
|
|
21
21
|
scheduled_messages, custom_attributes, webhooks, eclinica_integrations, tasks, notifications,
|
|
22
|
-
lead_forms (Formulários públicos de captação)
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
lead_forms (Formulários públicos de captação), signature_documents / signature_envelopes
|
|
23
|
+
(assinatura ELETRÔNICA de contratos — modelos e contratos enviados).
|
|
24
|
+
- **Fora do MCP por decisão do dono (19/08): assinatura DO PLANO (cobrança), plano, fatura, forma de
|
|
25
|
+
pagamento, cartão, saldo e recarga.** (A assinatura ELETRÔNICA de contratos é outra coisa e TEM
|
|
26
|
+
ferramentas: `lionchat_signature_*`.) Não existem ferramentas dessas áreas e não devem ser criadas. Se o usuário
|
|
25
27
|
pedir, diga que isso se resolve no painel, na área de assinatura da conta — não tente por
|
|
26
28
|
ferramenta nem por chamada direta.
|
|
27
29
|
- Só depois de pesquisar e não encontrar é que se pode dizer que a função não existe.
|
|
@@ -223,6 +225,17 @@ lionchat_conversations_messages_list (conversation_id: 123)
|
|
|
223
225
|
3. lionchat_inboxes_public_conversations_create (vincula contato à inbox)
|
|
224
226
|
```
|
|
225
227
|
|
|
228
|
+
**Telefone com ou sem o nono dígito (desde 05/09/2026):** a busca do passo 1 acha o contato
|
|
229
|
+
mesmo que ele esteja salvo na OUTRA forma do celular brasileiro (com o 9 quando você busca sem, e
|
|
230
|
+
vice-versa). Não precisa buscar duas vezes. Se mesmo assim `lionchat_contacts_create` devolver 422
|
|
231
|
+
com `attributes: ["phone_number"]`, o contato já existe — busque de novo e ATUALIZE em vez de criar.
|
|
232
|
+
Nunca tente "resolver" trocando a forma do número no create: a criação recusa as duas formas de
|
|
233
|
+
propósito (a recusa protege contra ficha em dobro).
|
|
234
|
+
**Atenção:** como a busca e o `contacts_filter` agora enxergam as duas formas, uma pessoa que tenha
|
|
235
|
+
ficha duplicada pode voltar como **2 resultados**. Nunca pegue o primeiro às cegas para
|
|
236
|
+
`contacts_update` — confira nome/e-mail ou pergunte ao usuário qual é a ficha certa. A lupa geral
|
|
237
|
+
(`lionchat_search_list`) NÃO tem essa tolerância: para telefone, use `lionchat_contacts_search`.
|
|
238
|
+
|
|
226
239
|
### Criar funil (kanban) novo com etapas
|
|
227
240
|
|
|
228
241
|
**FUNIL = KANBAN = pipeline = board — são a MESMA coisa no LionChat.** Quando o usuário pedir "cria um kanban", "monta um pipeline" ou "cria um funil", a ferramenta é `lionchat_funnels_create` (não existe endpoint separado de "criar kanban").
|
|
@@ -372,13 +385,14 @@ Antes de escolher a ferramenta, cheque se a intenção bate com a coluna da dire
|
|
|
372
385
|
|---|---|---|
|
|
373
386
|
| Listar / ver não lidas | `lionchat_conversations_list` (`conversation_type: 'unread'`) ou `lionchat_conversations_meta` | NÃO use `lionchat_conversations_unread` — é AÇÃO DE ESCRITA (marca como não-lida) |
|
|
374
387
|
| Achar a conversa **de uma pessoa/empresa** (nome, telefone, e-mail, CPF/CNPJ, nº da conversa) | `lionchat_search_list` (`/search/conversations`) ou `lionchat_contacts_search` | RÁPIDO. **NÃO use `lionchat_conversations_search`**: apesar do nome, ele é o legado que procura dentro das mensagens e leva **15 a 22 s** (medido em produção 11/08). O sufixo `_list` aqui é histórico — `lionchat_search_list*` **são buscas**, não listagens; a regra "não baixe tudo com `*_list`" vale para `lionchat_<recurso>_list` |
|
|
375
|
-
| Achar **onde foi dito** algo (palavra dentro da conversa) | `lionchat_search_list_2` (`/search/messages`) | RÁPIDO: índice trigram próprio e teto de tempo em duas fases (2 s / 14 s). É a substituta certa do `lionchat_conversations_search` |
|
|
388
|
+
| Achar **onde foi dito** algo (palavra dentro da conversa) | `lionchat_search_list_2` (`/search/messages`) | RÁPIDO: índice trigram próprio e teto de tempo em duas fases (2 s / 2 s desde 04/09 — antes a 2ª fase herdava 14 s e o pior caso da seção era 16 s). Estourou as duas, o payload volta com `message_search_interrupted: true` e a lista VAZIA — isso NÃO quer dizer que não existe, quer dizer que não deu tempo: tente de novo. É a substituta certa do `lionchat_conversations_search` |
|
|
376
389
|
| Não sei se o termo é nome de alguém ou algo dito no papo | `lionchat_search_search` (`/search`) | Cobre os dois numa chamada. Opção mais segura quando a intenção é ambígua |
|
|
377
390
|
| (qualquer busca) termo com menos de 3 caracteres | — | Volta **vazio de propósito** em todas as buscas. Vazio ≠ "não existe": quer dizer que a busca não rodou. Refaça com 3+ caracteres. Só-dígitos é isento nas rotas `/search/*`, mas **não** no `lionchat_conversations_search` legado |
|
|
378
391
|
| Só a contagem / números | `lionchat_conversations_meta` / `lionchat_reports_summary` | Não liste o conteúdo completo |
|
|
379
392
|
| Criar contato | `lionchat_contacts_create` base (path `/contacts`) | NÃO use as variantes `_1` … `_9` |
|
|
380
393
|
| Pausar a IA agora (botão de pânico) | `lionchat_captain_assistants_update` (`paused: true`, top-level) | — |
|
|
381
394
|
| Criar/editar **formulário público de captação** (página de captura própria) | `lionchat_lead_forms_create` / `_update` | Leia `lionchat://docs/formularios-publicos` ANTES — o desenho vai em `form_data` e só entra no ar depois do `publish` (que valida o desenho e pode voltar 422 com a lista de pendências). Caixa de WhatsApp vinculada (`inbox_id`) é obrigatória pra publicar. Escrita é só de administrador |
|
|
395
|
+
| **Mandar um contrato pra assinar** / ver quem assinou / reenviar / cancelar / criar ou editar o modelo escrito | `lionchat_signature_envelopes_create` / `_list` / `_show` / `_resend` / `_cancel`; `lionchat_signature_documents_list` / `_create` / `_update`; `lionchat_signature_envelopes_sign_as_sender` (o remetente assina pelo painel) | Leia `lionchat://docs/assinatura-eletronica` ANTES. Modelo `text` a API cria e edita (texto com `{{contact.*}}`); PDF/Word só pela tela. Campo do modelo sem valor na ficha bloqueia o envio (422 `variaveis_sem_valor` com a lista); `422 escolher_caixa` = repita com `inbox_id`. Cada contrato consome 1 vaga do limite mensal. Modelo Word: `422 fila_cheia` = muita gente convertendo agora, repita em instantes; `422 conversor_indisponivel` = o serviço de conversão está fora (não é o arquivo) — avise o operador. Remetente assina pelo painel com `_sign_as_sender` (PNG em base64). Importar Word, pré-visualizar e baixar PDF: só pela tela (o conector não envia arquivo nem recebe PDF) |
|
|
382
396
|
| **Testar um formulário** antes de publicar | `lionchat_lead_forms_test_run` | Roda o RASCUNHO no motor real e desfaz tudo no fim — zero rastro. Mande `answers: [{node_id, value}]` (até 60) pra reproduzir um caminho; a resposta traz o bloco atual + o log do percurso |
|
|
383
397
|
| Conferir se um site **aceita ser exibido dentro do formulário** (bloco Página externa) | `lionchat_lead_forms_check_embed` | Body `{url}`; devolve `{status: allowed\|blocked\|unknown, reason}`. Grave o veredito em `embed_allowed` do bloco. Admin-only |
|
|
384
398
|
| Ver **tudo que uma pessoa preencheu** (nosso formulário, anúncio do Meta, Webhook Universal, fluxo) | `lionchat_contacts_form_entries_list` / `_show` | Por CONTATO, sem paginação (teto 250 por origem, `meta.truncated`). O detalhe de Meta/webhook mostra SÓ os campos vinculados e gravados — nunca o payload cru. `show` exige `source` + `id` da mesma linha |
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Assinatura eletrônica de contratos
|
|
2
|
+
|
|
3
|
+
**Não confundir com "assinatura" de PLANO/cobrança** (fatura, cartão, saldo) — essa área fica fora do MCP.
|
|
4
|
+
Aqui é a **assinatura eletrônica de documentos**: o cliente assina um contrato pelo WhatsApp (ou e-mail),
|
|
5
|
+
com código de uso único, e o LionChat guarda a prova (IP, aparelho, localização, hash, PDF selado).
|
|
6
|
+
Feature `document_signing` (ligada por conta; 403 `feature_disabled` quando desligada).
|
|
7
|
+
|
|
8
|
+
## As três camadas
|
|
9
|
+
|
|
10
|
+
| Camada | O que é | Ferramentas |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| **Modelo** (`signature_documents`) | O contrato padrão, escrito uma vez com `{{variáveis}}` da ficha. `kind`: `text` (escrito no editor — o único que a API cria), `file` (PDF pronto, igual pra todos) ou `word` (.docx que sai idêntico com os campos mapeados) — os dois últimos só pela tela (upload). | `lionchat_signature_documents_list/show/create/update/destroy/field_catalog` |
|
|
13
|
+
| **Contrato** (`signature_envelopes`) | Cada ENVIO a uma pessoa: PDF próprio com os dados dela, prazo, linha do tempo. | `lionchat_signature_envelopes_list/show/create/resend/cancel/limits` |
|
|
14
|
+
| **Participante** | Quem assina dentro de um contrato: `signer` (titular, pode ser mais de um), `witness` (testemunha, opcional), `sender` (o remetente, quando o modelo tem "eu também assino" — assina NO PAINEL, sem link). Cada um tem link e código próprios. | dentro do contrato (`participants[]`) |
|
|
15
|
+
|
|
16
|
+
## Estados do contrato (`status`) e os baldes de filtro
|
|
17
|
+
|
|
18
|
+
| Balde (`status` na listagem) | Estados | Significado |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| `aguardando` | `draft`, `sent` | criado sem entrega (draft) ou enviado e ainda não aberto |
|
|
21
|
+
| `visualizado` | `viewed`, `partially_signed` | abriu o link / parte das pessoas já assinou |
|
|
22
|
+
| `assinado` | `signed_pending_seal`, `signed` | todos assinaram; selando / documento final pronto |
|
|
23
|
+
| `encerrado` | `refused`, `cancelled`, `expired` | recusado / cancelado pela equipe / prazo venceu |
|
|
24
|
+
| `falta_eu` | — | contratos abertos em que o usuário do token é o remetente e ainda não assinou |
|
|
25
|
+
|
|
26
|
+
Participante: `pending` → `viewed` → `verified` (confirmou o código) → `signed` | `refused`.
|
|
27
|
+
|
|
28
|
+
## Linha do tempo (`events[].kind`)
|
|
29
|
+
`created` · `delivered` (link entregue a uma pessoa) · `sent` · `opened` (cada abertura) · `code_requested` ·
|
|
30
|
+
`code_verified` · `signed` (com `ip`, `device`, `location`; `panel: true` = assinou no painel) · `all_signed` ·
|
|
31
|
+
`sealed` (documento final gerado, `sealed_sha256`) · `refused` · `cancelled` · `expired` · `delivery_failed`
|
|
32
|
+
(motivo em `delivery.failed[]`) · `reminded` · `resent`. Tudo append-only — é o relatório de evidências.
|
|
33
|
+
|
|
34
|
+
## Como mandar um contrato (receita)
|
|
35
|
+
1. `lionchat_signature_documents_list` → escolha o modelo (ou crie um `text` com `signature_documents_create`;
|
|
36
|
+
variáveis em `signature_documents_field_catalog`).
|
|
37
|
+
2. Confira a ficha: toda `{{variável}}` do modelo precisa ter valor no contato (nome, CPF, endereço…) —
|
|
38
|
+
senão o envio volta `422 variaveis_sem_valor` com a lista do que falta.
|
|
39
|
+
3. `lionchat_signature_envelopes_create` com `signature_document_id`, `contact_id` e `participants`
|
|
40
|
+
(`[{name, role: 'signer', phone, delivery_channel: 'whatsapp', contact_id}]`; testemunha = mais um item
|
|
41
|
+
com `role: 'witness'` e o telefone dela).
|
|
42
|
+
4. `422 escolher_caixa` → a pessoa conversa em mais de uma caixa de WhatsApp: repita com `inbox_id`.
|
|
43
|
+
5. Acompanhe com `signature_envelopes_show` (linha do tempo) ou `signature_envelopes_list`
|
|
44
|
+
(`contact_id`, `status`, `q`). Não chegou? `resend`. Errou? `cancel` (admin). Falta a SUA assinatura
|
|
45
|
+
(modelo com "eu também assino")? `signature_envelopes_sign_as_sender` — ver regra abaixo.
|
|
46
|
+
|
|
47
|
+
## Regras que valem sempre
|
|
48
|
+
- **Quem pode**: administrador ou cargo personalizado com "Gerenciar Assinaturas" (`signature_manage`) — vale para
|
|
49
|
+
criar/editar modelo, prévia, enviar, reenviar, baixar e "eu também assino" (403 sem a chave). A LISTA de modelos e a
|
|
50
|
+
leitura de um modelo continuam abertas a qualquer membro. Cancelar contrato e apagar modelo: só administrador.
|
|
51
|
+
- **Trava sagrada**: campo do modelo sem valor na ficha bloqueia o envio. Preencher a ficha primeiro.
|
|
52
|
+
- **Validade** (`roles_layout.validity_days`, padrão 7) conta do ENVIO; `{{document.deadline}}` imprime a data no
|
|
53
|
+
texto; passou = `expired` (cron de hora em hora). **Lembrete** (`reminder_days`, padrão 2, 0 = off): quem não
|
|
54
|
+
assinou recebe o link de novo a cada N dias.
|
|
55
|
+
- **Conversor de Word** é um serviço separado (docx-converter). Fora do ar = `422 conversor_indisponivel` na prévia e no envio de modelo Word — é o serviço, não o arquivo; repetir em instantes. Modelos `text` e `file` não passam por ele.
|
|
56
|
+
- **Fila única de conversão do Word**: uma conversão por vez em toda a instalação (todas as contas); pela tela espera-se até 10 s, automação/macro/fluxo/formulário até 2 s.
|
|
57
|
+
Passou disso o envio/prévia volta `422 fila_cheia` — é só repetir em instantes (o modelo está bom).
|
|
58
|
+
- **Limite mensal** (`signature_envelopes_limits`): cada contrato criado consome 1 vaga; cancelar não devolve.
|
|
59
|
+
- **PDFs** (original, assinado, evidências) e o **QR de conferência** só existem pela tela/download autenticado —
|
|
60
|
+
não há ferramenta que devolva os bytes. O `sealed_sha256` é o hash do documento final.
|
|
61
|
+
- **Só pela tela, de propósito** (existem na API, mas NÃO como ferramenta): importar um Word (`import_docx`),
|
|
62
|
+
pré-visualizar modelo ou rascunho (`preview`, `preview_draft`) e baixar PDF (`download`). O conector não envia
|
|
63
|
+
arquivo nem recebe PDF — não prometa "vou gerar a prévia" ou "vou baixar o assinado"; oriente a tela.
|
|
64
|
+
- **Assinar no painel** ("eu também assino", 08/09): `lionchat_signature_envelopes_sign_as_sender` assina como o
|
|
65
|
+
REMETENTE (a pessoa do token) — nunca no lugar do cliente. Manda `signature_image` (PNG em base64 com prefixo
|
|
66
|
+
`data:image/png;base64,...`), opcional `location {latitude, longitude, accuracy}` (vai pra prova) e
|
|
67
|
+
`remember_drawing`. 422: `nao_e_sua` (não é o remetente deste contrato), `ja_assinado`, `sem_desenho`. Era a
|
|
68
|
+
última que faltava? o contrato fecha e o PDF final é gerado em seguida. Os que esperam você: `status=falta_eu`.
|
|
69
|
+
- **Envio por outros caminhos**: ação `send_signature_document` no FlowBuilder, na Macro e na Automação;
|
|
70
|
+
bloco `generate_contract` no Formulário público (gera pelas respostas e manda o link). Gatilhos do Flow
|
|
71
|
+
`signature_*` (8 acontecimentos) trazem `{{contrato.*}}` — ver `lionchat_flows_schema_reference`.
|
|
72
|
+
|
|
73
|
+
## Onde o cliente vê
|
|
74
|
+
Menu **Assinaturas** (modelos e contratos, filtros, "Falta você assinar"), aba **Contratos** na ficha do contato,
|
|
75
|
+
pílulas na conversa a cada acontecimento e avisos no sininho para quem enviou.
|
|
@@ -160,11 +160,11 @@ Travas que valem conhecer (não dá pra desligar):
|
|
|
160
160
|
## Limite do prompt e cache OpenAI (2026-05-22)
|
|
161
161
|
|
|
162
162
|
- `config.instructions` (system prompt do agente) aceita até **20.000 caracteres** (antes 10k). Acima de 15k, o frontend mostra aviso "lost in the middle" — prefira colocar instruções críticas no início ou final.
|
|
163
|
-
- **Cache automático** ativo em todos os
|
|
163
|
+
- **Cache automático** ativo em todos os 19 modelos oferecidos na plataforma. Desconto 50-75% no input cachado, sem configuração. Reuso do prompt do agente em múltiplas conversas maximiza a economia.
|
|
164
164
|
|
|
165
165
|
### Lista real de modelos (`config.model`)
|
|
166
166
|
|
|
167
|
-
Estes são os
|
|
167
|
+
Estes são os 19 valores que o seletor de modelo do painel oferece (`ModelSelector.vue`). Só recomende
|
|
168
168
|
valores desta lista:
|
|
169
169
|
|
|
170
170
|
| Faixa | Modelos |
|
|
@@ -172,18 +172,21 @@ valores desta lista:
|
|
|
172
172
|
| Econômicos / rápidos | `gpt-4.1-nano`, `gpt-4o-mini`, `gpt-4.1-mini`, `gpt-5.4-nano`, `gpt-5.4-mini` |
|
|
173
173
|
| Intermediários | `gpt-4o`, `gpt-4.1`, `gpt-5-mini`, `gpt-5.4` |
|
|
174
174
|
| Raciocínio | `o3-mini`, `o4-mini` |
|
|
175
|
-
| Premium | `gpt-5`, `gpt-5.2`, `gpt-5.5`, `o1`, `o3` |
|
|
175
|
+
| Premium | `gpt-5`, `gpt-5.2`, `gpt-5.5`, `gpt-5.6-luna`, `gpt-5.6-terra`, `gpt-5.6-sol`, `o1`, `o3` |
|
|
176
176
|
|
|
177
177
|
**`GPT-5.2 Pro` não existe.** O valor válido é `gpt-5.2`, sem "Pro".
|
|
178
178
|
|
|
179
|
-
> **
|
|
180
|
-
>
|
|
181
|
-
>
|
|
182
|
-
>
|
|
183
|
-
> **
|
|
179
|
+
> **Família `gpt-5.6` (`gpt-5.6-luna`, `gpt-5.6-terra`, `gpt-5.6-sol`) — LIBERADA em 09/2026.**
|
|
180
|
+
> Foi removida em 29/07/2026 porque recusa function tools no canal antigo da OpenAI e deixava a IA MUDA.
|
|
181
|
+
> Desde 09/2026 o servidor fala com esses três pela porta `/v1/responses` (só para eles — nenhum outro
|
|
182
|
+
> modelo muda de canal). Podem ser gravados em `config.model` do assistente, no Copilot e no bloco de IA do
|
|
183
|
+
> Flow. **Recusam temperatura personalizada: `config.temperature` é ignorada** (só o padrão). O `sol` custa
|
|
184
|
+
> ~5x o `luna` — recomende o `luna` salvo pedido explícito. **NUNCA no bloco de IA do Formulário de Lead**
|
|
185
|
+
> (teto de 15 s; o servidor exclui e cai no fallback).
|
|
184
186
|
>
|
|
185
|
-
>
|
|
186
|
-
>
|
|
187
|
+
> Desde 09/2026 o campo `config.model` **tem lista branca no servidor** (`LlmConstants::SELECTABLE_MODELS`):
|
|
188
|
+
> trocar para um modelo fora da lista devolve **422** (`model is not included in the list`). Registro
|
|
189
|
+
> antigo com modelo fora da lista continua salvando os outros campos; só a troca é recusada.
|
|
187
190
|
> Desde 29/07 o erro vira uma **nota privada em português** na conversa (`llm_request_rejected`) — é o
|
|
188
191
|
> primeiro lugar a olhar quando "a IA parou de responder logo depois de mexerem nas configurações".
|
|
189
192
|
|
|
@@ -872,3 +875,16 @@ Custom attribute em lugar errado vira:
|
|
|
872
875
|
passageiro — o socorro cuida; reenviar por cima entrega em dobro.
|
|
873
876
|
- **Filtros de data fixa cortam o dia no fuso da CONTA** (padrão America/Sao_Paulo) — e mudar o
|
|
874
877
|
`timezone` da conta move essa fronteira.
|
|
878
|
+
|
|
879
|
+
## Editar o PRÓPRIO agente (02/09/2026)
|
|
880
|
+
|
|
881
|
+
`agents_update` passou a aceitar que a pessoa edite a si mesma — **times e caixas liberados**. Antes
|
|
882
|
+
nem a tela oferecia: um administrador não conseguia se colocar nem se tirar de um time ou de uma caixa.
|
|
883
|
+
|
|
884
|
+
**A trava:** ninguém muda o próprio **cargo** (nem o perfil base, nem o cargo personalizado). O
|
|
885
|
+
servidor recusa com 422 e a mensagem *"Você não pode alterar o próprio cargo. Peça a outro
|
|
886
|
+
administrador."* — a recusa é `before_action`, então NADA do resto do update é aplicado junto.
|
|
887
|
+
|
|
888
|
+
Ao atualizar o próprio usuário: mande times e caixas à vontade; **não mande `role` nem
|
|
889
|
+
`custom_role_id`** — se mandar, a chamada inteira falha e as outras alterações se perdem também.
|
|
890
|
+
Para trocar o cargo de alguém, use a conta de OUTRO administrador.
|
|
@@ -724,3 +724,20 @@ Os limites que a API devolve (`resource_limits.*` da conta, `email_usage.limit`,
|
|
|
724
724
|
duas contas no MESMO plano podem ter limites diferentes — não é defeito. Limite `0` significa
|
|
725
725
|
ILIMITADO em toda a plataforma. A contratação/remoção de adicionais é feita SÓ pela tela de
|
|
726
726
|
Cobrança do painel (não há ferramenta MCP para isso, por decisão do dono).
|
|
727
|
+
|
|
728
|
+
## Assinatura eletrônica de contratos (04/09)
|
|
729
|
+
|
|
730
|
+
```
|
|
731
|
+
SignatureDocument (modelo) 1 ──── N SignatureEnvelope (contrato de UMA pessoa) 1 ──── N SignatureParticipant
|
|
732
|
+
name, kind (text|file|word) title, status, sent_at, expires_at, name, role (signer|witness|sender),
|
|
733
|
+
body ({{variáveis}}), tags, contact_id, conversation_id, status, phone/email, delivery_channel,
|
|
734
|
+
roles_layout {signers, witnesses, original_sha256, sealed_sha256, conversation_id (a conversa DELE),
|
|
735
|
+
sender_signs, require_id_photo, created_by (quem mandou) public_url, signed_at, viewed_at
|
|
736
|
+
validity_days, reminder_days} │
|
|
737
|
+
progress (contagem por balde) └── N SignatureEvent (append-only: kind, occurred_at, ip, user_agent, detail)
|
|
738
|
+
```
|
|
739
|
+
- Contrato aponta pro contato (`contact_id`, nulifica se a ficha for apagada — a prova sobrevive) e pra conversa
|
|
740
|
+
do titular; cada participante tem a PRÓPRIA conversa (testemunha na dela).
|
|
741
|
+
- `roles_layout` é jsonb aberto e MESCLADO no update; `progress` é calculado (aguardando/visualizado/assinado/encerrado).
|
|
742
|
+
- Feature por conta: `document_signing`. Limite mensal em `usage_limits.signature_requests_per_month` (0 = ilimitado).
|
|
743
|
+
- Detalhe completo: resource `lionchat://docs/assinatura-eletronica`.
|
|
@@ -79,7 +79,7 @@ Mesmo shape de condição. 15/página.
|
|
|
79
79
|
|---|---|
|
|
80
80
|
| `id` (id interno do contato) | equal_to, not_equal_to |
|
|
81
81
|
| `name`, `email`, `identifier`, `city`, `company`, `profession` | equal_to, not_equal_to, contains, does_not_contain |
|
|
82
|
-
| `phone_number` | + starts_with (busca por DDD/prefixo) — **corrigido na atualização de 26/07/2026**; em instalação anterior devolve SEMPRE lista vazia (virava igualdade exata). Vazio com prefixo que existe = instalação antiga |
|
|
82
|
+
| `phone_number` | + starts_with (busca por DDD/prefixo) — **corrigido na atualização de 26/07/2026**; em instalação anterior devolve SEMPRE lista vazia (virava igualdade exata). Vazio com prefixo que existe = instalação antiga. **`equal_to`/`not_equal_to` casam as DUAS formas do celular BR (com e sem o 9º dígito) desde 05/09/2026** — mande `+5541999887766` ou `+554199887766`, os dois acham a mesma ficha; `not_equal_to` exclui as duas. Termo que não é celular BR completo (fixo, estrangeiro, trecho) segue exato |
|
|
83
83
|
| `cpf`, `cnpj`, `rg` (cadastral) | equal_to, not_equal_to, contains, does_not_contain, is_present, is_not_present |
|
|
84
84
|
| `country_code` | equal_to, not_equal_to |
|
|
85
85
|
| `labels` | equal_to, not_equal_to, is_present, is_not_present |
|
|
@@ -297,3 +297,41 @@ número/data em texto; array-de-objetos em query (padrão B exige JSON-string);
|
|
|
297
297
|
`custom_attribute_type` quando contato e conversa têm atributo de mesmo nome; esperar paginação
|
|
298
298
|
no kanban_items_filter (não tem — estreite o filtro); montar um `custom_dashboards_update` em cima
|
|
299
299
|
de uma listagem que veio cortada (apaga os blocos que não chegaram).
|
|
300
|
+
|
|
301
|
+
## Filtro de DATA do Kanban (02/09/2026) — `kanban_items_filter` e `funnels_stage_report`
|
|
302
|
+
|
|
303
|
+
Quatro eixos de data, cada um com **janela fixa** (`_start`/`_end`, ISO) OU **atalho relativo**
|
|
304
|
+
(`_relative` + `_relative_days`). Formato FLAT (o Kanban não usa o shape `payload` dos outros filtros).
|
|
305
|
+
|
|
306
|
+
| Eixo | Chaves | O que recorta |
|
|
307
|
+
|---|---|---|
|
|
308
|
+
| Criação do card | `date_start`/`date_end` · `date_relative`/`date_relative_days` | quando o card foi criado |
|
|
309
|
+
| Entrada na etapa | `stage_date_start`/`_end` · `stage_date_relative`/`_days` | quando entrou na etapa ATUAL |
|
|
310
|
+
| Atualização | `updated_date_start`/`_end` · `updated_date_relative`/`_days` | última alteração do card |
|
|
311
|
+
| Ganho/perdido em | `closed_date_start`/`_end` · `closed_date_relative`/`_days` | data do desfecho |
|
|
312
|
+
|
|
313
|
+
**Operadores do atalho** (`*_relative`): `today`, `yesterday`, `last_days`, `days_ago`, `days_before`.
|
|
314
|
+
- `today` e `yesterday` **não levam número** — não mande `_relative_days` com eles.
|
|
315
|
+
- `last_days` = os últimos N dias **incluindo hoje** (N=7 → de 6 dias atrás até o fim de hoje).
|
|
316
|
+
- `days_ago` = o dia exato de N dias atrás. `days_before` = mais de N dias atrás (janela aberta à esquerda).
|
|
317
|
+
- **N inteiro de 1 a 998.** Texto, zero, negativo, decimal ou maior que 998 é recusado.
|
|
318
|
+
- A janela é calculada no **fuso da conta** (não em UTC).
|
|
319
|
+
|
|
320
|
+
Os quatro eixos são independentes e podem ser combinados. Janela fixa e atalho no mesmo eixo:
|
|
321
|
+
mande só um dos dois.
|
|
322
|
+
|
|
323
|
+
> **CUIDADO — operador inválido NÃO dá erro, ALARGA o resultado.** Se `*_relative` vier com um
|
|
324
|
+
> operador fora da lista, ou `last_days`/`days_ago`/`days_before` sem número válido, o atalho é
|
|
325
|
+
> **ignorado em silêncio**: a resposta volta com MAIS cards (até 5.000) e a tela ainda mostra o selo
|
|
326
|
+
> de "filtrado". Como o quadro tem **ação em massa, inclusive excluir**, nunca use o retorno de um
|
|
327
|
+
> filtro de data para uma ação destrutiva sem conferir a contagem antes. (Em condição de ATRIBUTO o
|
|
328
|
+
> comportamento é o oposto e seguro: valor inválido fecha o filtro e devolve vazio.)
|
|
329
|
+
|
|
330
|
+
Exemplo — cards que entraram na etapa atual nos últimos 7 dias, no funil 12:
|
|
331
|
+
```json
|
|
332
|
+
{ "funnel_id": 12, "stage_date_relative": "last_days", "stage_date_relative_days": 7 }
|
|
333
|
+
```
|
|
334
|
+
Cards ganhos ou perdidos ontem:
|
|
335
|
+
```json
|
|
336
|
+
{ "closed_date_relative": "yesterday" }
|
|
337
|
+
```
|
|
@@ -385,6 +385,16 @@ só pra destravar, ela pode sair.
|
|
|
385
385
|
| `pagetrack_visited` / `pagetrack_event` | LionTrack |
|
|
386
386
|
| `sla_check` | status do SLA da conversa (usa `value` = código fixo; ver abaixo) |
|
|
387
387
|
|
|
388
|
+
> **ATENÇÃO — onde o VALOR vai (defeito real de 02/09/2026, conta 137):** no nó **Condição**, uma regra de atributo
|
|
389
|
+
> (`valueType: "attr_config"`) com operador `equal`, `not_equal`, `contains` ou `not_contains` guarda o valor em
|
|
390
|
+
> **`values: ["..."]` (lista)** e deixa `value: ""`. A TELA lê SÓ a lista: regra gravada com `value: "paid_ad"` e
|
|
391
|
+
> sem `values` roda certa no motor mas abre com a caixa de valor **VAZIA** — o cliente conclui que não foi
|
|
392
|
+
> configurado. Só `greater_than`, `less_than`, `starts_with` e `ends_with` usam `value` (campo único);
|
|
393
|
+
> `number_range` usa `value: "min-max"`; `is_empty`/`is_not_empty` não têm valor. Grave sempre o shape completo:
|
|
394
|
+
> `{ "id": 1, "field": "{{last_response}}", "operator": "equal", "value": "", "values": ["paid_ad"],
|
|
395
|
+
> "valueType": "attr_config", "attrSource": "conversation", "attrScope": "campaign", "attr_key": "origin_kind",
|
|
396
|
+
> "funnel_id": "", "stage": "" }` dentro de `rules`, com o branch repetindo `value`/`values`/`valueType`.
|
|
397
|
+
|
|
388
398
|
**Restrição por TIPO de atributo (a UI só oferece um subconjunto, e é o que faz sentido):**
|
|
389
399
|
- **Texto/string:** `equal`, `not_equal`, `contains`, `not_contains`, `starts_with`, `ends_with`, `is_empty`, `is_not_empty`
|
|
390
400
|
- **Número:** `equal`, `not_equal`, `greater_than`, `less_than`, `number_range`, `is_empty`, `is_not_empty`
|
|
@@ -427,6 +437,8 @@ campanha"):
|
|
|
427
437
|
- Caso real (Cast, 01/09): flow "Ativar IA" só para lead de anúncio = condição `origin_kind equal paid_ad`
|
|
428
438
|
na saída `cond_0` + ação `assign_captain` nessa saída; `default` sem nada.
|
|
429
439
|
|
|
440
|
+
- **`attrScope: "lead_origin"` (02/09/2026):** preset "Origem do lead" da aba Conversas — mesmo shape do `campaign_attr`, ja nasce com `attr_key: "origin_platform"`. Valores: plataformas fixas (`facebook`, `google`...) ou origem cadastrada como `custom:<slug>`. O motor ignora `attrScope`; sem ele a regra reabre como "Atributo de campanha" (falha macia).
|
|
441
|
+
|
|
430
442
|
**Agente de IA — `conversation_has_ai_agent` e irmãos (novo 2026-08-01):** o flow sempre soube LIGAR e
|
|
431
443
|
DESLIGAR a IA (ações `assign_captain` / `deactivate_captain`), mas não sabia PERGUNTAR se ela estava
|
|
432
444
|
ligada. Agora sabe. É o espelho exato do trio do agente humano:
|
|
@@ -504,7 +516,7 @@ o botão "Usar variável" ao lado do campo alterna lista fixa ↔ variável.
|
|
|
504
516
|
| `remove_conversation_label` | `{ labels: ['slug'] }` | Remove labels da CONVERSA |
|
|
505
517
|
| `mute_conversation` | `{}` | Silencia notificações |
|
|
506
518
|
| `mark_unread` | `{}` | Marca a conversa como NÃO LIDA pro time (espelho do `mute_conversation`; típico logo após `assign_agent`/`assign_team` numa transferência) |
|
|
507
|
-
| `add_private_note` | `{
|
|
519
|
+
| `add_private_note` | `{ text: 'texto' }` | Adiciona nota interna. **A chave é `text`** — é a que o formulário do bloco lê (`v-model="item.config.text"`). Até 04/09 esta linha dizia `content`, e por isso 56 blocos de 8 contas abriam VAZIOS na tela: a nota era gravada (o motor tem rede) mas ninguém conseguia ler nem editar o texto. `content` continua sendo aceito e normalizado para `text` na gravação |
|
|
508
520
|
| `create_kanban_item` | `{ funnel_id, funnel_stage, title?, description? }` | Cria card no Kanban — `funnel_id` e `funnel_stage` OBRIGATÓRIOS; `title`/`description` aceitam variáveis `{{ }}` |
|
|
509
521
|
| `move_kanban_item_to_stage` | `{ funnel_stage }` | Move card (precisa ter card vinculado) |
|
|
510
522
|
| `move_kanban_stage` | `{ funnel_id, funnel_stage }` | Idem |
|
|
@@ -512,12 +524,12 @@ o botão "Usar variável" ao lado do campo alterna lista fixa ↔ variável.
|
|
|
512
524
|
| `set_won` | `{}` | Atalho pra ganho |
|
|
513
525
|
| `set_lost` | `{ reason? }` | Atalho pra perdido |
|
|
514
526
|
| `assign_agent_card` | `{ agent_id, mode? }` | Responsável do card. `mode`: `'add'` (default — SOMA na lista), `'replace'` (só o escolhido fica; atribui antes de remover os demais) ou `'remove_all'` (tira TODOS os responsáveis; `agent_id` dispensado) |
|
|
515
|
-
| `add_card_note` | `{
|
|
527
|
+
| `add_card_note` | `{ text }` | Nota no card. **A chave é `text`**, igual à irmã `add_private_note`. Aqui é mais grave: o motor lê SÓ `text`, sem rede — nota criada com `content` sairia REALMENTE vazia, não só invisível no formulário. Corrigido em 04/09 (a linha dizia `content`); a gravação normaliza `content` para `text` |
|
|
516
528
|
| `add_card_checklist` | `{ template_id, funnel_id?, card_source? }` | Aplica um MODELO de checklist ao card (vira um grupo). `template_id` de `kanban_config.checklist_templates`. Um modelo por bloco (repita o bloco pra mais de um) |
|
|
517
529
|
| `add_card_offer` | `{ offer_id, use_custom_value?, custom_value?, funnel_id?, card_source? }` | Adiciona uma OFERTA (produto/serviço) ao card. `offer_id` de `offers_list`. `use_custom_value: true` + `custom_value` grava um valor personalizado na oferta; senão usa o valor cadastrado. O total do card recalcula sozinho (soma das ofertas). Respeita `card_source` (funnel só localiza o card) |
|
|
518
530
|
| `send_webhook` | `{ url, headers?, body? }` | Dispara webhook externo |
|
|
519
531
|
| `start_flow` | `{ flow_id }` | Inicia outro fluxo. **NÃO encerra o fluxo de origem** (desde 31/08): se houver bloco ligado depois dele, o fluxo SEGUE normalmente. Sendo o último do desenho, o fluxo termina ali como sempre. |
|
|
520
|
-
| `send_conversion` (novo 2026-09-01) | `{ destinations: ['meta'\|'ga4'\|'google_ads'], event_name, value? }` | Manda o evento de conversão pro Meta (CAPI), Google Ads e/ou GA4 — o mesmo caminho do Funil, de dentro do fluxo. Aba Sistema (só flow `conversation`). Ver bloco próprio abaixo |
|
|
532
|
+
| `send_conversion` (novo 2026-09-01; `event_names` 2026-09-02) | `{ destinations: ['meta'\|'ga4'\|'google_ads'], event_names: { meta?, google_ads?, ga4? }, event_name (reserva), value? }` | Manda o evento de conversão pro Meta (CAPI), Google Ads e/ou GA4 — o mesmo caminho do Funil, de dentro do fluxo. Aba Sistema (só flow `conversation`). Ver bloco próprio abaixo |
|
|
521
533
|
| `deactivate_flow` ou `disable_flow` | `{}` | Encerra fluxo atual |
|
|
522
534
|
| `update_attribute` | `{ attr_source: 'contact'\|'conversation'\|'card', attr_key, attr_value }` | Seta custom_attribute (ver abaixo) |
|
|
523
535
|
| `assign_captain` (ou `assign_captain_assistant`) | `{ assistant_id }` | Atribui IA Captain |
|
|
@@ -530,7 +542,7 @@ o botão "Usar variável" ao lado do campo alterna lista fixa ↔ variável.
|
|
|
530
542
|
**`send_conversion` — Enviar conversão (2026-09-01):**
|
|
531
543
|
|
|
532
544
|
```json
|
|
533
|
-
{ "key": "send_conversion", "config": { "destinations": ["meta", "google_ads"], "event_name": "Lead", "value": "1500,50" } }
|
|
545
|
+
{ "key": "send_conversion", "config": { "destinations": ["meta", "google_ads"], "event_names": { "meta": "Lead", "google_ads": "Contact" }, "event_name": "Lead", "value": "1500,50" } }
|
|
534
546
|
```
|
|
535
547
|
|
|
536
548
|
- `destinations`: array com `meta`, `ga4` e/ou `google_ads` — **OBRIGATÓRIO e não vazio** (vazio = a ação
|
|
@@ -539,7 +551,11 @@ o botão "Usar variável" ao lado do campo alterna lista fixa ↔ variável.
|
|
|
539
551
|
(o histórico do fluxo mostra "GA4: pulado (integração não configurada, evento não mapeado ou pausado)").
|
|
540
552
|
Confira antes com `lionchat_meta_pixel_integrations_list`, `lionchat_google_ads_integrations_list`,
|
|
541
553
|
`lionchat_ga4_integrations_list`.
|
|
542
|
-
- `
|
|
554
|
+
- `event_names` (**desde 2026-09-02**): um evento POR destino marcado — `{ "meta": "Lead", "google_ads": "Contact", "ga4": "generate_lead" }`.
|
|
555
|
+
Chave presente e em branco = aquele destino é PULADO ("sem nome de evento"); chave ausente cai em `event_name`.
|
|
556
|
+
Google Ads só envia evento que tenha ação mapeada na integração; a tela lista Meta (padrão + personalizados
|
|
557
|
+
da conta) e Google Ads (mapeados), GA4 é livre. Grave sempre `event_names` E `event_name` (= primeiro nome).
|
|
558
|
+
- `event_name`: reserva/compatibilidade (fluxos de antes de 02/09), só letras/números/sublinhado (até 40; ex.: `Lead`, `Schedule`,
|
|
543
559
|
`Purchase`); aceita variável `{{ }}`. No **Google Ads** o nome precisa estar mapeado no
|
|
544
560
|
`conversion_action_map` da integração, senão é pulado.
|
|
545
561
|
- `value` (opcional): número (vírgula BR aceita, `1500,50`) ou variável. **Vazio = valor do CARD** (ver
|
|
@@ -656,13 +672,15 @@ aiModel nos modos novos (proteção de nós antigos que carregam aiModel de defa
|
|
|
656
672
|
padrão da conta).
|
|
657
673
|
Exemplo: `{"aiMode":"sentiment","aiAssistantId":"12","aiModel":"gpt-4.1-mini","aiModelExplicit":true}`.
|
|
658
674
|
|
|
659
|
-
**A whitelist (`FlowBuilder::RawLlmService::SUPPORTED_MODELS`) é uma lista FECHADA de
|
|
675
|
+
**A whitelist (`FlowBuilder::RawLlmService::SUPPORTED_MODELS`) é uma lista FECHADA de 19 nomes, SEM
|
|
660
676
|
curinga** — não existe "a família gpt-5 inteira":
|
|
661
677
|
`gpt-4o-mini`, `gpt-4o`, `gpt-4.1-nano`, `gpt-4.1-mini`, `gpt-4.1`, `gpt-5-mini`, `gpt-5`,
|
|
662
|
-
`gpt-5.2`, `gpt-5.4-nano`, `gpt-5.4-mini`, `gpt-5.4`, `gpt-5.5`, `
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
678
|
+
`gpt-5.2`, `gpt-5.4-nano`, `gpt-5.4-mini`, `gpt-5.4`, `gpt-5.5`, `gpt-5.6-luna`, `gpt-5.6-terra`,
|
|
679
|
+
`gpt-5.6-sol`, `o1`, `o3`, `o3-mini`, `o4-mini`.
|
|
680
|
+
A família **`gpt-5.6` (luna/terra/sol) voltou em 09/2026** (tinha sido removida em 2026-07-29 porque
|
|
681
|
+
recusa function tools no canal antigo): o servidor fala com esses três pela porta `/v1/responses`.
|
|
682
|
+
Eles ignoram a temperatura do bloco (só o padrão) e **NÃO valem no bloco de IA do Formulário de Lead**
|
|
683
|
+
(teto de 15 s — o servidor exclui e usa o fallback). Também não existem `o1-mini`, `gpt-4.5-preview`,
|
|
666
684
|
`gpt-5.2-pro` nem `gpt-5.5-pro` (a OpenAI recusa).
|
|
667
685
|
|
|
668
686
|
**OBRIGATÓRIO via API — `aiAssistantId`:** os modos `generate`/`intent`/`sentiment`/`extract`
|
|
@@ -928,10 +946,35 @@ Node terminal, sem handles de saída. **EXCLUSIVO de flow `ai_tool`** — NUNCA
|
|
|
928
946
|
no último node, sem node de fim. Em `ai_tool` é OBRIGATÓRIO: o `data` do `end` define o que
|
|
929
947
|
volta pro LLM (modo de saída + template do resultado).
|
|
930
948
|
|
|
949
|
+
Campos do `data`:
|
|
950
|
+
|
|
951
|
+
| Campo | Valores | Default | O que faz |
|
|
952
|
+
|---|---|---|---|
|
|
953
|
+
| `mode` | `template`, `auto`, `silent` | `template` | como o resultado volta pro LLM |
|
|
954
|
+
| `template` | texto Liquid (`{{ params.x }}`, `{{ contact.x }}`) | vazio | SÓ no modo `template` |
|
|
955
|
+
| `include_log` | `true`/`false` | `false` | SÓ no modo `auto` — anexa o log da execução ao JSON |
|
|
956
|
+
|
|
957
|
+
- **`template`** — devolve o texto Liquid renderizado, precedido de um cabeçalho que MANDA a IA
|
|
958
|
+
cumprir aquilo neste turno. É o modo do "diga isso ao cliente".
|
|
959
|
+
- **`auto`** — devolve JSON com `params`, `variables` e `status`. Dado, não ordem.
|
|
960
|
+
- **`silent`** (desde 02/09/2026) — **encerra o turno sem resposta da IA**. Use quando o próprio
|
|
961
|
+
fluxo já enviou a mensagem final pelo bloco de mensagem: sem isso a IA fala de novo por cima e
|
|
962
|
+
duplica a informação. A IA continua ATIVA e responde normalmente a próxima mensagem do cliente.
|
|
963
|
+
|
|
931
964
|
```json
|
|
932
|
-
{ "id": "node-end", "type": "end", "position": { "x": 1330, "y": 300 }, "data": { "label": "Retorno", "mode": "
|
|
965
|
+
{ "id": "node-end", "type": "end", "position": { "x": 1330, "y": 300 }, "data": { "label": "Retorno", "mode": "template", "template": "Orçamento enviado. Confirme o recebimento com o cliente." } }
|
|
933
966
|
```
|
|
934
967
|
|
|
968
|
+
```json
|
|
969
|
+
{ "id": "node-fim-mudo", "type": "end", "position": { "x": 1330, "y": 520 }, "data": { "label": "Fim sem resposta", "mode": "silent" } }
|
|
970
|
+
```
|
|
971
|
+
|
|
972
|
+
**ATENÇÃO:** `mode` aceita SÓ os três valores acima. Até 02/09/2026 esta página ensinava
|
|
973
|
+
`mode: "structured"`, que NENHUMA tela produz e NENHUM leitor entende — o motor trata valor
|
|
974
|
+
desconhecido como `template`, e sem `template` a IA recebe **string vazia**. Se você criou algum
|
|
975
|
+
`end` com `structured` (ou qualquer outro valor), troque por um dos três. Mesma família do gatilho
|
|
976
|
+
do bloco Início que a documentação do MCP ensinou errado (19/08).
|
|
977
|
+
|
|
935
978
|
### 2.14 `note` (anotação visual / sticky note colorido)
|
|
936
979
|
|
|
937
980
|
Sticky note no canvas (aquele bloco colorido riscado na tela pra rotular/agrupar). Puramente visual: sem handles, NUNCA executado (não ligue edges nele). Disponível nos DOIS tipos de flow (`conversation` e `ai_tool`).
|
|
@@ -23,7 +23,7 @@ caixa de WhatsApp vinculada e (opcionalmente) dispara um fluxo do FlowBuilder no
|
|
|
23
23
|
responde 404** — ninguém consegue preencher. As tools de dashboard (listar, criar, editar,
|
|
24
24
|
publicar, ver respostas, simular) **funcionam mesmo assim**. Dá pra montar tudo antes de ligar a
|
|
25
25
|
flag; não adianta divulgar o link antes.
|
|
26
|
-
- **Escrita é
|
|
26
|
+
- **Escrita é de administrador ou de cargo personalizado com "Gerenciar Formulários" (`lead_form_manage`).** `create`, `update`, `destroy`, `publish`, `duplicate` e
|
|
27
27
|
`check_embed` passam por `check_admin_authorization?`; usuário não-admin recebe **401**. Leitura
|
|
28
28
|
(`list`, `show`, `stats`, `responses`) e o **simulador** (`test_run`) são liberados a qualquer
|
|
29
29
|
agente da conta.
|
|
@@ -145,6 +145,21 @@ Seguranças: o valor pulado **nunca aparece na tela nem no payload público**, e
|
|
|
145
145
|
alcança** a pergunta pulada. Código de outra conta, contato apagado ou qualquer pane = o formulário
|
|
146
146
|
roda anônimo normal. Link copiado do editor e colado fora de uma conversa NÃO tem carimbo.
|
|
147
147
|
|
|
148
|
+
**Toggle "Reconhecer quem recebeu o link"** (`settings.identify_by_link`, default `true` — inclusive
|
|
149
|
+
para formulário antigo, que não tem a chave). Desligado, o formulário **ignora o carimbo por
|
|
150
|
+
completo**: a resposta nasce anônima e cada pessoa preenche do zero.
|
|
151
|
+
|
|
152
|
+
Existe para o formulário **repassado**: o carimbo identifica o contato PARA QUEM o link foi enviado,
|
|
153
|
+
então, se essa pessoa encaminha o link (caso real: formulário que o cliente manda para os
|
|
154
|
+
familiares), todos abrem como se fossem ela — e o `ContactLinker` grava atributo personalizado, dado
|
|
155
|
+
cadastral e etiqueta de **todos na mesma ficha** (`apply_to_linked_contact`). O sintoma visível é só
|
|
156
|
+
o pulo das perguntas; o estrago real é no cadastro.
|
|
157
|
+
|
|
158
|
+
O corte acontece no **nascimento da resposta** (`identified_contact_id`, no controller público), não
|
|
159
|
+
no `WalkService`. Desligar apenas o pulo das perguntas seria conserto pela metade: a resposta
|
|
160
|
+
continuaria nascendo com o `contact_id` errado. A chave **não vai** para o payload público (a
|
|
161
|
+
whitelist do `metadata` segue sem ela) — a decisão é do servidor.
|
|
162
|
+
|
|
148
163
|
## O contrato do `form_data`
|
|
149
164
|
|
|
150
165
|
```json
|
|
@@ -179,6 +194,7 @@ roda anônimo normal. Link copiado do editor e colado fora de uma conversa NÃO
|
|
|
179
194
|
| `end` | `title, description, redirect_url, button_label, image, video_url` | — | sim |
|
|
180
195
|
| `api_request` | `label, method, url, headers, body, timeout` | `success`, `error` | não (mostra bloco de espera) |
|
|
181
196
|
| `ai` | `label, mode, prompt, categories, include_answers, model` | modo `generate`: `success`, `error` / modo `classify`: um `cat_<id>` por categoria + `other` | não (mostra bloco de espera) |
|
|
197
|
+
| `generate_contract` | `label, document_id, send_link` | `success`, `error` | não (mostra bloco de espera) |
|
|
182
198
|
|
|
183
199
|
**Chave fora da lista não é lida pelo motor** e o editor a **remove no próximo salvamento pela
|
|
184
200
|
tela**. Escrever um campo inventado pela API não gera erro nenhum — ele simplesmente não faz nada e
|
|
@@ -303,6 +319,16 @@ respostas já dadas como contexto. `model` é validado contra a lista suportada;
|
|
|
303
319
|
da conta. A IA usa a **chave da própria conta** — conta sem chave faz o bloco sair pela saída de
|
|
304
320
|
erro.
|
|
305
321
|
|
|
322
|
+
**`generate_contract`** (04/09 — bloco "Gerar contrato", feature `document_signing`): gera o CONTRATO de
|
|
323
|
+
assinatura eletrônica daquela pessoa a partir de um modelo (`document_id` = id de
|
|
324
|
+
`lionchat_signature_documents_list`) com os dados da FICHA — mapeie as perguntas com `map_to` para os
|
|
325
|
+
campos que o modelo usa (nome, CPF, endereço…); campo sem valor = saída `error` com o motivo
|
|
326
|
+
(`variaveis_sem_valor: contact.cpf`). `send_link` (padrão `true`) manda o link de assinatura no WhatsApp da
|
|
327
|
+
pessoa (conversa da caixa vinculada); `false` deixa o contrato pronto e você manda `{{contrato.<node_id>.link}}`
|
|
328
|
+
pelo bloco `send_message`. Roda DEPOIS do vínculo do contato, como efeito (bloco de espera), dentro dos
|
|
329
|
+
orçamentos do formulário (200 contratos/formulário/dia, 2.000/conta/dia). Consome 1 vaga do limite mensal
|
|
330
|
+
de contratos. Saídas: `success` (contrato criado) e `error`.
|
|
331
|
+
|
|
306
332
|
### Variáveis
|
|
307
333
|
|
|
308
334
|
| Variável | O que traz | Onde vale |
|
|
@@ -311,6 +337,7 @@ erro.
|
|
|
311
337
|
| `{{contact.name}}` `{{contact.phone}}` `{{contact.email}}` | O que a pessoa respondeu (a ficha é reserva) | idem |
|
|
312
338
|
| `{{api.<node_id>.<caminho>}}` | Um pedaço da resposta de uma consulta | idem |
|
|
313
339
|
| `{{ia.<node_id>}}` | O texto que a IA gerou naquele bloco | idem |
|
|
340
|
+
| `{{contrato.<node_id>.link}}` `.titulo` `.prazo` `.id` `.status` | O contrato gerado pelo bloco Gerar contrato (endereço de assinatura, título, data-limite) | mensagem, prompt, valores |
|
|
314
341
|
| `{{var.<nome>}}` | Variável criada pelo bloco Definir variável | idem |
|
|
315
342
|
| `{{conta.<variável>}}` | Variável da conta (cofre) | cabeçalho e CORPO de `api_request` (com segredo); em `set_variable` e no valor das Ações só as NÃO-secretas |
|
|
316
343
|
|
|
@@ -150,8 +150,8 @@ DESCARTADAS na entrada (não criam conversa nem notificam). Bloquear NÃO resolv
|
|
|
150
150
|
- `Channel::Whatsapp` — WhatsApp Cloud API (oficial)
|
|
151
151
|
- `Channel::WebWidget` — chat ao vivo no site
|
|
152
152
|
- `Channel::Email` — email
|
|
153
|
-
- `Channel::FacebookPage` — Messenger
|
|
154
|
-
- `Channel::Instagram` — Instagram DM
|
|
153
|
+
- `Channel::FacebookPage` — Messenger; com `medium: "instagram"` é uma caixa **só de Instagram** conectada pela Página do Facebook (trate como Instagram)
|
|
154
|
+
- `Channel::Instagram` — Instagram DM (login pelo Instagram)
|
|
155
155
|
- `Channel::Telegram` — Telegram
|
|
156
156
|
- `Channel::Api` — webhook custom
|
|
157
157
|
- `Channel::Voice` — VoIP / chamadas
|
|
@@ -533,3 +533,73 @@ Termos do formulário (18/08):
|
|
|
533
533
|
Detalhes completos (construtor, página pública, blocos, gatilhos de flow, tetos e limites) no
|
|
534
534
|
resource `lionchat://docs/formularios-publicos`.
|
|
535
535
|
|
|
536
|
+
## Histórico importado virou A conversa (02/09/2026)
|
|
537
|
+
|
|
538
|
+
Antes, a conversa trazida do celular (importação) e a conversa viva do mesmo contato eram DUAS. A
|
|
539
|
+
atendente escrevia da conversa de arquivo, o cliente respondia e a resposta abria uma terceira. Agora:
|
|
540
|
+
|
|
541
|
+
- **Um contato, uma conversa por caixa.** A mensagem que chega ADOTA a conversa que já existe —
|
|
542
|
+
importada ou não — e a reabre. Os importadores escrevem na conversa do contato.
|
|
543
|
+
- **A conversa é lida por DATA, não por número** (paginação e as leituras da IA mudaram juntas).
|
|
544
|
+
- **`live_since`** marca quando a conversa passou a ter atendimento de verdade. Relatório de
|
|
545
|
+
resolução e SLA contam desse marco, nunca da data importada.
|
|
546
|
+
- **Janela de 24h, reativação e seletor de modelo olham a última fala VIVA do cliente.** Conversa só
|
|
547
|
+
de arquivo, sem resposta, segue com a janela FECHADA — mandar texto livre nela falha.
|
|
548
|
+
- **Adoção NÃO dispara "conversa criada".** Fluxo/automação/IA presos nesse gatilho não rodam na
|
|
549
|
+
adoção; o gatilho equivalente é **"Conversa reaberta"**.
|
|
550
|
+
- Histórico importado continua fora do contexto da IA e não infla o contador do resumo pago.
|
|
551
|
+
|
|
552
|
+
### Chaves reservadas do sistema — API e MCP não gravam mais
|
|
553
|
+
|
|
554
|
+
`ConversationBuilder` passou a RECUSAR as chaves de `Conversation::RESERVED_ADDITIONAL_KEYS` vindas de
|
|
555
|
+
fora ao criar conversa: `imported_from`, `import_digits`, `mail_subject`, `type`, `in_reply_to`,
|
|
556
|
+
`initiated_by`, `auto_reply`, `original_channel_type`, `conversation_language`,
|
|
557
|
+
`agent_reply_time_window`, `conference_sid`, `call_status`, `tiktok_capabilities`,
|
|
558
|
+
`captain_media_asset_id`, `live_since`, `has_imported_history`.
|
|
559
|
+
|
|
560
|
+
Não tente mandá-las em `additional_attributes` ao criar conversa — são ignoradas. Gravar `live_since`
|
|
561
|
+
com data futura ou `has_imported_history` fecharia a janela de 24h daquela conversa para sempre.
|
|
562
|
+
|
|
563
|
+
## Campos novos na resposta da API (02/09/2026)
|
|
564
|
+
|
|
565
|
+
| Campo | Onde | Para que serve |
|
|
566
|
+
|---|---|---|
|
|
567
|
+
| `medium` | caixa (`inboxes_list`/`_show`) | sub-tipo do canal. Numa caixa de Página do Facebook diz se ela é Messenger ou **só Instagram** — é o que separa os dois |
|
|
568
|
+
| `content` | mensagem | já vem no formato de exibição (mensagem apagada mostra o aviso, não o texto cru) |
|
|
569
|
+
| `last_incoming_message_at` | conversa | data da última mensagem VIVA do cliente (unix). Use para saber se a janela de 24h está aberta — não confie na data da conversa, que pode vir de histórico importado. Mensagem que a Meta entregou ATRASADA (reentrega depois de uma queda) conta pela hora de ENVIO da Meta, não pela chegada (08/09): o campo, `can_reply` e a tela seguem a mesma régua que a Meta usa pra recusar |
|
|
570
|
+
|
|
571
|
+
## Formulário público: código para incorporar no site (02/09/2026)
|
|
572
|
+
|
|
573
|
+
Além do link público, o formulário passou a ter um **código para embutir no site do cliente** (iframe
|
|
574
|
+
gerado na tela do formulário) e um **interruptor para desligar o reconhecimento do link repassado** —
|
|
575
|
+
quando ligado, um link identificado enviado numa conversa pula os campos já conhecidos; desligado, o
|
|
576
|
+
formulário sempre pergunta tudo. Use quando o cliente reclamar que o formulário "já vem preenchido"
|
|
577
|
+
para a pessoa errada (link repassado a terceiros).
|
|
578
|
+
|
|
579
|
+
## Gravação de ligação do VTCall (02-03/09/2026)
|
|
580
|
+
|
|
581
|
+
A gravação permanente só nasce cerca de 24h depois da ligação. O card agora entra com a gravação
|
|
582
|
+
**conferida** (o arquivo é sondado antes de virar link) e é reconferido por até 36h; ligação
|
|
583
|
+
**recebida** passou a ter gravação, e o card é atualizado em silêncio (sem sino, sem reabrir a
|
|
584
|
+
conversa). Quem atendeu voltou a aparecer nas recebidas. Se o cliente diz que o botão de ouvir não
|
|
585
|
+
funciona numa ligação de hoje, o mais provável é que o arquivo permanente ainda não exista — a
|
|
586
|
+
reconferência resolve sozinha dentro de 36h.
|
|
587
|
+
|
|
588
|
+
## Assinatura eletrônica de contratos (04/09)
|
|
589
|
+
|
|
590
|
+
### `status` do contrato (`signature_envelopes`)
|
|
591
|
+
| Valor | Balde de filtro | Significado |
|
|
592
|
+
|---|---|---|
|
|
593
|
+
| `draft` | aguardando | criado sem nenhuma entrega (falhou) — use `resend` |
|
|
594
|
+
| `sent` | aguardando | link entregue, ninguém abriu ainda |
|
|
595
|
+
| `viewed` | visualizado | alguém abriu o link |
|
|
596
|
+
| `partially_signed` | visualizado | parte das pessoas assinou |
|
|
597
|
+
| `signed_pending_seal` | assinado | todos assinaram; o documento final está sendo gerado |
|
|
598
|
+
| `signed` | assinado | documento final pronto (`sealed_sha256`) |
|
|
599
|
+
| `refused` / `cancelled` / `expired` | encerrado | recusado / cancelado pela equipe / prazo venceu |
|
|
600
|
+
|
|
601
|
+
### `role` do participante: `signer` (titular), `witness` (testemunha), `sender` (remetente — assina no painel).
|
|
602
|
+
### `status` do participante: `pending` → `viewed` → `verified` → `signed` | `refused`.
|
|
603
|
+
### Erros do envio (`signature_envelopes_create`): `variaveis_sem_valor` (+ `missing[]`), `escolher_caixa` (+ `inboxes[]`),
|
|
604
|
+
`entrega_falhou`, `sem_caixa_whatsapp`, `telefone_invalido`, `limite_do_mes`, `cpf_invalido`, `funcionalidade_desligada`,
|
|
605
|
+
`fila_cheia` (fila única de conversão do Word cheia — repetir em instantes), `conversor_indisponivel` (o serviço de conversão de Word não respondeu — repetir em instantes).
|