Files
cotizador-wmc-artefactos-go…/cotizador-wmc-artefactos-google-workspace-gemini-nativo-sin-env.json

2871 lines
85 KiB
JSON

{
"updatedAt": "2026-08-22T14:58:32.112Z",
"createdAt": "2026-08-22T14:54:47.146Z",
"id": "kHT6jUVIcYGjagV3",
"name": "Cotizador WMC - Artefactos Google Workspace + Gemini Nativo - SIN ENV",
"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": [
-2416,
320
],
"id": "0e9e6d22-cbb9-4373-9cb5-be1b473408a9",
"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 }\n}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-2208,
320
],
"id": "11e3d051-19e4-4222-8213-4e2a0d308ba2",
"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 action=clean(body.action,80);\nconst allowed=['generate_quote','generate_proposal','generate_image','generate_monthly_glm'];\nif(!auth.startsWith('Bearer ')) throw new Error('Falta Authorization Bearer de Supabase.');\nreturn [{json:{\n auth,\n action,\n shouldGenerate:allowed.includes(action),\n quote:body.quote??null,\n artifact:body.artifact??null,\n user:body.user??{},\n conversationId:clean(body.conversationId,220),\n appSessionId:clean(body.appSessionId,250)||`artifact-${Date.now()}`,\n model:clean(body.model,120)\n}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-1984,
320
],
"id": "09c97b8c-757a-4725-8075-99a101e56dec",
"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": [
-1760,
320
],
"id": "716313a1-de24-433f-9615-d8c08472f561",
"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": [
-1536,
320
],
"id": "53ee014f-d483-418d-ab54-97870254d3e6",
"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": [
-1328,
320
],
"id": "171c3412-0a07-464f-abd5-0279ce1497bb",
"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": [
-1104,
608
],
"id": "5aab5220-1145-4928-a92b-9af12eef0e51",
"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' }}",
"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": [
-1104,
240
],
"id": "904105ac-2d15-4ebf-a1d9-eea772b73c86",
"name": "Supabase - acceso",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const req=$node[\"Validar identidad\"].json;\nconst rows=Array.isArray($json)?$json:[];\nconst row=rows[0]||null;\nreturn [{json:{\n ...req,\n accessAllowed:Boolean(row&&row.is_active===true&&String(row.email||'').toLowerCase()===req.verifiedEmail),\n fullName:row?.full_name||req.user?.name||req.verifiedEmail,\n canUseTarifario:Boolean(row?.can_use_tarifario)\n}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-880,
240
],
"id": "6f2cf220-c4be-44b9-88d7-3967cf3061af",
"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": [
-656,
240
],
"id": "38b9537e-d82d-40cc-bc1e-bbf3c941b77a",
"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": [
-448,
608
],
"id": "4707d4b8-2e3b-4360-a8e3-04fc3917c42e",
"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": [
-448,
240
],
"id": "167cec92-4fb6-478b-952a-cc5972a62fd5",
"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": [
-224,
608
],
"id": "227f697a-b1fd-4aab-ba78-d8ffa1610dcc",
"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": [
-224,
240
],
"id": "7b449346-9269-49d4-a342-3a0ecf66ffc4",
"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": [
0,
0
],
"id": "1af807d6-ebf1-42d1-83a2-9336b51503c4",
"name": "Gemini - Generar imagen",
"retryOnFail": true,
"maxTries": 2,
"waitBetweenTries": 1500,
"credentials": {
"googlePalmApi": {
"id": "jvsXYwL6IOoY2DBU",
"name": "Isaac - Gemini Api Pago"
}
}
},
{
"parameters": {
"name": "={{ 'WMC_' + String($node[\"Validar acceso\"].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": [
224,
0
],
"id": "d8d938ce-83d4-453c-831a-8b3de9b7abf7",
"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": "reader",
"type": "user",
"emailAddress": "={{ $node[\"Validar acceso\"].json.verifiedEmail }}"
}
},
"options": {
"sendNotificationEmail": false
}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
448,
0
],
"id": "947fb88e-8108-4a00-a8d3-b8323a321f66",
"name": "Compartir imagen con usuario",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"jsCode": "const req=$node[\"Validar acceso\"].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": [
672,
0
],
"id": "f35ee0c1-6df3-41bf-b071-5ed77095beaa",
"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": [
0,
352
],
"id": "1c9ab959-e774-42e3-8fef-5b28bc3e0496",
"name": "Es propuesta?"
},
{
"parameters": {
"jsCode": "const req=$node[\"Validar acceso\"].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": [
224,
352
],
"id": "f891c33f-6bd7-4341-878b-dbf8856e4cd6",
"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": [
448,
352
],
"id": "0a9c296e-bd9e-4e65-a56c-dced43ee0707",
"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": [
672,
288
],
"id": "a4836701-b05b-4bce-8959-721cde4475b9",
"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": [
880,
288
],
"id": "ed01b293-222f-40bc-a92d-5ff6a3051630",
"name": "Subir visuales propuesta",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"jsCode": "const req=$node[\"Validar acceso\"].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=$input.all();\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": [
1104,
288
],
"id": "f780c905-49ed-4857-aa4b-f7407eb55f07",
"name": "Recomponer propuesta"
},
{
"parameters": {
"jsCode": "const base=$node[\"Validar acceso\"].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": [
1328,
400
],
"id": "36027bb3-c9be-4e1b-9d41-860e3b05db0b",
"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": [
1552,
400
],
"id": "25df66d4-1fb1-4f01-ac00-553cd163076b",
"name": "Google Automation",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const x=$node[\"Preparar Google\"].json;\nconst base=$node[\"Validar acceso\"].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 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": [
1760,
400
],
"id": "9f4baf16-4df7-42a4-b803-1f5c44ea7858",
"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": [
1984,
400
],
"id": "7700e93d-b162-439a-8258-f2f2a51ede6a",
"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[\"Validar acceso\"].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": [
2208,
272
],
"id": "70ecdfca-a11f-48e1-89d6-3841b2e76011",
"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": [
2432,
272
],
"id": "f6fcf409-adce-4aeb-81de-71bee45b48c9",
"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[\"Validar acceso\"].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:null,p_conversation_id:$json.conversationId,p_display_name:$json.user.name,p_session_id:$json.appSessionId,p_metadata:{action:$node[\"Validar acceso\"].json.action}}) }}",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2208,
528
],
"id": "52958bff-a485-419a-8e6c-8f3486dcf9b0",
"name": "Guardar otro artefacto Supabase",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const action=String($node[\"Validar acceso\"].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": [
2432,
528
],
"id": "38ab8f71-7aaa-492a-b32a-c80989e2d638",
"name": "Preparar respuesta artefacto"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ {ok:$json.ok!==false,artifactUrl:$json.artifactUrl||null,artifactType:$json.artifactType||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": [
2640,
400
],
"id": "06c1fb6b-611b-4c48-b775-4473819fd5a3",
"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": [
224,
512
],
"id": "42c82407-d083-4ee4-81b4-886a96887ea7",
"name": "Acci贸n es cotizaci贸n?"
},
{
"parameters": {
"jsCode": "const req=$node[\"Validar acceso\"].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": [
448,
480
],
"id": "59b1f0db-e0ac-46cb-aa29-d173c96fe45c",
"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": [
672,
480
],
"id": "ee9f94bb-350e-442b-9bc3-4855acdbe768",
"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": [
880,
448
],
"id": "e71466e3-117f-4b4b-b931-62ebd3b72285",
"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": [
1104,
448
],
"id": "7ed3e857-a833-4272-a7e6-ef1484316d78",
"name": "Subir visuales cotizaci贸n",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"jsCode": "const req=$node[\"Validar acceso\"].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=$input.all();\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": [
1328,
448
],
"id": "680aaf35-738f-4c3f-863d-6d5d07f5575e",
"name": "Recomponer cotizaci贸n"
}
],
"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": "Supabase - validar JWT",
"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": "Debe generar?",
"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 usuario",
"type": "main",
"index": 0
}
]
]
},
"Compartir imagen con usuario": {
"main": [
[
{
"node": "Normalizar imagen generada",
"type": "main",
"index": 0
}
]
]
},
"Normalizar imagen generada": {
"main": [
[
{
"node": "Guardar otro artefacto Supabase",
"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": "Recomponer propuesta",
"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 es cotizaci贸n?",
"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": "Preparar Google",
"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": "Recomponer cotizaci贸n",
"type": "main",
"index": 0
}
]
]
},
"Recomponer cotizaci贸n": {
"main": [
[
{
"node": "Preparar Google",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"binaryMode": "separate"
},
"staticData": null,
"meta": null,
"versionId": "5e0892c6-3cfe-4d34-8af0-c7be5271ce6b",
"activeVersionId": "5e0892c6-3cfe-4d34-8af0-c7be5271ce6b",
"versionCounter": 9,
"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-22T14:59:09.000Z",
"createdAt": "2026-08-22T14:58:32.114Z",
"versionId": "5e0892c6-3cfe-4d34-8af0-c7be5271ce6b",
"workflowId": "kHT6jUVIcYGjagV3",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "cotizador-wmc-artifacts",
"responseMode": "responseNode",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
-2416,
320
],
"id": "0e9e6d22-cbb9-4373-9cb5-be1b473408a9",
"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 }\n}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-2208,
320
],
"id": "11e3d051-19e4-4222-8213-4e2a0d308ba2",
"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 action=clean(body.action,80);\nconst allowed=['generate_quote','generate_proposal','generate_image','generate_monthly_glm'];\nif(!auth.startsWith('Bearer ')) throw new Error('Falta Authorization Bearer de Supabase.');\nreturn [{json:{\n auth,\n action,\n shouldGenerate:allowed.includes(action),\n quote:body.quote??null,\n artifact:body.artifact??null,\n user:body.user??{},\n conversationId:clean(body.conversationId,220),\n appSessionId:clean(body.appSessionId,250)||`artifact-${Date.now()}`,\n model:clean(body.model,120)\n}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-1984,
320
],
"id": "09c97b8c-757a-4725-8075-99a101e56dec",
"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": [
-1760,
320
],
"id": "716313a1-de24-433f-9615-d8c08472f561",
"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": [
-1536,
320
],
"id": "53ee014f-d483-418d-ab54-97870254d3e6",
"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": [
-1328,
320
],
"id": "171c3412-0a07-464f-abd5-0279ce1497bb",
"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": [
-1104,
608
],
"id": "5aab5220-1145-4928-a92b-9af12eef0e51",
"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' }}",
"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": [
-1104,
240
],
"id": "904105ac-2d15-4ebf-a1d9-eea772b73c86",
"name": "Supabase - acceso",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const req=$node[\"Validar identidad\"].json;\nconst rows=Array.isArray($json)?$json:[];\nconst row=rows[0]||null;\nreturn [{json:{\n ...req,\n accessAllowed:Boolean(row&&row.is_active===true&&String(row.email||'').toLowerCase()===req.verifiedEmail),\n fullName:row?.full_name||req.user?.name||req.verifiedEmail,\n canUseTarifario:Boolean(row?.can_use_tarifario)\n}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-880,
240
],
"id": "6f2cf220-c4be-44b9-88d7-3967cf3061af",
"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": [
-656,
240
],
"id": "38b9537e-d82d-40cc-bc1e-bbf3c941b77a",
"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": [
-448,
608
],
"id": "4707d4b8-2e3b-4360-a8e3-04fc3917c42e",
"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": [
-448,
240
],
"id": "167cec92-4fb6-478b-952a-cc5972a62fd5",
"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": [
-224,
608
],
"id": "227f697a-b1fd-4aab-ba78-d8ffa1610dcc",
"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": [
-224,
240
],
"id": "7b449346-9269-49d4-a342-3a0ecf66ffc4",
"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": [
0,
0
],
"id": "1af807d6-ebf1-42d1-83a2-9336b51503c4",
"name": "Gemini - Generar imagen",
"retryOnFail": true,
"maxTries": 2,
"waitBetweenTries": 1500,
"credentials": {
"googlePalmApi": {
"id": "jvsXYwL6IOoY2DBU",
"name": "Isaac - Gemini Api Pago"
}
}
},
{
"parameters": {
"name": "={{ 'WMC_' + String($node[\"Validar acceso\"].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": [
224,
0
],
"id": "d8d938ce-83d4-453c-831a-8b3de9b7abf7",
"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": "reader",
"type": "user",
"emailAddress": "={{ $node[\"Validar acceso\"].json.verifiedEmail }}"
}
},
"options": {
"sendNotificationEmail": false
}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
448,
0
],
"id": "947fb88e-8108-4a00-a8d3-b8323a321f66",
"name": "Compartir imagen con usuario",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"jsCode": "const req=$node[\"Validar acceso\"].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": [
672,
0
],
"id": "f35ee0c1-6df3-41bf-b071-5ed77095beaa",
"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": [
0,
352
],
"id": "1c9ab959-e774-42e3-8fef-5b28bc3e0496",
"name": "Es propuesta?"
},
{
"parameters": {
"jsCode": "const req=$node[\"Validar acceso\"].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": [
224,
352
],
"id": "f891c33f-6bd7-4341-878b-dbf8856e4cd6",
"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": [
448,
352
],
"id": "0a9c296e-bd9e-4e65-a56c-dced43ee0707",
"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": [
672,
288
],
"id": "a4836701-b05b-4bce-8959-721cde4475b9",
"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": [
880,
288
],
"id": "ed01b293-222f-40bc-a92d-5ff6a3051630",
"name": "Subir visuales propuesta",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"jsCode": "const req=$node[\"Validar acceso\"].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=$input.all();\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": [
1104,
288
],
"id": "f780c905-49ed-4857-aa4b-f7407eb55f07",
"name": "Recomponer propuesta"
},
{
"parameters": {
"jsCode": "const base=$node[\"Validar acceso\"].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": [
1328,
400
],
"id": "36027bb3-c9be-4e1b-9d41-860e3b05db0b",
"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": [
1552,
400
],
"id": "25df66d4-1fb1-4f01-ac00-553cd163076b",
"name": "Google Automation",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const x=$node[\"Preparar Google\"].json;\nconst base=$node[\"Validar acceso\"].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 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": [
1760,
400
],
"id": "9f4baf16-4df7-42a4-b803-1f5c44ea7858",
"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": [
1984,
400
],
"id": "7700e93d-b162-439a-8258-f2f2a51ede6a",
"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[\"Validar acceso\"].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": [
2208,
272
],
"id": "70ecdfca-a11f-48e1-89d6-3841b2e76011",
"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": [
2432,
272
],
"id": "f6fcf409-adce-4aeb-81de-71bee45b48c9",
"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[\"Validar acceso\"].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:null,p_conversation_id:$json.conversationId,p_display_name:$json.user.name,p_session_id:$json.appSessionId,p_metadata:{action:$node[\"Validar acceso\"].json.action}}) }}",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2208,
528
],
"id": "52958bff-a485-419a-8e6c-8f3486dcf9b0",
"name": "Guardar otro artefacto Supabase",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const action=String($node[\"Validar acceso\"].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": [
2432,
528
],
"id": "38ab8f71-7aaa-492a-b32a-c80989e2d638",
"name": "Preparar respuesta artefacto"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ {ok:$json.ok!==false,artifactUrl:$json.artifactUrl||null,artifactType:$json.artifactType||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": [
2640,
400
],
"id": "06c1fb6b-611b-4c48-b775-4473819fd5a3",
"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": [
224,
512
],
"id": "42c82407-d083-4ee4-81b4-886a96887ea7",
"name": "Acci贸n es cotizaci贸n?"
},
{
"parameters": {
"jsCode": "const req=$node[\"Validar acceso\"].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": [
448,
480
],
"id": "59b1f0db-e0ac-46cb-aa29-d173c96fe45c",
"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": [
672,
480
],
"id": "ee9f94bb-350e-442b-9bc3-4855acdbe768",
"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": [
880,
448
],
"id": "e71466e3-117f-4b4b-b931-62ebd3b72285",
"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": [
1104,
448
],
"id": "7ed3e857-a833-4272-a7e6-ef1484316d78",
"name": "Subir visuales cotizaci贸n",
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
}
},
{
"parameters": {
"jsCode": "const req=$node[\"Validar acceso\"].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=$input.all();\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": [
1328,
448
],
"id": "680aaf35-738f-4c3f-863d-6d5d07f5575e",
"name": "Recomponer cotizaci贸n"
}
],
"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": "Supabase - validar JWT",
"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": "Debe generar?",
"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 usuario",
"type": "main",
"index": 0
}
]
]
},
"Compartir imagen con usuario": {
"main": [
[
{
"node": "Normalizar imagen generada",
"type": "main",
"index": 0
}
]
]
},
"Normalizar imagen generada": {
"main": [
[
{
"node": "Guardar otro artefacto Supabase",
"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": "Recomponer propuesta",
"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 es cotizaci贸n?",
"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": "Preparar Google",
"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": "Recomponer cotizaci贸n",
"type": "main",
"index": 0
}
]
]
},
"Recomponer cotizaci贸n": {
"main": [
[
{
"node": "Preparar Google",
"type": "main",
"index": 0
}
]
]
}
},
"authors": "Isaac Aracena",
"name": "Version 5e0892c6",
"description": "",
"autosaved": true,
"workflowPublishHistory": [
{
"createdAt": "2026-08-22T14:59:09.626Z",
"id": 5124,
"workflowId": "kHT6jUVIcYGjagV3",
"versionId": "5e0892c6-3cfe-4d34-8af0-c7be5271ce6b",
"event": "activated",
"userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
}
]
}
}