{ "updatedAt": "2026-07-29T18:48:09.844Z", "createdAt": "2026-07-28T16:18:07.824Z", "id": "F2rMlVS9mBypNNn7", "name": "GLM Hub - Generar ícono con Gemini", "description": null, "active": true, "isArchived": false, "nodes": [ { "parameters": { "httpMethod": "POST", "path": "glm-hub-generar-icono", "responseMode": "responseNode", "options": { "allowedOrigins": "*" } }, "id": "e9002643-523d-436d-8c57-3d37f80f7ec3", "name": "Webhook - Generar ícono", "type": "n8n-nodes-base.webhook", "typeVersion": 2.1, "position": [ -2992, 464 ], "webhookId": "bc20a398-5ecf-42a2-9d17-9396aa278708" }, { "parameters": { "jsCode": "const request = $input.first().json ?? {};\nconst rawBody = request.body ?? request;\nlet body = rawBody;\n\nif (typeof rawBody === 'string') {\n try {\n body = JSON.parse(rawBody);\n } catch {\n body = {};\n }\n}\n\nconst headers = request.headers ?? {};\nconst headerAuthorization = String(headers.authorization ?? headers.Authorization ?? '').trim();\nconst accessToken = String(body.accessToken ?? '').trim();\nconst authorization = headerAuthorization.toLowerCase().startsWith('bearer ')\n ? headerAuthorization\n : accessToken\n ? `Bearer ${accessToken}`\n : '';\nconst name = String(body.name ?? '').trim();\nconst description = String(body.description ?? '').trim();\n\nlet error = '';\nif (!authorization.toLowerCase().startsWith('bearer ')) {\n error = 'La sesión de Supabase no fue enviada o no es válida.';\n} else if (name.length < 2 || name.length > 60) {\n error = 'El nombre debe contener entre 2 y 60 caracteres.';\n} else if (!description || description.length > 180) {\n error = 'La descripción debe contener entre 1 y 180 caracteres.';\n}\n\nreturn [{ json: { valid: !error, error, authorization, name, description } }];" }, "id": "f7b0a22e-2651-4479-86c8-25262faa38c4", "name": "Validar solicitud", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ -2736, 464 ] }, { "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict", "version": 2 }, "conditions": [ { "id": "308c498d-7c3f-4414-a21f-571276aee28b", "leftValue": "={{ $json.valid }}", "rightValue": true, "operator": { "type": "boolean", "operation": "true", "singleValue": true } } ], "combinator": "and" }, "options": {} }, "id": "0313d3ca-0439-4c2d-bd34-4da5ef6c3950", "name": "¿Solicitud válida?", "type": "n8n-nodes-base.if", "typeVersion": 2.2, "position": [ -2512, 464 ] }, { "parameters": { "respondWith": "json", "responseBody": "={{ { ok: false, error: $json.error } }}", "options": { "responseCode": 400, "responseHeaders": { "entries": [ { "name": "Cache-Control", "value": "no-store" } ] } } }, "id": "bcfcc3ea-bbb3-4346-a5b4-1681d226a40c", "name": "Responder 400", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.4, "position": [ -2272, 640 ] }, { "parameters": { "method": "POST", "url": "https://dbit.digitalcompass.agency/rest/v1/rpc/glm_hub_icon_generation_access", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "apikey", "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" }, { "name": "Authorization", "value": "={{ $('Validar solicitud').first().json.authorization }}" }, { "name": "Content-Type", "value": "application/json" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "{}", "options": { "response": { "response": { "fullResponse": true, "neverError": true, "responseFormat": "json" } }, "timeout": 30000 } }, "id": "bf1ac078-9362-445b-99d4-cd884ba5a8e1", "name": "Validar administrador en Supabase", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ -2272, 384 ] }, { "parameters": { "jsCode": "const source = $input.first()?.json ?? {};\nconst request = $('Validar solicitud').first().json ?? {};\n\nconst statusCode = Number(source.statusCode ?? 200);\n\nlet permission = source.body ?? source;\n\nif (typeof permission === 'string') {\n try {\n permission = JSON.parse(permission);\n } catch {\n permission = {};\n }\n}\n\nif (Array.isArray(permission)) {\n permission = permission[0] ?? {};\n}\n\nif (\n permission &&\n typeof permission === 'object' &&\n permission.authorized === undefined &&\n permission.body !== undefined\n) {\n permission = permission.body;\n\n if (typeof permission === 'string') {\n try {\n permission = JSON.parse(permission);\n } catch {\n permission = {};\n }\n }\n}\n\nconst authorized =\n statusCode >= 200 &&\n statusCode < 300 &&\n (\n permission?.authorized === true ||\n String(permission?.authorized ?? '').toLowerCase() === 'true'\n );\n\nlet error = '';\n\nif (statusCode === 401) {\n error =\n 'La sesión de Supabase expiró. Cierra sesión e inicia nuevamente.';\n} else if (statusCode === 403) {\n error =\n 'Supabase rechazó la validación administrativa.';\n} else if (statusCode >= 400) {\n error =\n String(permission?.message ?? permission?.error ?? '') ||\n `Supabase respondió con el código ${statusCode}.`;\n} else if (!authorized) {\n error =\n 'Tu sesión no tiene permisos de administrador para generar íconos.';\n}\n\nreturn [\n {\n json: {\n authorized,\n error,\n name: String(request.name ?? ''),\n description: String(request.description ?? ''),\n email: String(permission?.email ?? ''),\n userId: String(permission?.userId ?? ''),\n supabaseStatus: statusCode\n }\n }\n];" }, "id": "0f6af309-436b-49df-8a1b-2120a0290474", "name": "Confirmar autorización", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ -2048, 384 ] }, { "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict", "version": 2 }, "conditions": [ { "id": "c9275da4-0bca-4ce9-bd75-cc7d06e4cf56", "leftValue": "={{ $json.authorized }}", "rightValue": true, "operator": { "type": "boolean", "operation": "true", "singleValue": true } } ], "combinator": "and" }, "options": {} }, "id": "c115098c-9289-46ad-902b-d79aa8168bc0", "name": "¿Es administrador?", "type": "n8n-nodes-base.if", "typeVersion": 2.2, "position": [ -1840, 384 ] }, { "parameters": { "respondWith": "json", "responseBody": "={{ { ok: false, error: $json.error } }}", "options": { "responseCode": 403, "responseHeaders": { "entries": [ { "name": "Cache-Control", "value": "no-store" } ] } } }, "id": "c44dee89-da47-43d0-9134-a723f80f7e39", "name": "Responder 403", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.4, "position": [ -1600, 560 ] }, { "parameters": { "jsCode": "const { name, description } = $input.first().json;\nconst prompt = `Crea un ícono cuadrado 1:1, profesional, minimalista y fácil de reconocer para una aplicación interna de GomezLee Marketing.\n\nNombre de la aplicación: ${name}\nDescripción funcional: ${description}\n\nRequisitos visuales obligatorios:\n- Representa la función principal con un único símbolo simple, claro y reconocible.\n- Estética corporativa moderna, limpia y tecnológica.\n- Paleta inspirada en GLM: azul grisáceo, verde claro y verde azulado.\n- Fondo blanco o transparente.\n- Composición centrada, con buen espacio de respiración.\n- Sin texto, sin letras, sin siglas, sin números, sin marcas comerciales y sin logotipos existentes.\n- Sin mockups, sin fotografías, sin personas, sin sombras exageradas y sin fondos complejos.\n- Debe seguir siendo legible al reducirse a 32 x 32 píxeles.\n- Entrega solamente el ícono final.`;\nreturn [{ json: { prompt } }];" }, "id": "4a092f12-4966-4d3e-ba45-f82626f8aff8", "name": "Construir prompt del ícono", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ -1600, 272 ] }, { "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.prompt }}", "options": { "binaryPropertyOutput": "data" } }, "id": "0daf0a06-a280-4500-95f6-f76b8945ed63", "name": "Generate an image", "type": "@n8n/n8n-nodes-langchain.googleGemini", "typeVersion": 1.2, "position": [ -1360, 272 ], "credentials": { "googlePalmApi": { "id": "jvsXYwL6IOoY2DBU", "name": "Isaac - Gemini Api Pago" } }, "onError": "continueErrorOutput" }, { "parameters": { "respondWith": "binary", "responseDataSource": "set", "options": { "responseCode": 200, "responseHeaders": { "entries": [ { "name": "Cache-Control", "value": "no-store" }, { "name": "Content-Disposition", "value": "inline; filename=\"glm-hub-icon.png\"" }, { "name": "Content-Type", "value": "image/png" }, { "name": "Cache-Control", "value": "no-store" } ] } } }, "id": "8594ec32-5d88-4435-aa8f-7d95d819eada", "name": "Responder con ícono", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.4, "position": [ -1072, 192 ] }, { "parameters": { "jsCode": "const input = $input.first().json ?? {};\nconst rawError = input.error ?? input.message ?? input.description ?? input;\nlet message = 'Gemini no pudo generar el ícono. Revisa la credencial, el modelo y la cuota disponible.';\n\nif (typeof rawError === 'string' && rawError.trim()) {\n message = rawError.trim();\n} else if (rawError && typeof rawError === 'object') {\n message = String(rawError.message ?? rawError.description ?? rawError.status ?? message);\n}\n\nreturn [{ json: { ok: false, error: message } }];" }, "id": "ef98ab6b-3341-441b-83bc-41eabfe1d839", "name": "Preparar error de Gemini", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ -1072, 384 ] }, { "parameters": { "respondWith": "json", "responseBody": "={{ { ok: false, error: $json.error } }}", "options": { "responseCode": 502, "responseHeaders": { "entries": [ { "name": "Cache-Control", "value": "no-store" } ] } } }, "id": "273ca42a-ef45-426d-a5c1-e4a3f9ea704d", "name": "Responder error de Gemini", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.4, "position": [ -832, 384 ] } ], "connections": { "Webhook - Generar ícono": { "main": [ [ { "node": "Validar solicitud", "type": "main", "index": 0 } ] ] }, "Validar solicitud": { "main": [ [ { "node": "¿Solicitud válida?", "type": "main", "index": 0 } ] ] }, "¿Solicitud válida?": { "main": [ [ { "node": "Validar administrador en Supabase", "type": "main", "index": 0 } ], [ { "node": "Responder 400", "type": "main", "index": 0 } ] ] }, "Validar administrador en Supabase": { "main": [ [ { "node": "Confirmar autorización", "type": "main", "index": 0 } ] ] }, "Confirmar autorización": { "main": [ [ { "node": "¿Es administrador?", "type": "main", "index": 0 } ] ] }, "¿Es administrador?": { "main": [ [ { "node": "Construir prompt del ícono", "type": "main", "index": 0 } ], [ { "node": "Responder 403", "type": "main", "index": 0 } ] ] }, "Construir prompt del ícono": { "main": [ [ { "node": "Generate an image", "type": "main", "index": 0 } ] ] }, "Generate an image": { "main": [ [ { "node": "Responder con ícono", "type": "main", "index": 0 } ], [ { "node": "Preparar error de Gemini", "type": "main", "index": 0 } ] ] }, "Preparar error de Gemini": { "main": [ [ { "node": "Responder error de Gemini", "type": "main", "index": 0 } ] ] } }, "settings": { "executionOrder": "v1", "binaryMode": "separate", "availableInMCP": true }, "staticData": null, "meta": { "templateCredsSetupCompleted": true }, "versionId": "ce03fd5f-2d70-44f1-b1e2-b31fc92ddf62", "activeVersionId": "ce03fd5f-2d70-44f1-b1e2-b31fc92ddf62", "versionCounter": 75, "triggerCount": 1, "shared": [ { "updatedAt": "2026-07-28T16:18:07.831Z", "createdAt": "2026-07-28T16:18:07.831Z", "role": "workflow:owner", "workflowId": "F2rMlVS9mBypNNn7", "projectId": "PJpTANzTXIFibWsW", "project": { "updatedAt": "2026-04-22T14:25:09.686Z", "createdAt": "2026-04-22T14:22:54.790Z", "id": "PJpTANzTXIFibWsW", "name": "Isaac Aracena ", "type": "personal", "icon": null, "description": null, "creatorId": "0a88c0b1-928e-4412-896e-c5d1c99b2029" } } ], "tags": [], "activeVersion": { "updatedAt": "2026-07-28T20:24:18.000Z", "createdAt": "2026-07-28T20:23:55.454Z", "versionId": "ce03fd5f-2d70-44f1-b1e2-b31fc92ddf62", "workflowId": "F2rMlVS9mBypNNn7", "nodes": [ { "parameters": { "httpMethod": "POST", "path": "glm-hub-generar-icono", "responseMode": "responseNode", "options": { "allowedOrigins": "*" } }, "id": "e9002643-523d-436d-8c57-3d37f80f7ec3", "name": "Webhook - Generar ícono", "type": "n8n-nodes-base.webhook", "typeVersion": 2.1, "position": [ -2992, 464 ], "webhookId": "bc20a398-5ecf-42a2-9d17-9396aa278708" }, { "parameters": { "jsCode": "const request = $input.first().json ?? {};\nconst rawBody = request.body ?? request;\nlet body = rawBody;\n\nif (typeof rawBody === 'string') {\n try {\n body = JSON.parse(rawBody);\n } catch {\n body = {};\n }\n}\n\nconst headers = request.headers ?? {};\nconst headerAuthorization = String(headers.authorization ?? headers.Authorization ?? '').trim();\nconst accessToken = String(body.accessToken ?? '').trim();\nconst authorization = headerAuthorization.toLowerCase().startsWith('bearer ')\n ? headerAuthorization\n : accessToken\n ? `Bearer ${accessToken}`\n : '';\nconst name = String(body.name ?? '').trim();\nconst description = String(body.description ?? '').trim();\n\nlet error = '';\nif (!authorization.toLowerCase().startsWith('bearer ')) {\n error = 'La sesión de Supabase no fue enviada o no es válida.';\n} else if (name.length < 2 || name.length > 60) {\n error = 'El nombre debe contener entre 2 y 60 caracteres.';\n} else if (!description || description.length > 180) {\n error = 'La descripción debe contener entre 1 y 180 caracteres.';\n}\n\nreturn [{ json: { valid: !error, error, authorization, name, description } }];" }, "id": "f7b0a22e-2651-4479-86c8-25262faa38c4", "name": "Validar solicitud", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ -2736, 464 ] }, { "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict", "version": 2 }, "conditions": [ { "id": "308c498d-7c3f-4414-a21f-571276aee28b", "leftValue": "={{ $json.valid }}", "rightValue": true, "operator": { "type": "boolean", "operation": "true", "singleValue": true } } ], "combinator": "and" }, "options": {} }, "id": "0313d3ca-0439-4c2d-bd34-4da5ef6c3950", "name": "¿Solicitud válida?", "type": "n8n-nodes-base.if", "typeVersion": 2.2, "position": [ -2512, 464 ] }, { "parameters": { "respondWith": "json", "responseBody": "={{ { ok: false, error: $json.error } }}", "options": { "responseCode": 400, "responseHeaders": { "entries": [ { "name": "Cache-Control", "value": "no-store" } ] } } }, "id": "bcfcc3ea-bbb3-4346-a5b4-1681d226a40c", "name": "Responder 400", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.4, "position": [ -2272, 640 ] }, { "parameters": { "method": "POST", "url": "https://dbit.digitalcompass.agency/rest/v1/rpc/glm_hub_icon_generation_access", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "apikey", "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" }, { "name": "Authorization", "value": "={{ $('Validar solicitud').first().json.authorization }}" }, { "name": "Content-Type", "value": "application/json" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "{}", "options": { "response": { "response": { "fullResponse": true, "neverError": true, "responseFormat": "json" } }, "timeout": 30000 } }, "id": "bf1ac078-9362-445b-99d4-cd884ba5a8e1", "name": "Validar administrador en Supabase", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ -2272, 384 ] }, { "parameters": { "jsCode": "const source = $input.first()?.json ?? {};\nconst request = $('Validar solicitud').first().json ?? {};\n\nconst statusCode = Number(source.statusCode ?? 200);\n\nlet permission = source.body ?? source;\n\nif (typeof permission === 'string') {\n try {\n permission = JSON.parse(permission);\n } catch {\n permission = {};\n }\n}\n\nif (Array.isArray(permission)) {\n permission = permission[0] ?? {};\n}\n\nif (\n permission &&\n typeof permission === 'object' &&\n permission.authorized === undefined &&\n permission.body !== undefined\n) {\n permission = permission.body;\n\n if (typeof permission === 'string') {\n try {\n permission = JSON.parse(permission);\n } catch {\n permission = {};\n }\n }\n}\n\nconst authorized =\n statusCode >= 200 &&\n statusCode < 300 &&\n (\n permission?.authorized === true ||\n String(permission?.authorized ?? '').toLowerCase() === 'true'\n );\n\nlet error = '';\n\nif (statusCode === 401) {\n error =\n 'La sesión de Supabase expiró. Cierra sesión e inicia nuevamente.';\n} else if (statusCode === 403) {\n error =\n 'Supabase rechazó la validación administrativa.';\n} else if (statusCode >= 400) {\n error =\n String(permission?.message ?? permission?.error ?? '') ||\n `Supabase respondió con el código ${statusCode}.`;\n} else if (!authorized) {\n error =\n 'Tu sesión no tiene permisos de administrador para generar íconos.';\n}\n\nreturn [\n {\n json: {\n authorized,\n error,\n name: String(request.name ?? ''),\n description: String(request.description ?? ''),\n email: String(permission?.email ?? ''),\n userId: String(permission?.userId ?? ''),\n supabaseStatus: statusCode\n }\n }\n];" }, "id": "0f6af309-436b-49df-8a1b-2120a0290474", "name": "Confirmar autorización", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ -2048, 384 ] }, { "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict", "version": 2 }, "conditions": [ { "id": "c9275da4-0bca-4ce9-bd75-cc7d06e4cf56", "leftValue": "={{ $json.authorized }}", "rightValue": true, "operator": { "type": "boolean", "operation": "true", "singleValue": true } } ], "combinator": "and" }, "options": {} }, "id": "c115098c-9289-46ad-902b-d79aa8168bc0", "name": "¿Es administrador?", "type": "n8n-nodes-base.if", "typeVersion": 2.2, "position": [ -1840, 384 ] }, { "parameters": { "respondWith": "json", "responseBody": "={{ { ok: false, error: $json.error } }}", "options": { "responseCode": 403, "responseHeaders": { "entries": [ { "name": "Cache-Control", "value": "no-store" } ] } } }, "id": "c44dee89-da47-43d0-9134-a723f80f7e39", "name": "Responder 403", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.4, "position": [ -1600, 560 ] }, { "parameters": { "jsCode": "const { name, description } = $input.first().json;\nconst prompt = `Crea un ícono cuadrado 1:1, profesional, minimalista y fácil de reconocer para una aplicación interna de GomezLee Marketing.\n\nNombre de la aplicación: ${name}\nDescripción funcional: ${description}\n\nRequisitos visuales obligatorios:\n- Representa la función principal con un único símbolo simple, claro y reconocible.\n- Estética corporativa moderna, limpia y tecnológica.\n- Paleta inspirada en GLM: azul grisáceo, verde claro y verde azulado.\n- Fondo blanco o transparente.\n- Composición centrada, con buen espacio de respiración.\n- Sin texto, sin letras, sin siglas, sin números, sin marcas comerciales y sin logotipos existentes.\n- Sin mockups, sin fotografías, sin personas, sin sombras exageradas y sin fondos complejos.\n- Debe seguir siendo legible al reducirse a 32 x 32 píxeles.\n- Entrega solamente el ícono final.`;\nreturn [{ json: { prompt } }];" }, "id": "4a092f12-4966-4d3e-ba45-f82626f8aff8", "name": "Construir prompt del ícono", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ -1600, 272 ] }, { "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.prompt }}", "options": { "binaryPropertyOutput": "data" } }, "id": "0daf0a06-a280-4500-95f6-f76b8945ed63", "name": "Generate an image", "type": "@n8n/n8n-nodes-langchain.googleGemini", "typeVersion": 1.2, "position": [ -1360, 272 ], "credentials": { "googlePalmApi": { "id": "jvsXYwL6IOoY2DBU", "name": "Isaac - Gemini Api Pago" } }, "onError": "continueErrorOutput" }, { "parameters": { "respondWith": "binary", "responseDataSource": "set", "options": { "responseCode": 200, "responseHeaders": { "entries": [ { "name": "Cache-Control", "value": "no-store" }, { "name": "Content-Disposition", "value": "inline; filename=\"glm-hub-icon.png\"" }, { "name": "Content-Type", "value": "image/png" }, { "name": "Cache-Control", "value": "no-store" } ] } } }, "id": "8594ec32-5d88-4435-aa8f-7d95d819eada", "name": "Responder con ícono", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.4, "position": [ -1072, 192 ] }, { "parameters": { "jsCode": "const input = $input.first().json ?? {};\nconst rawError = input.error ?? input.message ?? input.description ?? input;\nlet message = 'Gemini no pudo generar el ícono. Revisa la credencial, el modelo y la cuota disponible.';\n\nif (typeof rawError === 'string' && rawError.trim()) {\n message = rawError.trim();\n} else if (rawError && typeof rawError === 'object') {\n message = String(rawError.message ?? rawError.description ?? rawError.status ?? message);\n}\n\nreturn [{ json: { ok: false, error: message } }];" }, "id": "ef98ab6b-3341-441b-83bc-41eabfe1d839", "name": "Preparar error de Gemini", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ -1072, 384 ] }, { "parameters": { "respondWith": "json", "responseBody": "={{ { ok: false, error: $json.error } }}", "options": { "responseCode": 502, "responseHeaders": { "entries": [ { "name": "Cache-Control", "value": "no-store" } ] } } }, "id": "273ca42a-ef45-426d-a5c1-e4a3f9ea704d", "name": "Responder error de Gemini", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.4, "position": [ -832, 384 ] } ], "connections": { "Webhook - Generar ícono": { "main": [ [ { "node": "Validar solicitud", "type": "main", "index": 0 } ] ] }, "Validar solicitud": { "main": [ [ { "node": "¿Solicitud válida?", "type": "main", "index": 0 } ] ] }, "¿Solicitud válida?": { "main": [ [ { "node": "Validar administrador en Supabase", "type": "main", "index": 0 } ], [ { "node": "Responder 400", "type": "main", "index": 0 } ] ] }, "Validar administrador en Supabase": { "main": [ [ { "node": "Confirmar autorización", "type": "main", "index": 0 } ] ] }, "Confirmar autorización": { "main": [ [ { "node": "¿Es administrador?", "type": "main", "index": 0 } ] ] }, "¿Es administrador?": { "main": [ [ { "node": "Construir prompt del ícono", "type": "main", "index": 0 } ], [ { "node": "Responder 403", "type": "main", "index": 0 } ] ] }, "Construir prompt del ícono": { "main": [ [ { "node": "Generate an image", "type": "main", "index": 0 } ] ] }, "Generate an image": { "main": [ [ { "node": "Responder con ícono", "type": "main", "index": 0 } ], [ { "node": "Preparar error de Gemini", "type": "main", "index": 0 } ] ] }, "Preparar error de Gemini": { "main": [ [ { "node": "Responder error de Gemini", "type": "main", "index": 0 } ] ] } }, "authors": "Isaac Aracena", "name": "Version ce03fd5f", "description": "", "autosaved": true, "workflowPublishHistory": [ { "createdAt": "2026-07-28T20:24:18.060Z", "id": 3595, "workflowId": "F2rMlVS9mBypNNn7", "versionId": "ce03fd5f-2d70-44f1-b1e2-b31fc92ddf62", "event": "activated", "userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029" } ] } }