@lionchat/mcp-server 1.19.0 → 1.19.1

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.
@@ -0,0 +1,17 @@
1
+ export declare const BLOCKS_GUARD_TOOL_ID = "lionchat_canned_responses_update";
2
+ /**
3
+ * Verdadeiro quando quem chamou mandou `content` e NAO mandou `blocks` — o unico caso em que o
4
+ * Rails descarta o texto em silencio.
5
+ */
6
+ export declare function sentContentWithoutBlocks(body: unknown): boolean;
7
+ /** Acha o registro na lista e diz se ele e feito de blocos. */
8
+ export declare function recordHasBlocks(list: unknown, id: unknown): boolean;
9
+ export declare function blocksGuardMessage(id: unknown): string;
10
+ /**
11
+ * Devolve a mensagem de recusa, ou null pra seguir normalmente.
12
+ *
13
+ * FAIL-OPEN de proposito: se a lista nao puder ser lida (rede, permissao, formato inesperado), a
14
+ * gravacao segue como antes. O guard existe pra evitar um no-op silencioso, nunca pra impedir uma
15
+ * edicao legitima por indisponibilidade.
16
+ */
17
+ export declare function blocksGuardRefusal(toolId: string, body: unknown, id: unknown, loadList: () => Promise<unknown>): Promise<string | null>;
@@ -0,0 +1,86 @@
1
+ // AIDEV-NOTE: [resposta-pronta-blocos 01/09/2026] Resposta pronta guarda o texto em DOIS lugares:
2
+ // `blocks` (o que e REALMENTE enviado ao cliente, via CannedResponseDispatchService) e `content`
3
+ // (copia usada so pra busca/preview). O model do Rails tem `before_save :sync_content_from_blocks`,
4
+ // entao TODA gravacao reescreve `content` a partir do primeiro bloco de texto. Consequencia: mandar
5
+ // SO `content` numa resposta que tem blocos e descartado SEMPRE — a API responde 200, devolve o
6
+ // registro com o texto VELHO e nao levanta erro nenhum.
7
+ //
8
+ // Medido em 01/09/2026 (conta 56): 130 de 131 respostas prontas tem blocos, e 6 chamadas
9
+ // so-com-`content` nao gravaram absolutamente nada — o efeito parecia intermitente so porque outra
10
+ // pessoa editava as mesmas respostas no painel ao mesmo tempo.
11
+ //
12
+ // Este guard recusa esse caso ANTES de gravar e explica o que fazer. Mesma familia da trava de
13
+ // `confirm_required`: falha barulhenta em vez de silencio.
14
+ //
15
+ // GOTCHA: `canned_responses` NAO tem rota de leitura por id (routes.rb: only index/create/update/
16
+ // destroy). Ler `/canned_responses/{id}` daria 404 e o guard viraria no-op silencioso — por isso a
17
+ // conferencia passa pela LISTA e acha o registro pelo id.
18
+ export const BLOCKS_GUARD_TOOL_ID = 'lionchat_canned_responses_update';
19
+ const BODY_WRAPPER = 'canned_response';
20
+ /** Corpo ja embrulhado por separateParams: { canned_response: { ... } }. */
21
+ function unwrapBody(body) {
22
+ if (!body || typeof body !== 'object' || Array.isArray(body))
23
+ return undefined;
24
+ const inner = body[BODY_WRAPPER];
25
+ if (!inner || typeof inner !== 'object' || Array.isArray(inner))
26
+ return undefined;
27
+ return inner;
28
+ }
29
+ /**
30
+ * Verdadeiro quando quem chamou mandou `content` e NAO mandou `blocks` — o unico caso em que o
31
+ * Rails descarta o texto em silencio.
32
+ */
33
+ export function sentContentWithoutBlocks(body) {
34
+ const inner = unwrapBody(body);
35
+ if (!inner)
36
+ return false;
37
+ const content = inner['content'];
38
+ const hasContent = typeof content === 'string' && content.length > 0;
39
+ if (!hasContent)
40
+ return false;
41
+ const blocks = inner['blocks'];
42
+ const hasBlocks = Array.isArray(blocks) ? blocks.length > 0 : blocks !== undefined && blocks !== null;
43
+ return !hasBlocks;
44
+ }
45
+ /** Acha o registro na lista e diz se ele e feito de blocos. */
46
+ export function recordHasBlocks(list, id) {
47
+ if (!Array.isArray(list))
48
+ return false;
49
+ const wanted = String(id);
50
+ const record = list.find((r) => r && typeof r === 'object' && String(r['id']) === wanted);
51
+ if (!record)
52
+ return false;
53
+ const blocks = record['blocks'];
54
+ return Array.isArray(blocks) && blocks.length > 0;
55
+ }
56
+ export function blocksGuardMessage(id) {
57
+ return (`A resposta pronta ${id} e feita de BLOCOS, e os blocos sao o que o cliente recebe. ` +
58
+ 'O campo `content` e apenas uma copia: o servidor o reescreve a partir do primeiro bloco a cada ' +
59
+ 'gravacao, entao enviar so `content` NAO altera nada (a chamada responde sucesso e o texto ' +
60
+ 'antigo continua valendo). ' +
61
+ 'Reenvie com `blocks` — o array inteiro, com o texto novo dentro do bloco — de preferencia com ' +
62
+ '`content` igual ao primeiro bloco de texto. Use `lionchat_canned_responses_list` para ver os ' +
63
+ 'blocos atuais antes de montar o array.');
64
+ }
65
+ /**
66
+ * Devolve a mensagem de recusa, ou null pra seguir normalmente.
67
+ *
68
+ * FAIL-OPEN de proposito: se a lista nao puder ser lida (rede, permissao, formato inesperado), a
69
+ * gravacao segue como antes. O guard existe pra evitar um no-op silencioso, nunca pra impedir uma
70
+ * edicao legitima por indisponibilidade.
71
+ */
72
+ export async function blocksGuardRefusal(toolId, body, id, loadList) {
73
+ if (toolId !== BLOCKS_GUARD_TOOL_ID)
74
+ return null;
75
+ if (!sentContentWithoutBlocks(body))
76
+ return null;
77
+ let list;
78
+ try {
79
+ list = await loadList();
80
+ }
81
+ catch {
82
+ return null;
83
+ }
84
+ return recordHasBlocks(list, id) ? blocksGuardMessage(id) : null;
85
+ }
86
+ //# sourceMappingURL=blocksGuard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blocksGuard.js","sourceRoot":"","sources":["../src/blocksGuard.ts"],"names":[],"mappings":"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"}
@@ -378,6 +378,21 @@ Sem o tipo, o filtro pode bater no escopo errado. A UI mostra sufixo "(Conversa)
378
378
  pendência de permissão).
379
379
  - Meta CAPI: o evento `InitiateCheckout` foi RENOMEADO para `begin_checkout`.
380
380
 
381
+ ### Conversão de dentro do FLUXO — ação `send_conversion` (2026-09-01)
382
+
383
+ O bloco de Ações (aba Sistema) manda o evento de conversão pro Meta, Google Ads e/ou GA4 pelos MESMOS
384
+ serviços do Funil. Regras que valem a pena lembrar ao montar pelo MCP: destino só funciona com a
385
+ integração conectada na conta (senão é pulado em silêncio — confira as listas de integração antes);
386
+ `event_name` no Google Ads precisa estar no `conversion_action_map`; `value` vazio = valor do card
387
+ (o que iniciou o fluxo ou o mais recente da conversa); sem card, o registro NÃO aparece nas telas de
388
+ eventos do Funil (só no histórico do fluxo). Formato completo no `flowbuilder-design-guide`.
389
+
390
+ ### Meta Lead — token de anúncios de OUTRO app (2026-09-01)
391
+
392
+ `lionchat_meta_lead_validate_token` pode voltar `app_verified: false` com `expires_at` nulo: é token
393
+ válido de um app que não é o nosso (usuário de sistema da BM do cliente) — `debug_token` não alcança.
394
+ Não trate como inválido nem afirme validade: o que prova o token é `ads_check.ok` e as `permissions`.
395
+
381
396
  ### Meta CAPI — moeda do valor (2026-06)
382
397
 
383
398
  O disparo da conversão aceita `currency` (código ISO, ex: `BRL`, `USD`); default `BRL`. Dá pra
@@ -424,7 +424,7 @@ daquele tipo no calendário; vazio = cor do agente. A tarefa devolve `booking_co
424
424
 
425
425
  ## e-Clínicas (Efficient) — integração de clínicas
426
426
 
427
- 16 eventos de webhook, cada um mapeável a automação OU flow na tela Integrações > e-Clínica
427
+ 17 eventos de webhook, cada um mapeável a automação OU flow na tela Integrações > e-Clínica
428
428
  (o mapeamento e os lembretes passaram a ser editáveis por MCP em 31/08/2026, com
429
429
  `lionchat_eclinica_integrations_update` — ele **SUBSTITUI** o objeto inteiro, então leia com
430
430
  `_show` e devolva completo, senão apaga o resto):
@@ -432,7 +432,8 @@ daquele tipo no calendário; vazio = cor do agente. A tarefa devolve `booking_co
432
432
  `agendamento_atendido`, `agendamento_alterado`, `agendamento_desmarcado`,
