Pular para conteúdo

Conteudo Infinito — Referencia Tecnica

Atualizado: 2026-07-08 · por: sessão manual · aprovação em princípio da segmentação de clusters · rev: 5

IDs, credenciais, endpoints, custom fields, SQL schemas. Para arquitetura, ver ARQUITETURA.md.


Workflows n8n

Workflow ID Trigger Status
WF0 — A Ignicao 19v9V6NEIsJgpS3j Manual Ativo
WF1 — Motor de IA 3ZQCpuNIDjpnFlKH Schedule */5 8-17 * * 1-5 Ativo (auto-pausa)
WF2 — Fila de Disparo hyzhklpo9J4cbyIJ Webhook Ativo
WF3 — Gestao de Cadencia ny4gXcNU3dReDCba Webhook /nutricao-cadencia Ativo
WF4 — Opt-out Email paffbqyOJHAafePk Webhook Ativo
WF-Resumo-IA BL3me3JQiVmSbzn3 Manual Ativo
Cadastro Pool Conteudos p2LkQufi7fJlfUEx Form trigger Ativo
Probe (diagnostico) toquIjzNhIsNN59O Manual Ativo

URLs: - n8n: https://n8n.bepex.com.br - Webhook producao: https://n8n-hook.bepex.com.br - WF3 webhook: https://n8n.bepex.com.br/webhook/nutricao-cadencia


Credenciais n8n

Nome ID Tipo
Pipedrive account CHj11AO6T3756SqM pipedriveApi (rw)
Postgres n8n v2 7F3gxDoPsQGjAbOW postgres
Redis account LF7uoxStfwXCb9Gx redis

Auth headers para REST API:

browser-id: <ler do localStorage (n8n-client-id) — não hardcodar>
push-ref: sessionStorage.getItem('n8n-client-id')  // muda a cada F5


Cenarios Make.com

Cenario ID
Vendas1 3971432
Vendas2 3960338
Vendas3 3960351
Vendas4 3971434
Vendas5 3971438
Vendas6 3960363
Principal 3971429

Org ID: 115055 Regiao: US1 URL editor: https://us1.make.com/115055/scenarios/{id}/edit

Webhook do Disparador Vendas: ${WEBHOOK_MAKE_CONTEUDO_INFINITO}

Blueprint path do modulo 99 (callback): bp.flow[4].routes[3].flow[3].routes[1].flow[1]

Modulos de referencia: - {{43.*}} = Webhook trigger (Vendas1-6) / {{44.*}} = Webhook (Principal) - {{42.*}} = ParseJSON (dados da pessoa) - {{28.convid}} = ID da conversa Chatwoot


Pipedrive Custom Fields

Campo Field key Options
aceita_comunicacao 19bc9c4cde5a4a5959809e45e7f032ae7dd9c3a7 394=So Email, 395=So WhatsApp, 396=Email e WhatsApp, 397=Nao aceita
frequencia_email 938f19c2ca4c... 398=Mensal, 399=Bimestral, 400=Semestral
frequencia_whatsapp acd93e4fdd7b... 401=Mensal, 402=Bimestral, 403=Semestral

WF4 — logica do Code "Calcula Opt-out" (nuancada por canal, corrigida 2026-07-03)

WF4 e opt-out de EMAIL, nao opt-out total. O Code node aplica:

atual (aceita_comunicacao) novo_valor mudou
null / vazio 395 true
396 (Email e WhatsApp) 395 true
394 (So Email) 397 true
395 (So WhatsApp) atual (395) false

O IF "Ja Optou Out?" upstream ja bloqueia quem esta em 397 (nao chega no Code). Ver ARQUITETURA.md para o racional completo e HISTORICO.md (2026-07-03) para a causa raiz do bug que precedeu este fix.


WF3 — Guard de idempotência (adicionado 2026-07-03/04)

Workflow: ny4gXcNU3dReDCba — 4 nós novos inseridos entre "E Feriado?" (branch falso) e "Cria Próxima Atividade" (nó original, inalterado).

Tipo Parâmetros-chave
Verifica Atividade Aberta HTTP Request (GET) =https://api.pipedrive.com/v1/persons/{{ $('Calcula Próxima Data').item.json.person_id }}/activities · query done=0&limit=100 · credencial Bepex Enrico (n5IiwdsiIB3dAUQE, leitura) · onError: continueRegularOutput
Avalia Atividade Aberta Code Assertion de formato (typeof resp.success === 'undefined'guard_error: true, fail-open) + filtro list.some(a => a.type === targetType && a.done === false)ja_existe_atividade_aberta
Já Existe Atividade Aberta? IF (v2, typeValidation: loose) {{ $json.ja_existe_atividade_aberta }} === true
Guard - Pula Criação (Já Existe) NoOp Dead-end — branch "true" do IF acima

