Workflow: Code Webhook Automate

Workflow Details

Download Workflow
{
    "id": "D0I76cew5KOnlem0",
    "meta": {
        "instanceId": "fb924c73af8f703905bc09c9ee8076f48c17b596ed05b18c0ff86915ef8a7c4a",
        "templateCredsSetupCompleted": true
    },
    "name": "Workflow stats",
    "tags": [],
    "nodes": [
        {
            "id": "b1a73981-db6a-4fd2-9cad-d02bfecc7d3d",
            "name": "When clicking \"Test workflow\"",
            "type": "n8n-nodes-base.manualTrigger",
            "position": [
                1060,
                740
            ],
            "parameters": [],
            "typeVersion": 1
        },
        {
            "id": "cbe2d1a8-51e9-4f3d-8ca5-321f3edf9a92",
            "name": "nodes-section",
            "type": "n8n-nodes-base.code",
            "position": [
                1900,
                800
            ],
            "parameters": {
                "jsCode": "\/\/ Initialize an empty object to hold the mapping between nodes and workflows\nconst nodeToWorkflowsMap = {};\n\n\/\/ Iterate over each workflow in the input\n$input.all().forEach(item => {\n  const { wf_stats } = item.json;\n  const { nodes_unique, wf_name, wf_url, wf_id } = wf_stats;\n\n  \/\/ For each unique node in the workflow, update the mapping\n  nodes_unique.forEach(node => {\n    if (!nodeToWorkflowsMap[node]) {\n      \/\/ If the node has not been added to the map, initialize it with the current workflow\n      nodeToWorkflowsMap[node] = [{ wf_name, wf_url, wf_id }];\n    } else {\n      \/\/ If the node is already in the map, append the current workflow to its list\n      nodeToWorkflowsMap[node].push({ wf_name, wf_url, wf_id });\n    }\n  });\n});\n\n\/\/ Convert the map into an array format suitable for n8n's output\nconst result = Object.keys(nodeToWorkflowsMap).map(node => ({\n  json: {\n    node,\n    count: nodeToWorkflowsMap[node].length,\n    workflows: nodeToWorkflowsMap[node]\n  }\n}));\n\nreturn result;"
            },
            "typeVersion": 2
        },
        {
            "id": "49a10bf3-f2e6-4fe9-8390-2a266f1b52a9",
            "name": "workflows-section",
            "type": "n8n-nodes-base.set",
            "position": [
                1680,
                640
            ],
            "parameters": {
                "options": [],
                "assignments": {
                    "assignments": [
                        {
                            "id": "fd4aa80c-cd88-4a97-b943-dfcf1ab222ee",
                            "name": "wf_stats",
                            "type": "object",
                            "value": "={{ { nodes_unique     :[...new Set($json.nodes_array)],\n     nodes_count_total:$json.nodes_array.length,\n     nodes_count_uniq :[...new Set($json.nodes_array)].length,\n     wf_created       :DateTime.fromISO($json.createdAt).toFormat('yyyy-MM-dd HH:mm:ss'),\n     wf_updated       :DateTime.fromISO($json.updatedAt).toFormat('yyyy-MM-dd HH:mm:ss'),\n     wf_name          :$json.name,\n     wf_id            :`wf-${$json.id}`,\n     wf_url           :`${$json.instance_url}\/workflow\/${$json.id}` || \"\",\n     wf_active        :$json.active,\n     wf_trigcount     :$json.triggerCount,\n     wf_tags          :$json.tags_array,\n     wf_whooks        :$json.webhook_paths_array\n\n} }}"
                        }
                    ]
                }
            },
            "typeVersion": 3.29999999999999982236431605997495353221893310546875
        },
        {
            "id": "afbbc6a0-dcb8-48e7-b2d1-ef00c769d3b7",
            "name": "Sticky Note",
            "type": "n8n-nodes-base.stickyNote",
            "position": [
                1240,
                -120
            ],
            "parameters": {
                "width": 1490,
                "height": 1375,
                "content": "## Create the main JSON object with the workflow statistics\n* `globals` - general information (# of workflows, active workflows, total trigger count)\n* `wf_stats` - summary per workflow (number or nodes, unique nodes, list of nodes and tags)\n* `nodes-section` - summary per node (number of workflows that use a node and their URLs)\n* `tags-section` - summary per tag (number of workflows that use a node and their URLs)\n* `webhook-section` - lists all webhook endpoints of the instance and shows the workflow URLs\n\n### You can use this JSON in BI tools to create a custom dashboard\n\n## Learn JS tips & tricks\n### Instead of just using one Code node, the workflow contains several nodes with useful advanced tricks.\n\n### JMESPath\n* Make a simple array of strings out of a complex array: `$jmespath($json,'nodes[*].type')`\n* Extract values based on condition: `$jmespath($input.all(),'[?json.wf_stats.wf_active == `true`]')`\n\n### Map and arrow functions\n* Perform operation on each array element: `.map(item => (item.split('.').pop().toUpperCase() ))`\n* Calculate sum of values from an array: `.reduce((accumulator, currentValue) => accumulator + currentValue, 0)`\n\n### Create an array with only unique values\n* `[...new Set($json.nodes_array)]`\n\n### Date-time conversions with the Luxon library:\n* `DateTime.fromISO($json.createdAt).toFormat('yyyy-MM-dd HH:mm:ss')`\n\n### Template literals (Template strings) for creating strings in JS\n* `wf-${$json.id}`"
            },
            "typeVersion": 1
        },
        {
            "id": "9dcb369b-fe22-45e1-906d-848a85b0c1e4",
            "name": "tags-section",
            "type": "n8n-nodes-base.code",
            "position": [
                1900,
                960
            ],
            "parameters": {
                "jsCode": "\/\/ Initialize an empty object to hold the mapping between tags and workflows\nconst tagToWorkflowsMap = {};\n\n\/\/ Iterate over each workflow in the input\n$input.all().forEach(item => {\n  const { wf_stats } = item.json;\n  \/\/ Destructure wf_url along with other properties\n  const { wf_tags, wf_name, wf_id, wf_url } = wf_stats;\n\n  \/\/ Check if the workflow has tags\n  if (wf_tags && wf_tags.length > 0) {\n    \/\/ For each tag in the workflow, update the mapping\n    wf_tags.forEach(tag => {\n      if (!tagToWorkflowsMap[tag]) {\n        \/\/ If the tag has not been added to the map, initialize it with the current workflow including wf_url\n        tagToWorkflowsMap[tag] = [{ wf_name, wf_id, wf_url }];\n      } else {\n        \/\/ If the tag is already in the map, append the current workflow to its list including wf_url\n        tagToWorkflowsMap[tag].push({ wf_name, wf_id, wf_url });\n      }\n    });\n  } else {\n    \/\/ Handle workflows with no tags, categorizing them under a 'No Tags' category\n    const noTagKey = 'No Tags'; \/\/ or any other placeholder you prefer\n    if (!tagToWorkflowsMap[noTagKey]) {\n      \/\/ Initialize with the current workflow including wf_url\n      tagToWorkflowsMap[noTagKey] = [{ wf_name, wf_id, wf_url }];\n    } else {\n      \/\/ Append the current workflow to its list including wf_url\n      tagToWorkflowsMap[noTagKey].push({ wf_name, wf_id, wf_url });\n    }\n  }\n});\n\n\/\/ Convert the map into an array format suitable for n8n's output\nconst result = Object.keys(tagToWorkflowsMap).map(tag => ({\n  json: {\n    tag,\n    count: tagToWorkflowsMap[tag].length,\n    workflows: tagToWorkflowsMap[tag] \/\/ This now contains objects with wf_name, wf_id, and wf_url\n  }\n}));\n\nreturn result;"
            },
            "typeVersion": 2
        },
        {
            "id": "7509c96c-0907-4cf1-94cf-f9dfbc0d3f9d",
            "name": "globals-section",
            "type": "n8n-nodes-base.set",
            "position": [
                1900,
                520
            ],
            "parameters": {
                "options": [],
                "assignments": {
                    "assignments": [
                        {
                            "id": "9e1284bd-73c5-4d3d-bb5d-3437fca97780",
                            "name": "globals",
                            "type": "object",
                            "value": "={{ { global_total : $input.all().length,\n     global_active : $jmespath($input.all(),'[?json.wf_stats.wf_active == `true`]').length,\n     global_trigger: $jmespath($input.all(),'[].json.wf_stats.wf_trigcount').reduce((accumulator, currentValue) => accumulator + currentValue, 0) }  }}"
                        }
                    ]
                }
            },
            "executeOnce": true,
            "typeVersion": 3.29999999999999982236431605997495353221893310546875
        },
        {
            "id": "2c0bc2dd-63d9-4b65-9e4e-2920892efaf7",
            "name": "Execute Workflow Trigger",
            "type": "n8n-nodes-base.executeWorkflowTrigger",
            "position": [
                1060,
                540
            ],
            "parameters": [],
            "typeVersion": 1
        },
        {
            "id": "8bceb3e9-e1d9-4ca0-af91-5377d4300346",
            "name": "Convert to XML",
            "type": "n8n-nodes-base.xml",
            "position": [
                1480,
                1600
            ],
            "parameters": {
                "mode": "jsonToxml",
                "options": {
                    "headless": true
                }
            },
            "typeVersion": 1
        },
        {
            "id": "6151d4b8-f592-418d-b099-17c71b1de0e4",
            "name": "Create HTML",
            "type": "n8n-nodes-base.html",
            "position": [
                1680,
                1600
            ],
            "parameters": {
                "html": "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<?xml-stylesheet type=\"text\/xsl\" href=\"{{ $env.WEBHOOK_URL }}webhook\/73a91e4d-143d-4168-9efb-6c56f2258aec\/dashboard.xsl\"?>\n\n{{ $json.data }}"
            },
            "typeVersion": 1
        },
        {
            "id": "e5ebc5c1-0fcc-4f9d-b8eb-df3a367cc097",
            "name": "Move Binary Data",
            "type": "n8n-nodes-base.moveBinaryData",
            "position": [
                1880,
                1600
            ],
            "parameters": {
                "mode": "jsonToBinary",
                "options": {
                    "mimeType": "text\/xml",
                    "keepSource": false,
                    "useRawData": true
                },
                "sourceKey": "html",
                "convertAllData": false
            },
            "typeVersion": 1
        },
        {
            "id": "5fdb74f7-6b2a-4042-91a2-c2088e8ea712",
            "name": "Respond to Webhook",
            "type": "n8n-nodes-base.respondToWebhook",
            "position": [
                2080,
                1600
            ],
            "parameters": {
                "options": {
                    "responseCode": 200,
                    "responseHeaders": {
                        "entries": [
                            {
                                "name": "Content-Type",
                                "value": "text\/xml"
                            },
                            {
                                "name": "Control-Allow-Origin",
                                "value": "*"
                            }
                        ]
                    }
                },
                "respondWith": "binary"
            },
            "typeVersion": 1
        },
        {
            "id": "ed113e7c-c49f-4854-8fbf-5f7bf3591ede",
            "name": "Sticky Note1",
            "type": "n8n-nodes-base.stickyNote",
            "position": [
                1000,
                1840
            ],
            "parameters": {
                "color": 7,
                "width": 909,
                "height": 426,
                "content": "# DO NOT RUN THIS\n## This webhook is needed to comply with the CORS policy of modern browsers.\n### It generates XML template and serves it using your n8n URL\n\nXSLT template is created with 2 Set nodes:\n1. `Template elements` node defines each section of the Dashboard\n2. `Final template` node puts everything together\n3. Bootstrap 5.3 styling is added. You can save the .css and .js files on your server. Right now a CDN version of the librarly is used."
            },
            "typeVersion": 1
        },
        {
            "id": "b6674f77-7797-4090-a4f9-56a9ddc0d4e0",
            "name": "Respond to Webhook2",
            "type": "n8n-nodes-base.respondToWebhook",
            "position": [
                1700,
                2120
            ],
            "parameters": {
                "options": {
                    "responseCode": 200,
                    "responseHeaders": {
                        "entries": [
                            {
                                "name": "Content-Type",
                                "value": "text\/xsl"
                            }
                        ]
                    }
                },
                "respondWith": "text",
                "responseBody": "={{ $json.xsl_template }}"
            },
            "typeVersion": 1
        },
        {
            "id": "c8c906da-0b61-46b0-be96-11da3c203e3f",
            "name": "Final template",
            "type": "n8n-nodes-base.set",
            "position": [
                1500,
                2120
            ],
            "parameters": {
                "options": [],
                "assignments": {
                    "assignments": [
                        {
                            "id": "2a42cfed-0451-41c2-9634-865cac2ea68d",
                            "name": "xsl_template",
                            "type": "string",
                            "value": "=<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http:\/\/www.w3.org\/1999\/XSL\/Transform\">\n  <xsl:template match=\"\/\">\n    <html>\n      <head>\n        <title>n8n Workflows Dashboard<\/title>\n        <link href=\"https:\/\/cdn.jsdelivr.net\/npm\/bootstrap@5.3.3\/dist\/css\/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH\" crossorigin=\"anonymous\" \/>\n        <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/bootstrap@5.3.3\/dist\/js\/bootstrap.bundle.min.js\" integrity=\"sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz\" crossorigin=\"anonymous\"><\/script>\n        <style>\n          body {\n            position: relative;\n          }\n          \n          section {\n            scroll-margin-top: 20px;\n          }\n\n          .form-check-overlay {\n            position: absolute;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            cursor: default;\n            z-index: 1;\n          }\n\n          .badge-link {\n            scroll-margin-top: 80px;\n          }\n\n          .sidebar {\n            position: fixed;\n            top: 0;\n            bottom: 0;\n            left: 0;\n            z-index: 100;\n            padding: 20px 0 0;\n            box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1);\n            overflow-y: auto;\n          }\n\n          .sidebar-sticky {\n            position: relative;\n            top: 0;\n            height: calc(100vh - 20px);\n            overflow-x: hidden;\n            overflow-y: auto;\n            padding-left: .25rem;\n          }\n\n          .nooverflow {\n            overflow-x: hidden;\n          }\n\n          .sidebar .nav-link {\n            font-weight: 500;\n            color: var(--bs-gray-800);\n            white-space: nowrap;\n            overflow: hidden;\n            text-overflow: ellipsis;\n          }\n\n          .sidebar .nav-link.active {\n            color: var(--bs-primary);\n          }\n\n          .sidebar .btn {\n            padding: .25rem .5rem;\n            font-weight: 600;\n            color: var(--bs-gray-800);\n          }\n\n          .sidebar-a {\n            padding: .25rem .5rem;\n            margin-left: 1.25rem;\n            color: var(--bs-gray-800);\n            background-color: transparent;\n          }\n\n          .sidebar-bottom {\n            padding: .25rem .5rem;\n            margin-left: 1.25rem;\n          }\n\n          .btn-toggle::before {\n            width: 1.25em;\n            line-height: 0;\n            content: url(\"data:image\/svg+xml,%3csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='16' height='16' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%280,0,0,.5%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'\/%3e%3c\/svg%3e\");\n            transition: transform .35s ease;\n            transform-origin: .5em 50%;\n          }\n\n          .btn-toggle[aria-expanded=\"true\"] {\n            color: var(--bs-gray-800);\n          }\n\n          .btn-toggle[aria-expanded=\"true\"]::before {\n            transform: rotate(90deg);\n          }\n\n          .btn-toggle-nav a {\n            padding: .1rem .5rem;\n            margin-top: .125rem;\n          }\n\n          .sidebar-a:hover,\n          .sidebar-a:focus,\n\t\t  .btn-toggle:hover,\n          .btn-toggle:focus {\n            background-color: var(--bs-primary-bg-subtle);\n          }\n\n          .content {\n            margin-left: 16.66%;\n            padding: 20px;\n          }\n\n          .card-img-container {\n            max-height: 150px;\n            overflow: hidden;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n          }\n          \n          .card-img-top {\n            object-fit: cover;\n            object-position: top;\n            height: 100%;\n            width: 100%;\n          }\n\n        <\/style>\n      <\/head>\n      <body data-bs-spy=\"scroll\" data-bs-target=\"#sidebar\" data-bs-offset=\"10\">\n        <div class=\"container-fluid\">\n          <div class=\"row\">\n{{ $json.sidebar }}\n\n            <main class=\"col-10 content\">\n\n<!-- Overview section -->\n{{ $json.overview }}\n<!-- Workflows section -->\n{{ $json.workflows }}\n<!-- Nodes section -->\n{{ $json.nodes }}\n<!-- Tags section -->\n{{ $json.tags }}\n<!-- Webhooks section -->\n{{ $json.webhooks }}\n<!-- About section -->\n{{ $json.about }}\n\n            <\/main>\n          <\/div>\n        <\/div>\n      <\/body>\n    <\/html>\n  <\/xsl:template>\n<\/xsl:stylesheet>"
                        }
                    ]
                }
            },
            "typeVersion": 3.29999999999999982236431605997495353221893310546875
        },
        {
            "id": "173493c0-1f96-4416-a545-6d8c6034ac76",
            "name": "Template elements",
            "type": "n8n-nodes-base.set",
            "position": [
                1300,
                2120
            ],
            "parameters": {
                "options": [],
                "assignments": {
                    "assignments": [
                        {
                            "id": "afbcca70-2977-46a3-89c3-27a96f791d13",
                            "name": "sidebar",
                            "type": "string",
                            "value": "=            <nav id=\"sidebar\" class=\"col-2 bg-light sidebar\">\n              <div class=\"sidebar-sticky\">\n                <ul class=\"list-unstyled ps-0\">\n                  <li class=\"mb-1\">\n                    <a href=\"#overview\" class=\"btn d-inline-flex align-items-center rounded border-0 sidebar-a\">Overview<\/a>\n                  <\/li>\n                  <!-- Workflows Section -->\n                  <li class=\"mb-1\">\n                    <button class=\"btn btn-toggle d-inline-flex align-items-center rounded border-0 collapsed\" data-bs-toggle=\"collapse\" data-bs-target=\"#workflows-collapse\" aria-expanded=\"false\">\n                      Workflows\n                    <\/button>\n                    <div class=\"collapse\" id=\"workflows-collapse\">\n                      <ul class=\"btn-toggle-nav list-unstyled fw-normal pb-1 small\">\n                        <xsl:for-each select=\"root\/wf_stats\">\n                          <li><a href=\"#{wf_id}\" class=\"link-dark d-inline-flex text-decoration-none rounded sidebar-a\"><xsl:value-of select=\"wf_name\" \/><\/a><\/li>\n                        <\/xsl:for-each>\n                      <\/ul>\n                    <\/div>\n                  <\/li>\n                  <!-- Nodes Section (No Sanitization) -->\n                  <li class=\"mb-1\">\n                    <button class=\"btn btn-toggle d-inline-flex align-items-center rounded border-0 collapsed\" data-bs-toggle=\"collapse\" data-bs-target=\"#nodes-collapse\" aria-expanded=\"false\">\n                      Nodes\n                    <\/button>\n                    <div class=\"collapse\" id=\"nodes-collapse\">\n                      <ul class=\"btn-toggle-nav list-unstyled fw-normal pb-1 small\">\n                        <xsl:for-each select=\"root\/nodes-section\">\n                          <li>\n                            <a class=\"link-dark d-inline-flex text-decoration-none rounded sidebar-a\">\n                              <xsl:attribute name=\"href\">\n                                <!-- Use raw node name -->\n                                <xsl:value-of select=\"concat('#node-', node)\" \/>\n                              <\/xsl:attribute>\n                              <xsl:value-of select=\"node\" \/>\n                            <\/a>\n                          <\/li>\n                        <\/xsl:for-each>\n                      <\/ul>\n                    <\/div>\n                  <\/li>\n                  <!-- Tags Section (Keep Sanitization) -->\n                  <li class=\"mb-1\">\n                    <button class=\"btn btn-toggle d-inline-flex align-items-center rounded border-0 collapsed\" data-bs-toggle=\"collapse\" data-bs-target=\"#tags-collapse\" aria-expanded=\"false\">\n                      Tags\n                    <\/button>\n                    <div class=\"collapse\" id=\"tags-collapse\">\n                      <ul class=\"btn-toggle-nav list-unstyled fw-normal pb-1 small\">\n                        <xsl:for-each select=\"root\/tags-section\">\n                           <!-- Sanitize tag name for href -->\n                          <xsl:variable name=\"raw_tag\" select=\"tag\"\/>\n                          <xsl:variable name=\"lower_tag\" select=\"translate($raw_tag, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')\"\/>\n                          <xsl:variable name=\"spaced_tag\" select=\"translate($lower_tag, ' ', '-')\"\/>\n                          <xsl:variable name=\"invalid_chars\" select=\"&quot;'.\/?&amp;=:&quot;\"\/>\n                          <xsl:variable name=\"sanitized_tag_id\" select=\"translate($spaced_tag, $invalid_chars, '')\"\/>\n                          <li>\n                            <a class=\"link-dark d-inline-flex text-decoration-none rounded sidebar-a\">\n                              <xsl:attribute name=\"href\">\n                                <xsl:value-of select=\"concat('#tag-', $sanitized_tag_id)\" \/>\n                              <\/xsl:attribute>\n                              <xsl:value-of select=\"tag\" \/>\n                            <\/a>\n                          <\/li>\n                        <\/xsl:for-each>\n                      <\/ul>\n                    <\/div>\n                  <\/li>\n                  <!-- Webhooks Section (No Sanitization) -->\n                  <li class=\"mb-1\">\n                    <button class=\"btn btn-toggle d-inline-flex align-items-center rounded border-0 collapsed\" data-bs-toggle=\"collapse\" data-bs-target=\"#webhooks-collapse\" aria-expanded=\"false\">\n                      Webhooks\n                    <\/button>\n                    <div class=\"collapse\" id=\"webhooks-collapse\">\n                      <ul class=\"btn-toggle-nav list-unstyled fw-normal pb-1 small\">\n                        <xsl:for-each select=\"root\/whooks-section\">\n                          <li>\n                            <a class=\"link-dark d-inline-flex text-decoration-none rounded sidebar-a\">\n                              <xsl:attribute name=\"href\">\n                                <!-- Use raw hookpath -->\n                                <xsl:value-of select=\"concat('#whook-', hookpath)\" \/>\n                              <\/xsl:attribute>\n                              <xsl:value-of select=\"hookpath\" \/>\n                            <\/a>\n                          <\/li>\n                        <\/xsl:for-each>\n                      <\/ul>\n                    <\/div>\n                  <\/li>\n                  <!-- END: Webhooks Section -->\n                  <li class=\"border-top my-3\"><\/li>\n                  <li class=\"mb-1\">\n                    <a href=\"#about\" class=\"btn d-inline-flex align-items-center rounded border-0 sidebar-a\">About<\/a>\n                  <\/li>\n                <\/ul>\n                <div class=\"sidebar-bottom\">\n                  <p>n8n Dashboard ver 0.8<br\/> <!-- Updated version number -->\nContacts: <a class=\"link-offset-1 link-offset-1-hover link-underline link-underline-opacity-0 link-underline-opacity-75-hover\" href=\"https:\/\/www.linkedin.com\/in\/parsadanyan\/\" target=\"_blank\">Eduard Parsadanyan<\/a><\/p>\n                <\/div>\n              <\/div>\n            <\/nav>\n"
                        },
                        {
                            "id": "d6dc34a7-3c79-44ef-957c-63aec4b2d75a",
                            "name": "overview",
                            "type": "string",
                            "value": "=<section  id=\"overview\" class=\"container\">\n  <h1>n8n Workflow Dashboard<\/h1>\n<\/section>\n\n<section class=\"container mt-3\">\n  <h2>Overview<\/h2>\n  <div class=\"row\">\n    <div class=\"col-md-4\">\n      <div class=\"card bg-body-secondary mb-2 shadow-sm\">\n        <div class=\"card-body text-center\">\n          <h5 class=\"card-title\">Total Workflows<\/h5>\n          <p class=\"card-text display-4\">\ud83d\udcca <xsl:value-of select=\"root\/globals\/global_total\" \/><\/p>\n        <\/div>\n      <\/div>\n    <\/div>\n    <div class=\"col-md-4\">\n      <div class=\"card bg-body-secondary mb-2 shadow-sm\">\n        <div class=\"card-body text-center\">\n          <h5 class=\"card-title\">Active Workflows<\/h5>\n          <p class=\"card-text display-4\">\u2705 <xsl:value-of select=\"root\/globals\/global_active\" \/><\/p>\n        <\/div>\n      <\/div>\n    <\/div>\n    <div class=\"col-md-4\">\n      <div class=\"card bg-body-secondary mb-2 shadow-sm\">\n        <div class=\"card-body text-center\">\n          <h5 class=\"card-title\">Triggers Count<\/h5>\n          <p class=\"card-text display-4\">\u26a1 <xsl:value-of select=\"root\/globals\/global_trigger\" \/><\/p>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/section>"
                        },
                        {
                            "id": "19ed123c-404b-4a68-a298-8f24c285f71c",
                            "name": "workflows",
                            "type": "string",
                            "value": "=<section id=\"workflows\" class=\"container mt-3\">\n  <h2>Workflows<\/h2>\n  <xsl:for-each select=\"root\/wf_stats\">\n    <div class=\"card mb-3 shadow-sm nooverflow\">\n      <div class=\"card-body\">\n        <div class=\"d-flex align-items-center mb-2\">\n          <div class=\"form-check form-switch me-3 position-relative\">\n            <input class=\"form-check-input\" type=\"checkbox\" role=\"switch\">\n              <xsl:attribute name=\"id\">\n                <xsl:value-of select=\"concat('switch-', wf_id)\" \/>\n              <\/xsl:attribute>\n              <xsl:if test=\"wf_active = 'true'\">\n                <xsl:attribute name=\"checked\">checked<\/xsl:attribute>\n              <\/xsl:if>\n            <\/input>\n            <label class=\"form-check-label\">\n              <xsl:attribute name=\"for\">\n                <xsl:value-of select=\"concat('switch-', wf_id)\" \/>\n              <\/xsl:attribute>\n            <\/label>\n            <div class=\"form-check-overlay\"><\/div>\n          <\/div>\n          <h5 class=\"card-title mb-0\">\n            <a class=\"link-offset-1 link-offset-1-hover link-underline link-underline-opacity-0 link-underline-opacity-75-hover\" href=\"{wf_url}\" target=\"_blank\" title=\"Open workflow in a new window\">\n              <xsl:attribute name=\"id\">\n                <xsl:value-of select=\"wf_id\" \/>\n              <\/xsl:attribute>\n              <xsl:value-of select=\"wf_name\" \/>\n            <\/a>\n          <\/h5>\n          <div class=\"ms-auto\">\n            <span class=\"badge bg-light font-monospace text-dark me-2\">\n              Updated At: <xsl:value-of select=\"wf_updated\" \/>\n            <\/span>\n            <span class=\"badge bg-light font-monospace text-dark me-2\">\n              Created At: <xsl:value-of select=\"wf_created\" \/>\n            <\/span>\n            <span class=\"badge bg-light font-monospace text-dark me-2\">\n              Nodes (Tot | Uniq | Trig): <xsl:value-of select=\"nodes_count_total\" \/> | <xsl:value-of select=\"nodes_count_uniq\" \/> | <xsl:value-of select=\"wf_trigcount\" \/>\n            <\/span>\n          <\/div>\n        <\/div>\n        <div class=\"row\">\n          <div class=\"d-flex\">\n            <div>\n              <xsl:for-each select=\"nodes_unique\">\n                <a href=\"#node-{.}\" title=\"Jump to this node\" class=\"badge-link\">\n                  <span class=\"badge bg-info-subtle border border-info-subtle text-info-emphasis rounded-pill me-2 mb-2\">\n                    <xsl:value-of select=\".\" \/>\n                  <\/span>\n                <\/a>\n              <\/xsl:for-each>\n            <\/div>\n            <xsl:if test=\"wf_tags\">\n              <div class=\"ms-auto\">\n                <xsl:for-each select=\"wf_tags\">\n                  <a href=\"#tag-{.}\" title=\"Jump to this tag\" class=\"badge-link\">\n                    <span class=\"badge bg-light-subtle border border-light-subtle text-light-emphasis rounded-pill me-2 mb-2\">\n                      <xsl:value-of select=\".\" \/>\n                    <\/span>\n                  <\/a>\n                <\/xsl:for-each>\n              <\/div>\n            <\/xsl:if>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/xsl:for-each>\n<\/section>"
                        },
                        {
                            "id": "9869134d-ee39-49a2-a978-eb3adaac482d",
                            "name": "nodes",
                            "type": "string",
                            "value": "=<section id=\"nodes\" class=\"container mt-3\">\n  <h2>Nodes<\/h2>\n  <div class=\"accordion\" id=\"nodesAccordion\">\n    <xsl:for-each select=\"root\/nodes-section\">\n      <div class=\"accordion-item shadow-sm\">\n        <!-- Place the target ID directly on the H3 using the original node name -->\n        <h3 class=\"accordion-header\">\n            <xsl:attribute name=\"id\">\n                <!-- Use raw node name -->\n                <xsl:value-of select=\"concat('node-', node)\"\/>\n            <\/xsl:attribute>\n          <button class=\"accordion-button collapsed\" type=\"button\" data-bs-toggle=\"collapse\">\n            <xsl:attribute name=\"data-bs-target\">\n              <!-- Use raw node name for targeting -->\n              <xsl:value-of select=\"concat('#collapse-node-', node)\" \/>\n            <\/xsl:attribute>\n            <xsl:attribute name=\"aria-controls\">\n              <xsl:value-of select=\"concat('collapse-node-', node)\" \/>\n            <\/xsl:attribute>\n            <!-- The <a> tag no longer needs an ID -->\n            <a>\n              <!-- Display the original node name -->\n              <xsl:value-of select=\"node\" \/> <span class=\"badge bg-info-subtle text-info-emphasis rounded-pill ms-2\"><xsl:value-of select=\"count\" \/><\/span>\n            <\/a>\n          <\/button>\n        <\/h3>\n        <div class=\"accordion-collapse collapse\">\n          <xsl:attribute name=\"id\">\n            <!-- Use raw node name for collapse ID -->\n            <xsl:value-of select=\"concat('collapse-node-', node)\" \/>\n          <\/xsl:attribute>\n          <!-- aria-labelledby should point to the h3's ID -->\n          <xsl:attribute name=\"aria-labelledby\">\n            <xsl:value-of select=\"concat('node-', node)\" \/>\n          <\/xsl:attribute>\n          <div class=\"accordion-body\">\n            <xsl:for-each select=\"workflows\">\n              <span class=\"badge bg-info-subtle border border-info-subtle text-info-emphasis rounded-pill me-2 mb-2\">\n                <a href=\"#{wf_id}\" class=\"text-primary-emphasis text-decoration-none me-1 section-offset\" title=\"Jump to workflow details\">\n                  <xsl:value-of select=\"wf_name\" \/>\n                <\/a>\n                <a href=\"{wf_url}\" target=\"_blank\" class=\"text-primary-emphasis text-decoration-none\" title=\"Open workflow in a new window\">\n                  \ud83d\udd17\n                <\/a>\n              <\/span>\n            <\/xsl:for-each>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/xsl:for-each>\n  <\/div>\n<\/section>\n"
                        },
                        {
                            "id": "f09bc0d1-017e-44f5-bc39-6bdfeffe22ec",
                            "name": "tags",
                            "type": "string",
                            "value": "=<section id=\"tags\" class=\"container mt-3\">\n  <h2>Tags<\/h2>\n  <div class=\"accordion\" id=\"tagsAccordion\">\n    <xsl:for-each select=\"root\/tags-section\">\n      <!-- Sanitize the tag name -->\n      <xsl:variable name=\"raw_tag\" select=\"tag\"\/>\n      <xsl:variable name=\"lower_tag\" select=\"translate($raw_tag, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')\"\/>\n      <xsl:variable name=\"spaced_tag\" select=\"translate($lower_tag, ' ', '-')\"\/>\n      <xsl:variable name=\"invalid_chars\" select=\"&quot;'.\/?&amp;=:&quot;\"\/> <!-- Add any other chars you find problematic -->\n      <xsl:variable name=\"sanitized_tag_id\" select=\"translate($spaced_tag, $invalid_chars, '')\"\/>\n\n      <div class=\"accordion-item shadow-sm\">\n        <h3 class=\"accordion-header\">\n            <xsl:attribute name=\"id\">\n                <xsl:value-of select=\"concat('heading-tag-', $sanitized_tag_id)\"\/>\n            <\/xsl:attribute>\n          <button class=\"accordion-button collapsed\" type=\"button\" data-bs-toggle=\"collapse\">\n            <xsl:attribute name=\"data-bs-target\">\n              <xsl:value-of select=\"concat('#collapse-tag-', $sanitized_tag_id)\" \/>\n            <\/xsl:attribute>\n            <xsl:attribute name=\"aria-controls\">\n              <xsl:value-of select=\"concat('collapse-tag-', $sanitized_tag_id)\" \/>\n            <\/xsl:attribute>\n            <a>\n              <!-- Use the sanitized ID here -->\n              <xsl:attribute name=\"id\">\n                <xsl:value-of select=\"concat('tag-', $sanitized_tag_id)\" \/>\n              <\/xsl:attribute>\n              <!-- Display the original tag name -->\n              <xsl:value-of select=\"tag\" \/> <span class=\"badge bg-light-subtle text-light-emphasis rounded-pill ms-2\"><xsl:value-of select=\"count\" \/><\/span>\n            <\/a>\n          <\/button>\n        <\/h3>\n        <div class=\"accordion-collapse collapse\">\n          <xsl:attribute name=\"id\">\n            <xsl:value-of select=\"concat('collapse-tag-', $sanitized_tag_id)\" \/>\n          <\/xsl:attribute>\n          <xsl:attribute name=\"aria-labelledby\">\n            <xsl:value-of select=\"concat('heading-tag-', $sanitized_tag_id)\" \/>\n          <\/xsl:attribute>\n          <div class=\"accordion-body\">\n            <xsl:for-each select=\"workflows\">\n              <span class=\"badge bg-light-subtle border border-light-subtle text-light-emphasis rounded-pill me-2 mb-2\">\n                <a href=\"#{wf_id}\" class=\"text-primary-emphasis text-decoration-none me-1 section-offset\" title=\"Jump to workflow details\">\n                  <xsl:value-of select=\"wf_name\" \/>\n                <\/a>\n                <a href=\"{wf_url}\" target=\"_blank\" class=\"text-primary-emphasis text-decoration-none\" title=\"Open workflow in a new window\">\n                  \ud83d\udd17\n                <\/a>\n              <\/span>\n            <\/xsl:for-each>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/xsl:for-each>\n  <\/div>\n<\/section>\n"
                        },
                        {
                            "id": "2e1f449c-a59b-4eb7-a3b7-48bedff01812",
                            "name": "webhooks",
                            "type": "string",
                            "value": "=<section id=\"webhooks\" class=\"container mt-3\">\n  <h2>Webhooks<\/h2>\n  <div class=\"accordion\" id=\"webhooksAccordion\">\n    <xsl:for-each select=\"root\/whooks-section\">\n      <div class=\"accordion-item shadow-sm\">\n        <!-- Place the target ID directly on the H3 using the original hookpath -->\n        <h3 class=\"accordion-header\">\n            <xsl:attribute name=\"id\">\n                <!-- Use raw hookpath -->\n                <xsl:value-of select=\"concat('whook-', hookpath)\"\/>\n            <\/xsl:attribute>\n          <button class=\"accordion-button collapsed\" type=\"button\" data-bs-toggle=\"collapse\">\n            <xsl:attribute name=\"data-bs-target\">\n              <!-- Use raw hookpath for targeting -->\n              <xsl:value-of select=\"concat('#collapse-whook-', hookpath)\" \/>\n            <\/xsl:attribute>\n            <xsl:attribute name=\"aria-controls\">\n              <xsl:value-of select=\"concat('collapse-whook-', hookpath)\" \/>\n            <\/xsl:attribute>\n            <!-- The <a> tag no longer needs an ID -->\n            <a>\n              <!-- Display the original hookpath -->\n              <xsl:value-of select=\"hookpath\" \/> <span class=\"badge bg-secondary-subtle text-secondary-emphasis rounded-pill ms-2\"><xsl:value-of select=\"count\" \/><\/span>\n            <\/a>\n          <\/button>\n        <\/h3>\n        <div class=\"accordion-collapse collapse\">\n          <xsl:attribute name=\"id\">\n            <!-- Use raw hookpath for collapse ID -->\n            <xsl:value-of select=\"concat('collapse-whook-', hookpath)\" \/>\n          <\/xsl:attribute>\n          <!-- aria-labelledby should point to the h3's ID -->\n          <xsl:attribute name=\"aria-labelledby\">\n            <xsl:value-of select=\"concat('whook-', hookpath)\" \/>\n          <\/xsl:attribute>\n          <div class=\"accordion-body\">\n            <xsl:for-each select=\"workflows\">\n              <span class=\"badge bg-secondary-subtle border border-secondary-subtle text-secondary-emphasis rounded-pill me-2 mb-2\">\n                <a href=\"#{wf_id}\" class=\"text-primary-emphasis text-decoration-none me-1 section-offset\" title=\"Jump to workflow details\">\n                  <xsl:value-of select=\"wf_name\" \/>\n                <\/a>\n                <a href=\"{wf_url}\" target=\"_blank\" class=\"text-primary-emphasis text-decoration-none\" title=\"Open workflow in a new window\">\n                  \ud83d\udd17\n                <\/a>\n              <\/span>\n            <\/xsl:for-each>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/xsl:for-each>\n  <\/div>\n<\/section>\n"
                        },
                        {
                            "id": "2af68003-c9b9-4e60-8836-195da026ad2f",
                            "name": "about",
                            "type": "string",
                            "value": "=<hr class=\"featurette-divider border-dark\" \/>\n<section id=\"about\" class=\"container mt-3\">\n  <h2 class=\"text-center mb-5\">About This Dashboard &amp; Related Templates<\/h2>\n  <div class=\"row justify-content-center\">\n\n    <!-- Eduard Section -->\n    <div class=\"col-lg-3 text-center mb-4\">\n      <img src=\"https:\/\/gravatar.com\/avatar\/a551e67c6fe7affd5f882a527dee154bb6c3ac90cf878326accb3fb3ec77c8a6?r=pg&amp;d=retro&amp;size=200\" alt=\"Eduard\" class=\"rounded-circle mb-3\" width=\"140\" height=\"140\" \/>\n      <h3 class=\"fw-normal\">Eduard<\/h3>\n      <p><a class=\"btn btn-warning\" href=\"https:\/\/n8n.io\/creators\/eduard\/\" target=\"_blank\">More templates<\/a><\/p>\n      <p><a class=\"btn btn-outline-primary\" href=\"https:\/\/www.linkedin.com\/in\/parsadanyan\/\" target=\"_blank\">LinkedIn<\/a><\/p>\n    <\/div>\n\n    <!-- Original Article Card (Text Restored) -->\n    <div class=\"col-lg-3 text-center mb-4\">\n      <div class=\"card shadow-sm h-100\">\n         <div class=\"card-img-container\">\n            <img src=\"https:\/\/blog.n8n.io\/content\/images\/size\/w800\/2023\/09\/gg.png\" class=\"card-img-top\" alt=\"How to work with XML and SQL using n8n\" \/>\n         <\/div>\n        <div class=\"card-body d-flex flex-column\">\n          <!-- Restored original title -->\n          <h5 class=\"card-title\">Read the article to find out more!<\/h5>\n          <p class=\"card-text\">This dashboard was created using XML template language (XSLT) in n8n.<\/p>\n          <a href=\"https:\/\/blog.n8n.io\/sql-xml\/#how-to-deliver-the-xml-file\" class=\"btn btn-primary mt-auto\" target=\"_blank\">Read Article<\/a>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <!-- New Card 1: Docsify Template (Text Expanded) -->\n    <div class=\"col-lg-3 text-center mb-4\">\n      <div class=\"card shadow-sm h-100\">\n        <div class=\"card-body d-flex flex-column\">\n          <h5 class=\"card-title\">\ud83d\udcda Auto-generate documentation for n8n workflows with GPT and Docsify<\/h5>\n          <p class=\"card-subtitle mb-2 text-muted\">Creates a dynamic Docsify site with GPT-powered descriptions and Mermaid diagrams.<\/p>\n          <!-- Added descriptive text -->\n          <p class=\"card-text\">Features live editing, tag filtering, and automated documentation updates for your n8n instance.<\/p>\n          <a href=\"https:\/\/n8n.io\/workflows\/2669-auto-generate-documentation-for-n8n-workflows-with-gpt-and-docsify\/\" class=\"btn btn-primary mt-auto\" target=\"_blank\">View Template<\/a>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <!-- New Card 2: Mermaid Template (Text Expanded) -->\n    <div class=\"col-lg-3 text-center mb-4\">\n      <div class=\"card shadow-sm h-100\">\n        <div class=\"card-body d-flex flex-column\">\n          <h5 class=\"card-title\">\ud83d\udd0d Visualize Your n8n Workflows with Mermaid.js!<\/h5>\n           <p class=\"card-subtitle mb-2 text-muted\">Generates interactive workflow flowcharts using Mermaid.js and Bootstrap.<\/p>\n           <!-- Added descriptive text -->\n           <p class=\"card-text\">Instantly visualize structures with custom shapes and direct links to workflows, perfect for documentation.<\/p>\n          <a href=\"https:\/\/n8n.io\/workflows\/2378-visualize-your-n8n-workflows-with-mermaidjs\/\" class=\"btn btn-primary mt-auto\" target=\"_blank\">View Template<\/a>\n        <\/div>\n      <\/div>\n    <\/div>\n\n  <\/div> <!-- End row -->\n<\/section>\n"
                        }
                    ]
                }
            },
            "typeVersion": 3.29999999999999982236431605997495353221893310546875
        },
        {
            "id": "3555218e-8df2-4ae8-9482-2c8ec99798c0",
            "name": "Sort-workflows",
            "type": "n8n-nodes-base.sort",
            "position": [
                2080,
                640
            ],
            "parameters": {
                "options": [],
                "sortFieldsUi": {
                    "sortField": [
                        {
                            "order": "descending",
                            "fieldName": "wf_stats.wf_updated"
                        },
                        {
                            "fieldName": "wf_stats.wf_name"
                        }
                    ]
                }
            },
            "typeVersion": 1
        },
        {
            "id": "2d893970-825e-4842-811f-7e7a24dd3bac",
            "name": "Sort-nodes",
            "type": "n8n-nodes-base.sort",
            "position": [
                2080,
                800
            ],
            "parameters": {
                "options": [],
                "sortFieldsUi": {
                    "sortField": [
                        {
                            "order": "descending",
                            "fieldName": "count"
                        },
                        {
                            "fieldName": "node"
                        }
                    ]
                }
            },
            "typeVersion": 1
        },
        {
            "id": "c197f00e-d147-45af-b121-a70d28912a7f",
            "name": "Sort-tags",
            "type": "n8n-nodes-base.sort",
            "position": [
                2080,
                960
            ],
            "parameters": {
                "options": [],
                "sortFieldsUi": {
                    "sortField": [
                        {
                            "order": "descending",
                            "fieldName": "count"
                        },
                        {
                            "fieldName": "tag"
                        }
                    ]
                }
            },
            "typeVersion": 1
        },
        {
            "id": "4f28a9f6-b67e-42d8-8843-480803932c27",
            "name": "Aggregate-workflows",
            "type": "n8n-nodes-base.aggregate",
            "position": [
                2260,
                640
            ],
            "parameters": {
                "options": [],
                "fieldsToAggregate": {
                    "fieldToAggregate": [
                        {
                            "fieldToAggregate": "wf_stats"
                        }
                    ]
                }
            },
            "typeVersion": 1
        },
        {
            "id": "f4521a5c-8cc3-4831-90e2-1a1fda06fdac",
            "name": "Aggregate-nodes",
            "type": "n8n-nodes-base.aggregate",
            "position": [
                2260,
                800
            ],
            "parameters": {
                "options": [],
                "aggregate": "aggregateAllItemData",
                "destinationFieldName": "nodes-section"
            },
            "typeVersion": 1
        },
        {
            "id": "ae5040f7-4ae3-41e7-9afc-ebb625d303e7",
            "name": "Aggregate-tags",
            "type": "n8n-nodes-base.aggregate",
            "position": [
                2260,
                960
            ],
            "parameters": {
                "options": [],
                "aggregate": "aggregateAllItemData",
                "destinationFieldName": "tags-section"
            },
            "typeVersion": 1
        },
        {
            "id": "69a22d56-3b4e-4d5d-b351-3c787f23e9c9",
            "name": "n8n-get-workflows",
            "type": "n8n-nodes-base.n8n",
            "position": [
                1260,
                640
            ],
            "parameters": {
                "filters": [],
                "requestOptions": []
            },
            "credentials": {
                "n8nApi": {
                    "id": "45",
                    "name": "n8n account 4"
                }
            },
            "typeVersion": 1
        },
        {
            "id": "35564537-0053-4cdb-a05d-153ad4825393",
            "name": "Prepare JSON object",
            "type": "n8n-nodes-base.executeWorkflow",
            "position": [
                1260,
                1600
            ],
            "parameters": {
                "options": [],
                "workflowId": "={{ $workflow.id }}"
            },
            "typeVersion": 1
        },
        {
            "id": "9fd045f1-7126-4611-b26d-c45139429c6b",
            "name": "get-nodes-via-jmespath",
            "type": "n8n-nodes-base.set",
            "position": [
                1460,
                640
            ],
            "parameters": {
                "options": [],
                "assignments": {
                    "assignments": [
                        {
                            "id": "51f83719-066f-4231-a418-ba64a3b5b831",
                            "name": "nodes_array",
                            "type": "array",
                            "value": "={{$jmespath($json,'nodes[*].type').map(item => (item.split('.').pop().toUpperCase() ))}}"
                        },
                        {
                            "id": "bbc40849-66a7-4583-8c2c-ac590be59e38",
                            "name": "tags_array",
                            "type": "array",
                            "value": "={{$jmespath($json,'tags[*].name')}}"
                        },
                        {
                            "id": "08064cc3-f34e-4f05-9975-726378fe63ae",
                            "name": "instance_url",
                            "type": "string",
                            "value": "={{$env[\"N8N_PROTOCOL\"]}}:\/\/{{$env[\"N8N_HOST\"]}}"
                        },
                        {
                            "id": "1fdb9640-b628-4e13-9e4c-fef19cae7611",
                            "name": "webhook_paths_array",
                            "type": "array",
                            "value": "={{ $jmespath($json, `nodes[?type=='n8n-nodes-base.webhook'].parameters.path | [?@]`) }}"
                        }
                    ]
                },
                "includeOtherFields": true
            },
            "typeVersion": 3.29999999999999982236431605997495353221893310546875
        },
        {
            "id": "45723a66-03be-4be7-ae4a-978adb5b7e7b",
            "name": "Sticky Note2",
            "type": "n8n-nodes-base.stickyNote",
            "position": [
                960,
                1280
            ],
            "parameters": {
                "color": 6,
                "width": 1301.926282208590009759063832461833953857421875,
                "height": 1000.0640426993867322380538098514080047607421875,
                "content": "## Additional section to create a standalone dashboard via XLM templates\n### This section is not required if you only need a JSON\n\n### *IMPORTANT!*\n### This webhook is not protected. Everyone who knows the URL endpoint can get access to the Dashboard. Please consider adding authentication.\n\n1. `Request HTML dashboard` node runs that main section of the workflow\n2. It converts the JSON into an XML structure\n3. A final HTML page is created with the link to an XML stylesheet (this stylesheet controls the look of the dashboard)\n4. The resulting page is returned via `Respond to Webhook` node"
            },
            "typeVersion": 1
        },
        {
            "id": "b17fbec5-03e2-4836-8704-6b31cdf92a5b",
            "name": "Request HTML dashboard",
            "type": "n8n-nodes-base.webhook",
            "position": [
                1060,
                1600
            ],
            "webhookId": "fb550a01-12f2-4709-ba2d-f71197b68340",
            "parameters": {
                "path": "fb550a01-12f2-4709-ba2d-f71197b68340",
                "options": [],
                "responseMode": "responseNode"
            },
            "typeVersion": 2
        },
        {
            "id": "70fd1bbb-24e2-4fde-b054-6319120a7ac4",
            "name": "Sticky Note3",
            "type": "n8n-nodes-base.stickyNote",
            "position": [
                960,
                940
            ],
            "parameters": {
                "color": 3,
                "width": 663.915516288838944092276506125926971435546875,
                "height": 251.88666538384990190024836920201778411865234375,
                "content": "## IMPORTANT NOTE FOR CLOUD USERS\n### Since the cloud version doesn't support environmental variables, please make the following changes:\n\n1. **get-nodes-via-jmespath** node. Update the `instance_url` variable: enter your n8n URL instead of `{{$env[\"N8N_PROTOCOL\"]}}:\/\/{{$env[\"N8N_HOST\"]}}`\n2. **Create HTML** node. Please provide the n8n instance URL instead of `{{ $env.WEBHOOK_URL }}`"
            },
            "typeVersion": 1
        },
        {
            "id": "36288776-5f67-40fd-872f-0eeac0dd03b0",
            "name": "Request xsl template",
            "type": "n8n-nodes-base.webhook",
            "position": [
                1100,
                2120
            ],
            "webhookId": "73a91e4d-143d-4168-9efb-6c56f2258aec",
            "parameters": {
                "path": "73a91e4d-143d-4168-9efb-6c56f2258aec\/dashboard.xsl",
                "options": [],
                "responseMode": "responseNode"
            },
            "typeVersion": 2
        },
        {
            "id": "cda6fce6-0b0a-4fdf-b50c-b5bd874e43a0",
            "name": "Final-json",
            "type": "n8n-nodes-base.merge",
            "position": [
                2560,
                540
            ],
            "parameters": {
                "mode": "combine",
                "options": [],
                "combineBy": "combineByPosition",
                "numberInputs": 5
            },
            "typeVersion": 3.100000000000000088817841970012523233890533447265625
        },
        {
            "id": "1a7acbda-0eb4-4d1a-b458-02457ee82a9b",
            "name": "webhook-section",
            "type": "n8n-nodes-base.code",
            "position": [
                1900,
                1140
            ],
            "parameters": {
                "jsCode": "\/\/ Initialize an empty object to hold the mapping between webhook paths and workflows\nconst webhookMap = {};\n\n\/\/ Iterate over each workflow item passed from the previous node\n$input.all().forEach(item => {\n  \/\/ --- Extract Data ---\n  \/\/ Ensure wf_stats exists in the item's JSON payload\n  if (!item.json || !item.json.wf_stats) {\n    console.warn(\"Skipping item due to missing json or wf_stats:\", JSON.stringify(item));\n    return; \/\/ Skip this item if wf_stats is missing\n  }\n\n  const { wf_stats } = item.json;\n  \/\/ Destructure the necessary fields from wf_stats\n  \/\/ Use default values for safety\n  const { wf_whooks, wf_name = 'Unknown Workflow', wf_url = '', wf_id = 'unknown-' + Date.now() } = wf_stats;\n\n  \/\/ --- Process Webhooks ---\n  \/\/ Check if wf_whooks exists and is an array with items\n  if (Array.isArray(wf_whooks) && wf_whooks.length > 0) {\n    const workflowInfo = { wf_name, wf_url, wf_id }; \/\/ Prepare workflow details object\n\n    \/\/ For each webhook path associated with this workflow\n    wf_whooks.forEach(hookpath => {\n      \/\/ Ensure hookpath is a non-empty string before processing\n      if (typeof hookpath === 'string' && hookpath.trim() !== '') {\n        const cleanHookpath = hookpath.trim(); \/\/ Use trimmed path\n\n        \/\/ If this webhook path hasn't been seen before, initialize it in the map\n        if (!webhookMap[cleanHookpath]) {\n          webhookMap[cleanHookpath] = [workflowInfo];\n        } else {\n          \/\/ If the path exists, add this workflow's info to its list\n          \/\/ (Avoid adding duplicates if the same workflow info is already there for this path)\n          if (!webhookMap[cleanHookpath].some(wf => wf.wf_id === wf_id)) {\n             webhookMap[cleanHookpath].push(workflowInfo);\n          }\n        }\n      } else {\n        \/\/ Optional: Log if a non-string or empty path was found in the array\n         console.warn(`Invalid hookpath found in wf_whooks for workflow ${wf_id}:`, hookpath);\n      }\n    });\n  }\n  \/\/ Workflows without any webhooks (empty wf_whooks array) will be skipped naturally\n});\n\n\/\/ --- Format Output ---\n\/\/ Convert the map ( { path: [workflows] } ) into an array of items for n8n output\nconst result = Object.keys(webhookMap).map(hookpath => ({\n  json: {\n    hookpath: hookpath, \/\/ The webhook path\n    count: webhookMap[hookpath].length, \/\/ How many workflows use this path\n    workflows: webhookMap[hookpath] \/\/ The list of { wf_name, wf_url, wf_id } objects\n  }\n}));\n\n\/\/ Return the final array\nreturn result;\n"
            },
            "typeVersion": 2
        },
        {
            "id": "0cfcd940-f000-47ce-8e46-36dab4068acb",
            "name": "Sort-whooks",
            "type": "n8n-nodes-base.sort",
            "position": [
                2080,
                1140
            ],
            "parameters": {
                "options": [],
                "sortFieldsUi": {
                    "sortField": [
                        {
                            "order": "descending",
                            "fieldName": "count"
                        },
                        {
                            "fieldName": "hookpath"
                        }
                    ]
                }
            },
            "typeVersion": 1
        },
        {
            "id": "099ecc9b-ca8d-4ccb-aa64-30a563f27aeb",
            "name": "Aggregate-whooks",
            "type": "n8n-nodes-base.aggregate",
            "position": [
                2260,
                1140
            ],
            "parameters": {
                "options": [],
                "aggregate": "aggregateAllItemData",
                "destinationFieldName": "whooks-section"
            },
            "typeVersion": 1
        },
        {
            "id": "a01a78e6-0957-4602-a558-430b17000452",
            "name": "Sticky Note4",
            "type": "n8n-nodes-base.stickyNote",
            "position": [
                600,
                1580
            ],
            "parameters": {
                "width": 620,
                "content": "## &#x200B;\n# USE THIS WEBHOOK -->"
            },
            "typeVersion": 1
        }
    ],
    "active": true,
    "pinData": [],
    "settings": {
        "callerPolicy": "workflowsFromSameOwner",
        "executionOrder": "v1",
        "saveManualExecutions": true,
        "saveDataSuccessExecution": "all"
    },
    "versionId": "3fc1a529-eb6e-4f8a-9d7f-cb8e21e782a1",
    "connections": {
        "Sort-tags": {
            "main": [
                [
                    {
                        "node": "Aggregate-tags",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Sort-nodes": {
            "main": [
                [
                    {
                        "node": "Aggregate-nodes",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Create HTML": {
            "main": [
                [
                    {
                        "node": "Move Binary Data",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Sort-whooks": {
            "main": [
                [
                    {
                        "node": "Aggregate-whooks",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "tags-section": {
            "main": [
                [
                    {
                        "node": "Sort-tags",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "nodes-section": {
            "main": [
                [
                    {
                        "node": "Sort-nodes",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Aggregate-tags": {
            "main": [
                [
                    {
                        "node": "Final-json",
                        "type": "main",
                        "index": 3
                    }
                ]
            ]
        },
        "Convert to XML": {
            "main": [
                [
                    {
                        "node": "Create HTML",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Final template": {
            "main": [
                [
                    {
                        "node": "Respond to Webhook2",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Sort-workflows": {
            "main": [
                [
                    {
                        "node": "Aggregate-workflows",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Aggregate-nodes": {
            "main": [
                [
                    {
                        "node": "Final-json",
                        "type": "main",
                        "index": 2
                    }
                ]
            ]
        },
        "globals-section": {
            "main": [
                [
                    {
                        "node": "Final-json",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "webhook-section": {
            "main": [
                [
                    {
                        "node": "Sort-whooks",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Aggregate-whooks": {
            "main": [
                [
                    {
                        "node": "Final-json",
                        "type": "main",
                        "index": 4
                    }
                ]
            ]
        },
        "Move Binary Data": {
            "main": [
                [
                    {
                        "node": "Respond to Webhook",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Template elements": {
            "main": [
                [
                    {
                        "node": "Final template",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "n8n-get-workflows": {
            "main": [
                [
                    {
                        "node": "get-nodes-via-jmespath",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "workflows-section": {
            "main": [
                [
                    {
                        "node": "nodes-section",
                        "type": "main",
                        "index": 0
                    },
                    {
                        "node": "tags-section",
                        "type": "main",
                        "index": 0
                    },
                    {
                        "node": "globals-section",
                        "type": "main",
                        "index": 0
                    },
                    {
                        "node": "Sort-workflows",
                        "type": "main",
                        "index": 0
                    },
                    {
                        "node": "webhook-section",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Aggregate-workflows": {
            "main": [
                [
                    {
                        "node": "Final-json",
                        "type": "main",
                        "index": 1
                    }
                ]
            ]
        },
        "Prepare JSON object": {
            "main": [
                [
                    {
                        "node": "Convert to XML",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Request xsl template": {
            "main": [
                [
                    {
                        "node": "Template elements",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Request HTML dashboard": {
            "main": [
                [
                    {
                        "node": "Prepare JSON object",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "get-nodes-via-jmespath": {
            "main": [
                [
                    {
                        "node": "workflows-section",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Execute Workflow Trigger": {
            "main": [
                [
                    {
                        "node": "n8n-get-workflows",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "When clicking \"Test workflow\"": {
            "main": [
                [
                    {
                        "node": "n8n-get-workflows",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        }
    }
}
Back to Workflows

Related Workflows

[2/2] KNN classifier (lands dataset)
View
Manual Stickynote Process Triggered
View
Clickup Notion Update Triggered
View
Email
View
Stopanderror Webhook Create Webhook
View
Two Way Sync Pipedrive and MySQL
View
SQL agent with memory
View
Manual Splitinbatches Automate Triggered
View
Splitout Schedule Create Webhook
View
Functionitem Itemlists Automate
View