433
433
  `agendamento_transferido`, `cliente_baixa_pagamento`, `cliente_alteracao`,
434
434
  `cliente_inclusao_pagamento`, `controle_laboratorio_novo`, `controle_laboratorio_alterado`,
435
- `agendamento_aguardando`, `odontograma_aprovado`, `procedimento_finalizado`
435
+ `agendamento_aguardando`, `odontograma_aprovado`, `procedimento_finalizado`,
436
+ `cliente_alteracao_pagamento`, `odontograma_finalizado`, `inclusao_procedimento`
436
437
  (capturados ao vivo, não documentados pelo e-Clínica).
437
438
 
438
439
  Os 3 últimos são do perfil ODONTOLÓGICO: `agendamento_aguardando` = a recepção marcou a
@@ -441,6 +442,15 @@ chegada do paciente na clínica (grava a hora da chegada e `eclinica_status_agen
441
442
  `procedimento_finalizado` (2026-08-31) = UM procedimento do plano foi concluído (implante, lente,
442
443
  cirurgia, instalação/remoção de aparelho).
443
444
 
445
+ Dois tipos novos em 2026-09-01 (perfil odontológico, capturados ao vivo — antes caíam em "desconhecido"):
446
+ `odontograma_finalizado` = **o plano de tratamento INTEIRO foi concluído** (não confundir com
447
+ `procedimento_finalizado`, que é UM item do plano; payload igual ao do `odontograma_aprovado`, momento
448
+ diferente — grava `eclinica_odontograma_finalizado_em` e NÃO mexe em `eclinica_odontograma_aprovado_em`);
449
+ `inclusao_procedimento` = **um procedimento foi ACRESCENTADO ao plano, ainda não executado** (serve para
450
+ aviso de orçamento; NÃO é gatilho de orientação pós-procedimento — grava em campos próprios
451
+ `eclinica_procedimento_incluido_*`, nunca nos do finalizado, que são os que roteiam os flows de
452
+ pós-procedimento).
453
+
444
454
  **`procedimento_finalizado` dispara UMA VEZ POR PROCEDIMENTO.** Medido na Goya em 31/08: 24 avisos
445
455
  com 23 procedimentos distintos, 4 deles em 15 segundos no mesmo paciente. A plataforma **não roda o
446
456
  mesmo flow duas vezes na mesma conversa ao mesmo tempo**, então ligar UM flow direto neste evento faz
@@ -486,6 +496,10 @@ Atributos de sistema no CONTATO (prefixo `eclinica_`, protegidos, usáveis como
486
496
  | `eclinica_procedimento_valor` | text | Valor do procedimento concluído (`opr_valor`) |
487
497
  | `eclinica_procedimento_finalizado_em` | date | Dia em que o procedimento foi concluído (`opr_datafinalizado`) |
488
498
  | `eclinica_procedimento_profissional` | text | NOME do profissional que executou — pode DIVERGIR do profissional do odontograma (o plano é de um dentista, a cirurgia pode ser de outro) |
499
+ | `eclinica_odontograma_finalizado_em` | date | Dia em que o plano de tratamento INTEIRO foi concluído (evento `odontograma_finalizado`, 2026-09-01). Não confundir com a data do último procedimento |
500
+ | `eclinica_procedimento_incluido_id` | text | Número do último procedimento ACRESCENTADO ao plano (evento `inclusao_procedimento`, 2026-09-01) — planejado, ainda não executado |
501
+ | `eclinica_procedimento_incluido_dente` | text | Dente/região do procedimento acrescentado (`opr_dente`; `GE` = geral) |
502
+ | `eclinica_procedimento_incluido_valor` | text | Valor do procedimento acrescentado (`opr_valor`) |
489
503
  | `eclinica_marcador_nome` | text | Marca que a clínica digita no fim do nome do paciente no e-Clínica (ex: `*`, `***`) — retirada do nome e guardada aqui (2026-08-20). Significado é da clínica |
490
504
  | `eclinica_laboratorio_data_prevista` | date | Previsão de entrega da medicação (novo 2026-07-23) |
491
505
  | `eclinica_laboratorio_data_moldagem` | date | Data do pedido da medicação |
@@ -395,6 +395,38 @@ só pra destravar, ela pode sair.
395
395
 
396
396
  `greater_than`/`less_than` valem em atributo número (valor numérico) E temporais `date`/`time`/`datetime` (o backend detecta o formato do valor: instante > dia > minutos > número). `number_range` SÓ em número. Nunca use maior/menor em texto/lista.
397
397
 
398
+ **Condição por ORIGEM / CAMPANHA — preset "Atributo de campanha" (novo 2026-09-01):** o filtro
399
+ "só lead que veio de anúncio" (ou de uma campanha/UTM/origem específica) é uma regra de atributo da
400
+ CONVERSA no formato `attr_config`. Forma canônica (é o que a tela grava; reabre no card "Atributo de
401
+ campanha"):
402
+
403
+ ```json
404
+ { "id": "c1", "valueType": "attr_config", "attrSource": "conversation", "attrScope": "campaign",
405
+ "attr_key": "origin_kind", "operator": "equal", "value": "paid_ad" }
406
+ ```
407
+
408
+ - `attrSource: "conversation"` + `attr_key` é o que o MOTOR lê (`conversation.custom_attributes[attr_key]`);
409
+ `valueType: "attr_config"` e `attrScope: "campaign"` são marcadores de TELA (sem `attrScope` a regra reabre
410
+ no card genérico "Atributo da conversa" — funciona igual).
411
+ - Chaves da família de campanha (todas em `conversation.custom_attributes`): `origin_kind`, `origin_platform`,
412
+ `origin_first_kind`/`origin_first_platform`, `origin_last_kind`/`origin_last_platform`, `origin_*` em geral
413
+ (origem unificada), `ctwa_*` (anúncio click-to-WhatsApp: `ctwa_ad_id`, `ctwa_ad_title`, `ctwa_campaign_name`,
414
+ `ctwa_adset_name`...), `meta_lead_*` (formulário Meta Lead Ads), `lt_*` (LionTrack: UTMs, página, dispositivo).
415
+ Veja a lista real com `lionchat_custom_attributes_list` (`attribute_model: conversation`, `include_system: true` — as chaves de campanha são atributos de sistema).
416
+ - **Valores fechados** de `origin_kind` (e `origin_first_kind`/`origin_last_kind`): `paid_ad` (Anúncio),
417
+ `lead_form` (Formulário), `organic` (Orgânico), `direct` (Direto), `referral` (Indicação), `manual` (Origem
418
+ cadastrada). O painel mostra o rótulo em português, mas a comparação é pelo VALOR — `"Anúncio"` nunca casa.
419
+ - `origin_platform` (e first/last): `facebook`, `instagram`, `google`, `tiktok`, `linkedin`, `youtube`,
420
+ `whatsapp`, `direct` — e, para origem cadastrada pelo cliente em Configurações > Origens de Lead,
421
+ `custom:<slug>` (slug = nome parametrizado, ex.: "Indicação de amigo" → `custom:indicacao-de-amigo`;
422
+ liste com `lionchat_lead_origins_list`). Para filtrar por uma origem cadastrada use `origin_platform`
423
+ com `contains` + uma palavra do slug, ou `equal` + o `custom:<slug>` completo.
424
+ - Alternativa equivalente pro motor, em texto livre: `{ "field": "{{conversation.custom_attribute.origin_kind}}",
425
+ "operator": "equal", "value": "paid_ad", "valueType": "variable" }` — reabre no card "Variável", não no de
426
+ campanha. Prefira o formato `attr_config` acima quando o cliente vai editar pela tela.
427
+ - Caso real (Cast, 01/09): flow "Ativar IA" só para lead de anúncio = condição `origin_kind equal paid_ad`
428
+ na saída `cond_0` + ação `assign_captain` nessa saída; `default` sem nada.
429
+
398
430
  **Agente de IA — `conversation_has_ai_agent` e irmãos (novo 2026-08-01):** o flow sempre soube LIGAR e
399
431
  DESLIGAR a IA (ações `assign_captain` / `deactivate_captain`), mas não sabia PERGUNTAR se ela estava
400
432
  ligada. Agora sabe. É o espelho exato do trio do agente humano:
@@ -484,7 +516,8 @@ o botão "Usar variável" ao lado do campo alterna lista fixa ↔ variável.
484
516
  | `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) |
