@pipefy/pipefy-process-coder 0.1.0 → 0.1.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.
Files changed (159) hide show
  1. package/.agents/skills/ppc-pipefy-flow-authoring/SKILL.md +262 -262
  2. package/.agents/skills/ppc-pipefy-flow-authoring/examples/01-main-2-danfe-consulta.json +247 -247
  3. package/.agents/skills/ppc-pipefy-flow-authoring/examples/01-main-2-webhook-retorno-consulta.json +589 -589
  4. package/.agents/skills/ppc-pipefy-flow-authoring/examples/01-main-4-recebimento-barramento.json +1391 -1391
  5. package/.agents/skills/ppc-pipefy-flow-authoring/examples/02-subflow-2-danfe-retorno.json +623 -623
  6. package/.agents/skills/ppc-pipefy-flow-authoring/examples/02-subflow-4-criacao-operacao.json +636 -636
  7. package/.agents/skills/ppc-pipefy-flow-authoring/examples/03-subflow-4-criacao-titulo.json +3642 -3642
  8. package/.agents/skills/ppc-pipefy-flow-authoring/examples/04-subflow-4-criacao-cedente.json +863 -863
  9. package/.agents/skills/ppc-pipefy-flow-authoring/examples/04-subflow-4-criacao-sacado.json +799 -799
  10. package/.agents/skills/ppc-pipefy-flow-authoring/examples/README.md +42 -42
  11. package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-01-subflow-1-titulo-acompanhamento-cobranca.json +581 -581
  12. package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-01-subflow-1-titulo-nfe-monitoramento.json +503 -503
  13. package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-01-subflow-1-titulo-retorno-bancario.json +562 -562
  14. package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-02-subflow-2-retorno-consulta-cedente.json +557 -557
  15. package/.agents/skills/ppc-pipefy-flow-authoring/examples/hml-02-subflow-2-retorno-consulta-sacado.json +609 -609
  16. package/.agents/skills/ppc-pipefy-pipe-authoring/SKILL.md +146 -146
  17. package/.agents/skills/ppc-pipefy-process-design/SKILL.md +127 -127
  18. package/.agents/skills/ppc-pipefy-workspace/SKILL.md +91 -91
  19. package/AGENTS.md +465 -456
  20. package/README.md +825 -807
  21. package/bin/pipe.js +25 -4
  22. package/dist/apply/adopt.js +128 -0
  23. package/dist/apply/agentops.js +42 -0
  24. package/dist/apply/compile.js +722 -0
  25. package/dist/apply/execute.js +277 -0
  26. package/dist/apply/flowops.js +293 -0
  27. package/dist/apply/idmap.js +233 -0
  28. package/dist/apply/mutations.js +704 -0
  29. package/dist/apply/registry.js +348 -0
  30. package/dist/apply/types.js +18 -0
  31. package/dist/cli/args.js +79 -0
  32. package/dist/cli.js +187 -0
  33. package/dist/codec/flow.js +164 -0
  34. package/dist/codec/pack.js +88 -0
  35. package/dist/codec/roundtrip.js +86 -0
  36. package/dist/codec/unpack.js +181 -0
  37. package/dist/commands/agents.js +145 -0
  38. package/dist/commands/apply.js +982 -0
  39. package/dist/commands/context.js +79 -0
  40. package/dist/commands/create.js +63 -0
  41. package/dist/commands/diff.js +294 -0
  42. package/dist/commands/flows.js +348 -0
  43. package/dist/commands/misc.js +528 -0
  44. package/dist/commands/plan.js +301 -0
  45. package/dist/commands/pull.js +511 -0
  46. package/dist/commands/runs.js +74 -0
  47. package/dist/commands/skills.js +131 -0
  48. package/dist/commands/verify.js +205 -0
  49. package/dist/config.js +125 -0
  50. package/dist/diff/agents.js +80 -0
  51. package/dist/diff/diff.js +983 -0
  52. package/dist/diff/flow.js +258 -0
  53. package/{src/diff/html.ts → dist/diff/html.js} +274 -322
  54. package/dist/diff/render.js +90 -0
  55. package/dist/model/payload.js +84 -0
  56. package/dist/model/tree.js +7 -0
  57. package/dist/model/volatile.js +54 -0
  58. package/dist/pipefy/agents.js +122 -0
  59. package/dist/pipefy/automations.js +155 -0
  60. package/dist/pipefy/capability.js +84 -0
  61. package/dist/pipefy/client.js +204 -0
  62. package/dist/pipefy/discovery.js +148 -0
  63. package/dist/pipefy/internal.js +315 -0
  64. package/dist/pipefy/ipaas.js +269 -0
  65. package/dist/pipefy/reconstruct.js +674 -0
  66. package/dist/pipefy/reference.js +172 -0
  67. package/dist/pipefy/snapshot.js +185 -0
  68. package/dist/pipefy/toolkit.js +158 -0
  69. package/dist/report/integrations.js +165 -0
  70. package/dist/report/run.js +355 -0
  71. package/dist/util/fsx.js +50 -0
  72. package/dist/util/git.js +25 -0
  73. package/dist/util/json.js +56 -0
  74. package/dist/util/log.js +69 -0
  75. package/dist/util/pool.js +42 -0
  76. package/dist/util/slug.js +23 -0
  77. package/dist/util/tui.js +287 -0
  78. package/dist/validate/index.js +86 -0
  79. package/dist/validate/integrity.js +370 -0
  80. package/dist/validate/reference.js +120 -0
  81. package/dist/validate/schema.js +278 -0
  82. package/dist/workspace/agents.js +245 -0
  83. package/{src/workspace/docs.ts → dist/workspace/docs.js} +367 -407
  84. package/dist/workspace/flows.js +149 -0
  85. package/dist/workspace/layout.js +146 -0
  86. package/dist/workspace/lock.js +83 -0
  87. package/dist/workspace/read.js +168 -0
  88. package/dist/workspace/reference.js +24 -0
  89. package/dist/workspace/stamp.js +234 -0
  90. package/dist/workspace/write.js +194 -0
  91. package/package.json +37 -35
  92. package/src/apply/adopt.ts +0 -150
  93. package/src/apply/agentops.ts +0 -71
  94. package/src/apply/compile.ts +0 -875
  95. package/src/apply/execute.ts +0 -336
  96. package/src/apply/flowops.ts +0 -399
  97. package/src/apply/idmap.ts +0 -241
  98. package/src/apply/mutations.ts +0 -955
  99. package/src/apply/registry.ts +0 -430
  100. package/src/apply/types.ts +0 -134
  101. package/src/cli/args.ts +0 -88
  102. package/src/cli.ts +0 -211
  103. package/src/codec/flow.ts +0 -199
  104. package/src/codec/pack.ts +0 -103
  105. package/src/codec/roundtrip.ts +0 -94
  106. package/src/codec/unpack.ts +0 -198
  107. package/src/commands/agents.ts +0 -184
  108. package/src/commands/apply.ts +0 -1144
  109. package/src/commands/context.ts +0 -119
  110. package/src/commands/create.ts +0 -79
  111. package/src/commands/diff.ts +0 -314
  112. package/src/commands/flows.ts +0 -414
  113. package/src/commands/misc.ts +0 -644
  114. package/src/commands/plan.ts +0 -331
  115. package/src/commands/pull.ts +0 -567
  116. package/src/commands/runs.ts +0 -83
  117. package/src/commands/skills.ts +0 -137
  118. package/src/commands/verify.ts +0 -253
  119. package/src/config.ts +0 -168
  120. package/src/diff/agents.ts +0 -122
  121. package/src/diff/diff.ts +0 -1130
  122. package/src/diff/flow.ts +0 -318
  123. package/src/diff/render.ts +0 -101
  124. package/src/model/payload.ts +0 -154
  125. package/src/model/tree.ts +0 -99
  126. package/src/model/volatile.ts +0 -55
  127. package/src/pipefy/agents.ts +0 -165
  128. package/src/pipefy/automations.ts +0 -219
  129. package/src/pipefy/capability.ts +0 -119
  130. package/src/pipefy/client.ts +0 -267
  131. package/src/pipefy/discovery.ts +0 -209
  132. package/src/pipefy/internal.ts +0 -380
  133. package/src/pipefy/ipaas.ts +0 -365
  134. package/src/pipefy/reconstruct.ts +0 -775
  135. package/src/pipefy/reference.ts +0 -251
  136. package/src/pipefy/snapshot.ts +0 -245
  137. package/src/pipefy/toolkit.ts +0 -200
  138. package/src/report/integrations.ts +0 -231
  139. package/src/report/run.ts +0 -475
  140. package/src/util/fsx.ts +0 -45
  141. package/src/util/git.ts +0 -32
  142. package/src/util/json.ts +0 -55
  143. package/src/util/log.ts +0 -76
  144. package/src/util/pool.ts +0 -48
  145. package/src/util/slug.ts +0 -26
  146. package/src/util/tui.ts +0 -335
  147. package/src/validate/index.ts +0 -123
  148. package/src/validate/integrity.ts +0 -387
  149. package/src/validate/reference.ts +0 -136
  150. package/src/validate/schema.ts +0 -328
  151. package/src/workspace/agents.ts +0 -290
  152. package/src/workspace/flows.ts +0 -191
  153. package/src/workspace/layout.ts +0 -165
  154. package/src/workspace/lock.ts +0 -148
  155. package/src/workspace/read.ts +0 -165
  156. package/src/workspace/reference.ts +0 -24
  157. package/src/workspace/stamp.ts +0 -301
  158. package/src/workspace/write.ts +0 -225
  159. /package/{src → dist}/pipefy/toolkit_bearer.py +0 -0
