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).
| Nó | 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 emHISTORICO.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 |
|---|---|
| rafael@bepex.com.br | |
| 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) |