This workflow corresponds to n8n.io template #7464 — we link there as the canonical source.
This workflow follows the Google Drive → Google Sheets recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "968b5375-141c-4cad-b077-f0d5a84e162e",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
-1700,
780
],
"parameters": {
"path": "ops/n8n",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode",
"authentication": "headerAuth"
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"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": "Get a workflow1",
"type": "n8n-nodes-base.n8n",
"position": [
220,
1180
],
"parameters": {
"operation": "get",
"workflowId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "ef30f65a-2699-4d1b-830a-8d2197c1b768",
"name": "\ud83d\udd10 Security Validator",
"type": "n8n-nodes-base.code",
"position": [
-1440,
780
],
"parameters": {
"jsCode": "// Acc\u00e9der aux headers du webhook via $json.headers\nconst authHeader = $json.headers?.authorization || '';\nconst expectedToken = 'Bearer YOUR_TOKEN_HERE 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\u00e9der 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\u00e9es\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": "\ud83d\udd00 Action Router",
"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": "\ud83d\udcca Parse Audit Data",
"type": "n8n-nodes-base.code",
"position": [
220,
60
],
"parameters": {
"jsCode": "// Node Code \u00e0 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": "\ud83d\udd0d Filter Workflows",
"type": "n8n-nodes-base.code",
"position": [
-60,
280
],
"parameters": {
"jsCode": "// Filtrer les workflows selon les crit\u00e8res sp\u00e9cifi\u00e9s\nconst workflows = $input.all();\nconst filters = $('\ud83d\udd00 Action Router').item.json.filters || {};\nconst options = $('\ud83d\udd00 Action Router').item.json.options || {};\n\n// Workflows prot\u00e9g\u00e9s - s\u00e9curit\u00e9 renforc\u00e9e\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\u00e9cifi\u00e9\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\u00e9cifi\u00e9\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\u00e9g\u00e9s (s\u00e9curit\u00e9 prioritaire)\nfilteredWorkflows = filteredWorkflows.filter(wf => {\n if (protectedWorkflows.includes(wf.json.name)) {\n console.warn(`\u26a0\ufe0f Workflow prot\u00e9g\u00e9 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": "\ud83d\udccb Get Workflow Details",
"type": "n8n-nodes-base.n8n",
"position": [
220,
280
],
"parameters": {
"operation": "get",
"workflowId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "2a0d8c5c-29f6-4b40-8a71-f2ae0ef26dca",
"name": "\u2699\ufe0f Prepare Update JSON",
"type": "n8n-nodes-base.code",
"position": [
500,
280
],
"parameters": {
"jsCode": "const workflowData = $('\ud83d\udccb Get Workflow Details').item.json;\n\n// \u2705 Propri\u00e9t\u00e9s settings MINIMALES et g\u00e9n\u00e9ralement autoris\u00e9es\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, // \u2705 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": "\ud83e\udd16 AI Filter for Duplicate",
"type": "n8n-nodes-base.code",
"position": [
-60,
740
],
"parameters": {
"jsCode": "// Filtrer les workflows pour duplication selon les crit\u00e8res optimis\u00e9s avec IA\nconst workflows = $input.all();\nconst filters = $('\ud83d\udd00 Action Router').item.json.filters || {};\nconst options = $('\ud83d\udd00 Action Router').item.json.options || {};\n\n// Workflows prot\u00e9g\u00e9s - s\u00e9curit\u00e9 renforc\u00e9e\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\u00e9cifi\u00e9\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\u00e9cifi\u00e9\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\u00e9g\u00e9s (s\u00e9curit\u00e9 prioritaire)\nfilteredWorkflows = filteredWorkflows.filter(wf => {\n if (protectedWorkflows.includes(wf.json.name)) {\n console.warn(`\u26a0\ufe0f Workflow prot\u00e9g\u00e9 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// \ud83d\ude80 **LOGIQUE D'INTELLIGENCE ARTIFICIELLE POUR \u00c9VALUER L'INT\u00c9R\u00caT**\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\u00e8me de scoring intelligent\nfilteredWorkflows = filteredWorkflows.filter(wf => {\n const json = wf.json;\n let score = 0;\n let reasons = [];\n\n // \ud83d\udcca CRIT\u00c8RE 1: Statut d'activit\u00e9 (+2 points)\n if (json.active) {\n score += 2;\n reasons.push('actif');\n }\n\n // \ud83d\udd27 CRIT\u00c8RE 2: Complexit\u00e9 du workflow (bas\u00e9e sur le nombre de n\u0153uds)\n if (json.nodes && json.nodes.length > 20) {\n score += 3;\n reasons.push(`complexe (${json.nodes.length} n\u0153uds)`);\n } else if (json.nodes && json.nodes.length > 10) {\n score += 1;\n reasons.push(`mod\u00e9r\u00e9ment complexe (${json.nodes.length} n\u0153uds)`);\n }\n\n // \ud83c\udff7\ufe0f CRIT\u00c8RE 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 // \u23f0 CRIT\u00c8RE 4: R\u00e9cence des modifications\n if (json.updatedAt) {\n const days = daysSince(json.updatedAt);\n if (days < 7) {\n score += 3;\n reasons.push('r\u00e9cemment modifi\u00e9 (<7j)');\n } else if (days < 30) {\n score += 1;\n reasons.push('modifi\u00e9 r\u00e9cemment (<30j)');\n }\n }\n\n // \ud83d\udcbc CRIT\u00c8RE 5: Analyse s\u00e9mantique 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\u00e9rant un workflow business-critique');\n }\n\n // \ud83d\udcc8 CRIT\u00c8RE 6: D\u00e9clencheurs multiples (workflows complexes)\n if (json.triggerCount && json.triggerCount > 1) {\n score += 1;\n reasons.push(`${json.triggerCount} d\u00e9clencheurs`);\n }\n\n // \ud83c\udfaf D\u00c9CISION FINALE : Seuil d'int\u00e9r\u00eat\n const isInteresting = score >= 3;\n \n // Logging pour debug\n if (isInteresting) {\n console.log(`\u2705 Workflow \"${json.name}\" s\u00e9lectionn\u00e9 (score: ${score}) - Raisons: ${reasons.join(', ')}`);\n } else {\n console.log(`\u274c Workflow \"${json.name}\" ignor\u00e9 (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": "\ud83d\udccb Get Details for Duplicate",
"type": "n8n-nodes-base.n8n",
"position": [
220,
740
],
"parameters": {
"operation": "get",
"workflowId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "ad6d2c80-08da-4f73-9295-f6332d7e869c",
"name": "\ud83d\udd04 Prepare Duplicate Data",
"type": "n8n-nodes-base.code",
"position": [
500,
740
],
"parameters": {
"jsCode": "// Pr\u00e9parer les donn\u00e9es pour dupliquer TOUS les workflows\nconst allWorkflowsData = $('\ud83d\udccb Get Details for Duplicate').all();\n\nconsole.log(`\ud83d\udd04 Traitement de ${allWorkflowsData.length} workflows pour duplication`);\n\nconst results = [];\n\nallWorkflowsData.forEach((workflowItem, index) => {\n const workflowData = workflowItem.json;\n \n // G\u00e9n\u00e9rer 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\u00e9parer le payload pour la cr\u00e9ation 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\u00e9er inactif par s\u00e9curit\u00e9\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\u0153uds pour \u00e9viter les conflits\n if (duplicatePayload.nodes) {\n duplicatePayload.nodes = duplicatePayload.nodes.map(node => {\n const newNode = { ...node };\n // G\u00e9n\u00e9rer 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(`\ud83d\udd04 Pr\u00e9paration duplication ${index + 1}/${allWorkflowsData.length}: \"${originalName}\" \u2192 \"${duplicateName}\"`);\n console.log(`\ud83d\udcca N\u0153uds \u00e0 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(`\u2705 ${results.length} workflows pr\u00e9par\u00e9s pour duplication`);\nconsole.log(`\ud83c\udff7\ufe0f Tags ajout\u00e9s: backup, duplicate (avec index unique)`);\n\nreturn results;\n"
},
"typeVersion": 2
},
{
"id": "6af5e73e-4fb2-449e-8570-d8faa702913a",
"name": "\ud83d\udcdd Convert to JSON String",
"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": "\ud83e\udde0 AI Filter for Export",
"type": "n8n-nodes-base.code",
"position": [
-60,
1180
],
"parameters": {
"jsCode": "// Filtrage intelligent des workflows pour export\nconst workflows = $input.all();\nconst filters = $('\ud83d\udd00 Action Router').item.json.filters || {};\nconst options = $('\ud83d\udd00 Action Router').item.json.options || {};\n\n// Workflows syst\u00e8me (toujours inclus en export car critiques)\nconst systemWorkflows = ['n8n-auto-maintenance', 'Security', 'Backup'];\n\nlet filteredWorkflows = workflows;\n\n// \ud83e\udde0 INTELLIGENCE ARTIFICIELLE : Syst\u00e8me de scoring pour workflows pertinents\nfunction calculateExportValue(workflow) {\n const json = workflow.json;\n let score = 0;\n let reasons = [];\n\n // \ud83d\udd25 CRIT\u00c8RE 1: Workflows syst\u00e8me (toujours prioritaires)\n if (systemWorkflows.includes(json.name)) {\n score += 10;\n reasons.push('workflow syst\u00e8me critique');\n }\n\n // \ud83d\udcbc CRIT\u00c8RE 2: Workflows business-critiques (analyse s\u00e9mantique)\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\u00e9rant un workflow business-critique');\n }\n\n // \ud83c\udff7\ufe0f CRIT\u00c8RE 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 // \u26a1 CRIT\u00c8RE 4: Workflows actifs (en utilisation)\n if (json.active) {\n score += 3;\n reasons.push('workflow actif');\n }\n\n // \ud83d\udd27 CRIT\u00c8RE 5: Complexit\u00e9 technique (workflows sophistiqu\u00e9s)\n if (json.nodes && json.nodes.length > 15) {\n score += 3;\n reasons.push(`workflow complexe (${json.nodes.length} n\u0153uds)`);\n } else if (json.nodes && json.nodes.length > 8) {\n score += 1;\n reasons.push(`workflow mod\u00e9r\u00e9ment complexe (${json.nodes.length} n\u0153uds)`);\n }\n\n // \u23f0 CRIT\u00c8RE 6: Activit\u00e9 r\u00e9cente (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\u00e9cemment modifi\u00e9 (<30j)');\n } else if (daysSince < 90) {\n score += 1;\n reasons.push('modifi\u00e9 r\u00e9cemment (<90j)');\n }\n }\n\n // \ud83d\udcc8 CRIT\u00c8RE 7: Workflows avec d\u00e9clencheurs (automation active)\n if (json.triggerCount && json.triggerCount > 0) {\n score += 2;\n reasons.push(`${json.triggerCount} d\u00e9clencheur(s)`);\n }\n\n // \ud83d\udeab CRIT\u00c8RES DE P\u00c9NALIT\u00c9 (workflows \u00e0 \u00e9viter)\n \n // P\u00e9nalit\u00e9 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 \u00eatre un workflow de test/demo');\n }\n\n // P\u00e9nalit\u00e9 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(`\ud83d\udd0d Filtrage par nom: ${filteredWorkflows.length} workflows correspondent \u00e0 \"${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(`\ud83c\udff7\ufe0f Filtrage par tags: ${filteredWorkflows.length} workflows avec tags requis`);\n}\n\n// \ud83e\udde0 S\u00c9LECTION 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\u00e8me\nconst selectedWorkflows = scoredWorkflows.filter(item => {\n const isSelected = item.score >= 5 || systemWorkflows.includes(item.workflow.json.name);\n \n if (isSelected) {\n console.log(`\u2705 \"${item.workflow.json.name}\" s\u00e9lectionn\u00e9 (score: ${item.score}) - ${item.reasons.join(', ')}`);\n } else {\n console.log(`\u274c \"${item.workflow.json.name}\" ignor\u00e9 (score: ${item.score}) - ${item.reasons.join(', ')}`);\n }\n \n return isSelected;\n});\n\n// Si mode \"force include\" activ\u00e9, 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(`\ud83d\udfe1 \"${item.workflow.json.name}\" inclus (mode \u00e9tendu - 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(`\ud83d\udcca STATISTIQUES EXPORT:`);\nconsole.log(`\ud83d\udce6 Total workflows: ${stats.total}`);\nconsole.log(`\ud83d\udd0d Apr\u00e8s filtres manuels: ${stats.afterFilters}`);\nconsole.log(`\u2705 S\u00e9lectionn\u00e9s pour export: ${stats.selected}`);\nconsole.log(`\ud83d\udd25 Haute valeur (score \u22658): ${stats.highValue}`);\nconsole.log(`\u2699\ufe0f Workflows syst\u00e8me: ${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": "\ud83d\udce4 Prepare Export Data",
"type": "n8n-nodes-base.code",
"position": [
500,
1180
],
"parameters": {
"jsCode": "// Pr\u00e9parer les donn\u00e9es d'export avec m\u00e9tadonn\u00e9es compl\u00e8tes - VERSION CORRIG\u00c9E\nconst allWorkflows = $input.all();\nconst exportTimestamp = new Date().toISOString();\nconst exportDate = exportTimestamp.split('T')[0]; // Format YYYY-MM-DD\n\nconsole.log(`\ud83d\udce4 Pr\u00e9paration export de ${allWorkflows.length} workflows s\u00e9lectionn\u00e9s intelligemment`);\n\n// Statistiques en temps r\u00e9el\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 \u00e0 jour des statistiques\n stats.totalNodes += nodeCount;\n if (workflow.active) stats.activeWorkflows++;\n else stats.inactiveWorkflows++;\n \n // D\u00e9tection 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\u00e9tection 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 // \u2705 CORRECTION : R\u00e9cup\u00e9rer le score depuis les donn\u00e9es du n\u0153ud actuel\n const exportScore = item.json.exportScore || 5; // Score par d\u00e9faut si absent\n const exportReasons = item.json.exportReasons || ['s\u00e9lectionn\u00e9 par filtrage intelligent'];\n if (exportScore >= 8) stats.highValueWorkflows++;\n \n // Structure d'export optimis\u00e9e\n return {\n // M\u00e9tadonn\u00e9es 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\u00e9tadonn\u00e9es 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\u0153uds (pour statistiques)\n nodeTypes: workflow.nodes ? \n [...new Set(workflow.nodes.map(node => node.type))].sort() : [],\n \n // Credentials utilis\u00e9s (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\u00e9\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\u00e8te avec m\u00e9tadonn\u00e9es riches\nconst exportData = {\n // En-t\u00eate d'export\n metadata: {\n exportDate: exportDate,\n exportTimestamp: exportTimestamp,\n exportedBy: 'n8n-auto-maintenance',\n exportVersion: '2.0',\n sourceInstance: 'n8n-production', // \u00c0 adapter\n \n // Statistiques d\u00e9taill\u00e9es\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\u00e9es des workflows\n workflows: processedWorkflows\n};\n\n// G\u00e9n\u00e9ration 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\u00e9taill\u00e9s pour monitoring\nconsole.log(`\ud83d\udcca === STATISTIQUES D'EXPORT D\u00c9TAILL\u00c9ES ===`);\nconsole.log(`\ud83d\udce6 Total workflows export\u00e9s: ${stats.totalWorkflows}`);\nconsole.log(`\u26a1 Workflows actifs: ${stats.activeWorkflows} (${stats.activationRate}%)`);\nconsole.log(`\ud83d\udca4 Workflows inactifs: ${stats.inactiveWorkflows}`);\nconsole.log(`\ud83d\udd27 Total n\u0153uds: ${stats.totalNodes} (moyenne: ${stats.averageNodesPerWorkflow})`);\nconsole.log(`\ud83d\udd11 Avec credentials: ${stats.workflowsWithCredentials} (${stats.credentialCoverage}%)`);\nconsole.log(`\u26a1 Avec triggers: ${stats.workflowsWithTriggers}`);\nconsole.log(`\u2699\ufe0f Workflows syst\u00e8me: ${stats.systemWorkflows}`);\nconsole.log(`\ud83d\udcbc Business-critiques: ${stats.businessCritical}`);\nconsole.log(`\ud83d\udd25 Haute valeur (score \u22658): ${stats.highValueWorkflows}`);\nconsole.log(`\ud83d\udcc4 Taille export: ${JSON.stringify(exportData).length} caract\u00e8res`);\nconsole.log(`\ud83d\udcc1 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": "\ud83d\udcbe Prepare Binary Response",
"type": "n8n-nodes-base.code",
"position": [
-320,
960
],
"parameters": {
"jsCode": "// Pr\u00e9parer la r\u00e9ponse binaire pour t\u00e9l\u00e9chargement - VERSION CORRIG\u00c9E\nconst exportData = $json.exportData;\nconst filename = $json.filename;\nconst stats = $json.stats;\n\nconsole.log(`\ud83d\udce4 Pr\u00e9paration r\u00e9ponse binaire pour export: ${filename}`);\nconsole.log(`\ud83d\udcca Workflows \u00e0 t\u00e9l\u00e9charger: ${stats.totalWorkflows}`);\n\n// \u2705 CORRECTION : Cr\u00e9er le contenu JSON avec Buffer.from()\nconst jsonContent = JSON.stringify(exportData, null, 2);\nconst binaryData = Buffer.from(jsonContent, 'utf8');\n\nconsole.log(`\ud83d\udcc4 Taille fichier: ${binaryData.length} bytes (${Math.round(binaryData.length/1024)} KB)`);\n\n// \u2705 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": "\ud83d\udcc2 Get All Workflows",
"type": "n8n-nodes-base.n8n",
"position": [
-320,
60
],
"parameters": {
"filters": {
"tags": "",
"activeWorkflows": false
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "3010eed3-58c7-41ca-8107-8e1409247c63",
"name": "\ud83d\udd12 Generate Security Audit",
"type": "n8n-nodes-base.n8n",
"position": [
-60,
60
],
"parameters": {
"resource": "audit",
"operation": "generate",
"requestOptions": {},
"additionalOptions": {}
},
"credentials": {
"n8nApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "1e898452-a205-43a7-bf15-ec90305a9e8d",
"name": "\u23f8\ufe0f Get Workflows to Pause",
"type": "n8n-nodes-base.n8n",
"position": [
-320,
280
],
"parameters": {
"filters": {
"activeWorkflows": true
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "4221c708-7abe-441f-b6ec-b094e827f934",
"name": "\ud83d\udccb Get Workflows to Duplicate",
"type": "n8n-nodes-base.n8n",
"position": [
-320,
740
],
"parameters": {
"filters": {
"activeWorkflows": true
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "09650916-d4b7-46d0-933e-916814e2bc33",
"name": "\ud83d\udce6 Get Workflows for Export",
"type": "n8n-nodes-base.n8n",
"position": [
-320,
1180
],
"parameters": {
"filters": {
"activeWorkflows": false
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "9cdc509c-5b1f-44c6-b4c4-8202cd9ff234",
"name": "\u23f8\ufe0f Deactivate Workflow",
"type": "n8n-nodes-base.n8n",
"position": [
-320,
500
],
"parameters": {
"operation": "deactivate",
"workflowId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.workflowId }}"
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "b655347c-9fda-4a4e-a7a2-12bbd7e6b246",
"name": "\ud83d\udcc4 Get Workflow Status",
"type": "n8n-nodes-base.n8n",
"position": [
-60,
500
],
"parameters": {
"operation": "get",
"workflowId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "52b35908-e231-4c4f-b739-a559f2cf84b8",
"name": "\u23f0 Wait 8h for Reactivation",
"type": "n8n-nodes-base.wait",
"position": [
220,
500
],
"parameters": {
"unit": "hours",
"amount": 8
},
"typeVersion": 1.1
},
{
"id": "fe7de858-3240-4828-bade-9f8e02cb5d4a",
"name": "\u25b6\ufe0f Reactivate Workflows",
"type": "n8n-nodes-base.n8n",
"position": [
500,
500
],
"parameters": {
"operation": "activate",
"workflowId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "3e16c955-9ec6-4814-9fd2-afb85d1e89ae",
"name": "\u2795 Create Duplicate Workflow",
"type": "n8n-nodes-base.n8n",
"position": [
500,
960
],
"parameters": {
"operation": "create",
"requestOptions": {},
"workflowObject": "={{ $json.workflowJSON }}"
},
"credentials": {
"n8nApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "8bb9df05-663d-42e5-b2c4-b99350c1438e",
"name": "\ud83d\udcc5 Daily Pause Schedule (22h)",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-2260,
780
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 22
}
]
}
},
"typeVersion": 1.2
},
{
"id": "3ac317e2-fe93-48aa-b9ea-9d4b5bdb4ea7",
"name": "\ud83d\udcc5 Weekly Audit Schedule (Mon 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": "\ud83d\udcc5 Monthly Export Schedule (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": "\ud83c\udfaf Manual Test Trigger",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-2260,
960
],
"parameters": {},
"typeVersion": 1
},
{
"id": "59daa2b4-5a86-4b90-ab4a-ffb2792e6bb6",
"name": "\ud83d\udcca Example: Audit Request",
"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_TOKEN_HERE"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "856af42e-b2df-4f16-a601-8c4b51a3e3fc",
"name": "\u23f8\ufe0f Example: Pause Request",
"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_TOKEN_HERE"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "91c0a34b-d8d9-4fa4-879e-9864e616feec",
"name": "\ud83d\udd04 Example: Duplicate Request",
"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_TOKEN_HERE"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "eb3140eb-0075-45e3-be18-c41b9c22021a",
"name": "\ud83d\udce4 Example: Export Request",
"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_TOKEN_HERE"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "29741645-14c0-41de-b385-bd8a7a415513",
"name": "\u274c Authentication Error",
"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": "\ud83d\udcc8 Save to Google Sheets",
"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": {
"name": "<your credential>"
}
},
"typeVersion": 4.6
},
{
"id": "d3a47b59-93b1-4c10-ae8d-0e7a1a8db5bc",
"name": "\u2601\ufe0f Save to Google Drive",
"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": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "683fb61e-0867-4766-9f2f-c463a6045e2a",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2780,
520
],
"parameters": {
"width": 1000,
"height": 840,
"content": "# \ud83d\udd27 n8n Auto-Maintenance System\n\n## Overview\nAdvanced workflow automation with AI-powered intelligent selection\n\n## \ud83c\udfaf Core Actions\n- **\ud83d\udd12 AUDIT**: Security analysis & reporting\n- **\u23f8\ufe0f PAUSE**: Temporary workflow suspension \n- **\ud83d\udd04 DUPLICATE**: Smart backup creation\n- **\ud83d\udce4 EXPORT**: Complete system backup\n\n## \u2728 Key Features\n- \ud83e\udd16 AI-driven workflow filtering\n- \ud83d\udd10 Secure token-based authentication\n- \ud83d\udcca Automated reporting to Google Sheets\n- \u2601\ufe0f Google Drive integration\n- \u26a1 Scheduled maintenance cycles\n"
},
"typeVersion": 1
},
{
"id": "8faa0c78-0d50-4674-a6b9-e85b7d3436fa",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-980,
-220
],
"parameters": {
"color": 6,
"width": 600,
"height": 540,
"content": "# \ud83e\udde0 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## \ud83c\udfaf Selection Thresholds\n- **Duplicate**: \u22653 points\n- **Export**: \u22655 points or system workflow\n\n## \ud83d\udd0d Pattern Recognition\nAutomatically detects business-critical workflows using semantic analysis\n"
},
"typeVersion": 1
},
{
"id": "7b387337-4df9-42aa-8ba2-d136911184cc",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1700,
120
],
"parameters": {
"color": 3,
"width": 660,
"height": 520,
"content": "# \ud83d\udd10 Security Framework\n\n## Authentication\n- \u2705 **Bearer YOUR_TOKEN_HERE** validation required\n- \u2705 **Request format** validation\n- \u2705 **Action whitelist** enforcement\n- \u2705 **Error handling** with proper HTTP codes\n\n## Protected Workflows\n> **\u26a0\ufe0f Never modified by automation**\n\n- `n8n-auto-maintenance`\n- `Security` \n- `Backup`\n\n## Supported Actions\n`audit` \u2022 `pause` \u2022 `resume` \u2022 `duplicate` \u2022 `export` \u2022 `cleanup`\n"
},
"typeVersion": 1
},
{
"id": "bf26f38f-da76-4498-a671-85044372dc21",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1700,
1100
],
"parameters": {
"color": 4,
"width": 760,
"height": 500,
"content": "# \u2699\ufe0f Configuration & Scheduling\n\n## Default Schedules\n- **\ud83d\udd12 Audit**: Weekly (Monday 21:00)\n- **\u23f8\ufe0f Pause**: Daily (22:00) \n- **\ud83d\udce4 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": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
840,
-1220
],
"parameters": {
"width": 1600,
"height": 4160,
"content": "# \ud83d\udd27 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## \ud83d\udccb 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### \u2728 Key Features\n\n- **\ud83e\udd16 AI-Driven Selection**: Intelligent workflow filtering using multi-criteria scoring\n- **\ud83d\udd10 Secure Authentication**: Token-based security with protected workflows \n- **\ud83d\udcca Automated Reporting**: Security audit results to Google Sheets\n- **\u2601\ufe0f Cloud Integration**: Export backups to Google Drive\n- **\u26a1 Scheduled Operations**: Automated maintenance cycles\n- **\ud83c\udfaf Granular Control**: Tag-based and pattern filtering\n\n## \ud83c\udfaf Core Actions\n\n| Action | Description | Trigger | AI Filter |\n|--------|-------------|---------|-----------|\n| **\ud83d\udd12 AUDIT** | Security analysis & reporting | Weekly (Mon 21:00) | \u274c |\n| **\u23f8\ufe0f PAUSE** | Temporary workflow suspension | Daily (22:00) | \u2705 | \n| **\ud83d\udd04 DUPLICATE** | Smart backup creation | On-demand | \u2705 (\u22653 pts) |\n| **\ud83d\udce4 EXPORT** | Complete system backup | Monthly (1st, 09:00) | \u2705 (\u22655 pts) |\n\n## \ud83d\ude80 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 \u2192 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_TOKEN_HERE\"\n-H \"Content-Type: application/json\"\n-d '{\"action\":\"audit\",\"options\":{\"reason\":\"Setup test\"}}'\n\n\n## \ud83d\udcd6 Detailed Documentation\n\n- [\ud83d\udccb Installation Guide](docs/installation.md)\n- [\ud83d\udd27 Configuration Reference](docs/configuration.md)\n- [\ud83e\udd16 AI Filtering Logic](docs/ai-filtering.md)\n- [\ud83d\udd12 Security Best Practices](docs/security.md)\n- [\ud83d\udc1b Troubleshooting](docs/troubleshooting.md)\n\n## \ud83e\udd16 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**: \u22653 points (smart backup selection)\n- **Export**: \u22655 points or system workflow (comprehensive backup)\n\n## \ud83d\udd10 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 YOUR_TOKEN_HERE required for all operations\n- Request validation and sanitization\n- Action whitelist enforcement\n- Comprehensive error handling\n\n## \ud83d\udcca 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## \ud83d\udee0\ufe0f 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## \ud83d\udcc8 Changelog\n\n### v2.0.0 (Latest)\n- \u2728 AI-powered workflow selection\n- \ud83d\udd12 Enhanced security framework\n- \ud83d\udcca Advanced reporting capabilities\n- \u2601\ufe0f Google Drive integration\n- \ud83c\udfaf Granular filtering options\n\n## \ud83e\udd1d 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## \ud83d\udcc4 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## \ud83d\ude4f 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\u2b50 **Star this repo if it helped you automate your n8n maintenance!**\n\n"
},
"typeVersion": 1
}
],
"connections": {
"If": {
"main": [
[
{
"node": "\ud83d\udd00 Action Router",
"type": "main",
"index": 0
}
],
[
{
"node": "\u274c Authentication Error",
"type": "main",
"index": 0
}
]
]
},
"Webhook": {
"main": [
[
{
"node": "\ud83d\udd10 Security Validator",
"type": "main",
"index": 0
}
]
]
},
"Get a workflow1": {
"main": [
[
{
"node": "\ud83d\udce4 Prepare Export Data",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udd00 Action Router": {
"main": [
[
{
"node": "\ud83d\udcc2 Get All Workflows",
"type": "main",
"index": 0
}
],
[
{
"node": "\u23f8\ufe0f Get Workflows to Pause",
"type": "main",
"index": 0
}
],
[
{
"node": "\ud83d\udccb Get Workflows to Duplicate",
"type": "main",
"index": 0
}
],
[
{
"node": "\ud83d\udce6 Get Workflows for Export",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udcca Parse Audit Data": {
"main": [
[
{
"node": "\ud83d\udcc8 Save to Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udd0d Filter Workflows": {
"main": [
[
{
"node": "\ud83d\udccb Get Workflow Details",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udcc2 Get All Workflows": {
"main": [
[
{
"node": "\ud83d\udd12 Generate Security Audit",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udd10 Security Validator": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"\ud83c\udfaf Manual Test Trigger": {
"main": [
[
{
"node": "\ud83d\udd04 Example: Duplicate Request",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udcc4 Get Workflow Status": {
"main": [
[
{
"node": "\u23f0 Wait 8h for Reactivation",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udce4 Prepare Export Data": {
"main": [
[
{
"node": "\ud83d\udcbe Prepare Binary Response",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udccb Get Workflow Details": {
"main": [
[
{
"node": "\u2699\ufe0f Prepare Update JSON",
"type": "main",
"index": 0
}
]
]
},
"\ud83e\udde0 AI Filter for Export": {
"main": [
[
{
"node": "Get a workflow1",
"type": "main",
"index": 0
}
]
]
},
"\u23f8\ufe0f Deactivate Workflow": {
"main": [
[
{
"node": "\ud83d\udcc4 Get Workflow Status",
"type": "main",
"index": 0
}
]
]
},
"\u2699\ufe0f Prepare Update JSON": {
"main": [
[
{
"node": "\u23f8\ufe0f Deactivate Workflow",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udcdd Convert to JSON String": {
"main": [
[
{
"node": "\u2795 Create Duplicate Workflow",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udd04 Prepare Duplicate Data": {
"main": [
[
{
"node": "\ud83d\udcdd Convert to JSON String",
"type": "main",
"index": 0
}
]
]
},
"\u23f0 Wait 8h for Reactivation": {
"main": [
[
{
"node": "\u25b6\ufe0f Reactivate Workflows",
"type": "main",
"index": 0
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googleDriveOAuth2ApigoogleSheetsOAuth2ApihttpHeaderAuthn8nApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Transform your n8n instance management with this advanced automation system featuring artificial intelligence-driven workflow selection. This template provides comprehensive maintenance operations with smart filtering capabilities.
Source: https://n8n.io/workflows/7464/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Convalidaciones Académicas - Estructura Base. Uses googleSheets, emailSend, googleDrive, httpRequest. Webhook trigger; 35 nodes.
TrackCollect. Uses googleSheets, httpRequest, @n-octo-n/n8n-nodes-json-database, moveBinaryData. Webhook trigger; 31 nodes.
This workflow automatically saves files received via LINE Messaging API into Google Drive and logs the file details into a Google Sheet. It checks the file type against allowed types, organizes files
This workflow turns your Google Sheet into a fully automated AI video factory powered by Google Veo 3 via Vertex AI. Simply fill in your prompts, choose your video settings, tick a checkbox — and walk
WF02-선행기술검색. Uses httpRequest, googleDrive, googleSheets. Webhook trigger; 15 nodes.