Skip to content

Commit 24e0ae6

Browse files
committed
fix: corrige fetch indisponível e remove fallback de lead metric
- Substitui fetch() por helper https nativo no node "Buscar e Formatar Todos" para compatibilidade com versões do n8n que não expõem fetch globalmente - Remove fallback onsite_conversion.messaging_conversation_started_7d nos nodes "Buscar e Formatar Todos" e "Formatar Relatório" — o fallback usava janela de atribuição diferente e inflava o total de leads (ex: 45 vs 34) - Agora ambos os nodes usam exclusivamente onsite_conversion.total_messaging_connection para consistência com o Gerenciador de Anúncios da Meta https://claude.ai/code/session_01TSV3FcRdbPFXKZUAftjEoQ
1 parent d94e542 commit 24e0ae6

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

n8n-alicia-meta-ads.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@
146146
},
147147
{
148148
"parameters": {
149-
"jsCode": "const ctx = $('Calcular Datas').first().json;\nconst token = ctx.metaToken;\nconst datePreset = ctx.datePreset || 'last_7d';\nconst periodStart = ctx.periodStart;\nconst periodEnd = ctx.periodEnd;\nconst periodoLabel = ctx.periodoLabel || '\\u00faltimos 7 dias';\nconst phone = ctx.phone;\n\nconst clientMap = [\n { id: 'act_497795903676192', nome: 'Antonio Neto', type: 'lead' },\n { id: 'act_2493856707309984', nome: 'Gabriel Jacinto', type: 'lead' },\n { id: 'act_2145598605527232', nome: 'Dani Escudero', type: 'lead' },\n { id: 'act_929521557422139', nome: 'Agro', type: 'lead' },\n { id: 'act_544347952854095', nome: 'Escola de M\\u00fasica', type: 'lead' },\n { id: 'act_1509005182799187', nome: 'Panmalhas Assessoria T\\u00eaxtil', type: 'lead' },\n { id: 'act_2811791829124905', nome: 'GFiX Store', type: 'lead' },\n { id: 'act_5585082641598366', nome: 'Arte em Gelo', type: 'lead' },\n { id: 'act_738466861151636', nome: 'ITAG Tecnologia', type: 'lead' },\n { id: 'act_873195821346004', nome: 'Hi Dogz', type: 'purchase' },\n { id: 'act_1673012226810411', nome: 'Batata Bistr\\u00f4', type: 'purchase' },\n { id: 'act_1082397873705862', nome: 'Caribbean Bronze', type: 'lead' },\n { id: 'act_738280412237298', nome: 'Larissa Kelleter', type: 'lead' }\n];\n\nconst fmtMoney = (val) => {\n const n = parseFloat(val) || 0;\n const fixed = n.toFixed(2);\n const parts = fixed.split('.');\n parts[0] = parts[0].replace(/(\\d)(?=(\\d{3})+$)/g, '$1.');\n return parts[0] + ',' + parts[1];\n};\n\nconst fmtNum = (val) => {\n const n = parseInt(val) || 0;\n return String(n).replace(/(\\d)(?=(\\d{3})+$)/g, '$1.');\n};\n\nconst fmtBR = (dateStr) => {\n const d = new Date(dateStr + 'T12:00:00Z');\n return String(d.getUTCDate()).padStart(2, '0') + '/' + String(d.getUTCMonth() + 1).padStart(2, '0');\n};\n\nconst LEAD_ACTION = 'onsite_conversion.total_messaging_connection';\nconst LEAD_FALLBACK = 'onsite_conversion.messaging_conversation_started_7d';\nconst fields = 'spend,impressions,clicks,actions,action_values';\n\nconst dateRange = periodStart === periodEnd\n ? '_\\ud83d\\udcc5 ' + fmtBR(periodStart) + ' (' + periodoLabel + ')_'\n : '_\\ud83d\\udcc5 ' + fmtBR(periodStart) + ' a ' + fmtBR(periodEnd) + ' (' + periodoLabel + ')_';\n\nconst results = [];\n\nfor (const client of clientMap) {\n try {\n const url = 'https://graph.facebook.com/v19.0/' + client.id + '/insights?date_preset=' + encodeURIComponent(datePreset) + '&fields=' + encodeURIComponent(fields) + '&level=campaign&access_token=' + token;\n const res = await fetch(url);\n const data = await res.json();\n const campaigns = (data.data) || [];\n\n if (!campaigns.length) {\n results.push({ json: { phone: phone, output: '*' + client.nome.toUpperCase() + '*\\n\\n' + dateRange + '\\n\\n*Meta Ads*\\n\\n\\u274c Sem dados no per\\u00edodo.' } });\n continue;\n }\n\n let totalSpend = 0, totalImpressions = 0, totalClicks = 0;\n for (const c of campaigns) {\n totalSpend += parseFloat(c.spend || '0');\n totalImpressions += parseInt(c.impressions || '0');\n totalClicks += parseInt(c.clicks || '0');\n }\n\n let reportText;\n\n if (client.type === 'purchase') {\n let totalPurchases = 0, totalRevenue = 0;\n for (const c of campaigns) {\n const pa = (c.actions || []).find(a => a.action_type === 'purchase' || a.action_type === 'offsite_conversion.fb_pixel_purchase');\n if (pa) totalPurchases += parseInt(pa.value);\n const ra = (c.action_values || []).find(a => a.action_type === 'purchase' || a.action_type === 'offsite_conversion.fb_pixel_purchase');\n if (ra) totalRevenue += parseFloat(ra.value);\n }\n const cpp = totalPurchases > 0 ? totalSpend / totalPurchases : 0;\n reportText =\n '*' + client.nome.toUpperCase() + '*' + '\\n\\n' +\n dateRange + '\\n\\n' +\n '*Meta Ads*' + '\\n\\n' +\n 'Impress\\u00f5es: ' + fmtNum(totalImpressions) + '\\n\\n' +\n 'Cliques: ' + fmtNum(totalClicks) + '\\n\\n' +\n 'Vendas: ' + totalPurchases + '\\n\\n' +\n 'Faturamento: R$ ' + fmtMoney(totalRevenue) + '\\n\\n' +\n 'Custo por venda: R$ ' + fmtMoney(cpp) + '\\n\\n' +\n '*INVESTIMENTO TOTAL: R$ ' + fmtMoney(totalSpend) + '*';\n } else {\n // Leads = Novos contatos de mensagem (campanhas WhatsApp)\n let leadSpend = 0, totalLeads = 0;\n for (const c of campaigns) {\n const la = (c.actions || []).find(a => a.action_type === LEAD_ACTION)\n || (c.actions || []).find(a => a.action_type === LEAD_FALLBACK);\n if (la) {\n leadSpend += parseFloat(c.spend || '0');\n totalLeads += parseInt(la.value);\n }\n }\n const cpl = totalLeads > 0 ? leadSpend / totalLeads : 0;\n reportText =\n '*' + client.nome.toUpperCase() + '*' + '\\n\\n' +\n dateRange + '\\n\\n' +\n '*Meta Ads*' + '\\n\\n' +\n 'Impress\\u00f5es: ' + fmtNum(totalImpressions) + '\\n\\n' +\n 'Cliques: ' + fmtNum(totalClicks) + '\\n\\n' +\n 'Leads: ' + totalLeads + '\\n\\n' +\n 'Custo por lead: R$ ' + fmtMoney(cpl) + '\\n\\n' +\n '*INVESTIMENTO TOTAL: R$ ' + fmtMoney(totalSpend) + '*';\n }\n\n results.push({ json: { phone: phone, output: reportText } });\n } catch(e) {\n results.push({ json: { phone: phone, output: '*' + client.nome.toUpperCase() + '*\\n\\n\\u274c Erro ao buscar dados: ' + e.message } });\n }\n}\n\nreturn results;"
149+
"jsCode": "const https = require('https');\nconst httpGet = (url) => new Promise((resolve, reject) => { https.get(url, (res) => { let d = ''; res.on('data', c => d += c); res.on('end', () => { try { resolve(JSON.parse(d)); } catch(e) { reject(e); } }); }).on('error', reject); });\nconst ctx = $('Calcular Datas').first().json;\nconst token = ctx.metaToken;\nconst datePreset = ctx.datePreset || 'last_7d';\nconst periodStart = ctx.periodStart;\nconst periodEnd = ctx.periodEnd;\nconst periodoLabel = ctx.periodoLabel || '\\u00faltimos 7 dias';\nconst phone = ctx.phone;\n\nconst clientMap = [\n { id: 'act_497795903676192', nome: 'Antonio Neto', type: 'lead' },\n { id: 'act_2493856707309984', nome: 'Gabriel Jacinto', type: 'lead' },\n { id: 'act_2145598605527232', nome: 'Dani Escudero', type: 'lead' },\n { id: 'act_929521557422139', nome: 'Agro', type: 'lead' },\n { id: 'act_544347952854095', nome: 'Escola de M\\u00fasica', type: 'lead' },\n { id: 'act_1509005182799187', nome: 'Panmalhas Assessoria T\\u00eaxtil', type: 'lead' },\n { id: 'act_2811791829124905', nome: 'GFiX Store', type: 'lead' },\n { id: 'act_5585082641598366', nome: 'Arte em Gelo', type: 'lead' },\n { id: 'act_738466861151636', nome: 'ITAG Tecnologia', type: 'lead' },\n { id: 'act_873195821346004', nome: 'Hi Dogz', type: 'purchase' },\n { id: 'act_1673012226810411', nome: 'Batata Bistr\\u00f4', type: 'purchase' },\n { id: 'act_1082397873705862', nome: 'Caribbean Bronze', type: 'lead' },\n { id: 'act_738280412237298', nome: 'Larissa Kelleter', type: 'lead' }\n];\n\nconst fmtMoney = (val) => {\n const n = parseFloat(val) || 0;\n const fixed = n.toFixed(2);\n const parts = fixed.split('.');\n parts[0] = parts[0].replace(/(\\d)(?=(\\d{3})+$)/g, '$1.');\n return parts[0] + ',' + parts[1];\n};\n\nconst fmtNum = (val) => {\n const n = parseInt(val) || 0;\n return String(n).replace(/(\\d)(?=(\\d{3})+$)/g, '$1.');\n};\n\nconst fmtBR = (dateStr) => {\n const d = new Date(dateStr + 'T12:00:00Z');\n return String(d.getUTCDate()).padStart(2, '0') + '/' + String(d.getUTCMonth() + 1).padStart(2, '0');\n};\n\nconst LEAD_ACTION = 'onsite_conversion.total_messaging_connection';\nconst fields = 'spend,impressions,clicks,actions,action_values';\n\nconst dateRange = periodStart === periodEnd\n ? '_\\ud83d\\udcc5 ' + fmtBR(periodStart) + ' (' + periodoLabel + ')_'\n : '_\\ud83d\\udcc5 ' + fmtBR(periodStart) + ' a ' + fmtBR(periodEnd) + ' (' + periodoLabel + ')_';\n\nconst results = [];\n\nfor (const client of clientMap) {\n try {\n const url = 'https://graph.facebook.com/v19.0/' + client.id + '/insights?date_preset=' + encodeURIComponent(datePreset) + '&fields=' + encodeURIComponent(fields) + '&level=campaign&access_token=' + token;\n const data = await httpGet(url);\n const campaigns = (data.data) || [];\n\n if (!campaigns.length) {\n results.push({ json: { phone: phone, output: '*' + client.nome.toUpperCase() + '*\\n\\n' + dateRange + '\\n\\n*Meta Ads*\\n\\n\\u274c Sem dados no per\\u00edodo.' } });\n continue;\n }\n\n let totalSpend = 0, totalImpressions = 0, totalClicks = 0;\n for (const c of campaigns) {\n totalSpend += parseFloat(c.spend || '0');\n totalImpressions += parseInt(c.impressions || '0');\n totalClicks += parseInt(c.clicks || '0');\n }\n\n let reportText;\n\n if (client.type === 'purchase') {\n let totalPurchases = 0, totalRevenue = 0;\n for (const c of campaigns) {\n const pa = (c.actions || []).find(a => a.action_type === 'purchase' || a.action_type === 'offsite_conversion.fb_pixel_purchase');\n if (pa) totalPurchases += parseInt(pa.value);\n const ra = (c.action_values || []).find(a => a.action_type === 'purchase' || a.action_type === 'offsite_conversion.fb_pixel_purchase');\n if (ra) totalRevenue += parseFloat(ra.value);\n }\n const cpp = totalPurchases > 0 ? totalSpend / totalPurchases : 0;\n reportText =\n '*' + client.nome.toUpperCase() + '*' + '\\n\\n' +\n dateRange + '\\n\\n' +\n '*Meta Ads*' + '\\n\\n' +\n 'Impress\\u00f5es: ' + fmtNum(totalImpressions) + '\\n\\n' +\n 'Cliques: ' + fmtNum(totalClicks) + '\\n\\n' +\n 'Vendas: ' + totalPurchases + '\\n\\n' +\n 'Faturamento: R$ ' + fmtMoney(totalRevenue) + '\\n\\n' +\n 'Custo por venda: R$ ' + fmtMoney(cpp) + '\\n\\n' +\n '*INVESTIMENTO TOTAL: R$ ' + fmtMoney(totalSpend) + '*';\n } else {\n // Leads = Novos contatos de mensagem (campanhas WhatsApp)\n let leadSpend = 0, totalLeads = 0;\n for (const c of campaigns) {\n const la = (c.actions || []).find(a => a.action_type === LEAD_ACTION);\n if (la) {\n leadSpend += parseFloat(c.spend || '0');\n totalLeads += parseInt(la.value);\n }\n }\n const cpl = totalLeads > 0 ? leadSpend / totalLeads : 0;\n reportText =\n '*' + client.nome.toUpperCase() + '*' + '\\n\\n' +\n dateRange + '\\n\\n' +\n '*Meta Ads*' + '\\n\\n' +\n 'Impress\\u00f5es: ' + fmtNum(totalImpressions) + '\\n\\n' +\n 'Cliques: ' + fmtNum(totalClicks) + '\\n\\n' +\n 'Leads: ' + totalLeads + '\\n\\n' +\n 'Custo por lead: R$ ' + fmtMoney(cpl) + '\\n\\n' +\n '*INVESTIMENTO TOTAL: R$ ' + fmtMoney(totalSpend) + '*';\n }\n\n results.push({ json: { phone: phone, output: reportText } });\n } catch(e) {\n results.push({ json: { phone: phone, output: '*' + client.nome.toUpperCase() + '*\\n\\n\\u274c Erro ao buscar dados: ' + e.message } });\n }\n}\n\nreturn results;"
150150
},
151151
"id": "f1e2d3c4-b5a6-7890-abcd-ef1234567890",
152152
"name": "Buscar e Formatar Todos",
@@ -196,7 +196,7 @@
196196
},
197197
{
198198
"parameters": {
199-
"jsCode": "const metaData = $input.first().json;\nconst ctx = $('Calcular Datas').first().json;\nconst campaigns = metaData.data || [];\n\nconst fmtMoney = (val) => {\n const n = parseFloat(val) || 0;\n const fixed = n.toFixed(2);\n const parts = fixed.split('.');\n parts[0] = parts[0].replace(/(\\d)(?=(\\d{3})+$)/g, '$1.');\n return parts[0] + ',' + parts[1];\n};\n\nconst fmtNum = (val) => {\n const n = parseInt(val) || 0;\n return String(n).replace(/(\\d)(?=(\\d{3})+$)/g, '$1.');\n};\n\nconst fmtBR = (dateStr) => {\n const d = new Date(dateStr + 'T12:00:00Z');\n return String(d.getUTCDate()).padStart(2, '0') + '/' + String(d.getUTCMonth() + 1).padStart(2, '0');\n};\n\nif (!campaigns.length) {\n return [{ json: {\n phone: ctx.phone,\n output: '\\u274c Sem dados para *' + (ctx.clientNome || '').toUpperCase() + '* no per\\u00edodo solicitado.'\n } }];\n}\n\nconst purchaseAccountIds = ['act_873195821346004', 'act_1673012226810411'];\nconst isPurchase = purchaseAccountIds.includes(ctx.clientFound);\n\nlet totalSpend = 0;\nlet totalImpressions = 0;\nlet totalClicks = 0;\n\nfor (const c of campaigns) {\n totalSpend += parseFloat(c.spend || '0');\n totalImpressions += parseInt(c.impressions || '0');\n totalClicks += parseInt(c.clicks || '0');\n}\n\nconst clientNameUpper = (ctx.clientNome || '').toUpperCase();\nconst periodoLabel = ctx.periodoLabel || '\\u00faltimos 7 dias';\nconst periodStart = ctx.periodStart || ctx.last7Start;\nconst periodEnd = ctx.periodEnd || ctx.last7End;\nconst dateRange = periodStart === periodEnd\n ? '_\\ud83d\\udcc5 ' + fmtBR(periodStart) + ' (' + periodoLabel + ')_'\n : '_\\ud83d\\udcc5 ' + fmtBR(periodStart) + ' a ' + fmtBR(periodEnd) + ' (' + periodoLabel + ')_';\n\nlet reportText;\n\nif (isPurchase) {\n let totalPurchases = 0;\n let totalRevenue = 0;\n for (const c of campaigns) {\n const purchaseAction = (c.actions || []).find(a =>\n a.action_type === 'purchase' ||\n a.action_type === 'offsite_conversion.fb_pixel_purchase'\n );\n if (purchaseAction) totalPurchases += parseInt(purchaseAction.value);\n const revenueAction = (c.action_values || []).find(a =>\n a.action_type === 'purchase' ||\n a.action_type === 'offsite_conversion.fb_pixel_purchase'\n );\n if (revenueAction) totalRevenue += parseFloat(revenueAction.value);\n }\n const cpp = totalPurchases > 0 ? totalSpend / totalPurchases : 0;\n reportText =\n '*' + clientNameUpper + '*' + '\\n\\n' +\n dateRange + '\\n\\n' +\n '*Meta Ads*' + '\\n\\n' +\n 'Impress\\u00f5es: ' + fmtNum(totalImpressions) + '\\n\\n' +\n 'Cliques: ' + fmtNum(totalClicks) + '\\n\\n' +\n 'Vendas: ' + totalPurchases + '\\n\\n' +\n 'Faturamento: R$ ' + fmtMoney(totalRevenue) + '\\n\\n' +\n 'Custo por venda: R$ ' + fmtMoney(cpp) + '\\n\\n' +\n '*INVESTIMENTO TOTAL: R$ ' + fmtMoney(totalSpend) + '*';\n} else {\n // Leads = Novos contatos de mensagem (campanhas WhatsApp)\n // CPL calculado somente sobre campanhas com destino WhatsApp\n const LEAD_ACTION = 'onsite_conversion.total_messaging_connection';\n const LEAD_FALLBACK = 'onsite_conversion.messaging_conversation_started_7d';\n\n let leadSpend = 0;\n let totalLeads = 0;\n for (const c of campaigns) {\n const leadAction = (c.actions || []).find(a => a.action_type === LEAD_ACTION)\n || (c.actions || []).find(a => a.action_type === LEAD_FALLBACK);\n if (leadAction) {\n leadSpend += parseFloat(c.spend || '0');\n totalLeads += parseInt(leadAction.value);\n }\n }\n const cpl = totalLeads > 0 ? leadSpend / totalLeads : 0;\n reportText =\n '*' + clientNameUpper + '*' + '\\n\\n' +\n dateRange + '\\n\\n' +\n '*Meta Ads*' + '\\n\\n' +\n 'Impress\\u00f5es: ' + fmtNum(totalImpressions) + '\\n\\n' +\n 'Cliques: ' + fmtNum(totalClicks) + '\\n\\n' +\n 'Leads: ' + totalLeads + '\\n\\n' +\n 'Custo por lead: R$ ' + fmtMoney(cpl) + '\\n\\n' +\n '*INVESTIMENTO TOTAL: R$ ' + fmtMoney(totalSpend) + '*';\n}\n\nreturn [{ json: { phone: ctx.phone, output: reportText } }];"
199+
"jsCode": "const metaData = $input.first().json;\nconst ctx = $('Calcular Datas').first().json;\nconst campaigns = metaData.data || [];\n\nconst fmtMoney = (val) => {\n const n = parseFloat(val) || 0;\n const fixed = n.toFixed(2);\n const parts = fixed.split('.');\n parts[0] = parts[0].replace(/(\\d)(?=(\\d{3})+$)/g, '$1.');\n return parts[0] + ',' + parts[1];\n};\n\nconst fmtNum = (val) => {\n const n = parseInt(val) || 0;\n return String(n).replace(/(\\d)(?=(\\d{3})+$)/g, '$1.');\n};\n\nconst fmtBR = (dateStr) => {\n const d = new Date(dateStr + 'T12:00:00Z');\n return String(d.getUTCDate()).padStart(2, '0') + '/' + String(d.getUTCMonth() + 1).padStart(2, '0');\n};\n\nif (!campaigns.length) {\n return [{ json: {\n phone: ctx.phone,\n output: '\\u274c Sem dados para *' + (ctx.clientNome || '').toUpperCase() + '* no per\\u00edodo solicitado.'\n } }];\n}\n\nconst purchaseAccountIds = ['act_873195821346004', 'act_1673012226810411'];\nconst isPurchase = purchaseAccountIds.includes(ctx.clientFound);\n\nlet totalSpend = 0;\nlet totalImpressions = 0;\nlet totalClicks = 0;\n\nfor (const c of campaigns) {\n totalSpend += parseFloat(c.spend || '0');\n totalImpressions += parseInt(c.impressions || '0');\n totalClicks += parseInt(c.clicks || '0');\n}\n\nconst clientNameUpper = (ctx.clientNome || '').toUpperCase();\nconst periodoLabel = ctx.periodoLabel || '\\u00faltimos 7 dias';\nconst periodStart = ctx.periodStart || ctx.last7Start;\nconst periodEnd = ctx.periodEnd || ctx.last7End;\nconst dateRange = periodStart === periodEnd\n ? '_\\ud83d\\udcc5 ' + fmtBR(periodStart) + ' (' + periodoLabel + ')_'\n : '_\\ud83d\\udcc5 ' + fmtBR(periodStart) + ' a ' + fmtBR(periodEnd) + ' (' + periodoLabel + ')_';\n\nlet reportText;\n\nif (isPurchase) {\n let totalPurchases = 0;\n let totalRevenue = 0;\n for (const c of campaigns) {\n const purchaseAction = (c.actions || []).find(a =>\n a.action_type === 'purchase' ||\n a.action_type === 'offsite_conversion.fb_pixel_purchase'\n );\n if (purchaseAction) totalPurchases += parseInt(purchaseAction.value);\n const revenueAction = (c.action_values || []).find(a =>\n a.action_type === 'purchase' ||\n a.action_type === 'offsite_conversion.fb_pixel_purchase'\n );\n if (revenueAction) totalRevenue += parseFloat(revenueAction.value);\n }\n const cpp = totalPurchases > 0 ? totalSpend / totalPurchases : 0;\n reportText =\n '*' + clientNameUpper + '*' + '\\n\\n' +\n dateRange + '\\n\\n' +\n '*Meta Ads*' + '\\n\\n' +\n 'Impress\\u00f5es: ' + fmtNum(totalImpressions) + '\\n\\n' +\n 'Cliques: ' + fmtNum(totalClicks) + '\\n\\n' +\n 'Vendas: ' + totalPurchases + '\\n\\n' +\n 'Faturamento: R$ ' + fmtMoney(totalRevenue) + '\\n\\n' +\n 'Custo por venda: R$ ' + fmtMoney(cpp) + '\\n\\n' +\n '*INVESTIMENTO TOTAL: R$ ' + fmtMoney(totalSpend) + '*';\n} else {\n // Leads = Novos contatos de mensagem (campanhas WhatsApp)\n // CPL calculado somente sobre campanhas com destino WhatsApp\n const LEAD_ACTION = 'onsite_conversion.total_messaging_connection';\n\n let leadSpend = 0;\n let totalLeads = 0;\n for (const c of campaigns) {\n const leadAction = (c.actions || []).find(a => a.action_type === LEAD_ACTION);\n if (leadAction) {\n leadSpend += parseFloat(c.spend || '0');\n totalLeads += parseInt(leadAction.value);\n }\n }\n const cpl = totalLeads > 0 ? leadSpend / totalLeads : 0;\n reportText =\n '*' + clientNameUpper + '*' + '\\n\\n' +\n dateRange + '\\n\\n' +\n '*Meta Ads*' + '\\n\\n' +\n 'Impress\\u00f5es: ' + fmtNum(totalImpressions) + '\\n\\n' +\n 'Cliques: ' + fmtNum(totalClicks) + '\\n\\n' +\n 'Leads: ' + totalLeads + '\\n\\n' +\n 'Custo por lead: R$ ' + fmtMoney(cpl) + '\\n\\n' +\n '*INVESTIMENTO TOTAL: R$ ' + fmtMoney(totalSpend) + '*';\n}\n\nreturn [{ json: { phone: ctx.phone, output: reportText } }];"
200200
},
201201
"id": "2b3745d9-82ef-4d9a-aa8d-db402408a07e",
202202
"name": "Formatar Relatório",

0 commit comments

Comments
 (0)