Files
cotizador-wmc-artefactos/cotizador-wmc-artefactos.json
T

4187 lines
136 KiB
JSON

{
"updatedAt": "2026-08-29T16:24:36.304Z",
"createdAt": "2026-08-22T14:54:47.146Z",
"id": "kHT6jUVIcYGjagV3",
"name": "Cotizador WMC - Artefactos",
"description": null,
"active": true,
"isArchived": false,
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "cotizador-wmc-artifacts",
"responseMode": "responseNode",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
-6256,
8400
],
"id": "d2b8313c-4151-4279-b878-717c542c5921",
"name": "Webhook - Artefactos",
"webhookId": "796454bf-78e1-404c-9ff2-2fb65c10b41b"
},
{
"parameters": {
"jsCode": "// Configuraci贸n local del workflow. No utiliza variables de entorno.\nreturn [{json:{\n ...$json,\n config:{\n supabaseUrl:\"https://dbit.digitalcompass.agency\",\n supabaseAnonKey:\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE\",\n googleAutomationUrl:\"https://script.google.com/macros/s/AKfycbxCmB1VwGO9omH0jPWecOKBiRVQexhCLQa-uCDEXu1Q4vmYCjVPQig_lRFhXFZvFyct/exec\",\n googleAutomationSecret:\"mwI_n-1r4_-QTLp1-zIt-zQKh_HqaoGoVhyapyLN2T2-r7xf8iP5AC3v9wJt5Av6\",\n internalEmailSecret:\"fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08\"\n }\n}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-6048,
8400
],
"id": "48caedca-d987-4262-9a64-8fe7f269f28b",
"name": "Configuraci贸n - sin ENV"
},
{
"parameters": {
"jsCode": "const body=$json.body??{};\nconst headers=$json.headers??{};\nconst clean=(v,m=12000)=>typeof v==='string'?v.trim().slice(0,m):'';\nconst auth=clean(headers.authorization||headers.Authorization);\nconst internalSecret=clean(headers['x-wmc-internal-secret']||headers['X-WMC-Internal-Secret'],500);\nconst expectedInternalSecret='fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08';\nconst action=clean(body.action,80);\nconst allowed=['generate_quote','generate_proposal','generate_image','generate_monthly_glm'];\nconst internalEmail=body.internalEmail===true || internalSecret!=='';\nif(!internalEmail && !auth.startsWith('Bearer ')) throw new Error('Falta Authorization Bearer.');\nreturn [{json:{\n auth, internalEmail, internalAuthorized: internalEmail && internalSecret===expectedInternalSecret,\n action, shouldGenerate:allowed.includes(action), quote:body.quote??null, artifact:body.artifact??null,\n user:body.user??{}, conversationId:clean(body.conversationId,220),\n appSessionId:clean(body.appSessionId,250)||`artifact-${Date.now()}`, model:clean(body.model,120)\n}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-5824,
8400
],
"id": "69882ba8-924f-4f90-b5de-563bed38f4ae",
"name": "Normalizar solicitud"
},
{
"parameters": {
"url": "https://dbit.digitalcompass.agency/auth/v1/user",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "={{ $json.auth }}"
}
]
},
"options": {
"timeout": 20000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-5600,
8400
],
"id": "cc69a496-1954-47cd-abd7-8011d090f114",
"name": "Supabase - validar JWT",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const req=$node[\"Normalizar solicitud\"].json;\nconst u=$json??{};\nconst id=String(u.id||'').trim();\nconst email=String(u.email||'').trim().toLowerCase();\nconst claimed=String(req.user?.email||'').trim().toLowerCase();\nconst jwtValid=Boolean(id&&email.endsWith('@gomezleemarketing.com')&&(!claimed||claimed===email));\nreturn [{json:{...req,userId:id,verifiedEmail:email,jwtValid}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-5376,
8400
],
"id": "b8b1ec7a-90d3-4613-905c-073fb53acdc8",
"name": "Validar identidad"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "b044dcb5-a78a-40ce-a537-a7949ef226c8",
"leftValue": "={{ $json.jwtValid }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-5168,
8400
],
"id": "c3a2edf7-9d21-4c6a-9a63-665ca99b29d4",
"name": "JWT v谩lido?"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ {ok:false,error:'Sesi贸n Supabase inv谩lida.'} }}",
"options": {
"responseCode": 401
}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.4,
"position": [
-4944,
8688
],
"id": "f8c7aea9-0bdb-4828-badf-98f6caaf9c16",
"name": "Responder 401"
},
{
"parameters": {
"url": "={{ 'https://dbit.digitalcompass.agency/rest/v1/cotizador_wmc_access?select=email,full_name,is_active,can_use_tarifario&email=eq.' + encodeURIComponent($json.verifiedEmail) + '&is_active=eq.true' + '&limit=1' }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "={{ $json.auth }}"
}
]
},
"options": {
"timeout": 20000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-4944,
8320
],
"id": "2f107a29-ff3b-430a-9879-c6be179d3da3",
"name": "Supabase - acceso",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const req = $node[\"Validar identidad\"].json;\nconst raw = $json ?? {};\n\n// n8n 2.21.4 puede convertir una respuesta PostgREST con una sola fila\n// en un objeto individual en vez de conservar el array original.\n// Aceptamos todas las formas posibles de respuesta.\nlet row = null;\n\nif (Array.isArray(raw)) {\n row = raw[0] ?? null;\n} else if (Array.isArray(raw?.data)) {\n row = raw.data[0] ?? null;\n} else if (Array.isArray(raw?.body)) {\n row = raw.body[0] ?? null;\n} else if (raw?.body && typeof raw.body === 'object' && !Array.isArray(raw.body)) {\n row = raw.body;\n} else if (raw && typeof raw === 'object' && ('email' in raw || 'is_active' in raw || 'full_name' in raw)) {\n row = raw;\n}\n\nconst normalizeEmail = (value) => String(value ?? '').trim().toLowerCase();\nconst rowEmail = normalizeEmail(row?.email);\nconst active = row?.is_active === true || String(row?.is_active ?? '').toLowerCase() === 'true';\n\nconst accessAllowed = Boolean(\n row &&\n active &&\n rowEmail &&\n rowEmail === normalizeEmail(req.verifiedEmail)\n);\n\nreturn [{\n json: {\n ...req,\n accessAllowed,\n fullName: row?.full_name || req.user?.name || req.verifiedEmail,\n canUseTarifario: accessAllowed && (\n row?.can_use_tarifario === true ||\n String(row?.can_use_tarifario ?? '').toLowerCase() === 'true'\n ),\n accessLookupOk: Boolean(row)\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-4720,
8320
],
"id": "c9ef4878-6880-43af-8040-2040d43c521b",
"name": "Validar acceso"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "4539e2f3-4739-4d34-bbe0-4239868c30c4",
"leftValue": "={{ $json.accessAllowed }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-4496,
8320
],
"id": "5c315269-c38d-47e2-9d2b-fa02a4f3f1cc",
"name": "Acceso permitido?"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ {ok:false,error:'No tienes acceso activo al Cotizador Walmart Connect.'} }}",
"options": {
"responseCode": 403
}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.4,
"position": [
-4288,
8688
],
"id": "3a052ddc-3a65-4be0-8375-db968369562e",
"name": "Responder 403"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "25b6fd12-c4b4-4938-a319-0572e307e49b",
"leftValue": "={{ $json.shouldGenerate }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-4288,
8320
],
"id": "41bbecc4-458e-4bc2-8c68-7b32fa9ef020",
"name": "Debe generar?"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ {ok:true,skipped:true,message:'La respuesta no requiere crear un archivo.'} }}",
"options": {
"responseCode": 200
}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.4,
"position": [
-4064,
8688
],
"id": "799cfcaf-c04c-4b95-aec0-b2abc39613e1",
"name": "Responder sin artefacto"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "cd73b109-158e-4aa8-93ab-40b1c9c77de5",
"leftValue": "={{ $json.action }}",
"rightValue": "generate_image",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-4064,
8320
],
"id": "5a3ec8cb-c3d9-4e5c-8cea-7a389247adc0",
"name": "Es imagen?"
},
{
"parameters": {
"resource": "image",
"modelId": {
"__rl": true,
"value": "models/gemini-3-pro-image",
"mode": "list",
"cachedResultName": "models/gemini-3-pro-image (Nano Banana Pro)"
},
"prompt": "={{ $json.artifact?.imagePrompt || $json.artifact?.prompt || $json.artifact?.title || 'Visual profesional para Walmart Connect' }}",
"options": {
"binaryPropertyOutput": "data"
}
},
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"typeVersion": 1.2,
"position": [
-3840,
8080
],
"id": "bc3a2875-1e89-42e5-a2fb-a853901f9f5c",
"name": "Gemini - Generar imagen",
"retryOnFail": true,
"maxTries": 2,
"waitBetweenTries": 1500,
"credentials": {
"googlePalmApi": {
"id": "jvsXYwL6IOoY2DBU",
"name": "Isaac - Gemini Api Pago"
}
}
},
{
"parameters": {
"name": "={{ 'WMC_' + String($node[\"Contexto Artefacto\"].json.artifact?.title || 'visual').replace(/[^a-zA-Z0-9谩茅铆贸煤脕脡脥脫脷帽脩_-]+/g,'_').slice(0,80) + '.png' }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root",
"cachedResultName": "/ (Root folder)"
},
"options": {
"simplifyOutput": true
}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
-3616,
8080
],
"id": "f38634c2-9aff-4f37-9b49-f0b951ca5459",
"name": "Subir imagen a Drive",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"operation": "share",
"fileId": {
"__rl": true,
"value": "={{ $node[\"Subir imagen a Drive\"].json.id }}",
"mode": "id"
},
"permissionsUi": {
"permissionsValues": {
"role": "writer",
"type": "domain",
"domain": "gomezleemarketing.com"
}
},
"options": {}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
-3392,
8080
],
"id": "27946335-650b-4954-869b-2c20b1d6d717",
"name": "Compartir imagen con GomezLee Marketing",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"jsCode": "const req=$node[\"Contexto Artefacto\"].json;\nconst upload=$node[\"Subir imagen a Drive\"].json||{};\nconst id=String(upload.id||'');\nif(!id) return [{json:{ok:false,error:'Google Drive no devolvi贸 el ID de la imagen.',artifactType:null,artifactUrl:null}}];\nreturn [{json:{\n ok:true,\n artifactType:'image',\n artifactUrl:`https://drive.google.com/file/d/${id}/view`,\n artifactId:id,\n title:req.artifact?.title||'Visual WMC',\n quote:req.quote,\n user:{id:req.userId,email:req.verifiedEmail,name:req.fullName},\n conversationId:req.conversationId,\n appSessionId:req.appSessionId,\n provider:'Google Gemini + Google Drive'\n}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-3168,
8080
],
"id": "3227132d-a14c-4d73-bfc8-8dfc7986eee2",
"name": "Normalizar imagen generada"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "9f0781ba-0f4e-4d98-a205-e3b17998306b",
"leftValue": "={{ $json.action }}",
"rightValue": "generate_proposal",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-3840,
8432
],
"id": "9eb3b0dd-fbdd-4918-bd5e-19372a67f815",
"name": "Es propuesta?"
},
{
"parameters": {
"jsCode": "const req=$node[\"Contexto Artefacto\"].json;\nconst slides=Array.isArray(req.artifact?.slides)?req.artifact.slides:[];\nconst out=[];\nslides.forEach((slide,index)=>{\n const prompt=String(slide?.imagePrompt||'').trim();\n const dark=['cover','section','thankyou'].includes(String(slide?.type||'').toLowerCase());\n if(prompt && !dark && !slide?.imageUrl && !slide?.imageDriveId){\n out.push({json:{...req,hasVisual:true,slideIndex:index,imagePrompt:prompt,slideTitle:String(slide?.title||`Slide ${index+1}`)}});\n }\n});\nif(!out.length) out.push({json:{...req,hasVisual:false}});\nreturn out;"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-3616,
8432
],
"id": "d42489cd-4103-4a16-8479-5d8405e5b1f1",
"name": "Preparar visuales propuesta"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "b287fc35-9b12-45a2-bd69-f39a3d455454",
"leftValue": "={{ $json.hasVisual }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-3392,
8432
],
"id": "6da63b03-7229-496d-93b1-31936e32b7ae",
"name": "Tiene visuales?"
},
{
"parameters": {
"resource": "image",
"modelId": {
"__rl": true,
"value": "models/gemini-3-pro-image",
"mode": "list",
"cachedResultName": "models/gemini-3-pro-image (Nano Banana Pro)"
},
"prompt": "={{ $json.imagePrompt }}",
"options": {
"binaryPropertyOutput": "data"
}
},
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"typeVersion": 1.2,
"position": [
-3168,
8368
],
"id": "22f5b63b-96bd-4cac-ace4-296e9fa91dc1",
"name": "Gemini - Visuales propuesta",
"retryOnFail": true,
"maxTries": 2,
"waitBetweenTries": 1500,
"credentials": {
"googlePalmApi": {
"id": "jvsXYwL6IOoY2DBU",
"name": "Isaac - Gemini Api Pago"
}
}
},
{
"parameters": {
"name": "={{ 'WMC_Propuesta_' + ($itemIndex + 1) + '.png' }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root",
"cachedResultName": "/ (Root folder)"
},
"options": {
"simplifyOutput": true
}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
-2960,
8368
],
"id": "fbbe74fb-4b38-499c-9954-19afb75aaf74",
"name": "Subir visuales propuesta",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"jsCode": "const req=$node[\"Contexto Artefacto\"].json;\nconst artifact=JSON.parse(JSON.stringify(req.artifact||{}));\nconst slides=Array.isArray(artifact.slides)?artifact.slides:[];\nconst specs=$items(\"Preparar visuales propuesta\").filter(i=>i.json?.hasVisual===true);\nconst uploads=$items(\"Subir visuales propuesta\");\n\nfor(let i=0;i<Math.min(specs.length,uploads.length);i++){\n const idx=Number(specs[i].json.slideIndex);\n const id=String(uploads[i].json?.id||'');\n if(Number.isInteger(idx) && slides[idx] && id){\n slides[idx].imageDriveId=id;\n }\n}\nartifact.slides=slides;\nreturn [{json:{...req,artifact}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-2512,
8272
],
"id": "efa17d2b-c1f8-40e0-9ded-3ab8cf64d6e7",
"name": "Recomponer propuesta"
},
{
"parameters": {
"jsCode": "const base=$node[\"Contexto Artefacto\"].json;\nconst x=($json && $json.action)?$json:base;\nconst cfg=$node[\"Configuraci贸n - sin ENV\"].json.config||{};\nif(!cfg.googleAutomationUrl || cfg.googleAutomationUrl.includes('PEGAR_AQUI')){\n throw new Error('Falta configurar googleAutomationUrl en el nodo \"Configuraci贸n - sin ENV\".');\n}\nconst title=x.artifact?.title||x.quote?.project||'Walmart Connect';\nreturn [{json:{...x,googleAutomationUrl:cfg.googleAutomationUrl,googlePayload:{\n secret:cfg.googleAutomationSecret,\n action:x.action,\n title,\n quote:x.quote,\n artifact:x.artifact,\n user:{id:base.userId,email:base.verifiedEmail,name:base.fullName},\n conversationId:base.conversationId\n}}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-2064,
8480
],
"id": "798d0f3f-6a17-4687-a468-1f11dce36f67",
"name": "Preparar Google"
},
{
"parameters": {
"method": "POST",
"url": "={{ $json.googleAutomationUrl }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify($json.googlePayload) }}",
"options": {
"timeout": 180000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-1840,
8480
],
"id": "3ff785f2-728a-4706-b308-909f1a282e26",
"name": "Google Automation",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const x=$node[\"Preparar Google\"].json;\nconst base=$node[\"Contexto Artefacto\"].json;\nconst g=$json??{};\nif(g.ok===false||!g.artifactUrl) return [{json:{ok:false,error:g.error||g.message||'Google Automation no devolvi贸 un archivo.',artifactType:null,artifactUrl:null}}];\nreturn [{json:{\n ok:true,\n artifactType:g.artifactType||({generate_quote:'quote',generate_proposal:'proposal',generate_monthly_glm:'monthly_glm'}[x.action]||'other'),\n artifactUrl:g.artifactUrl,\n artifactId:g.artifactId||null,\n title:g.title||x.googlePayload.title,\n quote:x.quote,\n sourceQuoteId:x.artifact?.sourceQuoteId||x.quote?.sourceQuoteId||null,\n user:{id:base.userId,email:base.verifiedEmail,name:base.fullName},\n conversationId:base.conversationId,\n appSessionId:base.appSessionId,\n provider:g.provider||'Google Workspace'\n}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-1616,
8480
],
"id": "cd9d431f-cc96-4159-b2e4-a9443ff4ff06",
"name": "Normalizar resultado"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "d4033a43-9f19-4bd9-90b0-732581cd9c71",
"leftValue": "={{ $json.artifactType }}",
"rightValue": "quote",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-480,
8480
],
"id": "7f3f1427-6634-4826-b578-ae4985862481",
"name": "Resultado es cotizaci贸n?"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_save_my_generated_quote",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "={{ $node[\"Contexto Artefacto\"].json.auth }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify({p_quote:$json.quote,p_display_name:$json.user.name,p_document_url:$json.artifactUrl,p_session_id:$json.appSessionId,p_conversation_id:$json.conversationId}) }}",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-256,
8352
],
"id": "e8f03525-ae44-4982-8db4-c05b8144e6de",
"name": "Guardar cotizaci贸n Supabase",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const a=$node[\"Normalizar resultado\"].json||{};\nconst id=typeof $json==='string'?$json:($json?.id||$json||null);\nreturn [{json:{...a,quoteId:id}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-32,
8352
],
"id": "87dad15a-9daf-40b7-b195-481bb0ba5e1d",
"name": "Preparar respuesta cotizaci贸n"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_save_my_artifact",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "={{ $node[\"Contexto Artefacto\"].json.auth }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify({p_artifact_type:$json.artifactType,p_title:$json.title,p_url:$json.artifactUrl,p_provider:$json.provider,p_quote_id:($json.artifactType==='monthly_glm'&&$json.sourceQuoteId)?$json.sourceQuoteId:null,p_conversation_id:$json.conversationId,p_display_name:$json.user.name,p_session_id:$json.appSessionId,p_metadata:{action:$node[\"Contexto Artefacto\"].json.action,sourceQuoteId:$json.sourceQuoteId||null}}) }}",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-256,
8608
],
"id": "52296a6e-2bf4-4b78-b31d-7505c443f57d",
"name": "Guardar otro artefacto Supabase",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const action=String($node[\"Contexto Artefacto\"].json.action||'');\nconst a=action==='generate_image'\n ? ($node[\"Normalizar imagen generada\"].json||{})\n : ($node[\"Normalizar resultado\"].json||{});\nconst dbId=typeof $json==='string'?$json:($json?.id||$json||null);\nreturn [{json:{...a,artifactDbId:dbId}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-32,
8608
],
"id": "5f4b24ac-d4af-475b-859b-26fef9c3f4cd",
"name": "Preparar respuesta artefacto"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ {ok:$json.ok!==false,artifactUrl:$json.artifactUrl||null,artifactType:$json.artifactType||null,artifactId:$json.artifactId||null,quoteId:$json.quoteId||null,title:$json.title||null,error:$json.error||null} }}",
"options": {
"responseCode": 200
}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.4,
"position": [
368,
8544
],
"id": "70381624-8e34-41cf-8094-fd57d9ede34f",
"name": "Responder artefacto"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "9240c33f-9716-41ea-870c-eaeceb988d89",
"leftValue": "={{ $json.action }}",
"rightValue": "generate_quote",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-3616,
8592
],
"id": "6d4f960b-78ec-4cf7-b0bd-3beb79d3ed65",
"name": "Acci贸n es cotizaci贸n?"
},
{
"parameters": {
"jsCode": "const req=$node[\"Contexto Artefacto\"].json;\nconst refs=Array.isArray(req.quote?.visualReferences)?req.quote.visualReferences:[];\nconst out=[];\nrefs.forEach((ref,index)=>{\n const obj=(ref && typeof ref==='object')?ref:{};\n const prompt=String(obj.imagePrompt||obj.prompt||'').trim();\n const already=String(obj.imageDriveId||obj.driveId||obj.fileId||obj.imageUrl||obj.url||'').trim();\n if(prompt && !already){\n out.push({json:{...req,hasVisual:true,visualIndex:index,imagePrompt:prompt,visualTitle:String(obj.title||`Referencia visual ${index+1}`)}});\n }\n});\nif(!out.length) out.push({json:{...req,hasVisual:false}});\nreturn out;"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-3392,
8560
],
"id": "f107280d-36b5-4d46-b69d-592d79a6a1fb",
"name": "Preparar visuales cotizaci贸n"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "d5a0d13b-e1b9-465b-b321-b4c303ede9e1",
"leftValue": "={{ $json.hasVisual }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-3168,
8560
],
"id": "1fe96ff3-f7aa-4058-8fd9-1b983d288c10",
"name": "Tiene visuales cotizaci贸n?"
},
{
"parameters": {
"resource": "image",
"modelId": {
"__rl": true,
"value": "models/gemini-3-pro-image",
"mode": "list",
"cachedResultName": "models/gemini-3-pro-image (Nano Banana Pro)"
},
"prompt": "={{ $json.imagePrompt }}",
"options": {
"binaryPropertyOutput": "data"
}
},
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"typeVersion": 1.2,
"position": [
-2960,
8528
],
"id": "2f44ef05-7115-4ee2-8202-82adc2f0c979",
"name": "Gemini - Visuales cotizaci贸n",
"retryOnFail": true,
"maxTries": 2,
"waitBetweenTries": 1500,
"credentials": {
"googlePalmApi": {
"id": "jvsXYwL6IOoY2DBU",
"name": "Isaac - Gemini Api Pago"
}
}
},
{
"parameters": {
"name": "={{ 'WMC_Cotizacion_Visual_' + ($itemIndex + 1) + '.png' }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root",
"cachedResultName": "/ (Root folder)"
},
"options": {
"simplifyOutput": true
}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
-2736,
8528
],
"id": "e13fdd03-2239-4a23-9d6a-3d8163e58015",
"name": "Subir visuales cotizaci贸n",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"jsCode": "const req=$node[\"Contexto Artefacto\"].json;\nconst quote=JSON.parse(JSON.stringify(req.quote||{}));\nconst refs=Array.isArray(quote.visualReferences)?quote.visualReferences:[];\nconst specs=$items(\"Preparar visuales cotizaci贸n\").filter(i=>i.json?.hasVisual===true);\nconst uploads=$items(\"Subir visuales cotizaci贸n\");\nfor(let i=0;i<Math.min(specs.length,uploads.length);i++){\n const idx=Number(specs[i].json.visualIndex);\n const id=String(uploads[i].json?.id||'');\n if(Number.isInteger(idx) && refs[idx] && id){\n const prior=(refs[idx] && typeof refs[idx]==='object')?refs[idx]:{title:String(refs[idx]||'')};\n refs[idx]={...prior,imageDriveId:id,url:`https://drive.google.com/file/d/${id}/view`};\n }\n}\nquote.visualReferences=refs;\nreturn [{json:{...req,quote}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-2288,
8752
],
"id": "caf0791a-6bb3-4f6c-a79b-d2e64d21a4a8",
"name": "Recomponer cotizaci贸n"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "a5e86e6e-bfae-46e0-a3f1-a9273a444857",
"leftValue": "={{ $json.action }}",
"rightValue": "generate_monthly_glm",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-3392,
8688
],
"id": "ae70407c-465e-4a3b-a0d1-06aa81547198",
"name": "Es mensualizaci贸n?"
},
{
"parameters": {
"url": "={{ 'https://dbit.digitalcompass.agency/rest/v1/cotizador_wmc_quotes?select=id,status,conversation_id,country_code,country_name,brand_solution,project,advertiser,format,exchange_rate,local_currency_code,total_usd,total_local,document_url,metadata,created_at,cotizador_wmc_quote_items(id,sort_order,section,description,units,days,unit_cost_usd,total_usd,unit_cost_local,total_local,is_estimated,confidence,estimation_reason,metadata)&source=eq.app&conversation_id=eq.' + encodeURIComponent($node[\"Contexto Artefacto\"].json.conversationId) + '&order=created_at.desc&limit=1' }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "={{ $node[\"Contexto Artefacto\"].json.auth }}"
}
]
},
"options": {
"timeout": 20000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-3168,
8688
],
"id": "b52e340f-7881-4c00-9d60-e0e15e8f8941",
"name": "Supabase - 煤ltima cotizaci贸n WMC",
"alwaysOutputData": true,
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const req = $node[\"Contexto Artefacto\"].json;\nconst raw = $json ?? {};\n\nfunction firstRow_(value) {\n if (Array.isArray(value)) return value[0] ?? null;\n if (Array.isArray(value?.data)) return value.data[0] ?? null;\n if (Array.isArray(value?.body)) return value.body[0] ?? null;\n if (value?.body && typeof value.body === 'object' && !Array.isArray(value.body)) return value.body;\n if (value && typeof value === 'object' && ('id' in value || 'country_code' in value || 'project' in value)) return value;\n return null;\n}\nfunction n_(v, fallback = 0) {\n const n = Number(v);\n return Number.isFinite(n) ? n : fallback;\n}\nfunction money_(v) {\n return Math.round((n_(v, 0) + Number.EPSILON) * 100) / 100;\n}\nfunction currencyFor_(code) {\n return ({GT:'GTQ',CR:'CRC',SV:'USD',HN:'HNL',NI:'NIO'})[String(code||'').toUpperCase()] || '';\n}\nfunction countryFor_(code) {\n return ({GT:'Guatemala',CR:'Costa Rica',SV:'El Salvador',HN:'Honduras',NI:'Nicaragua'})[String(code||'').toUpperCase()] || '';\n}\n\nconst row = firstRow_(raw);\nlet q = req.quote && typeof req.quote === 'object' ? JSON.parse(JSON.stringify(req.quote)) : {};\nlet sourceQuoteId = String(req.artifact?.sourceQuoteId || '').trim();\n\nif (row) {\n const relItems =\n (Array.isArray(row.cotizador_wmc_quote_items) && row.cotizador_wmc_quote_items) ||\n (Array.isArray(row.quote_items) && row.quote_items) ||\n (Array.isArray(row.items) && row.items) ||\n [];\n\n const items = relItems\n .slice()\n .sort((a,b) => n_(a?.sort_order,0) - n_(b?.sort_order,0))\n .map((it) => ({\n section: it?.section || 'Otros',\n description: it?.description || 'Item',\n units: n_(it?.units, 0),\n days: n_(it?.days, 1),\n unitCostUsd: money_(it?.unit_cost_usd),\n totalUsd: money_(it?.total_usd),\n unitCostLocal: money_(it?.unit_cost_local),\n totalLocal: money_(it?.total_local),\n isEstimated: it?.is_estimated === true,\n confidence: it?.confidence === null || it?.confidence === undefined ? null : n_(it.confidence, 0),\n estimationReason: it?.estimation_reason || null,\n metadata: it?.metadata && typeof it.metadata === 'object' ? it.metadata : {}\n }));\n\n const subtotalUsd = money_(items.reduce((s,it)=>s+n_(it.totalUsd,0),0));\n const subtotalLocal = money_(items.reduce((s,it)=>s+n_(it.totalLocal,0),0));\n const totalUsd = money_(row.total_usd);\n const totalLocal = money_(row.total_local);\n const feeUsd = money_(Math.max(0, totalUsd - subtotalUsd));\n const feeLocal = money_(Math.max(0, totalLocal - subtotalLocal));\n const feeRate = subtotalUsd > 0 ? feeUsd / subtotalUsd : 0;\n\n q = {\n ...q,\n countryCode: String(row.country_code || q.countryCode || '').toUpperCase(),\n country: row.country_name || q.country || countryFor_(row.country_code),\n brandSolution: row.brand_solution || q.brandSolution || 'Walmart Connect',\n project: row.project || q.project || '',\n advertiser: row.advertiser || q.advertiser || '',\n format: row.format || q.format || '',\n exchangeRate: n_(row.exchange_rate, n_(q.exchangeRate,1)),\n currencyCode: row.local_currency_code || q.currencyCode || currencyFor_(row.country_code),\n status: row.status || q.status || 'generated',\n items: items.length ? items : (Array.isArray(q.items) ? q.items : []),\n subtotalUsd,\n subtotalLocal,\n agencyFeeRate: feeRate,\n agencyFeeUsd: feeUsd,\n agencyFeeLocal: feeLocal,\n totalUsd,\n totalLocal,\n documentUrl: row.document_url || q.documentUrl || null\n };\n sourceQuoteId = String(row.id || sourceQuoteId || '');\n}\n\nif (!q.countryCode || !q.country || !q.currencyCode || !Array.isArray(q.items) || !q.items.length) {\n throw new Error('No se encontr贸 una cotizaci贸n WMC previa completa en esta conversaci贸n para mensualizar.');\n}\n\nconst baseSubtotalLocal = money_(q.items.reduce((s,it)=>s+n_(it.totalLocal,0),0));\nconst approvedTotalLocal = money_(q.totalLocal);\nconst approvedTotalUsd = money_(q.totalUsd);\nlet feeLocal = n_(q.agencyFeeLocal, NaN);\nlet feeUsd = n_(q.agencyFeeUsd, NaN);\nlet feeRate = n_(q.agencyFeeRate, NaN);\n\nif (!Number.isFinite(feeLocal)) feeLocal = money_(Math.max(0, approvedTotalLocal - baseSubtotalLocal));\nif (!Number.isFinite(feeUsd)) {\n const subtotalUsd = money_(q.items.reduce((s,it)=>s+n_(it.totalUsd,0),0));\n feeUsd = money_(Math.max(0, approvedTotalUsd - subtotalUsd));\n}\nif (!Number.isFinite(feeRate)) {\n const subtotalUsd = money_(q.items.reduce((s,it)=>s+n_(it.totalUsd,0),0));\n feeRate = subtotalUsd > 0 ? feeUsd / subtotalUsd : 0;\n}\n\nq.agencyFeeLocal = money_(feeLocal);\nq.agencyFeeUsd = money_(feeUsd);\nq.agencyFeeRate = feeRate;\n\nconst monthlyLines = q.items.map(it => ({...it}));\nif (q.agencyFeeLocal > 0.005) {\n monthlyLines.push({\n section: 'Fee de agencia',\n description: `Fee de agencia (${(q.agencyFeeRate * 100).toFixed(2).replace(/\\.00$/,'')}%)`,\n units: 1,\n days: 1,\n unitCostUsd: q.agencyFeeUsd,\n totalUsd: q.agencyFeeUsd,\n unitCostLocal: q.agencyFeeLocal,\n totalLocal: q.agencyFeeLocal,\n isEstimated: false,\n confidence: 1,\n estimationReason: null,\n metadata: {systemGeneratedFromApprovedWmcTotal:true}\n });\n}\n\nconst artifact = JSON.parse(JSON.stringify(req.artifact || {}));\nartifact.sourceQuoteId = sourceQuoteId || artifact.sourceQuoteId || null;\nartifact.monthlyLines = monthlyLines;\nartifact.metadata = {\n ...(artifact.metadata && typeof artifact.metadata === 'object' ? artifact.metadata : {}),\n sourceQuoteId: artifact.sourceQuoteId,\n sourceDocumentUrl: q.documentUrl || null,\n countryCode: q.countryCode,\n country: q.country,\n currencyCode: q.currencyCode,\n exchangeRate: q.exchangeRate,\n approvedWmcTotalUsd: approvedTotalUsd,\n approvedWmcTotalLocal: approvedTotalLocal,\n agencyFeeRate: q.agencyFeeRate,\n agencyFeeUsd: q.agencyFeeUsd,\n agencyFeeLocal: q.agencyFeeLocal,\n walmartApproved: true,\n glmIvaRate: 0.12\n};\n\nreturn [{json:{...req,quote:q,artifact}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-2944,
8688
],
"id": "fd12a715-5138-46ec-8e50-a4c5e70a0f81",
"name": "Hidratar mensualizaci贸n aprobada"
},
{
"parameters": {
"operation": "share",
"fileId": {
"__rl": true,
"value": "={{ $json.id }}",
"mode": "id"
},
"permissionsUi": {
"permissionsValues": {
"role": "writer",
"type": "domain",
"domain": "gomezleemarketing.com"
}
},
"options": {}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
-2736,
8272
],
"id": "762165ec-1698-423a-a2f1-bc693d337532",
"name": "Compartir visuales propuesta con GomezLee Marketing",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"operation": "share",
"fileId": {
"__rl": true,
"value": "={{ $json.id }}",
"mode": "id"
},
"permissionsUi": {
"permissionsValues": {
"role": "writer",
"type": "domain",
"domain": "gomezleemarketing.com"
}
},
"options": {}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
-2512,
8752
],
"id": "f8aff62a-85af-4d36-8981-fed579a7be1e",
"name": "Compartir visuales cotizaci贸n con GomezLee Marketing",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"jsCode": "const a = $json ?? {};\n\nif (a.ok === false) {\n return [{json:{...a,shareFileId:null,shareRequired:false}}];\n}\n\nlet id = String(a.artifactId || '').trim();\nconst url = String(a.artifactUrl || '').trim();\n\nif (!id && url) {\n const patterns = [\n /\\/d\\/([A-Za-z0-9_-]{20,})/,\n /[?&]id=([A-Za-z0-9_-]{20,})/,\n /\\/folders\\/([A-Za-z0-9_-]{20,})/\n ];\n for (const pattern of patterns) {\n const match = url.match(pattern);\n if (match?.[1]) {\n id = match[1];\n break;\n }\n }\n}\n\nif (!id) {\n throw new Error('No se pudo identificar el archivo de Google Workspace para aplicar el acceso de GomezLee Marketing.');\n}\n\nreturn [{json:{...a,shareFileId:id,shareRequired:true}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-1392,
8480
],
"id": "6f44d625-0528-4a0e-9285-880a136e37e9",
"name": "Preparar permiso GomezLee Marketing"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "c8060fe4-e989-4cea-8b44-3e1f0e0c153c",
"leftValue": "={{ $json.shareRequired }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-1168,
8480
],
"id": "d5bf4b40-b2b7-40ac-abdc-19022b65d8a0",
"name": "驴Archivo Google para compartir?"
},
{
"parameters": {
"operation": "share",
"fileId": {
"__rl": true,
"value": "={{ $json.shareFileId }}",
"mode": "id"
},
"permissionsUi": {
"permissionsValues": {
"role": "writer",
"type": "domain",
"domain": "gomezleemarketing.com"
}
},
"options": {}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
-944,
8368
],
"id": "0755c9e3-db77-4263-a135-10c9e6edc017",
"name": "Compartir archivo final con GomezLee Marketing",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"jsCode": "const original = $node[\"Normalizar resultado\"].json ?? {};\nreturn [{json:original}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-704,
8368
],
"id": "ded9cefe-006e-44bc-9ffb-1df081b8a59a",
"name": "Restaurar resultado tras compartir"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "889b613b-a5d6-4362-bac9-969a9776b06f",
"leftValue": "={{ $json.internalEmail }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-5600,
7952
],
"id": "08fb954f-6326-4cbf-814f-8961d3252511",
"name": "驴Solicitud interna email?"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "5ee8550d-b245-47c1-9c58-722bf3e0c7d1",
"leftValue": "={{ $json.internalAuthorized }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-5376,
7952
],
"id": "5fbba220-1d24-4348-8c43-745664a9b848",
"name": "Interno autorizado?"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ {ok:false,error:'Solicitud interna no autorizada.'} }}",
"options": {
"responseCode": 401
}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.4,
"position": [
-5152,
8128
],
"id": "4fb3d352-64b1-4c11-aa23-1e802e8c00c4",
"name": "Responder 401 Interno"
},
{
"parameters": {
"jsCode": "const req=$node[\"Normalizar solicitud\"].json;\nconst email=String(req.user?.email||'wmc@gomezlee.marketing').trim().toLowerCase();\nreturn [{json:{...req,userId:null,verifiedEmail:email,fullName:req.user?.name||'Walmart Connect Email Agent',accessAllowed:true,canUseTarifario:false,internalEmail:true}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-5152,
7872
],
"id": "be28584f-082d-4774-818f-6670465432e8",
"name": "Autorizar email interno"
},
{
"parameters": {
"jsCode": "const x=$json??{};\nreturn [{json:{...x,internalEmail:Boolean(x.internalEmail)}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-4064,
8128
],
"id": "f832489e-9cf7-43ad-b246-0b89204dda0a",
"name": "Contexto Artefacto"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "03140a28-4f09-4a9c-b82b-4c6eeced8c17",
"leftValue": "={{ $node[\"Contexto Artefacto\"].json.internalEmail }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
80,
7968
],
"id": "3c1eaefc-44eb-4e31-8e9c-bacae9e6c86e",
"name": "驴Imagen interna email?"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "12b1ba07-d2ac-47df-9c66-5e18bdb41d79",
"leftValue": "={{ $node[\"Contexto Artefacto\"].json.internalEmail }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
112,
8400
],
"id": "e2370114-e36a-49f0-97a6-313a1af66866",
"name": "驴Resultado interno email?"
},
{
"parameters": {
"jsCode": "const a=$json??{};\nreturn [{json:{ok:a.ok!==false,artifactUrl:a.artifactUrl||null,artifactType:a.artifactType||null,artifactId:a.artifactId||null,quoteId:null,title:a.title||null,error:a.error||null}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
320,
8160
],
"id": "c6fe38d4-fa37-49a8-aa84-c7065a763b3b",
"name": "Preparar respuesta interna Artefactos"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ $json }}",
"options": {
"responseCode": 200
}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.4,
"position": [
560,
8160
],
"id": "eba6e35b-623e-4e6d-bdb2-00b943a5873a",
"name": "Responder artefacto interno"
}
],
"connections": {
"Webhook - Artefactos": {
"main": [
[
{
"node": "Configuraci贸n - sin ENV",
"type": "main",
"index": 0
}
]
]
},
"Configuraci贸n - sin ENV": {
"main": [
[
{
"node": "Normalizar solicitud",
"type": "main",
"index": 0
}
]
]
},
"Normalizar solicitud": {
"main": [
[
{
"node": "驴Solicitud interna email?",
"type": "main",
"index": 0
}
]
]
},
"Supabase - validar JWT": {
"main": [
[
{
"node": "Validar identidad",
"type": "main",
"index": 0
}
]
]
},
"Validar identidad": {
"main": [
[
{
"node": "JWT v谩lido?",
"type": "main",
"index": 0
}
]
]
},
"JWT v谩lido?": {
"main": [
[
{
"node": "Supabase - acceso",
"type": "main",
"index": 0
}
],
[
{
"node": "Responder 401",
"type": "main",
"index": 0
}
]
]
},
"Supabase - acceso": {
"main": [
[
{
"node": "Validar acceso",
"type": "main",
"index": 0
}
]
]
},
"Validar acceso": {
"main": [
[
{
"node": "Acceso permitido?",
"type": "main",
"index": 0
}
]
]
},
"Acceso permitido?": {
"main": [
[
{
"node": "Contexto Artefacto",
"type": "main",
"index": 0
}
],
[
{
"node": "Responder 403",
"type": "main",
"index": 0
}
]
]
},
"Debe generar?": {
"main": [
[
{
"node": "Es imagen?",
"type": "main",
"index": 0
}
],
[
{
"node": "Responder sin artefacto",
"type": "main",
"index": 0
}
]
]
},
"Es imagen?": {
"main": [
[
{
"node": "Gemini - Generar imagen",
"type": "main",
"index": 0
}
],
[
{
"node": "Es propuesta?",
"type": "main",
"index": 0
}
]
]
},
"Gemini - Generar imagen": {
"main": [
[
{
"node": "Subir imagen a Drive",
"type": "main",
"index": 0
}
]
]
},
"Subir imagen a Drive": {
"main": [
[
{
"node": "Compartir imagen con GomezLee Marketing",
"type": "main",
"index": 0
}
]
]
},
"Normalizar imagen generada": {
"main": [
[
{
"node": "驴Imagen interna email?",
"type": "main",
"index": 0
}
]
]
},
"Es propuesta?": {
"main": [
[
{
"node": "Preparar visuales propuesta",
"type": "main",
"index": 0
}
],
[
{
"node": "Acci贸n es cotizaci贸n?",
"type": "main",
"index": 0
}
]
]
},
"Preparar visuales propuesta": {
"main": [
[
{
"node": "Tiene visuales?",
"type": "main",
"index": 0
}
]
]
},
"Tiene visuales?": {
"main": [
[
{
"node": "Gemini - Visuales propuesta",
"type": "main",
"index": 0
}
],
[
{
"node": "Preparar Google",
"type": "main",
"index": 0
}
]
]
},
"Gemini - Visuales propuesta": {
"main": [
[
{
"node": "Subir visuales propuesta",
"type": "main",
"index": 0
}
]
]
},
"Subir visuales propuesta": {
"main": [
[
{
"node": "Compartir visuales propuesta con GomezLee Marketing",
"type": "main",
"index": 0
}
]
]
},
"Recomponer propuesta": {
"main": [
[
{
"node": "Preparar Google",
"type": "main",
"index": 0
}
]
]
},
"Preparar Google": {
"main": [
[
{
"node": "Google Automation",
"type": "main",
"index": 0
}
]
]
},
"Google Automation": {
"main": [
[
{
"node": "Normalizar resultado",
"type": "main",
"index": 0
}
]
]
},
"Normalizar resultado": {
"main": [
[
{
"node": "驴Resultado interno email?",
"type": "main",
"index": 0
}
]
]
},
"Guardar cotizaci贸n Supabase": {
"main": [
[
{
"node": "Preparar respuesta cotizaci贸n",
"type": "main",
"index": 0
}
]
]
},
"Preparar respuesta cotizaci贸n": {
"main": [
[
{
"node": "Responder artefacto",
"type": "main",
"index": 0
}
]
]
},
"Guardar otro artefacto Supabase": {
"main": [
[
{
"node": "Preparar respuesta artefacto",
"type": "main",
"index": 0
}
]
]
},
"Preparar respuesta artefacto": {
"main": [
[
{
"node": "Responder artefacto",
"type": "main",
"index": 0
}
]
]
},
"Resultado es cotizaci贸n?": {
"main": [
[
{
"node": "Guardar cotizaci贸n Supabase",
"type": "main",
"index": 0
}
],
[
{
"node": "Guardar otro artefacto Supabase",
"type": "main",
"index": 0
}
]
]
},
"Acci贸n es cotizaci贸n?": {
"main": [
[
{
"node": "Preparar visuales cotizaci贸n",
"type": "main",
"index": 0
}
],
[
{
"node": "Es mensualizaci贸n?",
"type": "main",
"index": 0
}
]
]
},
"Preparar visuales cotizaci贸n": {
"main": [
[
{
"node": "Tiene visuales cotizaci贸n?",
"type": "main",
"index": 0
}
]
]
},
"Tiene visuales cotizaci贸n?": {
"main": [
[
{
"node": "Gemini - Visuales cotizaci贸n",
"type": "main",
"index": 0
}
],
[
{
"node": "Preparar Google",
"type": "main",
"index": 0
}
]
]
},
"Gemini - Visuales cotizaci贸n": {
"main": [
[
{
"node": "Subir visuales cotizaci贸n",
"type": "main",
"index": 0
}
]
]
},
"Subir visuales cotizaci贸n": {
"main": [
[
{
"node": "Compartir visuales cotizaci贸n con GomezLee Marketing",
"type": "main",
"index": 0
}
]
]
},
"Recomponer cotizaci贸n": {
"main": [
[
{
"node": "Preparar Google",
"type": "main",
"index": 0
}
]
]
},
"Es mensualizaci贸n?": {
"main": [
[
{
"node": "Supabase - 煤ltima cotizaci贸n WMC",
"type": "main",
"index": 0
}
],
[
{
"node": "Preparar Google",
"type": "main",
"index": 0
}
]
]
},
"Supabase - 煤ltima cotizaci贸n WMC": {
"main": [
[
{
"node": "Hidratar mensualizaci贸n aprobada",
"type": "main",
"index": 0
}
]
]
},
"Hidratar mensualizaci贸n aprobada": {
"main": [
[
{
"node": "Preparar Google",
"type": "main",
"index": 0
}
]
]
},
"Compartir imagen con GomezLee Marketing": {
"main": [
[
{
"node": "Normalizar imagen generada",
"type": "main",
"index": 0
}
]
]
},
"Compartir visuales propuesta con GomezLee Marketing": {
"main": [
[
{
"node": "Recomponer propuesta",
"type": "main",
"index": 0
}
]
]
},
"Compartir visuales cotizaci贸n con GomezLee Marketing": {
"main": [
[
{
"node": "Recomponer cotizaci贸n",
"type": "main",
"index": 0
}
]
]
},
"Preparar permiso GomezLee Marketing": {
"main": [
[
{
"node": "驴Archivo Google para compartir?",
"type": "main",
"index": 0
}
]
]
},
"驴Archivo Google para compartir?": {
"main": [
[
{
"node": "Compartir archivo final con GomezLee Marketing",
"type": "main",
"index": 0
}
],
[
{
"node": "Resultado es cotizaci贸n?",
"type": "main",
"index": 0
}
]
]
},
"Compartir archivo final con GomezLee Marketing": {
"main": [
[
{
"node": "Restaurar resultado tras compartir",
"type": "main",
"index": 0
}
]
]
},
"Restaurar resultado tras compartir": {
"main": [
[
{
"node": "Resultado es cotizaci贸n?",
"type": "main",
"index": 0
}
]
]
},
"驴Solicitud interna email?": {
"main": [
[
{
"node": "Interno autorizado?",
"type": "main",
"index": 0
}
],
[
{
"node": "Supabase - validar JWT",
"type": "main",
"index": 0
}
]
]
},
"Interno autorizado?": {
"main": [
[
{
"node": "Autorizar email interno",
"type": "main",
"index": 0
}
],
[
{
"node": "Responder 401 Interno",
"type": "main",
"index": 0
}
]
]
},
"Autorizar email interno": {
"main": [
[
{
"node": "Contexto Artefacto",
"type": "main",
"index": 0
}
]
]
},
"Contexto Artefacto": {
"main": [
[
{
"node": "Debe generar?",
"type": "main",
"index": 0
}
]
]
},
"驴Imagen interna email?": {
"main": [
[
{
"node": "Preparar respuesta interna Artefactos",
"type": "main",
"index": 0
}
],
[
{
"node": "Guardar otro artefacto Supabase",
"type": "main",
"index": 0
}
]
]
},
"驴Resultado interno email?": {
"main": [
[
{
"node": "Preparar respuesta interna Artefactos",
"type": "main",
"index": 0
}
],
[
{
"node": "Preparar permiso GomezLee Marketing",
"type": "main",
"index": 0
}
]
]
},
"Preparar respuesta interna Artefactos": {
"main": [
[
{
"node": "Responder artefacto interno",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"binaryMode": "separate"
},
"staticData": null,
"meta": null,
"versionId": "59b8fc04-1a98-4aa6-b66f-fd437fe59265",
"activeVersionId": "59b8fc04-1a98-4aa6-b66f-fd437fe59265",
"versionCounter": 40,
"triggerCount": 1,
"shared": [
{
"updatedAt": "2026-08-22T14:54:47.152Z",
"createdAt": "2026-08-22T14:54:47.152Z",
"role": "workflow:owner",
"workflowId": "kHT6jUVIcYGjagV3",
"projectId": "PJpTANzTXIFibWsW",
"project": {
"updatedAt": "2026-04-22T14:25:09.686Z",
"createdAt": "2026-04-22T14:22:54.790Z",
"id": "PJpTANzTXIFibWsW",
"name": "Isaac Aracena <iaracena@gomezleemarketing.com>",
"type": "personal",
"icon": null,
"description": null,
"creatorId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
}
}
],
"tags": [],
"activeVersion": {
"updatedAt": "2026-08-29T16:24:37.000Z",
"createdAt": "2026-08-29T16:24:36.307Z",
"versionId": "59b8fc04-1a98-4aa6-b66f-fd437fe59265",
"workflowId": "kHT6jUVIcYGjagV3",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "cotizador-wmc-artifacts",
"responseMode": "responseNode",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
-6256,
8400
],
"id": "d2b8313c-4151-4279-b878-717c542c5921",
"name": "Webhook - Artefactos",
"webhookId": "796454bf-78e1-404c-9ff2-2fb65c10b41b"
},
{
"parameters": {
"jsCode": "// Configuraci贸n local del workflow. No utiliza variables de entorno.\nreturn [{json:{\n ...$json,\n config:{\n supabaseUrl:\"https://dbit.digitalcompass.agency\",\n supabaseAnonKey:\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE\",\n googleAutomationUrl:\"https://script.google.com/macros/s/AKfycbxCmB1VwGO9omH0jPWecOKBiRVQexhCLQa-uCDEXu1Q4vmYCjVPQig_lRFhXFZvFyct/exec\",\n googleAutomationSecret:\"mwI_n-1r4_-QTLp1-zIt-zQKh_HqaoGoVhyapyLN2T2-r7xf8iP5AC3v9wJt5Av6\",\n internalEmailSecret:\"fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08\"\n }\n}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-6048,
8400
],
"id": "48caedca-d987-4262-9a64-8fe7f269f28b",
"name": "Configuraci贸n - sin ENV"
},
{
"parameters": {
"jsCode": "const body=$json.body??{};\nconst headers=$json.headers??{};\nconst clean=(v,m=12000)=>typeof v==='string'?v.trim().slice(0,m):'';\nconst auth=clean(headers.authorization||headers.Authorization);\nconst internalSecret=clean(headers['x-wmc-internal-secret']||headers['X-WMC-Internal-Secret'],500);\nconst expectedInternalSecret='fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08';\nconst action=clean(body.action,80);\nconst allowed=['generate_quote','generate_proposal','generate_image','generate_monthly_glm'];\nconst internalEmail=body.internalEmail===true || internalSecret!=='';\nif(!internalEmail && !auth.startsWith('Bearer ')) throw new Error('Falta Authorization Bearer.');\nreturn [{json:{\n auth, internalEmail, internalAuthorized: internalEmail && internalSecret===expectedInternalSecret,\n action, shouldGenerate:allowed.includes(action), quote:body.quote??null, artifact:body.artifact??null,\n user:body.user??{}, conversationId:clean(body.conversationId,220),\n appSessionId:clean(body.appSessionId,250)||`artifact-${Date.now()}`, model:clean(body.model,120)\n}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-5824,
8400
],
"id": "69882ba8-924f-4f90-b5de-563bed38f4ae",
"name": "Normalizar solicitud"
},
{
"parameters": {
"url": "https://dbit.digitalcompass.agency/auth/v1/user",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "={{ $json.auth }}"
}
]
},
"options": {
"timeout": 20000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-5600,
8400
],
"id": "cc69a496-1954-47cd-abd7-8011d090f114",
"name": "Supabase - validar JWT",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const req=$node[\"Normalizar solicitud\"].json;\nconst u=$json??{};\nconst id=String(u.id||'').trim();\nconst email=String(u.email||'').trim().toLowerCase();\nconst claimed=String(req.user?.email||'').trim().toLowerCase();\nconst jwtValid=Boolean(id&&email.endsWith('@gomezleemarketing.com')&&(!claimed||claimed===email));\nreturn [{json:{...req,userId:id,verifiedEmail:email,jwtValid}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-5376,
8400
],
"id": "b8b1ec7a-90d3-4613-905c-073fb53acdc8",
"name": "Validar identidad"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "b044dcb5-a78a-40ce-a537-a7949ef226c8",
"leftValue": "={{ $json.jwtValid }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-5168,
8400
],
"id": "c3a2edf7-9d21-4c6a-9a63-665ca99b29d4",
"name": "JWT v谩lido?"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ {ok:false,error:'Sesi贸n Supabase inv谩lida.'} }}",
"options": {
"responseCode": 401
}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.4,
"position": [
-4944,
8688
],
"id": "f8c7aea9-0bdb-4828-badf-98f6caaf9c16",
"name": "Responder 401"
},
{
"parameters": {
"url": "={{ 'https://dbit.digitalcompass.agency/rest/v1/cotizador_wmc_access?select=email,full_name,is_active,can_use_tarifario&email=eq.' + encodeURIComponent($json.verifiedEmail) + '&is_active=eq.true' + '&limit=1' }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "={{ $json.auth }}"
}
]
},
"options": {
"timeout": 20000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-4944,
8320
],
"id": "2f107a29-ff3b-430a-9879-c6be179d3da3",
"name": "Supabase - acceso",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const req = $node[\"Validar identidad\"].json;\nconst raw = $json ?? {};\n\n// n8n 2.21.4 puede convertir una respuesta PostgREST con una sola fila\n// en un objeto individual en vez de conservar el array original.\n// Aceptamos todas las formas posibles de respuesta.\nlet row = null;\n\nif (Array.isArray(raw)) {\n row = raw[0] ?? null;\n} else if (Array.isArray(raw?.data)) {\n row = raw.data[0] ?? null;\n} else if (Array.isArray(raw?.body)) {\n row = raw.body[0] ?? null;\n} else if (raw?.body && typeof raw.body === 'object' && !Array.isArray(raw.body)) {\n row = raw.body;\n} else if (raw && typeof raw === 'object' && ('email' in raw || 'is_active' in raw || 'full_name' in raw)) {\n row = raw;\n}\n\nconst normalizeEmail = (value) => String(value ?? '').trim().toLowerCase();\nconst rowEmail = normalizeEmail(row?.email);\nconst active = row?.is_active === true || String(row?.is_active ?? '').toLowerCase() === 'true';\n\nconst accessAllowed = Boolean(\n row &&\n active &&\n rowEmail &&\n rowEmail === normalizeEmail(req.verifiedEmail)\n);\n\nreturn [{\n json: {\n ...req,\n accessAllowed,\n fullName: row?.full_name || req.user?.name || req.verifiedEmail,\n canUseTarifario: accessAllowed && (\n row?.can_use_tarifario === true ||\n String(row?.can_use_tarifario ?? '').toLowerCase() === 'true'\n ),\n accessLookupOk: Boolean(row)\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-4720,
8320
],
"id": "c9ef4878-6880-43af-8040-2040d43c521b",
"name": "Validar acceso"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "4539e2f3-4739-4d34-bbe0-4239868c30c4",
"leftValue": "={{ $json.accessAllowed }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-4496,
8320
],
"id": "5c315269-c38d-47e2-9d2b-fa02a4f3f1cc",
"name": "Acceso permitido?"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ {ok:false,error:'No tienes acceso activo al Cotizador Walmart Connect.'} }}",
"options": {
"responseCode": 403
}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.4,
"position": [
-4288,
8688
],
"id": "3a052ddc-3a65-4be0-8375-db968369562e",
"name": "Responder 403"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "25b6fd12-c4b4-4938-a319-0572e307e49b",
"leftValue": "={{ $json.shouldGenerate }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-4288,
8320
],
"id": "41bbecc4-458e-4bc2-8c68-7b32fa9ef020",
"name": "Debe generar?"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ {ok:true,skipped:true,message:'La respuesta no requiere crear un archivo.'} }}",
"options": {
"responseCode": 200
}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.4,
"position": [
-4064,
8688
],
"id": "799cfcaf-c04c-4b95-aec0-b2abc39613e1",
"name": "Responder sin artefacto"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "cd73b109-158e-4aa8-93ab-40b1c9c77de5",
"leftValue": "={{ $json.action }}",
"rightValue": "generate_image",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-4064,
8320
],
"id": "5a3ec8cb-c3d9-4e5c-8cea-7a389247adc0",
"name": "Es imagen?"
},
{
"parameters": {
"resource": "image",
"modelId": {
"__rl": true,
"value": "models/gemini-3-pro-image",
"mode": "list",
"cachedResultName": "models/gemini-3-pro-image (Nano Banana Pro)"
},
"prompt": "={{ $json.artifact?.imagePrompt || $json.artifact?.prompt || $json.artifact?.title || 'Visual profesional para Walmart Connect' }}",
"options": {
"binaryPropertyOutput": "data"
}
},
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"typeVersion": 1.2,
"position": [
-3840,
8080
],
"id": "bc3a2875-1e89-42e5-a2fb-a853901f9f5c",
"name": "Gemini - Generar imagen",
"retryOnFail": true,
"maxTries": 2,
"waitBetweenTries": 1500,
"credentials": {
"googlePalmApi": {
"id": "jvsXYwL6IOoY2DBU",
"name": "Isaac - Gemini Api Pago"
}
}
},
{
"parameters": {
"name": "={{ 'WMC_' + String($node[\"Contexto Artefacto\"].json.artifact?.title || 'visual').replace(/[^a-zA-Z0-9谩茅铆贸煤脕脡脥脫脷帽脩_-]+/g,'_').slice(0,80) + '.png' }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root",
"cachedResultName": "/ (Root folder)"
},
"options": {
"simplifyOutput": true
}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
-3616,
8080
],
"id": "f38634c2-9aff-4f37-9b49-f0b951ca5459",
"name": "Subir imagen a Drive",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"operation": "share",
"fileId": {
"__rl": true,
"value": "={{ $node[\"Subir imagen a Drive\"].json.id }}",
"mode": "id"
},
"permissionsUi": {
"permissionsValues": {
"role": "writer",
"type": "domain",
"domain": "gomezleemarketing.com"
}
},
"options": {}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
-3392,
8080
],
"id": "27946335-650b-4954-869b-2c20b1d6d717",
"name": "Compartir imagen con GomezLee Marketing",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"jsCode": "const req=$node[\"Contexto Artefacto\"].json;\nconst upload=$node[\"Subir imagen a Drive\"].json||{};\nconst id=String(upload.id||'');\nif(!id) return [{json:{ok:false,error:'Google Drive no devolvi贸 el ID de la imagen.',artifactType:null,artifactUrl:null}}];\nreturn [{json:{\n ok:true,\n artifactType:'image',\n artifactUrl:`https://drive.google.com/file/d/${id}/view`,\n artifactId:id,\n title:req.artifact?.title||'Visual WMC',\n quote:req.quote,\n user:{id:req.userId,email:req.verifiedEmail,name:req.fullName},\n conversationId:req.conversationId,\n appSessionId:req.appSessionId,\n provider:'Google Gemini + Google Drive'\n}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-3168,
8080
],
"id": "3227132d-a14c-4d73-bfc8-8dfc7986eee2",
"name": "Normalizar imagen generada"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "9f0781ba-0f4e-4d98-a205-e3b17998306b",
"leftValue": "={{ $json.action }}",
"rightValue": "generate_proposal",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-3840,
8432
],
"id": "9eb3b0dd-fbdd-4918-bd5e-19372a67f815",
"name": "Es propuesta?"
},
{
"parameters": {
"jsCode": "const req=$node[\"Contexto Artefacto\"].json;\nconst slides=Array.isArray(req.artifact?.slides)?req.artifact.slides:[];\nconst out=[];\nslides.forEach((slide,index)=>{\n const prompt=String(slide?.imagePrompt||'').trim();\n const dark=['cover','section','thankyou'].includes(String(slide?.type||'').toLowerCase());\n if(prompt && !dark && !slide?.imageUrl && !slide?.imageDriveId){\n out.push({json:{...req,hasVisual:true,slideIndex:index,imagePrompt:prompt,slideTitle:String(slide?.title||`Slide ${index+1}`)}});\n }\n});\nif(!out.length) out.push({json:{...req,hasVisual:false}});\nreturn out;"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-3616,
8432
],
"id": "d42489cd-4103-4a16-8479-5d8405e5b1f1",
"name": "Preparar visuales propuesta"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "b287fc35-9b12-45a2-bd69-f39a3d455454",
"leftValue": "={{ $json.hasVisual }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-3392,
8432
],
"id": "6da63b03-7229-496d-93b1-31936e32b7ae",
"name": "Tiene visuales?"
},
{
"parameters": {
"resource": "image",
"modelId": {
"__rl": true,
"value": "models/gemini-3-pro-image",
"mode": "list",
"cachedResultName": "models/gemini-3-pro-image (Nano Banana Pro)"
},
"prompt": "={{ $json.imagePrompt }}",
"options": {
"binaryPropertyOutput": "data"
}
},
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"typeVersion": 1.2,
"position": [
-3168,
8368
],
"id": "22f5b63b-96bd-4cac-ace4-296e9fa91dc1",
"name": "Gemini - Visuales propuesta",
"retryOnFail": true,
"maxTries": 2,
"waitBetweenTries": 1500,
"credentials": {
"googlePalmApi": {
"id": "jvsXYwL6IOoY2DBU",
"name": "Isaac - Gemini Api Pago"
}
}
},
{
"parameters": {
"name": "={{ 'WMC_Propuesta_' + ($itemIndex + 1) + '.png' }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root",
"cachedResultName": "/ (Root folder)"
},
"options": {
"simplifyOutput": true
}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
-2960,
8368
],
"id": "fbbe74fb-4b38-499c-9954-19afb75aaf74",
"name": "Subir visuales propuesta",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"jsCode": "const req=$node[\"Contexto Artefacto\"].json;\nconst artifact=JSON.parse(JSON.stringify(req.artifact||{}));\nconst slides=Array.isArray(artifact.slides)?artifact.slides:[];\nconst specs=$items(\"Preparar visuales propuesta\").filter(i=>i.json?.hasVisual===true);\nconst uploads=$items(\"Subir visuales propuesta\");\n\nfor(let i=0;i<Math.min(specs.length,uploads.length);i++){\n const idx=Number(specs[i].json.slideIndex);\n const id=String(uploads[i].json?.id||'');\n if(Number.isInteger(idx) && slides[idx] && id){\n slides[idx].imageDriveId=id;\n }\n}\nartifact.slides=slides;\nreturn [{json:{...req,artifact}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-2512,
8272
],
"id": "efa17d2b-c1f8-40e0-9ded-3ab8cf64d6e7",
"name": "Recomponer propuesta"
},
{
"parameters": {
"jsCode": "const base=$node[\"Contexto Artefacto\"].json;\nconst x=($json && $json.action)?$json:base;\nconst cfg=$node[\"Configuraci贸n - sin ENV\"].json.config||{};\nif(!cfg.googleAutomationUrl || cfg.googleAutomationUrl.includes('PEGAR_AQUI')){\n throw new Error('Falta configurar googleAutomationUrl en el nodo \"Configuraci贸n - sin ENV\".');\n}\nconst title=x.artifact?.title||x.quote?.project||'Walmart Connect';\nreturn [{json:{...x,googleAutomationUrl:cfg.googleAutomationUrl,googlePayload:{\n secret:cfg.googleAutomationSecret,\n action:x.action,\n title,\n quote:x.quote,\n artifact:x.artifact,\n user:{id:base.userId,email:base.verifiedEmail,name:base.fullName},\n conversationId:base.conversationId\n}}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-2064,
8480
],
"id": "798d0f3f-6a17-4687-a468-1f11dce36f67",
"name": "Preparar Google"
},
{
"parameters": {
"method": "POST",
"url": "={{ $json.googleAutomationUrl }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify($json.googlePayload) }}",
"options": {
"timeout": 180000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-1840,
8480
],
"id": "3ff785f2-728a-4706-b308-909f1a282e26",
"name": "Google Automation",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const x=$node[\"Preparar Google\"].json;\nconst base=$node[\"Contexto Artefacto\"].json;\nconst g=$json??{};\nif(g.ok===false||!g.artifactUrl) return [{json:{ok:false,error:g.error||g.message||'Google Automation no devolvi贸 un archivo.',artifactType:null,artifactUrl:null}}];\nreturn [{json:{\n ok:true,\n artifactType:g.artifactType||({generate_quote:'quote',generate_proposal:'proposal',generate_monthly_glm:'monthly_glm'}[x.action]||'other'),\n artifactUrl:g.artifactUrl,\n artifactId:g.artifactId||null,\n title:g.title||x.googlePayload.title,\n quote:x.quote,\n sourceQuoteId:x.artifact?.sourceQuoteId||x.quote?.sourceQuoteId||null,\n user:{id:base.userId,email:base.verifiedEmail,name:base.fullName},\n conversationId:base.conversationId,\n appSessionId:base.appSessionId,\n provider:g.provider||'Google Workspace'\n}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-1616,
8480
],
"id": "cd9d431f-cc96-4159-b2e4-a9443ff4ff06",
"name": "Normalizar resultado"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "d4033a43-9f19-4bd9-90b0-732581cd9c71",
"leftValue": "={{ $json.artifactType }}",
"rightValue": "quote",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-480,
8480
],
"id": "7f3f1427-6634-4826-b578-ae4985862481",
"name": "Resultado es cotizaci贸n?"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_save_my_generated_quote",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "={{ $node[\"Contexto Artefacto\"].json.auth }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify({p_quote:$json.quote,p_display_name:$json.user.name,p_document_url:$json.artifactUrl,p_session_id:$json.appSessionId,p_conversation_id:$json.conversationId}) }}",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-256,
8352
],
"id": "e8f03525-ae44-4982-8db4-c05b8144e6de",
"name": "Guardar cotizaci贸n Supabase",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const a=$node[\"Normalizar resultado\"].json||{};\nconst id=typeof $json==='string'?$json:($json?.id||$json||null);\nreturn [{json:{...a,quoteId:id}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-32,
8352
],
"id": "87dad15a-9daf-40b7-b195-481bb0ba5e1d",
"name": "Preparar respuesta cotizaci贸n"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_save_my_artifact",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "={{ $node[\"Contexto Artefacto\"].json.auth }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify({p_artifact_type:$json.artifactType,p_title:$json.title,p_url:$json.artifactUrl,p_provider:$json.provider,p_quote_id:($json.artifactType==='monthly_glm'&&$json.sourceQuoteId)?$json.sourceQuoteId:null,p_conversation_id:$json.conversationId,p_display_name:$json.user.name,p_session_id:$json.appSessionId,p_metadata:{action:$node[\"Contexto Artefacto\"].json.action,sourceQuoteId:$json.sourceQuoteId||null}}) }}",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-256,
8608
],
"id": "52296a6e-2bf4-4b78-b31d-7505c443f57d",
"name": "Guardar otro artefacto Supabase",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const action=String($node[\"Contexto Artefacto\"].json.action||'');\nconst a=action==='generate_image'\n ? ($node[\"Normalizar imagen generada\"].json||{})\n : ($node[\"Normalizar resultado\"].json||{});\nconst dbId=typeof $json==='string'?$json:($json?.id||$json||null);\nreturn [{json:{...a,artifactDbId:dbId}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-32,
8608
],
"id": "5f4b24ac-d4af-475b-859b-26fef9c3f4cd",
"name": "Preparar respuesta artefacto"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ {ok:$json.ok!==false,artifactUrl:$json.artifactUrl||null,artifactType:$json.artifactType||null,artifactId:$json.artifactId||null,quoteId:$json.quoteId||null,title:$json.title||null,error:$json.error||null} }}",
"options": {
"responseCode": 200
}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.4,
"position": [
368,
8544
],
"id": "70381624-8e34-41cf-8094-fd57d9ede34f",
"name": "Responder artefacto"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "9240c33f-9716-41ea-870c-eaeceb988d89",
"leftValue": "={{ $json.action }}",
"rightValue": "generate_quote",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-3616,
8592
],
"id": "6d4f960b-78ec-4cf7-b0bd-3beb79d3ed65",
"name": "Acci贸n es cotizaci贸n?"
},
{
"parameters": {
"jsCode": "const req=$node[\"Contexto Artefacto\"].json;\nconst refs=Array.isArray(req.quote?.visualReferences)?req.quote.visualReferences:[];\nconst out=[];\nrefs.forEach((ref,index)=>{\n const obj=(ref && typeof ref==='object')?ref:{};\n const prompt=String(obj.imagePrompt||obj.prompt||'').trim();\n const already=String(obj.imageDriveId||obj.driveId||obj.fileId||obj.imageUrl||obj.url||'').trim();\n if(prompt && !already){\n out.push({json:{...req,hasVisual:true,visualIndex:index,imagePrompt:prompt,visualTitle:String(obj.title||`Referencia visual ${index+1}`)}});\n }\n});\nif(!out.length) out.push({json:{...req,hasVisual:false}});\nreturn out;"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-3392,
8560
],
"id": "f107280d-36b5-4d46-b69d-592d79a6a1fb",
"name": "Preparar visuales cotizaci贸n"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "d5a0d13b-e1b9-465b-b321-b4c303ede9e1",
"leftValue": "={{ $json.hasVisual }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-3168,
8560
],
"id": "1fe96ff3-f7aa-4058-8fd9-1b983d288c10",
"name": "Tiene visuales cotizaci贸n?"
},
{
"parameters": {
"resource": "image",
"modelId": {
"__rl": true,
"value": "models/gemini-3-pro-image",
"mode": "list",
"cachedResultName": "models/gemini-3-pro-image (Nano Banana Pro)"
},
"prompt": "={{ $json.imagePrompt }}",
"options": {
"binaryPropertyOutput": "data"
}
},
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"typeVersion": 1.2,
"position": [
-2960,
8528
],
"id": "2f44ef05-7115-4ee2-8202-82adc2f0c979",
"name": "Gemini - Visuales cotizaci贸n",
"retryOnFail": true,
"maxTries": 2,
"waitBetweenTries": 1500,
"credentials": {
"googlePalmApi": {
"id": "jvsXYwL6IOoY2DBU",
"name": "Isaac - Gemini Api Pago"
}
}
},
{
"parameters": {
"name": "={{ 'WMC_Cotizacion_Visual_' + ($itemIndex + 1) + '.png' }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root",
"cachedResultName": "/ (Root folder)"
},
"options": {
"simplifyOutput": true
}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
-2736,
8528
],
"id": "e13fdd03-2239-4a23-9d6a-3d8163e58015",
"name": "Subir visuales cotizaci贸n",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"jsCode": "const req=$node[\"Contexto Artefacto\"].json;\nconst quote=JSON.parse(JSON.stringify(req.quote||{}));\nconst refs=Array.isArray(quote.visualReferences)?quote.visualReferences:[];\nconst specs=$items(\"Preparar visuales cotizaci贸n\").filter(i=>i.json?.hasVisual===true);\nconst uploads=$items(\"Subir visuales cotizaci贸n\");\nfor(let i=0;i<Math.min(specs.length,uploads.length);i++){\n const idx=Number(specs[i].json.visualIndex);\n const id=String(uploads[i].json?.id||'');\n if(Number.isInteger(idx) && refs[idx] && id){\n const prior=(refs[idx] && typeof refs[idx]==='object')?refs[idx]:{title:String(refs[idx]||'')};\n refs[idx]={...prior,imageDriveId:id,url:`https://drive.google.com/file/d/${id}/view`};\n }\n}\nquote.visualReferences=refs;\nreturn [{json:{...req,quote}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-2288,
8752
],
"id": "caf0791a-6bb3-4f6c-a79b-d2e64d21a4a8",
"name": "Recomponer cotizaci贸n"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "a5e86e6e-bfae-46e0-a3f1-a9273a444857",
"leftValue": "={{ $json.action }}",
"rightValue": "generate_monthly_glm",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-3392,
8688
],
"id": "ae70407c-465e-4a3b-a0d1-06aa81547198",
"name": "Es mensualizaci贸n?"
},
{
"parameters": {
"url": "={{ 'https://dbit.digitalcompass.agency/rest/v1/cotizador_wmc_quotes?select=id,status,conversation_id,country_code,country_name,brand_solution,project,advertiser,format,exchange_rate,local_currency_code,total_usd,total_local,document_url,metadata,created_at,cotizador_wmc_quote_items(id,sort_order,section,description,units,days,unit_cost_usd,total_usd,unit_cost_local,total_local,is_estimated,confidence,estimation_reason,metadata)&source=eq.app&conversation_id=eq.' + encodeURIComponent($node[\"Contexto Artefacto\"].json.conversationId) + '&order=created_at.desc&limit=1' }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "={{ $node[\"Contexto Artefacto\"].json.auth }}"
}
]
},
"options": {
"timeout": 20000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-3168,
8688
],
"id": "b52e340f-7881-4c00-9d60-e0e15e8f8941",
"name": "Supabase - 煤ltima cotizaci贸n WMC",
"alwaysOutputData": true,
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const req = $node[\"Contexto Artefacto\"].json;\nconst raw = $json ?? {};\n\nfunction firstRow_(value) {\n if (Array.isArray(value)) return value[0] ?? null;\n if (Array.isArray(value?.data)) return value.data[0] ?? null;\n if (Array.isArray(value?.body)) return value.body[0] ?? null;\n if (value?.body && typeof value.body === 'object' && !Array.isArray(value.body)) return value.body;\n if (value && typeof value === 'object' && ('id' in value || 'country_code' in value || 'project' in value)) return value;\n return null;\n}\nfunction n_(v, fallback = 0) {\n const n = Number(v);\n return Number.isFinite(n) ? n : fallback;\n}\nfunction money_(v) {\n return Math.round((n_(v, 0) + Number.EPSILON) * 100) / 100;\n}\nfunction currencyFor_(code) {\n return ({GT:'GTQ',CR:'CRC',SV:'USD',HN:'HNL',NI:'NIO'})[String(code||'').toUpperCase()] || '';\n}\nfunction countryFor_(code) {\n return ({GT:'Guatemala',CR:'Costa Rica',SV:'El Salvador',HN:'Honduras',NI:'Nicaragua'})[String(code||'').toUpperCase()] || '';\n}\n\nconst row = firstRow_(raw);\nlet q = req.quote && typeof req.quote === 'object' ? JSON.parse(JSON.stringify(req.quote)) : {};\nlet sourceQuoteId = String(req.artifact?.sourceQuoteId || '').trim();\n\nif (row) {\n const relItems =\n (Array.isArray(row.cotizador_wmc_quote_items) && row.cotizador_wmc_quote_items) ||\n (Array.isArray(row.quote_items) && row.quote_items) ||\n (Array.isArray(row.items) && row.items) ||\n [];\n\n const items = relItems\n .slice()\n .sort((a,b) => n_(a?.sort_order,0) - n_(b?.sort_order,0))\n .map((it) => ({\n section: it?.section || 'Otros',\n description: it?.description || 'Item',\n units: n_(it?.units, 0),\n days: n_(it?.days, 1),\n unitCostUsd: money_(it?.unit_cost_usd),\n totalUsd: money_(it?.total_usd),\n unitCostLocal: money_(it?.unit_cost_local),\n totalLocal: money_(it?.total_local),\n isEstimated: it?.is_estimated === true,\n confidence: it?.confidence === null || it?.confidence === undefined ? null : n_(it.confidence, 0),\n estimationReason: it?.estimation_reason || null,\n metadata: it?.metadata && typeof it.metadata === 'object' ? it.metadata : {}\n }));\n\n const subtotalUsd = money_(items.reduce((s,it)=>s+n_(it.totalUsd,0),0));\n const subtotalLocal = money_(items.reduce((s,it)=>s+n_(it.totalLocal,0),0));\n const totalUsd = money_(row.total_usd);\n const totalLocal = money_(row.total_local);\n const feeUsd = money_(Math.max(0, totalUsd - subtotalUsd));\n const feeLocal = money_(Math.max(0, totalLocal - subtotalLocal));\n const feeRate = subtotalUsd > 0 ? feeUsd / subtotalUsd : 0;\n\n q = {\n ...q,\n countryCode: String(row.country_code || q.countryCode || '').toUpperCase(),\n country: row.country_name || q.country || countryFor_(row.country_code),\n brandSolution: row.brand_solution || q.brandSolution || 'Walmart Connect',\n project: row.project || q.project || '',\n advertiser: row.advertiser || q.advertiser || '',\n format: row.format || q.format || '',\n exchangeRate: n_(row.exchange_rate, n_(q.exchangeRate,1)),\n currencyCode: row.local_currency_code || q.currencyCode || currencyFor_(row.country_code),\n status: row.status || q.status || 'generated',\n items: items.length ? items : (Array.isArray(q.items) ? q.items : []),\n subtotalUsd,\n subtotalLocal,\n agencyFeeRate: feeRate,\n agencyFeeUsd: feeUsd,\n agencyFeeLocal: feeLocal,\n totalUsd,\n totalLocal,\n documentUrl: row.document_url || q.documentUrl || null\n };\n sourceQuoteId = String(row.id || sourceQuoteId || '');\n}\n\nif (!q.countryCode || !q.country || !q.currencyCode || !Array.isArray(q.items) || !q.items.length) {\n throw new Error('No se encontr贸 una cotizaci贸n WMC previa completa en esta conversaci贸n para mensualizar.');\n}\n\nconst baseSubtotalLocal = money_(q.items.reduce((s,it)=>s+n_(it.totalLocal,0),0));\nconst approvedTotalLocal = money_(q.totalLocal);\nconst approvedTotalUsd = money_(q.totalUsd);\nlet feeLocal = n_(q.agencyFeeLocal, NaN);\nlet feeUsd = n_(q.agencyFeeUsd, NaN);\nlet feeRate = n_(q.agencyFeeRate, NaN);\n\nif (!Number.isFinite(feeLocal)) feeLocal = money_(Math.max(0, approvedTotalLocal - baseSubtotalLocal));\nif (!Number.isFinite(feeUsd)) {\n const subtotalUsd = money_(q.items.reduce((s,it)=>s+n_(it.totalUsd,0),0));\n feeUsd = money_(Math.max(0, approvedTotalUsd - subtotalUsd));\n}\nif (!Number.isFinite(feeRate)) {\n const subtotalUsd = money_(q.items.reduce((s,it)=>s+n_(it.totalUsd,0),0));\n feeRate = subtotalUsd > 0 ? feeUsd / subtotalUsd : 0;\n}\n\nq.agencyFeeLocal = money_(feeLocal);\nq.agencyFeeUsd = money_(feeUsd);\nq.agencyFeeRate = feeRate;\n\nconst monthlyLines = q.items.map(it => ({...it}));\nif (q.agencyFeeLocal > 0.005) {\n monthlyLines.push({\n section: 'Fee de agencia',\n description: `Fee de agencia (${(q.agencyFeeRate * 100).toFixed(2).replace(/\\.00$/,'')}%)`,\n units: 1,\n days: 1,\n unitCostUsd: q.agencyFeeUsd,\n totalUsd: q.agencyFeeUsd,\n unitCostLocal: q.agencyFeeLocal,\n totalLocal: q.agencyFeeLocal,\n isEstimated: false,\n confidence: 1,\n estimationReason: null,\n metadata: {systemGeneratedFromApprovedWmcTotal:true}\n });\n}\n\nconst artifact = JSON.parse(JSON.stringify(req.artifact || {}));\nartifact.sourceQuoteId = sourceQuoteId || artifact.sourceQuoteId || null;\nartifact.monthlyLines = monthlyLines;\nartifact.metadata = {\n ...(artifact.metadata && typeof artifact.metadata === 'object' ? artifact.metadata : {}),\n sourceQuoteId: artifact.sourceQuoteId,\n sourceDocumentUrl: q.documentUrl || null,\n countryCode: q.countryCode,\n country: q.country,\n currencyCode: q.currencyCode,\n exchangeRate: q.exchangeRate,\n approvedWmcTotalUsd: approvedTotalUsd,\n approvedWmcTotalLocal: approvedTotalLocal,\n agencyFeeRate: q.agencyFeeRate,\n agencyFeeUsd: q.agencyFeeUsd,\n agencyFeeLocal: q.agencyFeeLocal,\n walmartApproved: true,\n glmIvaRate: 0.12\n};\n\nreturn [{json:{...req,quote:q,artifact}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-2944,
8688
],
"id": "fd12a715-5138-46ec-8e50-a4c5e70a0f81",
"name": "Hidratar mensualizaci贸n aprobada"
},
{
"parameters": {
"operation": "share",
"fileId": {
"__rl": true,
"value": "={{ $json.id }}",
"mode": "id"
},
"permissionsUi": {
"permissionsValues": {
"role": "writer",
"type": "domain",
"domain": "gomezleemarketing.com"
}
},
"options": {}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
-2736,
8272
],
"id": "762165ec-1698-423a-a2f1-bc693d337532",
"name": "Compartir visuales propuesta con GomezLee Marketing",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"operation": "share",
"fileId": {
"__rl": true,
"value": "={{ $json.id }}",
"mode": "id"
},
"permissionsUi": {
"permissionsValues": {
"role": "writer",
"type": "domain",
"domain": "gomezleemarketing.com"
}
},
"options": {}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
-2512,
8752
],
"id": "f8aff62a-85af-4d36-8981-fed579a7be1e",
"name": "Compartir visuales cotizaci贸n con GomezLee Marketing",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"jsCode": "const a = $json ?? {};\n\nif (a.ok === false) {\n return [{json:{...a,shareFileId:null,shareRequired:false}}];\n}\n\nlet id = String(a.artifactId || '').trim();\nconst url = String(a.artifactUrl || '').trim();\n\nif (!id && url) {\n const patterns = [\n /\\/d\\/([A-Za-z0-9_-]{20,})/,\n /[?&]id=([A-Za-z0-9_-]{20,})/,\n /\\/folders\\/([A-Za-z0-9_-]{20,})/\n ];\n for (const pattern of patterns) {\n const match = url.match(pattern);\n if (match?.[1]) {\n id = match[1];\n break;\n }\n }\n}\n\nif (!id) {\n throw new Error('No se pudo identificar el archivo de Google Workspace para aplicar el acceso de GomezLee Marketing.');\n}\n\nreturn [{json:{...a,shareFileId:id,shareRequired:true}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-1392,
8480
],
"id": "6f44d625-0528-4a0e-9285-880a136e37e9",
"name": "Preparar permiso GomezLee Marketing"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "c8060fe4-e989-4cea-8b44-3e1f0e0c153c",
"leftValue": "={{ $json.shareRequired }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-1168,
8480
],
"id": "d5bf4b40-b2b7-40ac-abdc-19022b65d8a0",
"name": "驴Archivo Google para compartir?"
},
{
"parameters": {
"operation": "share",
"fileId": {
"__rl": true,
"value": "={{ $json.shareFileId }}",
"mode": "id"
},
"permissionsUi": {
"permissionsValues": {
"role": "writer",
"type": "domain",
"domain": "gomezleemarketing.com"
}
},
"options": {}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
-944,
8368
],
"id": "0755c9e3-db77-4263-a135-10c9e6edc017",
"name": "Compartir archivo final con GomezLee Marketing",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"jsCode": "const original = $node[\"Normalizar resultado\"].json ?? {};\nreturn [{json:original}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-704,
8368
],
"id": "ded9cefe-006e-44bc-9ffb-1df081b8a59a",
"name": "Restaurar resultado tras compartir"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "889b613b-a5d6-4362-bac9-969a9776b06f",
"leftValue": "={{ $json.internalEmail }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-5600,
7952
],
"id": "08fb954f-6326-4cbf-814f-8961d3252511",
"name": "驴Solicitud interna email?"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "5ee8550d-b245-47c1-9c58-722bf3e0c7d1",
"leftValue": "={{ $json.internalAuthorized }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-5376,
7952
],
"id": "5fbba220-1d24-4348-8c43-745664a9b848",
"name": "Interno autorizado?"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ {ok:false,error:'Solicitud interna no autorizada.'} }}",
"options": {
"responseCode": 401
}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.4,
"position": [
-5152,
8128
],
"id": "4fb3d352-64b1-4c11-aa23-1e802e8c00c4",
"name": "Responder 401 Interno"
},
{
"parameters": {
"jsCode": "const req=$node[\"Normalizar solicitud\"].json;\nconst email=String(req.user?.email||'wmc@gomezlee.marketing').trim().toLowerCase();\nreturn [{json:{...req,userId:null,verifiedEmail:email,fullName:req.user?.name||'Walmart Connect Email Agent',accessAllowed:true,canUseTarifario:false,internalEmail:true}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-5152,
7872
],
"id": "be28584f-082d-4774-818f-6670465432e8",
"name": "Autorizar email interno"
},
{
"parameters": {
"jsCode": "const x=$json??{};\nreturn [{json:{...x,internalEmail:Boolean(x.internalEmail)}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-4064,
8128
],
"id": "f832489e-9cf7-43ad-b246-0b89204dda0a",
"name": "Contexto Artefacto"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "03140a28-4f09-4a9c-b82b-4c6eeced8c17",
"leftValue": "={{ $node[\"Contexto Artefacto\"].json.internalEmail }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
80,
7968
],
"id": "3c1eaefc-44eb-4e31-8e9c-bacae9e6c86e",
"name": "驴Imagen interna email?"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "12b1ba07-d2ac-47df-9c66-5e18bdb41d79",
"leftValue": "={{ $node[\"Contexto Artefacto\"].json.internalEmail }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
112,
8400
],
"id": "e2370114-e36a-49f0-97a6-313a1af66866",
"name": "驴Resultado interno email?"
},
{
"parameters": {
"jsCode": "const a=$json??{};\nreturn [{json:{ok:a.ok!==false,artifactUrl:a.artifactUrl||null,artifactType:a.artifactType||null,artifactId:a.artifactId||null,quoteId:null,title:a.title||null,error:a.error||null}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
320,
8160
],
"id": "c6fe38d4-fa37-49a8-aa84-c7065a763b3b",
"name": "Preparar respuesta interna Artefactos"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ $json }}",
"options": {
"responseCode": 200
}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.4,
"position": [
560,
8160
],
"id": "eba6e35b-623e-4e6d-bdb2-00b943a5873a",
"name": "Responder artefacto interno"
}
],
"connections": {
"Webhook - Artefactos": {
"main": [
[
{
"node": "Configuraci贸n - sin ENV",
"type": "main",
"index": 0
}
]
]
},
"Configuraci贸n - sin ENV": {
"main": [
[
{
"node": "Normalizar solicitud",
"type": "main",
"index": 0
}
]
]
},
"Normalizar solicitud": {
"main": [
[
{
"node": "驴Solicitud interna email?",
"type": "main",
"index": 0
}
]
]
},
"Supabase - validar JWT": {
"main": [
[
{
"node": "Validar identidad",
"type": "main",
"index": 0
}
]
]
},
"Validar identidad": {
"main": [
[
{
"node": "JWT v谩lido?",
"type": "main",
"index": 0
}
]
]
},
"JWT v谩lido?": {
"main": [
[
{
"node": "Supabase - acceso",
"type": "main",
"index": 0
}
],
[
{
"node": "Responder 401",
"type": "main",
"index": 0
}
]
]
},
"Supabase - acceso": {
"main": [
[
{
"node": "Validar acceso",
"type": "main",
"index": 0
}
]
]
},
"Validar acceso": {
"main": [
[
{
"node": "Acceso permitido?",
"type": "main",
"index": 0
}
]
]
},
"Acceso permitido?": {
"main": [
[
{
"node": "Contexto Artefacto",
"type": "main",
"index": 0
}
],
[
{
"node": "Responder 403",
"type": "main",
"index": 0
}
]
]
},
"Debe generar?": {
"main": [
[
{
"node": "Es imagen?",
"type": "main",
"index": 0
}
],
[
{
"node": "Responder sin artefacto",
"type": "main",
"index": 0
}
]
]
},
"Es imagen?": {
"main": [
[
{
"node": "Gemini - Generar imagen",
"type": "main",
"index": 0
}
],
[
{
"node": "Es propuesta?",
"type": "main",
"index": 0
}
]
]
},
"Gemini - Generar imagen": {
"main": [
[
{
"node": "Subir imagen a Drive",
"type": "main",
"index": 0
}
]
]
},
"Subir imagen a Drive": {
"main": [
[
{
"node": "Compartir imagen con GomezLee Marketing",
"type": "main",
"index": 0
}
]
]
},
"Normalizar imagen generada": {
"main": [
[
{
"node": "驴Imagen interna email?",
"type": "main",
"index": 0
}
]
]
},
"Es propuesta?": {
"main": [
[
{
"node": "Preparar visuales propuesta",
"type": "main",
"index": 0
}
],
[
{
"node": "Acci贸n es cotizaci贸n?",
"type": "main",
"index": 0
}
]
]
},
"Preparar visuales propuesta": {
"main": [
[
{
"node": "Tiene visuales?",
"type": "main",
"index": 0
}
]
]
},
"Tiene visuales?": {
"main": [
[
{
"node": "Gemini - Visuales propuesta",
"type": "main",
"index": 0
}
],
[
{
"node": "Preparar Google",
"type": "main",
"index": 0
}
]
]
},
"Gemini - Visuales propuesta": {
"main": [
[
{
"node": "Subir visuales propuesta",
"type": "main",
"index": 0
}
]
]
},
"Subir visuales propuesta": {
"main": [
[
{
"node": "Compartir visuales propuesta con GomezLee Marketing",
"type": "main",
"index": 0
}
]
]
},
"Recomponer propuesta": {
"main": [
[
{
"node": "Preparar Google",
"type": "main",
"index": 0
}
]
]
},
"Preparar Google": {
"main": [
[
{
"node": "Google Automation",
"type": "main",
"index": 0
}
]
]
},
"Google Automation": {
"main": [
[
{
"node": "Normalizar resultado",
"type": "main",
"index": 0
}
]
]
},
"Normalizar resultado": {
"main": [
[
{
"node": "驴Resultado interno email?",
"type": "main",
"index": 0
}
]
]
},
"Guardar cotizaci贸n Supabase": {
"main": [
[
{
"node": "Preparar respuesta cotizaci贸n",
"type": "main",
"index": 0
}
]
]
},
"Preparar respuesta cotizaci贸n": {
"main": [
[
{
"node": "Responder artefacto",
"type": "main",
"index": 0
}
]
]
},
"Guardar otro artefacto Supabase": {
"main": [
[
{
"node": "Preparar respuesta artefacto",
"type": "main",
"index": 0
}
]
]
},
"Preparar respuesta artefacto": {
"main": [
[
{
"node": "Responder artefacto",
"type": "main",
"index": 0
}
]
]
},
"Resultado es cotizaci贸n?": {
"main": [
[
{
"node": "Guardar cotizaci贸n Supabase",
"type": "main",
"index": 0
}
],
[
{
"node": "Guardar otro artefacto Supabase",
"type": "main",
"index": 0
}
]
]
},
"Acci贸n es cotizaci贸n?": {
"main": [
[
{
"node": "Preparar visuales cotizaci贸n",
"type": "main",
"index": 0
}
],
[
{
"node": "Es mensualizaci贸n?",
"type": "main",
"index": 0
}
]
]
},
"Preparar visuales cotizaci贸n": {
"main": [
[
{
"node": "Tiene visuales cotizaci贸n?",
"type": "main",
"index": 0
}
]
]
},
"Tiene visuales cotizaci贸n?": {
"main": [
[
{
"node": "Gemini - Visuales cotizaci贸n",
"type": "main",
"index": 0
}
],
[
{
"node": "Preparar Google",
"type": "main",
"index": 0
}
]
]
},
"Gemini - Visuales cotizaci贸n": {
"main": [
[
{
"node": "Subir visuales cotizaci贸n",
"type": "main",
"index": 0
}
]
]
},
"Subir visuales cotizaci贸n": {
"main": [
[
{
"node": "Compartir visuales cotizaci贸n con GomezLee Marketing",
"type": "main",
"index": 0
}
]
]
},
"Recomponer cotizaci贸n": {
"main": [
[
{
"node": "Preparar Google",
"type": "main",
"index": 0
}
]
]
},
"Es mensualizaci贸n?": {
"main": [
[
{
"node": "Supabase - 煤ltima cotizaci贸n WMC",
"type": "main",
"index": 0
}
],
[
{
"node": "Preparar Google",
"type": "main",
"index": 0
}
]
]
},
"Supabase - 煤ltima cotizaci贸n WMC": {
"main": [
[
{
"node": "Hidratar mensualizaci贸n aprobada",
"type": "main",
"index": 0
}
]
]
},
"Hidratar mensualizaci贸n aprobada": {
"main": [
[
{
"node": "Preparar Google",
"type": "main",
"index": 0
}
]
]
},
"Compartir imagen con GomezLee Marketing": {
"main": [
[
{
"node": "Normalizar imagen generada",
"type": "main",
"index": 0
}
]
]
},
"Compartir visuales propuesta con GomezLee Marketing": {
"main": [
[
{
"node": "Recomponer propuesta",
"type": "main",
"index": 0
}
]
]
},
"Compartir visuales cotizaci贸n con GomezLee Marketing": {
"main": [
[
{
"node": "Recomponer cotizaci贸n",
"type": "main",
"index": 0
}
]
]
},
"Preparar permiso GomezLee Marketing": {
"main": [
[
{
"node": "驴Archivo Google para compartir?",
"type": "main",
"index": 0
}
]
]
},
"驴Archivo Google para compartir?": {
"main": [
[
{
"node": "Compartir archivo final con GomezLee Marketing",
"type": "main",
"index": 0
}
],
[
{
"node": "Resultado es cotizaci贸n?",
"type": "main",
"index": 0
}
]
]
},
"Compartir archivo final con GomezLee Marketing": {
"main": [
[
{
"node": "Restaurar resultado tras compartir",
"type": "main",
"index": 0
}
]
]
},
"Restaurar resultado tras compartir": {
"main": [
[
{
"node": "Resultado es cotizaci贸n?",
"type": "main",
"index": 0
}
]
]
},
"驴Solicitud interna email?": {
"main": [
[
{
"node": "Interno autorizado?",
"type": "main",
"index": 0
}
],
[
{
"node": "Supabase - validar JWT",
"type": "main",
"index": 0
}
]
]
},
"Interno autorizado?": {
"main": [
[
{
"node": "Autorizar email interno",
"type": "main",
"index": 0
}
],
[
{
"node": "Responder 401 Interno",
"type": "main",
"index": 0
}
]
]
},
"Autorizar email interno": {
"main": [
[
{
"node": "Contexto Artefacto",
"type": "main",
"index": 0
}
]
]
},
"Contexto Artefacto": {
"main": [
[
{
"node": "Debe generar?",
"type": "main",
"index": 0
}
]
]
},
"驴Imagen interna email?": {
"main": [
[
{
"node": "Preparar respuesta interna Artefactos",
"type": "main",
"index": 0
}
],
[
{
"node": "Guardar otro artefacto Supabase",
"type": "main",
"index": 0
}
]
]
},
"驴Resultado interno email?": {
"main": [
[
{
"node": "Preparar respuesta interna Artefactos",
"type": "main",
"index": 0
}
],
[
{
"node": "Preparar permiso GomezLee Marketing",
"type": "main",
"index": 0
}
]
]
},
"Preparar respuesta interna Artefactos": {
"main": [
[
{
"node": "Responder artefacto interno",
"type": "main",
"index": 0
}
]
]
}
},
"authors": "Isaac Aracena",
"name": "Version 59b8fc04",
"description": "",
"autosaved": true,
"workflowPublishHistory": [
{
"createdAt": "2026-08-29T16:24:37.308Z",
"id": 5304,
"workflowId": "kHT6jUVIcYGjagV3",
"versionId": "59b8fc04-1a98-4aa6-b66f-fd437fe59265",
"event": "activated",
"userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
}
]
}
}