485
517
  | `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) |
486
518
  | `send_webhook` | `{ url, headers?, body? }` | Dispara webhook externo |
487
- | `start_flow` | `{ flow_id }` | Inicia outro fluxo |
519
+ | `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 |
488
521
  | `deactivate_flow` ou `disable_flow` | `{}` | Encerra fluxo atual |
489
522
  | `update_attribute` | `{ attr_source: 'contact'\|'conversation'\|'card', attr_key, attr_value }` | Seta custom_attribute (ver abaixo) |
490
523
  | `assign_captain` (ou `assign_captain_assistant`) | `{ assistant_id }` | Atribui IA Captain |
@@ -494,6 +527,35 @@ o botão "Usar variável" ao lado do campo alterna lista fixa ↔ variável.
494
527
 
495
528
  **`card_source` (blocos de card) — opcional:** as ações de card aceitam `card_source`: `'funnel'` (default — procura o card pelo `funnel_id`) ou `'trigger'` (usa o card que DISPAROU o flow, em flows iniciados por `card_created`/`card_moved`/`card_won`/`card_lost`). Com `'trigger'`, `funnel_id` deixa de ser obrigatório — EXCETO em `move_kanban_stage`/`create_kanban_item`, cujo funil/etapa são o DESTINO. Sem card-gatilho disponível, a ação é pulada (não cai no fallback de funil). Aplica-se a `move_kanban_stage`, `set_won`/`set_lost`/`set_open`, `assign_agent_card`, `add_card_note`, `add_card_checklist`, `add_card_offer`, `update_attribute` (com `attr_source: 'card'`) e às condições `card_attr_equals`/`card_attr_contains` (gravando `card_source` na própria regra).
496
529
 
530
+ **`send_conversion` — Enviar conversão (2026-09-01):**
531
+
532
+ ```json
533
+ { "key": "send_conversion", "config": { "destinations": ["meta", "google_ads"], "event_name": "Lead", "value": "1500,50" } }
534
+ ```
535
+
536
+ - `destinations`: array com `meta`, `ga4` e/ou `google_ads` — **OBRIGATÓRIO e não vazio** (vazio = a ação
537
+ sai calada e o passo fica sem registro). Só marque destino que a conta já conectou em Configurações >
538
+ Integrações (Meta Pixel/CAPI, Google Ads, GA4): destino sem integração é PULADO em silêncio pelo serviço
539
+ (o histórico do fluxo mostra "GA4: pulado (integração não configurada, evento não mapeado ou pausado)").
540
+ Confira antes com `lionchat_meta_pixel_integrations_list`, `lionchat_google_ads_integrations_list`,
541
+ `lionchat_ga4_integrations_list`.
542
+ - `event_name`: **OBRIGATÓRIO**, só letras/números/sublinhado (até 40; ex.: `Lead`, `Schedule`,
543
+ `Purchase`); aceita variável `{{ }}`. No **Google Ads** o nome precisa estar mapeado no
544
+ `conversion_action_map` da integração, senão é pulado.
545
+ - `value` (opcional): número (vírgula BR aceita, `1500,50`) ou variável. **Vazio = valor do CARD** (ver
546
+ abaixo); sem card, o evento sai sem valor (nunca zero).
547
+ - **Card do evento:** o card que INICIOU o fluxo (gatilho `card_created`/`card_moved`/...) ou, sem ele, o
548
+ card mais recente da conversa (mesma busca das ações de card). Com card, o evento aparece na aba
549
+ Atividades do card e na tela de eventos do Funil (`funnels_meta_capi_events_list` e irmãs); **sem card o
550
+ registro só existe no histórico do fluxo** (as telas de eventos são por funil).
551
+ - **Identidade/dedup:** uma conversão por (sessão do fluxo, bloco) — `event_id` `lc_flow_<sessão>_<bloco>_evt_<evento>`.
552
+ O mesmo lead passando duas vezes pelo mesmo bloco NÃO gera duas conversões; dois leads diferentes sim.
553
+ - **Histórico:** o passo mostra uma linha por destino — `Meta: enfileirado (registro #161)` / `GA4: pulado (...)`
554
+ / `Meta: erro (...)`. O registro (`MetaCapiEvent`/`Ga4Event`/`GoogleAdsConversion`) guarda a resposta HTTP
555
+ e o motivo de falha; `trigger_type` = `flow`.
556
+ - Falha de um destino nunca derruba o fluxo (rescue por destino). Dry-run (Testar) não dispara.
557
+ - Cuidado com laço + `start_flow`: outra sessão = outra identidade = outra conversão.
558
+
497
559
  **`update_attribute` — campos EXATOS:** `attr_source` (`'contact'`, `'conversation'` ou `'card'`), `attr_key` (nome do atributo), `attr_value` (valor). NÃO existem `entity`/`key`/`value` — esses são ignorados e não salvam nada.
498
560
 
499
561
  **Coerção por TIPO (2026-07-29):** em `attr_source: 'contact'|'conversation'`, o `attr_value` de atributo personalizado é coagido pelo tipo da definição antes de gravar: número/moeda/porcentagem viram numérico ("1.234,56" → 1234.56; inteiro fica inteiro), checkbox aceita sim/não/true/false e grava BOOLEANO, lista casa caixa-insensível e grava a opção canônica, data aceita DD/MM/AAAA ou ISO, hora aceita "14:30"/"14h30". Valor irreconhecível grava como veio e o passo mostra nota âmbar no histórico. Card NÃO coage (atributo de card não tem definição tipada no backend).
@@ -921,7 +983,7 @@ O campo `flow_type` (definido na criação, IMUTÁVEL depois) decide a natureza
921
983
  Se o cliente pediu "uma ferramenta que a IA usa pra consultar X / calcular Y", é `ai_tool`. Se pediu "quando chega mensagem, faça Z", é `conversation`. Na dúvida, `conversation`.
922
984
 
923
985
  **No flow `ai_tool`, o node `action` NÃO aceita as keys da aba "Sistema"** (`send_webhook` /
924
- `start_flow`) — elas só valem em flow `conversation`. No `action` de um `ai_tool` use apenas keys
986
+ `start_flow` / `send_conversion`) — elas só valem em flow `conversation`. No `action` de um `ai_tool` use apenas keys
925
987
  das abas Conversas / Contatos / Kanban (ex: `add_label`, `change_status`, `update_attribute`,
926
988
  `create_kanban_item`). Para gravar atributo no `ai_tool`, use `action` com `update_attribute`
927
989
  (o antigo node `save_attribute` foi removido — não existe mais em nenhum tipo de flow).
@@ -1065,6 +1127,7 @@ texto trocava o protocolo pelo id interno do banco.
1065
1127
  - `conversation_resolved` — `{ "type": "conversation_resolved" }`
1066
1128
  - `agent_assigned` / `team_assigned` — `{ "type": "agent_assigned", "value": "<id opcional>" }` (vazio = qualquer)
1067
1129
  - `kanban_won` / `kanban_lost` — `{ "type": "kanban_won", "value": "<funnel_id opcional>" }`
1130
+ - `agent_replied` — `{ "type": "agent_replied" }` (sem `value`; vale pra QUALQUER atendente). Sai no instante em que um humano assume: mensagem do painel, do celular da empresa (eco do app nativo) ou agendada por um atendente. NÃO conta nota interna, mensagem do próprio flow, da IA, de follow-up, de automação nem de campanha. É estritamente por EVENTO — conversa que já tinha mensagem de atendente ANTES do flow começar não derruba o flow.
1068
1131
 
1069
1132
  **Rico por atributo** (novo 2026-07-08; REATIVO desde 2026-07-09) — sai assim que o atributo VIRA pro valor que bate:
