Files
glm-hub-generar-icono-con-g…/glm-hub-generar-icono-con-gemini.json
T

960 lines
32 KiB
JSON

{
"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 <iaracena@gomezleemarketing.com>",
"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"
}
]
}
}