@@ -1,609 +1,609 @@
1
- {
2
- "name": "✅[PRD][HML][2/2 SUBFLOW][RETORNO CONSULTA/UPDATE] Retorno Sacado",
3
- "type": "SHARED",
4
- "summary": "",
5
- "description": "",
6
- "tags": [],
7
- "blogUrl": "",
8
- "metadata": {
9
- "externalId": "exampleFlowId03aaaaaa"
10
- },
11
- "author": "Integrações Ipaas 000000000",
12
- "categories": [],
13
- "pieces": [
14
- "@activepieces/piece-subflows",
15
- "@activepieces/piece-pipefy"
16
- ],
17
- "flows": [
18
- {
19
- "displayName": "✅[PRD][HML][2/2 SUBFLOW][RETORNO CONSULTA/UPDATE] Retorno Sacado",
20
- "trigger": {
21
- "name": "trigger",
22
- "valid": true,
23
- "displayName": "Callable Flow",
24
- "nextAction": {
25
- "name": "step_2",
26
- "type": "PIECE",
27
- "valid": true,
28
- "settings": {
29
- "input": {
30
- "auth": "{{connections['exampleConnectionId3']}}",
31
- "pipeId": "200000005",
32
- "fieldId": "idsacado",
33
- "fieldValue": "{{trigger['output']['data']['sacado']['idSacado']}}",
34
- "organizationId": "100000001"
35
- },
36
- "pieceName": "@activepieces/piece-pipefy",
37
- "actionName": "getCardsByFieldValue",
38
- "sampleData": {},
39
- "pieceVersion": "0.1.6",
40
- "propertySettings": {
41
- "pipeId": {
42
- "type": "MANUAL"
43
- },
44
- "fieldId": {
45
- "type": "MANUAL"
46
- },
47
- "fieldValue": {
48
- "type": "MANUAL"
49
- },
50
- "organizationId": {
51
- "type": "MANUAL"
52
- }
53
- },
54
- "errorHandlingOptions": {
55
- "retryOnFailure": {
56
- "value": false
57
- },
58
- "continueOnFailure": {
59
- "value": false
60
- }
61
- }
62
- },
63
- "nextAction": {
64
- "name": "step_11",
65
- "skip": false,
66
- "type": "CODE",
67
- "valid": true,
68
- "settings": {
69
- "input": {
70
- "base": "{{trigger['output']['data']['sacado']['origem']}}",
71
- "cards": "{{step_2['output']['data']['cards']}}",
72
- "empresaCodigo": "{{trigger['output']['data']['sacado']['codigoEmpresa']}}"
73
- },
74
- "sampleData": {},
75
- "sourceCode": {
76
- "code": "export const code = async (inputs) => {\n const alvoEmpresa = String(inputs.empresaCodigo ?? '').trim();\n const alvoBase = String(inputs.base ?? '').trim();\n\n const card = inputs.cards.find(c => {\n const empresaCard = String(c.fields?.empresacodigo?.value ?? '').trim();\n const baseCard = String(c.fields?.base?.value ?? '').trim();\n return empresaCard === alvoEmpresa && baseCard === alvoBase;\n });\n\n return {\n cardId: card?.id ?? null,\n encontrado: !!card\n };\n};",
77
- "packageJson": "{}"
78
- },
79
- "errorHandlingOptions": {
80
- "retryOnFailure": {
81
- "value": false
82
- },
83
- "continueOnFailure": {
84
- "value": false
85
- }
86
- }
87
- },
88
- "nextAction": {
89
- "name": "step_3",
90
- "skip": false,
91
- "type": "ROUTER",
92
- "valid": true,
93
- "children": [
94
- {
95
- "name": "step_1",
96
- "skip": false,
97
- "type": "CODE",
98
- "valid": true,
99
- "settings": {
100
- "input": {
101
- "email": "{{trigger['output']['data']['sacado']['email']}}",
102
- "cnpjOuCpf": "{{trigger['output']['data']['sacado']['cnpjOuCpf']}}",
103
- "bodyBarramento ": "{{trigger['output']['data']['sacado']}}",
104
- "telefoneContato ": "{{trigger['output']['data']['sacado']['telefoneContato']}}"
105
- },
106
- "sampleData": {},
107
- "sourceCode": {
108
- "code": "export const code = async (inputs) => {\n // Normaliza chaves removendo espaços extras\n const normalizedInputs = {};\n for (const key in inputs) {\n normalizedInputs[key.trim()] = inputs[key];\n }\n inputs = normalizedInputs;\n\n // ===== Helper para arredondar números com 2 casas decimais =====\n const round2 = (n) => Math.round((Number(n) || 0) * 100) / 100;\n\n // DDDs válidos no Brasil (nenhum começa com 0 ou 1)\n const DDD_VALIDOS = new Set([\n '11','12','13','14','15','16','17','18','19',\n '21','22','24',\n '27','28',\n '31','32','33','34','35','37','38',\n '41','42','43','44','45','46',\n '47','48','49',\n '51','53','54','55',\n '61',\n '62','63','64',\n '65','66',\n '67',\n '68',\n '69',\n '71','73','74','75','77',\n '79',\n '81','82','83','84','87',\n '85','88','86','89',\n '91','92','93','94','97',\n '95',\n '96',\n '98','99',\n ]);\n\n // ===== Normaliza telefone =====\n let telefoneContato = '';\n let telefoneContatoFormatado = '';\n if (inputs.telefoneContato) {\n let numeros = String(inputs.telefoneContato).replace(/\\D/g, '');\n\n // Remove o 55 inicial se já vier com código do país\n if ((numeros.length === 12 || numeros.length === 13) && numeros.startsWith('55')) {\n numeros = numeros.substring(2);\n }\n\n // Corrige prefixo \"0\" indevido antes do DDD (ex: \"084 3064-6035\" -> \"84 3064-6035\")\n // Nenhum DDD começa com 0, então um \"0\" sobrando aqui sempre indica esse erro de digitação/formatação,\n // seja em número fixo (11 dígitos -> 10) ou celular (12 dígitos -> 11)\n if (numeros.startsWith('0') && (numeros.length === 11 || numeros.length === 12)) {\n numeros = numeros.substring(1);\n }\n\n // Sanity check adicional: se o DDD calculado não é válido, tenta reancorar\n // deslocando um dígito (cobre outros casos de dígito extra vazado no começo)\n const dddCandidato = numeros.substring(0, 2);\n if (!DDD_VALIDOS.has(dddCandidato) && (numeros.length === 11 || numeros.length === 12)) {\n const dddAlternativo = numeros.substring(1, 3);\n if (DDD_VALIDOS.has(dddAlternativo)) {\n numeros = numeros.substring(1);\n }\n }\n\n if (numeros.length === 11) {\n // Celular com DDD\n const ddd = numeros.substring(0, 2);\n const parte1 = numeros.substring(2, 7);\n const parte2 = numeros.substring(7);\n telefoneContato = `55${numeros}`;\n telefoneContatoFormatado = `+55 (${ddd}) ${parte1}-${parte2}`;\n } else if (numeros.length === 10) {\n // Fixo com DDD\n const ddd = numeros.substring(0, 2);\n const parte1 = numeros.substring(2, 6);\n const parte2 = numeros.substring(6);\n telefoneContato = `55${numeros}`;\n telefoneContatoFormatado = `+55 (${ddd}) ${parte1}-${parte2}`;\n } else {\n telefoneContato = numeros;\n telefoneContatoFormatado = numeros;\n }\n }\n\n // ===== Normaliza e-mails =====\n // Se não houver nenhum '@' no input, devolve o valor original e marca emailCheck = false.\n // Caso contrário, considera apenas e-mails válidos (com @ e domínio com TLD),\n // aceitando separação por ; , espaço ou quebra de linha, e devolve separados por vírgula.\n let email = '';\n let emailCheck = true;\n if (inputs.email) {\n const emailStr = String(inputs.email);\n if (!emailStr.includes('@')) {\n // Nenhum @ encontrado - retorna valor original\n email = emailStr;\n emailCheck = false;\n } else {\n const emailRegex = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$/;\n const validos = emailStr\n .split(/[;,\\s]+/)\n .map((e) => e.trim())\n .filter((e) => e && emailRegex.test(e));\n // Remove duplicatas mantendo a ordem\n email = Array.from(new Set(validos)).join(', ');\n }\n }\n\n // ===== Identifica e formata CPF/CNPJ =====\n let cpf = '';\n let cnpj = '';\n let tipo = '';\n if (inputs.cnpjOuCpf) {\n const doc = String(inputs.cnpjOuCpf).replace(/\\D/g, '');\n if (doc.length === 11) {\n cpf = `${doc.substring(0, 3)}.${doc.substring(3, 6)}.${doc.substring(6, 9)}-${doc.substring(9)}`;\n tipo = 'cpf';\n } else if (doc.length === 14) {\n cnpj = `${doc.substring(0, 2)}.${doc.substring(2, 5)}.${doc.substring(5, 8)}/${doc.substring(8, 12)}-${doc.substring(12)}`;\n tipo = 'cnpj';\n }\n }\n\n // ===== Helpers de formatação numérica =====\n const formatBRL = (valor) => {\n const num = Number(valor) || 0;\n return num.toLocaleString('pt-BR', {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n };\n\n const formatInt = (valor) => {\n const num = Number(valor) || 0;\n return num.toLocaleString('pt-BR');\n };\n\n // Formata número como percentual no padrão pt-BR (ex.: \"12,34%\")\n const formatPerc = (valor) => {\n const num = Number(valor) || 0;\n return (\n num.toLocaleString('pt-BR', {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n }) + '%'\n );\n };\n\n // Heurística: campos de contagem/código não levam casas decimais\n const isCountField = (key) => {\n const lower = String(key).toLowerCase();\n return (\n lower.endsWith('qtd') ||\n lower.includes('quantidade') ||\n lower.includes('codigo') ||\n lower.includes('numero')\n );\n };\n\n // Labels amigáveis para campos conhecidos\n const labelMap = {\n totalTitulosLiquidados: 'Total de Títulos Liquidados',\n totalTitulosLiquidadosPagoDia: 'Títulos Liquidados Pagos no Dia',\n totalTitulosLiquidadosPagoAtraso: 'Títulos Liquidados Pagos em Atraso',\n totalOpeNaoEfetivadas: 'Operações Não Efetivadas',\n totalTitulosLiquidadosChequeDevolvido: 'Títulos Liquidados com Cheque Devolvido',\n totalTitulosAbertos: 'Total de Títulos em Aberto',\n totalTitulosAbertosVencidos: 'Títulos em Aberto Vencidos',\n totalTitulosAbertosVencer: 'Títulos em Aberto a Vencer',\n totPresente: 'Total Presente',\n totSac: 'Total Sacado',\n totQtd: 'Total Quantidade',\n totNegativa: 'Total Negativa',\n codigoEvento: 'Código do Evento',\n descricao: 'Descrição',\n totalLiquidado: 'Total Liquidado',\n quantidadeTitulos: 'Quantidade de Títulos',\n historicoValorLiquidado: 'Histórico de Valores Liquidados',\n historicoValorAberto: 'Histórico de Valores em Aberto',\n liquidacaoPorEvento: 'Liquidação por Evento',\n percHPre: 'Percentual Histórico - Presente',\n percHNeg: 'Percentual Histórico - Negativo',\n };\n\n const camelToTitle = (str) =>\n String(str)\n .replace(/([A-Z])/g, ' $1')\n .replace(/^./, (s) => s.toUpperCase())\n .trim();\n\n const getLabel = (key) => labelMap[key] || camelToTitle(key);\n\n // ===== Converte objeto em tabela markdown =====\n // Detecta pares X / XQtd e gera 3 colunas (Indicador | Valor | Quantidade)\n // Caso contrário gera 2 colunas (Campo | Valor)\n const objToMarkdown = (obj) => {\n if (!obj || typeof obj !== 'object' || Array.isArray(obj)) return '';\n const keys = Object.keys(obj);\n if (keys.length === 0) return '';\n\n const temPares = keys.some(\n (k) => !k.endsWith('Qtd') && keys.includes(`${k}Qtd`)\n );\n\n if (temPares) {\n const usados = new Set();\n const linhas = [];\n\n keys.forEach((k) => {\n if (usados.has(k)) return;\n\n if (k.endsWith('Qtd')) {\n // Qtd órfão (sem par valor)\n const baseKey = k.substring(0, k.length - 3);\n if (!keys.includes(baseKey)) {\n linhas.push({\n label: getLabel(baseKey),\n valor: '-',\n qtd: formatInt(obj[k]),\n });\n usados.add(k);\n }\n } else {\n const qtdKey = `${k}Qtd`;\n if (keys.includes(qtdKey)) {\n linhas.push({\n label: getLabel(k),\n valor: formatBRL(obj[k]),\n qtd: formatInt(obj[qtdKey]),\n });\n usados.add(k);\n usados.add(qtdKey);\n } else {\n linhas.push({\n label: getLabel(k),\n valor: formatBRL(obj[k]),\n qtd: '-',\n });\n usados.add(k);\n }\n }\n });\n\n let md = '| Indicador | Valor (R$) | Quantidade |\\n';\n md += '|-----------|-----------:|-----------:|\\n';\n linhas.forEach((l) => {\n md += `| ${l.label} | ${l.valor} | ${l.qtd} |\\n`;\n });\n return md.trim();\n }\n\n // Tabela simples Campo / Valor\n let md = '| Campo | Valor |\\n';\n md += '|-------|------:|\\n';\n keys.forEach((k) => {\n const v = obj[k];\n let formatado;\n if (typeof v === 'number') {\n formatado = isCountField(k) ? formatInt(v) : formatBRL(v);\n } else {\n formatado = v === null || v === undefined ? '' : String(v);\n }\n md += `| ${getLabel(k)} | ${formatado} |\\n`;\n });\n return md.trim();\n };\n\n // ===== Converte array de objetos em tabela markdown =====\n const arrayToMarkdown = (arr) => {\n if (!Array.isArray(arr) || arr.length === 0) return '';\n const itensValidos = arr.filter((i) => i && typeof i === 'object');\n if (itensValidos.length === 0) return '';\n\n const colunas = Array.from(\n itensValidos.reduce((set, item) => {\n Object.keys(item).forEach((k) => set.add(k));\n return set;\n }, new Set())\n );\n\n let md = '| ' + colunas.map(getLabel).join(' | ') + ' |\\n';\n md += '|' + colunas.map(() => '------').join('|') + '|\\n';\n itensValidos.forEach((item) => {\n md +=\n '| ' +\n colunas\n .map((c) => {\n const v = item[c];\n if (v === undefined || v === null) return '';\n if (typeof v === 'number') {\n return isCountField(c) ? formatInt(v) : formatBRL(v);\n }\n return String(v);\n })\n .join(' | ') +\n ' |\\n';\n });\n return md.trim();\n };\n\n // ===== Processa bodyBarramento =====\n const objetosMarkdown = {};\n const partesMarkdown = [];\n\n // Valores calculados de %Hpre e %Hneg (default zerado)\n let percHPre = '0,00%';\n let percHNeg = '0,00%';\n let percHPreNum = 0;\n let percHNegNum = 0;\n\n if (inputs.bodyBarramento && typeof inputs.bodyBarramento === 'object') {\n // Aceita tanto o payload completo (com data.sacado) quanto o objeto direto\n const root =\n (inputs.bodyBarramento.data && inputs.bodyBarramento.data.sacado) ||\n inputs.bodyBarramento;\n\n // ===== Calcula %Hpre e %Hneg =====\n // %Hpre = totPresente / totSac (valor histórico de presente / valor histórico total do sacado)\n if (root.percHPre && typeof root.percHPre === 'object') {\n const totPresente = Number(root.percHPre.totPresente) || 0;\n const totSac = Number(root.percHPre.totSac) || 0;\n const rawHPre = totSac > 0 ? (totPresente / totSac) * 100 : 0;\n percHPreNum = round2(rawHPre);\n percHPre = formatPerc(percHPreNum);\n }\n\n // %Hneg = totNegativa / totSac (valor histórico negativo / valor histórico total do sacado)\n if (root.percHNeg && typeof root.percHNeg === 'object') {\n const totNegativa = Number(root.percHNeg.totNegativa) || 0;\n const totSac = Number(root.percHNeg.totSac) || 0;\n const rawHNeg = totSac > 0 ? (totNegativa / totSac) * 100 : 0;\n percHNegNum = round2(rawHNeg);\n percHNeg = formatPerc(percHNegNum);\n }\n\n // ===== Demais objetos em markdown =====\n for (const key in root) {\n const value = root[key];\n\n // Objeto aninhado com mais de um parâmetro\n if (\n value &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n Object.keys(value).length > 1\n ) {\n const md = objToMarkdown(value);\n if (md) {\n objetosMarkdown[key] = md;\n partesMarkdown.push(`### ${getLabel(key)}\\n\\n${md}`);\n }\n }\n // Array de objetos\n else if (\n Array.isArray(value) &&\n value.length > 0 &&\n typeof value[0] === 'object'\n ) {\n const md = arrayToMarkdown(value);\n if (md) {\n objetosMarkdown[key] = md;\n partesMarkdown.push(`### ${getLabel(key)}\\n\\n${md}`);\n }\n }\n }\n }\n\n const markdownCompleto = partesMarkdown.join('\\n\\n');\n\n return {\n telefoneContato,\n telefoneContatoFormatado,\n email,\n emailCheck,\n tipo,\n cpf,\n cnpj,\n percHPre,\n percHNeg,\n percHPreNum,\n percHNegNum,\n objetosMarkdown,\n markdownCompleto,\n };\n};",
109
- "packageJson": "{}"
110
- },
111
- "errorHandlingOptions": {
112
- "retryOnFailure": {
113
- "value": false
114
- },
115
- "continueOnFailure": {
116
- "value": false
117
- }
118
- }
119
- },
120
- "nextAction": {
121
- "name": "step_4",
122
- "skip": true,
123
- "type": "CODE",
124
- "valid": true,
125
- "settings": {
126
- "input": {
127
- "email": "{{trigger['output']['data']['sacado']['email']}}",
128
- "cnpjOuCpf": "{{trigger['output']['data']['sacado']['cnpjOuCpf']}}",
129
- "bodyBarramento ": "{{trigger['output']['data']['sacado']}}",
130
- "telefoneContato ": "{{trigger['output']['data']['sacado']['telefoneContato']}}"
131
- },
132
- "sampleData": {},
133
- "sourceCode": {
134
- "code": "export const code = async (inputs) => {\n // Normaliza chaves removendo espaços extras\n const normalizedInputs = {};\n for (const key in inputs) {\n normalizedInputs[key.trim()] = inputs[key];\n }\n inputs = normalizedInputs;\n\n // ===== Helper para arredondar números com 2 casas decimais =====\n const round2 = (n) => Math.round((Number(n) || 0) * 100) / 100;\n\n // ===== Normaliza telefone =====\n let telefoneContato = '';\n let telefoneContatoFormatado = '';\n if (inputs.telefoneContato) {\n let numeros = String(inputs.telefoneContato).replace(/\\D/g, '');\n // Remove o 55 inicial se já vier com código do país\n if ((numeros.length === 12 || numeros.length === 13) && numeros.startsWith('55')) {\n numeros = numeros.substring(2);\n }\n if (numeros.length === 11) {\n // Celular com DDD\n const ddd = numeros.substring(0, 2);\n const parte1 = numeros.substring(2, 7);\n const parte2 = numeros.substring(7);\n telefoneContato = `55${numeros}`;\n telefoneContatoFormatado = `+55 (${ddd}) ${parte1}-${parte2}`;\n } else if (numeros.length === 10) {\n // Fixo com DDD\n const ddd = numeros.substring(0, 2);\n const parte1 = numeros.substring(2, 6);\n const parte2 = numeros.substring(6);\n telefoneContato = `55${numeros}`;\n telefoneContatoFormatado = `+55 (${ddd}) ${parte1}-${parte2}`;\n } else {\n telefoneContato = numeros;\n telefoneContatoFormatado = numeros;\n }\n }\n\n // ===== Normaliza e-mails =====\n // Se não houver nenhum '@' no input, devolve o valor original e marca emailCheck = false.\n // Caso contrário, considera apenas e-mails válidos (com @ e domínio com TLD),\n // aceitando separação por ; , espaço ou quebra de linha, e devolve separados por vírgula.\n let email = '';\n let emailCheck = true;\n if (inputs.email) {\n const emailStr = String(inputs.email);\n if (!emailStr.includes('@')) {\n // Nenhum @ encontrado - retorna valor original\n email = emailStr;\n emailCheck = false;\n } else {\n const emailRegex = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$/;\n const validos = emailStr\n .split(/[;,\\s]+/)\n .map((e) => e.trim())\n .filter((e) => e && emailRegex.test(e));\n // Remove duplicatas mantendo a ordem\n email = Array.from(new Set(validos)).join(', ');\n }\n }\n\n // ===== Identifica e formata CPF/CNPJ =====\n let cpf = '';\n let cnpj = '';\n let tipo = '';\n if (inputs.cnpjOuCpf) {\n const doc = String(inputs.cnpjOuCpf).replace(/\\D/g, '');\n if (doc.length === 11) {\n cpf = `${doc.substring(0, 3)}.${doc.substring(3, 6)}.${doc.substring(6, 9)}-${doc.substring(9)}`;\n tipo = 'cpf';\n } else if (doc.length === 14) {\n cnpj = `${doc.substring(0, 2)}.${doc.substring(2, 5)}.${doc.substring(5, 8)}/${doc.substring(8, 12)}-${doc.substring(12)}`;\n tipo = 'cnpj';\n }\n }\n\n // ===== Helpers de formatação numérica =====\n const formatBRL = (valor) => {\n const num = Number(valor) || 0;\n return num.toLocaleString('pt-BR', {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n };\n\n const formatInt = (valor) => {\n const num = Number(valor) || 0;\n return num.toLocaleString('pt-BR');\n };\n\n // Formata número como percentual no padrão pt-BR (ex.: \"12,34%\")\n const formatPerc = (valor) => {\n const num = Number(valor) || 0;\n return (\n num.toLocaleString('pt-BR', {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n }) + '%'\n );\n };\n\n // Heurística: campos de contagem/código não levam casas decimais\n const isCountField = (key) => {\n const lower = String(key).toLowerCase();\n return (\n lower.endsWith('qtd') ||\n lower.includes('quantidade') ||\n lower.includes('codigo') ||\n lower.includes('numero')\n );\n };\n\n // Labels amigáveis para campos conhecidos\n const labelMap = {\n totalTitulosLiquidados: 'Total de Títulos Liquidados',\n totalTitulosLiquidadosPagoDia: 'Títulos Liquidados Pagos no Dia',\n totalTitulosLiquidadosPagoAtraso: 'Títulos Liquidados Pagos em Atraso',\n totalOpeNaoEfetivadas: 'Operações Não Efetivadas',\n totalTitulosLiquidadosChequeDevolvido: 'Títulos Liquidados com Cheque Devolvido',\n totalTitulosAbertos: 'Total de Títulos em Aberto',\n totalTitulosAbertosVencidos: 'Títulos em Aberto Vencidos',\n totalTitulosAbertosVencer: 'Títulos em Aberto a Vencer',\n totPresente: 'Total Presente',\n totSac: 'Total Sacado',\n totQtd: 'Total Quantidade',\n totNegativa: 'Total Negativa',\n codigoEvento: 'Código do Evento',\n descricao: 'Descrição',\n totalLiquidado: 'Total Liquidado',\n quantidadeTitulos: 'Quantidade de Títulos',\n historicoValorLiquidado: 'Histórico de Valores Liquidados',\n historicoValorAberto: 'Histórico de Valores em Aberto',\n liquidacaoPorEvento: 'Liquidação por Evento',\n percHPre: 'Percentual Histórico - Presente',\n percHNeg: 'Percentual Histórico - Negativo',\n };\n\n const camelToTitle = (str) =>\n String(str)\n .replace(/([A-Z])/g, ' $1')\n .replace(/^./, (s) => s.toUpperCase())\n .trim();\n\n const getLabel = (key) => labelMap[key] || camelToTitle(key);\n\n // ===== Converte objeto em tabela markdown =====\n // Detecta pares X / XQtd e gera 3 colunas (Indicador | Valor | Quantidade)\n // Caso contrário gera 2 colunas (Campo | Valor)\n const objToMarkdown = (obj) => {\n if (!obj || typeof obj !== 'object' || Array.isArray(obj)) return '';\n const keys = Object.keys(obj);\n if (keys.length === 0) return '';\n\n const temPares = keys.some(\n (k) => !k.endsWith('Qtd') && keys.includes(`${k}Qtd`)\n );\n\n if (temPares) {\n const usados = new Set();\n const linhas = [];\n\n keys.forEach((k) => {\n if (usados.has(k)) return;\n\n if (k.endsWith('Qtd')) {\n // Qtd órfão (sem par valor)\n const baseKey = k.substring(0, k.length - 3);\n if (!keys.includes(baseKey)) {\n linhas.push({\n label: getLabel(baseKey),\n valor: '-',\n qtd: formatInt(obj[k]),\n });\n usados.add(k);\n }\n } else {\n const qtdKey = `${k}Qtd`;\n if (keys.includes(qtdKey)) {\n linhas.push({\n label: getLabel(k),\n valor: formatBRL(obj[k]),\n qtd: formatInt(obj[qtdKey]),\n });\n usados.add(k);\n usados.add(qtdKey);\n } else {\n linhas.push({\n label: getLabel(k),\n valor: formatBRL(obj[k]),\n qtd: '-',\n });\n usados.add(k);\n }\n }\n });\n\n let md = '| Indicador | Valor (R$) | Quantidade |\\n';\n md += '|-----------|-----------:|-----------:|\\n';\n linhas.forEach((l) => {\n md += `| ${l.label} | ${l.valor} | ${l.qtd} |\\n`;\n });\n return md.trim();\n }\n\n // Tabela simples Campo / Valor\n let md = '| Campo | Valor |\\n';\n md += '|-------|------:|\\n';\n keys.forEach((k) => {\n const v = obj[k];\n let formatado;\n if (typeof v === 'number') {\n formatado = isCountField(k) ? formatInt(v) : formatBRL(v);\n } else {\n formatado = v === null || v === undefined ? '' : String(v);\n }\n md += `| ${getLabel(k)} | ${formatado} |\\n`;\n });\n return md.trim();\n };\n\n // ===== Converte array de objetos em tabela markdown =====\n const arrayToMarkdown = (arr) => {\n if (!Array.isArray(arr) || arr.length === 0) return '';\n const itensValidos = arr.filter((i) => i && typeof i === 'object');\n if (itensValidos.length === 0) return '';\n\n const colunas = Array.from(\n itensValidos.reduce((set, item) => {\n Object.keys(item).forEach((k) => set.add(k));\n return set;\n }, new Set())\n );\n\n let md = '| ' + colunas.map(getLabel).join(' | ') + ' |\\n';\n md += '|' + colunas.map(() => '------').join('|') + '|\\n';\n itensValidos.forEach((item) => {\n md +=\n '| ' +\n colunas\n .map((c) => {\n const v = item[c];\n if (v === undefined || v === null) return '';\n if (typeof v === 'number') {\n return isCountField(c) ? formatInt(v) : formatBRL(v);\n }\n return String(v);\n })\n .join(' | ') +\n ' |\\n';\n });\n return md.trim();\n };\n\n // ===== Processa bodyBarramento =====\n const objetosMarkdown = {};\n const partesMarkdown = [];\n\n // Valores calculados de %Hpre e %Hneg (default zerado)\n let percHPre = '0,00%';\n let percHNeg = '0,00%';\n let percHPreNum = 0;\n let percHNegNum = 0;\n\n if (inputs.bodyBarramento && typeof inputs.bodyBarramento === 'object') {\n // Aceita tanto o payload completo (com data.sacado) quanto o objeto direto\n const root =\n (inputs.bodyBarramento.data && inputs.bodyBarramento.data.sacado) ||\n inputs.bodyBarramento;\n\n // ===== Calcula %Hpre e %Hneg =====\n // %Hpre = totPresente / totSac (valor histórico de presente / valor histórico total do sacado)\n if (root.percHPre && typeof root.percHPre === 'object') {\n const totPresente = Number(root.percHPre.totPresente) || 0;\n const totSac = Number(root.percHPre.totSac) || 0;\n const rawHPre = totSac > 0 ? (totPresente / totSac) * 100 : 0;\n percHPreNum = round2(rawHPre);\n percHPre = formatPerc(percHPreNum);\n }\n\n // %Hneg = totNegativa / totSac (valor histórico negativo / valor histórico total do sacado)\n if (root.percHNeg && typeof root.percHNeg === 'object') {\n const totNegativa = Number(root.percHNeg.totNegativa) || 0;\n const totSac = Number(root.percHNeg.totSac) || 0;\n const rawHNeg = totSac > 0 ? (totNegativa / totSac) * 100 : 0;\n percHNegNum = round2(rawHNeg);\n percHNeg = formatPerc(percHNegNum);\n }\n\n // ===== Demais objetos em markdown =====\n for (const key in root) {\n const value = root[key];\n\n // Objeto aninhado com mais de um parâmetro\n if (\n value &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n Object.keys(value).length > 1\n ) {\n const md = objToMarkdown(value);\n if (md) {\n objetosMarkdown[key] = md;\n partesMarkdown.push(`### ${getLabel(key)}\\n\\n${md}`);\n }\n }\n // Array de objetos\n else if (\n Array.isArray(value) &&\n value.length > 0 &&\n typeof value[0] === 'object'\n ) {\n const md = arrayToMarkdown(value);\n if (md) {\n objetosMarkdown[key] = md;\n partesMarkdown.push(`### ${getLabel(key)}\\n\\n${md}`);\n }\n }\n }\n }\n\n const markdownCompleto = partesMarkdown.join('\\n\\n');\n\n return {\n telefoneContato,\n telefoneContatoFormatado,\n email,\n emailCheck,\n tipo,\n cpf,\n cnpj,\n percHPre,\n percHNeg,\n percHPreNum,\n percHNegNum,\n objetosMarkdown,\n markdownCompleto,\n };\n};",
135
- "packageJson": "{}"
136
- },
137
- "errorHandlingOptions": {
138
- "retryOnFailure": {
139
- "value": false
140
- },
141
- "continueOnFailure": {
142
- "value": false
143
- }
144
- }
145
- },
146
- "nextAction": {
147
- "name": "step_6",
148
- "skip": false,
149
- "type": "PIECE",
150
- "valid": true,
151
- "settings": {
152
- "input": {
153
- "auth": "{{connections['exampleConnectionId3']}}",
154
- "cardId": "{{step_11['output']['cardId']}}",
155
- "pipeId": "200000005",
156
- "phaseId": "300000004",
157
- "phaseFields": {
158
- "cep": "{{trigger['output']['data']['sacado']['cep']}}",
159
- "cpf": "{{step_1['output']['cpf']}}",
160
- "cnpj": "{{step_1['output']['cnpj']}}",
161
- "hneg": "{{step_1['output']['objetosMarkdown']['percHNeg']}}",
162
- "hpre": "{{step_1['output']['objetosMarkdown']['percHPre']}}",
163
- "nome": "{{trigger['output']['data']['sacado']['nome']}}",
164
- "email": "{{step_1['output']['email']}}",
165
- "h_neg": "{{step_1['output']['percHNegNum']}}",
166
- "h_pre": "{{step_1['output']['percHPreNum']}}",
167
- "cidade": "{{trigger['output']['data']['sacado']['cidade']}}",
168
- "estado": "{{trigger['output']['data']['sacado']['estado']}}",
169
- "endere_o": "{{trigger['output']['data']['sacado']['endereco']}}",
170
- "raz_o_social": "{{trigger['output']['data']['sacado']['razaoSocial']}}",
171
- "nome_fantasia": "{{trigger['output']['data']['sacado']['nomeFantasia']}}",
172
- "hist_rico_valor_presente": "{{step_1['output']['objetosMarkdown']['historicoValorAberto']}}",
173
- "hist_rico_valor_liquidado": "{{step_1['output']['objetosMarkdown']['historicoValorLiquidado']}}"
174
- },
175
- "organizationId": "100000001"
176
- },
177
- "pieceName": "@activepieces/piece-pipefy",
178
- "actionName": "updateCard",
179
- "sampleData": {},
180
- "pieceVersion": "0.1.7",
181
- "propertySettings": {
182
- "cardId": {
183
- "type": "MANUAL"
184
- },
185
- "pipeId": {
186
- "type": "MANUAL"
187
- },
188
- "phaseId": {
189
- "type": "MANUAL"
190
- },
191
- "phaseFields": {
192
- "type": "MANUAL",
193
- "schema": {
194
- "cep": {
195
- "type": "SHORT_TEXT",
196
- "required": false,
197
- "description": "\"cep\"",
198
- "displayName": "CEP"
199
- },
200
- "cpf": {
201
- "type": "SHORT_TEXT",
202
- "required": false,
203
- "description": "\"cnpjOuCpf\"",
204
- "displayName": "CPF"
205
- },
206
- "cnpj": {
207
- "type": "SHORT_TEXT",
208
- "required": false,
209
- "description": "\"cnpjOuCpf\"",
210
- "displayName": "CNPJ"
211
- },
212
- "hneg": {
213
- "type": "LONG_TEXT",
214
- "required": false,
215
- "description": "❓❓ Aguardando exemplo para conferir como vamos receber o dado",
216
- "displayName": "hNeg"
217
- },
218
- "hpre": {
219
- "type": "LONG_TEXT",
220
- "required": false,
221
- "description": "❓❓ Aguardando exemplo para conferir como vamos receber o dado",
222
- "displayName": "hPre"
223
- },
224
- "nome": {
225
- "type": "SHORT_TEXT",
226
- "required": false,
227
- "description": "\"sacado\"\n\"nome\"",
228
- "displayName": "Nome"
229
- },
230
- "email": {
231
- "type": "LONG_TEXT",
232
- "required": false,
233
- "description": "\"sacado\"\n\"email\"",
234
- "displayName": "E-mail"
235
- },
236
- "h_neg": {
237
- "type": "NUMBER",
238
- "required": false,
239
- "description": "percHNeg\n\n\"totNegativa\" / \"totSac\"",
240
- "displayName": "%H.Neg"
241
- },
242
- "h_pre": {
243
- "type": "NUMBER",
244
- "required": false,
245
- "description": "percHPre\n\n\"totPresente\" / \"totSac\"",
246
- "displayName": "%H.Pre"
247
- },
248
- "cidade": {
249
- "type": "SHORT_TEXT",
250
- "required": false,
251
- "description": "\"cidade\"",
252
- "displayName": "Cidade"
253
- },
254
- "e_mail": {
255
- "type": "SHORT_TEXT",
256
- "required": false,
257
- "description": "❌ Deletar campo, mas antes ajustar os templates de e-mail",
258
- "displayName": "[DEPRECADO] E-mail"
259
- },
260
- "estado": {
261
- "type": "SHORT_TEXT",
262
- "required": false,
263
- "description": "\"estado\"",
264
- "displayName": "Estado"
265
- },
266
- "endere_o": {
267
- "type": "LONG_TEXT",
268
- "required": false,
269
- "description": "\"endereco\"",
270
- "displayName": "Endereço"
271
- },
272
- "idsacado": {
273
- "type": "SHORT_TEXT",
274
- "required": false,
275
- "description": "\"idSacado\"",
276
- "displayName": "ID Sacado (Barramento)"
277
- },
278
- "raz_o_social": {
279
- "type": "SHORT_TEXT",
280
- "required": false,
281
- "description": "\"razaoSocial\"",
282
- "displayName": "Razão social"
283
- },
284
- "empresacodigo": {
285
- "type": "SHORT_TEXT",
286
- "required": false,
287
- "description": "\"codigoEmpresa\"",
288
- "displayName": "empresaCodigo"
289
- },
290
- "nome_fantasia": {
291
- "type": "SHORT_TEXT",
292
- "required": false,
293
- "description": "\"nomeFantasia\"",
294
- "displayName": "Nome fantasia"
295
- },
296
- "telefone_de_contato": {
297
- "type": "NUMBER",
298
- "required": false,
299
- "description": "\"telefoneContato\"",
300
- "displayName": "Telefone de contato"
301
- },
302
- "hist_rico_valor_presente": {
303
- "type": "LONG_TEXT",
304
- "required": false,
305
- "description": "\"historicoValorAberto\"",
306
- "displayName": "Histórico valor presente"
307
- },
308
- "hist_rico_valor_liquidado": {
309
- "type": "LONG_TEXT",
310
- "required": false,
311
- "description": "\"historicoValorLiquidado\"",
312
- "displayName": "Histórico valor liquidado"
313
- },
314
- "hist_rico_do_sacado_1ano_6meses": {
315
- "type": "LONG_TEXT",
316
- "required": false,
317
- "description": "",
318
- "displayName": "Histórico do sacado (1ano/6meses)"
319
- },
320
- "statement_8180825c_61ed_4fb3_9d96_cdc5340b20f1": {
321
- "type": "SHORT_TEXT",
322
- "required": false,
323
- "description": "<p>❓❓❓ \"liquidacaoPorEvento\" - Campo vem do JSON mas não tem campo ( o que vem neste campo??) Esperar exemplo</p>\n<p> </p>\n<p>Exemplo: </p>\n<p> </p>\n<div>\"liquidacaoPorEvento\": [</div>\n<div>{</div>\n<div>\"codigoEvento\": 2,</div>\n<div>\"descricao\": \"Recomprado pelo Cedente\",</div>\n<div>\"totalLiquidado\": 13382.72,</div>\n<div>\"quantidadeTitulos\": 3</div>\n<div>},</div>\n<div>{</div>\n<div>\"codigoEvento\": 313,</div>\n<div>\"descricao\": \"LIQUIDACAO CARTORIO\",</div>\n<div>\"totalLiquidado\": 9903.39,</div>\n<div>\"quantidadeTitulos\": 3</div>\n<div>}</div>\n<p> </p>",
324
- "displayName": "Statement-8180825c-61ed-4fb3-9d96-cdc5340b20f1"
325
- }
326
- }
327
- },
328
- "organizationId": {
329
- "type": "MANUAL"
330
- },
331
- "v_nculo_com_grupo_econ_mico": {
332
- "type": "DYNAMIC"
333
- }
334
- },
335
- "errorHandlingOptions": {
336
- "retryOnFailure": {
337
- "value": false
338
- },
339
- "continueOnFailure": {
340
- "value": false
341
- }
342
- }
343
- },
344
- "nextAction": {
345
- "name": "step_8",
346
- "skip": false,
347
- "type": "PIECE",
348
- "valid": true,
349
- "settings": {
350
- "input": {
351
- "url": {
352
- "url": "https://api.pipefy.com/graphql"
353
- },
354
- "auth": "{{connections['exampleConnectionId3']}}",
355
- "body": {
356
- "data": {
357
- "query": "mutation {\n updateCardField(\n input: {card_id: \"{{step_11['output']['cardId']}}\", field_id:\"telefone_de_contato\",new_value:\"{{step_1['output']['telefoneContatoFormatado']}}\"}\n ) {\n clientMutationId\n }\n}\n",
358
- "variables": null
359
- }
360
- },
361
- "method": "POST",
362
- "headers": {},
363
- "failsafe": false,
364
- "body_type": "json",
365
- "queryParams": {},
366
- "followRedirects": false,
367
- "response_is_binary": false
368
- },
369
- "pieceName": "@activepieces/piece-pipefy",
370
- "actionName": "custom_api_call",
371
- "sampleData": {},
372
- "pieceVersion": "0.1.7",
373
- "propertySettings": {
374
- "url": {
375
- "type": "MANUAL",
376
- "schema": {
377
- "url": {
378
- "type": "SHORT_TEXT",
379
- "required": true,
380
- "description": "You can either use the full URL or the relative path to the base URL\ni.e https://api.pipefy.com/graphql/resource or /resource",
381
- "displayName": "URL",
382
- "defaultValue": "https://api.pipefy.com/graphql"
383
- }
384
- }
385
- },
386
- "body": {
387
- "type": "MANUAL",
388
- "schema": {
389
- "data": {
390
- "type": "JSON",
391
- "required": true,
392
- "displayName": "JSON Body"
393
- }
394
- }
395
- },
396
- "method": {
397
- "type": "MANUAL"
398
- },
399
- "headers": {
400
- "type": "MANUAL"
401
- },
402
- "timeout": {
403
- "type": "MANUAL"
404
- },
405
- "failsafe": {
406
- "type": "MANUAL"
407
- },
408
- "body_type": {
409
- "type": "MANUAL"
410
- },
411
- "queryParams": {
412
- "type": "MANUAL"
413
- },
414
- "followRedirects": {
415
- "type": "MANUAL"
416
- },
417
- "response_is_binary": {
418
- "type": "MANUAL"
419
- }
420
- },
421
- "errorHandlingOptions": {
422
- "retryOnFailure": {
423
- "value": false
424
- },
425
- "continueOnFailure": {
426
- "value": false
427
- }
428
- }
429
- },
430
- "nextAction": {
431
- "name": "step_10",
432
- "skip": false,
433
- "type": "PIECE",
434
- "valid": true,
435
- "settings": {
436
- "input": {
437
- "mode": "simple",
438
- "response": {
439
- "response": {}
440
- }
441
- },
442
- "pieceName": "@activepieces/piece-subflows",
443
- "actionName": "returnResponse",
444
- "sampleData": {},
445
- "pieceVersion": "0.4.12",
446
- "propertySettings": {
447
- "mode": {
448
- "type": "MANUAL"
449
- },
450
- "response": {
451
- "type": "MANUAL",
452
- "schema": {
453
- "response": {
454
- "type": "OBJECT",
455
- "required": true,
456
- "displayName": "Response"
457
- }
458
- }
459
- }
460
- },
461
- "errorHandlingOptions": {
462
- "retryOnFailure": {
463
- "value": false
464
- },
465
- "continueOnFailure": {
466
- "value": false
467
- }
468
- }
469
- },
470
- "displayName": "Retornar Copy",
471
- "lastUpdatedDate": "2026-08-11T14:44:34.017Z"
472
- },
473
- "displayName": "atualização Telefone {\"query\":\"mutation {\\n updateCardField(\\n input: {card_id: \\\"0\\\", field_id:\\\"telefone_de_contato\\\",new_value:\\\"+55 (11) 2222-3333\\\"}\\n ) {\\n clientMutationId\\n }\\n}\\n\",\"variables\":null} Copy",
474
- "lastUpdatedDate": "2026-08-11T14:44:34.016Z"
475
- },
476
- "displayName": "Atualização de campos",
477
- "lastUpdatedDate": "2026-08-11T14:44:34.016Z"
478
- },
479
- "displayName": "Normalização v.1",
480
- "lastUpdatedDate": "2026-08-11T14:44:34.016Z"
481
- },
482
- "displayName": "Normalização",
483
- "lastUpdatedDate": "2026-08-11T14:44:34.016Z"
484
- },
485
- null
486
- ],
487
- "settings": {
488
- "branches": [
489
- {
490
- "branchName": "Existe",
491
- "branchType": "CONDITION",
492
- "conditions": [
493
- [
494
- {
495
- "operator": "BOOLEAN_IS_TRUE",
496
- "firstValue": "{{step_11['output']['encontrado']}}"
497
- }
498
- ]
499
- ]
500
- },
501
- {
502
- "branchName": "Otherwise",
503
- "branchType": "FALLBACK"
504
- }
505
- ],
506
- "sampleData": {},
507
- "executionType": "EXECUTE_FIRST_MATCH"
508
- },
509
- "displayName": "Lista Sacado",
510
- "lastUpdatedDate": "2026-08-11T14:44:34.015Z"
511
- },
512
- "displayName": "Conferência id e codigoEmpresa Copy",
513
- "lastUpdatedDate": "2026-08-17T03:09:49.129Z"
514
- },
515
- "displayName": "Buscar Sacado",
516
- "lastUpdatedDate": "2026-08-11T14:44:34.015Z"
517
- },
518
- "lastUpdatedDate": "2026-08-17T03:06:40.549Z",
519
- "type": "PIECE_TRIGGER",
520
- "settings": {
521
- "sampleData": {},
522
- "propertySettings": {
523
- "mode": {
524
- "type": "MANUAL"
525
- },
526
- "exampleData": {
527
- "type": "MANUAL",
528
- "schema": {
529
- "sampleData": {
530
- "type": "example",
531
- "required": false,
532
- "displayName": "example"
533
- }
534
- }
535
- }
536
- },
537
- "pieceName": "@activepieces/piece-subflows",
538
- "pieceVersion": "0.4.11",
539
- "triggerName": "callableFlow",
540
- "input": {
541
- "mode": "advanced",
542
- "exampleData": {
543
- "sampleData": {
544
- "sacado": {
545
- "cep": "example",
546
- "nome": "example",
547
- "email": "example",
548
- "cidade": "example",
549
- "estado": "example",
550
- "origem": "example",
551
- "endereco": "example",
552
- "idSacado": "example",
553
- "percHNeg": {
554
- "totQtd": 0,
555
- "totSac": 0,
556
- "totNaoConfirma": 0
557
- },
558
- "percHPre": {
559
- "totQtd": 0,
560
- "totSac": 0,
561
- "totPresente": 0
562
- },
563
- "cnpjOuCpf": "example",
564
- "idCedente": "example",
565
- "razaoSocial": "example",
566
- "codigoEmpresa": 0,
567
- "telefoneContato": "example",
568
- "liquidacaoPorEvento": [
569
- {
570
- "descricao": "example",
571
- "codigoEvento": 0,
572
- "totalLiquidado": 0,
573
- "quantidadeTitulos": 0
574
- }
575
- ],
576
- "historicoValorAberto": {
577
- "totalTitulosAbertos": 0,
578
- "totalTitulosAbertosQtd": 0,
579
- "totalTitulosAbertosVencer": 0,
580
- "totalTitulosAbertosVencidos": 0,
581
- "totalTitulosAbertosVencerQtd": 0,
582
- "totalTitulosAbertosVencidosQtd": 0
583
- },
584
- "historicoValorLiquidado": {
585
- "totalOpeNaoEfetivadas": 0,
586
- "totalTitulosLiquidados": 0,
587
- "totalOpeNaoEfetivadasQtd": 0,
588
- "totalTitulosLiquidadosQtd": 0,
589
- "totalTitulosLiquidadosPagoDia": 0,
590
- "totalTitulosLiquidadosPagoAtraso": 0,
591
- "totalTitulosLiquidadosPagoDiaQtd": 0,
592
- "totalTitulosLiquidadosPagoAtrasoQtd": 0,
593
- "totalTitulosLiquidadosChequeDevolvido": 0,
594
- "totalTitulosLiquidadosChequeDevolvidoQtd": 0
595
- }
596
- },
597
- "empresaCodigo": 0
598
- }
599
- }
600
- }
601
- }
602
- },
603
- "valid": true,
604
- "schemaVersion": "22",
605
- "notes": []
606
- }
607
- ],
608
- "status": "PUBLISHED"
609
- }
1
+ {
2
+ "name": "✅[PRD][HML][2/2 SUBFLOW][RETORNO CONSULTA/UPDATE] Retorno Sacado",
3
+ "type": "SHARED",
4
+ "summary": "",
5
+ "description": "",
6
+ "tags": [],
7
+ "blogUrl": "",
8
+ "metadata": {
9
+ "externalId": "exampleFlowId03aaaaaa"
10
+ },
11
+ "author": "Integrações Ipaas 000000000",
12
+ "categories": [],
13
+ "pieces": [
14
+ "@activepieces/piece-subflows",
15
+ "@activepieces/piece-pipefy"
16
+ ],
17
+ "flows": [
18
+ {
19
+ "displayName": "✅[PRD][HML][2/2 SUBFLOW][RETORNO CONSULTA/UPDATE] Retorno Sacado",
20
+ "trigger": {
21
+ "name": "trigger",
22
+ "valid": true,
23
+ "displayName": "Callable Flow",
24
+ "nextAction": {
25
+ "name": "step_2",
26
+ "type": "PIECE",
27
+ "valid": true,
28
+ "settings": {
29
+ "input": {
30
+ "auth": "{{connections['exampleConnectionId3']}}",
31
+ "pipeId": "200000005",
32
+ "fieldId": "idsacado",
33
+ "fieldValue": "{{trigger['output']['data']['sacado']['idSacado']}}",
34
+ "organizationId": "100000001"
35
+ },
36
+ "pieceName": "@activepieces/piece-pipefy",
37
+ "actionName": "getCardsByFieldValue",
38
+ "sampleData": {},
39
+ "pieceVersion": "0.1.6",
40
+ "propertySettings": {
41
+ "pipeId": {
42
+ "type": "MANUAL"
43
+ },
44
+ "fieldId": {
45
+ "type": "MANUAL"
46
+ },
47
+ "fieldValue": {
48
+ "type": "MANUAL"
49
+ },
50
+ "organizationId": {
51
+ "type": "MANUAL"
52
+ }
53
+ },
54
+ "errorHandlingOptions": {
55
+ "retryOnFailure": {
56
+ "value": false
57
+ },
58
+ "continueOnFailure": {
59
+ "value": false
60
+ }
61
+ }
62
+ },
63
+ "nextAction": {
64
+ "name": "step_11",
65
+ "skip": false,
66
+ "type": "CODE",
67
+ "valid": true,
68
+ "settings": {
69
+ "input": {
70
+ "base": "{{trigger['output']['data']['sacado']['origem']}}",
71
+ "cards": "{{step_2['output']['data']['cards']}}",
72
+ "empresaCodigo": "{{trigger['output']['data']['sacado']['codigoEmpresa']}}"
73
+ },
74
+ "sampleData": {},
75
+ "sourceCode": {
76
+ "code": "export const code = async (inputs) => {\n const alvoEmpresa = String(inputs.empresaCodigo ?? '').trim();\n const alvoBase = String(inputs.base ?? '').trim();\n\n const card = inputs.cards.find(c => {\n const empresaCard = String(c.fields?.empresacodigo?.value ?? '').trim();\n const baseCard = String(c.fields?.base?.value ?? '').trim();\n return empresaCard === alvoEmpresa && baseCard === alvoBase;\n });\n\n return {\n cardId: card?.id ?? null,\n encontrado: !!card\n };\n};",
77
+ "packageJson": "{}"
78
+ },
79
+ "errorHandlingOptions": {
80
+ "retryOnFailure": {
81
+ "value": false
82
+ },
83
+ "continueOnFailure": {
84
+ "value": false
85
+ }
86
+ }
87
+ },
88
+ "nextAction": {
89
+ "name": "step_3",
90
+ "skip": false,
91
+ "type": "ROUTER",
92
+ "valid": true,
93
+ "children": [
94
+ {
95
+ "name": "step_1",
96
+ "skip": false,
97
+ "type": "CODE",
98
+ "valid": true,
99
+ "settings": {
100
+ "input": {
101
+ "email": "{{trigger['output']['data']['sacado']['email']}}",
102
+ "cnpjOuCpf": "{{trigger['output']['data']['sacado']['cnpjOuCpf']}}",
103
+ "bodyBarramento ": "{{trigger['output']['data']['sacado']}}",
104
+ "telefoneContato ": "{{trigger['output']['data']['sacado']['telefoneContato']}}"
105
+ },
106
+ "sampleData": {},
107
+ "sourceCode": {
108
+ "code": "export const code = async (inputs) => {\n // Normaliza chaves removendo espaços extras\n const normalizedInputs = {};\n for (const key in inputs) {\n normalizedInputs[key.trim()] = inputs[key];\n }\n inputs = normalizedInputs;\n\n // ===== Helper para arredondar números com 2 casas decimais =====\n const round2 = (n) => Math.round((Number(n) || 0) * 100) / 100;\n\n // DDDs válidos no Brasil (nenhum começa com 0 ou 1)\n const DDD_VALIDOS = new Set([\n '11','12','13','14','15','16','17','18','19',\n '21','22','24',\n '27','28',\n '31','32','33','34','35','37','38',\n '41','42','43','44','45','46',\n '47','48','49',\n '51','53','54','55',\n '61',\n '62','63','64',\n '65','66',\n '67',\n '68',\n '69',\n '71','73','74','75','77',\n '79',\n '81','82','83','84','87',\n '85','88','86','89',\n '91','92','93','94','97',\n '95',\n '96',\n '98','99',\n ]);\n\n // ===== Normaliza telefone =====\n let telefoneContato = '';\n let telefoneContatoFormatado = '';\n if (inputs.telefoneContato) {\n let numeros = String(inputs.telefoneContato).replace(/\\D/g, '');\n\n // Remove o 55 inicial se já vier com código do país\n if ((numeros.length === 12 || numeros.length === 13) && numeros.startsWith('55')) {\n numeros = numeros.substring(2);\n }\n\n // Corrige prefixo \"0\" indevido antes do DDD (ex: \"084 3064-6035\" -> \"84 3064-6035\")\n // Nenhum DDD começa com 0, então um \"0\" sobrando aqui sempre indica esse erro de digitação/formatação,\n // seja em número fixo (11 dígitos -> 10) ou celular (12 dígitos -> 11)\n if (numeros.startsWith('0') && (numeros.length === 11 || numeros.length === 12)) {\n numeros = numeros.substring(1);\n }\n\n // Sanity check adicional: se o DDD calculado não é válido, tenta reancorar\n // deslocando um dígito (cobre outros casos de dígito extra vazado no começo)\n const dddCandidato = numeros.substring(0, 2);\n if (!DDD_VALIDOS.has(dddCandidato) && (numeros.length === 11 || numeros.length === 12)) {\n const dddAlternativo = numeros.substring(1, 3);\n if (DDD_VALIDOS.has(dddAlternativo)) {\n numeros = numeros.substring(1);\n }\n }\n\n if (numeros.length === 11) {\n // Celular com DDD\n const ddd = numeros.substring(0, 2);\n const parte1 = numeros.substring(2, 7);\n const parte2 = numeros.substring(7);\n telefoneContato = `55${numeros}`;\n telefoneContatoFormatado = `+55 (${ddd}) ${parte1}-${parte2}`;\n } else if (numeros.length === 10) {\n // Fixo com DDD\n const ddd = numeros.substring(0, 2);\n const parte1 = numeros.substring(2, 6);\n const parte2 = numeros.substring(6);\n telefoneContato = `55${numeros}`;\n telefoneContatoFormatado = `+55 (${ddd}) ${parte1}-${parte2}`;\n } else {\n telefoneContato = numeros;\n telefoneContatoFormatado = numeros;\n }\n }\n\n // ===== Normaliza e-mails =====\n // Se não houver nenhum '@' no input, devolve o valor original e marca emailCheck = false.\n // Caso contrário, considera apenas e-mails válidos (com @ e domínio com TLD),\n // aceitando separação por ; , espaço ou quebra de linha, e devolve separados por vírgula.\n let email = '';\n let emailCheck = true;\n if (inputs.email) {\n const emailStr = String(inputs.email);\n if (!emailStr.includes('@')) {\n // Nenhum @ encontrado - retorna valor original\n email = emailStr;\n emailCheck = false;\n } else {\n const emailRegex = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$/;\n const validos = emailStr\n .split(/[;,\\s]+/)\n .map((e) => e.trim())\n .filter((e) => e && emailRegex.test(e));\n // Remove duplicatas mantendo a ordem\n email = Array.from(new Set(validos)).join(', ');\n }\n }\n\n // ===== Identifica e formata CPF/CNPJ =====\n let cpf = '';\n let cnpj = '';\n let tipo = '';\n if (inputs.cnpjOuCpf) {\n const doc = String(inputs.cnpjOuCpf).replace(/\\D/g, '');\n if (doc.length === 11) {\n cpf = `${doc.substring(0, 3)}.${doc.substring(3, 6)}.${doc.substring(6, 9)}-${doc.substring(9)}`;\n tipo = 'cpf';\n } else if (doc.length === 14) {\n cnpj = `${doc.substring(0, 2)}.${doc.substring(2, 5)}.${doc.substring(5, 8)}/${doc.substring(8, 12)}-${doc.substring(12)}`;\n tipo = 'cnpj';\n }\n }\n\n // ===== Helpers de formatação numérica =====\n const formatBRL = (valor) => {\n const num = Number(valor) || 0;\n return num.toLocaleString('pt-BR', {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n };\n\n const formatInt = (valor) => {\n const num = Number(valor) || 0;\n return num.toLocaleString('pt-BR');\n };\n\n // Formata número como percentual no padrão pt-BR (ex.: \"12,34%\")\n const formatPerc = (valor) => {\n const num = Number(valor) || 0;\n return (\n num.toLocaleString('pt-BR', {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n }) + '%'\n );\n };\n\n // Heurística: campos de contagem/código não levam casas decimais\n const isCountField = (key) => {\n const lower = String(key).toLowerCase();\n return (\n lower.endsWith('qtd') ||\n lower.includes('quantidade') ||\n lower.includes('codigo') ||\n lower.includes('numero')\n );\n };\n\n // Labels amigáveis para campos conhecidos\n const labelMap = {\n totalTitulosLiquidados: 'Total de Títulos Liquidados',\n totalTitulosLiquidadosPagoDia: 'Títulos Liquidados Pagos no Dia',\n totalTitulosLiquidadosPagoAtraso: 'Títulos Liquidados Pagos em Atraso',\n totalOpeNaoEfetivadas: 'Operações Não Efetivadas',\n totalTitulosLiquidadosChequeDevolvido: 'Títulos Liquidados com Cheque Devolvido',\n totalTitulosAbertos: 'Total de Títulos em Aberto',\n totalTitulosAbertosVencidos: 'Títulos em Aberto Vencidos',\n totalTitulosAbertosVencer: 'Títulos em Aberto a Vencer',\n totPresente: 'Total Presente',\n totSac: 'Total Sacado',\n totQtd: 'Total Quantidade',\n totNegativa: 'Total Negativa',\n codigoEvento: 'Código do Evento',\n descricao: 'Descrição',\n totalLiquidado: 'Total Liquidado',\n quantidadeTitulos: 'Quantidade de Títulos',\n historicoValorLiquidado: 'Histórico de Valores Liquidados',\n historicoValorAberto: 'Histórico de Valores em Aberto',\n liquidacaoPorEvento: 'Liquidação por Evento',\n percHPre: 'Percentual Histórico - Presente',\n percHNeg: 'Percentual Histórico - Negativo',\n };\n\n const camelToTitle = (str) =>\n String(str)\n .replace(/([A-Z])/g, ' $1')\n .replace(/^./, (s) => s.toUpperCase())\n .trim();\n\n const getLabel = (key) => labelMap[key] || camelToTitle(key);\n\n // ===== Converte objeto em tabela markdown =====\n // Detecta pares X / XQtd e gera 3 colunas (Indicador | Valor | Quantidade)\n // Caso contrário gera 2 colunas (Campo | Valor)\n const objToMarkdown = (obj) => {\n if (!obj || typeof obj !== 'object' || Array.isArray(obj)) return '';\n const keys = Object.keys(obj);\n if (keys.length === 0) return '';\n\n const temPares = keys.some(\n (k) => !k.endsWith('Qtd') && keys.includes(`${k}Qtd`)\n );\n\n if (temPares) {\n const usados = new Set();\n const linhas = [];\n\n keys.forEach((k) => {\n if (usados.has(k)) return;\n\n if (k.endsWith('Qtd')) {\n // Qtd órfão (sem par valor)\n const baseKey = k.substring(0, k.length - 3);\n if (!keys.includes(baseKey)) {\n linhas.push({\n label: getLabel(baseKey),\n valor: '-',\n qtd: formatInt(obj[k]),\n });\n usados.add(k);\n }\n } else {\n const qtdKey = `${k}Qtd`;\n if (keys.includes(qtdKey)) {\n linhas.push({\n label: getLabel(k),\n valor: formatBRL(obj[k]),\n qtd: formatInt(obj[qtdKey]),\n });\n usados.add(k);\n usados.add(qtdKey);\n } else {\n linhas.push({\n label: getLabel(k),\n valor: formatBRL(obj[k]),\n qtd: '-',\n });\n usados.add(k);\n }\n }\n });\n\n let md = '| Indicador | Valor (R$) | Quantidade |\\n';\n md += '|-----------|-----------:|-----------:|\\n';\n linhas.forEach((l) => {\n md += `| ${l.label} | ${l.valor} | ${l.qtd} |\\n`;\n });\n return md.trim();\n }\n\n // Tabela simples Campo / Valor\n let md = '| Campo | Valor |\\n';\n md += '|-------|------:|\\n';\n keys.forEach((k) => {\n const v = obj[k];\n let formatado;\n if (typeof v === 'number') {\n formatado = isCountField(k) ? formatInt(v) : formatBRL(v);\n } else {\n formatado = v === null || v === undefined ? '' : String(v);\n }\n md += `| ${getLabel(k)} | ${formatado} |\\n`;\n });\n return md.trim();\n };\n\n // ===== Converte array de objetos em tabela markdown =====\n const arrayToMarkdown = (arr) => {\n if (!Array.isArray(arr) || arr.length === 0) return '';\n const itensValidos = arr.filter((i) => i && typeof i === 'object');\n if (itensValidos.length === 0) return '';\n\n const colunas = Array.from(\n itensValidos.reduce((set, item) => {\n Object.keys(item).forEach((k) => set.add(k));\n return set;\n }, new Set())\n );\n\n let md = '| ' + colunas.map(getLabel).join(' | ') + ' |\\n';\n md += '|' + colunas.map(() => '------').join('|') + '|\\n';\n itensValidos.forEach((item) => {\n md +=\n '| ' +\n colunas\n .map((c) => {\n const v = item[c];\n if (v === undefined || v === null) return '';\n if (typeof v === 'number') {\n return isCountField(c) ? formatInt(v) : formatBRL(v);\n }\n return String(v);\n })\n .join(' | ') +\n ' |\\n';\n });\n return md.trim();\n };\n\n // ===== Processa bodyBarramento =====\n const objetosMarkdown = {};\n const partesMarkdown = [];\n\n // Valores calculados de %Hpre e %Hneg (default zerado)\n let percHPre = '0,00%';\n let percHNeg = '0,00%';\n let percHPreNum = 0;\n let percHNegNum = 0;\n\n if (inputs.bodyBarramento && typeof inputs.bodyBarramento === 'object') {\n // Aceita tanto o payload completo (com data.sacado) quanto o objeto direto\n const root =\n (inputs.bodyBarramento.data && inputs.bodyBarramento.data.sacado) ||\n inputs.bodyBarramento;\n\n // ===== Calcula %Hpre e %Hneg =====\n // %Hpre = totPresente / totSac (valor histórico de presente / valor histórico total do sacado)\n if (root.percHPre && typeof root.percHPre === 'object') {\n const totPresente = Number(root.percHPre.totPresente) || 0;\n const totSac = Number(root.percHPre.totSac) || 0;\n const rawHPre = totSac > 0 ? (totPresente / totSac) * 100 : 0;\n percHPreNum = round2(rawHPre);\n percHPre = formatPerc(percHPreNum);\n }\n\n // %Hneg = totNegativa / totSac (valor histórico negativo / valor histórico total do sacado)\n if (root.percHNeg && typeof root.percHNeg === 'object') {\n const totNegativa = Number(root.percHNeg.totNegativa) || 0;\n const totSac = Number(root.percHNeg.totSac) || 0;\n const rawHNeg = totSac > 0 ? (totNegativa / totSac) * 100 : 0;\n percHNegNum = round2(rawHNeg);\n percHNeg = formatPerc(percHNegNum);\n }\n\n // ===== Demais objetos em markdown =====\n for (const key in root) {\n const value = root[key];\n\n // Objeto aninhado com mais de um parâmetro\n if (\n value &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n Object.keys(value).length > 1\n ) {\n const md = objToMarkdown(value);\n if (md) {\n objetosMarkdown[key] = md;\n partesMarkdown.push(`### ${getLabel(key)}\\n\\n${md}`);\n }\n }\n // Array de objetos\n else if (\n Array.isArray(value) &&\n value.length > 0 &&\n typeof value[0] === 'object'\n ) {\n const md = arrayToMarkdown(value);\n if (md) {\n objetosMarkdown[key] = md;\n partesMarkdown.push(`### ${getLabel(key)}\\n\\n${md}`);\n }\n }\n }\n }\n\n const markdownCompleto = partesMarkdown.join('\\n\\n');\n\n return {\n telefoneContato,\n telefoneContatoFormatado,\n email,\n emailCheck,\n tipo,\n cpf,\n cnpj,\n percHPre,\n percHNeg,\n percHPreNum,\n percHNegNum,\n objetosMarkdown,\n markdownCompleto,\n };\n};",
109
+ "packageJson": "{}"
110
+ },
111
+ "errorHandlingOptions": {
112
+ "retryOnFailure": {
113
+ "value": false
114
+ },
115
+ "continueOnFailure": {
116
+ "value": false
117
+ }
118
+ }
119
+ },
120
+ "nextAction": {
121
+ "name": "step_4",
122
+ "skip": true,
123
+ "type": "CODE",
124
+ "valid": true,
125
+ "settings": {
126
+ "input": {
127
+ "email": "{{trigger['output']['data']['sacado']['email']}}",
128
+ "cnpjOuCpf": "{{trigger['output']['data']['sacado']['cnpjOuCpf']}}",
129
+ "bodyBarramento ": "{{trigger['output']['data']['sacado']}}",
130
+ "telefoneContato ": "{{trigger['output']['data']['sacado']['telefoneContato']}}"
131
+ },
132
+ "sampleData": {},
133
+ "sourceCode": {
134
+ "code": "export const code = async (inputs) => {\n // Normaliza chaves removendo espaços extras\n const normalizedInputs = {};\n for (const key in inputs) {\n normalizedInputs[key.trim()] = inputs[key];\n }\n inputs = normalizedInputs;\n\n // ===== Helper para arredondar números com 2 casas decimais =====\n const round2 = (n) => Math.round((Number(n) || 0) * 100) / 100;\n\n // ===== Normaliza telefone =====\n let telefoneContato = '';\n let telefoneContatoFormatado = '';\n if (inputs.telefoneContato) {\n let numeros = String(inputs.telefoneContato).replace(/\\D/g, '');\n // Remove o 55 inicial se já vier com código do país\n if ((numeros.length === 12 || numeros.length === 13) && numeros.startsWith('55')) {\n numeros = numeros.substring(2);\n }\n if (numeros.length === 11) {\n // Celular com DDD\n const ddd = numeros.substring(0, 2);\n const parte1 = numeros.substring(2, 7);\n const parte2 = numeros.substring(7);\n telefoneContato = `55${numeros}`;\n telefoneContatoFormatado = `+55 (${ddd}) ${parte1}-${parte2}`;\n } else if (numeros.length === 10) {\n // Fixo com DDD\n const ddd = numeros.substring(0, 2);\n const parte1 = numeros.substring(2, 6);\n const parte2 = numeros.substring(6);\n telefoneContato = `55${numeros}`;\n telefoneContatoFormatado = `+55 (${ddd}) ${parte1}-${parte2}`;\n } else {\n telefoneContato = numeros;\n telefoneContatoFormatado = numeros;\n }\n }\n\n // ===== Normaliza e-mails =====\n // Se não houver nenhum '@' no input, devolve o valor original e marca emailCheck = false.\n // Caso contrário, considera apenas e-mails válidos (com @ e domínio com TLD),\n // aceitando separação por ; , espaço ou quebra de linha, e devolve separados por vírgula.\n let email = '';\n let emailCheck = true;\n if (inputs.email) {\n const emailStr = String(inputs.email);\n if (!emailStr.includes('@')) {\n // Nenhum @ encontrado - retorna valor original\n email = emailStr;\n emailCheck = false;\n } else {\n const emailRegex = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$/;\n const validos = emailStr\n .split(/[;,\\s]+/)\n .map((e) => e.trim())\n .filter((e) => e && emailRegex.test(e));\n // Remove duplicatas mantendo a ordem\n email = Array.from(new Set(validos)).join(', ');\n }\n }\n\n // ===== Identifica e formata CPF/CNPJ =====\n let cpf = '';\n let cnpj = '';\n let tipo = '';\n if (inputs.cnpjOuCpf) {\n const doc = String(inputs.cnpjOuCpf).replace(/\\D/g, '');\n if (doc.length === 11) {\n cpf = `${doc.substring(0, 3)}.${doc.substring(3, 6)}.${doc.substring(6, 9)}-${doc.substring(9)}`;\n tipo = 'cpf';\n } else if (doc.length === 14) {\n cnpj = `${doc.substring(0, 2)}.${doc.substring(2, 5)}.${doc.substring(5, 8)}/${doc.substring(8, 12)}-${doc.substring(12)}`;\n tipo = 'cnpj';\n }\n }\n\n // ===== Helpers de formatação numérica =====\n const formatBRL = (valor) => {\n const num = Number(valor) || 0;\n return num.toLocaleString('pt-BR', {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n };\n\n const formatInt = (valor) => {\n const num = Number(valor) || 0;\n return num.toLocaleString('pt-BR');\n };\n\n // Formata número como percentual no padrão pt-BR (ex.: \"12,34%\")\n const formatPerc = (valor) => {\n const num = Number(valor) || 0;\n return (\n num.toLocaleString('pt-BR', {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n }) + '%'\n );\n };\n\n // Heurística: campos de contagem/código não levam casas decimais\n const isCountField = (key) => {\n const lower = String(key).toLowerCase();\n return (\n lower.endsWith('qtd') ||\n lower.includes('quantidade') ||\n lower.includes('codigo') ||\n lower.includes('numero')\n );\n };\n\n // Labels amigáveis para campos conhecidos\n const labelMap = {\n totalTitulosLiquidados: 'Total de Títulos Liquidados',\n totalTitulosLiquidadosPagoDia: 'Títulos Liquidados Pagos no Dia',\n totalTitulosLiquidadosPagoAtraso: 'Títulos Liquidados Pagos em Atraso',\n totalOpeNaoEfetivadas: 'Operações Não Efetivadas',\n totalTitulosLiquidadosChequeDevolvido: 'Títulos Liquidados com Cheque Devolvido',\n totalTitulosAbertos: 'Total de Títulos em Aberto',\n totalTitulosAbertosVencidos: 'Títulos em Aberto Vencidos',\n totalTitulosAbertosVencer: 'Títulos em Aberto a Vencer',\n totPresente: 'Total Presente',\n totSac: 'Total Sacado',\n totQtd: 'Total Quantidade',\n totNegativa: 'Total Negativa',\n codigoEvento: 'Código do Evento',\n descricao: 'Descrição',\n totalLiquidado: 'Total Liquidado',\n quantidadeTitulos: 'Quantidade de Títulos',\n historicoValorLiquidado: 'Histórico de Valores Liquidados',\n historicoValorAberto: 'Histórico de Valores em Aberto',\n liquidacaoPorEvento: 'Liquidação por Evento',\n percHPre: 'Percentual Histórico - Presente',\n percHNeg: 'Percentual Histórico - Negativo',\n };\n\n const camelToTitle = (str) =>\n String(str)\n .replace(/([A-Z])/g, ' $1')\n .replace(/^./, (s) => s.toUpperCase())\n .trim();\n\n const getLabel = (key) => labelMap[key] || camelToTitle(key);\n\n // ===== Converte objeto em tabela markdown =====\n // Detecta pares X / XQtd e gera 3 colunas (Indicador | Valor | Quantidade)\n // Caso contrário gera 2 colunas (Campo | Valor)\n const objToMarkdown = (obj) => {\n if (!obj || typeof obj !== 'object' || Array.isArray(obj)) return '';\n const keys = Object.keys(obj);\n if (keys.length === 0) return '';\n\n const temPares = keys.some(\n (k) => !k.endsWith('Qtd') && keys.includes(`${k}Qtd`)\n );\n\n if (temPares) {\n const usados = new Set();\n const linhas = [];\n\n keys.forEach((k) => {\n if (usados.has(k)) return;\n\n if (k.endsWith('Qtd')) {\n // Qtd órfão (sem par valor)\n const baseKey = k.substring(0, k.length - 3);\n if (!keys.includes(baseKey)) {\n linhas.push({\n label: getLabel(baseKey),\n valor: '-',\n qtd: formatInt(obj[k]),\n });\n usados.add(k);\n }\n } else {\n const qtdKey = `${k}Qtd`;\n if (keys.includes(qtdKey)) {\n linhas.push({\n label: getLabel(k),\n valor: formatBRL(obj[k]),\n qtd: formatInt(obj[qtdKey]),\n });\n usados.add(k);\n usados.add(qtdKey);\n } else {\n linhas.push({\n label: getLabel(k),\n valor: formatBRL(obj[k]),\n qtd: '-',\n });\n usados.add(k);\n }\n }\n });\n\n let md = '| Indicador | Valor (R$) | Quantidade |\\n';\n md += '|-----------|-----------:|-----------:|\\n';\n linhas.forEach((l) => {\n md += `| ${l.label} | ${l.valor} | ${l.qtd} |\\n`;\n });\n return md.trim();\n }\n\n // Tabela simples Campo / Valor\n let md = '| Campo | Valor |\\n';\n md += '|-------|------:|\\n';\n keys.forEach((k) => {\n const v = obj[k];\n let formatado;\n if (typeof v === 'number') {\n formatado = isCountField(k) ? formatInt(v) : formatBRL(v);\n } else {\n formatado = v === null || v === undefined ? '' : String(v);\n }\n md += `| ${getLabel(k)} | ${formatado} |\\n`;\n });\n return md.trim();\n };\n\n // ===== Converte array de objetos em tabela markdown =====\n const arrayToMarkdown = (arr) => {\n if (!Array.isArray(arr) || arr.length === 0) return '';\n const itensValidos = arr.filter((i) => i && typeof i === 'object');\n if (itensValidos.length === 0) return '';\n\n const colunas = Array.from(\n itensValidos.reduce((set, item) => {\n Object.keys(item).forEach((k) => set.add(k));\n return set;\n }, new Set())\n );\n\n let md = '| ' + colunas.map(getLabel).join(' | ') + ' |\\n';\n md += '|' + colunas.map(() => '------').join('|') + '|\\n';\n itensValidos.forEach((item) => {\n md +=\n '| ' +\n colunas\n .map((c) => {\n const v = item[c];\n if (v === undefined || v === null) return '';\n if (typeof v === 'number') {\n return isCountField(c) ? formatInt(v) : formatBRL(v);\n }\n return String(v);\n })\n .join(' | ') +\n ' |\\n';\n });\n return md.trim();\n };\n\n // ===== Processa bodyBarramento =====\n const objetosMarkdown = {};\n const partesMarkdown = [];\n\n // Valores calculados de %Hpre e %Hneg (default zerado)\n let percHPre = '0,00%';\n let percHNeg = '0,00%';\n let percHPreNum = 0;\n let percHNegNum = 0;\n\n if (inputs.bodyBarramento && typeof inputs.bodyBarramento === 'object') {\n // Aceita tanto o payload completo (com data.sacado) quanto o objeto direto\n const root =\n (inputs.bodyBarramento.data && inputs.bodyBarramento.data.sacado) ||\n inputs.bodyBarramento;\n\n // ===== Calcula %Hpre e %Hneg =====\n // %Hpre = totPresente / totSac (valor histórico de presente / valor histórico total do sacado)\n if (root.percHPre && typeof root.percHPre === 'object') {\n const totPresente = Number(root.percHPre.totPresente) || 0;\n const totSac = Number(root.percHPre.totSac) || 0;\n const rawHPre = totSac > 0 ? (totPresente / totSac) * 100 : 0;\n percHPreNum = round2(rawHPre);\n percHPre = formatPerc(percHPreNum);\n }\n\n // %Hneg = totNegativa / totSac (valor histórico negativo / valor histórico total do sacado)\n if (root.percHNeg && typeof root.percHNeg === 'object') {\n const totNegativa = Number(root.percHNeg.totNegativa) || 0;\n const totSac = Number(root.percHNeg.totSac) || 0;\n const rawHNeg = totSac > 0 ? (totNegativa / totSac) * 100 : 0;\n percHNegNum = round2(rawHNeg);\n percHNeg = formatPerc(percHNegNum);\n }\n\n // ===== Demais objetos em markdown =====\n for (const key in root) {\n const value = root[key];\n\n // Objeto aninhado com mais de um parâmetro\n if (\n value &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n Object.keys(value).length > 1\n ) {\n const md = objToMarkdown(value);\n if (md) {\n objetosMarkdown[key] = md;\n partesMarkdown.push(`### ${getLabel(key)}\\n\\n${md}`);\n }\n }\n // Array de objetos\n else if (\n Array.isArray(value) &&\n value.length > 0 &&\n typeof value[0] === 'object'\n ) {\n const md = arrayToMarkdown(value);\n if (md) {\n objetosMarkdown[key] = md;\n partesMarkdown.push(`### ${getLabel(key)}\\n\\n${md}`);\n }\n }\n }\n }\n\n const markdownCompleto = partesMarkdown.join('\\n\\n');\n\n return {\n telefoneContato,\n telefoneContatoFormatado,\n email,\n emailCheck,\n tipo,\n cpf,\n cnpj,\n percHPre,\n percHNeg,\n percHPreNum,\n percHNegNum,\n objetosMarkdown,\n markdownCompleto,\n };\n};",
135
+ "packageJson": "{}"
136
+ },
137
+ "errorHandlingOptions": {
138
+ "retryOnFailure": {
139
+ "value": false
140
+ },
141
+ "continueOnFailure": {
142
+ "value": false
143
+ }
144
+ }
145
+ },
146
+ "nextAction": {
147
+ "name": "step_6",
148
+ "skip": false,
149
+ "type": "PIECE",
150
+ "valid": true,
151
+ "settings": {
152
+ "input": {
153
+ "auth": "{{connections['exampleConnectionId3']}}",
154
+ "cardId": "{{step_11['output']['cardId']}}",
155
+ "pipeId": "200000005",
156
+ "phaseId": "300000004",
157
+ "phaseFields": {
158
+ "cep": "{{trigger['output']['data']['sacado']['cep']}}",
159
+ "cpf": "{{step_1['output']['cpf']}}",
160
+ "cnpj": "{{step_1['output']['cnpj']}}",
161
+ "hneg": "{{step_1['output']['objetosMarkdown']['percHNeg']}}",
162
+ "hpre": "{{step_1['output']['objetosMarkdown']['percHPre']}}",
163
+ "nome": "{{trigger['output']['data']['sacado']['nome']}}",
164
+ "email": "{{step_1['output']['email']}}",
165
+ "h_neg": "{{step_1['output']['percHNegNum']}}",
166
+ "h_pre": "{{step_1['output']['percHPreNum']}}",
167
+ "cidade": "{{trigger['output']['data']['sacado']['cidade']}}",
168
+ "estado": "{{trigger['output']['data']['sacado']['estado']}}",
169
+ "endere_o": "{{trigger['output']['data']['sacado']['endereco']}}",
170
+ "raz_o_social": "{{trigger['output']['data']['sacado']['razaoSocial']}}",
171
+ "nome_fantasia": "{{trigger['output']['data']['sacado']['nomeFantasia']}}",
172
+ "hist_rico_valor_presente": "{{step_1['output']['objetosMarkdown']['historicoValorAberto']}}",
173
+ "hist_rico_valor_liquidado": "{{step_1['output']['objetosMarkdown']['historicoValorLiquidado']}}"
174
+ },
175
+ "organizationId": "100000001"
176
+ },
177
+ "pieceName": "@activepieces/piece-pipefy",
178
+ "actionName": "updateCard",
179
+ "sampleData": {},
180
+ "pieceVersion": "0.1.7",
181
+ "propertySettings": {
182
+ "cardId": {
183
+ "type": "MANUAL"
184
+ },
185
+ "pipeId": {
186
+ "type": "MANUAL"
187
+ },
188
+ "phaseId": {
189
+ "type": "MANUAL"
190
+ },
191
+ "phaseFields": {
192
+ "type": "MANUAL",
193
+ "schema": {
194
+ "cep": {
195
+ "type": "SHORT_TEXT",
196
+ "required": false,
197
+ "description": "\"cep\"",
198
+ "displayName": "CEP"
199
+ },
200
+ "cpf": {
201
+ "type": "SHORT_TEXT",
202
+ "required": false,
203
+ "description": "\"cnpjOuCpf\"",
204
+ "displayName": "CPF"
205
+ },
206
+ "cnpj": {
207
+ "type": "SHORT_TEXT",
208
+ "required": false,
209
+ "description": "\"cnpjOuCpf\"",
210
+ "displayName": "CNPJ"
211
+ },
212
+ "hneg": {
213
+ "type": "LONG_TEXT",
214
+ "required": false,
215
+ "description": "❓❓ Aguardando exemplo para conferir como vamos receber o dado",
216
+ "displayName": "hNeg"
217
+ },
218
+ "hpre": {
219
+ "type": "LONG_TEXT",
220
+ "required": false,
221
+ "description": "❓❓ Aguardando exemplo para conferir como vamos receber o dado",
222
+ "displayName": "hPre"
223
+ },
224
+ "nome": {
225
+ "type": "SHORT_TEXT",
226
+ "required": false,
227
+ "description": "\"sacado\"\n\"nome\"",
228
+ "displayName": "Nome"
229
+ },
230
+ "email": {
231
+ "type": "LONG_TEXT",
232
+ "required": false,
233
+ "description": "\"sacado\"\n\"email\"",
234
+ "displayName": "E-mail"
235
+ },
236
+ "h_neg": {
237
+ "type": "NUMBER",
238
+ "required": false,
239
+ "description": "percHNeg\n\n\"totNegativa\" / \"totSac\"",
240
+ "displayName": "%H.Neg"
241
+ },
242
+ "h_pre": {
243
+ "type": "NUMBER",
244
+ "required": false,
245
+ "description": "percHPre\n\n\"totPresente\" / \"totSac\"",
246
+ "displayName": "%H.Pre"
247
+ },
248
+ "cidade": {
249
+ "type": "SHORT_TEXT",
250
+ "required": false,
251
+ "description": "\"cidade\"",
252
+ "displayName": "Cidade"
253
+ },
254
+ "e_mail": {
255
+ "type": "SHORT_TEXT",
256
+ "required": false,
257
+ "description": "❌ Deletar campo, mas antes ajustar os templates de e-mail",
258
+ "displayName": "[DEPRECADO] E-mail"
259
+ },
260
+ "estado": {
261
+ "type": "SHORT_TEXT",
262
+ "required": false,
263
+ "description": "\"estado\"",
264
+ "displayName": "Estado"
265
+ },
266
+ "endere_o": {
267
+ "type": "LONG_TEXT",
268
+ "required": false,
269
+ "description": "\"endereco\"",
270
+ "displayName": "Endereço"
271
+ },
272
+ "idsacado": {
273
+ "type": "SHORT_TEXT",
274
+ "required": false,
275
+ "description": "\"idSacado\"",
276
+ "displayName": "ID Sacado (Barramento)"
277
+ },
278
+ "raz_o_social": {
279
+ "type": "SHORT_TEXT",
280
+ "required": false,
281
+ "description": "\"razaoSocial\"",
282
+ "displayName": "Razão social"
283
+ },
284
+ "empresacodigo": {
285
+ "type": "SHORT_TEXT",
286
+ "required": false,
287
+ "description": "\"codigoEmpresa\"",
288
+ "displayName": "empresaCodigo"
289
+ },
290
+ "nome_fantasia": {
291
+ "type": "SHORT_TEXT",
292
+ "required": false,
293
+ "description": "\"nomeFantasia\"",
294
+ "displayName": "Nome fantasia"
295
+ },
296
+ "telefone_de_contato": {
297
+ "type": "NUMBER",
298
+ "required": false,
299
+ "description": "\"telefoneContato\"",
300
+ "displayName": "Telefone de contato"
301
+ },
302
+ "hist_rico_valor_presente": {
303
+ "type": "LONG_TEXT",
304
+ "required": false,
305
+ "description": "\"historicoValorAberto\"",
306
+ "displayName": "Histórico valor presente"
307
+ },
308
+ "hist_rico_valor_liquidado": {
309
+ "type": "LONG_TEXT",
310
+ "required": false,
311
+ "description": "\"historicoValorLiquidado\"",
312
+ "displayName": "Histórico valor liquidado"
313
+ },
314
+ "hist_rico_do_sacado_1ano_6meses": {
315
+ "type": "LONG_TEXT",
316
+ "required": false,
317
+ "description": "",
318
+ "displayName": "Histórico do sacado (1ano/6meses)"
319
+ },
320
+ "statement_8180825c_61ed_4fb3_9d96_cdc5340b20f1": {
321
+ "type": "SHORT_TEXT",
322
+ "required": false,
323
+ "description": "<p>❓❓❓ \"liquidacaoPorEvento\" - Campo vem do JSON mas não tem campo ( o que vem neste campo??) Esperar exemplo</p>\n<p> </p>\n<p>Exemplo: </p>\n<p> </p>\n<div>\"liquidacaoPorEvento\": [</div>\n<div>{</div>\n<div>\"codigoEvento\": 2,</div>\n<div>\"descricao\": \"Recomprado pelo Cedente\",</div>\n<div>\"totalLiquidado\": 13382.72,</div>\n<div>\"quantidadeTitulos\": 3</div>\n<div>},</div>\n<div>{</div>\n<div>\"codigoEvento\": 313,</div>\n<div>\"descricao\": \"LIQUIDACAO CARTORIO\",</div>\n<div>\"totalLiquidado\": 9903.39,</div>\n<div>\"quantidadeTitulos\": 3</div>\n<div>}</div>\n<p> </p>",
324
+ "displayName": "Statement-8180825c-61ed-4fb3-9d96-cdc5340b20f1"
325
+ }
326
+ }
327
+ },
328
+ "organizationId": {
329
+ "type": "MANUAL"
330
+ },
331
+ "v_nculo_com_grupo_econ_mico": {
332
+ "type": "DYNAMIC"
333
+ }
334
+ },
335
+ "errorHandlingOptions": {
336
+ "retryOnFailure": {
337
+ "value": false
338
+ },
339
+ "continueOnFailure": {
340
+ "value": false
341
+ }
342
+ }
343
+ },
344
+ "nextAction": {
345
+ "name": "step_8",
346
+ "skip": false,
347
+ "type": "PIECE",
348
+ "valid": true,
349
+ "settings": {
350
+ "input": {
351
+ "url": {
352
+ "url": "https://api.pipefy.com/graphql"
353
+ },
354
+ "auth": "{{connections['exampleConnectionId3']}}",
355
+ "body": {
356
+ "data": {
357
+ "query": "mutation {\n updateCardField(\n input: {card_id: \"{{step_11['output']['cardId']}}\", field_id:\"telefone_de_contato\",new_value:\"{{step_1['output']['telefoneContatoFormatado']}}\"}\n ) {\n clientMutationId\n }\n}\n",
358
+ "variables": null
359
+ }
360
+ },
361
+ "method": "POST",
362
+ "headers": {},
363
+ "failsafe": false,
364
+ "body_type": "json",
365
+ "queryParams": {},
366
+ "followRedirects": false,
367
+ "response_is_binary": false
368
+ },
369
+ "pieceName": "@activepieces/piece-pipefy",
370
+ "actionName": "custom_api_call",
371
+ "sampleData": {},
372
+ "pieceVersion": "0.1.7",
373
+ "propertySettings": {
374
+ "url": {
375
+ "type": "MANUAL",
376
+ "schema": {
377
+ "url": {
378
+ "type": "SHORT_TEXT",
379
+ "required": true,
380
+ "description": "You can either use the full URL or the relative path to the base URL\ni.e https://api.pipefy.com/graphql/resource or /resource",
381
+ "displayName": "URL",
382
+ "defaultValue": "https://api.pipefy.com/graphql"
383
+ }
384
+ }
385
+ },
386
+ "body": {
387
+ "type": "MANUAL",
388
+ "schema": {
389
+ "data": {
390
+ "type": "JSON",
391
+ "required": true,
392
+ "displayName": "JSON Body"
393
+ }
394
+ }
395
+ },
396
+ "method": {
397
+ "type": "MANUAL"
398
+ },
399
+ "headers": {
400
+ "type": "MANUAL"
401
+ },
402
+ "timeout": {
403
+ "type": "MANUAL"
404
+ },
405
+ "failsafe": {
406
+ "type": "MANUAL"
407
+ },
408
+ "body_type": {
409
+ "type": "MANUAL"
410
+ },
411
+ "queryParams": {
412
+ "type": "MANUAL"
413
+ },
414
+ "followRedirects": {
415
+ "type": "MANUAL"
416
+ },
417
+ "response_is_binary": {
418
+ "type": "MANUAL"
419
+ }
420
+ },
421
+ "errorHandlingOptions": {
422
+ "retryOnFailure": {
423
+ "value": false
424
+ },
425
+ "continueOnFailure": {
426
+ "value": false
427
+ }
428
+ }
429
+ },
430
+ "nextAction": {
431
+ "name": "step_10",
432
+ "skip": false,
433
+ "type": "PIECE",
434
+ "valid": true,
435
+ "settings": {
436
+ "input": {
437
+ "mode": "simple",
438
+ "response": {
439
+ "response": {}
440
+ }
441
+ },
442
+ "pieceName": "@activepieces/piece-subflows",
443
+ "actionName": "returnResponse",
444
+ "sampleData": {},
445
+ "pieceVersion": "0.4.12",
446
+ "propertySettings": {
447
+ "mode": {
448
+ "type": "MANUAL"
449
+ },
450
+ "response": {
451
+ "type": "MANUAL",
452
+ "schema": {
453
+ "response": {
454
+ "type": "OBJECT",
455
+ "required": true,
456
+ "displayName": "Response"
457
+ }
458
+ }
459
+ }
460
+ },
461
+ "errorHandlingOptions": {
462
+ "retryOnFailure": {
463
+ "value": false
464
+ },
465
+ "continueOnFailure": {
466
+ "value": false
467
+ }
468
+ }
469
+ },
470
+ "displayName": "Retornar Copy",
471
+ "lastUpdatedDate": "2026-08-11T14:44:34.017Z"
472
+ },
473
+ "displayName": "atualização Telefone {\"query\":\"mutation {\\n updateCardField(\\n input: {card_id: \\\"0\\\", field_id:\\\"telefone_de_contato\\\",new_value:\\\"+55 (11) 2222-3333\\\"}\\n ) {\\n clientMutationId\\n }\\n}\\n\",\"variables\":null} Copy",
474
+ "lastUpdatedDate": "2026-08-11T14:44:34.016Z"
475
+ },
476
+ "displayName": "Atualização de campos",
477
+ "lastUpdatedDate": "2026-08-11T14:44:34.016Z"
478
+ },
479
+ "displayName": "Normalização v.1",
480
+ "lastUpdatedDate": "2026-08-11T14:44:34.016Z"
481
+ },
482
+ "displayName": "Normalização",
483
+ "lastUpdatedDate": "2026-08-11T14:44:34.016Z"
484
+ },
485
+ null
486
+ ],
487
+ "settings": {
488
+ "branches": [
489
+ {
490
+ "branchName": "Existe",
491
+ "branchType": "CONDITION",
492
+ "conditions": [
493
+ [
494
+ {
495
+ "operator": "BOOLEAN_IS_TRUE",
496
+ "firstValue": "{{step_11['output']['encontrado']}}"
497
+ }
498
+ ]
499
+ ]
500
+ },
501
+ {
502
+ "branchName": "Otherwise",
503
+ "branchType": "FALLBACK"
504
+ }
505
+ ],
506
+ "sampleData": {},
507
+ "executionType": "EXECUTE_FIRST_MATCH"
508
+ },
509
+ "displayName": "Lista Sacado",
510
+ "lastUpdatedDate": "2026-08-11T14:44:34.015Z"
511
+ },
512
+ "displayName": "Conferência id e codigoEmpresa Copy",
513
+ "lastUpdatedDate": "2026-08-17T03:09:49.129Z"
514
+ },
515
+ "displayName": "Buscar Sacado",
516
+ "lastUpdatedDate": "2026-08-11T14:44:34.015Z"
517
+ },
518
+ "lastUpdatedDate": "2026-08-17T03:06:40.549Z",
519
+ "type": "PIECE_TRIGGER",
520
+ "settings": {
521
+ "sampleData": {},
522
+ "propertySettings": {
523
+ "mode": {
524
+ "type": "MANUAL"
525
+ },
526
+ "exampleData": {
527
+ "type": "MANUAL",
528
+ "schema": {
529
+ "sampleData": {
530
+ "type": "example",
531
+ "required": false,
532
+ "displayName": "example"
533
+ }
534
+ }
535
+ }
536
+ },
537
+ "pieceName": "@activepieces/piece-subflows",
538
+ "pieceVersion": "0.4.11",
539
+ "triggerName": "callableFlow",
540
+ "input": {
541
+ "mode": "advanced",
542
+ "exampleData": {
543
+ "sampleData": {
544
+ "sacado": {
545
+ "cep": "example",
546
+ "nome": "example",
547
+ "email": "example",
548
+ "cidade": "example",
549
+ "estado": "example",
550
+ "origem": "example",
551
+ "endereco": "example",
552
+ "idSacado": "example",
553
+ "percHNeg": {
554
+ "totQtd": 0,
555
+ "totSac": 0,
556
+ "totNaoConfirma": 0
557
+ },
558
+ "percHPre": {
559
+ "totQtd": 0,
560
+ "totSac": 0,
561
+ "totPresente": 0
562
+ },
563
+ "cnpjOuCpf": "example",
564
+ "idCedente": "example",
565
+ "razaoSocial": "example",
566
+ "codigoEmpresa": 0,
567
+ "telefoneContato": "example",
568
+ "liquidacaoPorEvento": [
569
+ {
570
+ "descricao": "example",
571
+ "codigoEvento": 0,
572
+ "totalLiquidado": 0,
573
+ "quantidadeTitulos": 0
574
+ }
575
+ ],
576
+ "historicoValorAberto": {
577
+ "totalTitulosAbertos": 0,
578
+ "totalTitulosAbertosQtd": 0,
579
+ "totalTitulosAbertosVencer": 0,
580
+ "totalTitulosAbertosVencidos": 0,
581
+ "totalTitulosAbertosVencerQtd": 0,
582
+ "totalTitulosAbertosVencidosQtd": 0
583
+ },
584
+ "historicoValorLiquidado": {
585
+ "totalOpeNaoEfetivadas": 0,
586
+ "totalTitulosLiquidados": 0,
587
+ "totalOpeNaoEfetivadasQtd": 0,
588
+ "totalTitulosLiquidadosQtd": 0,
589
+ "totalTitulosLiquidadosPagoDia": 0,
590
+ "totalTitulosLiquidadosPagoAtraso": 0,
591
+ "totalTitulosLiquidadosPagoDiaQtd": 0,
592
+ "totalTitulosLiquidadosPagoAtrasoQtd": 0,
593
+ "totalTitulosLiquidadosChequeDevolvido": 0,
594
+ "totalTitulosLiquidadosChequeDevolvidoQtd": 0
595
+ }
596
+ },
597
+ "empresaCodigo": 0
598
+ }
599
+ }
600
+ }
601
+ }
602
+ },
603
+ "valid": true,
604
+ "schemaVersion": "22",
605
+ "notes": []
606
+ }
607
+ ],
608
+ "status": "PUBLISHED"
609
+ }