1070
1133
  ```json
@@ -165,7 +165,11 @@ Feature flag específica (ex: `feature_kanban`, `feature_captain`) está OFF.
165
165
 
166
166
  ### Contact
167
167
  - `"email has already been taken"` — duplicado na conta
168
- - `"phone_number has already been taken"` — mesmo problema
168
+ - `"phone_number has already been taken"` — mesmo problema. **Desde 2026-09-01 é trava do BANCO** (índice
169
+ único telefone+conta, como e-mail e identifier têm desde 2023): dois `contacts_create` com o mesmo
170
+ telefone em paralelo já não criam gêmeos — o segundo volta 422. Antes de criar, procure com
171
+ `lionchat_contacts_search` (acha com e sem o 9º dígito desde 29/08); para atualizar, use `contacts_update`
172
+ no que já existe. Duplicado só aparece se as fichas nasceram ANTES da trava
169
173
  - `"phone_number must be a valid number with country code"` — formato E.164: `+5511999999999`
170
174
 
171
175
  ### Message
@@ -634,6 +638,27 @@ ficaram sem nome. E desde 25/08 o CONECTAR exige escolha: `meta_lead_create` com
634
638
  ele TODAS as páginas do login entram — caso real de 25 páginas numa conta); pra limpar excesso
635
639
  antigo, `lionchat_meta_lead_bulk_destroy`.
636
640
 
641
+ ### "Testei o token de anúncios e voltou '(#100) App_id did not match' / a tela dizia Pendente com o token salvo" — 01/09
642
+
643
+ Corrigido em 01/09. O token de anúncios que o cliente cola pode ser de OUTRO app da Meta (usuário de
644
+ sistema da própria BM) — o `debug_token` só responde para tokens do nosso app, e o teste concluía
645
+ "inválido" para um token válido (caso real: conta 53, 51 contas de anúncio alcançáveis). Agora
646
+ `lionchat_meta_lead_validate_token` cai num caminho sem `debug_token`: responde `valid: true` com
647
+ `app_verified: false` e `app_id`/`app_name`/`expires_at` **nulos** (não há como saber sem o debug_token —
648
+ NÃO afirme "nunca expira"), `permissions` (do `me/permissions`, só as concedidas) e `ads_check`
649
+ (`{ok, ad_accounts_count}` = alcança anúncio de verdade). Token do NOSSO app segue com `app_verified: true`
650
+ e validade. Segundo ajuste: o resumo de conta (`ads_capable`/`has_manual_ads_token` em `meta_lead_list` e na
651
+ resposta de `ads_token`) considerava só integrações LIGADAS — conta com todas as páginas desligadas parecia
652
+ "sem token". Agora prefere as ligadas e, sem nenhuma, olha todas. Páginas com `token_expired` continuam
653
+ precisando de reconexão por um admin da página — o token de anúncios não resolve isso.
654
+
655
+ ### "Menção em grupo mostra um código no lugar do nome" — 01/09
656
+
657
+ `@201103320871050` no lugar de `@Marcelo`: o WhatsApp identifica cada APARELHO com `:NN` no fim do
658
+ telefone e o aprendizado do grupo colava o número do aparelho no telefone (`551599749220048`), que não
659
+ existe. Corrigido em 01/09 (aguarda deploy): a próxima mensagem de cada participante conserta o par
660
+ sozinha; para reescrever menções antigas há o rake `waha:backfill_mentions` — só DEPOIS do deploy.
661
+
637
662
  ## "Atualizei a chave da caixa oficial pelo update e ela parou de receber" — 26/08
638
663
 
639
664
  `inboxes_update` com `channel.provider_config` SUBSTITUI o objeto inteiro: mandar só o campo
package/dist/tools.js CHANGED
@@ -6,6 +6,7 @@ import { readFileSync } from 'fs';
6
6
  import { resolve, dirname } from 'path';
7
7
  import { fileURLToPath } from 'url';
8
8
  import { FULL_RESPONSE_PARAM, FULL_RESPONSE_DESCRIPTION, CONFIRM_PARAM, CONFIRM_DESCRIPTION, supportsFullResponse, } from './sanitize.js';
9
+ import { blocksGuardRefusal } from './blocksGuard.js';
9
10
  // AIDEV-NOTE: Map HTTP method to tool annotations for MCP client hinting
10
11
  function getToolAnnotations(method) {
11
12
  switch (method.toUpperCase()) {
@@ -261,6 +262,19 @@ function registerSingleTool(server, config, client, endpoint) {
261
262
  const path = substitutePath(endpoint.path, effectiveAccountId, pathParams);
262
263
  const queryStr = buildQueryString(queryParams);
263
264
  const fullPath = queryStr ? `${path}${queryStr}` : path;
265
+ // AIDEV-NOTE: [resposta-pronta-blocos 01/09/2026] recusa a gravacao que o Rails
266
+ // descartaria em silencio (so `content` numa resposta feita de blocos). Ver blocksGuard.ts.
267
+ // Fail-open: se a lista nao puder ser lida, segue como antes.
268
+ const blocksRefusal = await blocksGuardRefusal(endpoint.id, bodyParams, pathParams['id'], () => client.request({
269
+ method: 'GET',
270
+ path: `/api/v1/accounts/${effectiveAccountId}/canned_responses`,
271
+ }));
272
+ if (blocksRefusal) {
273
+ return {
274
+ content: [{ type: 'text', text: blocksRefusal }],
275
+ isError: true,
276
+ };
277
+ }
264
278
  const result = await client.request({
265
279
  method: endpoint.method,
266
280
  path: fullPath,
@@ -332,7 +346,7 @@ function registerListCategoriesTool(server, allEndpoints) {
332
346
  // Helps LLMs build correct flow_data without hitting trial-and-error on
333
347
  // node types, action keys, source handles, etc.
334
348
  function registerFlowsSchemaReferenceTool(server) {
335
- const reference = `LIONCHAT FLOW BUILDER — SCHEMA REFERENCE (atualizado 2026-08-31)
349
+ const reference = `LIONCHAT FLOW BUILDER — SCHEMA REFERENCE (atualizado 2026-09-01)
336
350
 
337
351
  flow_data tem o formato Vue Flow: { nodes: [...], edges: [...] }.
338
352
 
@@ -347,7 +361,7 @@ flow_data tem o formato Vue Flow: { nodes: [...], edges: [...] }.
347
361
  com tool_name (snake_case, max 50) + tool_description (max 500). SEM inbox_ids. No 'end' OBRIGATORIO.
348
362
  Nodes permitidos em ai_tool: start, end, api, condition, set_variable, ai, randomizer, action,
349
363
  send_message, note (SEM wait, wait_response, update_group). No action de ai_tool NAO use keys da
350
- aba Sistema (send_webhook/start_flow). Vincular ao assistente: POST /flow_tools/{id}/assistants.
364
+ aba Sistema (send_webhook/start_flow/send_conversion). Vincular ao assistente: POST /flow_tools/{id}/assistants.
351
365
  Testar: POST /flow_tools/{id}/run.
352
366
 
353
367
  ═══ NODE GERAL ═══
@@ -589,6 +603,22 @@ flow_data tem o formato Vue Flow: { nodes: [...], edges: [...] }.
589
603
  salvar o flow pela tela nesse estado, a regra e PERDIDA. (Excecoes que nao usam field/valueType
590
604
  "variable": regras por attr_key/attrSource="attr_config", business_hours, can_reply, sla_check,
591
605
  kanban_*, conversation_has_agent/no_agent, pagetrack_*.)
606
+ ORIGEM / CAMPANHA (NOVO 01/09 — preset "Atributo de campanha" da tela): regra de atributo da CONVERSA:
607
+ { id, valueType:'attr_config', attrSource:'conversation', attrScope:'campaign', attr_key:'origin_kind',
608
+ operator:'equal', value:'paid_ad' }
609
+ O motor le attrSource+attr_key (conversation.custom_attributes[attr_key]); valueType e attrScope sao
610
+ marcadores de TELA (sem attrScope reabre no card generico "Atributo da conversa" — roda igual).
611
+ Chaves de campanha: origin_kind, origin_platform, origin_first_kind/_platform, origin_last_kind/_platform,
612
+ ctwa_* (anuncio click-to-WhatsApp: ctwa_ad_id, ctwa_ad_title, ctwa_campaign_name, ctwa_adset_name...),
613
+ meta_lead_* (formulario Meta Lead Ads), lt_* (LionTrack: UTMs, pagina, dispositivo). Lista real:
614
+ lionchat_custom_attributes_list {attribute_model:'conversation', include_system:true}.
615
+ VALORES FECHADOS de origin_kind (e first/last): paid_ad (Anuncio), lead_form (Formulario), organic
616
+ (Organico), direct (Direto), referral (Indicacao), manual (Origem cadastrada) — compara pelo VALOR, nunca
617
+ pelo rotulo ("Anuncio" nunca casa). origin_platform: facebook, instagram, google, tiktok, linkedin, youtube,
618
+ whatsapp, direct, e origem cadastrada pelo cliente = 'custom:<slug>' (ex 'custom:indicacao-de-amigo';
619
+ lionchat_lead_origins_list) — filtre com contains + palavra do slug ou equal + 'custom:<slug>'.
620
+ Caso real (Cast 01/09): "Ativar IA so para lead de anuncio" = cond_0 {origin_kind equal paid_ad} ->
621
+ assign_captain; default sem nada.
592
622
  Agrupar E/OU: cada saida pode trocar a regra plana por rules[]+logic:
593
623
  { id, label, logic: "and"|"or", rules: [ {field,operator,value,valueType}, ... ] }
594
624
  logic ausente = "and"; ate 10 regras por saida; sem rules = grupo de 1 (retrocompat).
@@ -685,7 +715,21 @@ flow_data tem o formato Vue Flow: { nodes: [...], edges: [...] }.
685
715
  grava valor personalizado, senao usa o valor cadastrado; total do card recalcula sozinho
686
716
  Sistema (SO flow conversation): send_webhook({url,headers?,body?}), start_flow({flow_id}
687
717
  — flow_id tem que ser de OUTRO flow: apontar pro proprio flow e aceito no save mas IGNORADO
688
- EM SILENCIO na execucao, e o fluxo para ali [2026-08-18]), deactivate_flow({})
718
+ EM SILENCIO na execucao, e o fluxo para ali [2026-08-18]), deactivate_flow({}),
719
+ send_conversion({destinations:['meta'|'ga4'|'google_ads'], event_name, value?}) — NOVO 01/09: manda o
720
+ evento de conversao pro Meta (CAPI), Google Ads e/ou GA4 pelos MESMOS servicos do Funil.
721
+ destinations OBRIGATORIO e nao vazio; so destino com integracao conectada na conta (senao o servico
722
+ PULA em silencio — confira meta_pixel_integrations_list / google_ads_integrations_list /
723
+ ga4_integrations_list antes). event_name OBRIGATORIO: letras/numeros/sublinhado ate 40 (Lead,
724
+ Schedule, Purchase), aceita variavel; no Google Ads precisa estar no conversion_action_map.
725
+ value opcional (virgula BR ok, variavel ok); VAZIO = valor do CARD; sem card = sem valor.
726
+ CARD do evento: o que iniciou o fluxo (gatilho de card) ou, sem ele, o card mais recente da conversa
727
+ (mesma busca das acoes de card). Com card aparece na aba Atividades do card e nas telas de eventos do
728
+ Funil (funnels_meta_capi_events_list e irmas); SEM card so existe no historico do fluxo.
729
+ DEDUP: 1 conversao por (sessao do fluxo, bloco) — event_id lc_flow_<sessao>_<bloco>_evt_<evento>;
730
+ o mesmo lead passando 2x pelo mesmo bloco NAO duplica, leads diferentes sim. Historico do passo mostra
731
+ uma linha por destino: "Meta: enfileirado (registro #N)" / "GA4: pulado (...)" / "Meta: erro (...)".
732
+ Falha de um destino nunca derruba o fluxo. Dry-run nao dispara.
689
733
  card_source (acoes de card): 'funnel' (default, acha o card pelo funnel_id) | 'trigger' (usa o card
690
734
  que DISPAROU o flow em card_created/card_moved/card_won/card_lost). Com 'trigger' o funnel_id e
691
735
  ignorado — EXCETO create_kanban_item/move_kanban_stage (funil = DESTINO). Vale pra move_kanban_stage,
package/dist/tools.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/endpoints.json CHANGED
@@ -173,7 +173,7 @@
173
173
  "method": "POST",
174
174
  "path": "/api/v1/accounts/{account_id}/contacts",
175
175
  "title": "Criar Contato",
176
- "description": "Cria um contato. Nenhum campo e estritamente obrigatorio (recomendado phone_number ou email). Aceita name, email, phone_number, identifier, additional_attributes, custom_attributes, blocked.",
176
+ "description": "Cria um contato. Nenhum campo e estritamente obrigatorio (recomendado phone_number ou email). Aceita name, email, phone_number, identifier, additional_attributes, custom_attributes, blocked. TELEFONE UNICO POR CONTA (trava no BANCO desde 01/09/2026, como e-mail e identifier): phone_number ja cadastrado em outro contato da conta = 422 'phone_number has already been taken' — inclusive em chamadas paralelas. Procure antes com contacts_search (acha com e sem o 9o digito) e use contacts_update no que existe.",
177
177
  "category": "Contatos",
178
178
  "params": [
179
179
  {
@@ -283,7 +283,7 @@
283
283
  "method": "PATCH",
284
284
  "path": "/api/v1/accounts/{account_id}/contacts/{id}",
285
285
  "title": "Atualizar Contato",
286
- "description": "Atualiza um contato. Aceita name, email, phone_number, identifier, custom_attributes, additional_attributes, blocked, avatar/avatar_url. NUNCA sobrescreva phone_number/email ja preenchido sem confirmacao.",
286
+ "description": "Atualiza um contato. Aceita name, email, phone_number, identifier, custom_attributes, additional_attributes, blocked, avatar/avatar_url. NUNCA sobrescreva phone_number/email ja preenchido sem confirmacao. TELEFONE UNICO POR CONTA (trava no banco desde 01/09/2026): trocar phone_number para um numero que ja e de outro contato da conta = 422 'phone_number has already been taken'.",
287
287
  "category": "Contatos",
288
288
  "params": [
289
289
  {
@@ -904,7 +904,7 @@
904
904
  "method": "POST",
905
905
  "path": "/api/v1/accounts/{account_id}/contacts/import",
906
906
  "title": "Importar Contatos",
907
- "description": "Importa contatos em lote via CSV. **Requer perfil Administrador.**. Cria novo contato. Obrigatórios: import_file. Valida unicidade quando aplicável. Retorna o contato criado com ID atribuído. REGRA DO DDI (18/08): o telefone precisa vir COM o codigo do pais (5511988887777 ou +351912345678; o + e opcional). O sistema NAO completa mais 55: sem DDI ou numero que nao existe em pais nenhum = ERRO na linha (o contato nao e criado; o relatorio de erros mostra linha a linha); comecando com 0 = recusado; brasileiro com 55 e 12-13 digitos e aceito mesmo no formato antigo sem o 9o digito.",
907
+ "description": "Importa contatos em lote via CSV. **Requer perfil Administrador.**. Cria novo contato. Obrigatórios: import_file. Valida unicidade quando aplicável. Retorna o contato criado com ID atribuído. REGRA DO DDI (18/08): o telefone precisa vir COM o codigo do pais (5511988887777 ou +351912345678; o + e opcional). O sistema NAO completa mais 55: sem DDI ou numero que nao existe em pais nenhum = ERRO na linha (o contato nao e criado; o relatorio de erros mostra linha a linha); comecando com 0 = recusado; brasileiro com 55 e 12-13 digitos e aceito mesmo no formato antigo sem o 9o digito. TELEFONE UNICO POR CONTA (trava no BANCO desde 01/09/2026, como e-mail e identifier): linha com telefone que ja e de outro contato da conta e recusada 'phone_number has already been taken' — inclusive em chamadas paralelas. Procure antes com contacts_search (acha com e sem o 9o digito) e use contacts_update no que existe.",
908
908
  "category": "Contatos",
909
909
  "params": [
910
910
  {
@@ -7228,7 +7228,7 @@
7228
7228
  "method": "PATCH",
7229
7229
  "path": "/api/v1/accounts/{account_id}/canned_responses/{id}",
7230
7230
  "title": "Atualizar Resposta Rápida",
7231
- "description": "Atualiza uma resposta rápida. Atualiza campos do resposta rápida existente. Suporta atualização parcial (PATCH) — só campos enviados são alterados. Campos suportados: short_code, content, blocks.",
7231
+ "description": "Atualiza uma resposta rápida. Atualiza campos do resposta rápida existente. Suporta atualização parcial (PATCH) — só campos enviados são alterados. Campos suportados: short_code, content, blocks. ATENÇÃO: os BLOCOS são a fonte da verdade — é o que o cliente recebe. Numa resposta feita de blocos, enviar só `content` NÃO altera nada (o servidor reescreve `content` a partir do primeiro bloco a cada gravação); mande `blocks` com o array inteiro. Chamar assim é RECUSADO pelo conector, com aviso.",
7232
7232
  "category": "Respostas Rapidas",
7233
7233
  "params": [
7234
7234
  {
@@ -7250,14 +7250,14 @@
7250
7250
  "type": "string",
7251
7251
  "location": "body",
7252
7252
  "required": false,
7253
- "description": "Conteudo, dentro de canned_response"
7253
+ "description": "Conteudo, dentro de canned_response. É apenas uma CÓPIA usada para busca/preview: numa resposta que tem `blocks`, o servidor reescreve este campo a partir do primeiro bloco de texto em toda gravação. Para mudar o texto que o cliente recebe, envie `blocks` (e, de preferência, `content` igual ao primeiro bloco de texto)."
7254
7254
  },
7255
7255
  {
7256
7256
  "name": "blocks",
7257
7257
  "type": "array",
7258
7258
  "location": "body",
7259
7259
  "required": false,
7260
- "description": "Blocos, dentro de canned_response. Bloco de MIDIA aceita `caption` (legenda que vai colada na midia, como no WhatsApp) desde 29/08/2026 — antes era preciso um bloco de midia + um de texto. O disparo le `content || caption`. NAO use em bloco de audio: nenhum canal mostra legenda em nota de voz."
7260
+ "description": "Blocos, dentro de canned_response. FONTE DA VERDADE do que o cliente recebe — para alterar o texto, mande o array INTEIRO com o conteúdo novo. Bloco de MIDIA aceita `caption` (legenda que vai colada na midia, como no WhatsApp) desde 29/08/2026 — antes era preciso um bloco de midia + um de texto. O disparo le `content || caption`. NAO use em bloco de audio: nenhum canal mostra legenda em nota de voz."
7261
7261
  },
7262
7262
  {
7263
7263
  "name": "requires_official_api",
@@ -9596,7 +9596,7 @@
9596
9596
  "method": "POST",
9597
9597
  "path": "/api/v1/accounts/{account_id}/flows",
9598
9598
  "title": "Criar Flow",
9599
- "description": "Cria um flow (FlowBuilder) na conta. Requer Admin. flow_data segue formato Vue Flow {nodes:[], edges:[]}. NODE SCHEMA — start: {label}. send_message: {label, messageItems:[{id, type:'text', content}]} handles: success/no_response/error. wait_response: {label, waitTime, waitUnit:'minutes'|'seconds', validation:'any'|'options'|'regex', acceptedOptions:['1','2'] (se options), regexPattern (se regex), invalidMessage, maxRetries:3, saveTo:'variable'|'contact_name'|'contact_email'|'contact_phone'|'contact_attr'|'conversation_attr'|'', saveVariable, saveAttrKey} — quando validation='options' os handles ficam 'option_{val}' + 'timeout'; senão 'success' + 'timeout' — NUNCA precisa de condition node depois. condition: {label, conditions:[{id, label, field, operator, value}]} handles = 'cond_0','cond_1',... (INDICE no array, NAO o id) + 'default'. action: {label, items:[{key, config:{...}}]} keys comuns assign_team({team_id}), assign_agent({agent_id}), add_label({labels:['slug',...]}), remove_label({labels}), change_status({status}), change_priority({priority}), mute_conversation({}), add_private_note({content}), create_kanban_item({funnel_id, funnel_stage,...}), move_kanban_stage({funnel_id, funnel_stage}), deactivate_flow({}), assign_captain({assistant_id}). api: {label, method, url, headers:[{key,value}], body, apiResponseVar}. set_variable: {label, variables:[{name, value}]}. wait: {label, waitTime, waitUnit}. EDGE SCHEMA: {id, source, target, sourceHandle (opcional, OBRIGATORIO casar com handle exposto pelo node source), type:'deletable', animated:true}. ERROS COMUNS QUE DEVEM SER EVITADOS: (1) action usa items[].config NAO items[].params; (2) send_message usa messageItems NAO items; (3) wait_response com validation='options' NAO precisa de condition node — use sourceHandle='option_X' diretamente; (4) sourceHandle inventado tipo 'c1','c2' nao funciona — sempre usar o handle real; (5) inbox_ids precisa vir aninhado em {flow:{inbox_ids:[]}} no PUT bruto, mas no MCP basta inbox_ids no nivel raiz. Cria novo flow. Obrigatórios: name, channel_type. Valida unicidade quando aplicável. Retorna o flow criado com ID atribuído. POSITIONING (CRITICO): cada node DEVE ter position:{x,y}. Sem isso, todos empilham no canvas no (0,0). Regra basica de layout: start em {x:50,y:300}, espaco horizontal +320 entre nodes sequenciais, ramificacoes em +/-150 vertical. ANTES DE GERAR JSON consulte o resource lionchat://docs/flowbuilder-design-guide (schema completo de cada tipo de node, handles expostos, erros comuns, checklist) e lionchat://docs/flowbuilder-patterns (10 templates prontos pra adaptar). BRAINSTORMING: se faltou info critica (canal, gatilho, conteudo), use o prompt create_flow_brainstorm como banco de perguntas sugeridas — pergunte SO o que falta, sem checklist forcado. APOS GERAR: rode o checklist da secao 6 do design guide antes de submeter (1 node start, todo node com id unico + position + data, todo edge com sourceHandle valido). NUNCA invente sourceHandle (no condition use cond_0/cond_1/default, no wait_response options use option_X, no AI intent use intent_<opcao>). IMPORTANTE: chame lionchat_flows_schema_reference antes pra ver o schema COMPLETO e atualizado (nodes end/ai/note, etiqueta conversa vs contato, webhook embutido, timeout, anti-loop). Pra ferramentas da IA (ai_tool) use lionchat_flow_tools_create. conversation_mode: 'individual' (default) | 'group'. Sticky note (type 'note'): data usa title+body+color(yellow|teal|blue|violet|pink|orange|slate)+width+height — NUNCA 'content'. ORGANIZAÇÃO: preencha tags ao criar (reutilizando as tags já existentes nos flows da conta — veja flows_list) pra manter a lista organizada. STICKY NOTE: o texto da nota (type note) vai em data.title + data.body — content/label/text deixam a nota EM BRANCO na tela; nunca crie nota sem body. LAYOUT: espace os nodes (colunas a >=320px no x, ramos a >=180px no y; notas AO LADO/ACIMA do trecho, nunca sobre nodes ou linhas). REGRAS 18/08: acao start_flow com flow_id do PROPRIO flow e aceita no save mas IGNORADA EM SILENCIO na execucao (o fluxo para ali) — aponte sempre pra OUTRO flow. Condicoes: preencha operator E field juntos (tabela dos pares no resource flowbuilder-patterns), senao a regra roda certa e aparece errada na tela do cliente.",
9599
+ "description": "Cria um flow (FlowBuilder) na conta. Requer Admin. flow_data segue formato Vue Flow {nodes:[], edges:[]}. NODE SCHEMA — start: {label}. send_message: {label, messageItems:[{id, type:'text', content}]} handles: success/no_response/error. wait_response: {label, waitTime, waitUnit:'minutes'|'seconds', validation:'any'|'options'|'regex', acceptedOptions:['1','2'] (se options), regexPattern (se regex), invalidMessage, maxRetries:3, saveTo:'variable'|'contact_name'|'contact_email'|'contact_phone'|'contact_attr'|'conversation_attr'|'', saveVariable, saveAttrKey} — quando validation='options' os handles ficam 'option_{val}' + 'timeout'; senão 'success' + 'timeout' — NUNCA precisa de condition node depois. condition: {label, conditions:[{id, label, field, operator, value}]} handles = 'cond_0','cond_1',... (INDICE no array, NAO o id) + 'default'. action: {label, items:[{key, config:{...}}]} keys comuns assign_team({team_id}), assign_agent({agent_id}), add_label({labels:['slug',...]}), remove_label({labels}), change_status({status}), change_priority({priority}), mute_conversation({}), add_private_note({content}), create_kanban_item({funnel_id, funnel_stage,...}), move_kanban_stage({funnel_id, funnel_stage}), deactivate_flow({}), assign_captain({assistant_id}). api: {label, method, url, headers:[{key,value}], body, apiResponseVar}. set_variable: {label, variables:[{name, value}]}. wait: {label, waitTime, waitUnit}. EDGE SCHEMA: {id, source, target, sourceHandle (opcional, OBRIGATORIO casar com handle exposto pelo node source), type:'deletable', animated:true}. ERROS COMUNS QUE DEVEM SER EVITADOS: (1) action usa items[].config NAO items[].params; (2) send_message usa messageItems NAO items; (3) wait_response com validation='options' NAO precisa de condition node — use sourceHandle='option_X' diretamente; (4) sourceHandle inventado tipo 'c1','c2' nao funciona — sempre usar o handle real; (5) inbox_ids precisa vir aninhado em {flow:{inbox_ids:[]}} no PUT bruto, mas no MCP basta inbox_ids no nivel raiz. Cria novo flow. Obrigatórios: name, channel_type. Valida unicidade quando aplicável. Retorna o flow criado com ID atribuído. POSITIONING (CRITICO): cada node DEVE ter position:{x,y}. Sem isso, todos empilham no canvas no (0,0). Regra basica de layout: start em {x:50,y:300}, espaco horizontal +320 entre nodes sequenciais, ramificacoes em +/-150 vertical. ANTES DE GERAR JSON consulte o resource lionchat://docs/flowbuilder-design-guide (schema completo de cada tipo de node, handles expostos, erros comuns, checklist) e lionchat://docs/flowbuilder-patterns (10 templates prontos pra adaptar). BRAINSTORMING: se faltou info critica (canal, gatilho, conteudo), use o prompt create_flow_brainstorm como banco de perguntas sugeridas — pergunte SO o que falta, sem checklist forcado. APOS GERAR: rode o checklist da secao 6 do design guide antes de submeter (1 node start, todo node com id unico + position + data, todo edge com sourceHandle valido). NUNCA invente sourceHandle (no condition use cond_0/cond_1/default, no wait_response options use option_X, no AI intent use intent_<opcao>). IMPORTANTE: chame lionchat_flows_schema_reference antes pra ver o schema COMPLETO e atualizado (nodes end/ai/note, etiqueta conversa vs contato, webhook embutido, timeout, anti-loop). Pra ferramentas da IA (ai_tool) use lionchat_flow_tools_create. conversation_mode: 'individual' (default) | 'group'. Sticky note (type 'note'): data usa title+body+color(yellow|teal|blue|violet|pink|orange|slate)+width+height — NUNCA 'content'. ORGANIZAÇÃO: preencha tags ao criar (reutilizando as tags já existentes nos flows da conta — veja flows_list) pra manter a lista organizada. STICKY NOTE: o texto da nota (type note) vai em data.title + data.body — content/label/text deixam a nota EM BRANCO na tela; nunca crie nota sem body. LAYOUT: espace os nodes (colunas a >=320px no x, ramos a >=180px no y; notas AO LADO/ACIMA do trecho, nunca sobre nodes ou linhas). REGRAS 18/08: acao start_flow com flow_id do PROPRIO flow e aceita no save mas IGNORADA EM SILENCIO na execucao (o fluxo para ali) — aponte sempre pra OUTRO flow. Condicoes: preencha operator E field juntos (tabela dos pares no resource flowbuilder-patterns), senao a regra roda certa e aparece errada na tela do cliente. NOVIDADES 01/09/2026 no schema (lionchat_flows_schema_reference): acao send_conversion (Meta/Google Ads/GA4 de dentro do fluxo) e condicao por origem/campanha (attr_config de conversa com origin_kind=paid_ad etc.).",
9600
9600
  "category": "Flows",
9601
9601
  "params": [
9602
9602
  {
@@ -9691,7 +9691,7 @@
9691
9691
  "method": "PUT",
9692
9692
  "path": "/api/v1/accounts/{account_id}/flows/{id}",
9693
9693
  "title": "Atualizar Flow",
9694
- "description": "Atualiza nome, descricao, caixas de entrada ou dados dos blocos. Mesmo schema de flow_data do tool lionchat_flows_create — consulte a descricao daquele tool para o schema completo dos nodes (start, send_message, wait_response, condition, action, api, set_variable) e dos edges. RECAP RAPIDO: action items[].config (nao params); send_message messageItems (nao items); wait_response validation='options' gera handles 'option_X' (dispensa condition node); edges sourceHandle DEVE casar com handle real do node source. Atualiza campos do flow existente. Suporta atualização parcial (PATCH) — só campos enviados são alterados. Campos suportados: name, description, inbox_ids, flow_data. IMPORTANTE: chame lionchat_flows_schema_reference antes pra ver o schema COMPLETO e atualizado (nodes end/ai/note, etiqueta conversa vs contato, webhook embutido, timeout, anti-loop). Pra ferramentas da IA (ai_tool) use lionchat_flow_tools_create. STICKY NOTE: o texto da nota (type note) vai em data.title + data.body — content/label/text deixam a nota EM BRANCO na tela; nunca crie nota sem body. LAYOUT: espace os nodes (colunas a >=320px no x, ramos a >=180px no y; notas AO LADO/ACIMA do trecho, nunca sobre nodes ou linhas). REGRAS 18/08: acao start_flow com flow_id do PROPRIO flow e aceita no save mas IGNORADA EM SILENCIO na execucao (o fluxo para ali) — aponte sempre pra OUTRO flow. Condicoes: preencha operator E field juntos (tabela dos pares no resource flowbuilder-patterns), senao a regra roda certa e aparece errada na tela do cliente.",
9694
+ "description": "Atualiza nome, descricao, caixas de entrada ou dados dos blocos. Mesmo schema de flow_data do tool lionchat_flows_create — consulte a descricao daquele tool para o schema completo dos nodes (start, send_message, wait_response, condition, action, api, set_variable) e dos edges. RECAP RAPIDO: action items[].config (nao params); send_message messageItems (nao items); wait_response validation='options' gera handles 'option_X' (dispensa condition node); edges sourceHandle DEVE casar com handle real do node source. Atualiza campos do flow existente. Suporta atualização parcial (PATCH) — só campos enviados são alterados. Campos suportados: name, description, inbox_ids, flow_data. IMPORTANTE: chame lionchat_flows_schema_reference antes pra ver o schema COMPLETO e atualizado (nodes end/ai/note, etiqueta conversa vs contato, webhook embutido, timeout, anti-loop). Pra ferramentas da IA (ai_tool) use lionchat_flow_tools_create. STICKY NOTE: o texto da nota (type note) vai em data.title + data.body — content/label/text deixam a nota EM BRANCO na tela; nunca crie nota sem body. LAYOUT: espace os nodes (colunas a >=320px no x, ramos a >=180px no y; notas AO LADO/ACIMA do trecho, nunca sobre nodes ou linhas). REGRAS 18/08: acao start_flow com flow_id do PROPRIO flow e aceita no save mas IGNORADA EM SILENCIO na execucao (o fluxo para ali) — aponte sempre pra OUTRO flow. Condicoes: preencha operator E field juntos (tabela dos pares no resource flowbuilder-patterns), senao a regra roda certa e aparece errada na tela do cliente. NOVIDADES 01/09/2026 no schema (lionchat_flows_schema_reference): acao send_conversion (Meta/Google Ads/GA4 de dentro do fluxo) e condicao por origem/campanha (attr_config de conversa com origin_kind=paid_ad etc.).",
9695
9695
  "category": "Flows",
9696
9696
  "params": [
9697
9697
  {
@@ -18709,7 +18709,7 @@
18709
18709
  "method": "GET",
18710
18710
  "path": "/api/v1/accounts/{account_id}/integrations/meta_lead",
18711
18711
  "title": "Listar Paginas Meta Lead Ads",
18712
- "description": "Lista as integracoes Meta Lead Ads conectadas. NOVO (2026-06): conexao agora e POR PAGINA selecionada (BM virou rotulo); resposta traz enrichment_active e pending_businesses (BMs com pendencia).",
18712
+ "description": "Lista as integracoes Meta Lead Ads conectadas. NOVO (2026-06): conexao agora e POR PAGINA selecionada (BM virou rotulo); resposta traz enrichment_active e pending_businesses (BMs com pendencia). A resposta traz tambem, no nivel da conta, ads_capable e has_manual_ads_token (situacao do token de ANUNCIOS): calculados sobre as integracoes ligadas, ou sobre todas se nenhuma estiver ligada (01/09/2026).",
18713
18713
  "category": "Meta Lead Ads",
18714
18714
  "params": [],
18715
18715
  "returns": "{ data: [...integracoes...] }",
@@ -31610,7 +31610,7 @@
31610
31610
  "method": "POST",
31611
31611
  "path": "/api/v1/accounts/{account_id}/integrations/meta_lead/ads_token",
31612
31612
  "title": "Gravar Token de Anuncios (Meta Lead)",
31613
- "description": "[POST] Grava o token de ANUNCIOS da Meta colado a mao pelo cliente — e de CONTA (vale pra todas as paginas conectadas), nao de pagina. Com ele os leads passam a mostrar NOME de campanha/conjunto/anuncio em vez de so ids, e o servidor ja reprocessa retroativamente os leads que ficaram sem nome. Mandar vazio LIMPA o token. Valide antes com meta_lead_validate_token. Resposta: {meta} com a situacao do token. A resposta e {meta:{ads_capable, has_manual_ads_token}} — os MESMOS booleanos que aparecem em cada integracao do meta_lead_list (e no meta de conta): ads_capable = a conta consegue resolver nomes; has_manual_ads_token = ha token colado a mao. Os campos com os NOMES ja resolvidos moram em conversation.custom_attributes com prefixo ctwa_ (conversa vinda de anuncio) e em contact.custom_attributes com prefixo meta_lead_ (lead de formulario) — existem desde antes; o token so habilita o preenchimento.",
31613
+ "description": "[POST] Grava o token de ANUNCIOS da Meta colado a mao pelo cliente — e de CONTA (vale pra todas as paginas conectadas), nao de pagina. Com ele os leads passam a mostrar NOME de campanha/conjunto/anuncio em vez de so ids, e o servidor ja reprocessa retroativamente os leads que ficaram sem nome. Mandar vazio LIMPA o token. Valide antes com meta_lead_validate_token. Resposta: {meta} com a situacao do token. A resposta e {meta:{ads_capable, has_manual_ads_token}} — os MESMOS booleanos que aparecem em cada integracao do meta_lead_list (e no meta de conta): ads_capable = a conta consegue resolver nomes; has_manual_ads_token = ha token colado a mao. Os campos com os NOMES ja resolvidos moram em conversation.custom_attributes com prefixo ctwa_ (conversa vinda de anuncio) e em contact.custom_attributes com prefixo meta_lead_ (lead de formulario) — existem desde antes; o token so habilita o preenchimento. ATUALIZADO 01/09/2026: o resumo (ads_capable/has_manual_ads_token) e calculado sobre as integracoes LIGADAS e, se nenhuma estiver ligada, sobre todas — antes uma conta com todas as paginas desligadas parecia 'sem token' mesmo com token gravado. Pagina com token_expired continua precisando de reconexao por admin da pagina; o token de anuncios nao resolve isso.",
31614
31614
  "category": "Integracoes",
31615
31615
  "params": [
31616
31616
  {
@@ -31635,7 +31635,7 @@
31635
31635
  "method": "POST",
31636
31636
  "path": "/api/v1/accounts/{account_id}/integrations/meta_lead/validate_token",
31637
31637
  "title": "Testar Token de Anuncios (Meta Lead)",
31638
- "description": "[POST] Confere o token de anuncios NA HORA, sem gravar nada: valido? de qual app? quais permissoes? alcanca anuncio de verdade? Sem manual_ads_token no corpo, testa o token JA SALVO. Resposta: {data} com o raio-x do token. Use pra diagnosticar 'os leads chegam so com id de campanha' antes de pedir token novo ao cliente.",
31638
+ "description": "[POST] Confere o token de anuncios NA HORA, sem gravar nada: valido? de qual app? quais permissoes? alcanca anuncio de verdade? Sem manual_ads_token no corpo, testa o token JA SALVO. Resposta: {data} com o raio-x do token. Use pra diagnosticar 'os leads chegam so com id de campanha' antes de pedir token novo ao cliente. ATUALIZADO 01/09/2026: token de OUTRO app da Meta (usuario de sistema da BM do cliente) tambem e testado — antes voltava '(#100) App_id did not match' para token VALIDO, porque o debug_token so responde para tokens do nosso app. Nesse caso a resposta vem com app_verified:false e app_id/app_name/token_type/expires_at NULOS (nao ha como saber sem o debug_token — NAO afirme 'nunca expira'), permissions (so as concedidas, lidas em me/permissions) e ads_check {ok, ad_accounts_count} — e o ads_check que prova que o token alcanca anuncio. Token do nosso app segue com app_verified:true e validade. valid:false so quando o token realmente nao responde.",
31639
31639
  "category": "Integracoes",
31640
31640
  "params": [
31641
31641
  {
@@ -31646,7 +31646,7 @@
31646
31646
  "description": "Token a testar. Ausente = testa o token salvo na conta."
31647
31647
  }
31648
31648
  ],
31649
- "returns": "{data: diagnostico do token}",
31649
+ "returns": "{data: diagnostico do token — valid, app_verified (false = token de outro app: app/validade desconhecidos), app_id, app_name, expires_at, permissions[{key,granted}], extra_scopes, ads_check{ok, ad_accounts_count|error}}",
31650
31650
  "common_use_cases": [
31651
31651
  "Diagnosticar por que o nome da campanha nao aparece nos leads"
31652
31652
  ],
@@ -32003,7 +32003,7 @@
32003
32003
  "method": "PATCH",
32004
32004
  "path": "/api/v1/accounts/{account_id}/eclinica_integrations/{id}",
32005
32005
  "title": "Configurar Integração e-Clínica (mapeamento de eventos e lembretes)",
32006
- "description": "AÇÃO DE ESCRITA, somente administrador. Configura a integração e-Clínica: o MAPEAMENTO evento→automação/fluxo (event_mapping) e os LEMBRETES automáticos (reminder_config). Até 31/08/2026 os dois só existiam na tela — este comando fecha a lacuna.\n\nSUBSTITUIÇÃO TOTAL — LEIA ANTES DE GRAVAR: os dois campos SUBSTITUEM o conteúdo inteiro, NÃO mesclam (o backend faz update! direto no jsonb). Mandar event_mapping com um evento só APAGA todos os outros mapeamentos do cliente; o mesmo vale pra reminder_config. SEMPRE chame lionchat_eclinica_integrations_show ANTES, pegue o objeto atual, altere só o que precisa e devolva o objeto COMPLETO.\n\nevent_mapping: objeto {tipo_do_evento: {automation_id, flow_id}} — pode deixar um dos dois nulo. Tipos aceitos: cliente_novo, cliente_alteracao, agendamento_novo, agendamento_alterado, agendamento_atendido, agendamento_desmarcado, agendamento_transferido, falta, pagamento, cliente_baixa_pagamento, cliente_inclusao_pagamento, controle_laboratorio_novo, controle_laboratorio_alterado, agendamento_aguardando, odontograma_aprovado, procedimento_finalizado (NOVO 31/08 — um procedimento do plano de tratamento foi concluído; dispara UMA VEZ POR PROCEDIMENTO e grava eclinica_procedimento_id/_dente/_valor/_finalizado_em/_profissional no contato, então o fluxo ligado aqui precisa filtrar pelo número do procedimento). Tipo fora da lista = 422; flow_id e automation_id precisam ser da PRÓPRIA conta = 422 senão.\n\nreminder_config: array de {days_before (inteiro >= 0), event_type ('agendamento' padrão | 'controle_laboratorio_novo' | 'cliente_inclusao_pagamento'), flow_id e/ou automation_id (pelo menos um dos dois; com os dois a AUTOMAÇÃO vence), label, dispatch_time (OBRIGATÓRIA — 'HH:MM' fixo ou fórmula Liquid), filter_field/filter_operator/filter_value (opcional; filter_field precisa começar com eclinica_, operadores contains/equal/not_equal)}. Duas linhas com a MESMA régua = 422.\n\nALERTA de regra de negócio: isto muda, na hora e em produção, o que o paciente recebe. E no lembrete por automação as AÇÕES rodam SEM avaliar as CONDIÇÕES da automação — paciente com duas consultas no dia recebe DOIS lembretes (o caminho por fluxo descarta o segundo).",
32006
+ "description": "AÇÃO DE ESCRITA, somente administrador. Configura a integração e-Clínica: o MAPEAMENTO evento→automação/fluxo (event_mapping) e os LEMBRETES automáticos (reminder_config). Até 31/08/2026 os dois só existiam na tela — este comando fecha a lacuna.\n\nSUBSTITUIÇÃO TOTAL — LEIA ANTES DE GRAVAR: os dois campos SUBSTITUEM o conteúdo inteiro, NÃO mesclam (o backend faz update! direto no jsonb). Mandar event_mapping com um evento só APAGA todos os outros mapeamentos do cliente; o mesmo vale pra reminder_config. SEMPRE chame lionchat_eclinica_integrations_show ANTES, pegue o objeto atual, altere só o que precisa e devolva o objeto COMPLETO.\n\nevent_mapping: objeto {tipo_do_evento: {automation_id, flow_id}} — pode deixar um dos dois nulo. Tipos aceitos: cliente_novo, cliente_alteracao, agendamento_novo, agendamento_alterado, agendamento_atendido, agendamento_desmarcado, agendamento_transferido, falta, pagamento, cliente_baixa_pagamento, cliente_inclusao_pagamento, controle_laboratorio_novo, controle_laboratorio_alterado, agendamento_aguardando, odontograma_aprovado, cliente_alteracao_pagamento (NOVO 01/09 — a cobrança foi EDITADA: mesmos campos da inclusão e o lembrete de vencimento é MOVIDO, não duplicado; dispara a cada edição, então não sirva para avisar \"nova cobrança\"), procedimento_finalizado (NOVO 31/08 — um procedimento do plano de tratamento foi concluído; dispara UMA VEZ POR PROCEDIMENTO e grava eclinica_procedimento_id/_dente/_valor/_finalizado_em/_profissional no contato, então o fluxo ligado aqui precisa filtrar pelo número do procedimento). odontograma_finalizado (NOVO 01/09 — o plano de tratamento INTEIRO foi concluido; nao confundir com procedimento_finalizado, que e UM item do plano; grava eclinica_odontograma_finalizado_em e nao mexe na data de aprovacao), inclusao_procedimento (NOVO 01/09 — um procedimento foi ACRESCENTADO ao plano, ainda nao executado: serve para aviso de orcamento, NAO e gatilho de orientacao pos-procedimento; grava eclinica_procedimento_incluido_id/_dente/_valor, nunca nos campos do finalizado). Tipo fora da lista = 422; flow_id e automation_id precisam ser da PRÓPRIA conta = 422 senão.\n\nreminder_config: array de {days_before (inteiro >= 0), event_type ('agendamento' padrão | 'controle_laboratorio_novo' | 'cliente_inclusao_pagamento'), flow_id e/ou automation_id (pelo menos um dos dois; com os dois a AUTOMAÇÃO vence), label, dispatch_time (OBRIGATÓRIA — 'HH:MM' fixo ou fórmula Liquid), filter_field/filter_operator/filter_value (opcional; filter_field precisa começar com eclinica_, operadores contains/equal/not_equal)}. Duas linhas com a MESMA régua = 422.\n\nALERTA de regra de negócio: isto muda, na hora e em produção, o que o paciente recebe. E no lembrete por automação as AÇÕES rodam SEM avaliar as CONDIÇÕES da automação — paciente com duas consultas no dia recebe DOIS lembretes (o caminho por fluxo descarta o segundo).",
32007
32007
  "category": "Integracoes",
32008
32008
  "params": [
32009
32009
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lionchat/mcp-server",
3
- "version": "1.19.0",
3
+ "version": "1.19.1",
4
4
  "description": "MCP server for LionChat API — 547 tools + 10 resources + 9 prompts. Audit-log aware, completion API, progress notifications.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",