feat: versión inicial de GLM Hub
This commit is contained in:
@@ -0,0 +1,464 @@
|
||||
{
|
||||
"name": "GLM Hub - Generar ícono con Gemini (Nodo nativo)",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {
|
||||
"httpMethod": "POST",
|
||||
"path": "glm-hub-generar-icono",
|
||||
"responseMode": "responseNode",
|
||||
"options": {
|
||||
"allowedOrigins": "*"
|
||||
}
|
||||
},
|
||||
"id": "47ec047e-250d-4056-a2af-2bb6c5f072b0",
|
||||
"name": "Webhook - Generar ícono",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"typeVersion": 2.1,
|
||||
"position": [
|
||||
-1120,
|
||||
0
|
||||
],
|
||||
"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": "934fb8be-c5bc-43bd-b44a-53f9db105b32",
|
||||
"name": "Validar solicitud",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
-860,
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"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": "3344b885-db2b-473d-a444-a51ca00d063d",
|
||||
"name": "¿Solicitud válida?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 2.2,
|
||||
"position": [
|
||||
-640,
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "={{ { ok: false, error: $json.error } }}",
|
||||
"options": {
|
||||
"responseCode": 400,
|
||||
"responseHeaders": {
|
||||
"entries": [
|
||||
{
|
||||
"name": "Cache-Control",
|
||||
"value": "no-store"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "af555c88-6ec6-4e0f-9d01-64b6cb16a5c5",
|
||||
"name": "Responder 400",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1.4,
|
||||
"position": [
|
||||
-400,
|
||||
180
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"method": "POST",
|
||||
"url": "={{ ($env.SUPABASE_URL || '').replace(/\\/$/, '') + '/rest/v1/rpc/glm_hub_icon_generation_access' }}",
|
||||
"sendHeaders": true,
|
||||
"headerParameters": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "apikey",
|
||||
"value": "={{ $env.SUPABASE_ANON_KEY }}"
|
||||
},
|
||||
{
|
||||
"name": "Authorization",
|
||||
"value": "={{ $('Validar solicitud').item.json.authorization }}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sendBody": true,
|
||||
"contentType": "raw",
|
||||
"rawContentType": "application/json",
|
||||
"body": "{}",
|
||||
"options": {
|
||||
"response": {
|
||||
"response": {
|
||||
"neverError": true,
|
||||
"responseFormat": "json"
|
||||
}
|
||||
},
|
||||
"timeout": 30000
|
||||
}
|
||||
},
|
||||
"id": "42ba23d6-9f3a-4b67-ae48-8253adfb7110",
|
||||
"name": "Validar administrador en Supabase",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"typeVersion": 4.2,
|
||||
"position": [
|
||||
-400,
|
||||
-80
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "const permission = $input.first().json ?? {};\nconst request = $('Validar solicitud').first().json;\nconst authorized = permission.authorized === true;\nreturn [{\n json: {\n authorized,\n error: authorized ? '' : 'Tu sesión no tiene permisos de administrador para generar íconos.',\n name: request.name,\n description: request.description,\n email: String(permission.email ?? '')\n }\n}];"
|
||||
},
|
||||
"id": "489c0999-9ca3-4361-8262-18404f5aad35",
|
||||
"name": "Confirmar autorización",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
-180,
|
||||
-80
|
||||
]
|
||||
},
|
||||
{
|
||||
"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": "7c199474-f2b6-4c1c-873d-e578d1f7d500",
|
||||
"name": "¿Es administrador?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"typeVersion": 2.2,
|
||||
"position": [
|
||||
40,
|
||||
-80
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "={{ { ok: false, error: $json.error } }}",
|
||||
"options": {
|
||||
"responseCode": 403,
|
||||
"responseHeaders": {
|
||||
"entries": [
|
||||
{
|
||||
"name": "Cache-Control",
|
||||
"value": "no-store"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "1b105633-29f8-4e75-bead-d3022420dfed",
|
||||
"name": "Responder 403",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1.4,
|
||||
"position": [
|
||||
280,
|
||||
100
|
||||
]
|
||||
},
|
||||
{
|
||||
"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": "1ae24908-c67d-4742-917e-573b69f4ca19",
|
||||
"name": "Construir prompt del ícono",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
280,
|
||||
-180
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"resource": "image",
|
||||
"operation": "generate",
|
||||
"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": "bdeed7c1-71ba-4af4-9424-b248c06c9e75",
|
||||
"name": "Generate an image",
|
||||
"type": "@n8n/n8n-nodes-langchain.googleGemini",
|
||||
"typeVersion": 1.2,
|
||||
"position": [
|
||||
520,
|
||||
-180
|
||||
],
|
||||
"onError": "continueErrorOutput"
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "binary",
|
||||
"responseDataSource": "set",
|
||||
"inputFieldName": "data",
|
||||
"options": {
|
||||
"responseCode": 200,
|
||||
"responseHeaders": {
|
||||
"entries": [
|
||||
{
|
||||
"name": "Cache-Control",
|
||||
"value": "no-store"
|
||||
},
|
||||
{
|
||||
"name": "Content-Disposition",
|
||||
"value": "inline; filename=\"glm-hub-icon.png\""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "7349fabd-6d25-48b1-94be-64e36eef5f7e",
|
||||
"name": "Responder con ícono",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1.4,
|
||||
"position": [
|
||||
800,
|
||||
-260
|
||||
]
|
||||
},
|
||||
{
|
||||
"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": "fc7b61a0-fb00-42a4-bc4a-2e530da36a12",
|
||||
"name": "Preparar error de Gemini",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
800,
|
||||
-80
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"respondWith": "json",
|
||||
"responseBody": "={{ { ok: false, error: $json.error } }}",
|
||||
"options": {
|
||||
"responseCode": 502,
|
||||
"responseHeaders": {
|
||||
"entries": [
|
||||
{
|
||||
"name": "Cache-Control",
|
||||
"value": "no-store"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "c0bc7fee-a55e-4f40-90b5-f875c41b131c",
|
||||
"name": "Responder error de Gemini",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"typeVersion": 1.4,
|
||||
"position": [
|
||||
1040,
|
||||
-80
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"content": "## CONFIGURACIÓN ÚNICA\n\nEn el nodo **Generate an image**, confirma la credencial existente **Isaac - Gemini Api Pago** después de importar.\n\nEl webhook devuelve la imagen directamente como archivo binario al GLM Hub.",
|
||||
"height": 220,
|
||||
"width": 380,
|
||||
"color": 5
|
||||
},
|
||||
"id": "fd8a87b4-3924-412b-8d3d-b7707bf6388b",
|
||||
"name": "Nota de configuración",
|
||||
"type": "n8n-nodes-base.stickyNote",
|
||||
"typeVersion": 1,
|
||||
"position": [
|
||||
420,
|
||||
100
|
||||
]
|
||||
}
|
||||
],
|
||||
"pinData": {},
|
||||
"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
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1",
|
||||
"saveManualExecutions": true,
|
||||
"callerPolicy": "workflowsFromSameOwner"
|
||||
},
|
||||
"versionId": "ae79a50a-79d1-43f8-b856-b4106bae3e60",
|
||||
"meta": {
|
||||
"templateCredsSetupCompleted": false
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
Reference in New Issue
Block a user