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

Summarize Google Drive Documents with Mistral AI and Send via Gmail
View
Create a project, tag, and time entry, and update the time entry in Clockify
View
Send daily weather updates via a message in Line
View
Manual Stickynote Automation Webhook
View
Code Manual Create Webhook
View
BambooHR AI-Powered Company Policies and Benefits Chatbot
View
Code GoogleCalendar Create Webhook
View
Redis Schedule Import Scheduled
View
Sync Todoist tasks to Notion
View
Microsoftexcel Manual Create Triggered
View