From 4ee6eba338bb300b5cc73042bc02885e98cf6079 Mon Sep 17 00:00:00 2001 From: Isaac_Aracena Date: Sun, 30 Aug 2026 04:00:54 +0000 Subject: [PATCH] Create backup: Cotizador WMC - Artefactos --- cotizador-wmc-artefactos.json | 4187 +++++++++++++++++++++++++++++++++ 1 file changed, 4187 insertions(+) create mode 100644 cotizador-wmc-artefactos.json diff --git a/cotizador-wmc-artefactos.json b/cotizador-wmc-artefactos.json new file mode 100644 index 0000000..4217363 --- /dev/null +++ b/cotizador-wmc-artefactos.json @@ -0,0 +1,4187 @@ +{ + "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{\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 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 ", + "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{\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 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" + } + ] + } +} \ No newline at end of file