1531 lines
57 KiB
JSON
1531 lines
57 KiB
JSON
{
|
|
"updatedAt": "2026-07-25T17:12:49.910Z",
|
|
"createdAt": "2026-06-05T14:36:49.343Z",
|
|
"id": "jtJGuwijffvHznH2",
|
|
"name": "Gitea n8n Auto Backup",
|
|
"description": "Realiza respaldos automáticos de los workflows de n8n en Gitea, creando o actualizando el repositorio correspondiente con el archivo workflow.json y su documentación.",
|
|
"active": true,
|
|
"isArchived": false,
|
|
"nodes": [
|
|
{
|
|
"parameters": {},
|
|
"type": "n8n-nodes-base.manualTrigger",
|
|
"typeVersion": 1,
|
|
"position": [
|
|
-16,
|
|
416
|
|
],
|
|
"id": "8b02b163-b1b9-4715-a426-3c07f15afd96",
|
|
"name": "Manual - Ejecutar respaldo ahora"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"assignments": {
|
|
"assignments": [
|
|
{
|
|
"id": "463e6c6e-40ee-46ff-b30f-3a612f21af4a",
|
|
"name": "n8n_base_url",
|
|
"value": "https://agenteit.digitalcompass.agency",
|
|
"type": "string"
|
|
},
|
|
{
|
|
"id": "73de7608-d7ca-4893-babc-5c59552bbd25",
|
|
"name": "gitea_base_url",
|
|
"value": "https://git.digitalcompass.agency",
|
|
"type": "string"
|
|
},
|
|
{
|
|
"id": "83967bc3-16a0-4afc-9bd1-2325d759395a",
|
|
"name": "gitea_owner",
|
|
"value": "Isaac_Aracena",
|
|
"type": "string"
|
|
},
|
|
{
|
|
"id": "b62d61e7-9688-4ebe-bf0e-c40d38c84ffc",
|
|
"name": "owner_type",
|
|
"value": "user",
|
|
"type": "string"
|
|
},
|
|
{
|
|
"id": "f4443432-6bda-4b9b-9b86-c62158fb201f",
|
|
"name": "default_branch",
|
|
"value": "main",
|
|
"type": "string"
|
|
},
|
|
{
|
|
"id": "a6681aaf-eccc-42e6-95b9-d1926cff2fab",
|
|
"name": "private_repo",
|
|
"value": false,
|
|
"type": "boolean"
|
|
},
|
|
{
|
|
"id": "1501bda6-ee9b-4633-979a-46176c853ce4",
|
|
"name": "force_full_backup",
|
|
"value": false,
|
|
"type": "boolean"
|
|
},
|
|
{
|
|
"id": "859f8c57-9a61-4d81-8e1d-74e2767d60d3",
|
|
"name": "only_published_workflows",
|
|
"value": true,
|
|
"type": "boolean"
|
|
},
|
|
{
|
|
"id": "ce4d20a9-5f5c-45c4-80dc-63e628ccdcbc",
|
|
"name": "ignore_workflow_ids_csv",
|
|
"value": "",
|
|
"type": "string"
|
|
}
|
|
]
|
|
},
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.set",
|
|
"typeVersion": 3.4,
|
|
"position": [
|
|
256,
|
|
512
|
|
],
|
|
"id": "fb75c274-8db3-4ad3-8903-74f2dbcc99ec",
|
|
"name": "Config"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"url": "={{ $json.n8n_base_url.replace(/\\/$/, '') + '/api/v1/workflows?limit=250' }}",
|
|
"authentication": "genericCredentialType",
|
|
"genericAuthType": "httpHeaderAuth",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
512,
|
|
512
|
|
],
|
|
"id": "13b905b8-ffa8-4020-a02f-b5db5d78d99b",
|
|
"name": "n8n - Listar workflows",
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "UPDlAh0YeGhLTTiE",
|
|
"name": "Header Auth account 2"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"jsCode": "const cfg = $('Config').first().json;\nconst response = $input.first().json;\n\n// La API pública de n8n normalmente devuelve { data: [...], nextCursor: ... }.\n// Dejamos fallback por si la instancia devuelve un array directo.\nconst workflows = Array.isArray(response.data)\n ? response.data\n : (Array.isArray(response) ? response : []);\n\nif (!workflows.length) {\n throw new Error('No recibí workflows desde la API de n8n. Revisa n8n_base_url, credencial X-N8N-API-KEY y endpoint /api/v1/workflows.');\n}\n\nconst staticData = $getWorkflowStaticData('global');\nstaticData.backedUpWorkflows = staticData.backedUpWorkflows || {};\n\nconst forceAll = cfg.force_full_backup === true || String(cfg.force_full_backup).toLowerCase() === 'true';\nconst onlyPublished = cfg.only_published_workflows === true || String(cfg.only_published_workflows).toLowerCase() === 'true';\nconst ignored = String(cfg.ignore_workflow_ids_csv || '')\n .split(',')\n .map(v => v.trim())\n .filter(Boolean);\n\nconst out = [];\n\nfor (const wf of workflows) {\n const id = String(wf.id || wf.workflowId || '');\n if (!id) continue;\n if (ignored.includes(id)) continue;\n\n // En n8n la lista suele traer active=true para workflows publicados/activos.\n // Si tu instancia usa otro campo, dejamos varios fallbacks comunes.\n const isPublished = wf.active === true || wf.isActive === true || wf.published === true || String(wf.active).toLowerCase() === 'true';\n if (onlyPublished && !isPublished) continue;\n\n const updatedAt = String(wf.updatedAt || wf.updated_at || wf.versionId || wf.version_id || '');\n const previousUpdatedAt = staticData.backedUpWorkflows[id]?.updatedAt;\n\n // Primera ejecución: respalda todos los publicados detectados.\n // Luego: solo workflows publicados nuevos o modificados.\n if (forceAll || !previousUpdatedAt || previousUpdatedAt !== updatedAt) {\n out.push({\n json: {\n ...cfg,\n workflow_id: id,\n workflow_name_hint: wf.name || `workflow-${id}`,\n workflow_updated_at: updatedAt,\n workflow_published: isPublished,\n detected_at: new Date().toISOString(),\n }\n });\n }\n}\n\nreturn out;"
|
|
},
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
768,
|
|
512
|
|
],
|
|
"id": "bb3bd9fe-8c31-43bf-8ed2-988e9df69c8a",
|
|
"name": "Filtrar workflows nuevos o modificados"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"url": "={{ $json.n8n_base_url.replace(/\\/$/, '') + '/api/v1/workflows/' + $json.workflow_id }}",
|
|
"authentication": "genericCredentialType",
|
|
"genericAuthType": "httpHeaderAuth",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
1024,
|
|
512
|
|
],
|
|
"id": "2425a188-773c-4776-9e05-8b7d1af59c2b",
|
|
"name": "n8n - Obtener workflow completo",
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "UPDlAh0YeGhLTTiE",
|
|
"name": "Header Auth account 2"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"mode": "runOnceForEachItem",
|
|
"jsCode": "const cfg = $('Filtrar workflows nuevos o modificados').item.json;\nconst workflow = $input.item.json;\n\nfunction slugifyForRepo(value) {\n return String(value || '')\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase()\n .replace(/ñ/g, 'n')\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .replace(/-{2,}/g, '-')\n .slice(0, 90) || 'workflow-sin-nombre';\n}\n\nconst workflowName = workflow.name || cfg.workflow_name_hint || `workflow-${cfg.workflow_id}`;\nconst workflowId = String(workflow.id || cfg.workflow_id);\nconst repoName = slugifyForRepo(workflowName);\nconst filePath = `${repoName}.json`;\nconst branch = cfg.default_branch || 'main';\n\nconst exportWorkflow = {\n ...workflow,\n};\n\n// Evita guardar datos de prueba pesados si vienen en la respuesta.\ndelete exportWorkflow.pinData;\n\nconst content = Buffer.from(\n JSON.stringify(exportWorkflow, null, 2),\n 'utf8'\n).toString('base64');\n\nreturn {\n json: {\n ...cfg,\n workflow_id: workflowId,\n workflow_name: workflowName,\n repo_name: repoName,\n file_path: filePath,\n branch,\n repo_description: `Backup público automático del workflow n8n: ${workflowName}`,\n content,\n commit_create_message: `Create backup: ${workflowName}`,\n commit_update_message: `Update backup: ${workflowName}`,\n }\n};"
|
|
},
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
1344,
|
|
432
|
|
],
|
|
"id": "75ce5ba0-c1ea-4a22-8e15-648d82e6e827",
|
|
"name": "Preparar repo y archivo"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"url": "={{ $json.gitea_base_url.replace(/\\/$/, '') + '/api/v1/repos/' + $json.gitea_owner + '/' + $json.repo_name }}",
|
|
"authentication": "genericCredentialType",
|
|
"genericAuthType": "httpHeaderAuth",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
1968,
|
|
432
|
|
],
|
|
"id": "a221abfd-0ce0-4c7c-86eb-f9e9314f940d",
|
|
"name": "Gitea - Verificar repo",
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "goGJ7p07L5ygli0D",
|
|
"name": "Header Auth account"
|
|
}
|
|
},
|
|
"onError": "continueErrorOutput"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"method": "POST",
|
|
"url": "={{ $('Loop Over Items').item.json.gitea_base_url.replace(/\\/$/, '') + ($('Loop Over Items').item.json.owner_type === 'org' ? '/api/v1/orgs/' + $('Loop Over Items').item.json.gitea_owner + '/repos' : '/api/v1/user/repos') }}",
|
|
"authentication": "genericCredentialType",
|
|
"genericAuthType": "httpHeaderAuth",
|
|
"sendBody": true,
|
|
"specifyBody": "json",
|
|
"jsonBody": "={{ { name: $('Loop Over Items').item.json.repo_name, description: $('Loop Over Items').item.json.repo_description, private: false, auto_init: true, default_branch: $('Loop Over Items').item.json.branch } }}",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
2224,
|
|
624
|
|
],
|
|
"id": "26e851db-95d6-4756-852c-ffa29bf9ed0a",
|
|
"name": "Gitea - Crear repo público si no existe",
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "goGJ7p07L5ygli0D",
|
|
"name": "Header Auth account"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"url": "={{ $('Loop Over Items').item.json.gitea_base_url.replace(/\\/$/, '') + '/api/v1/repos/' + $('Loop Over Items').item.json.gitea_owner + '/' + $('Loop Over Items').item.json.repo_name + '/contents/' + $('Loop Over Items').item.json.file_path }}",
|
|
"authentication": "genericCredentialType",
|
|
"genericAuthType": "httpHeaderAuth",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
2480,
|
|
432
|
|
],
|
|
"id": "bed90785-6c35-4d38-8942-f644fa8b655b",
|
|
"name": "Gitea - Verificar archivo",
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "goGJ7p07L5ygli0D",
|
|
"name": "Header Auth account"
|
|
}
|
|
},
|
|
"onError": "continueErrorOutput"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"method": "PUT",
|
|
"url": "={{ $('Loop Over Items').item.json.gitea_base_url.replace(/\\/$/, '') + '/api/v1/repos/' + $('Loop Over Items').item.json.gitea_owner + '/' + $('Loop Over Items').item.json.repo_name + '/contents/' + $('Loop Over Items').item.json.file_path }}",
|
|
"authentication": "genericCredentialType",
|
|
"genericAuthType": "httpHeaderAuth",
|
|
"sendBody": true,
|
|
"specifyBody": "json",
|
|
"jsonBody": "={{ { message: $('Loop Over Items').item.json.commit_update_message, content: $('Loop Over Items').item.json.content, sha: $json.sha, branch: $('Loop Over Items').item.json.branch } }}",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
2768,
|
|
320
|
|
],
|
|
"id": "fac285a6-2e37-4043-8127-d534c78aa607",
|
|
"name": "Gitea - Actualizar workflow.json",
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "goGJ7p07L5ygli0D",
|
|
"name": "Header Auth account"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"method": "POST",
|
|
"url": "={{ $('Loop Over Items').item.json.gitea_base_url.replace(/\\/$/, '') + '/api/v1/repos/' + $('Loop Over Items').item.json.gitea_owner + '/' + $('Loop Over Items').item.json.repo_name + '/contents/' + $('Loop Over Items').item.json.file_path }}",
|
|
"authentication": "genericCredentialType",
|
|
"genericAuthType": "httpHeaderAuth",
|
|
"sendBody": true,
|
|
"specifyBody": "json",
|
|
"jsonBody": "={{ { message: $('Loop Over Items').item.json.commit_create_message, content: $('Loop Over Items').item.json.content, branch: $('Loop Over Items').item.json.branch } }}",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
2768,
|
|
624
|
|
],
|
|
"id": "a76819e9-ba84-40d9-8799-ffe86cf0f53f",
|
|
"name": "Gitea - Crear workflow.json",
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "goGJ7p07L5ygli0D",
|
|
"name": "Header Auth account"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"mode": "runOnceForEachItem",
|
|
"jsCode": "const data = $('Loop Over Items').item.json;\n\nconst staticData = $getWorkflowStaticData('global');\nstaticData.backedUpWorkflows = staticData.backedUpWorkflows || {};\n\nstaticData.backedUpWorkflows[data.workflow_id] = {\n name: data.workflow_name,\n repo_name: data.repo_name,\n file_path: data.file_path,\n updatedAt: data.workflow_updated_at || '',\n backedUpAt: new Date().toISOString(),\n};\n\nreturn {\n json: {\n ok: true,\n workflow_id: data.workflow_id,\n workflow_name: data.workflow_name,\n repo_name: data.repo_name,\n file_path: data.file_path,\n repo_public: true,\n backedUpAt: new Date().toISOString(),\n }\n};"
|
|
},
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
3040,
|
|
464
|
|
],
|
|
"id": "6b48a9df-89ef-4a8a-a6ff-2c7cfa789b51",
|
|
"name": "Marcar respaldado"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.splitInBatches",
|
|
"typeVersion": 3,
|
|
"position": [
|
|
1696,
|
|
432
|
|
],
|
|
"id": "1e618c0d-2b6d-4f69-9b63-300c222004e8",
|
|
"name": "Loop Over Items"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"method": "PATCH",
|
|
"url": "={{ $('Loop Over Items').item.json.gitea_base_url.replace(/\\/$/, '') + '/api/v1/repos/' + $('Loop Over Items').item.json.gitea_owner + '/' + $('Loop Over Items').item.json.repo_name }}",
|
|
"authentication": "genericCredentialType",
|
|
"genericAuthType": "httpHeaderAuth",
|
|
"sendBody": true,
|
|
"specifyBody": "json",
|
|
"jsonBody": "={{ { private: false } }}",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
2224,
|
|
336
|
|
],
|
|
"id": "bcaa9c9b-bd82-4dc9-aa6f-e8b4391d26a8",
|
|
"name": "Gitea - Asegurar repo público",
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "goGJ7p07L5ygli0D",
|
|
"name": "Header Auth account"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"content": "## ✅ Backup automático y ⚙️ Configuración\n\nEste workflow revisa n8n cada 1 minuto.\n\nSi un workflow publicado es nuevo o cambió, crea o actualiza su repo en Gitea.\n\n\nEn Config ajustar:\n\n- n8n_base_url\n- gitea_base_url\n- gitea_owner\n- force_full_backup = false\n\nCredenciales:\nn8n → X-N8N-API-KEY\nGitea → Authorization: token",
|
|
"height": 736,
|
|
"width": 1280,
|
|
"color": 6
|
|
},
|
|
"type": "n8n-nodes-base.stickyNote",
|
|
"typeVersion": 1,
|
|
"position": [
|
|
-80,
|
|
80
|
|
],
|
|
"id": "3be54cf0-4c34-4678-ab3e-b6c8ddce9af1",
|
|
"name": "Sticky Note"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"content": "## 🌍 Repos públicos\n\nLos repos nuevos se crean públicos.\n\nSi el repo ya existe, se asegura como público y luego actualiza el archivo .json.",
|
|
"height": 736,
|
|
"width": 1968,
|
|
"color": 4
|
|
},
|
|
"type": "n8n-nodes-base.stickyNote",
|
|
"typeVersion": 1,
|
|
"position": [
|
|
1264,
|
|
80
|
|
],
|
|
"id": "20864b61-de27-46fb-a4c0-175269061f31",
|
|
"name": "Sticky Note2"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"rule": {
|
|
"interval": [
|
|
{
|
|
"field": "weeks"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"type": "n8n-nodes-base.scheduleTrigger",
|
|
"typeVersion": 1.2,
|
|
"position": [
|
|
-16,
|
|
640
|
|
],
|
|
"id": "b5c75588-f5a2-4e04-a567-7c98c1e20d87",
|
|
"name": "Schedule - Revisar publicados cada día"
|
|
}
|
|
],
|
|
"connections": {
|
|
"Manual - Ejecutar respaldo ahora": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Config",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Config": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "n8n - Listar workflows",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"n8n - Listar workflows": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Filtrar workflows nuevos o modificados",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Filtrar workflows nuevos o modificados": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "n8n - Obtener workflow completo",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"n8n - Obtener workflow completo": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Preparar repo y archivo",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Preparar repo y archivo": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Loop Over Items",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Loop Over Items": {
|
|
"main": [
|
|
[],
|
|
[
|
|
{
|
|
"node": "Gitea - Verificar repo",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Gitea - Verificar repo": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Gitea - Asegurar repo público",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"node": "Gitea - Crear repo público si no existe",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Gitea - Asegurar repo público": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Gitea - Verificar archivo",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Gitea - Crear repo público si no existe": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Gitea - Verificar archivo",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Gitea - Verificar archivo": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Gitea - Actualizar workflow.json",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"node": "Gitea - Crear workflow.json",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Gitea - Actualizar workflow.json": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Marcar respaldado",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Gitea - Crear workflow.json": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Marcar respaldado",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Marcar respaldado": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Loop Over Items",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Schedule - Revisar publicados cada día": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Config",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
}
|
|
},
|
|
"settings": {
|
|
"executionOrder": "v1",
|
|
"binaryMode": "separate",
|
|
"availableInMCP": true,
|
|
"timeSavedMode": "fixed",
|
|
"errorWorkflow": "puF4LUczoSz3hcek",
|
|
"timezone": "America/Santo_Domingo",
|
|
"callerPolicy": "workflowsFromSameOwner"
|
|
},
|
|
"staticData": {
|
|
"node:Schedule - Revisar publicados cada 1 min": {
|
|
"recurrenceRules": []
|
|
},
|
|
"global": {
|
|
"backedUpWorkflows": {
|
|
"4eCPQcE3FDIll8bW": {
|
|
"name": "TEST - Telegram - Propuestas Ejecutadas",
|
|
"repo_name": "test-telegram-propuestas-ejecutadas",
|
|
"file_path": "test-telegram-propuestas-ejecutadas.json",
|
|
"updatedAt": "2026-07-16T16:14:53.908Z",
|
|
"backedUpAt": "2026-07-19T04:00:45.196Z"
|
|
},
|
|
"8jCi4gPc5kfHZvk2": {
|
|
"name": "Cruce de Cuentas - GLM",
|
|
"repo_name": "cruce-de-cuentas-glm",
|
|
"file_path": "cruce-de-cuentas-glm.json",
|
|
"updatedAt": "2026-06-25T11:33:29.701Z",
|
|
"backedUpAt": "2026-06-28T04:00:29.274Z"
|
|
},
|
|
"J4EmhOad6NtLHzkA": {
|
|
"name": "Gitea n8n Auto Backup READY - Publicados a Gitea",
|
|
"repo_name": "gitea-n8n-auto-backup-ready-publicados-a-gitea",
|
|
"file_path": "gitea-n8n-auto-backup-ready-publicados-a-gitea.json",
|
|
"updatedAt": "2026-06-05T14:35:59.420Z",
|
|
"backedUpAt": "2026-06-05T14:47:21.527Z"
|
|
},
|
|
"MU5GdxLtFzcRcfyM": {
|
|
"name": "Tablero CDC - Sync Listas",
|
|
"repo_name": "tablero-cdc-sync-listas",
|
|
"file_path": "tablero-cdc-sync-listas.json",
|
|
"updatedAt": "2026-07-18T13:04:19.432Z",
|
|
"backedUpAt": "2026-07-19T04:01:15.243Z"
|
|
},
|
|
"NDHPXi6jzVifyZU1": {
|
|
"name": "Fulgencio Procesar Propuestas en Bruto - GLM",
|
|
"repo_name": "fulgencio-procesar-propuestas-en-bruto-glm",
|
|
"file_path": "fulgencio-procesar-propuestas-en-bruto-glm.json",
|
|
"updatedAt": "2026-07-16T16:19:45.836Z",
|
|
"backedUpAt": "2026-07-19T04:01:17.533Z"
|
|
},
|
|
"UzzVI2AKIXuZGgTL": {
|
|
"name": "Fulgencio Alertas Sheets - GLM",
|
|
"repo_name": "fulgencio-alertas-sheets-glm",
|
|
"file_path": "fulgencio-alertas-sheets-glm.json",
|
|
"updatedAt": "2026-07-16T16:19:25.101Z",
|
|
"backedUpAt": "2026-07-19T04:01:22.393Z"
|
|
},
|
|
"Z8W67i7RfrhXRDFQ": {
|
|
"name": "CDC Brief - GLM V2",
|
|
"repo_name": "cdc-brief-glm-v2",
|
|
"file_path": "cdc-brief-glm-v2.json",
|
|
"updatedAt": "2026-07-18T12:44:16.818Z",
|
|
"backedUpAt": "2026-07-19T04:01:30.652Z"
|
|
},
|
|
"d39DtIUTQzduqX0v": {
|
|
"name": "Tablero CDC - Sync Proyecto a Sheet WEBHOOK",
|
|
"repo_name": "tablero-cdc-sync-proyecto-a-sheet-webhook",
|
|
"file_path": "tablero-cdc-sync-proyecto-a-sheet-webhook.json",
|
|
"updatedAt": "2026-07-16T16:14:01.567Z",
|
|
"backedUpAt": "2026-07-19T04:01:45.261Z"
|
|
},
|
|
"jtJGuwijffvHznH2": {
|
|
"name": "Gitea n8n Auto Backup",
|
|
"repo_name": "gitea-n8n-auto-backup",
|
|
"file_path": "gitea-n8n-auto-backup.json",
|
|
"updatedAt": "2026-07-16T16:16:48.045Z",
|
|
"backedUpAt": "2026-07-19T04:01:56.005Z"
|
|
},
|
|
"puF4LUczoSz3hcek": {
|
|
"name": "Reportar Error - Isaac",
|
|
"repo_name": "reportar-error-isaac",
|
|
"file_path": "reportar-error-isaac.json",
|
|
"updatedAt": "2026-07-17T23:10:33.237Z",
|
|
"backedUpAt": "2026-07-19T04:02:00.965Z"
|
|
},
|
|
"t6lFUulNtDIR3tAm": {
|
|
"name": "Chat de WhatsApp de propuestas ejecutadas",
|
|
"repo_name": "chat-de-whatsapp-de-propuestas-ejecutadas",
|
|
"file_path": "chat-de-whatsapp-de-propuestas-ejecutadas.json",
|
|
"updatedAt": "2026-06-04T00:42:33.818Z",
|
|
"backedUpAt": "2026-06-05T14:47:30.527Z"
|
|
},
|
|
"l8koc0x9iIFqKn7P": {
|
|
"name": "Nomina Panama V2",
|
|
"repo_name": "nomina-panama-v2",
|
|
"file_path": "nomina-panama-v2.json",
|
|
"updatedAt": "2026-06-25T11:38:14.778Z",
|
|
"backedUpAt": "2026-06-28T04:00:44.935Z"
|
|
},
|
|
"sXH75CXIQ0sEzm1Y": {
|
|
"name": "Chat de WhatsApp - Propuestas Ejecutadas",
|
|
"repo_name": "chat-de-whatsapp-propuestas-ejecutadas",
|
|
"file_path": "chat-de-whatsapp-propuestas-ejecutadas.json",
|
|
"updatedAt": "2026-06-20T16:19:11.789Z",
|
|
"backedUpAt": "2026-06-21T04:00:28.342Z"
|
|
},
|
|
"1ykpTM58gz0iOxvK": {
|
|
"name": "Sofía MVP - Gmail a Neo4j",
|
|
"repo_name": "sofia-mvp-gmail-a-neo4j",
|
|
"file_path": "sofia-mvp-gmail-a-neo4j.json",
|
|
"updatedAt": "2026-07-16T16:14:46.749Z",
|
|
"backedUpAt": "2026-07-19T04:00:39.564Z"
|
|
},
|
|
"BNNxfjME3SomZVnL": {
|
|
"name": "Prueba con API de Kan.bn",
|
|
"repo_name": "prueba-con-api-de-kan-bn",
|
|
"file_path": "prueba-con-api-de-kan-bn.json",
|
|
"updatedAt": "2026-07-16T16:14:38.349Z",
|
|
"backedUpAt": "2026-07-19T04:00:57.278Z"
|
|
},
|
|
"IZLgEpGSfWhjj6Qy": {
|
|
"name": "Tablero CDC - Migrar Legacy Sheet a Supabase",
|
|
"repo_name": "tablero-cdc-migrar-legacy-sheet-a-supabase",
|
|
"file_path": "tablero-cdc-migrar-legacy-sheet-a-supabase.json",
|
|
"updatedAt": "2026-07-16T16:20:08.637Z",
|
|
"backedUpAt": "2026-07-19T04:01:04.905Z"
|
|
},
|
|
"6ktj8FJeteAi6l3U": {
|
|
"name": "Agente PMIT IA",
|
|
"repo_name": "agente-pmit-ia",
|
|
"file_path": "agente-pmit-ia.json",
|
|
"updatedAt": "2026-07-16T16:19:17.293Z",
|
|
"backedUpAt": "2026-07-19T04:00:52.526Z"
|
|
},
|
|
"aJH5uWZx3lUnNBbx": {
|
|
"name": "Tablero CDC - Sync Proyecto a Banco Fulgencio IA",
|
|
"repo_name": "tablero-cdc-sync-proyecto-a-banco-fulgencio-ia",
|
|
"file_path": "tablero-cdc-sync-proyecto-a-banco-fulgencio-ia.json",
|
|
"updatedAt": "2026-07-16T16:19:53.423Z",
|
|
"backedUpAt": "2026-07-19T04:01:33.330Z"
|
|
},
|
|
"g2JtKXNz5GDbkmQH": {
|
|
"name": "Tablero CDC - Refrescar Banco Fulgencio Diario",
|
|
"repo_name": "tablero-cdc-refrescar-banco-fulgencio-diario",
|
|
"file_path": "tablero-cdc-refrescar-banco-fulgencio-diario.json",
|
|
"updatedAt": "2026-07-16T16:20:01.984Z",
|
|
"backedUpAt": "2026-07-19T04:01:50.962Z"
|
|
},
|
|
"k2NNakqj2TaP0HKy": {
|
|
"name": "Tablero CDC - Sync Proyecto a Banco Fulgencio",
|
|
"repo_name": "tablero-cdc-sync-proyecto-a-banco-fulgencio",
|
|
"file_path": "tablero-cdc-sync-proyecto-a-banco-fulgencio.json",
|
|
"updatedAt": "2026-07-16T16:20:23.940Z",
|
|
"backedUpAt": "2026-07-19T04:01:58.337Z"
|
|
},
|
|
"7eyfZEkGuDSUodDX": {
|
|
"name": "Tablero CDC - Sync Tarifario Sheet a Supabase",
|
|
"repo_name": "tablero-cdc-sync-tarifario-sheet-a-supabase",
|
|
"file_path": "tablero-cdc-sync-tarifario-sheet-a-supabase.json",
|
|
"updatedAt": "2026-07-16T16:20:16.077Z",
|
|
"backedUpAt": "2026-07-19T04:00:55.090Z"
|
|
},
|
|
"s688ICOeW8Y8Q8IW": {
|
|
"name": "FulgencioChat V3 - GLM",
|
|
"repo_name": "fulgenciochat-v3-glm",
|
|
"file_path": "fulgenciochat-v3-glm.json",
|
|
"updatedAt": "2026-06-19T17:32:10.943Z",
|
|
"backedUpAt": "2026-06-21T04:00:27.064Z"
|
|
},
|
|
"5VOiadzdgbs2Qq1N": {
|
|
"name": "BambooHR Agent Core",
|
|
"repo_name": "bamboohr-agent-core",
|
|
"file_path": "bamboohr-agent-core.json",
|
|
"updatedAt": "2026-07-16T16:14:20.251Z",
|
|
"backedUpAt": "2026-07-19T04:00:50.390Z"
|
|
},
|
|
"CdosDIWBgnDMnPdr": {
|
|
"name": "Chat de WhatsApp - Propuestas Ejecutadas - Versión Final",
|
|
"repo_name": "chat-de-whatsapp-propuestas-ejecutadas-version-final",
|
|
"file_path": "chat-de-whatsapp-propuestas-ejecutadas-version-final.json",
|
|
"updatedAt": "2026-07-16T16:14:30.458Z",
|
|
"backedUpAt": "2026-07-19T04:00:59.845Z"
|
|
},
|
|
"KRF6cPYGgmYT68rF": {
|
|
"name": "FulgencioChat V3 - GLM - Versión Final",
|
|
"repo_name": "fulgenciochat-v3-glm-version-final",
|
|
"file_path": "fulgenciochat-v3-glm-version-final.json",
|
|
"updatedAt": "2026-07-16T16:19:39.815Z",
|
|
"backedUpAt": "2026-07-19T04:01:09.260Z"
|
|
},
|
|
"HXEZPnVf1ALsLncE": {
|
|
"name": "Formulario_HN_Seguridad",
|
|
"repo_name": "formulario-hn-seguridad",
|
|
"file_path": "formulario-hn-seguridad.json",
|
|
"updatedAt": "2026-06-30T14:10:51.676Z",
|
|
"backedUpAt": "2026-07-05T04:00:33.204Z"
|
|
},
|
|
"MJw54TamRSuKs2vX": {
|
|
"name": "Formulario_GT_Seguridad",
|
|
"repo_name": "formulario-gt-seguridad",
|
|
"file_path": "formulario-gt-seguridad.json",
|
|
"updatedAt": "2026-06-30T14:01:23.256Z",
|
|
"backedUpAt": "2026-07-05T04:00:35.233Z"
|
|
},
|
|
"N6WRF7MmEVuh7I7A": {
|
|
"name": "Formulario_RD_Seguridad",
|
|
"repo_name": "formulario-rd-seguridad",
|
|
"file_path": "formulario-rd-seguridad.json",
|
|
"updatedAt": "2026-06-30T14:17:19.061Z",
|
|
"backedUpAt": "2026-07-05T04:00:37.272Z"
|
|
},
|
|
"TNoTZLisReBssKjy": {
|
|
"name": "Portal de Verificación de Nómina",
|
|
"repo_name": "portal-de-verificacion-de-nomina",
|
|
"file_path": "portal-de-verificacion-de-nomina.json",
|
|
"updatedAt": "2026-07-11T13:46:57.620Z",
|
|
"backedUpAt": "2026-07-12T04:00:42.610Z"
|
|
},
|
|
"j04wjKihKPzBIqW8": {
|
|
"name": "Cruce de Seguridad Social - Honduras",
|
|
"repo_name": "cruce-de-seguridad-social-honduras",
|
|
"file_path": "cruce-de-seguridad-social-honduras.json",
|
|
"updatedAt": "2026-07-16T19:52:48.955Z",
|
|
"backedUpAt": "2026-07-19T04:01:53.332Z"
|
|
},
|
|
"loFncgFuvBlXUf8u": {
|
|
"name": "Cruce de Seguridad Social Guatemala - Q1 Q2 PRODUCCIÓN FINAL",
|
|
"repo_name": "cruce-de-seguridad-social-guatemala-q1-q2-produccion-final",
|
|
"file_path": "cruce-de-seguridad-social-guatemala-q1-q2-produccion-final.json",
|
|
"updatedAt": "2026-07-04T14:18:46.100Z",
|
|
"backedUpAt": "2026-07-05T04:00:45.311Z"
|
|
},
|
|
"KBV3AEEpys8KqPLX": {
|
|
"name": "Finiquitos GT - Procesar 1 empleado",
|
|
"repo_name": "finiquitos-gt-procesar-1-empleado",
|
|
"file_path": "finiquitos-gt-procesar-1-empleado.json",
|
|
"updatedAt": "2026-07-16T16:20:47.768Z",
|
|
"backedUpAt": "2026-07-19T04:01:07.065Z"
|
|
},
|
|
"KuJTvjNNx9XmoazA": {
|
|
"name": "Portal de Verificación de Nómina GT - Envío de Reporte",
|
|
"repo_name": "portal-de-verificacion-de-nomina-gt-envio-de-reporte",
|
|
"file_path": "portal-de-verificacion-de-nomina-gt-envio-de-reporte.json",
|
|
"updatedAt": "2026-07-16T16:24:07.482Z",
|
|
"backedUpAt": "2026-07-19T04:01:12.353Z"
|
|
},
|
|
"QDKFgvoJKviQbDl3": {
|
|
"name": "Portal de Verificación de Nómina GT - Históricos",
|
|
"repo_name": "portal-de-verificacion-de-nomina-gt-historicos",
|
|
"file_path": "portal-de-verificacion-de-nomina-gt-historicos.json",
|
|
"updatedAt": "2026-07-16T16:24:51.988Z",
|
|
"backedUpAt": "2026-07-19T04:01:20.162Z"
|
|
},
|
|
"V73ZjH7QBjLndXQV": {
|
|
"name": "Cruce de Seguridad Social - Guatemala",
|
|
"repo_name": "cruce-de-seguridad-social-guatemala",
|
|
"file_path": "cruce-de-seguridad-social-guatemala.json",
|
|
"updatedAt": "2026-07-16T19:35:22.329Z",
|
|
"backedUpAt": "2026-07-19T04:01:28.255Z"
|
|
},
|
|
"adEY9RJsE9o9AJPb": {
|
|
"name": "Cruce de Seguridad Social - República Dominicana",
|
|
"repo_name": "cruce-de-seguridad-social-republica-dominicana",
|
|
"file_path": "cruce-de-seguridad-social-republica-dominicana.json",
|
|
"updatedAt": "2026-07-18T12:47:21.475Z",
|
|
"backedUpAt": "2026-07-19T04:01:36.309Z"
|
|
},
|
|
"4WrHnfh80M7Zewjw": {
|
|
"name": "GLM - Limpieza de temporales IR Nicaragua",
|
|
"repo_name": "glm-limpieza-de-temporales-ir-nicaragua",
|
|
"file_path": "glm-limpieza-de-temporales-ir-nicaragua.json",
|
|
"updatedAt": "2026-07-16T16:21:03.344Z",
|
|
"backedUpAt": "2026-07-19T04:00:42.691Z"
|
|
},
|
|
"5AujMxduslftVg9z": {
|
|
"name": "Portal de Verificación de Nómina - TT",
|
|
"repo_name": "portal-de-verificacion-de-nomina-tt",
|
|
"file_path": "portal-de-verificacion-de-nomina-tt.json",
|
|
"updatedAt": "2026-07-16T16:22:13.609Z",
|
|
"backedUpAt": "2026-07-19T04:00:47.787Z"
|
|
},
|
|
"E9cNPlUjeGnhFqW2": {
|
|
"name": "Portal de Verificación de Nómina - Analizar Nómina con Gemini GT y TT",
|
|
"repo_name": "portal-de-verificacion-de-nomina-analizar-nomina-con-gemini-gt-y-tt",
|
|
"file_path": "portal-de-verificacion-de-nomina-analizar-nomina-con-gemini-gt-y-tt.json",
|
|
"updatedAt": "2026-07-16T16:22:56.845Z",
|
|
"backedUpAt": "2026-07-19T04:01:02.431Z"
|
|
},
|
|
"V1JFqI8iDtzzO5F0": {
|
|
"name": "Cálculo de IR - Nicaragua",
|
|
"repo_name": "calculo-de-ir-nicaragua",
|
|
"file_path": "calculo-de-ir-nicaragua.json",
|
|
"updatedAt": "2026-07-16T16:13:39.561Z",
|
|
"backedUpAt": "2026-07-19T04:01:25.425Z"
|
|
},
|
|
"aihmNdYFskfvf3XF": {
|
|
"name": "Portal de Verificación de Nómina TT - Envío de Reporte",
|
|
"repo_name": "portal-de-verificacion-de-nomina-tt-envio-de-reporte",
|
|
"file_path": "portal-de-verificacion-de-nomina-tt-envio-de-reporte.json",
|
|
"updatedAt": "2026-07-16T16:23:39.126Z",
|
|
"backedUpAt": "2026-07-19T04:01:39.173Z"
|
|
},
|
|
"cmtY0sJInCi21otP": {
|
|
"name": "Cruce de Seguridad Social - Costa Rica",
|
|
"repo_name": "cruce-de-seguridad-social-costa-rica",
|
|
"file_path": "cruce-de-seguridad-social-costa-rica.json",
|
|
"updatedAt": "2026-07-18T17:04:50.880Z",
|
|
"backedUpAt": "2026-07-19T04:01:42.402Z"
|
|
},
|
|
"d3vXYr7ucbaiU5ct": {
|
|
"name": "Portal de Verificación de Nómina - GT",
|
|
"repo_name": "portal-de-verificacion-de-nomina-gt",
|
|
"file_path": "portal-de-verificacion-de-nomina-gt.json",
|
|
"updatedAt": "2026-07-16T16:14:10.569Z",
|
|
"backedUpAt": "2026-07-19T04:01:48.631Z"
|
|
},
|
|
"wCud4hOciMao0Ab3": {
|
|
"name": "Cruce de Seguridad Social - El Salvador",
|
|
"repo_name": "cruce-de-seguridad-social-el-salvador",
|
|
"file_path": "cruce-de-seguridad-social-el-salvador.json",
|
|
"updatedAt": "2026-07-18T16:05:12.193Z",
|
|
"backedUpAt": "2026-07-19T04:02:03.788Z"
|
|
}
|
|
}
|
|
},
|
|
"node:Schedule - Revisar publicados cada día": {
|
|
"recurrenceRules": [
|
|
168
|
|
]
|
|
}
|
|
},
|
|
"meta": null,
|
|
"versionId": "418269c9-35fc-403a-bf4d-decafef5f378",
|
|
"activeVersionId": "418269c9-35fc-403a-bf4d-decafef5f378",
|
|
"versionCounter": 774,
|
|
"triggerCount": 1,
|
|
"shared": [
|
|
{
|
|
"updatedAt": "2026-06-05T14:36:49.347Z",
|
|
"createdAt": "2026-06-05T14:36:49.347Z",
|
|
"role": "workflow:owner",
|
|
"workflowId": "jtJGuwijffvHznH2",
|
|
"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-22T14:42:22.000Z",
|
|
"createdAt": "2026-07-22T14:42:19.627Z",
|
|
"versionId": "418269c9-35fc-403a-bf4d-decafef5f378",
|
|
"workflowId": "jtJGuwijffvHznH2",
|
|
"nodes": [
|
|
{
|
|
"parameters": {},
|
|
"type": "n8n-nodes-base.manualTrigger",
|
|
"typeVersion": 1,
|
|
"position": [
|
|
-16,
|
|
416
|
|
],
|
|
"id": "8b02b163-b1b9-4715-a426-3c07f15afd96",
|
|
"name": "Manual - Ejecutar respaldo ahora"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"assignments": {
|
|
"assignments": [
|
|
{
|
|
"id": "463e6c6e-40ee-46ff-b30f-3a612f21af4a",
|
|
"name": "n8n_base_url",
|
|
"value": "https://agenteit.digitalcompass.agency",
|
|
"type": "string"
|
|
},
|
|
{
|
|
"id": "73de7608-d7ca-4893-babc-5c59552bbd25",
|
|
"name": "gitea_base_url",
|
|
"value": "https://git.digitalcompass.agency",
|
|
"type": "string"
|
|
},
|
|
{
|
|
"id": "83967bc3-16a0-4afc-9bd1-2325d759395a",
|
|
"name": "gitea_owner",
|
|
"value": "Isaac_Aracena",
|
|
"type": "string"
|
|
},
|
|
{
|
|
"id": "b62d61e7-9688-4ebe-bf0e-c40d38c84ffc",
|
|
"name": "owner_type",
|
|
"value": "user",
|
|
"type": "string"
|
|
},
|
|
{
|
|
"id": "f4443432-6bda-4b9b-9b86-c62158fb201f",
|
|
"name": "default_branch",
|
|
"value": "main",
|
|
"type": "string"
|
|
},
|
|
{
|
|
"id": "a6681aaf-eccc-42e6-95b9-d1926cff2fab",
|
|
"name": "private_repo",
|
|
"value": false,
|
|
"type": "boolean"
|
|
},
|
|
{
|
|
"id": "1501bda6-ee9b-4633-979a-46176c853ce4",
|
|
"name": "force_full_backup",
|
|
"value": false,
|
|
"type": "boolean"
|
|
},
|
|
{
|
|
"id": "859f8c57-9a61-4d81-8e1d-74e2767d60d3",
|
|
"name": "only_published_workflows",
|
|
"value": true,
|
|
"type": "boolean"
|
|
},
|
|
{
|
|
"id": "ce4d20a9-5f5c-45c4-80dc-63e628ccdcbc",
|
|
"name": "ignore_workflow_ids_csv",
|
|
"value": "",
|
|
"type": "string"
|
|
}
|
|
]
|
|
},
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.set",
|
|
"typeVersion": 3.4,
|
|
"position": [
|
|
256,
|
|
512
|
|
],
|
|
"id": "fb75c274-8db3-4ad3-8903-74f2dbcc99ec",
|
|
"name": "Config"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"url": "={{ $json.n8n_base_url.replace(/\\/$/, '') + '/api/v1/workflows?limit=250' }}",
|
|
"authentication": "genericCredentialType",
|
|
"genericAuthType": "httpHeaderAuth",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
512,
|
|
512
|
|
],
|
|
"id": "13b905b8-ffa8-4020-a02f-b5db5d78d99b",
|
|
"name": "n8n - Listar workflows",
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "UPDlAh0YeGhLTTiE",
|
|
"name": "Header Auth account 2"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"jsCode": "const cfg = $('Config').first().json;\nconst response = $input.first().json;\n\n// La API pública de n8n normalmente devuelve { data: [...], nextCursor: ... }.\n// Dejamos fallback por si la instancia devuelve un array directo.\nconst workflows = Array.isArray(response.data)\n ? response.data\n : (Array.isArray(response) ? response : []);\n\nif (!workflows.length) {\n throw new Error('No recibí workflows desde la API de n8n. Revisa n8n_base_url, credencial X-N8N-API-KEY y endpoint /api/v1/workflows.');\n}\n\nconst staticData = $getWorkflowStaticData('global');\nstaticData.backedUpWorkflows = staticData.backedUpWorkflows || {};\n\nconst forceAll = cfg.force_full_backup === true || String(cfg.force_full_backup).toLowerCase() === 'true';\nconst onlyPublished = cfg.only_published_workflows === true || String(cfg.only_published_workflows).toLowerCase() === 'true';\nconst ignored = String(cfg.ignore_workflow_ids_csv || '')\n .split(',')\n .map(v => v.trim())\n .filter(Boolean);\n\nconst out = [];\n\nfor (const wf of workflows) {\n const id = String(wf.id || wf.workflowId || '');\n if (!id) continue;\n if (ignored.includes(id)) continue;\n\n // En n8n la lista suele traer active=true para workflows publicados/activos.\n // Si tu instancia usa otro campo, dejamos varios fallbacks comunes.\n const isPublished = wf.active === true || wf.isActive === true || wf.published === true || String(wf.active).toLowerCase() === 'true';\n if (onlyPublished && !isPublished) continue;\n\n const updatedAt = String(wf.updatedAt || wf.updated_at || wf.versionId || wf.version_id || '');\n const previousUpdatedAt = staticData.backedUpWorkflows[id]?.updatedAt;\n\n // Primera ejecución: respalda todos los publicados detectados.\n // Luego: solo workflows publicados nuevos o modificados.\n if (forceAll || !previousUpdatedAt || previousUpdatedAt !== updatedAt) {\n out.push({\n json: {\n ...cfg,\n workflow_id: id,\n workflow_name_hint: wf.name || `workflow-${id}`,\n workflow_updated_at: updatedAt,\n workflow_published: isPublished,\n detected_at: new Date().toISOString(),\n }\n });\n }\n}\n\nreturn out;"
|
|
},
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
768,
|
|
512
|
|
],
|
|
"id": "bb3bd9fe-8c31-43bf-8ed2-988e9df69c8a",
|
|
"name": "Filtrar workflows nuevos o modificados"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"url": "={{ $json.n8n_base_url.replace(/\\/$/, '') + '/api/v1/workflows/' + $json.workflow_id }}",
|
|
"authentication": "genericCredentialType",
|
|
"genericAuthType": "httpHeaderAuth",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
1024,
|
|
512
|
|
],
|
|
"id": "2425a188-773c-4776-9e05-8b7d1af59c2b",
|
|
"name": "n8n - Obtener workflow completo",
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "UPDlAh0YeGhLTTiE",
|
|
"name": "Header Auth account 2"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"mode": "runOnceForEachItem",
|
|
"jsCode": "const cfg = $('Filtrar workflows nuevos o modificados').item.json;\nconst workflow = $input.item.json;\n\nfunction slugifyForRepo(value) {\n return String(value || '')\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase()\n .replace(/ñ/g, 'n')\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .replace(/-{2,}/g, '-')\n .slice(0, 90) || 'workflow-sin-nombre';\n}\n\nconst workflowName = workflow.name || cfg.workflow_name_hint || `workflow-${cfg.workflow_id}`;\nconst workflowId = String(workflow.id || cfg.workflow_id);\nconst repoName = slugifyForRepo(workflowName);\nconst filePath = `${repoName}.json`;\nconst branch = cfg.default_branch || 'main';\n\nconst exportWorkflow = {\n ...workflow,\n};\n\n// Evita guardar datos de prueba pesados si vienen en la respuesta.\ndelete exportWorkflow.pinData;\n\nconst content = Buffer.from(\n JSON.stringify(exportWorkflow, null, 2),\n 'utf8'\n).toString('base64');\n\nreturn {\n json: {\n ...cfg,\n workflow_id: workflowId,\n workflow_name: workflowName,\n repo_name: repoName,\n file_path: filePath,\n branch,\n repo_description: `Backup público automático del workflow n8n: ${workflowName}`,\n content,\n commit_create_message: `Create backup: ${workflowName}`,\n commit_update_message: `Update backup: ${workflowName}`,\n }\n};"
|
|
},
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
1344,
|
|
432
|
|
],
|
|
"id": "75ce5ba0-c1ea-4a22-8e15-648d82e6e827",
|
|
"name": "Preparar repo y archivo"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"url": "={{ $json.gitea_base_url.replace(/\\/$/, '') + '/api/v1/repos/' + $json.gitea_owner + '/' + $json.repo_name }}",
|
|
"authentication": "genericCredentialType",
|
|
"genericAuthType": "httpHeaderAuth",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
1968,
|
|
432
|
|
],
|
|
"id": "a221abfd-0ce0-4c7c-86eb-f9e9314f940d",
|
|
"name": "Gitea - Verificar repo",
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "goGJ7p07L5ygli0D",
|
|
"name": "Header Auth account"
|
|
}
|
|
},
|
|
"onError": "continueErrorOutput"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"method": "POST",
|
|
"url": "={{ $('Loop Over Items').item.json.gitea_base_url.replace(/\\/$/, '') + ($('Loop Over Items').item.json.owner_type === 'org' ? '/api/v1/orgs/' + $('Loop Over Items').item.json.gitea_owner + '/repos' : '/api/v1/user/repos') }}",
|
|
"authentication": "genericCredentialType",
|
|
"genericAuthType": "httpHeaderAuth",
|
|
"sendBody": true,
|
|
"specifyBody": "json",
|
|
"jsonBody": "={{ { name: $('Loop Over Items').item.json.repo_name, description: $('Loop Over Items').item.json.repo_description, private: false, auto_init: true, default_branch: $('Loop Over Items').item.json.branch } }}",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
2224,
|
|
624
|
|
],
|
|
"id": "26e851db-95d6-4756-852c-ffa29bf9ed0a",
|
|
"name": "Gitea - Crear repo público si no existe",
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "goGJ7p07L5ygli0D",
|
|
"name": "Header Auth account"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"url": "={{ $('Loop Over Items').item.json.gitea_base_url.replace(/\\/$/, '') + '/api/v1/repos/' + $('Loop Over Items').item.json.gitea_owner + '/' + $('Loop Over Items').item.json.repo_name + '/contents/' + $('Loop Over Items').item.json.file_path }}",
|
|
"authentication": "genericCredentialType",
|
|
"genericAuthType": "httpHeaderAuth",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
2480,
|
|
432
|
|
],
|
|
"id": "bed90785-6c35-4d38-8942-f644fa8b655b",
|
|
"name": "Gitea - Verificar archivo",
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "goGJ7p07L5ygli0D",
|
|
"name": "Header Auth account"
|
|
}
|
|
},
|
|
"onError": "continueErrorOutput"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"method": "PUT",
|
|
"url": "={{ $('Loop Over Items').item.json.gitea_base_url.replace(/\\/$/, '') + '/api/v1/repos/' + $('Loop Over Items').item.json.gitea_owner + '/' + $('Loop Over Items').item.json.repo_name + '/contents/' + $('Loop Over Items').item.json.file_path }}",
|
|
"authentication": "genericCredentialType",
|
|
"genericAuthType": "httpHeaderAuth",
|
|
"sendBody": true,
|
|
"specifyBody": "json",
|
|
"jsonBody": "={{ { message: $('Loop Over Items').item.json.commit_update_message, content: $('Loop Over Items').item.json.content, sha: $json.sha, branch: $('Loop Over Items').item.json.branch } }}",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
2768,
|
|
320
|
|
],
|
|
"id": "fac285a6-2e37-4043-8127-d534c78aa607",
|
|
"name": "Gitea - Actualizar workflow.json",
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "goGJ7p07L5ygli0D",
|
|
"name": "Header Auth account"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"method": "POST",
|
|
"url": "={{ $('Loop Over Items').item.json.gitea_base_url.replace(/\\/$/, '') + '/api/v1/repos/' + $('Loop Over Items').item.json.gitea_owner + '/' + $('Loop Over Items').item.json.repo_name + '/contents/' + $('Loop Over Items').item.json.file_path }}",
|
|
"authentication": "genericCredentialType",
|
|
"genericAuthType": "httpHeaderAuth",
|
|
"sendBody": true,
|
|
"specifyBody": "json",
|
|
"jsonBody": "={{ { message: $('Loop Over Items').item.json.commit_create_message, content: $('Loop Over Items').item.json.content, branch: $('Loop Over Items').item.json.branch } }}",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
2768,
|
|
624
|
|
],
|
|
"id": "a76819e9-ba84-40d9-8799-ffe86cf0f53f",
|
|
"name": "Gitea - Crear workflow.json",
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "goGJ7p07L5ygli0D",
|
|
"name": "Header Auth account"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"mode": "runOnceForEachItem",
|
|
"jsCode": "const data = $('Loop Over Items').item.json;\n\nconst staticData = $getWorkflowStaticData('global');\nstaticData.backedUpWorkflows = staticData.backedUpWorkflows || {};\n\nstaticData.backedUpWorkflows[data.workflow_id] = {\n name: data.workflow_name,\n repo_name: data.repo_name,\n file_path: data.file_path,\n updatedAt: data.workflow_updated_at || '',\n backedUpAt: new Date().toISOString(),\n};\n\nreturn {\n json: {\n ok: true,\n workflow_id: data.workflow_id,\n workflow_name: data.workflow_name,\n repo_name: data.repo_name,\n file_path: data.file_path,\n repo_public: true,\n backedUpAt: new Date().toISOString(),\n }\n};"
|
|
},
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
3040,
|
|
464
|
|
],
|
|
"id": "6b48a9df-89ef-4a8a-a6ff-2c7cfa789b51",
|
|
"name": "Marcar respaldado"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.splitInBatches",
|
|
"typeVersion": 3,
|
|
"position": [
|
|
1696,
|
|
432
|
|
],
|
|
"id": "1e618c0d-2b6d-4f69-9b63-300c222004e8",
|
|
"name": "Loop Over Items"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"method": "PATCH",
|
|
"url": "={{ $('Loop Over Items').item.json.gitea_base_url.replace(/\\/$/, '') + '/api/v1/repos/' + $('Loop Over Items').item.json.gitea_owner + '/' + $('Loop Over Items').item.json.repo_name }}",
|
|
"authentication": "genericCredentialType",
|
|
"genericAuthType": "httpHeaderAuth",
|
|
"sendBody": true,
|
|
"specifyBody": "json",
|
|
"jsonBody": "={{ { private: false } }}",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
2224,
|
|
336
|
|
],
|
|
"id": "bcaa9c9b-bd82-4dc9-aa6f-e8b4391d26a8",
|
|
"name": "Gitea - Asegurar repo público",
|
|
"credentials": {
|
|
"httpHeaderAuth": {
|
|
"id": "goGJ7p07L5ygli0D",
|
|
"name": "Header Auth account"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"content": "## ✅ Backup automático y ⚙️ Configuración\n\nEste workflow revisa n8n cada 1 minuto.\n\nSi un workflow publicado es nuevo o cambió, crea o actualiza su repo en Gitea.\n\n\nEn Config ajustar:\n\n- n8n_base_url\n- gitea_base_url\n- gitea_owner\n- force_full_backup = false\n\nCredenciales:\nn8n → X-N8N-API-KEY\nGitea → Authorization: token",
|
|
"height": 736,
|
|
"width": 1280,
|
|
"color": 6
|
|
},
|
|
"type": "n8n-nodes-base.stickyNote",
|
|
"typeVersion": 1,
|
|
"position": [
|
|
-80,
|
|
80
|
|
],
|
|
"id": "3be54cf0-4c34-4678-ab3e-b6c8ddce9af1",
|
|
"name": "Sticky Note"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"content": "## 🌍 Repos públicos\n\nLos repos nuevos se crean públicos.\n\nSi el repo ya existe, se asegura como público y luego actualiza el archivo .json.",
|
|
"height": 736,
|
|
"width": 1968,
|
|
"color": 4
|
|
},
|
|
"type": "n8n-nodes-base.stickyNote",
|
|
"typeVersion": 1,
|
|
"position": [
|
|
1264,
|
|
80
|
|
],
|
|
"id": "20864b61-de27-46fb-a4c0-175269061f31",
|
|
"name": "Sticky Note2"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"rule": {
|
|
"interval": [
|
|
{
|
|
"field": "weeks"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"type": "n8n-nodes-base.scheduleTrigger",
|
|
"typeVersion": 1.2,
|
|
"position": [
|
|
-16,
|
|
640
|
|
],
|
|
"id": "b5c75588-f5a2-4e04-a567-7c98c1e20d87",
|
|
"name": "Schedule - Revisar publicados cada día"
|
|
}
|
|
],
|
|
"connections": {
|
|
"Manual - Ejecutar respaldo ahora": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Config",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Config": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "n8n - Listar workflows",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"n8n - Listar workflows": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Filtrar workflows nuevos o modificados",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Filtrar workflows nuevos o modificados": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "n8n - Obtener workflow completo",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"n8n - Obtener workflow completo": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Preparar repo y archivo",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Preparar repo y archivo": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Loop Over Items",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Loop Over Items": {
|
|
"main": [
|
|
[],
|
|
[
|
|
{
|
|
"node": "Gitea - Verificar repo",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Gitea - Verificar repo": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Gitea - Asegurar repo público",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"node": "Gitea - Crear repo público si no existe",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Gitea - Asegurar repo público": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Gitea - Verificar archivo",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Gitea - Crear repo público si no existe": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Gitea - Verificar archivo",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Gitea - Verificar archivo": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Gitea - Actualizar workflow.json",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"node": "Gitea - Crear workflow.json",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Gitea - Actualizar workflow.json": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Marcar respaldado",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Gitea - Crear workflow.json": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Marcar respaldado",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Marcar respaldado": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Loop Over Items",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Schedule - Revisar publicados cada día": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Config",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
}
|
|
},
|
|
"authors": "Isaac Aracena",
|
|
"name": "Version 418269c9",
|
|
"description": "",
|
|
"autosaved": true,
|
|
"workflowPublishHistory": [
|
|
{
|
|
"createdAt": "2026-07-22T14:42:22.080Z",
|
|
"id": 3374,
|
|
"workflowId": "jtJGuwijffvHznH2",
|
|
"versionId": "418269c9-35fc-403a-bf4d-decafef5f378",
|
|
"event": "activated",
|
|
"userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
|
|
},
|
|
{
|
|
"createdAt": "2026-07-25T17:12:50.007Z",
|
|
"id": 3442,
|
|
"workflowId": "jtJGuwijffvHznH2",
|
|
"versionId": "418269c9-35fc-403a-bf4d-decafef5f378",
|
|
"event": "activated",
|
|
"userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
|
|
},
|
|
{
|
|
"createdAt": "2026-07-25T17:12:49.966Z",
|
|
"id": 3441,
|
|
"workflowId": "jtJGuwijffvHznH2",
|
|
"versionId": "418269c9-35fc-403a-bf4d-decafef5f378",
|
|
"event": "deactivated",
|
|
"userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
|
|
}
|
|
]
|
|
}
|
|
} |