Workflow n8n

Automatisation n8n : gestion des dépendances et auto-tagging

  • Ce workflow n8n a pour objectif de gérer les dépendances entre les sous-workflows et d'automatiser le processus de tagging dans votre environnement n8n. Il est particulièrement utile pour les équipes de développement et d'automatisation qui cherchent à maintenir une organisation claire de leurs workflows tout en évitant les doublons. En intégrant des appels HTTP pour récupérer les workflows et les tags existants, ce workflow permet également d'identifier les nouveaux appelants et de créer des tags correspondants.
  • Le processus commence par un déclencheur planifié qui s'exécute chaque dimanche, suivi de l'activation du workflow. Ensuite, il récupère tous les workflows existants et filtre ceux qui ne sont pas appelés ou qui manquent. À partir de là, le workflow compte les appelants et identifie les nouveaux, en les séparant pour une création de tags efficace. Les étapes incluent des appels HTTP pour mettre à jour les tags, ainsi que des traitements pour visualiser les dépendances sous forme de graphique.
  • Les bénéfices de ce workflow résident dans la simplification de la gestion des workflows, la réduction des erreurs humaines lors de la création de tags et l'amélioration de la visibilité des dépendances. En utilisant ce workflow, les équipes peuvent gagner du temps et garantir une meilleure organisation de leurs processus d'automatisation n8n.
Tags clés :automatisationn8ngestion des workflowstaggingoptimisation
Catégorie: Scheduled · Tags: automatisation, n8n, gestion des workflows, tagging, optimisation0

Workflow n8n gestion des workflows, tagging, optimisation : vue d'ensemble

Schéma des nœuds et connexions de ce workflow n8n, généré à partir du JSON n8n.

Workflow n8n gestion des workflows, tagging, optimisation : détail des nœuds

  • Update workflow tags

    Met à jour les tags du workflow via une requête HTTP.

  • GET all workflows

    Récupère tous les workflows existants.

  • List callers of subworkflows

    Liste les appelants des sous-workflows à l'aide d'un code JavaScript.

  • Exclude uncalled workflows

    Exclut les workflows non appelés en fonction de certaines conditions.

  • Exclude missing workflows

    Exclut les workflows manquants selon des critères définis.

  • And every Sunday

    Déclenche le workflow chaque dimanche selon une règle programmée.

  • When this workflow is activated

    Déclenche le workflow lorsque celui-ci est activé.

  • GET workflow(s)

    Récupère un ou plusieurs workflows spécifiques.

  • Count callers and identify new callers

    Compte les appelants et identifie les nouveaux appelants.

  • Loop through workflows

    Parcourt les workflows en les divisant en lots.

  • GET all tags

    Récupère tous les tags existants via une requête HTTP.

  • Remove existing tags from new_callers list

    Supprime les tags existants de la liste des nouveaux appelants.

  • If any new callers

    Vérifie s'il y a de nouveaux appelants selon des conditions définies.

  • Split out new callers as new tags

    Sépare les nouveaux appelants en tant que nouveaux tags.

  • Create new tags

    Crée de nouveaux tags via une requête HTTP.

  • Return original pass through values

    Retourne les valeurs originales sans modification.

  • Merge

    Fusionne les données provenant de plusieurs sources.

  • GET all tags again

    Récupère à nouveau tous les tags via une requête HTTP.

  • Create tag id:name dictionary

    Crée un dictionnaire d'identifiants et de noms de tags.

  • Retrieve tag ids and names from dictionary

    Récupère les identifiants et noms de tags à partir du dictionnaire.

  • Return dependency graph data

    Retourne les données du graphique de dépendance.

  • Combine dependency graph values into labels

    Combine les valeurs du graphique de dépendance en étiquettes.

  • Visualize subworkflow dependency graph

    Visualise le graphique de dépendance des sous-workflows.

  • Sticky Note

    Crée une note autocollante avec des paramètres définis.

  • Sticky Note1

    Crée une autre note autocollante avec des paramètres définis.

  • Sticky Note2

    Crée une note autocollante supplémentaire avec des paramètres définis.

  • Sticky Note3

    Crée une note autocollante encore une fois avec des paramètres définis.

  • Sticky Note4

    Crée une note autocollante avec des paramètres définis.

  • Sticky Note7

    Crée une note autocollante avec des paramètres définis.

  • Sticky Note5

    Crée une note autocollante avec des paramètres définis.

  • Sticky Note6

    Crée une note autocollante avec des paramètres définis.

  • Sticky Note8

    Crée une note autocollante avec des paramètres définis.

  • SET instance_url

    Définit l'URL d'instance à l'aide d'assignations.

  • When viewed in a browser

    Déclenche le workflow lorsqu'il est visualisé dans un navigateur.

  • Sticky Note9

    Crée une note autocollante avec des paramètres définis.

  • Sticky Note10

    Crée une note autocollante avec des paramètres définis.

  • Format workflow relationship data for rendering

    Formate les données de relation des workflows pour le rendu.

  • Visualize dependency graph with MermaidJS

    Visualise le graphique de dépendance avec MermaidJS.

  • Sticky Note11

    Crée une note autocollante avec des paramètres définis.

  • Sticky Note12

    Crée une note autocollante avec des paramètres définis.

