Sistema inteligente de mantenimiento de flujos de trabajo
Este es unDevOps, Multimodal AIflujo de automatización del dominio deautomatización que contiene 42 nodos.Utiliza principalmente nodos como If, N8n, Code, Wait, Switch. Sistema de mantenimiento de flujos de trabajo inteligentes con filtrado de IA e integración de Google Workspace
- •Punto final de HTTP Webhook (n8n generará automáticamente)
- •Credenciales de API de Google Drive
- •Pueden requerirse credenciales de autenticación para la API de destino
- •Credenciales de API de Google Sheets
Nodos utilizados (42)
Categoría
{
"meta": {
"instanceId": "8599d7845a778242eb2b590f9276e0b22e25a242e7728a8fa6887cb7c35c668a",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "968b5375-141c-4cad-b077-f0d5a84e162e",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
-1700,
780
],
"webhookId": "0624042d-08fd-4e8f-8399-e3defa12a95d",
"parameters": {
"path": "ops/n8n",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode",
"authentication": "headerAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "THpi8axJMuZwMUJB",
"name": "n8n_audit_header"
}
},
"typeVersion": 2
},
{
"id": "1d426d09-8892-4e4d-807f-15fcd89036c1",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
-1220,
780
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "189fc963-efff-4b59-b455-a53cb1d7f07a",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "success"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "804eff08-b03e-44e6-8fef-8792d7df7d57",
"name": "Obtener un workflow1",
"type": "n8n-nodes-base.n8n",
"position": [
220,
1180
],
"parameters": {
"operation": "get",
"workflowId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"id": "vg8fTUqz9p4BdZGi",
"name": "n8n account"
}
},
"typeVersion": 1
},
{
"id": "ef30f65a-2699-4d1b-830a-8d2197c1b768",
"name": "🔐 Validador de Seguridad",
"type": "n8n-nodes-base.code",
"position": [
-1440,
780
],
"parameters": {
"jsCode": "// Accéder aux headers du webhook via $json.headers\nconst authHeader = $json.headers?.authorization || '';\nconst expectedToken = 'Bearer Bearer YOUR_WEBHOOK_TOKEN_HERE';\n\n// Validation du token\nif (!authHeader.startsWith('Bearer ')) {\n return [{ json: {\n status: 'error',\n code: 401,\n message: 'Missing or invalid Authorization header format. Expected: Bearer <token>'\n }}];\n}\n\nif (authHeader !== expectedToken) {\n return [{ json: {\n status: 'error',\n code: 401,\n message: 'Invalid authorization token'\n }}];\n}\n\n// Accéder au body du webhook via $json.body\nconst body = $json.body;\nif (!body || !body.action) {\n return [{ json: {\n status: 'error',\n code: 400,\n message: 'Missing required field: action'\n }}];\n}\n\n// Validation des actions supportées\nconst validActions = ['audit', 'pause', 'resume', 'duplicate', 'export', 'cleanup'];\nif (!validActions.includes(body.action)) {\n return [{ json: {\n status: 'error',\n code: 400,\n message: `Invalid action. Supported: ${validActions.join(', ')}`\n }}];\n}\n\n// Si tout est OK\nreturn [{ json: {\n status: 'success',\n action: body.action,\n filters: body.filters || {},\n options: body.options || {},\n originalBody: body\n}}];\n"
},
"typeVersion": 2
},
{
"id": "1e6b87f0-39a0-48c3-9e45-a3e005b2044d",
"name": "🔀 Enrutador de Acciones",
"type": "n8n-nodes-base.switch",
"position": [
-920,
560
],
"parameters": {
"mode": "expression",
"output": "={{\n $json.action === 'audit' ? 0 :\n $json.action === 'pause' ? 1 :\n $json.action === 'duplicate' ? 2 :\n $json.action === 'export' ? 3 :0\n}}\n\n"
},
"typeVersion": 3.2
},
{
"id": "cedc60ed-38c6-440e-bb70-fe037e57b238",
"name": "📊 Analizar Datos de Auditoría",
"type": "n8n-nodes-base.code",
"position": [
220,
60
],
"parameters": {
"jsCode": "// Node Code à ajouter avant Google Sheets\nconst auditData = $input.all()[0].json;\nconst processedRows = [];\n\n// Traiter chaque type de rapport (Credentials, Nodes, Instance)\nObject.entries(auditData).forEach(([reportKey, reportData]) => {\n if (reportData && reportData.sections) {\n reportData.sections.forEach(section => {\n processedRows.push({\n date: new Date().toISOString(),\n risk_type: reportData.risk,\n report_category: reportKey,\n section_title: section.title,\n description: section.description,\n recommendation: section.recommendation,\n issues_count: section.location ? section.location.length : 0,\n severity: getSeverity(reportData.risk, section.title),\n affected_workflows: section.location ? \n [...new Set(section.location.map(item => item.workflowId).filter(Boolean))].join('; ') : 'N/A',\n issue_types: section.location ? \n [...new Set(section.location.map(item => item.kind))].join('; ') : 'N/A'\n });\n });\n }\n});\n\nfunction getSeverity(riskType, sectionTitle) {\n if (riskType === 'nodes' && sectionTitle.includes('risky')) return 'Critical';\n if (riskType === 'instance' && sectionTitle.includes('webhook')) return 'High';\n if (riskType === 'credentials') return 'Medium';\n return 'Low';\n}\n\nreturn processedRows.map(row => ({ json: row }));\n"
},
"typeVersion": 2
},
{
"id": "43ebdd05-9eba-4a78-a143-229ce0f0b61f",
"name": "🔍 Filtrar Flujos de Trabajo",
"type": "n8n-nodes-base.code",
"position": [
-60,
280
],
"parameters": {
"jsCode": "// Filtrer les workflows selon les critères spécifiés\nconst workflows = $input.all();\nconst filters = $('🔀 Action Router').item.json.filters || {};\nconst options = $('🔀 Action Router').item.json.options || {};\n\n// Workflows protégés - sécurité renforcée\nconst protectedWorkflows = [\n 'n8n-auto-maintenance', // Ne pas pauser le workflow de maintenance !\n 'Security',\n 'Backup'\n];\n\nlet filteredWorkflows = workflows;\n\n// Filtrer par nom si spécifié\nif (filters.namePattern) {\n const regex = new RegExp(filters.namePattern, 'i');\n filteredWorkflows = filteredWorkflows.filter(wf => \n regex.test(wf.json.name)\n );\n}\n\n// Filtrer par tags si spécifié\nif (filters.tags) {\n const requiredTags = filters.tags.split(',').map(t => t.trim());\n filteredWorkflows = filteredWorkflows.filter(wf =>\n requiredTags.some(tag => \n wf.json.tags?.some(wfTag => wfTag.name === tag)\n )\n );\n}\n\n// Exclure les workflows protégés (sécurité prioritaire)\nfilteredWorkflows = filteredWorkflows.filter(wf => {\n if (protectedWorkflows.includes(wf.json.name)) {\n console.warn(`⚠️ Workflow protégé exclu du filtrage: ${wf.json.name}`);\n return false;\n }\n return true;\n});\n\n// Exclure certains workflows critiques (logique existante)\nconst criticalWorkflows = options.excludeCritical ? \n ['Security Audit', 'Backup System', 'Health Check'] : [];\nfilteredWorkflows = filteredWorkflows.filter(wf =>\n !criticalWorkflows.includes(wf.json.name)\n);\n\nreturn filteredWorkflows.map(wf => ({\n json: {\n id: wf.json.id,\n name: wf.json.name,\n active: wf.json.active,\n tags: wf.json.tags,\n action: 'pause'\n }\n}));\n"
},
"typeVersion": 2
},
{
"id": "6297b646-2788-49a1-b9ca-133892d34c13",
"name": "📋 Obtener Detalles del Flujo de Trabajo",
"type": "n8n-nodes-base.n8n",
"position": [
220,
280
],
"parameters": {
"operation": "get",
"workflowId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"id": "vg8fTUqz9p4BdZGi",
"name": "n8n account"
}
},
"typeVersion": 1
},
{
"id": "2a0d8c5c-29f6-4b40-8a71-f2ae0ef26dca",
"name": "⚙️ Preparar Actualización JSON",
"type": "n8n-nodes-base.code",
"position": [
500,
280
],
"parameters": {
"jsCode": "const workflowData = $('📋 Get Workflow Details').item.json;\n\n// ✅ Propriétés settings MINIMALES et généralement autorisées\nconst minimalSettings = {\n executionOrder: workflowData.settings?.executionOrder || \"v1\"\n};\n\nconst updatePayload = {\n name: workflowData.name,\n nodes: workflowData.nodes,\n connections: workflowData.connections,\n settings: minimalSettings, // ✅ Settings minimal mais requis\n active: false,\n staticData: workflowData.staticData || {}\n};\n\nreturn [{ \n json: { \n workflowJSON: JSON.stringify(updatePayload),\n workflowId: workflowData.id\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "83e91c12-b93b-4280-8165-e9c5721fa128",
"name": "🤖 Filtro AI para Duplicados",
"type": "n8n-nodes-base.code",
"position": [
-60,
740
],
"parameters": {
"jsCode": "// Filtrer les workflows pour duplication selon les critères optimisés avec IA\nconst workflows = $input.all();\nconst filters = $('🔀 Action Router').item.json.filters || {};\nconst options = $('🔀 Action Router').item.json.options || {};\n\n// Workflows protégés - sécurité renforcée\nconst protectedWorkflows = [\n 'n8n-auto-maintenance', // Ne pas dupliquer le workflow de maintenance !\n 'Security',\n 'Backup'\n];\n\nlet filteredWorkflows = workflows;\n\n// Filtrer par nom si spécifié\nif (filters.namePattern) {\n const regex = new RegExp(filters.namePattern, 'i');\n filteredWorkflows = filteredWorkflows.filter(wf => \n regex.test(wf.json.name)\n );\n}\n\n// Filtrer par tags si spécifié\nif (filters.tags) {\n const requiredTags = filters.tags.split(',').map(t => t.trim());\n filteredWorkflows = filteredWorkflows.filter(wf =>\n requiredTags.some(tag => \n wf.json.tags?.some(wfTag => wfTag.name === tag)\n )\n );\n}\n\n// Exclure les workflows protégés (sécurité prioritaire)\nfilteredWorkflows = filteredWorkflows.filter(wf => {\n if (protectedWorkflows.includes(wf.json.name)) {\n console.warn(`⚠️ Workflow protégé exclu de la duplication: ${wf.json.name}`);\n return false;\n }\n return true;\n});\n\n// Exclure certains workflows critiques\nconst criticalWorkflows = options.excludeCritical ? \n ['Security Audit', 'Backup System', 'Health Check'] : [];\nfilteredWorkflows = filteredWorkflows.filter(wf =>\n !criticalWorkflows.includes(wf.json.name)\n);\n\n// 🚀 **LOGIQUE D'INTELLIGENCE ARTIFICIELLE POUR ÉVALUER L'INTÉRÊT**\n\n// Fonction utilitaire pour calculer les jours depuis une date\nfunction daysSince(dateString) {\n const date = new Date(dateString);\n const diffTime = Math.abs(new Date() - date);\n return Math.ceil(diffTime / (1000 * 60 * 60 * 24));\n}\n\n// Système de scoring intelligent\nfilteredWorkflows = filteredWorkflows.filter(wf => {\n const json = wf.json;\n let score = 0;\n let reasons = [];\n\n // 📊 CRITÈRE 1: Statut d'activité (+2 points)\n if (json.active) {\n score += 2;\n reasons.push('actif');\n }\n\n // 🔧 CRITÈRE 2: Complexité du workflow (basée sur le nombre de nœuds)\n if (json.nodes && json.nodes.length > 20) {\n score += 3;\n reasons.push(`complexe (${json.nodes.length} nœuds)`);\n } else if (json.nodes && json.nodes.length > 10) {\n score += 1;\n reasons.push(`modérément complexe (${json.nodes.length} nœuds)`);\n }\n\n // 🏷️ CRITÈRE 3: Tags prioritaires (+3 points chacun)\n const priorityTags = ['important', 'critical', 'core', 'production', 'business'];\n if (json.tags) {\n for (const tag of json.tags) {\n if (priorityTags.includes(tag.name.toLowerCase())) {\n score += 3;\n reasons.push(`tag prioritaire: ${tag.name}`);\n }\n }\n }\n\n // ⏰ CRITÈRE 4: Récence des modifications\n if (json.updatedAt) {\n const days = daysSince(json.updatedAt);\n if (days < 7) {\n score += 3;\n reasons.push('récemment modifié (<7j)');\n } else if (days < 30) {\n score += 1;\n reasons.push('modifié récemment (<30j)');\n }\n }\n\n // 💼 CRITÈRE 5: Analyse sémantique du nom (patterns business-critiques)\n const businessPatterns = [\n /production/i, /business/i, /core/i, /main/i, /primary/i,\n /client/i, /customer/i, /order/i, /payment/i, /integration/i\n ];\n \n const isBusinessCritical = businessPatterns.some(pattern => \n pattern.test(json.name)\n );\n \n if (isBusinessCritical) {\n score += 2;\n reasons.push('nom suggérant un workflow business-critique');\n }\n\n // 📈 CRITÈRE 6: Déclencheurs multiples (workflows complexes)\n if (json.triggerCount && json.triggerCount > 1) {\n score += 1;\n reasons.push(`${json.triggerCount} déclencheurs`);\n }\n\n // 🎯 DÉCISION FINALE : Seuil d'intérêt\n const isInteresting = score >= 3;\n \n // Logging pour debug\n if (isInteresting) {\n console.log(`✅ Workflow \"${json.name}\" sélectionné (score: ${score}) - Raisons: ${reasons.join(', ')}`);\n } else {\n console.log(`❌ Workflow \"${json.name}\" ignoré (score: ${score}) - Raisons: ${reasons.join(', ')}`);\n }\n\n return isInteresting;\n});\n\nreturn filteredWorkflows.map(wf => ({\n json: {\n id: wf.json.id,\n name: wf.json.name,\n active: wf.json.active,\n tags: wf.json.tags,\n action: 'duplicate'\n }\n}));\n"
},
"typeVersion": 2
},
{
"id": "7f396759-1d1e-45c7-8233-610876dc2dda",
"name": "📋 Obtener Detalles para Duplicado",
"type": "n8n-nodes-base.n8n",
"position": [
220,
740
],
"parameters": {
"operation": "get",
"workflowId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"id": "vg8fTUqz9p4BdZGi",
"name": "n8n account"
}
},
"typeVersion": 1
},
{
"id": "ad6d2c80-08da-4f73-9295-f6332d7e869c",
"name": "🔄 Preparar Datos de Duplicado",
"type": "n8n-nodes-base.code",
"position": [
500,
740
],
"parameters": {
"jsCode": "// Préparer les données pour dupliquer TOUS les workflows\nconst allWorkflowsData = $('📋 Get Details for Duplicate').all();\n\nconsole.log(`🔄 Traitement de ${allWorkflowsData.length} workflows pour duplication`);\n\nconst results = [];\n\nallWorkflowsData.forEach((workflowItem, index) => {\n const workflowData = workflowItem.json;\n \n // Générer un nom unique pour chaque copie\n const originalName = workflowData.name;\n const timestamp = new Date().toISOString().split('T')[0]; // Format YYYY-MM-DD\n const duplicateName = `${originalName} - Backup ${timestamp}`;\n\n // Préparer le payload pour la création d'une copie\n const duplicatePayload = {\n name: duplicateName,\n nodes: workflowData.nodes,\n connections: workflowData.connections,\n settings: workflowData.settings || { executionOrder: \"v1\" },\n active: false, // Créer inactif par sécurité\n staticData: workflowData.staticData || {},\n tags: [\n ...(workflowData.tags || []),\n { \n name: \"backup\",\n id: \"backup-\" + Date.now() + \"-\" + index\n },\n {\n name: \"duplicate\",\n id: \"duplicate-\" + Date.now() + \"-\" + index\n }\n ]\n };\n\n // Nettoyer les IDs des nœuds pour éviter les conflits\n if (duplicatePayload.nodes) {\n duplicatePayload.nodes = duplicatePayload.nodes.map(node => {\n const newNode = { ...node };\n // Générer un nouvel ID unique\n newNode.id = 'dup-' + Math.random().toString(36).substr(2, 9) + '-' + Date.now().toString(36) + '-' + index;\n return newNode;\n });\n }\n\n console.log(`🔄 Préparation duplication ${index + 1}/${allWorkflowsData.length}: \"${originalName}\" → \"${duplicateName}\"`);\n console.log(`📊 Nœuds à copier: ${duplicatePayload.nodes?.length || 0}`);\n\n results.push({ \n json: { \n workflowJSON: duplicatePayload,\n originalName: originalName,\n duplicateName: duplicateName,\n originalId: workflowData.id,\n batchIndex: index + 1,\n totalInBatch: allWorkflowsData.length\n }\n });\n});\n\nconsole.log(`✅ ${results.length} workflows préparés pour duplication`);\nconsole.log(`🏷️ Tags ajoutés: backup, duplicate (avec index unique)`);\n\nreturn results;\n"
},
"typeVersion": 2
},
{
"id": "6af5e73e-4fb2-449e-8570-d8faa702913a",
"name": "📝 Convertir a Cadena JSON",
"type": "n8n-nodes-base.code",
"position": [
220,
960
],
"parameters": {
"jsCode": "// Convertir l'objet workflow en JSON string pour l'API n8n\nconst workflowObj = $json.workflowJSON;\n\nreturn [{\n json: {\n workflowJSON: JSON.stringify(workflowObj),\n originalName: $json.originalName,\n duplicateName: $json.duplicateName,\n originalId: $json.originalId,\n batchIndex: $json.batchIndex,\n totalInBatch: $json.totalInBatch\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "65fd019c-c128-47ca-b519-659547d67dd8",
"name": "🧠 Filtro AI para Exportación",
"type": "n8n-nodes-base.code",
"position": [
-60,
1180
],
"parameters": {
"jsCode": "// Filtrage intelligent des workflows pour export\nconst workflows = $input.all();\nconst filters = $('🔀 Action Router').item.json.filters || {};\nconst options = $('🔀 Action Router').item.json.options || {};\n\n// Workflows système (toujours inclus en export car critiques)\nconst systemWorkflows = ['n8n-auto-maintenance', 'Security', 'Backup'];\n\nlet filteredWorkflows = workflows;\n\n// 🧠 INTELLIGENCE ARTIFICIELLE : Système de scoring pour workflows pertinents\nfunction calculateExportValue(workflow) {\n const json = workflow.json;\n let score = 0;\n let reasons = [];\n\n // 🔥 CRITÈRE 1: Workflows système (toujours prioritaires)\n if (systemWorkflows.includes(json.name)) {\n score += 10;\n reasons.push('workflow système critique');\n }\n\n // 💼 CRITÈRE 2: Workflows business-critiques (analyse sémantique)\n const businessPatterns = [\n /production/i, /business/i, /core/i, /main/i, /primary/i,\n /client/i, /customer/i, /order/i, /payment/i, /integration/i,\n /api/i, /webhook/i, /sync/i, /import/i, /export/i, /notification/i\n ];\n \n const isBusinessCritical = businessPatterns.some(pattern => \n pattern.test(json.name)\n );\n \n if (isBusinessCritical) {\n score += 5;\n reasons.push('nom suggérant un workflow business-critique');\n }\n\n // 🏷️ CRITÈRE 3: Tags prioritaires\n const priorityTags = ['important', 'critical', 'core', 'production', 'business', 'live'];\n if (json.tags) {\n for (const tag of json.tags) {\n if (priorityTags.includes(tag.name.toLowerCase())) {\n score += 4;\n reasons.push(`tag prioritaire: ${tag.name}`);\n }\n }\n }\n\n // ⚡ CRITÈRE 4: Workflows actifs (en utilisation)\n if (json.active) {\n score += 3;\n reasons.push('workflow actif');\n }\n\n // 🔧 CRITÈRE 5: Complexité technique (workflows sophistiqués)\n if (json.nodes && json.nodes.length > 15) {\n score += 3;\n reasons.push(`workflow complexe (${json.nodes.length} nœuds)`);\n } else if (json.nodes && json.nodes.length > 8) {\n score += 1;\n reasons.push(`workflow modérément complexe (${json.nodes.length} nœuds)`);\n }\n\n // ⏰ CRITÈRE 6: Activité récente (workflows maintenus)\n if (json.updatedAt) {\n const daysSince = Math.ceil((new Date() - new Date(json.updatedAt)) / (1000 * 60 * 60 * 24));\n if (daysSince < 30) {\n score += 2;\n reasons.push('récemment modifié (<30j)');\n } else if (daysSince < 90) {\n score += 1;\n reasons.push('modifié récemment (<90j)');\n }\n }\n\n // 📈 CRITÈRE 7: Workflows avec déclencheurs (automation active)\n if (json.triggerCount && json.triggerCount > 0) {\n score += 2;\n reasons.push(`${json.triggerCount} déclencheur(s)`);\n }\n\n // 🚫 CRITÈRES DE PÉNALITÉ (workflows à éviter)\n \n // Pénalité pour workflows de test\n const testPatterns = [/test/i, /demo/i, /example/i, /sample/i, /backup.*\\d{4}/i];\n const isTestWorkflow = testPatterns.some(pattern => pattern.test(json.name));\n \n if (isTestWorkflow) {\n score -= 3;\n reasons.push('semble être un workflow de test/demo');\n }\n\n // Pénalité pour workflows inactifs depuis longtemps\n if (!json.active && json.updatedAt) {\n const daysSince = Math.ceil((new Date() - new Date(json.updatedAt)) / (1000 * 60 * 60 * 24));\n if (daysSince > 180) {\n score -= 2;\n reasons.push('inactif depuis >6 mois');\n }\n }\n\n return { score, reasons };\n}\n\n// Appliquer les filtres manuels d'abord\nif (filters.namePattern) {\n const regex = new RegExp(filters.namePattern, 'i');\n filteredWorkflows = filteredWorkflows.filter(wf => \n regex.test(wf.json.name)\n );\n console.log(`🔍 Filtrage par nom: ${filteredWorkflows.length} workflows correspondent à \"${filters.namePattern}\"`);\n}\n\nif (filters.tags) {\n const requiredTags = filters.tags.split(',').map(t => t.trim());\n filteredWorkflows = filteredWorkflows.filter(wf =>\n requiredTags.some(tag => \n wf.json.tags?.some(wfTag => wfTag.name === tag)\n )\n );\n console.log(`🏷️ Filtrage par tags: ${filteredWorkflows.length} workflows avec tags requis`);\n}\n\n// 🧠 SÉLECTION INTELLIGENTE : Appliquer le scoring\nconst scoredWorkflows = filteredWorkflows.map(wf => {\n const analysis = calculateExportValue(wf);\n return {\n workflow: wf,\n score: analysis.score,\n reasons: analysis.reasons\n };\n});\n\n// Seuil intelligent : workflows avec score >= 5 OU workflows système\nconst selectedWorkflows = scoredWorkflows.filter(item => {\n const isSelected = item.score >= 5 || systemWorkflows.includes(item.workflow.json.name);\n \n if (isSelected) {\n console.log(`✅ \"${item.workflow.json.name}\" sélectionné (score: ${item.score}) - ${item.reasons.join(', ')}`);\n } else {\n console.log(`❌ \"${item.workflow.json.name}\" ignoré (score: ${item.score}) - ${item.reasons.join(', ')}`);\n }\n \n return isSelected;\n});\n\n// Si mode \"force include\" activé, inclure aussi les workflows avec score 3-4\nif (options.includeModerateWorkflows) {\n const moderateWorkflows = scoredWorkflows.filter(item => \n item.score >= 3 && item.score < 5 && !systemWorkflows.includes(item.workflow.json.name)\n );\n \n moderateWorkflows.forEach(item => {\n selectedWorkflows.push(item);\n console.log(`🟡 \"${item.workflow.json.name}\" inclus (mode étendu - score: ${item.score})`);\n });\n}\n\n// Statistiques finales\nconst stats = {\n total: workflows.length,\n afterFilters: filteredWorkflows.length,\n selected: selectedWorkflows.length,\n highValue: selectedWorkflows.filter(item => item.score >= 8).length,\n systemWorkflows: selectedWorkflows.filter(item => \n systemWorkflows.includes(item.workflow.json.name)\n ).length\n};\n\nconsole.log(`📊 STATISTIQUES EXPORT:`);\nconsole.log(`📦 Total workflows: ${stats.total}`);\nconsole.log(`🔍 Après filtres manuels: ${stats.afterFilters}`);\nconsole.log(`✅ Sélectionnés pour export: ${stats.selected}`);\nconsole.log(`🔥 Haute valeur (score ≥8): ${stats.highValue}`);\nconsole.log(`⚙️ Workflows système: ${stats.systemWorkflows}`);\n\nreturn selectedWorkflows.map(item => ({\n json: {\n id: item.workflow.json.id,\n name: item.workflow.json.name,\n active: item.workflow.json.active,\n tags: item.workflow.json.tags,\n action: 'export',\n exportScore: item.score,\n exportReasons: item.reasons\n }\n}));\n"
},
"typeVersion": 2
},
{
"id": "a443f5ba-9dd8-4771-9531-0da98494d514",
"name": "📤 Preparar Datos de Exportación",
"type": "n8n-nodes-base.code",
"position": [
500,
1180
],
"parameters": {
"jsCode": "// Préparer les données d'export avec métadonnées complètes - VERSION CORRIGÉE\nconst allWorkflows = $input.all();\nconst exportTimestamp = new Date().toISOString();\nconst exportDate = exportTimestamp.split('T')[0]; // Format YYYY-MM-DD\n\nconsole.log(`📤 Préparation export de ${allWorkflows.length} workflows sélectionnés intelligemment`);\n\n// Statistiques en temps réel\nlet stats = {\n totalWorkflows: allWorkflows.length,\n activeWorkflows: 0,\n inactiveWorkflows: 0,\n totalNodes: 0,\n workflowsWithCredentials: 0,\n workflowsWithTriggers: 0,\n systemWorkflows: 0,\n businessCritical: 0,\n highValueWorkflows: 0\n};\n\n// Traitement intelligent de chaque workflow\nconst processedWorkflows = allWorkflows.map((item, index) => {\n const workflow = item.json;\n const nodeCount = workflow.nodes?.length || 0;\n \n // Mise à jour des statistiques\n stats.totalNodes += nodeCount;\n if (workflow.active) stats.activeWorkflows++;\n else stats.inactiveWorkflows++;\n \n // Détection des credentials\n const hasCredentials = workflow.nodes?.some(node => \n node.credentials && Object.keys(node.credentials).length > 0\n ) || false;\n if (hasCredentials) stats.workflowsWithCredentials++;\n \n // Détection des triggers\n const triggerCount = workflow.nodes?.filter(node => \n node.type.includes('Trigger') || node.type.includes('trigger')\n ).length || 0;\n if (triggerCount > 0) stats.workflowsWithTriggers++;\n \n // Classification intelligente\n const systemWorkflows = ['n8n-auto-maintenance', 'Security', 'Backup'];\n const isSystemWorkflow = systemWorkflows.includes(workflow.name);\n if (isSystemWorkflow) stats.systemWorkflows++;\n \n const businessPatterns = [\n /production/i, /business/i, /core/i, /main/i, /primary/i,\n /client/i, /customer/i, /order/i, /payment/i, /integration/i,\n /api/i, /webhook/i, /sync/i, /import/i, /export/i, /notification/i\n ];\n const isBusinessCritical = businessPatterns.some(pattern => \n pattern.test(workflow.name)\n );\n if (isBusinessCritical) stats.businessCritical++;\n \n // ✅ CORRECTION : Récupérer le score depuis les données du nœud actuel\n const exportScore = item.json.exportScore || 5; // Score par défaut si absent\n const exportReasons = item.json.exportReasons || ['sélectionné par filtrage intelligent'];\n if (exportScore >= 8) stats.highValueWorkflows++;\n \n // Structure d'export optimisée\n return {\n // Métadonnées principales\n id: workflow.id,\n name: workflow.name,\n active: workflow.active,\n versionId: workflow.versionId,\n \n // Timestamps\n createdAt: workflow.createdAt,\n updatedAt: workflow.updatedAt,\n exportedAt: exportTimestamp,\n \n // Structure workflow\n nodes: workflow.nodes,\n connections: workflow.connections,\n settings: workflow.settings || { executionOrder: \"v1\" },\n staticData: workflow.staticData || {},\n \n // Métadonnées organisationnelles\n tags: workflow.tags || [],\n \n // Analytics et insights pour l'import\n exportMetadata: {\n originallyActive: workflow.active,\n nodeCount: nodeCount,\n triggerCount: triggerCount,\n hasCredentials: hasCredentials,\n isSystemWorkflow: isSystemWorkflow,\n isBusinessCritical: isBusinessCritical,\n exportScore: exportScore,\n exportReasons: exportReasons,\n \n // Types de nœuds (pour statistiques)\n nodeTypes: workflow.nodes ? \n [...new Set(workflow.nodes.map(node => node.type))].sort() : [],\n \n // Credentials utilisés (noms seulement, pas les valeurs)\n credentialTypes: hasCredentials ? \n [...new Set(workflow.nodes.flatMap(node => \n node.credentials ? Object.keys(node.credentials) : []\n ))].sort() : [],\n \n // Estimation de complexité\n complexityLevel: nodeCount < 5 ? 'Simple' : \n nodeCount < 15 ? 'Moderate' : \n nodeCount < 30 ? 'Complex' : 'Very Complex'\n }\n };\n});\n\n// Calculs statistiques finaux\nstats.averageNodesPerWorkflow = Math.round(stats.totalNodes / stats.totalWorkflows);\nstats.credentialCoverage = Math.round((stats.workflowsWithCredentials / stats.totalWorkflows) * 100);\nstats.activationRate = Math.round((stats.activeWorkflows / stats.totalWorkflows) * 100);\n\n// Structure d'export complète avec métadonnées riches\nconst exportData = {\n // En-tête d'export\n metadata: {\n exportDate: exportDate,\n exportTimestamp: exportTimestamp,\n exportedBy: 'n8n-auto-maintenance',\n exportVersion: '2.0',\n sourceInstance: 'n8n-production', // À adapter\n \n // Statistiques détaillées\n statistics: stats,\n \n // Configuration d'export\n exportConfig: {\n intelligentFiltering: true,\n includeMetadata: true,\n includeSettings: true,\n includeStaticData: true,\n credentialsHandling: 'references-only'\n }\n },\n \n // Données des workflows\n workflows: processedWorkflows\n};\n\n// Génération du nom de fichier intelligent\nconst filenamePrefix = stats.businessCritical > 0 ? 'n8n-business-workflows' : 'n8n-workflows';\nconst filename = `${filenamePrefix}-export-${exportDate}.json`;\n\n// Logs détaillés pour monitoring\nconsole.log(`📊 === STATISTIQUES D'EXPORT DÉTAILLÉES ===`);\nconsole.log(`📦 Total workflows exportés: ${stats.totalWorkflows}`);\nconsole.log(`⚡ Workflows actifs: ${stats.activeWorkflows} (${stats.activationRate}%)`);\nconsole.log(`💤 Workflows inactifs: ${stats.inactiveWorkflows}`);\nconsole.log(`🔧 Total nœuds: ${stats.totalNodes} (moyenne: ${stats.averageNodesPerWorkflow})`);\nconsole.log(`🔑 Avec credentials: ${stats.workflowsWithCredentials} (${stats.credentialCoverage}%)`);\nconsole.log(`⚡ Avec triggers: ${stats.workflowsWithTriggers}`);\nconsole.log(`⚙️ Workflows système: ${stats.systemWorkflows}`);\nconsole.log(`💼 Business-critiques: ${stats.businessCritical}`);\nconsole.log(`🔥 Haute valeur (score ≥8): ${stats.highValueWorkflows}`);\nconsole.log(`📄 Taille export: ${JSON.stringify(exportData).length} caractères`);\nconsole.log(`📁 Nom fichier: ${filename}`);\n\nreturn [{\n json: {\n exportData: exportData,\n stats: stats,\n filename: filename,\n success: true\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "4b886cf9-9006-4895-8070-8c4cfd9d45d3",
"name": "💾 Preparar Respuesta Binaria",
"type": "n8n-nodes-base.code",
"position": [
-320,
960
],
"parameters": {
"jsCode": "// Préparer la réponse binaire pour téléchargement - VERSION CORRIGÉE\nconst exportData = $json.exportData;\nconst filename = $json.filename;\nconst stats = $json.stats;\n\nconsole.log(`📤 Préparation réponse binaire pour export: ${filename}`);\nconsole.log(`📊 Workflows à télécharger: ${stats.totalWorkflows}`);\n\n// ✅ CORRECTION : Créer le contenu JSON avec Buffer.from()\nconst jsonContent = JSON.stringify(exportData, null, 2);\nconst binaryData = Buffer.from(jsonContent, 'utf8');\n\nconsole.log(`📄 Taille fichier: ${binaryData.length} bytes (${Math.round(binaryData.length/1024)} KB)`);\n\n// ✅ CORRECTION : Structure exacte requise par n8n\nreturn [{\n json: {\n filename: filename,\n fileSize: binaryData.length,\n stats: stats,\n downloadReady: true\n },\n binary: {\n exportData: {\n data: binaryData,\n mimeType: 'application/json',\n fileName: filename\n }\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "d6e01bb8-c5d3-48fd-88ae-5b5a3a6b7081",
"name": "📂 Obtener Todos los Flujos de Trabajo",
"type": "n8n-nodes-base.n8n",
"position": [
-320,
60
],
"parameters": {
"filters": {
"tags": "",
"activeWorkflows": false
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"id": "vg8fTUqz9p4BdZGi",
"name": "n8n account"
}
},
"typeVersion": 1
},
{
"id": "3010eed3-58c7-41ca-8107-8e1409247c63",
"name": "🔒 Generar Auditoría de Seguridad",
"type": "n8n-nodes-base.n8n",
"position": [
-60,
60
],
"parameters": {
"resource": "audit",
"operation": "generate",
"requestOptions": {},
"additionalOptions": {}
},
"credentials": {
"n8nApi": {
"id": "vg8fTUqz9p4BdZGi",
"name": "n8n account"
}
},
"typeVersion": 1
},
{
"id": "1e898452-a205-43a7-bf15-ec90305a9e8d",
"name": "⏸️ Obtener Flujos a Pausar",
"type": "n8n-nodes-base.n8n",
"position": [
-320,
280
],
"parameters": {
"filters": {
"activeWorkflows": true
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"id": "vg8fTUqz9p4BdZGi",
"name": "n8n account"
}
},
"typeVersion": 1
},
{
"id": "4221c708-7abe-441f-b6ec-b094e827f934",
"name": "📋 Obtener Flujos a Duplicar",
"type": "n8n-nodes-base.n8n",
"position": [
-320,
740
],
"parameters": {
"filters": {
"activeWorkflows": true
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"id": "vg8fTUqz9p4BdZGi",
"name": "n8n account"
}
},
"typeVersion": 1
},
{
"id": "09650916-d4b7-46d0-933e-916814e2bc33",
"name": "📦 Obtener Flujos para Exportar",
"type": "n8n-nodes-base.n8n",
"position": [
-320,
1180
],
"parameters": {
"filters": {
"activeWorkflows": false
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"id": "vg8fTUqz9p4BdZGi",
"name": "n8n account"
}
},
"typeVersion": 1
},
{
"id": "9cdc509c-5b1f-44c6-b4c4-8202cd9ff234",
"name": "⏸️ Desactivar Flujo de Trabajo",
"type": "n8n-nodes-base.n8n",
"position": [
-320,
500
],
"parameters": {
"operation": "deactivate",
"workflowId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.workflowId }}"
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"id": "vg8fTUqz9p4BdZGi",
"name": "n8n account"
}
},
"typeVersion": 1
},
{
"id": "b655347c-9fda-4a4e-a7a2-12bbd7e6b246",
"name": "📄 Obtener Estado del Flujo de Trabajo",
"type": "n8n-nodes-base.n8n",
"position": [
-60,
500
],
"parameters": {
"operation": "get",
"workflowId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"id": "vg8fTUqz9p4BdZGi",
"name": "n8n account"
}
},
"typeVersion": 1
},
{
"id": "52b35908-e231-4c4f-b739-a559f2cf84b8",
"name": "⏰ Esperar 8h para Reactivación",
"type": "n8n-nodes-base.wait",
"position": [
220,
500
],
"webhookId": "186c8076-cf20-46de-b9da-9dc0f1bfa764",
"parameters": {
"unit": "hours",
"amount": 8
},
"typeVersion": 1.1
},
{
"id": "fe7de858-3240-4828-bade-9f8e02cb5d4a",
"name": "▶️ Reactivar Flujos de Trabajo",
"type": "n8n-nodes-base.n8n",
"position": [
500,
500
],
"parameters": {
"operation": "activate",
"workflowId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"id": "vg8fTUqz9p4BdZGi",
"name": "n8n account"
}
},
"typeVersion": 1
},
{
"id": "3e16c955-9ec6-4814-9fd2-afb85d1e89ae",
"name": "➕ Crear Flujo de Trabajo Duplicado",
"type": "n8n-nodes-base.n8n",
"position": [
500,
960
],
"parameters": {
"operation": "create",
"requestOptions": {},
"workflowObject": "={{ $json.workflowJSON }}"
},
"credentials": {
"n8nApi": {
"id": "vg8fTUqz9p4BdZGi",
"name": "n8n account"
}
},
"typeVersion": 1
},
{
"id": "8bb9df05-663d-42e5-b2c4-b99350c1438e",
"name": "📅 Programación Diaria de Pausa (22h)",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-2260,
780
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 22
}
]
}
},
"typeVersion": 1.2
},
{
"id": "3ac317e2-fe93-48aa-b9ea-9d4b5bdb4ea7",
"name": "📅 Programación Semanal de Auditoría (Lun 21h)",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-2260,
600
],
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
1
],
"triggerAtHour": 21
}
]
}
},
"typeVersion": 1.2
},
{
"id": "113734a6-70eb-40ef-b527-07455e4e8253",
"name": "📅 Programación Mensual de Exportación (9h)",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-2260,
1160
],
"parameters": {
"rule": {
"interval": [
{
"field": "months",
"triggerAtHour": 9
}
]
}
},
"typeVersion": 1.2
},
{
"id": "05bd883f-a194-4e1f-bf60-291874c733cf",
"name": "🎯 Activador de Prueba Manual",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-2260,
960
],
"parameters": {},
"typeVersion": 1
},
{
"id": "59daa2b4-5a86-4b90-ab4a-ffb2792e6bb6",
"name": "📊 Ejemplo: Solicitud de Auditoría",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1980,
600
],
"parameters": {
"url": "https://your-n8n-instance.com/webhook/ops/n8n",
"method": "POST",
"options": {},
"jsonBody": "{\n \"action\": \"audit\",\n \"filters\": {\n \"tags\": \"maintenance,test\",\n \"namePattern\": \"Test.*\"\n },\n \"options\": {\n \"excludeCritical\": true,\n \"reason\": \"Scheduled maintenance\"\n }\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_WEBHOOK_TOKEN_HERE"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "856af42e-b2df-4f16-a601-8c4b51a3e3fc",
"name": "⏸️ Ejemplo: Solicitud de Pausa",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1980,
780
],
"parameters": {
"url": "https://your-n8n-instance.com/webhook/ops/n8n",
"method": "POST",
"options": {},
"jsonBody": "{\n \"action\": \"pause\",\n \"filters\": {\n \"tags\": \"maintenance,test\",\n \"namePattern\": \"Test.*\"\n },\n \"options\": {\n \"excludeCritical\": true,\n \"reason\": \"Scheduled maintenance\"\n }\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_WEBHOOK_TOKEN_HERE"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "91c0a34b-d8d9-4fa4-879e-9864e616feec",
"name": "🔄 Ejemplo: Solicitud de Duplicado",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1980,
960
],
"parameters": {
"url": "https://your-n8n-instance.com/webhook/ops/n8n",
"method": "POST",
"options": {},
"jsonBody": "{\n \"action\": \"duplicate\",\n \"filters\": {\n \"tags\": \"maintenance,test\",\n \"namePattern\": \"Test.*\"\n },\n \"options\": {\n \"excludeCritical\": true,\n \"reason\": \"Scheduled maintenance\"\n }\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_WEBHOOK_TOKEN_HERE"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "eb3140eb-0075-45e3-be18-c41b9c22021a",
"name": "📤 Ejemplo: Solicitud de Exportación",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1980,
1160
],
"parameters": {
"url": "https://your-n8n-instance.com/webhook/ops/n8n",
"method": "POST",
"options": {},
"jsonBody": "{\n \"action\": \"export\",\n \"filters\": {\n \"tags\": \"maintenance,test\",\n \"namePattern\": \"Test.*\"\n },\n \"options\": {\n \"excludeCritical\": true,\n \"reason\": \"Scheduled maintenance\"\n }\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_WEBHOOK_TOKEN_HERE"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "29741645-14c0-41de-b385-bd8a7a415513",
"name": "❌ Error de Autenticación",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
-960,
1000
],
"parameters": {
"options": {
"responseCode": "={{ $json.code }}"
},
"respondWith": "json",
"responseBody": "{\n \"success\": false,\n \"error\": \"{{ $json.message }}\",\n \"timestamp\": \"{{ $now }}\"\n}\n"
},
"typeVersion": 1.4
},
{
"id": "3025cc68-8d55-4ac4-b4f6-7ed8ea7176b6",
"name": "📈 Guardar en Hojas Google",
"type": "n8n-nodes-base.googleSheets",
"position": [
500,
60
],
"parameters": {
"columns": {
"value": {},
"schema": [],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "id",
"value": "YOUR_SHEET_ID_HERE"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "YOUR_GOOGLE_SHEET_ID_HERE"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "lmJOtRvKMOD3WkGJ",
"name": "Google Sheets account"
}
},
"typeVersion": 4.6
},
{
"id": "d3a47b59-93b1-4c10-ae8d-0e7a1a8db5bc",
"name": "☁️ Guardar en Drive Google",
"type": "n8n-nodes-base.googleDrive",
"position": [
-60,
960
],
"parameters": {
"name": "={{ $json.filename }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root",
"cachedResultName": "/ (Root folder)"
},
"inputDataFieldName": "exportData"
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "q3CEz3EULOFD0Ybj",
"name": "Google Drive account 2"
}
},
"typeVersion": 3
},
{
"id": "683fb61e-0867-4766-9f2f-c463a6045e2a",
"name": "Nota Adhesiva",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2780,
520
],
"parameters": {
"width": 1000,
"height": 840,
"content": "# 🔧 n8n Auto-Maintenance System\n\n## Overview\nAdvanced workflow automation with AI-powered intelligent selection\n\n## 🎯 Core Actions\n- **🔒 AUDIT**: Security analysis & reporting\n- **⏸️ PAUSE**: Temporary workflow suspension \n- **🔄 DUPLICATE**: Smart backup creation\n- **📤 EXPORT**: Complete system backup\n\n## ✨ Key Features\n- 🤖 AI-driven workflow filtering\n- 🔐 Secure token-based authentication\n- 📊 Automated reporting to Google Sheets\n- ☁️ Google Drive integration\n- ⚡ Scheduled maintenance cycles\n"
},
"typeVersion": 1
},
{
"id": "8faa0c78-0d50-4674-a6b9-e85b7d3436fa",
"name": "Nota Adhesiva2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-980,
-220
],
"parameters": {
"color": 6,
"width": 600,
"height": 540,
"content": "# 🧠 Artificial Intelligence Engine\n\n## Smart Scoring System\n| Criteria | Points | Description |\n|----------|--------|-------------|\n| **Active Status** | +2 | Currently running |\n| **Complexity** | +1-3 | Node count based |\n| **Priority Tags** | +3 | Critical/Important |\n| **Business Critical** | +2-5 | Production patterns |\n| **Recent Updates** | +1-3 | Maintenance activity |\n\n## 🎯 Selection Thresholds\n- **Duplicate**: ≥3 points\n- **Export**: ≥5 points or system workflow\n\n## 🔍 Pattern Recognition\nAutomatically detects business-critical workflows using semantic analysis\n"
},
"typeVersion": 1
},
{
"id": "7b387337-4df9-42aa-8ba2-d136911184cc",
"name": "Nota Adhesiva1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1700,
120
],
"parameters": {
"color": 3,
"width": 660,
"height": 520,
"content": "# 🔐 Security Framework\n\n## Authentication\n- ✅ **Bearer Token** validation required\n- ✅ **Request format** validation\n- ✅ **Action whitelist** enforcement\n- ✅ **Error handling** with proper HTTP codes\n\n## Protected Workflows\n> **⚠️ Never modified by automation**\n\n- `n8n-auto-maintenance`\n- `Security` \n- `Backup`\n\n## Supported Actions\n`audit` • `pause` • `resume` • `duplicate` • `export` • `cleanup`\n"
},
"typeVersion": 1
},
{
"id": "bf26f38f-da76-4498-a671-85044372dc21",
"name": "Nota Adhesiva3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1700,
1100
],
"parameters": {
"color": 4,
"width": 760,
"height": 500,
"content": "# ⚙️ Configuration & Scheduling\n\n## Default Schedules\n- **🔒 Audit**: Weekly (Monday 21:00)\n- **⏸️ Pause**: Daily (22:00) \n- **📤 Export**: Monthly (Day 1, 09:00)\n\n## Required Credentials\n1. **n8n API**: Full workflow access\n2. **Google Sheets**: Audit logging\n3. **Google Drive**: Export storage\n4. **Webhook Auth**: Security validation\n\n## Environment Variables\nWEBHOOK_TOKEN=your_secure_token_here\nGOOGLE_SHEET_ID=your_sheet_id\nMAINTENANCE_HOUR=22\n\n\n"
},
"typeVersion": 1
},
{
"id": "301da1ba-dbc5-49e5-8c59-1f194f2fcec9",
"name": "Nota Adhesiva4",
"type": "n8n-nodes-base.stickyNote",
"position": [
840,
-1220
],
"parameters": {
"width": 1600,
"height": 4160,
"content": "# 🔧 n8n Advanced Auto-Maintenance System\n\n[](https://n8n.io)\n[](https://opensource.org/licenses/MIT)\n[](https://github.com/yourusername/n8n-auto-maintenance/graphs/commit-activity)\n\n## 📋 Overview\n\nAdvanced workflow automation system with **AI-powered intelligent selection** for n8n maintenance operations. Automates security audits, workflow management, backups, and exports with smart filtering capabilities.\n\n### ✨ Key Features\n\n- **🤖 AI-Driven Selection**: Intelligent workflow filtering using multi-criteria scoring\n- **🔐 Secure Authentication**: Token-based security with protected workflows \n- **📊 Automated Reporting**: Security audit results to Google Sheets\n- **☁️ Cloud Integration**: Export backups to Google Drive\n- **⚡ Scheduled Operations**: Automated maintenance cycles\n- **🎯 Granular Control**: Tag-based and pattern filtering\n\n## 🎯 Core Actions\n\n| Action | Description | Trigger | AI Filter |\n|--------|-------------|---------|-----------|\n| **🔒 AUDIT** | Security analysis & reporting | Weekly (Mon 21:00) | ❌ |\n| **⏸️ PAUSE** | Temporary workflow suspension | Daily (22:00) | ✅ | \n| **🔄 DUPLICATE** | Smart backup creation | On-demand | ✅ (≥3 pts) |\n| **📤 EXPORT** | Complete system backup | Monthly (1st, 09:00) | ✅ (≥5 pts) |\n\n## 🚀 Quick Start\n\n### Prerequisites\n\n- n8n instance (v1.0+) with API enabled\n- Google Workspace account (Sheets + Drive)\n- Webhook endpoint access\n\n### Installation\n\n1. **Import Template**\n\nDownload the workflow JSON\ncurl -O https://github.com/yourusername/n8n-auto-maintenance/raw/main/workflow.json\n\nImport in n8n interface: Settings → Import workflow\n\n\n2. **Configure Credentials**\n- `your_n8n_api_credential`: n8n API credentials\n- `your_google_sheets_credential`: Google Sheets OAuth2\n- `your_google_drive_credential`: Google Drive OAuth2\n- `your_webhook_auth_credential`: Header auth with token\n\n3. **Environment Setup**\nWEBHOOK_TOKEN=your_secure_token_here_32_chars_min\nGOOGLE_SHEET_ID=1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms\nMAINTENANCE_HOUR=22\n\n\n4. **Test Setup**\ncurl -X POST https://your-instance.com/webhook/ops/n8n\n-H \"Authorization: Bearer YOUR_WEBHOOK_TOKEN_HERE\"\n-H \"Content-Type: application/json\"\n-d '{\"action\":\"audit\",\"options\":{\"reason\":\"Setup test\"}}'\n\n\n## 📖 Detailed Documentation\n\n- [📋 Installation Guide](docs/installation.md)\n- [🔧 Configuration Reference](docs/configuration.md)\n- [🤖 AI Filtering Logic](docs/ai-filtering.md)\n- [🔒 Security Best Practices](docs/security.md)\n- [🐛 Troubleshooting](docs/troubleshooting.md)\n\n## 🤖 AI Intelligence\n\n### Smart Scoring System\n\n| Criteria | Points | Logic |\n|----------|--------|-------|\n| **Active Status** | +2 | Currently running workflows |\n| **Complexity** | +1-3 | Based on node count (>10: +1, >20: +3) |\n| **Priority Tags** | +3 | `critical`, `important`, `core`, `production` |\n| **Business Critical** | +2-5 | Semantic analysis of workflow names |\n| **Recent Activity** | +1-3 | Last modification (<7d: +3, <30d: +1) |\n\n### Selection Thresholds\n- **Duplicate**: ≥3 points (smart backup selection)\n- **Export**: ≥5 points or system workflow (comprehensive backup)\n\n## 🔐 Security\n\n### Protected Workflows\nThese workflows are **never** modified by automation:\n- `n8n-auto-maintenance` (this workflow itself)\n- `Security` (security-related workflows) \n- `Backup` (backup workflows)\n\n### Authentication\n- Bearer token required for all operations\n- Request validation and sanitization\n- Action whitelist enforcement\n- Comprehensive error handling\n\n## 📊 Monitoring & Logging\n\n- **Google Sheets**: Audit results with severity classification\n- **Console Logs**: Detailed execution information\n- **Error Responses**: Structured JSON with HTTP status codes\n- **Statistics**: Workflow counts, success rates, performance metrics\n\n## 🛠️ API Reference\n\n### Request Format\n{\n\"action\": \"audit|pause|duplicate|export\",\n\"filters\": {\n\"tags\": \"production,critical\",\n\"namePattern\": \".Business.\"\n},\n\"options\": {\n\"excludeCritical\": true,\n\"reason\": \"Scheduled maintenance\"\n}\n}\n\n### Response Format\n{\n\"success\": true,\n\"message\": \"Action completed successfully\",\n\"timestamp\": \"2025-08-16T08:47:00Z\",\n\"affected_workflows\": 5,\n\"statistics\": {\n\"processed\": 12,\n\"selected\": 5,\n\"skipped\": 7\n}\n}\n\n\n## 📈 Changelog\n\n### v2.0.0 (Latest)\n- ✨ AI-powered workflow selection\n- 🔒 Enhanced security framework\n- 📊 Advanced reporting capabilities\n- ☁️ Google Drive integration\n- 🎯 Granular filtering options\n\n## 🤝 Contributing\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit changes (`git commit -m 'Add amazing feature'`)\n4. Push to branch (`git push origin feature/amazing-feature`) \n5. Open a Pull Request\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 🙏 Acknowledgments\n\n- n8n community for the amazing automation platform\n- AI/ML community for intelligent filtering concepts\n- Contributors and beta testers\n\n---\n\n⭐ **Star this repo if it helped you automate your n8n maintenance!**\n\n"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"1d426d09-8892-4e4d-807f-15fcd89036c1": {
"main": [
[
{
"node": "1e6b87f0-39a0-48c3-9e45-a3e005b2044d",
"type": "main",
"index": 0
}
],
[
{
"node": "29741645-14c0-41de-b385-bd8a7a415513",
"type": "main",
"index": 0
}
]
]
},
"968b5375-141c-4cad-b077-f0d5a84e162e": {
"main": [
[
{
"node": "ef30f65a-2699-4d1b-830a-8d2197c1b768",
"type": "main",
"index": 0
}
]
]
},
"804eff08-b03e-44e6-8fef-8792d7df7d57": {
"main": [
[
{
"node": "a443f5ba-9dd8-4771-9531-0da98494d514",
"type": "main",
"index": 0
}
]
]
},
"1e6b87f0-39a0-48c3-9e45-a3e005b2044d": {
"main": [
[
{
"node": "d6e01bb8-c5d3-48fd-88ae-5b5a3a6b7081",
"type": "main",
"index": 0
}
],
[
{
"node": "1e898452-a205-43a7-bf15-ec90305a9e8d",
"type": "main",
"index": 0
}
],
[
{
"node": "4221c708-7abe-441f-b6ec-b094e827f934",
"type": "main",
"index": 0
}
],
[
{
"node": "09650916-d4b7-46d0-933e-916814e2bc33",
"type": "main",
"index": 0
}
]
]
},
"cedc60ed-38c6-440e-bb70-fe037e57b238": {
"main": [
[
{
"node": "3025cc68-8d55-4ac4-b4f6-7ed8ea7176b6",
"type": "main",
"index": 0
}
]
]
},
"43ebdd05-9eba-4a78-a143-229ce0f0b61f": {
"main": [
[
{
"node": "6297b646-2788-49a1-b9ca-133892d34c13",
"type": "main",
"index": 0
}
]
]
},
"d6e01bb8-c5d3-48fd-88ae-5b5a3a6b7081": {
"main": [
[
{
"node": "3010eed3-58c7-41ca-8107-8e1409247c63",
"type": "main",
"index": 0
}
]
]
},
"ef30f65a-2699-4d1b-830a-8d2197c1b768": {
"main": [
[
{
"node": "1d426d09-8892-4e4d-807f-15fcd89036c1",
"type": "main",
"index": 0
}
]
]
},
"05bd883f-a194-4e1f-bf60-291874c733cf": {
"main": [
[
{
"node": "91c0a34b-d8d9-4fa4-879e-9864e616feec",
"type": "main",
"index": 0
}
]
]
},
"b655347c-9fda-4a4e-a7a2-12bbd7e6b246": {
"main": [
[
{
"node": "52b35908-e231-4c4f-b739-a559f2cf84b8",
"type": "main",
"index": 0
}
]
]
},
"a443f5ba-9dd8-4771-9531-0da98494d514": {
"main": [
[
{
"node": "4b886cf9-9006-4895-8070-8c4cfd9d45d3",
"type": "main",
"index": 0
}
]
]
},
"6297b646-2788-49a1-b9ca-133892d34c13": {
"main": [
[
{
"node": "2a0d8c5c-29f6-4b40-8a71-f2ae0ef26dca",
"type": "main",
"index": 0
}
]
]
},
"65fd019c-c128-47ca-b519-659547d67dd8": {
"main": [
[
{
"node": "804eff08-b03e-44e6-8fef-8792d7df7d57",
"type": "main",
"index": 0
}
]
]
},
"9cdc509c-5b1f-44c6-b4c4-8202cd9ff234": {
"main": [
[
{
"node": "b655347c-9fda-4a4e-a7a2-12bbd7e6b246",
"type": "main",
"index": 0
}
]
]
},
"2a0d8c5c-29f6-4b40-8a71-f2ae0ef26dca": {
"main": [
[
{
"node": "9cdc509c-5b1f-44c6-b4c4-8202cd9ff234",
"type": "main",
"index": 0
}
]
]
},
"6af5e73e-4fb2-449e-8570-d8faa702913a": {
"main": [
[
{
"node": "3e16c955-9ec6-4814-9fd2-afb85d1e89ae",
"type": "main",
"index": 0
}
]
]
},
"ad6d2c80-08da-4f73-9295-f6332d7e869c": {
"main": [
[
{
"node": "6af5e73e-4fb2-449e-8570-d8faa702913a",
"type": "main",
"index": 0
}
]
]
},
"52b35908-e231-4c4f-b739-a559f2cf84b8": {
"main": [
[
{
"node": "fe7de858-3240-4828-bade-9f8e02cb5d4a",
"type": "main",
"index": 0
}
]
]
},
"4b886cf9-9006-4895-8070-8c4cfd9d45d3": {
"main": [
[
{
"node": "d3a47b59-93b1-4c10-ae8d-0e7a1a8db5bc",
"type": "main",
"index": 0
}
]
]
},
"3010eed3-58c7-41ca-8107-8e1409247c63": {
"main": [
[
{
"node": "cedc60ed-38c6-440e-bb70-fe037e57b238",
"type": "main",
"index": 0
}
]
]
},
"83e91c12-b93b-4280-8165-e9c5721fa128": {
"main": [
[
{
"node": "7f396759-1d1e-45c7-8233-610876dc2dda",
"type": "main",
"index": 0
}
]
]
},
"1e898452-a205-43a7-bf15-ec90305a9e8d": {
"main": [
[
{
"node": "43ebdd05-9eba-4a78-a143-229ce0f0b61f",
"type": "main",
"index": 0
}
]
]
},
"09650916-d4b7-46d0-933e-916814e2bc33": {
"main": [
[
{
"node": "65fd019c-c128-47ca-b519-659547d67dd8",
"type": "main",
"index": 0
}
]
]
},
"7f396759-1d1e-45c7-8233-610876dc2dda": {
"main": [
[
{
"node": "ad6d2c80-08da-4f73-9295-f6332d7e869c",
"type": "main",
"index": 0
}
]
]
},
"8bb9df05-663d-42e5-b2c4-b99350c1438e": {
"main": [
[
{
"node": "856af42e-b2df-4f16-a601-8c4b51a3e3fc",
"type": "main",
"index": 0
}
]
]
},
"4221c708-7abe-441f-b6ec-b094e827f934": {
"main": [
[
{
"node": "83e91c12-b93b-4280-8165-e9c5721fa128",
"type": "main",
"index": 0
}
]
]
},
"113734a6-70eb-40ef-b527-07455e4e8253": {
"main": [
[
{
"node": "eb3140eb-0075-45e3-be18-c41b9c22021a",
"type": "main",
"index": 0
}
]
]
},
"3ac317e2-fe93-48aa-b9ea-9d4b5bdb4ea7": {
"main": [
[
{
"node": "59daa2b4-5a86-4b90-ab4a-ffb2792e6bb6",
"type": "main",
"index": 0
}
]
]
}
}
}¿Cómo usar este flujo de trabajo?
Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.
¿En qué escenarios es adecuado este flujo de trabajo?
Avanzado - DevOps, IA Multimodal
¿Es de pago?
Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.
Flujos de trabajo relacionados recomendados
Jimmy Gay
@jimmyjoeCompartir este flujo de trabajo