{
  "workflow": {
    "id": 7989,
    "name": "Website SEO health analytics with Google Sheets, PDF reports & Gmail alerts",
    "views": 516,
    "recentViews": 0,
    "totalViews": 516,
    "createdAt": "2025-08-28T10:39:03.801Z",
    "description": "# Automated SEO Health Monitoring & Reporting\n\nThis workflow automatically monitors the SEO health of websites stored in a Google Sheet. It fetches each website’s HTML, analyzes key SEO metrics (title, meta description, H1 count, canonical, robots, performance score, etc.) and updates results back into Google Sheets. If performance is poor (&lt;50), it sends an alert email. For healthy sites, it generates a detailed PDF report and stores it in Google Drive.\n\n## Who’s it for\n\n* Digital marketing teams\n* SEO agencies\n* Website administrators who want automated SEO health checks\n* Businesses with multiple websites or landing pages to monitor\n\n## How it works\n\n1. **Daily Trigger** – Runs every day at 9 AM.\n2. **Fetch Website List** – Reads website URLs from Google Sheets.\n3. **Crawl Websites** – Uses HTTP requests to fetch each website’s HTML.\n4. **SEO Analysis** – Extracts SEO-related metadata (title, meta description, H1, etc.).\n5. **Health Check** – Scores SEO performance based on predefined rules.\n6. **Decision Node** – If score &lt; 50 → Send alert email; else → Generate full SEO report.\n7. **Update Logs** – Logs results back into Google Sheets.\n8. **Generate PDF Reports** – Converts HTML reports into PDFs via PDF.co API.\n9. **Save to Drive** – Stores the PDF reports in Google Drive for long-term access.\n\n## How to set up\n\n1. Open n8n and import the workflow.\n2. Configure your **Google Sheets** credentials and specify the sheet containing your website URLs.\n3. Add your **Gmail** account to allow automated alert emails.\n4. Set up your **Google Drive** credentials for storing PDF reports.\n5. Obtain an **API key from PDF.co** and configure the HTTP Request node.\n6. Adjust the **Schedule Trigger** to the time that works best (default: 9 AM daily).\n7. Test the workflow with a sample domain list.\n\n## Requirements\n\n* n8n instance (self-hosted or cloud)\n* Google Sheets account (to store website URLs and logs)\n* Gmail account (for sending alerts)\n* Google Drive account (to save SEO reports)\n* PDF.co API Key (for HTML → PDF conversion)\n\n## How to customize\n\n* **Change performance threshold**: Modify the IF node condition (default &lt;50).\n* **Custom SEO rules**: Edit the “SEO Health Check” Function node to add/remove checks (e.g., missing schema tags, page load times).\n* **Different output storage**: Replace Google Drive with Dropbox, S3 or OneDrive.\n* **Alternate notification channels**: Swap Gmail with Slack, Microsoft Teams or Telegram.\n\n## Add-ons\n\n* Send Slack/Teams notifications for low scores.\n* Add PageSpeed Insights API for performance scoring.\n* Generate weekly summary reports per domain.\n* Integrate with Notion/Confluence to log SEO health history.\n\n## Use Case Examples\n\n* An SEO agency monitors **100+ client websites** daily and sends alerts when a site has poor SEO signals.\n* A company’s **marketing manager** gets a daily SEO health PDF report stored in Drive.\n* A SaaS product team automatically logs performance changes for each release.\n\n## Common Troubleshooting\n\n| **Issue** | **Possible Cause** | **Solution** |\n| ------------------------------------ | ------------------------------------------------ | --------------------------------------------------------------------------- |\n| Workflow fails at **HTTP Crawl** | Website blocks requests / timeout | Increase timeout in Set Config node or add retry logic. |\n| Always returns `https://example.com` | Missing canonical / OG tags in HTML | Enhanced code now infers from JSON-LD or domain detection. Update analyzer. |\n| PDF not generated | Invalid API key or wrong endpoint in PDF.co node | Verify PDF.co API key and endpoint URL. |\n| Email not sending | Gmail credentials not set or blocked | Reconnect Gmail in n8n credentials manager. |\n| Google Sheet not updating | Wrong column mapping in Update Sheet node | Check node mapping: domain column vs performance/date columns. |\n| Google Drive upload fails | Missing folder permissions | Ensure correct Drive folder ID and credentials. |\n\n## Need Help?\n\nIf you’d like assistance setting up, customizing or scaling this workflow for your use case, our n8n automation team at WeblineIndia can help you:\n\n* Tailor SEO rules for your industry.\n* Connect to additional APIs (Ahrefs, Semrush, PageSpeed).\n* Automate weekly/monthly reporting with summary dashboards.\n",
    "workflow": {
      "id": "FhqpDaUdWSIToAh4",
      "meta": {
        "instanceId": "14e4c77104722ab186539dfea5182e419aecc83d85963fe13f6de862c875ebfa",
        "templateCredsSetupCompleted": true
      },
      "name": "Automated SEO Health Monitoring & Reporting",
      "tags": [],
      "nodes": [
        {
          "id": "5b417215-e917-4183-b57a-66bfa835fbe1",
          "name": "Sticky Note",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            -290,
            -600
          ],
          "parameters": {
            "width": 2460,
            "height": 860,
            "content": "# **Automated SEO Health Monitoring & Reporting**\n\n## This workflow runs daily to analyze websites from Google Sheets, evaluate their SEO health, send alerts if performance is low, and generate PDF reports stored in Google Drive.\n"
          },
          "typeVersion": 1
        },
        {
          "id": "2733c633-858e-4a0f-807f-79727f3bd178",
          "name": "Sticky Note1",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            -280,
            300
          ],
          "parameters": {
            "width": 2460,
            "height": 2300,
            "content": "# **Node Breakdown & Descriptions:**\n\n# 1. **Daily 9 AM Trigger**\n\n## Triggers the workflow **every day at 9 AM** to start the SEO health monitoring pipeline.\n\n# 2. **Fetch Website Links**\n\n## Reads a list of **website URLs** from a predefined Google Sheet where domains to be monitored are stored.\n\n# 3. **Attach Config & Timeout**\n\n## Takes the website links and attaches configuration values like **timeout** and other metadata for each request.\n\n# 4. **Fetch Website HTML**\n\n## Fetches the **raw HTML content** of each website URL to prepare it for SEO analysis.\n\n# 5. **Analyze HTML (SEO Basics)**\n\n## Parses the HTML content and extracts SEO-related fields like **title, meta description, H1 count, canonical link, robots tag, and image alt attributes**.\n\n# 6. **SEO Health Check & Score**\n\n## Runs a **health scoring algorithm** on the extracted SEO content, checking for issues and calculating the final **performance score**.\n\n# 7. **Check Performance < 50**\n\n## Evaluates whether the website’s SEO **performance score is below 50**.\n\n## * **True branch** → Alert email + log poor performance.\n## * **False branch** → Generate full report + store results.\n\n# 8. **Send Alert Email (Low SEO Score)**\n\n## If performance is **< 50**, sends an **alert email** to the monitoring team with details of the failed SEO health check.\n\n# 9. **Merge Alert & Normal Results**\n\n## Merges results from both branches (low-performing and acceptable-performing sites) so all can be logged in the sheet.\n\n# 10. **Update Performance Log**\n\n## Updates the Google Sheet with the **performance score and timestamp** for each domain that was analyzed.\n\n# 11. **Generate SEO Report (HTML)**\n\n## For websites that passed the performance threshold, generates a **detailed HTML SEO report** with findings and summary.\n\n# 12. **Convert HTML to PDF**\n\n## Sends the generated HTML to **PDF.co API** to convert it into a **PDF SEO report**.\n\n# 13. **Download PDF File**\n\n## Downloads the **generated PDF file** from the PDF.co temporary storage URL.\n\n# 14. **Save SEO Report to Drive**\n\n## Uploads the **PDF SEO Report** into the configured Google Drive folder for record-keeping and future reference.\n"
          },
          "typeVersion": 1
        },
        {
          "id": "41837314-159b-4d19-91ae-dfa75519a762",
          "name": "Daily 9 AM Trigger",
          "type": "n8n-nodes-base.cron",
          "position": [
            -220,
            -160
          ],
          "parameters": {
            "triggerTimes": {
              "item": [
                {
                  "hour": 9
                }
              ]
            }
          },
          "typeVersion": 1
        },
        {
          "id": "4c9372e7-50e3-42e3-96ad-90bd6cf38feb",
          "name": "Fetch Website Links",
          "type": "n8n-nodes-base.googleSheets",
          "position": [
            0,
            -160
          ],
          "parameters": {
            "options": {},
            "sheetName": {
              "__rl": true,
              "mode": "list",
              "value": 228478758,
              "cachedResultUrl": "",
              "cachedResultName": "Website_Seo_Testing"
            },
            "documentId": {
              "__rl": true,
              "mode": "list",
              "value": "1cQ-TBf3-dqo7njDYzYpxpASYFvEp8lIzH7vpIqTLcwc",
              "cachedResultUrl": "",
              "cachedResultName": "N8N_Email_Attachment"
            }
          },
          "credentials": {
            "googleSheetsOAuth2Api": {
              "id": "credential-id",
              "name": "googleSheetsOAuth2Api Credential"
            }
          },
          "typeVersion": 4.6
        },
        {
          "id": "0fc6228a-9783-4f66-a777-86f7dadcd440",
          "name": "Attach Config & Timeout",
          "type": "n8n-nodes-base.set",
          "position": [
            220,
            -160
          ],
          "parameters": {
            "fields": {
              "values": [
                {
                  "name": "siteUrl",
                  "stringValue": "={{ $json[\"Website Link\"] }}"
                },
                {
                  "name": "timeoutMs",
                  "stringValue": "2000"
                }
              ]
            },
            "options": {}
          },
          "typeVersion": 3
        },
        {
          "id": "70be1b7b-880a-4f81-9ee0-92d3003153ad",
          "name": "Fetch Website HTML",
          "type": "n8n-nodes-base.httpRequest",
          "position": [
            440,
            -160
          ],
          "parameters": {
            "url": "={{$json[\"siteUrl\"]}}",
            "options": {
              "timeout": "={{$json[\"timeoutMs\"]}}"
            }
          },
          "typeVersion": 4
        },
        {
          "id": "93ca197e-4579-4703-b457-f57600fb574c",
          "name": "Analyze HTML (SEO Basics)",
          "type": "n8n-nodes-base.code",
          "position": [
            660,
            -160
          ],
          "parameters": {
            "jsCode": "// Robust SEO analyzer:\n// - Accepts html from item.json.body OR item.json.data OR item.binary.data (base64)\n// - Guesses siteUrl from canonical/og:url/base if missing (enhanced with JSON-LD, home/logo, dominant domain, form/asset hosts, first absolute URL)\n// - Falls back to og:description if meta[name=\"description\"] missing\n// - Returns: url, seo{}, summary{}, issues[], brokenLinks[], critical, plus config passthrough\n\nconst out = [];\n\nfunction getHtmlFromItem(item) {\n  // Prefer explicit fields first\n  if (typeof item.json.body === 'string' && item.json.body.trim()) return { html: item.json.body, source: 'json.body' };\n  if (typeof item.json.data === 'string' && item.json.data.trim()) return { html: item.json.data, source: 'json.data' };\n\n  // Binary (e.g., from HTTP node set to \"File\")\n  if (item.binary && item.binary.data && item.binary.data.data) {\n    try {\n      const decoded = Buffer.from(item.binary.data.data, 'base64').toString('utf8');\n      if (decoded && /<html[^>]*>/i.test(decoded)) return { html: decoded, source: 'binary.data' };\n    } catch {}\n  }\n  return { html: '', source: 'none' };\n}\n\nfor (const item of items) {\n  const { html, source: htmlSource } = getHtmlFromItem(item);\n\n  // Pull config if present (still works with your Set Config + Merge approach)\n  const timeoutMs = Number(item.json.timeoutMs ?? 5000);\n  const maxLinkChecks = Number(item.json.maxLinkChecks ?? 30);\n\n  // helpers\n  const issues = [];\n  const warn = (msg) => issues.push({ level: \"warning\", msg });\n  const crit = (msg) => issues.push({ level: \"critical\", msg });\n\n  const grab = (re, s) => {\n    const m = re.exec(s);\n    return m ? m[1] : null;\n  };\n  const grabAll = (re, s) => {\n    const arr = [];\n    let m;\n    while ((m = re.exec(s)) !== null) arr.push(m[1]);\n    return arr;\n  };\n\n  // --- ADDED HELPERS (safe additions) ---\n  const ABS_RE = /^https?:\\/\\//i;\n  const isAbs = (u) => ABS_RE.test(u);\n  const toAbs = (maybeUrl, base) => { try { return new URL(maybeUrl, base).href; } catch { return null; } };\n  const originOf = (u) => { try { const x = new URL(u); return `${x.protocol}//${x.host}/`; } catch { return null; } };\n  const hostOf   = (u) => { try { return new URL(u).host; } catch { return null; } };\n\n  // Third-party patterns to ignore when inferring the site's own host\n  const THIRD_PARTY = /(googleapis\\.com|gstatic\\.com|googletagmanager\\.com|google-analytics\\.com|doubleclick\\.net|facebook\\.com|twitter\\.com|instagram\\.com|youtube\\.com|vimeo\\.com|cloudfront\\.net|fonts\\.googleapis\\.com|fonts\\.gstatic\\.com|ajax\\.googleapis\\.com)/i;\n\n  // Parse JSON-LD to find a plausible page URL\n  function jsonLdUrl(htmlText) {\n    const blocks = [];\n    let m;\n    const re = /<script[^>]*type=[\"']application\\/ld\\+json[\"'][^>]*>([\\s\\S]*?)<\\/script>/gi;\n    while ((m = re.exec(htmlText)) !== null) blocks.push(m[1]);\n    for (const raw of blocks) {\n      try {\n        const data = JSON.parse(raw.trim());\n        const nodes = Array.isArray(data['@graph']) ? data['@graph'] : [data];\n        for (const node of nodes) {\n          if (node['@type'] && /WebPage/i.test(node['@type']) && typeof node.url === 'string' && node.url) return node.url;\n          if (node.mainEntityOfPage) {\n            if (typeof node.mainEntityOfPage === 'string') return node.mainEntityOfPage;\n            if (typeof node.mainEntityOfPage === 'object' && typeof node.mainEntityOfPage['@id'] === 'string') return node.mainEntityOfPage['@id'];\n          }\n          if (typeof node.url === 'string' && node.url) return node.url;\n        }\n      } catch {}\n    }\n    return null;\n  }\n\n  // Try to find a home-like URL (rel=home / logo link)\n  function homeLikeUrl(htmlText) {\n    const relHome = grab(/<link[^>]*rel=[\"']home[\"'][^>]*href=[\"']([^\"']+)[\"'][^>]*>/i, htmlText);\n    if (relHome) return relHome;\n    const aRelHome = grab(/<a[^>]*rel=[\"']home[\"'][^>]*href=[\"']([^\"']+)[\"'][^>]*>/i, htmlText);\n    if (aRelHome) return aRelHome;\n    const aLogo = grab(/<a[^>]*class=[\"'][^\"']*\\blogo\\b[^\"']*[\"'][^>]*href=[\"']([^\"']+)[\"'][^>]*>/i, htmlText)\n               || grab(/<a[^>]*aria-label=[\"'][^\"']*home[^\"']*[\"'][^>]*href=[\"']([^\"']+)[\"'][^>]*>/i, htmlText);\n    return aLogo || null;\n  }\n\n  // Compute a dominant first-party domain by counting absolute href/src/action attributes (skip common CDNs)\n  function dominantDomain(htmlText) {\n    const attrRe = /\\b(?:href|src|action)\\s*=\\s*[\"']([^\"']+)[\"']/gi;\n    const counts = new Map();\n    let m;\n    while ((m = attrRe.exec(htmlText)) !== null) {\n      const u = (m[1] || '').trim();\n      if (!u || !isAbs(u) || THIRD_PARTY.test(u)) continue;\n      try {\n        const h = new URL(u).host;\n        counts.set(h, (counts.get(h) || 0) + 1);\n      } catch {}\n    }\n    let best = null, n = 0;\n    for (const [h, c] of counts.entries()) if (c > n) { best = h; n = c; }\n    return best ? `https://${best}/` : null;\n  }\n\n  // Extra fallback: prefer form action or stylesheet/script host\n  function firstPartyByFormOrAsset(htmlText) {\n    // <form action=\"...\">\n    const formAction = grab(/<form\\b[^>]*action=[\"']([^\"']+)[\"']/i, htmlText);\n    if (formAction && isAbs(formAction) && !THIRD_PARTY.test(formAction)) {\n      const o = originOf(formAction);\n      if (o) return o;\n    }\n    // Stylesheets and scripts that are absolute and not third-party\n    const assets = grabAll(/\\b(?:href|src)\\s*=\\s*[\"']([^\"']+)[\"']/gi, htmlText)\n      .filter(u => isAbs(u) && !THIRD_PARTY.test(u));\n    for (const u of assets) {\n      const o = originOf(u);\n      if (o) return o;\n    }\n    return null;\n  }\n\n  // If siteUrl wasn't injected by Set Config or upstream merge, try to infer it\n  let siteUrl = item.json.siteUrl || null;\n  const canonical = grab(/<link[^>]*rel=[\"']canonical[\"'][^>]*href=[\"']([^\"']+)[\"'][^>]*>/i, html);\n  const ogUrl = grab(/<meta[^>]*property=[\"']og:url[\"'][^>]*content=[\"']([^\"']+)[\"'][^>]*>/i, html);\n  const baseHref = grab(/<base[^>]*href=[\"']([^\"']+)[\"'][^>]*>/i, html);\n\n  if (!siteUrl) {\n    siteUrl = canonical || ogUrl || baseHref || \"https://example.com\";\n  }\n\n  // --- ENHANCEMENT: resolve relatives + alternate signals + normalize ---\n  const domainByVoting = dominantDomain(html);\n  const bestBase = baseHref || domainByVoting || null;\n\n  const candidateIsPlaceholder = siteUrl === \"https://example.com\";\n  const candidateIsRelative = !!siteUrl && !isAbs(siteUrl);\n\n  if (candidateIsPlaceholder || candidateIsRelative) {\n    // Prefer canonical (resolved), then og:url (resolved)\n    let resolved = null;\n    if (canonical) resolved = isAbs(canonical) ? canonical : (bestBase ? toAbs(canonical, bestBase) : null);\n    if (!resolved && ogUrl) resolved = isAbs(ogUrl) ? ogUrl : (bestBase ? toAbs(ogUrl, bestBase) : null);\n\n    // JSON-LD candidates (WebPage.url / mainEntityOfPage / url)\n    const ld = jsonLdUrl(html);\n    if (!resolved && ld) resolved = isAbs(ld) ? ld : (bestBase ? toAbs(ld, bestBase) : null);\n\n    // Home/logo links as a hint\n    const home = homeLikeUrl(html);\n    if (!resolved && home) resolved = isAbs(home) ? home : (bestBase ? toAbs(home, bestBase) : null);\n\n    // Fall back to dominant domain origin\n    if (!resolved && domainByVoting) resolved = domainByVoting;\n\n    // NEW: prefer form action / asset host\n    if (!resolved) {\n      const formOrAsset = firstPartyByFormOrAsset(html);\n      if (formOrAsset) resolved = formOrAsset;\n    }\n\n    // NEW: last-resort — first absolute non-third-party URL's origin\n    if (!resolved) {\n      const firstAbs = grab(/\\b(?:href|src|action)\\s*=\\s*[\"'](https?:\\/\\/[^\"']+)[\"']/i, html);\n      if (firstAbs && !THIRD_PARTY.test(firstAbs)) {\n        const o = originOf(firstAbs);\n        if (o) resolved = o;\n      }\n    }\n\n    // Last resort: keep what we had\n    siteUrl = resolved || siteUrl;\n  }\n\n  // Normalize to site origin (scheme + host + trailing slash)\n  const normalizedOrigin = originOf(siteUrl);\n  if (normalizedOrigin) siteUrl = normalizedOrigin;\n  if (!/\\/$/.test(siteUrl)) siteUrl = siteUrl + '/';\n\n  // basic SEO fields\n  const title = grab(/<title[^>]*>([\\s\\S]{0,2000}?)<\\/title>/i, html)?.trim() || null;\n\n  // Prefer meta[name=\"description\"]; fall back to og:description if missing\n  let metaDesc =\n    grab(/<meta[^>]*name=[\"']description[\"'][^>]*content=[\"']([^\"']{0,4000})[\"'][^>]*>/i, html) ||\n    grab(/<meta[^>]*property=[\"']og:description[\"'][^>]*content=[\"']([^\"']{0,4000})[\"'][^>]*>/i, html) ||\n    null;\n\n  const robots = grab(/<meta[^>]*name=[\"']robots[\"'][^>]*content=[\"']([^\"']+)[\"'][^>]*>/i, html);\n  const h1s = grabAll(/<h1\\b[^>]*>([\\s\\S]*?)<\\/h1>/gi, html);\n\n  // checks\n  if (!title) crit(\"Missing <title> tag.\");\n  if (!metaDesc) warn(\"Missing meta description.\");\n  if (metaDesc && (metaDesc.length < 50 || metaDesc.length > 160)) {\n    warn(`Meta description suboptimal length (${metaDesc.length}).`);\n  }\n  if (h1s.length === 0) warn(\"Missing <h1>.\");\n  if (h1s.length > 1) warn(`Multiple <h1> tags (${h1s.length}).`);\n  if (!canonical) warn(\"Missing canonical link.\");\n  if (robots && /noindex/i.test(robots)) crit('robots meta includes \"noindex\".');\n  if (robots && /nofollow/i.test(robots)) warn('robots meta includes \"nofollow\".');\n\n  // images without alt\n  const imgTags = html.match(/<img\\b[^>]*>/gi) || [];\n  let imagesMissingAlt = 0;\n  for (const img of imgTags) {\n    const hasAlt = /alt\\s*=\\s*[\"'][^\"']*[\"']/i.test(img);\n    if (!hasAlt) imagesMissingAlt++;\n  }\n  if (imagesMissingAlt > 0) warn(`${imagesMissingAlt} image(s) without alt.`);\n\n  // internal link checking (HEAD, fallback GET)\n  let host = null;\n  try { host = new URL(siteUrl).host; } catch {}\n\n  const linkRe = /<a\\b[^>]*href=[\"']([^\"']+)[\"'][^>]*>/gi;\n  const linkHrefs = [];\n  let m;\n  while ((m = linkRe.exec(html)) !== null && linkHrefs.length < maxLinkChecks) {\n    let href = m[1].trim();\n    if (!href || /^javascript:|^mailto:|^tel:/i.test(href)) continue;\n    try { href = new URL(href, siteUrl).href; } catch { continue; }\n    try {\n      const u = new URL(href);\n      if (!host || u.host === host) linkHrefs.push(u.href);\n    } catch {}\n  }\n\n  const uniqueLinks = [...new Set(linkHrefs)];\n  const brokenLinks = [];\n\n  async function checkUrl(url) {\n    // Prefer HEAD\n    try {\n      const res = await this.helpers.httpRequest({\n        method: 'HEAD',\n        url,\n        timeout: timeoutMs,\n        resolveWithFullResponse: true,\n        simple: false,\n      });\n      const code = res.statusCode || res.status || 0;\n      if (code >= 400) brokenLinks.push({ url, status: code });\n      return;\n    } catch (e) {\n      // fall back to GET\n    }\n    try {\n      const res2 = await this.helpers.httpRequest({\n        method: 'GET',\n        url,\n        timeout: timeoutMs,\n        resolveWithFullResponse: true,\n        simple: false,\n      });\n      const code2 = res2.statusCode || res2.status || 0;\n      if (code2 >= 400) brokenLinks.push({ url, status: code2 });\n    } catch (e2) {\n      brokenLinks.push({ url, status: 'timeout/error' });\n    }\n  }\n\n  // Sequential (gentle). Raise concurrency if you control the target.\n  for (const u of uniqueLinks) {\n    /* eslint-disable no-await-in-loop */\n    await checkUrl.call(this, u);\n  }\n\n  if (brokenLinks.length > 0) crit(`${brokenLinks.length} broken internal link(s).`);\n\n  const summary = {\n    url: siteUrl,\n    titlePresent: !!title,\n    hasMetaDescription: !!metaDesc,\n    metaDescriptionLength: metaDesc ? metaDesc.length : 0,\n    h1Count: h1s.length,\n    hasCanonical: !!canonical,\n    robots: robots || null,\n    imagesMissingAlt,\n    internalLinksChecked: uniqueLinks.length,\n    brokenLinksCount: brokenLinks.length,\n    htmlSource\n  };\n\n  const critical = issues.some(i => i.level === \"critical\");\n\n  out.push({\n    json: {\n      url: siteUrl,\n      seo: {\n        title,\n        metaDesc,\n        robots: robots || null,\n        canonical: canonical || null,\n        h1Count: h1s.length,\n      },\n      summary,\n      brokenLinks,\n      issues,\n      critical,\n      // pass through any config if present\n      driveFolderId: item.json.driveFolderId,\n      slackChannel: item.json.slackChannel,\n      psiStrategy: item.json.psiStrategy || \"mobile\",\n    }\n  });\n}\n\nreturn out;\n"
          },
          "typeVersion": 2
        },
        {
          "id": "bad0e4d4-a40e-4434-a46a-797d4067cde7",
          "name": "SEO Health Check & Score",
          "type": "n8n-nodes-base.code",
          "position": [
            880,
            -160
          ],
          "parameters": {
            "jsCode": "// // Node name: PSI (with backoff)\n// // Input: item.json.url (or summary.url), item.json.psiStrategy; env PSI_API_KEY\n// // Output: { psi: { ok, performance, rawError, testedUrl, fetchedAt, strategy } }\n\n// const KEY = $env.PSI_API_KEY || 'AIzaYOUR_GOOGLE_API_KEY_HERE';\n// const ENDPOINT = 'https://pagespeedonline.googleapis.com/pagespeedonline/v5/runPagespeed';\n\n// async function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }\n\n// async function runPSI(url, strategy, quotaUser, attempts = 4) {\n//   let lastErr = null;\n//   for (let i = 0; i < attempts; i++) {\n//     try {\n//       const res = await this.helpers.httpRequest({\n//         method: 'GET',\n//         url: ENDPOINT,\n//         qs: {\n//           url,\n//           strategy: strategy || 'mobile',\n//           category: 'performance',\n//           key: KEY,\n//           quotaUser: quotaUser || url, // helps per-user quota accounting\n//         },\n//         json: true,\n//         resolveWithFullResponse: false,\n//         simple: false,              // do not throw on non-2xx\n//       });\n\n//       // If Google returned an HTML \"Sorry...\" page, normalize it to an error\n//       if (typeof res === 'string' && /Sorry/i.test(res) && /automated queries/i.test(res)) {\n//         throw new Error('blocked_by_google_sorry_page');\n//       }\n//       if (res?.error?.message) {\n//         // 429 / quota / abuse, retry with backoff\n//         lastErr = new Error(res.error.message);\n//       } else {\n//         return res; // success JSON with lighthouseResult\n//       }\n//     } catch (e) {\n//       lastErr = e;\n//     }\n\n//     // Exponential backoff with jitter: 1s, 2s, 4s, 8s (+random)\n//     const waitMs = (2 ** i) * 1000 + Math.floor(Math.random() * 400);\n//     await sleep(waitMs);\n//   }\n//   throw lastErr || new Error('psi_failed');\n// }\n\n// const out = [];\n// for (const item of items) {\n//   const siteUrl = item.json.url || item.json.summary?.url || item.json.siteUrl || 'https://example.com';\n//   const strategy = item.json.psiStrategy || 'mobile';\n\n//   let psi = { ok: false, performance: null, rawError: null, testedUrl: null, fetchedAt: null, strategy: null };\n//   try {\n//     const raw = await runPSI.call(this, siteUrl, strategy, siteUrl);\n//     const score = raw?.lighthouseResult?.categories?.performance?.score;\n//     psi.performance = (typeof score === 'number') ? Math.round(score * 100) : null;\n//     psi.ok = psi.performance !== null;\n//     psi.testedUrl = raw?.id || null;\n//     psi.fetchedAt = raw?.analysisUTCTimestamp || null;\n//     psi.strategy = raw?.lighthouseResult?.configSettings?.formFactor || strategy;\n//   } catch (e) {\n//     psi.rawError = String(e.message || e);\n//   }\n\n//   out.push({ json: { ...item.json, psi } });\n// }\n// return out;\n\n\n// Node name: PSI (with backoff)\n// Requires: env PSI_API_KEY (no default)\n// Reads site URL from: item.json.url || item.json.summary?.url || item.json.siteUrl\n// Outputs: item.json.psi = { ok, performance, rawError, testedUrl, fetchedAt, strategy }\n\nconst KEY = 'AIzaYOUR_GOOGLE_API_KEY_HERE';\nif (!KEY) {\n  // Fail fast so you don't waste retries without a key.\n  throw new Error('PSI_API_KEY is not set. Add it to n8n environment and restart.');\n}\n\nconst ENDPOINT = 'https://pagespeedonline.googleapis.com/pagespeedonline/v5/runPagespeed';\n\nasync function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }\n\nfunction extractError(e) {\n  // Try to normalize different error shapes from n8n/http/got\n  if (!e) return 'unknown_error';\n  if (typeof e === 'string') return e;\n  if (e?.message) return e.message;\n  const res = e?.response;\n  if (res) {\n    const status = res.statusCode || res.status;\n    let body = res.body || res.data;\n    if (Buffer.isBuffer(body)) body = body.toString('utf8');\n    let msg = '';\n    try {\n      const j = typeof body === 'string' ? JSON.parse(body) : body;\n      msg = j?.error?.message || j?.message || '';\n    } catch {\n      // not JSON\n      if (typeof body === 'string') msg = body.slice(0, 200);\n    }\n    return `HTTP ${status}${msg ? `: ${msg}` : ''}`;\n  }\n  return 'request_failed';\n}\n\nasync function runPSI(url, strategy, quotaUser, attempts = 6) {\n  let lastErr = null;\n  for (let i = 0; i < attempts; i++) {\n    try {\n      const res = await this.helpers.httpRequest({\n        method: 'GET',\n        url: ENDPOINT,\n        qs: {\n          url,\n          strategy: strategy || 'mobile',\n          category: 'performance',\n          key: KEY,\n          quotaUser: quotaUser || url, // helps distribute quota\n        },\n        json: true,\n        // The helper ignores some libs' flags; we still guard with try/catch.\n        // These hints help in newer n8n versions:\n        resolveWithFullResponse: false,\n        simple: false,\n        throwHttpErrors: false,\n        ignoreHttpStatusErrors: true,\n      });\n\n      // If PSI returned a valid JSON with lighthouseResult, we're done.\n      if (res?.lighthouseResult?.categories?.performance?.score != null) {\n        return res;\n      }\n\n      // If PSI returned JSON error shape, prepare to retry.\n      if (res?.error?.message) {\n        lastErr = new Error(res.error.message);\n      } else if (typeof res === 'string' && /automated queries/i.test(res)) {\n        // Google \"Sorry\" HTML\n        lastErr = new Error('blocked_by_google_sorry_page');\n      } else {\n        // Unknown shape; stringify to inspect\n        lastErr = new Error('psi_unknown_response');\n      }\n    } catch (e) {\n      // Network or non-2xx thrown by transport\n      const msg = extractError(e);\n      lastErr = new Error(msg);\n      // If it wasn't a 429-like situation, you can break early.\n      if (!/429|rate|quota|limit|blocked/i.test(msg)) break;\n    }\n\n    // Backoff: 1s, 2s, 4s, 8s, 16s, 32s (+ jitter)\n    const waitMs = (2 ** i) * 1000 + Math.floor(Math.random() * 400);\n    await sleep(waitMs);\n  }\n  throw lastErr || new Error('psi_failed');\n}\n\nconst out = [];\nfor (const item of items) {\n  const siteUrl = item.json.url || item.json.summary?.url || item.json.siteUrl || 'https://example.com';\n  const strategy = item.json.psiStrategy || 'mobile';\n\n  const hostForQuota =\n    (() => { try { return new URL(siteUrl).host; } catch { return siteUrl; } })();\n\n  const psi = { ok: false, performance: null, rawError: null, testedUrl: null, fetchedAt: null, strategy: null };\n\n  try {\n    const raw = await runPSI.call(this, siteUrl, strategy, hostForQuota);\n    const score = raw?.lighthouseResult?.categories?.performance?.score;\n    psi.performance = (typeof score === 'number') ? Math.round(score * 100) : null;\n    psi.ok = psi.performance !== null;\n    psi.testedUrl = raw?.id || null;\n    psi.fetchedAt = raw?.analysisUTCTimestamp || null;\n    psi.strategy = raw?.lighthouseResult?.configSettings?.formFactor || strategy;\n  } catch (e) {\n    psi.rawError = extractError(e);\n  }\n\n  out.push({ json: { ...item.json, psi } });\n}\n\nreturn out;\n\n"
          },
          "typeVersion": 2
        },
        {
          "id": "cb514485-6246-4500-9587-c7d6db259e63",
          "name": "Check Performance < 50",
          "type": "n8n-nodes-base.if",
          "position": [
            1100,
            -160
          ],
          "parameters": {
            "options": {},
            "conditions": {
              "options": {
                "version": 1,
                "leftValue": "",
                "caseSensitive": true,
                "typeValidation": "strict"
              },
              "combinator": "and",
              "conditions": [
                {
                  "id": "1a38884a-0d96-4658-9b87-e6897b9bab2c",
                  "operator": {
                    "type": "number",
                    "operation": "lt"
                  },
                  "leftValue": "={{ $json.psi.performance }}",
                  "rightValue": 50
                }
              ]
            }
          },
          "typeVersion": 2
        },
        {
          "id": "daed86d5-0796-4272-b685-0e48910307a2",
          "name": "Send Alert Email (Low SEO Score)",
          "type": "n8n-nodes-base.gmail",
          "position": [
            1320,
            -360
          ],
          "webhookId": "7d6ee81e-f4da-442c-a4c3-25dcd5b3ce32",
          "parameters": {
            "sendTo": "user@example.com",
            "message": "=<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <title>SEO & Performance Report</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n  </head>\n  <body style=\"margin:0; padding:0; background:#f6f9fc;\">\n    <!-- Wrapper -->\n    <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"background:#f6f9fc;\">\n      <tr>\n        <td align=\"center\" style=\"padding:24px 12px;\">\n          <!-- Container -->\n          <table role=\"presentation\" width=\"600\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"width:600px; max-width:100%; background:#ffffff; border-radius:10px; overflow:hidden; font-family:Arial, Helvetica, sans-serif; color:#111827;\">\n            <!-- Header -->\n            <tr>\n              <td style=\"padding:20px 24px; background:#0f172a; color:#ffffff;\">\n                <div style=\"font-size:18px; font-weight:bold;\">SEO & Performance Report</div>\n                <div style=\"font-size:12px; opacity:0.85; margin-top:4px;\">Generated for: <a href=\"https://www.weblineindia.com/\" style=\"color:#93c5fd; text-decoration:none;\">{{ $json.summary.url }}</a></div>\n              </td>\n            </tr>\n\n            <!-- Site Overview -->\n            <tr>\n              <td style=\"padding:16px 24px;\">\n                <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n                  <tr>\n                    <td style=\"padding:12px 0;\">\n                      <div style=\"font-size:14px; color:#6b7280;\">Page Title</div>\n                      <div style=\"font-size:16px; font-weight:600;\">{{ $json.seo.title }}</div>\n                    </td>\n                  </tr>\n                  <tr>\n                    <td style=\"padding:6px 0;\">\n                      <span style=\"display:inline-block; font-size:12px; background:#e5f4ff; color:#075985; padding:6px 10px; border-radius:999px; margin-right:6px;\">robots: {{ $json.seo.robots }}</span>\n                      <span style=\"display:inline-block; font-size:12px; background:#e5f4ff; color:#075985; padding:6px 10px; border-radius:999px; margin-right:6px;\">canonical present: {{ $json.seo.canonical }}</span>\n                      <span style=\"display:inline-block; font-size:12px; background:#ecfdf5; color:#065f46; padding:6px 10px; border-radius:999px;\">critical: {{ $json.critical }}</span>\n                    </td>\n                  </tr>\n                </table>\n              </td>\n            </tr>\n\n            <!-- KPI Row -->\n            <tr>\n              <td style=\"padding:0 24px 8px 24px;\">\n                <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n                  <tr>\n                    <!-- PSI Score -->\n                    <td valign=\"top\" width=\"50%\" style=\"padding:12px; border:1px solid #e5e7eb; border-radius:8px;\">\n                      <div style=\"font-size:14px; color:#6b7280; margin-bottom:6px;\">PageSpeed Insights (mobile)</div>\n                      <div style=\"font-size:32px; font-weight:700; line-height:1; color:#b45309;\">{{ $json.psi.performance }}</div>\n                      <div style=\"font-size:12px; color:#6b7280; margin-top:6px;\">Status: <span style=\"color:#16a34a;\">ok</span></div>\n                      <div style=\"font-size:12px; color:#6b7280; margin-top:2px;\">Tested URL: <a href=\"{{ $json.psi.testedUrl }}\" style=\"color:#2563eb; text-decoration:none;\">{{ $json.psi.testedUrl }}</a></div>\n                      <div style=\"font-size:12px; color:#6b7280; margin-top:2px;\">Fetched at: 2025-08-14 11:22:47 UTC</div>\n                      <!-- Legend -->\n                      <div style=\"font-size:11px; color:#6b7280; margin-top:10px;\">\n                        <span style=\"color:#16a34a; font-weight:bold;\">90–100</span> Good &nbsp;|&nbsp;\n                        <span style=\"color:#b45309; font-weight:bold;\">50–89</span> Needs Improvement &nbsp;|&nbsp;\n                        <span style=\"color:#dc2626; font-weight:bold;\">0–49</span> Poor\n                      </div>\n                    </td>\n\n                    <!-- SEO Summary -->\n                    <td valign=\"top\" width=\"50%\" style=\"padding:12px; border:1px solid #e5e7eb; border-radius:8px; vertical-align:top;\">\n                      <div style=\"font-size:14px; color:#6b7280; margin-bottom:6px;\">SEO Summary</div>\n                      <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"font-size:13px;\">\n                        <tr>\n                          <td style=\"padding:4px 0; color:#374151;\">Meta Description</td>\n                          <td style=\"padding:4px 0; text-align:right;\">\n                            <span style=\"background:#ecfdf5; color:#065f46; padding:2px 8px; border-radius:999px;\">present</span>\n                            <span style=\"color:#6b7280; margin-left:6px;\">({{ $json.summary.metaDescriptionLength }} chars)</span>\n                          </td>\n                        </tr>\n                        <tr>\n                          <td style=\"padding:4px 0; color:#374151;\">H1 Count</td>\n                          <td style=\"padding:4px 0; text-align:right;\">{{ $json.summary.h1Count }}</td>\n                        </tr>\n                        <tr>\n                          <td style=\"padding:4px 0; color:#374151;\">Images missing alt</td>\n                          <td style=\"padding:4px 0; text-align:right;\">\n                            <span style=\"background:#ecfdf5; color:#065f46; padding:2px 8px; border-radius:999px;\">{{ $json.summary.imagesMissingAlt }}</span>\n                          </td>\n                        </tr>\n                        <tr>\n                          <td style=\"padding:4px 0; color:#374151;\">Broken links</td>\n                          <td style=\"padding:4px 0; text-align:right;\">\n                            <span style=\"background:#ecfdf5; color:#065f46; padding:2px 8px; border-radius:999px;\">{{ $json.summary.brokenLinksCount }}</span>\n                          </td>\n                        </tr>\n                      </table>\n                    </td>\n                  </tr>\n                </table>\n              </td>\n            </tr>\n\n            <!-- Details: Meta Description -->\n            <tr>\n              <td style=\"padding:8px 24px 0 24px;\">\n                <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"border:1px solid #e5e7eb; border-radius:8px;\">\n                  <tr>\n                    <td style=\"padding:12px;\">\n                      <div style=\"font-size:14px; color:#6b7280; margin-bottom:6px;\">Meta Description</div>\n                      <div style=\"font-size:14px; color:#111827;\">\n                        {{ $json.seo.metaDesc }}\n                      </div>\n                    </td>\n                  </tr>\n                </table>\n              </td>\n            </tr>\n\n            <!-- Canonical / Robots -->\n            <tr>\n              <td style=\"padding:12px 24px 0 24px;\">\n                <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"border:1px solid #e5e7eb; border-radius:8px;\">\n                  <tr>\n                    <td style=\"padding:12px;\">\n                      <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"font-size:13px;\">\n                        <tr>\n                          <td style=\"padding:4px 0; color:#374151;\">Canonical URL</td>\n                          <td style=\"padding:4px 0; text-align:right;\">\n                            <a href=\"{{ $json.seo.canonical }}\" style=\"color:#2563eb; text-decoration:none;\">{{ $json.seo.canonical }}</a>\n                          </td>\n                        </tr>\n                        <tr>\n                          <td style=\"padding:4px 0; color:#374151;\">Robots</td>\n                          <td style=\"padding:4px 0; text-align:right;\">{{ $json.seo.robots }}</td>\n                        </tr>\n                      </table>\n                    </td>\n                  </tr>\n                </table>\n              </td>\n            </tr>\n\n            <!-- Footer -->\n            <tr>\n              <td style=\"padding:18px 24px 22px 24px; color:#6b7280; font-size:12px;\">\n                This automated report is based on the latest crawl & PSI test (mobile). If you’d like this email to include multiple URLs or a trend chart, reply and I’ll add it.\n              </td>\n            </tr>\n          </table>\n          <!-- /Container -->\n        </td>\n      </tr>\n    </table>\n    <!-- /Wrapper -->\n  </body>\n</html>",
            "options": {},
            "subject": "Website Health & SEO Audit"
          },
          "credentials": {
            "gmailOAuth2": {
              "id": "credential-id",
              "name": "gmailOAuth2 Credential"
            }
          },
          "typeVersion": 2.1
        },
        {
          "id": "407a2d4c-f9e6-4343-b9a2-551bfbde84df",
          "name": "Merge Alert & Normal Results",
          "type": "n8n-nodes-base.merge",
          "position": [
            1320,
            -160
          ],
          "parameters": {},
          "typeVersion": 3.2
        },
        {
          "id": "9e9563df-7000-4230-a3cb-1f232c8d1b72",
          "name": "Update Performance Log",
          "type": "n8n-nodes-base.googleSheets",
          "position": [
            1540,
            -160
          ],
          "parameters": {
            "columns": {
              "value": {
                "Date": "={{ $json.psi.fetchedAt }}",
                "Domain": "={{ $json.url.extractDomain() }}",
                "Performance": "={{ $json.psi.performance }}",
                "Website Link": "={{ $json.url }}"
              },
              "schema": [
                {
                  "id": "Domain",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Domain",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Website Link",
                  "type": "string",
                  "display": true,
                  "required": false,
                  "displayName": "Website Link",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Performance",
                  "type": "string",
                  "display": true,
                  "required": false,
                  "displayName": "Performance",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Date",
                  "type": "string",
                  "display": true,
                  "required": false,
                  "displayName": "Date",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "row_number",
                  "type": "string",
                  "display": true,
                  "removed": true,
                  "readOnly": true,
                  "required": false,
                  "displayName": "row_number",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                }
              ],
              "mappingMode": "defineBelow",
              "matchingColumns": [
                "Domain"
              ],
              "attemptToConvertTypes": false,
              "convertFieldsToString": false
            },
            "options": {},
            "operation": "update",
            "sheetName": {
              "__rl": true,
              "mode": "list",
              "value": 228478758,
              "cachedResultUrl": "",
              "cachedResultName": "Website_Seo_Testing"
            },
            "documentId": {
              "__rl": true,
              "mode": "list",
              "value": "1cQ-TBf3-dqo7njDYzYpxpASYFvEp8lIzH7vpIqTLcwc",
              "cachedResultUrl": "",
              "cachedResultName": "N8N_Email_Attachment"
            }
          },
          "credentials": {
            "googleSheetsOAuth2Api": {
              "id": "credential-id",
              "name": "googleSheetsOAuth2Api Credential"
            }
          },
          "typeVersion": 4.6
        },
        {
          "id": "9355a6c8-da5c-40b4-8999-a0a0eb50d9d5",
          "name": "Generate SEO Report (HTML)",
          "type": "n8n-nodes-base.html",
          "position": [
            1320,
            40
          ],
          "parameters": {
            "html": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <title>SEO & Performance Report</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n  </head>\n  <body style=\"margin:0; padding:0; background:#f6f9fc;\">\n    <!-- Wrapper -->\n    <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"background:#f6f9fc;\">\n      <tr>\n        <td align=\"center\" style=\"padding:24px 12px;\">\n          <!-- Container -->\n          <table role=\"presentation\" width=\"600\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"width:600px; max-width:100%; background:#ffffff; border-radius:10px; overflow:hidden; font-family:Arial, Helvetica, sans-serif; color:#111827;\">\n            <!-- Header -->\n            <tr>\n              <td style=\"padding:20px 24px; background:#0f172a; color:#ffffff;\">\n                <div style=\"font-size:18px; font-weight:bold;\">SEO & Performance Report</div>\n                <div style=\"font-size:12px; opacity:0.85; margin-top:4px;\">Generated for: <a href=\"https://www.weblineindia.com/\" style=\"color:#93c5fd; text-decoration:none;\">{{ $json.summary.url }}</a></div>\n              </td>\n            </tr>\n\n            <!-- Site Overview -->\n            <tr>\n              <td style=\"padding:16px 24px;\">\n                <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n                  <tr>\n                    <td style=\"padding:12px 0;\">\n                      <div style=\"font-size:14px; color:#6b7280;\">Page Title</div>\n                      <div style=\"font-size:16px; font-weight:600;\">{{ $json.seo.title }}</div>\n                    </td>\n                  </tr>\n                  <tr>\n                    <td style=\"padding:6px 0;\">\n                      <span style=\"display:inline-block; font-size:12px; background:#e5f4ff; color:#075985; padding:6px 10px; border-radius:999px; margin-right:6px;\">robots: {{ $json.seo.robots }}</span>\n                      <span style=\"display:inline-block; font-size:12px; background:#e5f4ff; color:#075985; padding:6px 10px; border-radius:999px; margin-right:6px;\">canonical present: {{ $json.seo.canonical }}</span>\n                      <span style=\"display:inline-block; font-size:12px; background:#ecfdf5; color:#065f46; padding:6px 10px; border-radius:999px;\">critical: {{ $json.critical }}</span>\n                    </td>\n                  </tr>\n                </table>\n              </td>\n            </tr>\n\n            <!-- KPI Row -->\n            <tr>\n              <td style=\"padding:0 24px 8px 24px;\">\n                <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n                  <tr>\n                    <!-- PSI Score -->\n                    <td valign=\"top\" width=\"50%\" style=\"padding:12px; border:1px solid #e5e7eb; border-radius:8px;\">\n                      <div style=\"font-size:14px; color:#6b7280; margin-bottom:6px;\">PageSpeed Insights (mobile)</div>\n                      <div style=\"font-size:32px; font-weight:700; line-height:1; color:#b45309;\">{{ $json.psi.performance }}</div>\n                      <div style=\"font-size:12px; color:#6b7280; margin-top:6px;\">Status: <span style=\"color:#16a34a;\">ok</span></div>\n                      <div style=\"font-size:12px; color:#6b7280; margin-top:2px;\">Tested URL: <a href=\"{{ $json.psi.testedUrl }}\" style=\"color:#2563eb; text-decoration:none;\">{{ $json.psi.testedUrl }}</a></div>\n                      <div style=\"font-size:12px; color:#6b7280; margin-top:2px;\">Fetched at: 2025-08-14 11:22:47 UTC</div>\n                      <!-- Legend -->\n                      <div style=\"font-size:11px; color:#6b7280; margin-top:10px;\">\n                        <span style=\"color:#16a34a; font-weight:bold;\">90–100</span> Good &nbsp;|&nbsp;\n                        <span style=\"color:#b45309; font-weight:bold;\">50–89</span> Needs Improvement &nbsp;|&nbsp;\n                        <span style=\"color:#dc2626; font-weight:bold;\">0–49</span> Poor\n                      </div>\n                    </td>\n\n                    <!-- SEO Summary -->\n                    <td valign=\"top\" width=\"50%\" style=\"padding:12px; border:1px solid #e5e7eb; border-radius:8px; vertical-align:top;\">\n                      <div style=\"font-size:14px; color:#6b7280; margin-bottom:6px;\">SEO Summary</div>\n                      <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"font-size:13px;\">\n                        <tr>\n                          <td style=\"padding:4px 0; color:#374151;\">Meta Description</td>\n                          <td style=\"padding:4px 0; text-align:right;\">\n                            <span style=\"background:#ecfdf5; color:#065f46; padding:2px 8px; border-radius:999px;\">present</span>\n                            <span style=\"color:#6b7280; margin-left:6px;\">({{ $json.summary.metaDescriptionLength }} chars)</span>\n                          </td>\n                        </tr>\n                        <tr>\n                          <td style=\"padding:4px 0; color:#374151;\">H1 Count</td>\n                          <td style=\"padding:4px 0; text-align:right;\">{{ $json.summary.h1Count }}</td>\n                        </tr>\n                        <tr>\n                          <td style=\"padding:4px 0; color:#374151;\">Images missing alt</td>\n                          <td style=\"padding:4px 0; text-align:right;\">\n                            <span style=\"background:#ecfdf5; color:#065f46; padding:2px 8px; border-radius:999px;\">{{ $json.summary.imagesMissingAlt }}</span>\n                          </td>\n                        </tr>\n                        <tr>\n                          <td style=\"padding:4px 0; color:#374151;\">Broken links</td>\n                          <td style=\"padding:4px 0; text-align:right;\">\n                            <span style=\"background:#ecfdf5; color:#065f46; padding:2px 8px; border-radius:999px;\">{{ $json.summary.brokenLinksCount }}</span>\n                          </td>\n                        </tr>\n                      </table>\n                    </td>\n                  </tr>\n                </table>\n              </td>\n            </tr>\n\n            <!-- Details: Meta Description -->\n            <tr>\n              <td style=\"padding:8px 24px 0 24px;\">\n                <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"border:1px solid #e5e7eb; border-radius:8px;\">\n                  <tr>\n                    <td style=\"padding:12px;\">\n                      <div style=\"font-size:14px; color:#6b7280; margin-bottom:6px;\">Meta Description</div>\n                      <div style=\"font-size:14px; color:#111827;\">\n                        {{ $json.seo.metaDesc }}\n                      </div>\n                    </td>\n                  </tr>\n                </table>\n              </td>\n            </tr>\n\n            <!-- Canonical / Robots -->\n            <tr>\n              <td style=\"padding:12px 24px 0 24px;\">\n                <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"border:1px solid #e5e7eb; border-radius:8px;\">\n                  <tr>\n                    <td style=\"padding:12px;\">\n                      <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"font-size:13px;\">\n                        <tr>\n                          <td style=\"padding:4px 0; color:#374151;\">Canonical URL</td>\n                          <td style=\"padding:4px 0; text-align:right;\">\n                            <a href=\"{{ $json.seo.canonical }}\" style=\"color:#2563eb; text-decoration:none;\">{{ $json.seo.canonical }}</a>\n                          </td>\n                        </tr>\n                        <tr>\n                          <td style=\"padding:4px 0; color:#374151;\">Robots</td>\n                          <td style=\"padding:4px 0; text-align:right;\">{{ $json.seo.robots }}</td>\n                        </tr>\n                      </table>\n                    </td>\n                  </tr>\n                </table>\n              </td>\n            </tr>\n\n            <!-- Footer -->\n            <tr>\n              <td style=\"padding:18px 24px 22px 24px; color:#6b7280; font-size:12px;\">\n                This automated report is based on the latest crawl & PSI test (mobile). If you’d like this email to include multiple URLs or a trend chart, reply and I’ll add it.\n              </td>\n            </tr>\n          </table>\n          <!-- /Container -->\n        </td>\n      </tr>\n    </table>\n    <!-- /Wrapper -->\n  </body>\n</html>"
          },
          "typeVersion": 1.2
        },
        {
          "id": "43688275-562b-4696-8f75-bc1f8ae8bcdc",
          "name": "Convert HTML to PDF",
          "type": "n8n-nodes-base.httpRequest",
          "position": [
            1540,
            40
          ],
          "parameters": {
            "url": "https://api.pdf.co/v1/pdf/convert/from/html",
            "method": "POST",
            "options": {
              "redirect": {
                "redirect": {}
              }
            },
            "sendBody": true,
            "sendHeaders": true,
            "bodyParameters": {
              "parameters": [
                {
                  "name": "html",
                  "value": "={{ $json.html }}"
                },
                {
                  "name": "name",
                  "value": "SEO-Report.pdf"
                },
                {
                  "name": "paperSize",
                  "value": "A4"
                },
                {
                  "name": "margins",
                  "value": "12mm 12mm 12mm 12mm"
                },
                {
                  "name": "orientation",
                  "value": "Portrait"
                },
                {
                  "name": "printBackground",
                  "value": "true"
                },
                {
                  "name": "mediaType",
                  "value": "print"
                },
                {
                  "name": "async",
                  "value": "false"
                }
              ]
            },
            "headerParameters": {
              "parameters": [
                {
                  "name": "x-api-key",
                  "value": ""
                }
              ]
            }
          },
          "typeVersion": 4.2
        },
        {
          "id": "0bfa99f1-ee76-4b0a-a166-7dad819c47a1",
          "name": "Download PDF File",
          "type": "n8n-nodes-base.httpRequest",
          "position": [
            1760,
            40
          ],
          "parameters": {
            "url": "={{ $json.url }}",
            "options": {}
          },
          "typeVersion": 4.2
        },
        {
          "id": "c827e55f-b760-4c63-8b07-e147d048e050",
          "name": "Save SEO Report to Drive",
          "type": "n8n-nodes-base.googleDrive",
          "position": [
            1980,
            40
          ],
          "parameters": {
            "name": "={{ $('Check Performance < 50').item.json.url.extractDomain().split('.')[1] }}.pdf",
            "driveId": {
              "__rl": true,
              "mode": "list",
              "value": "My Drive",
              "cachedResultUrl": "",
              "cachedResultName": "My Drive"
            },
            "options": {},
            "folderId": {
              "__rl": true,
              "mode": "list",
              "value": "1lpAV7XUx2pByMu58WYbiShuxEiwwLDQK",
              "cachedResultUrl": "",
              "cachedResultName": "SEO_PDF_Store"
            }
          },
          "credentials": {
            "googleDriveOAuth2Api": {
              "id": "credential-id",
              "name": "googleDriveOAuth2Api Credential"
            }
          },
          "typeVersion": 3
        }
      ],
      "active": false,
      "pinData": {},
      "settings": {
        "executionOrder": "v1"
      },
      "versionId": "42d51b50-48eb-44ee-bb38-2387900cbf79",
      "connections": {
        "Download PDF File": {
          "main": [
            [
              {
                "node": "Save SEO Report to Drive",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Daily 9 AM Trigger": {
          "main": [
            [
              {
                "node": "Fetch Website Links",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Fetch Website HTML": {
          "main": [
            [
              {
                "node": "Analyze HTML (SEO Basics)",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Convert HTML to PDF": {
          "main": [
            [
              {
                "node": "Download PDF File",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Fetch Website Links": {
          "main": [
            [
              {
                "node": "Attach Config & Timeout",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Check Performance < 50": {
          "main": [
            [
              {
                "node": "Send Alert Email (Low SEO Score)",
                "type": "main",
                "index": 0
              },
              {
                "node": "Merge Alert & Normal Results",
                "type": "main",
                "index": 0
              }
            ],
            [
              {
                "node": "Generate SEO Report (HTML)",
                "type": "main",
                "index": 0
              },
              {
                "node": "Merge Alert & Normal Results",
                "type": "main",
                "index": 1
              }
            ]
          ]
        },
        "Attach Config & Timeout": {
          "main": [
            [
              {
                "node": "Fetch Website HTML",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "SEO Health Check & Score": {
          "main": [
            [
              {
                "node": "Check Performance < 50",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Save SEO Report to Drive": {
          "main": [
            []
          ]
        },
        "Analyze HTML (SEO Basics)": {
          "main": [
            [
              {
                "node": "SEO Health Check & Score",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Generate SEO Report (HTML)": {
          "main": [
            [
              {
                "node": "Convert HTML to PDF",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Merge Alert & Normal Results": {
          "main": [
            [
              {
                "node": "Update Performance Log",
                "type": "main",
                "index": 0
              }
            ]
          ]
        }
      }
    },
    "lastUpdatedBy": 29,
    "workflowInfo": {
      "nodeCount": 16,
      "nodeTypes": {
        "n8n-nodes-base.if": {
          "count": 1
        },
        "n8n-nodes-base.set": {
          "count": 1
        },
        "n8n-nodes-base.code": {
          "count": 2
        },
        "n8n-nodes-base.cron": {
          "count": 1
        },
        "n8n-nodes-base.html": {
          "count": 1
        },
        "n8n-nodes-base.gmail": {
          "count": 1
        },
        "n8n-nodes-base.merge": {
          "count": 1
        },
        "n8n-nodes-base.stickyNote": {
          "count": 2
        },
        "n8n-nodes-base.googleDrive": {
          "count": 1
        },
        "n8n-nodes-base.httpRequest": {
          "count": 3
        },
        "n8n-nodes-base.googleSheets": {
          "count": 2
        }
      }
    },
    "status": "published",
    "user": {
      "name": "WeblineIndia",
      "username": "weblineindia",
      "bio": "A Leading Software Engineering, Consulting & Outsourcing Services Company in USA & India serving Clients Globally since 1999.",
      "verified": true,
      "links": [
        "https://www.weblineindia.com/"
      ],
      "avatar": "https://gravatar.com/avatar/a229d43aefca4588581583c58bb37b4773aebbdf4c1fef86a08bb1d38eae91fa?r=pg&d=retro&size=200"
    },
    "nodes": [
      {
        "id": 7,
        "icon": "fa:clock",
        "name": "n8n-nodes-base.cron",
        "codex": {
          "data": {
            "alias": [
              "Time",
              "Scheduler",
              "Polling",
              "Cron",
              "Interval"
            ],
            "details": "The Cron node uses Cron under the hood - a time-based job scheduler in Unix-like computer operating systems. Use this node when you want to trigger workflows periodically, especially in more complex scenarios like \"every Tuesday at 9 am\" or \"Weekdays\".",
            "resources": {
              "generic": [
                {
                  "url": "https://n8n.io/blog/2021-goals-level-up-your-vocabulary-with-vonage-and-n8n/",
                  "icon": "🎯",
                  "label": "2021 Goals: Level Up Your Vocabulary With Vonage and n8n"
                },
                {
                  "url": "https://n8n.io/blog/love-at-first-sight-ricardos-n8n-journey/",
                  "icon": "❤️",
                  "label": "Love at first sight: Ricardo’s n8n journey"
                },
                {
                  "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/why-i-chose-n8n-over-zapier-in-2020/",
                  "icon": "😍",
                  "label": "Why I chose n8n over Zapier in 2020"
                },
                {
                  "url": "https://n8n.io/blog/how-to-host-virtual-coffee-breaks-with-n8n/",
                  "icon": "☕️",
                  "label": "How to host virtual coffee breaks with n8n"
                },
                {
                  "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/how-to-sync-data-between-two-systems/",
                  "icon": "🏬",
                  "label": "How to synchronize data between two systems (one-way vs. two-way sync"
                },
                {
                  "url": "https://n8n.io/blog/database-monitoring-and-alerting-with-n8n/",
                  "icon": "📡",
                  "label": "Database Monitoring and Alerting with n8n"
                },
                {
                  "url": "https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/",
                  "icon": "⚙️",
                  "label": "Automate your data processing pipeline in 9 steps"
                },
                {
                  "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/tracking-time-spent-in-meetings-with-google-calendar-twilio-and-n8n/",
                  "icon": "🗓",
                  "label": "Tracking Time Spent in Meetings With Google Calendar, Twilio, and n8n"
                },
                {
                  "url": "https://n8n.io/blog/creating-error-workflows-in-n8n/",
                  "icon": "🌪",
                  "label": "Creating Error Workflows in n8n"
                },
                {
                  "url": "https://n8n.io/blog/using-automation-to-boost-productivity-in-the-workplace/",
                  "icon": "💪",
                  "label": "Using Automation to Boost Productivity in the Workplace"
                },
                {
                  "url": "https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/",
                  "icon": "🧠",
                  "label": "Why this Product Manager loves workflow automation with n8n"
                },
                {
                  "url": "https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/",
                  "icon": "🙌",
                  "label": "Sending Automated Congratulations with Google Sheets, Twilio, and n8n "
                },
                {
                  "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/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/",
                  "icon": "🎖",
                  "label": "Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin"
                },
                {
                  "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"
                }
              ],
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.scheduletrigger/"
                }
              ]
            },
            "categories": [
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "Core Nodes": [
                "Flow"
              ]
            }
          }
        },
        "group": "[\"trigger\",\"schedule\"]",
        "defaults": {
          "name": "Cron",
          "color": "#29a568"
        },
        "iconData": {
          "icon": "clock",
          "type": "icon"
        },
        "displayName": "Cron",
        "typeVersion": 1,
        "nodeCategories": [
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      },
      {
        "id": 18,
        "icon": "file:googleSheets.svg",
        "name": "n8n-nodes-base.googleSheets",
        "codex": {
          "data": {
            "alias": [
              "CSV",
              "Sheet",
              "Spreadsheet",
              "GS"
            ],
            "resources": {
              "generic": [
                {
                  "url": "https://n8n.io/blog/love-at-first-sight-ricardos-n8n-journey/",
                  "icon": "❤️",
                  "label": "Love at first sight: Ricardo’s n8n journey"
                },
                {
                  "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-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/supercharging-your-conference-registration-process-with-n8n/",
                  "icon": "🎫",
                  "label": "Supercharging your conference registration process with n8n"
                },
                {
                  "url": "https://n8n.io/blog/creating-triggers-for-n8n-workflows-using-polling/",
                  "icon": "⏲",
                  "label": "Creating triggers for n8n workflows using polling"
                },
                {
                  "url": "https://n8n.io/blog/no-code-ecommerce-workflow-automations/",
                  "icon": "store",
                  "label": "6 e-commerce workflows to power up your Shopify s"
                },
                {
                  "url": "https://n8n.io/blog/migrating-community-metrics-to-orbit-using-n8n/",
                  "icon": "📈",
                  "label": "Migrating Community Metrics to Orbit using n8n"
                },
                {
                  "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/your-business-doesnt-need-you-to-operate/",
                  "icon": " 🖥️",
                  "label": "Hey founders! Your business doesn't need you to operate"
                },
                {
                  "url": "https://n8n.io/blog/how-honest-burgers-use-automation-to-save-100k-per-year/",
                  "icon": "🍔",
                  "label": "How Honest Burgers Use Automation to Save $100k per year"
                },
                {
                  "url": "https://n8n.io/blog/how-a-digital-strategist-uses-n8n-for-online-marketing/",
                  "icon": "💻",
                  "label": "How a digital strategist uses n8n for online marketing"
                },
                {
                  "url": "https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/",
                  "icon": "🧠",
                  "label": "Why this Product Manager loves workflow automation with n8n"
                },
                {
                  "url": "https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/",
                  "icon": "🙌",
                  "label": "Sending Automated Congratulations with Google Sheets, Twilio, and n8n "
                },
                {
                  "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/aws-workflow-automation/",
                  "label": "7 no-code workflow automations for Amazon Web Services"
                }
              ],
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googlesheets/"
                }
              ],
              "credentialDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/credentials/google/oauth-single-service/"
                }
              ]
            },
            "categories": [
              "Data & Storage",
              "Productivity"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0"
          }
        },
        "group": "[\"input\",\"output\"]",
        "defaults": {
          "name": "Google Sheets"
        },
        "iconData": {
          "type": "file",
          "fileBuffer": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MCIgaGVpZ2h0PSI2MCI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGZpbGw9IiMyOEI0NDYiIGQ9Ik0zNS42OSAxIDUyIDE3LjIyNXYzOS4wODdhMy42NyAzLjY3IDAgMCAxLTEuMDg0IDIuNjFBMy43IDMuNyAwIDAgMSA0OC4yOTMgNjBIMTIuNzA3YTMuNyAzLjcgMCAwIDEtMi42MjMtMS4wNzhBMy42NyAzLjY3IDAgMCAxIDkgNTYuMzEyVjQuNjg4YTMuNjcgMy42NyAwIDAgMSAxLjA4NC0yLjYxQTMuNyAzLjcgMCAwIDEgMTIuNzA3IDF6Ii8+PHBhdGggZmlsbD0iIzZBQ0U3QyIgZD0iTTM1LjY5IDEgNTIgMTcuMjI1SDM5LjM5N2MtMi4wNTQgMC0zLjcwNy0xLjgyOS0zLjcwNy0zLjg3MnoiLz48cGF0aCBmaWxsPSIjMjE5QjM4IiBkPSJNMzkuMjExIDE3LjIyNSA1MiAyMi40OHYtNS4yNTV6Ii8+PHBhdGggZmlsbD0iI0ZGRiIgZD0iTTIwLjEyIDMxLjk3NWMwLS44MTcuNjYyLTEuNDc1IDEuNDgzLTEuNDc1aDE3Ljc5NGMuODIxIDAgMS40ODIuNjU4IDEuNDgyIDEuNDc1djE1LjQ4N2MwIC44MTgtLjY2MSAxLjQ3NS0xLjQ4MiAxLjQ3NUgyMS42MDNhMS40NzYgMS40NzYgMCAwIDEtMS40ODItMS40NzRWMzEuOTc0em0yLjIyNSAxLjQ3NWg2LjY3MnYyLjIxMmgtNi42NzJ6bTAgNS4xNjJoNi42NzJ2Mi4yMTNoLTYuNjcyem0wIDUuMTYzaDYuNjcydjIuMjEyaC02LjY3MnptOS42MzgtMTAuMzI1aDYuNjcydjIuMjEyaC02LjY3MnptMCA1LjE2Mmg2LjY3MnYyLjIxM2gtNi42NzJ6bTAgNS4xNjNoNi42NzJ2Mi4yMTJoLTYuNjcyeiIvPjxwYXRoIGZpbGw9IiMyOEI0NDYiIGQ9Ik0zNC42OSAwIDUxIDE2LjIyNXYzOS4wODdhMy42NyAzLjY3IDAgMCAxLTEuMDg0IDIuNjFBMy43IDMuNyAwIDAgMSA0Ny4yOTMgNTlIMTEuNzA3YTMuNyAzLjcgMCAwIDEtMi42MjMtMS4wNzhBMy42NyAzLjY3IDAgMCAxIDggNTUuMzEyVjMuNjg4YTMuNjcgMy42NyAwIDAgMSAxLjA4NC0yLjYxQTMuNyAzLjcgMCAwIDEgMTEuNzA3IDB6Ii8+PHBhdGggZmlsbD0iIzZBQ0U3QyIgZD0iTTM0LjY5IDAgNTEgMTYuMjI1SDM4LjM5N2MtMi4wNTQgMC0zLjcwNy0xLjgyOS0zLjcwNy0zLjg3MnoiLz48cGF0aCBmaWxsPSIjMjE5QjM4IiBkPSJNMzguMjExIDE2LjIyNSA1MSAyMS40OHYtNS4yNTV6Ii8+PHBhdGggZmlsbD0iI0ZGRiIgZD0iTTE5LjEyIDMwLjk3NWMwLS44MTcuNjYyLTEuNDc1IDEuNDgzLTEuNDc1aDE3Ljc5NGMuODIxIDAgMS40ODIuNjU4IDEuNDgyIDEuNDc1djE1LjQ4N2MwIC44MTgtLjY2MSAxLjQ3NS0xLjQ4MiAxLjQ3NUgyMC42MDNhMS40NzYgMS40NzYgMCAwIDEtMS40ODItMS40NzRWMzAuOTc0em0yLjIyNSAxLjQ3NWg2LjY3MnYyLjIxMmgtNi42NzJ6bTAgNS4xNjJoNi42NzJ2Mi4yMTNoLTYuNjcyem0wIDUuMTYzaDYuNjcydjIuMjEyaC02LjY3MnptOS42MzgtMTAuMzI1aDYuNjcydjIuMjEyaC02LjY3MnptMCA1LjE2Mmg2LjY3MnYyLjIxM2gtNi42NzJ6bTAgNS4xNjNoNi42NzJ2Mi4yMTJoLTYuNjcyeiIvPjwvZz48L3N2Zz4="
        },
        "displayName": "Google Sheets",
        "typeVersion": 5,
        "nodeCategories": [
          {
            "id": 3,
            "name": "Data & Storage"
          },
          {
            "id": 4,
            "name": "Productivity"
          }
        ]
      },
      {
        "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": 20,
        "icon": "fa:map-signs",
        "name": "n8n-nodes-base.if",
        "codex": {
          "data": {
            "alias": [
              "Router",
              "Filter",
              "Condition",
              "Logic",
              "Boolean",
              "Branch"
            ],
            "details": "The IF node can be used to implement binary conditional logic in your workflow. You can set up one-to-many conditions to evaluate each item of data being inputted into the node. That data will either evaluate to TRUE or FALSE and route out of the node accordingly.\n\nThis node has multiple types of conditions: Bool, String, Number, and Date & Time.",
            "resources": {
              "generic": [
                {
                  "url": "https://n8n.io/blog/learn-to-automate-your-factorys-incident-reporting-a-step-by-step-guide/",
                  "icon": "🏭",
                  "label": "Learn to Automate Your Factory's Incident Reporting: A Step by Step Guide"
                },
                {
                  "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/create-a-toxic-language-detector-for-telegram/",
                  "icon": "🤬",
                  "label": "Create a toxic language detector for Telegram in 4 step"
                },
                {
                  "url": "https://n8n.io/blog/no-code-ecommerce-workflow-automations/",
                  "icon": "store",
                  "label": "6 e-commerce workflows to power up your Shopify s"
                },
                {
                  "url": "https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/",
                  "icon": "🔗",
                  "label": "How to build a low-code, self-hosted URL shortener in 3 steps"
                },
                {
                  "url": "https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/",
                  "icon": "⚙️",
                  "label": "Automate your data processing pipeline in 9 steps"
                },
                {
                  "url": "https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/",
                  "icon": "👥",
                  "label": "How to get started with CRM automation (with 3 no-code workflow ideas"
                },
                {
                  "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/automate-google-apps-for-productivity/",
                  "icon": "💡",
                  "label": "15 Google apps you can combine and automate to increase productivity"
                },
                {
                  "url": "https://n8n.io/blog/automation-for-maintainers-of-open-source-projects/",
                  "icon": "🏷️",
                  "label": "How to automatically manage contributions to open-source projects"
                },
                {
                  "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/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/why-this-product-manager-loves-workflow-automation-with-n8n/",
                  "icon": "🧠",
                  "label": "Why this Product Manager loves workflow automation with n8n"
                },
                {
                  "url": "https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/",
                  "icon": "🙌",
                  "label": "Sending Automated Congratulations with Google Sheets, Twilio, and n8n "
                },
                {
                  "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/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/",
                  "icon": "🎖",
                  "label": "Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin"
                },
                {
                  "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.if/"
                }
              ]
            },
            "categories": [
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "Core Nodes": [
                "Flow"
              ]
            }
          }
        },
        "group": "[\"transform\"]",
        "defaults": {
          "name": "If",
          "color": "#408000"
        },
        "iconData": {
          "icon": "map-signs",
          "type": "icon"
        },
        "displayName": "If",
        "typeVersion": 2,
        "nodeCategories": [
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      },
      {
        "id": 24,
        "icon": "file:merge.svg",
        "name": "n8n-nodes-base.merge",
        "codex": {
          "data": {
            "alias": [
              "Join",
              "Concatenate",
              "Wait"
            ],
            "resources": {
              "generic": [
                {
                  "url": "https://n8n.io/blog/how-to-sync-data-between-two-systems/",
                  "icon": "🏬",
                  "label": "How to synchronize data between two systems (one-way vs. two-way sync"
                },
                {
                  "url": "https://n8n.io/blog/supercharging-your-conference-registration-process-with-n8n/",
                  "icon": "🎫",
                  "label": "Supercharging your conference registration process with n8n"
                },
                {
                  "url": "https://n8n.io/blog/migrating-community-metrics-to-orbit-using-n8n/",
                  "icon": "📈",
                  "label": "Migrating Community Metrics to Orbit using n8n"
                },
                {
                  "url": "https://n8n.io/blog/build-your-own-virtual-assistant-with-n8n-a-step-by-step-guide/",
                  "icon": "👦",
                  "label": "Build your own virtual assistant with n8n: A step by step guide"
                },
                {
                  "url": "https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/",
                  "icon": "🙌",
                  "label": "Sending Automated Congratulations with Google Sheets, Twilio, and n8n "
                },
                {
                  "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.merge/"
                }
              ]
            },
            "categories": [
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "Core Nodes": [
                "Flow",
                "Data Transformation"
              ]
            }
          }
        },
        "group": "[\"transform\"]",
        "defaults": {
          "name": "Merge"
        },
        "iconData": {
          "type": "file",
          "fileBuffer": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xMTc3XzUxOCkiPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTAgNDhDMCAyMS40OTAzIDIxLjQ5MDMgMCA0OCAwSDExMkMxMzguNTEgMCAxNjAgMjEuNDkwMyAxNjAgNDhWNTZIMTk2LjI1MkMyNDAuNDM1IDU2IDI3Ni4yNTIgOTEuODE3MiAyNzYuMjUyIDEzNlYxOTJDMjc2LjI1MiAyMTQuMDkxIDI5NC4xNjEgMjMyIDMxNi4yNTIgMjMySDM1MlYyMjRDMzUyIDE5Ny40OSAzNzMuNDkgMTc2IDQwMCAxNzZINDY0QzQ5MC41MSAxNzYgNTEyIDE5Ny40OSA1MTIgMjI0VjI4OEM1MTIgMzE0LjUxIDQ5MC41MSAzMzYgNDY0IDMzNkg0MDBDMzczLjQ5IDMzNiAzNTIgMzE0LjUxIDM1MiAyODhWMjgwSDMxNi4yNTJDMjk0LjE2MSAyODAgMjc2LjI1MiAyOTcuOTA5IDI3Ni4yNTIgMzIwVjM3NkMyNzYuMjUyIDQyMC4xODMgMjQwLjQzNSA0NTYgMTk2LjI1MiA0NTZIMTYwVjQ2NEMxNjAgNDkwLjUxIDEzOC41MSA1MTIgMTEyIDUxMkg0OEMyMS40OTAzIDUxMiAwIDQ5MC41MSAwIDQ2NFY0MDBDMCAzNzMuNDkgMjEuNDkwMyAzNTIgNDggMzUySDExMkMxMzguNTEgMzUyIDE2MCAzNzMuNDkgMTYwIDQwMFY0MDhIMTk2LjI1MkMyMTMuOTI1IDQwOCAyMjguMjUyIDM5My42NzMgMjI4LjI1MiAzNzZWMzIwQzIyOC4yNTIgMjk0Ljc4NCAyMzguODU5IDI3Mi4wNDQgMjU1Ljg1MyAyNTZDMjM4Ljg1OSAyMzkuOTU2IDIyOC4yNTIgMjE3LjIxNiAyMjguMjUyIDE5MlYxMzZDMjI4LjI1MiAxMTguMzI3IDIxMy45MjUgMTA0IDE5Ni4yNTIgMTA0SDE2MFYxMTJDMTYwIDEzOC41MSAxMzguNTEgMTYwIDExMiAxNjBINDhDMjEuNDkwMyAxNjAgMCAxMzguNTEgMCAxMTJWNDhaTTEwNCA0OEMxMDguNDE4IDQ4IDExMiA1MS41ODE3IDExMiA1NlYxMDRDMTEyIDEwOC40MTggMTA4LjQxOCAxMTIgMTA0IDExMkg1NkM1MS41ODE3IDExMiA0OCAxMDguNDE4IDQ4IDEwNFY1NkM0OCA1MS41ODE3IDUxLjU4MTcgNDggNTYgNDhIMTA0Wk00NTYgMjI0QzQ2MC40MTggMjI0IDQ2NCAyMjcuNTgyIDQ2NCAyMzJWMjgwQzQ2NCAyODQuNDE4IDQ2MC40MTggMjg4IDQ1NiAyODhINDA4QzQwMy41ODIgMjg4IDQwMCAyODQuNDE4IDQwMCAyODBWMjMyQzQwMCAyMjcuNTgyIDQwMy41ODIgMjI0IDQwOCAyMjRINDU2Wk0xMTIgNDA4QzExMiA0MDMuNTgyIDEwOC40MTggNDAwIDEwNCA0MDBINTZDNTEuNTgxNyA0MDAgNDggNDAzLjU4MiA0OCA0MDhWNDU2QzQ4IDQ2MC40MTggNTEuNTgxNyA0NjQgNTYgNDY0SDEwNEMxMDguNDE4IDQ2NCAxMTIgNDYwLjQxOCAxMTIgNDU2VjQwOFoiIGZpbGw9IiM1NEI4QzkiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8xMTc3XzUxOCI+CjxyZWN0IHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="
        },
        "displayName": "Merge",
        "typeVersion": 3,
        "nodeCategories": [
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      },
      {
        "id": 38,
        "icon": "fa:pen",
        "name": "n8n-nodes-base.set",
        "codex": {
          "data": {
            "alias": [
              "Set",
              "JS",
              "JSON",
              "Filter",
              "Transform",
              "Map"
            ],
            "resources": {
              "generic": [
                {
                  "url": "https://n8n.io/blog/learn-to-automate-your-factorys-incident-reporting-a-step-by-step-guide/",
                  "icon": "🏭",
                  "label": "Learn to Automate Your Factory's Incident Reporting: A Step by Step Guide"
                },
                {
                  "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/automatically-pulling-and-visualizing-data-with-n8n/",
                  "icon": "📈",
                  "label": "Automatically pulling and visualizing data with n8n"
                },
                {
                  "url": "https://n8n.io/blog/database-monitoring-and-alerting-with-n8n/",
                  "icon": "📡",
                  "label": "Database Monitoring and Alerting 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/no-code-ecommerce-workflow-automations/",
                  "icon": "store",
                  "label": "6 e-commerce workflows to power up your Shopify s"
                },
                {
                  "url": "https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/",
                  "icon": "🔗",
                  "label": "How to build a low-code, self-hosted URL shortener in 3 steps"
                },
                {
                  "url": "https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/",
                  "icon": "⚙️",
                  "label": "Automate your data processing pipeline in 9 steps"
                },
                {
                  "url": "https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/",
                  "icon": "👥",
                  "label": "How to get started with CRM automation (with 3 no-code workflow ideas"
                },
                {
                  "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/automate-google-apps-for-productivity/",
                  "icon": "💡",
                  "label": "15 Google apps you can combine and automate to increase productivity"
                },
                {
                  "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/the-ultimate-guide-to-automate-your-video-collaboration-with-whereby-mattermost-and-n8n/",
                  "icon": "📹",
                  "label": "The ultimate guide to automate your video collaboration with Whereby, Mattermost, and n8n"
                },
                {
                  "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/learn-to-build-powerful-api-endpoints-using-webhooks/",
                  "icon": "🧰",
                  "label": "Learn to Build Powerful API Endpoints Using Webhooks"
                },
                {
                  "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/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/",
                  "icon": "🎖",
                  "label": "Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin"
                },
                {
                  "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.set/"
                }
              ]
            },
            "categories": [
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "Core Nodes": [
                "Data Transformation"
              ]
            }
          }
        },
        "group": "[\"input\"]",
        "defaults": {
          "name": "Edit Fields"
        },
        "iconData": {
          "icon": "pen",
          "type": "icon"
        },
        "displayName": "Edit Fields (Set)",
        "typeVersion": 3,
        "nodeCategories": [
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      },
      {
        "id": 58,
        "icon": "file:googleDrive.svg",
        "name": "n8n-nodes-base.googleDrive",
        "codex": {
          "data": {
            "resources": {
              "generic": [
                {
                  "url": "https://n8n.io/blog/your-business-doesnt-need-you-to-operate/",
                  "icon": " 🖥️",
                  "label": "Hey founders! Your business doesn't need you to operate"
                },
                {
                  "url": "https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/",
                  "icon": "🧠",
                  "label": "Why this Product Manager loves workflow automation with n8n"
                },
                {
                  "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/app-nodes/n8n-nodes-base.googledrive/"
                }
              ],
              "credentialDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/credentials/google/oauth-single-service/"
                }
              ]
            },
            "categories": [
              "Data & Storage"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0"
          }
        },
        "group": "[\"input\"]",
        "defaults": {
          "name": "Google Drive"
        },
        "iconData": {
          "type": "file",
          "fileBuffer": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiB2aWV3Qm94PSIwIDAgODEgNzMiPjx1c2UgeGxpbms6aHJlZj0iI2EiIHg9Ii41IiB5PSIuNSIvPjxzeW1ib2wgaWQ9ImEiIG92ZXJmbG93PSJ2aXNpYmxlIj48ZyBmaWxsLXJ1bGU9Im5vbnplcm8iIHN0cm9rZT0ibm9uZSI+PHBhdGggZmlsbD0iIzAwNjZkYSIgZD0ibTYuMDQ4IDYxLjI2IDMuNTI4IDYuMDk0Yy43MzMgMS4yODMgMS43ODcgMi4yOTEgMy4wMjQgMy4wMjRsMTIuNi0yMS44MUgwYTguMyA4LjMgMCAwIDAgMS4xIDQuMTI0eiIvPjxwYXRoIGZpbGw9IiMwMGFjNDciIGQ9Ik00MCAyMi45MSAyNy40IDEuMWMtMS4yMzcuNzMzLTIuMjkxIDEuNzQxLTMuMDI0IDMuMDI0TDEuMSA0NC40NDVBOC4zIDguMyAwIDAgMCAwIDQ4LjU2OGgyNS4yeiIvPjxwYXRoIGZpbGw9IiNlYTQzMzUiIGQ9Ik02Ny40IDcwLjM3OGMxLjIzNy0uNzMzIDIuMjkxLTEuNzQxIDMuMDI0LTMuMDI0bDEuNDY2LTIuNTIgNy4wMS0xMi4xNDJhOC4zIDguMyAwIDAgMCAxLjEtNC4xMjRINTQuNzk4bDUuMzYzIDEwLjUzOHoiLz48cGF0aCBmaWxsPSIjMDA4MzJkIiBkPSJNNDAgMjIuOTEgNTIuNiAxLjFDNTEuMzYzLjM2NyA0OS45NDMgMCA0OC40NzcgMEgzMS41MjRjLTEuNDY2IDAtMi44ODcuNDEyLTQuMTI0IDEuMXoiLz48cGF0aCBmaWxsPSIjMjY4NGZjIiBkPSJNNTQuNzk5IDQ4LjU2OEgyNS4ybC0xMi42IDIxLjgxYzEuMjM3LjczMyAyLjY1NyAxLjEgNC4xMjQgMS4xaDQ2LjU1MmMxLjQ2NiAwIDIuODg3LS40MTIgNC4xMjQtMS4xeiIvPjxwYXRoIGZpbGw9IiNmZmJhMDAiIGQ9Ik02Ny4yNjIgMjQuMjg0IDU1LjYyNCA0LjEyNEM1NC44OTEgMi44NDEgNTMuODM3IDEuODMzIDUyLjYgMS4xTDQwIDIyLjkxbDE0LjggMjUuNjU5aDI1LjE1NWE4LjMgOC4zIDAgMCAwLTEuMS00LjEyNHoiLz48L2c+PC9zeW1ib2w+PC9zdmc+"
        },
        "displayName": "Google Drive",
        "typeVersion": 3,
        "nodeCategories": [
          {
            "id": 3,
            "name": "Data & Storage"
          }
        ]
      },
      {
        "id": 356,
        "icon": "file:gmail.svg",
        "name": "n8n-nodes-base.gmail",
        "codex": {
          "data": {
            "alias": [
              "email",
              "human",
              "form",
              "wait",
              "hitl",
              "approval"
            ],
            "resources": {
              "generic": [
                {
                  "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/supercharging-your-conference-registration-process-with-n8n/",
                  "icon": "🎫",
                  "label": "Supercharging your conference registration process with n8n"
                },
                {
                  "url": "https://n8n.io/blog/no-code-ecommerce-workflow-automations/",
                  "icon": "store",
                  "label": "6 e-commerce workflows to power up your Shopify s"
                },
                {
                  "url": "https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/",
                  "icon": "👥",
                  "label": "How to get started with CRM automation (with 3 no-code workflow ideas"
                },
                {
                  "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/your-business-doesnt-need-you-to-operate/",
                  "icon": " 🖥️",
                  "label": "Hey founders! Your business doesn't need you to operate"
                },
                {
                  "url": "https://n8n.io/blog/using-automation-to-boost-productivity-in-the-workplace/",
                  "icon": "💪",
                  "label": "Using Automation to Boost Productivity in the Workplace"
                }
              ],
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.gmail/"
                }
              ],
              "credentialDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/credentials/google/oauth-single-service/"
                }
              ]
            },
            "categories": [
              "Communication",
              "HITL"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "HITL": [
                "Human in the Loop"
              ]
            }
          }
        },
        "group": "[\"transform\"]",
        "defaults": {
          "name": "Gmail"
        },
        "iconData": {
          "type": "file",
          "fileBuffer": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTYiIGhlaWdodD0iMTkzIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCI+PHBhdGggZmlsbD0iIzQyODVGNCIgZD0iTTU4LjE4MiAxOTIuMDVWOTMuMTRMMjcuNTA3IDY1LjA3NyAwIDQ5LjUwNHYxMjUuMDkxYzAgOS42NTggNy44MjUgMTcuNDU1IDE3LjQ1NSAxNy40NTV6Ii8+PHBhdGggZmlsbD0iIzM0QTg1MyIgZD0iTTE5Ny44MTggMTkyLjA1aDQwLjcyN2M5LjY1OSAwIDE3LjQ1NS03LjgyNiAxNy40NTUtMTcuNDU1VjQ5LjUwNWwtMzEuMTU2IDE3LjgzNy0yNy4wMjYgMjUuNzk4eiIvPjxwYXRoIGZpbGw9IiNFQTQzMzUiIGQ9Im01OC4xODIgOTMuMTQtNC4xNzQtMzguNjQ3IDQuMTc0LTM2Ljk4OUwxMjggNjkuODY4bDY5LjgxOC01Mi4zNjQgNC42NyAzNC45OTItNC42NyA0MC42NDRMMTI4IDE0NS41MDR6Ii8+PHBhdGggZmlsbD0iI0ZCQkMwNCIgZD0iTTE5Ny44MTggMTcuNTA0VjkzLjE0TDI1NiA0OS41MDRWMjYuMjMxYzAtMjEuNTg1LTI0LjY0LTMzLjg5LTQxLjg5LTIwLjk0NXoiLz48cGF0aCBmaWxsPSIjQzUyMjFGIiBkPSJtMCA0OS41MDQgMjYuNzU5IDIwLjA3TDU4LjE4MiA5My4xNFYxNy41MDRMNDEuODkgNS4yODZDMjQuNjEtNy42NiAwIDQuNjQ2IDAgMjYuMjN6Ii8+PC9zdmc+"
        },
        "displayName": "Gmail",
        "typeVersion": 2,
        "nodeCategories": [
          {
            "id": 6,
            "name": "Communication"
          },
          {
            "id": 28,
            "name": "HITL"
          }
        ]
      },
      {
        "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": 834,
        "icon": "file:code.svg",
        "name": "n8n-nodes-base.code",
        "codex": {
          "data": {
            "alias": [
              "cpde",
              "Javascript",
              "JS",
              "Python",
              "Script",
              "Custom Code",
              "Function"
            ],
            "details": "The Code node allows you to execute JavaScript in your workflow.",
            "resources": {
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code/"
                }
              ]
            },
            "categories": [
              "Development",
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "Core Nodes": [
                "Helpers",
                "Data Transformation"
              ]
            }
          }
        },
        "group": "[\"transform\"]",
        "defaults": {
          "name": "Code"
        },
        "iconData": {
          "type": "file",
          "fileBuffer": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xMTcxXzQ0MSkiPgo8cGF0aCBkPSJNMTcwLjI4MyA0OEgxOTYuNUMyMDMuMTI3IDQ4IDIwOC41IDQyLjYyNzQgMjA4LjUgMzZWMTJDMjA4LjUgNS4zNzI1OCAyMDMuMTI3IDAgMTk2LjUgMEgxNzAuMjgzQzEyNi4xIDAgOTAuMjgzIDM1LjgxNzIgOTAuMjgzIDgwVjE3NkM5MC4yODMgMjA2LjkyOCA2NS4yMTA5IDIzMiAzNC4yODMgMjMySDIzQzE2LjM3MjYgMjMyIDExIDIzNy4zNzIgMTEgMjQ0VjI2OEMxMSAyNzQuNjI3IDE2LjM3MjQgMjgwIDIyLjk5OTYgMjgwTDM0LjI4MyAyODBDNjUuMjEwOSAyODAgOTAuMjgzIDMwNS4wNzIgOTAuMjgzIDMzNlY0NDBDOTAuMjgzIDQ3OS43NjQgMTIyLjUxOCA1MTIgMTYyLjI4MyA1MTJIMTk2LjVDMjAzLjEyNyA1MTIgMjA4LjUgNTA2LjYyNyAyMDguNSA1MDBWNDc2QzIwOC41IDQ2OS4zNzMgMjAzLjEyNyA0NjQgMTk2LjUgNDY0SDE2Mi4yODNDMTQ5LjAyOCA0NjQgMTM4LjI4MyA0NTMuMjU1IDEzOC4yODMgNDQwVjMzNkMxMzguMjgzIDMwOS4wMjIgMTI4LjAxMSAyODQuNDQzIDExMS4xNjQgMjY1Ljk2MUMxMDYuMTA5IDI2MC40MTYgMTA2LjEwOSAyNTEuNTg0IDExMS4xNjQgMjQ2LjAzOUMxMjguMDExIDIyNy41NTcgMTM4LjI4MyAyMDIuOTc4IDEzOC4yODMgMTc2VjgwQzEzOC4yODMgNjIuMzI2OSAxNTIuNjEgNDggMTcwLjI4MyA0OFoiIGZpbGw9IiNGRjk5MjIiLz4KPHBhdGggZD0iTTMwNSAzNkMzMDUgNDIuNjI3NCAzMTAuMzczIDQ4IDMxNyA0OEgzNDIuOTc5QzM2MC42NTIgNDggMzc0Ljk3OCA2Mi4zMjY5IDM3NC45NzggODBWMTc2QzM3NC45NzggMjAyLjk3OCAzODUuMjUxIDIyNy41NTcgNDAyLjA5OCAyNDYuMDM5QzQwNy4xNTMgMjUxLjU4NCA0MDcuMTUzIDI2MC40MTYgNDAyLjA5OCAyNjUuOTYxQzM4NS4yNTEgMjg0LjQ0MyAzNzQuOTc4IDMwOS4wMjIgMzc0Ljk3OCAzMzZWNDMyQzM3NC45NzggNDQ5LjY3MyAzNjAuNjUyIDQ2NCAzNDIuOTc5IDQ2NEgzMTdDMzEwLjM3MyA0NjQgMzA1IDQ2OS4zNzMgMzA1IDQ3NlY1MDBDMzA1IDUwNi42MjcgMzEwLjM3MyA1MTIgMzE3IDUxMkgzNDIuOTc5QzM4Ny4xNjEgNTEyIDQyMi45NzggNDc2LjE4MyA0MjIuOTc4IDQzMlYzMzZDNDIyLjk3OCAzMDUuMDcyIDQ0OC4wNTEgMjgwIDQ3OC45NzkgMjgwSDQ5MEM0OTYuNjI3IDI4MCA1MDIgMjc0LjYyOCA1MDIgMjY4VjI0NEM1MDIgMjM3LjM3MyA0OTYuNjI4IDIzMiA0OTAgMjMyTDQ3OC45NzkgMjMyQzQ0OC4wNTEgMjMyIDQyMi45NzggMjA2LjkyOCA0MjIuOTc4IDE3NlY4MEM0MjIuOTc4IDM1LjgxNzIgMzg3LjE2MSAwIDM0Mi45NzkgMEgzMTdDMzEwLjM3MyAwIDMwNSA1LjM3MjU4IDMwNSAxMlYzNloiIGZpbGw9IiNGRjk5MjIiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8xMTcxXzQ0MSI+CjxyZWN0IHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="
        },
        "displayName": "Code",
        "typeVersion": 2,
        "nodeCategories": [
          {
            "id": 5,
            "name": "Development"
          },
          {
            "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"
          }
        ]
      }
    ],
    "categories": [
      {
        "id": 32,
        "name": "Market Research"
      },
      {
        "id": 51,
        "name": "Multimodal AI"
      }
    ],
    "image": []
  }
}