Inscris-toi pour voir l'intégralité du workflow

Inscription gratuite

S'inscrire gratuitementBesoin d'aide ?
{
  "id": "P9Jr9s9yfcDXTe9R",
  "meta": {
    "instanceId": "a9f3b18652ddc96459b459de4fa8fa33252fb820a9e5a1593074f3580352864a",
    "templateCredsSetupCompleted": true
  },
  "name": "n8n Subworkflow Dependency Graph & Auto-Tagging",
  "tags": [],
  "nodes": [
    {
      "id": "c3e6b9cb-4681-4778-b2f4-01c4a7d8c844",
      "name": "Update workflow tags",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3200,
        740
      ],
      "parameters": {
        "url": "={{ $('SET instance_url').item.json.instance_url }}/api/v1/workflows/{{ $json.id }}/tags",
        "method": "PUT",
        "options": {},
        "jsonBody": "={{ $json.tags }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "n8nApi"
      },
      "credentials": {
        "n8nApi": {
          "id": "XXXXXX",
          "name": "n8n account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "d348051c-cc81-40cf-9c9b-f42c6f16c9d6",
      "name": "GET all workflows",
      "type": "n8n-nodes-base.n8n",
      "position": [
        1000,
        0
      ],
      "parameters": {
        "filters": {},
        "requestOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "id": "XXXXXX",
          "name": "n8n account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "bd1c08e5-f8fa-46a0-bfa9-ced09373d3eb",
      "name": "List callers of subworkflows",
      "type": "n8n-nodes-base.code",
      "position": [
        1200,
        0
      ],
      "parameters": {
        "jsCode": "const workflows = $input.all();\nconst dependencyGraph = {};\n\n// Helper function to initialize a workflow entry\nconst getOrCreateWorkflowEntry = (id, name, tags) => {\n  if (!dependencyGraph[id]) {\n    dependencyGraph[id] = { id, name, callers: [], tags };\n  }\n  return dependencyGraph[id];\n};\n\n// Build lookup tables for workflow names and tags\nconst workflowNameMap = {};\nconst workflowTagsMap = {};\n\nworkflows.forEach(item => {\n  workflowNameMap[item.json.id] = item.json.name;\n  workflowTagsMap[item.json.id] = item.json.tags || [];\n});\n\n// Process each workflow\nworkflows.forEach(item => {\n  const { id: workflowId, name: workflowName, nodes = [], tags = [] } = item.json;\n  \n  // Ensure the workflow itself exists in the output, with its own tags\n  getOrCreateWorkflowEntry(workflowId, workflowName, tags);\n\n  // Process nodes that execute workflows\n  nodes.forEach(({ type, parameters }) => {\n    if (\n      type !== 'n8n-nodes-base.executeWorkflow' &&\n      type !== '@n8n/n8n-nodes-langchain.toolWorkflow'\n    ) return;\n\n    let subWorkflowId = parameters?.workflowId?.value || parameters?.workflowId;\n    if (subWorkflowId === \"={{ $workflow.id }}\") subWorkflowId = workflowId; // Handle self-referencing\n\n    if (subWorkflowId) {\n      const subWorkflowName = workflowNameMap[subWorkflowId] || \"Unknown Workflow\"; // Lookup name\n      const subWorkflowTags = workflowTagsMap[subWorkflowId] || []; // Lookup correct tags\n\n      const entry = getOrCreateWorkflowEntry(subWorkflowId, subWorkflowName, subWorkflowTags);\n\n      if (!entry.callers.includes(workflowId)) {\n        entry.callers.push(workflowId);\n      }\n    }\n  });\n});\n\n// Convert to an array format\nreturn Object.values(dependencyGraph);"
      },
      "typeVersion": 2
    },
    {
      "id": "8a1ad58d-feb4-428f-b1e3-df0c08486416",
      "name": "Exclude uncalled workflows",
      "type": "n8n-nodes-base.filter",
      "position": [
        1400,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "a1ccd5c3-ee85-412b-ac36-b68f9d2bc904",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.callers.length }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "d654ca59-f4d6-4b67-9e87-021346ded854",
      "name": "Exclude missing workflows",
      "type": "n8n-nodes-base.filter",
      "position": [
        1800,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "d12ad828-2f0c-4e2d-a6d5-de28007253cf",
              "operator": {
                "type": "boolean",
                "operation": "false",
                "singleValue": true
              },
              "leftValue": "={{ $json.hasField(\"error\") }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "56a8b861-0f20-4379-b094-ebd3976ab95c",
      "name": "And every Sunday",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        760,
        160
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "efacee31-5265-46e4-bc6d-c921a4169546",
      "name": "When this workflow is activated",
      "type": "n8n-nodes-base.n8nTrigger",
      "position": [
        760,
        0
      ],
      "parameters": {
        "events": [
          "activate"
        ]
      },
      "typeVersion": 1
    },
    {
      "id": "0eb2bb9b-0529-4d8e-bdd9-78e0373de744",
      "name": "GET workflow(s)",
      "type": "n8n-nodes-base.n8n",
      "onError": "continueRegularOutput",
      "position": [
        1600,
        0
      ],
      "parameters": {
        "operation": "get",
        "workflowId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "requestOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "id": "XXXXXX",
          "name": "n8n account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "24efc8dc-103f-44fb-b229-8b8785ec75ed",
      "name": "Count callers and identify new callers",
      "type": "n8n-nodes-base.set",
      "position": [
        2000,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "34f1dd94-28dc-4105-8e81-8fcf2672e631",
              "name": "id",
              "type": "string",
              "value": "={{ $('Exclude uncalled workflows').item.json.id }}"
            },
            {
              "id": "809b0f5d-4a4f-470c-a514-1e2dc7df92c4",
              "name": "name",
              "type": "string",
              "value": "={{ $('Exclude uncalled workflows').item.json.name }}"
            },
            {
              "id": "422ef66d-c26a-454c-85fd-856fca668782",
              "name": "callers",
              "type": "array",
              "value": "={{ $('Exclude uncalled workflows').item.json.callers }}"
            },
            {
              "id": "3353b704-871b-4b22-95c2-2e6fd5bb1df3",
              "name": "callers_count",
              "type": "number",
              "value": "={{ $('Exclude uncalled workflows').item.json.callers.length }}"
            },
            {
              "id": "b23ab78d-2136-4cc3-9b9a-1b5ed89d1e28",
              "name": "new_callers",
              "type": "array",
              "value": "={{ $('Exclude uncalled workflows').item.json.callers.difference($('Exclude uncalled workflows').item.json.tags.map(item => item.name)) }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "887bf07e-08f7-4491-aee4-a67ce0778319",
      "name": "Loop through workflows",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        2240,
        0
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "dd5379fa-74be-44b7-9d49-9b1ae3fab425",
      "name": "GET all tags",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2800,
        220
      ],
      "parameters": {
        "url": "={{ $json.instance_url }}/api/v1/tags",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "n8nApi"
      },
      "credentials": {
        "n8nApi": {
          "id": "XXXXXX",
          "name": "n8n account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "ba913e58-4c40-4e97-b4da-18ff3050a895",
      "name": "Remove existing tags from new_callers list",
      "type": "n8n-nodes-base.set",
      "position": [
        3000,
        220
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "0b40958a-6ab4-4e35-9aee-1d1346dfe8a6",
              "name": "id",
              "type": "string",
              "value": "={{ $('SET instance_url').item.json.id }}"
            },
            {
              "id": "95c97ab8-2945-4818-9a10-1ed1b69369bb",
              "name": "name",
              "type": "string",
              "value": "={{ $('SET instance_url').item.json.name }}"
            },
            {
              "id": "2ed9bf03-2b09-43e1-8cb5-5e6e3c9c9e99",
              "name": "callers",
              "type": "array",
              "value": "={{ $('SET instance_url').item.json.callers }}"
            },
            {
              "id": "3477c08a-7c35-4c0e-85bb-67144e12bff0",
              "name": "callers_count",
              "type": "number",
              "value": "={{ $('SET instance_url').item.json.callers_count }}"
            },
            {
              "id": "f816907e-f679-4573-a14b-2dce6ef69eb1",
              "name": "new_callers",
              "type": "array",
              "value": "={{ $('SET instance_url').item.json.new_callers.difference($json.data.map(item => item.name)) }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "745ed318-8c11-4eb7-8c62-82fa85d32dde",
      "name": "If any new callers",
      "type": "n8n-nodes-base.if",
      "position": [
        2600,
        560
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "42126431-2ae2-4265-aa4d-0d3e77a730b3",
              "operator": {
                "type": "array",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.new_callers }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "a22e9a9d-33ed-4c73-b557-03fc6eb572bd",
      "name": "Split out new callers as new tags",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        2800,
        440
      ],
      "parameters": {
        "options": {
          "destinationFieldName": "new_tag_name"
        },
        "fieldToSplitOut": "new_callers"
      },
      "typeVersion": 1
    },
    {
      "id": "2af955b7-f50f-4422-b5a7-4b330a350f5d",
      "name": "Create new tags",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3000,
        440
      ],
      "parameters": {
        "url": "={{ $('SET instance_url').item.json.instance_url }}/api/v1/tags",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "predefinedCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "name",
              "value": "={{ $json.new_tag_name }}"
            }
          ]
        },
        "nodeCredentialType": "n8nApi"
      },
      "credentials": {
        "n8nApi": {
          "id": "XXXXXX",
          "name": "n8n account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "03e389d8-3f48-4fcc-b097-7f631f4e98ad",
      "name": "Return original pass through values",
      "type": "n8n-nodes-base.code",
      "position": [
        3200,
        440
      ],
      "parameters": {
        "jsCode": "return $('SET instance_url').all();"
      },
      "typeVersion": 2
    },
    {
      "id": "8ff8a3f3-e12c-4206-916e-856e3e88c2ce",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        3400,
        560
      ],
      "parameters": {
        "mode": "combine",
        "options": {
          "includeUnpaired": true
        },
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3
    },
    {
      "id": "a1043d63-67e3-41d9-a5de-485068a9b5c7",
      "name": "GET all tags again",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2600,
        740
      ],
      "parameters": {
        "url": "={{ $('SET instance_url').item.json.instance_url }}/api/v1/tags",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "n8nApi"
      },
      "credentials": {
        "n8nApi": {
          "id": "XXXXXX",
          "name": "n8n account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "4a81485a-6f1a-44b3-8a2e-64190572f423",
      "name": "Create tag id:name dictionary",
      "type": "n8n-nodes-base.set",
      "position": [
        2800,
        740
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "b5f7ba8d-1b94-4cae-a0d1-f2f14c7cb5a3",
              "name": "tags",
              "type": "object",
              "value": "={{ $json.data.reduce((acc, { id, name }) => ({ ...acc, [id]: name }), {}) }}"
            },
            {
              "id": "23a993a4-26e1-474a-9f0a-cedc9792a2f2",
              "name": "callers",
              "type": "array",
              "value": "={{ $('Merge').item.json.callers }}"
            },
            {
              "id": "0d451e74-d701-4ddb-b11c-8d5aa3efdde6",
              "name": "id",
              "type": "string",
              "value": "={{ $('Merge').item.json.id }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a1dbb6f5-fc0e-4506-890a-64c0da6b5b8c",
      "name": "Retrieve tag ids and names from dictionary",
      "type": "n8n-nodes-base.set",
      "position": [
        3000,
        740
      ],
      "parameters": {
        "include": "selected",
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "762920de-98a6-4027-8e39-1244042f52e1",
              "name": "tags",
              "type": "array",
              "value": "={{ [$json].flatMap(item => item.callers.map(id => ({ id: Object.keys(item.tags).find(key => item.tags[key] === id) }))).filter(item => item.id); }}"
            },
            {
              "id": "1ff05b15-343a-49da-a70d-92c3a5d19011",
              "name": "id",
              "type": "string",
              "value": "={{ $json.id }}"
            },
            {
              "id": "f1afee56-a17f-422b-aabe-e59126efbb8e",
              "name": "callers",
              "type": "array",
              "value": "={{ $json.callers }}"
            },
            {
              "id": "39a0887c-8863-4968-9015-3add683eecd7",
              "name": "name",
              "type": "string",
              "value": "={{ $('Merge').item.json.name }}"
            },
            {
              "id": "4ae3b23c-1faf-4426-8e2e-5254a32d458b",
              "name": "callers_count",
              "type": "number",
              "value": "={{ $('Merge').item.json.callers_count }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "174d23bc-3aa1-4e05-81e2-8f45f92a16ee",
      "name": "Return dependency graph data",
      "type": "n8n-nodes-base.set",
      "position": [
        3400,
        740
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "eda3be17-95a6-457f-b620-459cf11c9aee",
              "name": "id",
              "type": "string",
              "value": "={{ $('Retrieve tag ids and names from dictionary').item.json.id }}"
            },
            {
              "id": "02b79f2a-b128-4686-8bb2-78ff44c43698",
              "name": "callers",
              "type": "array",
              "value": "={{ $('Retrieve tag ids and names from dictionary').item.json.callers }}"
            },
            {
              "id": "816163c9-7a5c-445d-8b59-592af7c2a4ac",
              "name": "name",
              "type": "string",
              "value": "={{ $('Retrieve tag ids and names from dictionary').item.json.name }}"
            },
            {
              "id": "c860552e-70d0-4d61-9b9d-ccff690b703b",
              "name": "callers_count",
              "type": "number",
              "value": "={{ $('Retrieve tag ids and names from dictionary').item.json.callers_count }}"
            }
          ]
        }
      },
      "executeOnce": true,
      "typeVersion": 3.4
    },
    {
      "id": "d45f7287-09f8-4de2-b74d-c55e200750aa",
      "name": "Combine dependency graph values into labels",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        2600,
        -20
      ],
      "parameters": {
        "options": {},
        "fieldsToAggregate": {
          "fieldToAggregate": [
            {
              "fieldToAggregate": "name"
            },
            {
              "fieldToAggregate": "id"
            },
            {
              "fieldToAggregate": "callers_count"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "aeee2b70-e6e2-4d3e-bfda-2b69a7e95ffc",
      "name": "Visualize subworkflow dependency graph",
      "type": "n8n-nodes-base.quickChart",
      "position": [
        3000,
        -20
      ],
      "parameters": {
        "data": "={{ $json.callers_count }}",
        "chartType": "pie",
        "labelsMode": "array",
        "labelsArray": "={{ $json.name }}",
        "chartOptions": {
          "width": 600,
          "format": "png",
          "height": 600,
          "backgroundColor": "#ffffff"
        },
        "datasetOptions": {
          "borderColor": "#000"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f57710f5-788f-473d-b429-59eaf7193a7b",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        660,
        -397.5668732742495
      ],
      "parameters": {
        "color": 7,
        "width": 2909.758966302104,
        "height": 1357.9229992534551,
        "content": "# n8n Subworkflow Dependency Graph & Auto-Tagging"
      },
      "typeVersion": 1
    },
    {
      "id": "ce9a88c8-5d6b-4b74-ae59-52128ec6d1af",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1160,
        160
      ],
      "parameters": {
        "color": 6,
        "width": 190.3269519041407,
        "height": 172.4182620239646,
        "content": "The script builds a dependency graph of workflows by identifying which workflows call others (via execution nodes) while preserving workflow names, caller relationships, and tags."
      },
      "typeVersion": 1
    },
    {
      "id": "9e5bbc26-006e-45bf-be5c-d5e0cf7228f0",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1380,
        160
      ],
      "parameters": {
        "color": 6,
        "width": 150,
        "height": 135.16347595207057,
        "content": "Here we filter out any workflows that are not [sub-workflows](https://docs.n8n.io/flow-logic/subworkflows/) (i.e. executed by other workflows)."
      },
      "typeVersion": 1
    },
    {
      "id": "6c957763-7410-4b3c-b08c-f73f2c502d5e",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1580,
        160
      ],
      "parameters": {
        "color": 6,
        "width": 345.30539364962834,
        "height": 100.16655570271519,
        "content": "We verify that the sub-workflows we intend to tag exist in our instance (not old workflow ids left over after importing a workflow from another instance)"
      },
      "typeVersion": 1
    },
    {
      "id": "21ea4110-0f31-4621-b401-3bac222352d9",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3160,
        220
      ],
      "parameters": {
        "color": 6,
        "width": 320.4824213076102,
        "height": 97.51953145794394,
        "content": "If a tag is freshly created during an earlier iteration through the list of workflows, then it is removed from the list of new callers (i.e. new tags to create)."
      },
      "typeVersion": 1
    },
    {
      "id": "0b04a2d3-5a10-4500-9450-5fee1ff77dec",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2560,
        180
      ],
      "parameters": {
        "color": 3,
        "width": 188.64373499228745,
        "height": 206.54161516323953,
        "content": "### Change instance URL"
      },
      "typeVersion": 1
    },
    {
      "id": "98812066-6de5-48c4-a945-6639158b6394",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2940,
        -80
      ],
      "parameters": {
        "color": 6,
        "width": 502.4185703091201,
        "height": 243.8281544043028,
        "content": "## Generate chart"
      },
      "typeVersion": 1
    },
    {
      "id": "1427d97f-7971-494c-9594-b3ec81d83511",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3220,
        -20
      ],
      "parameters": {
        "color": 7,
        "width": 180.46986136506064,
        "height": 135.95151736720237,
        "content": "### Pie Chart\nBasic visualization of which sub-workflows are called most often by other workflows"
      },
      "typeVersion": 1
    },
    {
      "id": "1b8ee382-3e5d-4f6a-863b-100c84c3435e",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        680,
        500
      ],
      "parameters": {
        "color": 5,
        "width": 434.64763783570623,
        "height": 447.49544828389617,
        "content": "## Setup instructions:\n1. [Set n8n API credentials](https://docs.n8n.io/api/authentication/)\n2. Replace instance_url in workflow (highlighted in red)\n\n## Frequently used terms\n1. **Callers**: Workflows that execute or trigger another workflow (a subworkflow) within n8n. They often use the Execute Workflow node to pass data and control execution flow.\n2. **Sub-workflow**: A sub-workflow is any workflow that is executed by another workflow. These are often used for reusable automation logic, breaking down complex workflows into modular components.\n3. **Dependency Graph**: A dependency graph visually represents the relationships between workflows in an n8n instance. It maps out which workflows call others, helping users understand execution dependencies, optimize workflow organization, and prevent unintended changes that may break subworkflows."
      },
      "typeVersion": 1
    },
    {
      "id": "c005ed7e-8a7c-4588-944d-be0fa28b6959",
      "name": "SET instance_url",
      "type": "n8n-nodes-base.set",
      "position": [
        2600,
        220
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "3bfad885-f167-47fa-a615-da3661c60d85",
              "name": "instance_url",
              "type": "string",
              "value": "https://n8n.example.com"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "1ab2c9e9-fec1-4ab6-ace3-0bbe54a81058",
      "name": "When viewed in a browser",
      "type": "n8n-nodes-base.webhook",
      "position": [
        760,
        -160
      ],
      "webhookId": "9ef127d4-bd1e-40db-999b-0881afbd2ab3",
      "parameters": {
        "path": "dependency-graph",
        "options": {},
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "f1f930ed-2c42-4cab-a1a8-71b8810e0273",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2940,
        -360
      ],
      "parameters": {
        "color": 6,
        "width": 502.4185703091201,
        "height": 243.8281544043028,
        "content": "## Generate dependency graph"
      },
      "typeVersion": 1
    },
    {
      "id": "d47598c9-1a50-4754-a6a5-b6e9976d83a0",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3220,
        -300
      ],
      "parameters": {
        "color": 7,
        "width": 180.46986136506064,
        "height": 135.95151736720237,
        "content": "### Dependency Graph\nA visual representation of the relationships between the workflows in your n8n instance"
      },
      "typeVersion": 1
    },
    {
      "id": "18b2022a-dabc-4176-9b86-f3c1639d9b32",
      "name": "Format workflow relationship data for rendering",
      "type": "n8n-nodes-base.code",
      "position": [
        2600,
        -280
      ],
      "parameters": {
        "jsCode": "// Assuming the incoming JSON data looks like this:\nconst workflows = $input.all(); // The input data passed to the Code Node\n\n// Function to build the Mermaid chart\nconst buildMermaidChart = (workflows) => {\n    let mermaidChart = 'graph TD\\n'; // Mermaid format for directed graph\n\n    // Iterate over workflows to build relationships\n    workflows.forEach(workflow => {\n        // Accessing the workflow JSON data\n        const workflowData = workflow.json;\n\n        // If the workflow has callers (i.e., workflows that call this one)\n        if (workflowData.callers && workflowData.callers.length > 0) {\n            workflowData.callers.forEach(callerId => {\n                // Add a directed edge in Mermaid format (caller --> current workflow)\n                mermaidChart += `  ${callerId} --> ${workflowData.id}\\n`;\n            });\n        }\n    });\n\n    return mermaidChart;\n};\n\n// Generate the Mermaid chart\nconst mermaidChart = buildMermaidChart(workflows);\n\n// Set the mermaid chart into the output JSON for the next node\nreturn [\n    {\n        json: {\n            mermaidChart: mermaidChart,\n        },\n    },\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "3655d6bd-45a1-4c2e-856f-44104f0bd832",
      "name": "Visualize dependency graph with MermaidJS",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        3000,
        -280
      ],
      "parameters": {
        "options": {},
        "respondWith": "text",
        "responseBody": "=<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>n8n Subworkflow Dependency Graph with Mermaid</title>\n    <link href=\"https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css\" rel=\"stylesheet\">\n    <script src=\"https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js\"></script>\n    <style>\n      .mermaid-container {\n        margin-top: 20px;\n        width: 100%;\n        height: 100vh;\n      }\n    </style>\n</head>\n<body>\n    <div class=\"container mt-4\">\n        <h2>n8n Subworkflow Dependency Graph with Mermaid</h2>\n        <div id=\"workflows-container\"></div>\n    </div>\n    <hr class=\"featurette-divider border-dark\" />\n\n    <script>\n        // JSON object containing mermaidChart data\n        const workflowsData = [\n            {\n                mermaidChart: `{{ $json.mermaidChart }}`\n            }\n        ];\n\n        document.addEventListener('DOMContentLoaded', () => {\n            const workflowsContainer = document.getElementById('workflows-container');\n\n            // Render workflow immediately\n            renderWorkflows(workflowsData);\n\n            function renderWorkflows(workflows) {\n                workflows.forEach((workflow) => {\n                    const mermaidContainer = document.createElement('div');\n                    mermaidContainer.className = 'mermaid-container';\n                    mermaidContainer.innerHTML = workflow.mermaidChart;\n                    workflowsContainer.appendChild(mermaidContainer);\n                    mermaid.init(undefined, mermaidContainer); // Initialize mermaid to render the graph\n                });\n            }\n        });\n\n        // Initialize mermaid with the config\n        mermaid.initialize({ startOnLoad: false });\n    </script>\n\n    <script src=\"https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js\"></script>\n</body>\n</html>\n"
      },
      "typeVersion": 1.1
    },
    {
      "id": "d9b0e9be-1794-4f5e-899c-b5d1e22baa58",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        680,
        -320
      ],
      "parameters": {
        "color": 5,
        "width": 653.2415806326139,
        "height": 140.62930090784633,
        "content": "## About this workflow\nThis workflow analyzes an n8n instance to detect dependencies between workflows. It identifies which workflows call others ([sub-workflows](https://docs.n8n.io/flow-logic/subworkflows/)), builds a dependency graph, and automatically tags subworkflows with their calling workflows. This makes it easier to track dependencies, optimize workflow structures, and maintain documentation in complex n8n environments."
      },
      "typeVersion": 1
    },
    {
      "id": "357037ff-f5f7-4b5d-9b72-7c2aec393de4",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1360,
        -320
      ],
      "parameters": {
        "color": 4,
        "width": 266.5295926113459,
        "height": 95.5709893724457,
        "content": "## About the maker\n**[Find Ludwig Gerdes on LinkedIn](https://www.linkedin.com/in/ludwiggerdes)**"
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "f1c5dcd4-bcdb-4336-922f-656adc9c36a6",
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "GET all tags again",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GET all tags": {
      "main": [
        [
          {
            "node": "Remove existing tags from new_callers list",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create new tags": {
      "main": [
        [
          {
            "node": "Return original pass through values",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GET workflow(s)": {
      "main": [
        [
          {
            "node": "Exclude missing workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "And every Sunday": {
      "main": [
        [
          {
            "node": "GET all workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SET instance_url": {
      "main": [
        [
          {
            "node": "GET all tags",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GET all workflows": {
      "main": [
        [
          {
            "node": "List callers of subworkflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GET all tags again": {
      "main": [
        [
          {
            "node": "Create tag id:name dictionary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If any new callers": {
      "main": [
        [
          {
            "node": "Split out new callers as new tags",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Update workflow tags": {
      "main": [
        [
          {
            "node": "Return dependency graph data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop through workflows": {
      "main": [
        [
          {
            "node": "Combine dependency graph values into labels",
            "type": "main",
            "index": 0
          },
          {
            "node": "Format workflow relationship data for rendering",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "SET instance_url",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When viewed in a browser": {
      "main": [
        [
          {
            "node": "GET all workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Exclude missing workflows": {
      "main": [
        [
          {
            "node": "Count callers and identify new callers",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Exclude uncalled workflows": {
      "main": [
        [
          {
            "node": "GET workflow(s)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List callers of subworkflows": {
      "main": [
        [
          {
            "node": "Exclude uncalled workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Return dependency graph data": {
      "main": [
        [
          {
            "node": "Loop through workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create tag id:name dictionary": {
      "main": [
        [
          {
            "node": "Retrieve tag ids and names from dictionary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When this workflow is activated": {
      "main": [
        [
          {
            "node": "GET all workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split out new callers as new tags": {
      "main": [
        [
          {
            "node": "Create new tags",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Return original pass through values": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Count callers and identify new callers": {
      "main": [
        [
          {
            "node": "Loop through workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove existing tags from new_callers list": {
      "main": [
        [
          {
            "node": "If any new callers",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Retrieve tag ids and names from dictionary": {
      "main": [
        [
          {
            "node": "Update workflow tags",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine dependency graph values into labels": {
      "main": [
        [
          {
            "node": "Visualize subworkflow dependency graph",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format workflow relationship data for rendering": {
      "main": [
        [
          {
            "node": "Visualize dependency graph with MermaidJS",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Workflow n8n gestion des workflows, tagging, optimisation : pour qui est ce workflow ?

Ce workflow s'adresse principalement aux équipes techniques et aux développeurs qui utilisent n8n pour automatiser leurs processus. Il est idéal pour les entreprises de taille moyenne à grande qui ont besoin d'une gestion efficace de leurs workflows et d'une organisation claire des dépendances. Un niveau technique intermédiaire est recommandé pour tirer pleinement parti de cette automatisation.

Workflow n8n gestion des workflows, tagging, optimisation : problème résolu

Ce workflow résout le problème de la gestion des dépendances entre les sous-workflows dans n8n, ce qui peut souvent devenir complexe et désordonné. En automatisant le processus de tagging, il élimine les risques de doublons et de confusion, permettant ainsi aux équipes de se concentrer sur des tâches à plus forte valeur ajoutée. Les utilisateurs bénéficient d'une meilleure visibilité sur leurs workflows, ce qui facilite la maintenance et l'évolution de leurs processus d'automatisation.

Workflow n8n gestion des workflows, tagging, optimisation : étapes du workflow

Étape 1 : Le workflow est déclenché chaque dimanche.

  • Étape 1 : Il récupère tous les workflows existants et filtre ceux qui ne sont pas appelés ou qui manquent.
  • Étape 2 : Il compte les appelants et identifie les nouveaux.
  • Étape 3 : Les nouveaux appelants sont séparés pour créer des tags.
  • Étape 4 : Les tags existants sont mis à jour et les nouveaux tags sont créés.
  • Étape 5 : Les dépendances sont visualisées sous forme de graphique pour une meilleure compréhension.

Workflow n8n gestion des workflows, tagging, optimisation : guide de personnalisation

Pour personnaliser ce workflow, vous pouvez modifier les paramètres du déclencheur planifié, tels que la fréquence d'exécution. Vous pouvez également ajuster les URL des appels HTTP pour correspondre à votre environnement n8n. Si vous souhaitez ajouter d'autres outils ou services, vous pouvez intégrer des noeuds supplémentaires pour enrichir le flux. Assurez-vous de sécuriser les appels HTTP en utilisant des authentifications appropriées et de surveiller les performances du workflow pour garantir son bon fonctionnement.