{"workflow":{"id":13545,"name":"Host a static HTML KPI dashboard from Google Sheets with CustomJS","views":1032,"recentViews":4,"totalViews":1032,"createdAt":"2026-02-20T12:41:01.892Z","description":"\n#  Hosting a static HTML KPI dashboard with CustomJS\n\nThis workflow demonstrates how to **automatically generate a weekly KPI dashboard** from Google Sheets and host it as a live static HTML page using [CustomJS](https://www.customjs.space).  \n\nInstead of manually building and updating dashboards, the workflow fetches KPI data, transforms it into JSON, and generates charts, tables, and KPI cards automatically. The hosted HTML page can be connected to a custom domain with one click.\n\nThe result is a **fully interactive, production-ready KPI dashboard** that updates weekly with minimal effort.\n\n---\n\n## Why This Workflow?\n\nCreating dashboards manually or passing raw sheet data to visualization tools is:\n\n- time-consuming  \n- error-prone  \n- hard to automate  \n\nThis workflow automates the process by converting sheet data into **structured JSON** and feeding it directly into a **CustomJS HTML template**, generating charts and tables automatically.\n\n---\n\n## What This Workflow Does\n\n- Fetches **KPI metrics** (Visitors, Leads, Demo Booked, Proposal Sent, Won) from Google Sheets  \n- Aggregates metrics by week and channel  \n- Converts the structured data into JSON for dashboard consumption  \n- Generates a **static HTML page** with KPI cards, charts, and tables  \n- Hosts the HTML page on **CustomJS**, optionally connected to a custom domain  \n\nAll without manual intervention.\n\n---\n\n## Key Features\n\n- **Automated KPI Dashboards**  \n  Generate charts, tables, and KPI cards from Google Sheets data\n\n- **Static HTML Hosting**  \n  Live dashboards are instantly deployable and accessible anywhere\n\n- **Custom Domains**  \n  Connect your own domain with a single click\n\n- **Interactive Charts**  \n  Uses Chart.js for bar and line charts, fully responsive\n\n- **QR Code Ready**  \n  Optional QR code generation for sharing dashboard links\n\n- **Token-Efficient**  \n  Only structured JSON is processed, no large unnecessary payloads\n\n---\n\n## How It Works\n\n1. **Manual or Scheduled Trigger**  \n   Run the workflow on demand or weekly\n\n2. **Load Data from Google Sheets**  \n   - Pull metrics for the desired period  \n   - Aggregate weekly or by channel\n\n3. **Prepare Structured JSON**  \n   Format sheet rows into structured JSON for the dashboard\n\n4. **Generate HTML Dashboard**  \n   Feed JSON into a **CustomJS HTML template** node  \n   Automatically builds KPI cards, charts, and tables\n\n5. **Host Static HTML**  \n   - Deploy instantly via CustomJS  \n   - Optional: connect a custom domain  \n   - Each update overwrites the previous dashboard\n\n6. **Optional Enhancements**  \n   - Generate QR codes for the dashboard link  \n   - Include multiple charts, historical trends, or multiple sheets","workflow":{"meta":{"instanceId":"148ba950667ef04d0c16951c0250998ce6284ec0fd24f99df14953aba6dd4949","templateCredsSetupCompleted":true},"nodes":[{"id":"c430dbe3-a6b8-4e18-8cf8-a5e42a495f46","name":"When clicking ‘Execute workflow’","type":"n8n-nodes-base.manualTrigger","position":[5856,1920],"parameters":{},"typeVersion":1},{"id":"a63f4cbf-2477-4662-b651-af1c14332d32","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[4528,1408],"parameters":{"width":1200,"height":1184,"content":"# Hosting Static HTML KPI Dashboard with CustomJS\n\n[KPI Google Sheet](https://docs.google.com/spreadsheets/d/10mj6hngkPTg1_A6bVNn8QfKujap6j-Lrt_LwAkY2d7Q/edit?usp=sharing)  \n\nThis workflow automatically generates a weekly KPI dashboard from Google Sheets data and hosts it as a live static HTML page using [CustomJS](https://www.customjs.space).\n\n---\n\n## Setup\n- Requires a **self-hosted n8n instance** and a **CustomJS API key**.\n- Google Sheets should be **publicly accessible** or shared with a service account for n8n access.\n- Optional: Additional JSON/CSV sources can be integrated.\n\n---\n\n## How it works\n1 **Manual Trigger**  \n- Run the workflow on demand or schedule weekly.\n\n\n2 **Load Data from Google Sheet**  \n- Pull KPI metrics such as Visitors, Leads, Demo Booked, Proposal Sent, Won.  \n- Aggregate weekly or per channel as needed.\n\n\n3 **Prepare Structured JSON**  \n- Transform sheet rows into a clean JSON structure ready for the dashboard.  \n- Example structure: \n```json\n[\n  {\"Date\":\"2026-02-01\",\"Channel\":\"Google Ads\",\"Visitors\":1200,\"Leads\":95,\"Demo Booked\":40,\"Proposal Sent\":22,\"Won\":9},\n  {\"Date\":\"2026-02-01\",\"Channel\":\"LinkedIn\",\"Visitors\":800,\"Leads\":70,\"Demo Booked\":28,\"Proposal Sent\":16,\"Won\":7}\n]\n```\n\n4 **Generate HTML Dashboard**  \n- Feed JSON into a CustomJS HTML template node.\n- Automatically builds KPI cards, tables, and charts using Chart.js.\n\n\n5 **Host Static HTML**\n- CustomJS deploys the HTML page instantly.\n- Optional: Connect a custom domain in one click.\n- Each weekly update overwrites the previous dashboard.\n\n\n6 **Optional Enhancements**\n- Generate QR codes for the live dashboard link.\n- Include multiple charts, multiple sheets, or historical trends."},"typeVersion":1},{"id":"63aad3dc-26fd-4427-ab40-762761c6b1fe","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[5776,1824],"parameters":{"color":7,"width":960,"height":416,"content":"## Collect sheet data and convert to json"},"typeVersion":1},{"id":"dd1a3ad4-505f-4222-a05c-e66bd9332c99","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[6848,1824],"parameters":{"color":7,"width":544,"height":416,"content":"## Build and publish HTML"},"typeVersion":1},{"id":"63ab98d5-413e-4c9f-9334-742c5a87c3b4","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[7504,1840],"parameters":{"color":7,"width":432,"height":400,"content":"## Generate QR code"},"typeVersion":1},{"id":"3ceea1d1-37dd-48f3-a571-4a9bbbe02479","name":"HTML","type":"n8n-nodes-base.html","position":[6960,1968],"parameters":{"html":"<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"UTF-8\">\n<title>KPI Dashboard</title>\n<script src=\"https://cdn.jsdelivr.net/npm/chart.js\"></script>\n\n<style>\nbody{\n  font-family: system-ui, -apple-system, sans-serif;\n  background:#f6f7fb;\n  margin:0;\n  padding:24px;\n  color:#111;\n}\n.container{\n  max-width:1100px;\n  margin:auto;\n}\nh1{margin-bottom:4px;}\n.subtitle{color:#666;margin-bottom:30px;}\n\n.cards{\n  display:grid;\n  grid-template-columns:repeat(auto-fit,minmax(180px,1fr));\n  gap:16px;\n  margin-bottom:30px;\n}\n.card{\n  background:white;\n  padding:18px;\n  border-radius:12px;\n  box-shadow:0 2px 6px rgba(0,0,0,0.06);\n}\n.card .label{font-size:13px;color:#666}\n.card .value{font-size:24px;font-weight:700;margin-top:6px}\n\n.charts{\n  display:grid;\n  grid-template-columns:repeat(auto-fit, minmax(300px,1fr));\n  gap:24px;\n  margin-bottom:24px;\n}\n@media(max-width:900px){\n  .charts{\n    grid-template-columns:1fr;\n  }\n}\ncanvas{\n  max-width:100%;\n  width:100%;\n  height:280px;\n  box-sizing:border-box;\n}\n\n.section{\n  background:white;\n  padding:18px;\n  border-radius:12px;\n  margin-bottom:24px;\n  box-shadow:0 2px 6px rgba(0,0,0,0.06);\n}\n\ntable{\n  width:100%;\n  border-collapse:collapse;\n}\nth,td{\n  padding:10px;\n  border-bottom:1px solid #eee;\n  text-align:left;\n  font-size:14px;\n}\nth{color:#666;font-weight:600;}\n\n.footer{\n  text-align:center;\n  margin-top:30px;\n  color:#999;\n  font-size:12px;\n}\n</style>\n</head>\n\n<body>\n<div class=\"container\">\n\n<h1 id=\"title\"></h1>\n<div class=\"subtitle\" id=\"period\"></div>\n\n<div class=\"cards\" id=\"kpiCards\"></div>\n\n<div class=\"charts\">\n\n  <div class=\"section\">\n    <h3>Visitors by Channel</h3>\n    <canvas id=\"visitorsChart\"></canvas>\n  </div>\n\n  <div class=\"section\">\n    <h3>Funnel Conversion</h3>\n    <canvas id=\"funnelChart\"></canvas>\n  </div>\n\n</div>\n\n<div class=\"section\">\n  <h3>Channel Breakdown</h3>\n  <table id=\"table\"></table>\n</div>\n\n<div class=\"footer\">\nGenerated automatically • KPI Dashboard\n</div>\n\n</div>\n\n<script>\n/* ===== JSON Daten ===== */\nconst report = {\n  reportTitle: \"Weekly Sales Funnel Report\",\n  period: \"Week ending 2026-02-01\",\n  data: {{ JSON.stringify($json.data) }}\n};\n\n/* ===== Totals berechnen ===== */\nconst totals = report.data.reduce((a,c)=>({\n  visitors: a.visitors + (Number(c[\"Visitors\"]) || 0),\n  leads: a.leads + (Number(c[\"Leads\"]) || 0),\n  demo: a.demo + (Number(c[\"Demo Booked\"]) || 0),\n  proposal: a.proposal + (Number(c[\"Proposal Sent\"]) || 0),\n  won: a.won + (Number(c[\"Won\"]) || 0)\n}), {visitors:0, leads:0, demo:0, proposal:0, won:0});\n\n/* ===== KPIs ===== */\nconst leadRate = totals.visitors\n  ? ((totals.leads / totals.visitors)*100).toFixed(1)\n  : \"0.0\";\n\nconst closeRate = totals.leads\n  ? ((totals.won / totals.leads)*100).toFixed(1)\n  : \"0.0\";\n\n/* ===== HEADER ===== */\ndocument.getElementById(\"title\").textContent = report.reportTitle;\ndocument.getElementById(\"period\").textContent = report.period;\n\n/* ===== KPI CARDS ===== */\nconst cards = [\n  [\"Visitors\", totals.visitors],\n  [\"Leads\", totals.leads],\n  [\"Deals Won\", totals.won],\n  [\"Lead Rate\", leadRate+\"%\"],\n  [\"Close Rate\", closeRate+\"%\"]\n];\ndocument.getElementById(\"kpiCards\").innerHTML = cards.map(c=>`\n<div class=\"card\">\n  <div class=\"label\">${c[0]}</div>\n  <div class=\"value\">${c[1]}</div>\n</div>`).join(\"\");\n\n/* ===== TABLE ===== */\ndocument.getElementById(\"table\").innerHTML = `\n<tr>\n  <th>Channel</th>\n  <th>Visitors</th>\n  <th>Leads</th>\n  <th>Demo</th>\n  <th>Proposal</th>\n  <th>Won</th>\n</tr>` + report.data.map(r=>`\n<tr>\n  <td>${r[\"Channel\"]}</td>\n  <td>${r[\"Visitors\"]}</td>\n  <td>${r[\"Leads\"]}</td>\n  <td>${r[\"Demo Booked\"]}</td>\n  <td>${r[\"Proposal Sent\"]}</td>\n  <td>${r[\"Won\"]}</td>\n</tr>`).join(\"\");\n\n/* ===== VISITORS CHART ===== */\nnew Chart(document.getElementById('visitorsChart'),{\n  type:'bar',\n  data:{\n    labels: report.data.map(r=>r[\"Channel\"]),\n    datasets:[{\n      label:'Visitors',\n      data: report.data.map(r=>Number(r[\"Visitors\"]) || 0),\n      backgroundColor:['#4f46e5','#10b981','#f59e0b']\n    }]\n  },\n  options:{\n    responsive:true,\n    plugins:{legend:{display:false}},\n    layout:{padding:8}\n  }\n});\n\n/* ===== FUNNEL CHART ===== */\nnew Chart(document.getElementById('funnelChart'),{\n  type:'line',\n  data:{\n    labels:[\"Visitors\",\"Leads\",\"Demo\",\"Proposal\",\"Won\"],\n    datasets:[{\n      label:'Total Funnel',\n      data:[\n        totals.visitors,\n        totals.leads,\n        totals.demo,\n        totals.proposal,\n        totals.won\n      ],\n      borderColor:'#4f46e5',\n      backgroundColor:'rgba(79,70,229,0.2)',\n      tension:0.4,\n      fill:true\n    }]\n  },\n  options:{\n    responsive:true,\n    plugins:{legend:{display:false}},\n    layout:{padding:8}\n  }\n});\n</script>\n</body>\n</html>"},"typeVersion":1.2},{"id":"af3d762b-f5c4-4b39-8f0a-8bf275e53dc7","name":"Get Data From Sheet","type":"n8n-nodes-base.httpRequest","position":[6096,1968],"parameters":{"url":"https://docs.google.com/spreadsheets/d/10mj6hngkPTg1_A6bVNn8QfKujap6j-Lrt_LwAkY2d7Q/gviz/tq?tqx=out:csv&sheet=Sheet1","options":{"response":{"response":{"responseFormat":"file"}}}},"typeVersion":4.4},{"id":"effc82e4-f01b-4984-8b4b-5353d203f4f7","name":"Convert HTML to PDF","type":"@custom-js/n8n-nodes-pdf-toolkit-v2.pdfToolkit","position":[7632,1968],"parameters":{"html":"=<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"UTF-8\">\n<title>KPI Dashbaord</title>\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js\"></script>\n<style>\nbody {\n  font-family: system-ui, -apple-system, sans-serif;\n  background: #f6f7fb;\n  margin: 0;\n  padding: 24px;\n  color: #111;\n}\n.container {\n  max-width: 400px;\n  margin: auto;\n  background: #fff;\n  padding: 24px;\n  border-radius: 12px;\n  box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n}\nh1 {\n  margin-bottom: 24px;\n}\n#qrcode {\n  margin-top: 24px;\n}\n</style>\n</head>\n<body>\n\n<div class=\"container\">\n  <h1>KPI Dashboard</h1>\n  <div id=\"qrcode\"></div>\n</div>\n\n<script>\nconst url = \"{{ $json.htmlFileUrl }}\";\n\nnew QRCode(document.getElementById(\"qrcode\"), {\n  text: url,\n  width: 200,\n  height: 200,\n  colorDark: \"#4f46e5\",\n  colorLight: \"#ffffff\",\n  correctLevel: QRCode.CorrectLevel.H\n});\n</script>\n\n</body>\n</html> ","operation":"htmlToPdf","pdfHeightMm":120},"credentials":{"customJsApi":{"id":"d0EHxiyZak4WWRfy","name":"CustomJS account"}},"typeVersion":1},{"id":"9ec01a64-4ba6-4df0-a3fc-8d4dc711af49","name":"Extract from File","type":"n8n-nodes-base.extractFromFile","position":[6320,1968],"parameters":{"options":{}},"typeVersion":1.1},{"id":"c05037bf-f6cb-4238-b45d-17f7bd3c3304","name":"Aggregate","type":"n8n-nodes-base.aggregate","position":[6512,1968],"parameters":{"options":{},"aggregate":"aggregateAllItemData"},"typeVersion":1},{"id":"64a36470-99ac-45a7-86c5-6d40ca508615","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[5856,2096],"parameters":{"rule":{"interval":[{}]}},"typeVersion":1.3},{"id":"95630953-76c3-4af6-80d9-4714c17715df","name":"Upsert HTML Page","type":"@custom-js/n8n-nodes-pdf-toolkit-v2.pdfToolkit","position":[7200,1968],"parameters":{"pageName":"KPI Dashboard","resource":"page","operation":"upsert","htmlContent":"={{ $('HTML').item.json.html }}"},"credentials":{"customJsApi":{"id":"d0EHxiyZak4WWRfy","name":"CustomJS account"}},"typeVersion":1}],"pinData":{},"connections":{"HTML":{"main":[[{"node":"Upsert HTML Page","type":"main","index":0}]]},"Aggregate":{"main":[[{"node":"HTML","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Get Data From Sheet","type":"main","index":0}]]},"Upsert HTML Page":{"main":[[{"node":"Convert HTML to PDF","type":"main","index":0}]]},"Extract from File":{"main":[[{"node":"Aggregate","type":"main","index":0}]]},"Get Data From Sheet":{"main":[[{"node":"Extract from File","type":"main","index":0}]]},"When clicking ‘Execute workflow’":{"main":[[{"node":"Get Data From Sheet","type":"main","index":0}]]}}},"lastUpdatedBy":29,"workflowInfo":{"nodeCount":12,"nodeTypes":{"n8n-nodes-base.html":{"count":1},"n8n-nodes-base.aggregate":{"count":1},"n8n-nodes-base.stickyNote":{"count":4},"n8n-nodes-base.httpRequest":{"count":1},"n8n-nodes-base.manualTrigger":{"count":1},"n8n-nodes-base.extractFromFile":{"count":1},"n8n-nodes-base.scheduleTrigger":{"count":1},"@custom-js/n8n-nodes-pdf-toolkit-v2.pdfToolkit":{"count":2}}},"status":"published","readyToDemo":null,"user":{"name":"CustomJS","username":"customjs","bio":"","verified":true,"links":["https://www.customjs.space"],"avatar":"https://gravatar.com/avatar/942ecdadf17761bc7f516b67fb0f3617809720caf8912cfd1815ed2a9f8b9ad3?r=pg&d=retro&size=200"},"nodes":[{"id":19,"icon":"file:httprequest.svg","name":"n8n-nodes-base.httpRequest","codex":{"data":{"alias":["API","Request","URL","Build","cURL"],"resources":{"generic":[{"url":"https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/","icon":"☀️","label":"2021: The Year to Automate the New You with n8n"},{"url":"https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/","icon":"🧬","label":"Why business process automation with n8n can change your daily life"},{"url":"https://n8n.io/blog/automatically-pulling-and-visualizing-data-with-n8n/","icon":"📈","label":"Automatically pulling and visualizing data with n8n"},{"url":"https://n8n.io/blog/learn-how-to-automatically-cross-post-your-content-with-n8n/","icon":"✍️","label":"Learn how to automatically cross-post your content with n8n"},{"url":"https://n8n.io/blog/automatically-adding-expense-receipts-to-google-sheets-with-telegram-mindee-twilio-and-n8n/","icon":"🧾","label":"Automatically Adding Expense Receipts to Google Sheets with Telegram, Mindee, Twilio, and n8n"},{"url":"https://n8n.io/blog/running-n8n-on-ships-an-interview-with-maranics/","icon":"🛳","label":"Running n8n on ships: An interview with Maranics"},{"url":"https://n8n.io/blog/what-are-apis-how-to-use-them-with-no-code/","icon":" 🪢","label":"What are APIs and how to use them with no code"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/world-poetry-day-workflow/","icon":"📜","label":"Celebrating World Poetry Day with a daily poem in Telegram"},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/automate-designs-with-bannerbear-and-n8n/","icon":"🎨","label":"Automate Designs with Bannerbear and n8n"},{"url":"https://n8n.io/blog/how-uproc-scraped-a-multi-page-website-with-a-low-code-workflow/","icon":" 🕸️","label":"How uProc scraped a multi-page website with a low-code workflow"},{"url":"https://n8n.io/blog/building-an-expense-tracking-app-in-10-minutes/","icon":"📱","label":"Building an expense tracking app in 10 minutes"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/how-to-use-the-http-request-node-the-swiss-army-knife-for-workflow-automation/","icon":"🧰","label":"How to use the HTTP Request Node - The Swiss Army Knife for Workflow Automation"},{"url":"https://n8n.io/blog/learn-how-to-use-webhooks-with-mattermost-slash-commands/","icon":"🦄","label":"Learn how to use webhooks with Mattermost slash commands"},{"url":"https://n8n.io/blog/how-a-membership-development-manager-automates-his-work-and-investments/","icon":"📈","label":"How a Membership Development Manager automates his work and investments"},{"url":"https://n8n.io/blog/a-low-code-bitcoin-ticker-built-with-questdb-and-n8n-io/","icon":"📈","label":"A low-code bitcoin ticker built with QuestDB and n8n.io"},{"url":"https://n8n.io/blog/how-to-set-up-a-ci-cd-pipeline-with-no-code/","icon":"🎡","label":"How to set up a no-code CI/CD pipeline with GitHub and TravisCI"},{"url":"https://n8n.io/blog/automations-for-activists/","icon":"✨","label":"How Common Knowledge use workflow automation for activism"},{"url":"https://n8n.io/blog/creating-scheduled-text-affirmations-with-n8n/","icon":"🤟","label":"Creating scheduled text affirmations with n8n"},{"url":"https://n8n.io/blog/how-goomer-automated-their-operations-with-over-200-n8n-workflows/","icon":"🛵","label":"How Goomer automated their operations with over 200 n8n workflows"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/"}]},"categories":["Development","Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"output\"]","defaults":{"name":"HTTP Request","color":"#0004F5"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHZpZXdCb3g9IjAgMCA0MCA0MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00MCAyMEM0MCA4Ljk1MzE0IDMxLjA0NjkgMCAyMCAwQzguOTUzMTQgMCAwIDguOTUzMTQgMCAyMEMwIDMxLjA0NjkgOC45NTMxNCA0MCAyMCA0MEMzMS4wNDY5IDQwIDQwIDMxLjA0NjkgNDAgMjBaTTIwIDM2Ljk0NThDMTguODg1MiAzNi45NDU4IDE3LjEzNzggMzUuOTY3IDE1LjQ5OTggMzIuNjk4NUMxNC43OTY0IDMxLjI5MTggMTQuMTk2MSAyOS41NDMxIDEzLjc1MjYgMjcuNjg0N0gyNi4xODk4QzI1LjgwNDUgMjkuNTQwMyAyNS4yMDQ0IDMxLjI5MDEgMjQuNTAwMiAzMi42OTg1QzIyLjg2MjIgMzUuOTY3IDIxLjExNDggMzYuOTQ1OCAyMCAzNi45NDU4Wk0xMi45MDY0IDIwQzEyLjkwNjQgMjEuNjA5NyAxMy4wMDg3IDIzLjE2NCAxMy4yMDAzIDI0LjYzMDVIMjYuNzk5N0MyNi45OTEzIDIzLjE2NCAyNy4wOTM2IDIxLjYwOTcgMjcuMDkzNiAyMEMyNy4wOTM2IDE4LjM5MDMgMjYuOTkxMyAxNi44MzYgMjYuNzk5NyAxNS4zNjk1SDEzLjIwMDNDMTMuMDA4NyAxNi44MzYgMTIuOTA2NCAxOC4zOTAzIDEyLjkwNjQgMjBaTTIwIDMuMDU0MTlDMjEuMTE0OSAzLjA1NDE5IDIyLjg2MjIgNC4wMzA3OCAyNC41MDAxIDcuMzAwMzlDMjUuMjA2NiA4LjcxNDA4IDI1LjgwNzIgMTAuNDA2NyAyNi4xOTIgMTIuMzE1M0gxMy43NTAxQzE0LjE5MzMgMTAuNDA0NyAxNC43OTQyIDguNzEyNTQgMTUuNDk5OCA3LjMwMDY0QzE3LjEzNzcgNC4wMzA4MyAxOC44ODUxIDMuMDU0MTkgMjAgMy4wNTQxOVpNMzAuMTQ3OCAyMEMzMC4xNDc4IDE4LjQwOTkgMzAuMDU0MyAxNi44NjE3IDI5LjgyMjcgMTUuMzY5NUgzNi4zMDQyQzM2LjcyNTIgMTYuODQyIDM2Ljk0NTggMTguMzk2NCAzNi45NDU4IDIwQzM2Ljk0NTggMjEuNjAzNiAzNi43MjUyIDIzLjE1OCAzNi4zMDQyIDI0LjYzMDVIMjkuODIyN0MzMC4wNTQzIDIzLjEzODMgMzAuMTQ3OCAyMS41OTAxIDMwLjE0NzggMjBaTTI2LjI3NjcgNC4yNTUxMkMyNy42MzY1IDYuMzYwMTkgMjguNzExIDkuMTMyIDI5LjM3NzQgMTIuMzE1M0gzNS4xMDQ2QzMzLjI1MTEgOC42NjggMzAuMTA3IDUuNzgzNDYgMjYuMjc2NyA0LjI1NTEyWk0xMC42MjI2IDEyLjMxNTNINC44OTI5M0M2Ljc1MTQ3IDguNjY3ODQgOS44OTM1MSA1Ljc4MzQxIDEzLjcyMzIgNC4yNTUxM0MxMi4zNjM1IDYuMzYwMjEgMTEuMjg5IDkuMTMyMDEgMTAuNjIyNiAxMi4zMTUzWk0zLjA1NDE5IDIwQzMuMDU0MTkgMjEuNjAzIDMuMjc3NDMgMjMuMTU3NSAzLjY5NDg0IDI0LjYzMDVIMTAuMTIxN0M5Ljk0NjE5IDIzLjE0MiA5Ljg1MjIyIDIxLjU5NDMgOS44NTIyMiAyMEM5Ljg1MjIyIDE4LjQwNTcgOS45NDYxOSAxNi44NTggMTAuMTIxNyAxNS4zNjk1SDMuNjk0ODRDMy4yNzc0MyAxNi44NDI1IDMuMDU0MTkgMTguMzk3IDMuMDU0MTkgMjBaTTI2LjI3NjYgMzUuNzQyN0MyNy42MzY1IDMzLjYzOTMgMjguNzExIDMwLjg2OCAyOS4zNzc0IDI3LjY4NDdIMzUuMTA0NkMzMy4yNTEgMzEuMzMyMiAzMC4xMDY4IDM0LjIxNzkgMjYuMjc2NiAzNS43NDI3Wk0xMy43MjM0IDM1Ljc0MjdDOS44OTM2OSAzNC4yMTc5IDYuNzUxNTUgMzEuMzMyNCA0Ljg5MjkzIDI3LjY4NDdIMTAuNjIyNkMxMS4yODkgMzAuODY4IDEyLjM2MzUgMzMuNjM5MyAxMy43MjM0IDM1Ljc0MjdaIiBmaWxsPSIjM0E0MkU5Ii8+Cjwvc3ZnPgo="},"displayName":"HTTP Request","typeVersion":4,"nodeCategories":[{"id":5,"name":"Development"},{"id":9,"name":"Core Nodes"}]},{"id":565,"icon":"fa:sticky-note","name":"n8n-nodes-base.stickyNote","codex":{"data":{"alias":["Comments","Notes","Sticky"],"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"input\"]","defaults":{"name":"Sticky Note","color":"#FFD233"},"iconData":{"icon":"sticky-note","type":"icon"},"displayName":"Sticky Note","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":838,"icon":"fa:mouse-pointer","name":"n8n-nodes-base.manualTrigger","codex":{"data":{"resources":{"generic":[],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.manualworkflowtrigger/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0"}},"group":"[\"trigger\"]","defaults":{"name":"When clicking ‘Execute workflow’","color":"#909298"},"iconData":{"icon":"mouse-pointer","type":"icon"},"displayName":"Manual Trigger","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":839,"icon":"fa:clock","name":"n8n-nodes-base.scheduleTrigger","codex":{"data":{"alias":["Time","Scheduler","Polling","Cron","Interval"],"resources":{"generic":[],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.scheduletrigger/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0"}},"group":"[\"trigger\",\"schedule\"]","defaults":{"name":"Schedule Trigger","color":"#31C49F"},"iconData":{"icon":"clock","type":"icon"},"displayName":"Schedule Trigger","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":842,"icon":"file:html.svg","name":"n8n-nodes-base.html","codex":{"data":{"alias":["extract","template","table"],"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.html/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Data Transformation"]}}},"group":"[\"transform\"]","defaults":{"name":"HTML"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHZpZXdCb3g9IjAgMCA0MCA0MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTguNjQwNjIgMEgxMC40Mzc1VjEuNzgxMjVIMTIuMDkzN1YwSDEzLjg5MDZWNS4zOTA2MkgxMi4wOTM3VjMuNTkzNzVIMTAuNDUzMVY1LjM5MDYySDguNjQwNjJNMTYuMjY1NiAxLjc5Njg3SDE0LjY3OTdWMEgxOS42NTYyVjEuNzk2ODdIMTguMDYyNVY1LjM5MDYySDE2LjI2NTZNMjAuNDQ1MyAwSDIyLjMyODFMMjMuNDg0NCAxLjg5ODQ0TDI0LjY0MDYgMEgyNi41MjM0VjUuMzkwNjJIMjQuNzI2NlYyLjcxODc1TDIzLjQ2ODcgNC42NTYyNUwyMi4yMTA5IDIuNzE4NzVWNS4zOTA2MkgyMC40NDUzTTI3LjQxNDEgMEgyOS4yMTA5VjMuNjA5MzdIMzEuNzU3OFY1LjM5MDYySDI3LjQxNDEiIGZpbGw9ImJsYWNrIi8+CjxwYXRoIGQ9Ik04LjU3ODEyIDM2Ljc5NjlMNiA3Ljg1OTM4SDM0LjM0MzdMMzEuNzY1NiAzNi43ODEyTDIwLjE0ODQgNDAiIGZpbGw9IiNFNDREMjYiLz4KPHBhdGggZD0iTTIwLjE3MTkgMzcuNTM5MVYxMC4yMzQ0SDMxLjc1NzhMMjkuNTQ2OSAzNC45MjE5IiBmaWxsPSIjRjE2NTI5Ii8+CjxwYXRoIGQ9Ik0xMS4yNjU2IDEzLjc3MzRIMjAuMTcxOVYxNy4zMjAzSDE1LjE1NjJMMTUuNDg0NCAyMC45NTMxSDIwLjE3MTlWMjQuNDkyMkgxMi4yMzQ0TTEyLjM5MDYgMjYuMjczNEgxNS45NTMxTDE2LjIwMzEgMjkuMTA5NEwyMC4xNzE5IDMwLjE3MTlWMzMuODc1TDEyLjg5MDYgMzEuODQzNyIgZmlsbD0iI0VCRUJFQiIvPgo8cGF0aCBkPSJNMjkuMDQ2OSAxMy43NzM0SDIwLjE1NjJWMTcuMzIwM0gyOC43MTg3TTI4LjM5ODQgMjAuOTUzMUgyMC4xNTYyVjI0LjVIMjQuNTMxMkwyNC4xMTcyIDI5LjEwOTRMMjAuMTU2MiAzMC4xNzE5VjMzLjg1OTRMMjcuNDIxOSAzMS44NDM3IiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K"},"displayName":"HTML","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":1235,"icon":"file:extractFromFile.svg","name":"n8n-nodes-base.extractFromFile","codex":{"data":{"alias":["CSV","Spreadsheet","Excel","xls","xlsx","ods","tabular","decode","decoding","Move Binary Data","Binary","File","PDF","JSON","HTML","ICS","iCal","txt","Text","RTF","XML","64","Base64","Convert"],"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.extractfromfile/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Files","Data Transformation"]}}},"group":"[\"input\"]","defaults":{"name":"Extract from File"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHZpZXdCb3g9IjAgMCA0MCA0MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAuOTM3NSAyQzAuNDE5NzMzIDIgMCAyLjQxOTczIDAgMi45Mzc1VjM3LjMyMjFDMCAzNy44Mzk5IDAuNDE5NzMzIDM4LjI1OTYgMC45Mzc1IDM4LjI1OTZIMjYuMjE1NEMyNi43MzMyIDM4LjI1OTYgMjcuMTUyOSAzNy44Mzk5IDI3LjE1MjkgMzcuMzIyMUwyNy4xNTI5IDMwLjY3MTlMMTYuNzk2OSAzMC42NzE5QzE0Ljg5ODQgMzAuNjcxOSAxMy4zNTk0IDI5LjEzMjkgMTMuMzU5NCAyNy4yMzQ0VjI1LjM1OTRDMTMuMzU5NCAyMy40NjA5IDE0Ljg5ODQgMjEuOTIxOSAxNi43OTY5IDIxLjkyMTlIMjcuMTUyOUwyNy4xNTI5IDE1Ljc4MjFIMTQuMzA4M0MxMy43OTA2IDE1Ljc4MjEgMTMuMzcwOCAxNS4zNjI0IDEzLjM3MDggMTQuODQ0NlYySDAuOTM3NVoiIGZpbGw9IiMzNTNGNkUiLz4KPHBhdGggZD0iTTE2LjAyNzEgMkMxNS45NDA4IDIgMTUuODcwOCAyLjA2OTk2IDE1Ljg3MDggMi4xNTYyNVYxMi44MTM0QzE1Ljg3MDggMTMuMDcyMyAxNi4wODA3IDEzLjI4MjEgMTYuMzM5NiAxMy4yODIxSDI2Ljk5NjdDMjcuMDgzIDEzLjI4MjEgMjcuMTUyOSAxMy4yMTIyIDI3LjE1MjkgMTMuMTI1OUwyNy4xNTI5IDEyLjYxNzFDMjcuMTUyOSAxMi4zNjg4IDI3LjA1NDUgMTIuMTMwNyAyNi44NzkxIDExLjk1NUwxNy4yMjI1IDIuMjc1MzhDMTcuMDQ2NiAyLjA5OTA4IDE2LjgwNzkgMiAxNi41NTg4IDJIMTYuMDI3MVoiIGZpbGw9IiMzNTNGNkUiLz4KPHBhdGggZD0iTTI5Ljc2NDIgMzQuNjUwM0MyOS4wMzQgMzMuOTE2IDI5LjAzNzQgMzIuNzI4OCAyOS43NzE2IDMxLjk5ODZMMzMuNjE5NyAyOC4xNzE5TDE2Ljc5NjkgMjguMTcxOUMxNi4yNzkxIDI4LjE3MTkgMTUuODU5NCAyNy43NTIxIDE1Ljg1OTQgMjcuMjM0NFYyNS4zNTk0QzE1Ljg1OTQgMjQuODQxNiAxNi4yNzkxIDI0LjQyMTkgMTYuNzk2OSAyNC40MjE5TDMzLjU0MTIgMjQuNDIxOUwyOS43NzE2IDIwLjY3MzNDMjkuMDM3NCAxOS45NDMxIDI5LjAzNCAxOC43NTU5IDI5Ljc2NDIgMTguMDIxNkMzMC40OTQ0IDE3LjI4NzQgMzEuNjgxNiAxNy4yODQgMzIuNDE1OSAxOC4wMTQyTDM5LjQ0NzEgMjUuMDA2NEMzOS44MDEgMjUuMzU4MyA0MCAyNS44MzY4IDQwIDI2LjMzNTlDNDAgMjYuODM1IDM5LjgwMSAyNy4zMTM1IDM5LjQ0NzEgMjcuNjY1NUwzMi40MTU5IDM0LjY1NzZDMzEuNjgxNiAzNS4zODc4IDMwLjQ5NDQgMzUuMzg0NSAyOS43NjQyIDM0LjY1MDNaIiBmaWxsPSIjMzUzRjZFIi8+Cjwvc3ZnPgo="},"displayName":"Extract from File","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":1236,"icon":"file:aggregate.svg","name":"n8n-nodes-base.aggregate","codex":{"data":{"alias":["Aggregate","Combine","Flatten","Transform","Array","List","Item"],"details":"","resources":{"generic":[],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.aggregate/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Data Transformation"]}}},"group":"[\"transform\"]","defaults":{"name":"Aggregate"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJub25lIj48ZyBmaWxsPSIjRkY2RDVBIiBjbGlwLXBhdGg9InVybCgjYSkiPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTMyIDE0OGMwLTYuNjI3IDUuMzczLTEyIDEyLTEyaDE0NmM2LjYyNyAwIDEyIDUuMzczIDEyIDEydjI0YzAgNi42MjctNS4zNzMgMTItMTIgMTJINDRjLTYuNjI3IDAtMTItNS4zNzMtMTItMTJ6bTAgOTZjMC02LjYyNyA1LjM3My0xMiAxMi0xMmgxNDZjNi42MjcgMCAxMiA1LjM3MyAxMiAxMnYyNGMwIDYuNjI3LTUuMzczIDEyLTEyIDEySDQ0Yy02LjYyNyAwLTEyLTUuMzczLTEyLTEyem0wIDk2YzAtNi42MjcgNS4zNzMtMTIgMTItMTJoMTQ2YzYuNjI3IDAgMTIgNS4zNzMgMTIgMTJ2MjRjMCA2LjYyNy01LjM3MyAxMi0xMiAxMkg0NGMtNi42MjcgMC0xMi01LjM3My0xMi0xMnoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGQ9Ik03NCA3NmMwIDYuNjI3IDUuMzczIDEyIDEyIDEyaDExNi4yMTdjMTcuNjczIDAgMzIgMTQuMzI3IDMyIDMydjU2YzAgMjYuOTc4IDEwLjI3MiA1MS41NTcgMjcuMTE5IDcwLjAzOSA1LjA1NSA1LjU0NSA1LjA1NSAxNC4zNzcgMCAxOS45MjItMTYuODQ3IDE4LjQ4Mi0yNy4xMTkgNDMuMDYxLTI3LjExOSA3MC4wMzl2NTZjMCAxNy42NzMtMTQuMzI3IDMyLTMyIDMySDg2Yy02LjYyNyAwLTEyIDUuMzczLTEyIDEydjI0YzAgNi42MjcgNS4zNzMgMTIgMTIgMTJoMTE2LjIxN2M0NC4xODMgMCA4MC0zNS44MTcgODAtODB2LTU2YzAtMzAuOTI4IDI1LjA3Mi01NiA1Ni01NmE1Ljc4MyA1Ljc4MyAwIDAgMCA1Ljc4My01Ljc4M3YtMzYuNDM0YTUuNzgzIDUuNzgzIDAgMCAwLTUuNzgzLTUuNzgzYy0zMC45MjggMC01Ni0yNS4wNzItNTYtNTZ2LTU2YzAtNDQuMTgzLTM1LjgxNy04MC04MC04MEg4NmMtNi42MjcgMC0xMiA1LjM3My0xMiAxMnoiLz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0zNzYgMjQ0YzAtNi42MjcgNS4zNzMtMTIgMTItMTJoMTEyYzYuNjI3IDAgMTIgNS4zNzMgMTIgMTJ2MjRjMCA2LjYyNy01LjM3MyAxMi0xMiAxMkgzODhjLTYuNjI3IDAtMTItNS4zNzMtMTItMTJ6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L2c+PGRlZnM+PGNsaXBQYXRoIGlkPSJhIj48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMCAwaDUxMnY1MTJIMHoiLz48L2NsaXBQYXRoPjwvZGVmcz48L3N2Zz4="},"displayName":"Aggregate","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]}],"categories":[{"id":35,"name":"Document Extraction"}],"image":[]}}