Pegadinha crítica — endpoint errado quase virou regressão: GET /v1/activities (endpoint de coleção) NÃO filtra por person_id via query string — o parâmetro é silenciosamente ignorado pelo Pipedrive v1. Usar sempre GET /v1/persons/{person_id}/activities para atividades de uma pessoa específica. O filtro por type não é confiável em nenhum dos dois via query string — fazer o match em Code node depois de buscar done=0. Descoberto e corrigido em 2026-07-03/04 (ver HISTORICO.md).

Decisão fail-open: se Verifica Atividade Aberta retornar algo fora do formato {success, data} (erro de rede, timeout, 404), Avalia Atividade Aberta marca guard_error: true + guard_error_msg mas não bloqueia a criação — decisão consciente pra evitar repetir o padrão do bug do WF4 (fail-closed silencioso). Ver ARQUITETURA.md (decisão de design #9).

Campos usados na segmentação de clusters (2026-07-03) — ver seção "Segmentação de clusters" abaixo:

Campo Field ID (filtro) Key (API pessoa)
Junk (Lixo) 9087 4d64d121086c8a8b53af29253a2e0847fbb53d35 (enum, opção "Sim")
won_deals_count 9050 won_deals_count
open_deals_count 9045 open_deals_count
lost_deals_count 9051 lost_deals_count
closed_deals_count 9052 closed_deals_count (= won + lost)
last_activity_date 9048 last_activity_date
RFM Segment (Person) cdf413668f4a75c86bf2d2a122c02447c4110264 (varchar, abandonado — stale desde 2024-08-21, cobre só 2,3% da base)
RFM Score (Person) b073ad3304474a05061c0b8fb210802f8777e281 (double, abandonado, mesma razão)

Segmentação de clusters e cadência (aprovada em princípio em 2026-07-08 — implementação pendente)

Contexto e racional completos em ARQUITETURA.md (seção "Segmentação de clusters e cadência"). Cronologia em HISTORICO.md. Entrega visual: Proposta_Clusters_Cadencia_WhatsApp_2026-07-03.html (nesta pasta).

Os 6 clusters — filtros reais no Pipedrive

Todos excluem Junk (9087 IS NULL) e opt-out (9094 != 397). Corte de atividade: last_activity_date >= 2024-07-03 (2 anos) para "ativo", < 2024-07-03 para "adormecido".

Cluster N (contado via API, 2026-07-03) Filtro Pipedrive (ID) Link
1 — Frio 20.607 139540 https://bepex.pipedrive.com/persons/list/filter/139540?quickFilter=none
2 — Cliente ativo 614 139541 https://bepex.pipedrive.com/persons/list/filter/139541?quickFilter=none
3 — Cliente recorrente 321 139542 https://bepex.pipedrive.com/persons/list/filter/139542?quickFilter=none
4 — Recorrente ativo 481 139533 https://bepex.pipedrive.com/persons/list/filter/139533?quickFilter=none
5 — Cliente adormecido 1.017 139537 https://bepex.pipedrive.com/persons/list/filter/139537?quickFilter=none
6 — Recorrente adormecido 228 139538 https://bepex.pipedrive.com/persons/list/filter/139538?quickFilter=none

Total: 23.268 pessoas. Contagem feita via paginação real da API (GET /v1/persons?filter_id=X), não estimativa.

Filtros descontinuados (v1, fundidos no Cluster 1): 139531 e 139536, renomeados para DEPRECADO — substituido pelo Cluster 1 (139540) — mantidos no Pipedrive por rastreabilidade, não usar.

Cadência proposta (calendário único por canal, tipo alternado — ver ARQUITETURA.md)

Cluster N Email — a cada WhatsApp — a cada WhatsApp msgs/dia
1 — Frio 20.607 30 dias 120 dias (só nutrição) 171,7
2 — Cliente ativo 614 25 dias 35 dias 17,5
3 — Cliente recorrente 321 15 dias 25 dias 12,8
4 — Recorrente ativo 481 15 dias 18 dias 26,7
5 — Cliente adormecido 1.017 35 dias 55 dias 18,5
6 — Recorrente adormecido 228 21 dias 25 dias 9,1
Total 23.268 ≈ 256/dia

Dimensionamento de WhatsApp: 256 msgs/dia ÷ 30 msgs/dia/número = 8,5 → 10 números recomendados (~15% de folga). Hoje existem 6 (Vendas1-6) — faltam 4.

Pegadinha da API de Filtros do Pipedrive (POST /v1/filters)

Descoberta ao criar os filtros acima: o array conditions.conditions no nível raiz aceita no máximo 2 itens (erro: "body/conditions/conditions must NOT have more than 2 items"). Um grupo aninhado (nível 2) não pode conter outro grupo aninhado — só condições-folha com object (erro: "must have required property 'object'" quando se tenta 3 níveis). Ou seja, a API só suporta 2 níveis de profundidade.

Padrão que funciona para lógica mista AND/OR: agrupar todas as condições AND num único grupo-folha (glue "and", quantos leaves precisar) e todas as condições OR noutro grupo-folha (glue "or"), e combinar os dois grupos no nível raiz (exatamente 2 itens, glue "and"):

{
  "glue": "and",
  "conditions": [
    { "glue": "and", "conditions": [ /* leaves AND, quantas quiser */ ] },
    { "glue": "or",  "conditions": [ /* leaves OR, quantas quiser */ ] }
  ]
}

PostgreSQL — Tabelas

nutricao_fila (controle de processamento WF1)

CREATE TABLE nutricao_fila (
  id SERIAL PRIMARY KEY,
  activity_id INTEGER UNIQUE NOT NULL,
  person_id INTEGER NOT NULL,
  activity_data JSONB,
  activity_type TEXT,
  status TEXT DEFAULT 'pending' CHECK (status IN ('pending', 'processing', 'done', 'error')),
  created_at TIMESTAMP DEFAULT NOW(),
  processed_at TIMESTAMP,
  error_message TEXT
);
CREATE INDEX idx_nutricao_fila_pending ON nutricao_fila (status, id) WHERE status = 'pending';

Queries uteis:

-- Ver status da fila
SELECT status, COUNT(*) FROM nutricao_fila GROUP BY status;

-- Ver items stuck em processing
SELECT * FROM nutricao_fila WHERE status = 'processing' ORDER BY created_at;

-- Resetar stuck (CUIDADO: verificar se ja foram processados antes!)
UPDATE nutricao_fila SET status = 'done' WHERE status = 'processing' AND processed_at IS NULL;

-- Limpar items antigos
DELETE FROM nutricao_fila WHERE status = 'done' AND processed_at < NOW() - INTERVAL '30 days';

pool_conteudos (conteudos para nutricao)

Schema detalhado na skill n8n-bepex-conteudo-infinito.


Redis (feriados)

  • Credencial: LF7uoxStfwXCb9Gx / "Redis account"
  • Pattern: key = YYYY-MM-DD, value = "feriado"
  • Populado com feriados brasileiros
  • Consultado pelo WF3 antes de criar proxima atividade

Webhook payload — WF2 para Make

{
  "inboxID": 27,
  "telefone_verificado": "5527999990000",
  "First_Name": "NOME",
  "mautic_id": 0,
  "sid": "email@exemplo.com",
  "messages": "{\"id\":\"12345\",\"first_name\":\"NOME\",\"messages\":[{\"line\":\"texto\",\"link\":\"no\"}]}",
  "Owner_name": "Vendas",
  "tag": "nutricao",
  "idatividade": 404251,
  "person_id": 12345,
  "activity_id": 404251
}

Nota: messages e uma STRING JSON (nao objeto) — precisa de JSON.stringify().


Webhook payload — Make callback para WF3

{
  "activity_id": "404251",
  "person_id": "12345",
  "canal": "whatsapp"
}

URL: https://n8n.bepex.com.br/webhook/nutricao-cadencia Atencao: A URL correta e nutricao-cadencia, NAO nutricao-gestao-cadencia.


Dados de teste seguros

Campo Valor
Email rafael@bepex.com.br
WhatsApp 5527981155155
Person ID teste 1953 (usar com cuidado, restaurar depois)

Backups e evidencias (pasta pai)

Arquivo Conteudo
CONTROLE_FIXES_CONTEUDO_INFINITO.md Log legado dos fixes de abril
progress_control_nutricao_fila.md Implementacao da fila (maio)
progress_control_fix-pipeline-nutricao.md Fixes de abril + remediacao isNotEmpty
backup_prompt_cadencia_v1_2026-04-28.md Prompt v1 (antes da revisao)
prompt_cadencia_v2_proposta.md Proposta do prompt v2
evidencia_fix_mod99_vendas1-6.md Evidencias do fix Make
relatorio_teste_fase2_sem_contato.md Teste E2E do "sem contato"
relatorio_teste_fase3_unsubscribe.md Teste E2E do unsubscribe
backup_wf3_pre_idempotencia_2026-07-06.json Backup do WF3 antes do guard de idempotência (2026-07-03/04)