From 53a6cd577486efd0eac75ed3d687d49d287a0d79 Mon Sep 17 00:00:00 2001 From: Isaac_Aracena Date: Sun, 23 Aug 2026 04:01:00 +0000 Subject: [PATCH] Create backup: Cotizador WMC - Artefactos Google Workspace + Gemini Nativo - SIN ENV --- ...oogle-workspace-gemini-nativo-sin-env.json | 2871 +++++++++++++++++ 1 file changed, 2871 insertions(+) create mode 100644 cotizador-wmc-artefactos-google-workspace-gemini-nativo-sin-env.json diff --git a/cotizador-wmc-artefactos-google-workspace-gemini-nativo-sin-env.json b/cotizador-wmc-artefactos-google-workspace-gemini-nativo-sin-env.json new file mode 100644 index 0000000..decb989 --- /dev/null +++ b/cotizador-wmc-artefactos-google-workspace-gemini-nativo-sin-env.json @@ -0,0 +1,2871 @@ +{ + "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{\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", + "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{\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