{
  "id": "QAdpeXOiLC5dyajJ",
  "name": "Intelligent Skool Community Search with AI Analysis",
  "tags": [],
  "nodes": [
    {
      "id": "251e52ca-6e6b-418b-a015-33ff27367ddc",
      "name": "Sticky Note - Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2000,
        1312
      ],
      "parameters": {
        "width": 644,
        "height": 764,
        "content": "## Skool Community Search with AI Analysis\n\nThis workflow transforms any Skool community into a searchable database. Instead of manually scrolling through a large number of Community tab history, this tool uses AI to extract, aggregate, and summarize content from hundreds of past discussions to answer complex questions instantly.\n\n### How it works\nThe process begins with an n8n Form Trigger where you input your query and search depth. The workflow first validates your session cookie and dynamically extracts the latest BuildId from Skool's source code\u2014this prevents the automation from breaking when Skool updates its frontend. Claude Haiku identifies the most effective search keywords based on your question. The system fetches multiple pages of search results in parallel, deduplicates them, and passes the top-ranking content to Claude Sonnet. The AI analyzes the collective community sentiment and insights, drafts a report saved to Google Docs before displaying an HTML summary in your browser.\n\n### Setup steps\n1. **Authentication:** Log in to Skool, open DevTools (F12) \u2192 Application \u2192 Cookies and copy the value for www.skool.com.\n2. **API Keys:** Get an Anthropic API Key and connect Google Docs (OAuth2) credentials in n8n.\n3. **Configuration:** Open the Config node and paste your cookie, Anthropic key, and Community Slug.\n4. **Google Drive:** Create a folder for reports and paste its Folder ID into `DEFAULT_FOLDER_ID`.\n\n### Pro Tip\nThis uses Claude Sonnet for final analysis. For large communities, you can switch to Claude Haiku to save tokens, though insight depth may decrease."
      },
      "typeVersion": 1
    },
    {
      "id": "466f4b18-ac72-422b-a4be-218f2ec7a77b",
      "name": "Sticky Note - Input",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2720,
        1520
      ],
      "parameters": {
        "color": 7,
        "width": 514,
        "height": 280,
        "content": "## Input and Validate Data\nForm trigger collects query, Config holds settings, validates cookie and extracts BuildId"
      },
      "typeVersion": 1
    },
    {
      "id": "ffd98290-b6c6-4a87-bda1-969e77728c8a",
      "name": "Sticky Note - Errors",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3824,
        1184
      ],
      "parameters": {
        "color": 6,
        "width": 434,
        "height": 258,
        "content": "## Cookie Expired\nReturns friendly error with refresh instructions when session expires"
      },
      "typeVersion": 1
    },
    {
      "id": "f8cd833e-6116-42bd-81ae-d0930134e7ae",
      "name": "Sticky Note - Keywords",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3280,
        1520
      ],
      "parameters": {
        "color": 7,
        "width": 710,
        "height": 310,
        "content": "## Extract Keywords\nClaude Haiku identifies the best search terms \nfrom your question"
      },
      "typeVersion": 1
    },
    {
      "id": "10c63423-7f57-4d8a-b9e8-24c7dfe36d0d",
      "name": "Sticky Note - Search",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4032,
        1520
      ],
      "parameters": {
        "color": 7,
        "width": 680,
        "height": 294,
        "content": "## Search & Aggregate Data\nFetches multiple pages in parallel, deduplicates posts, sorts by engagement"
      },
      "typeVersion": 1
    },
    {
      "id": "fcbe09b6-475c-45d5-abe2-72b13b6d8253",
      "name": "Sticky Note - No Results",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4784,
        1312
      ],
      "parameters": {
        "color": 7,
        "width": 420,
        "height": 238,
        "content": "## No Output\nReturns helpful suggestions if search finds nothing"
      },
      "typeVersion": 1
    },
    {
      "id": "688c1ff2-191b-4b85-be0a-ea00f152f1e2",
      "name": "Sticky Note - Analysis",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4752,
        1712
      ],
      "parameters": {
        "color": 7,
        "width": 622,
        "height": 262,
        "content": "## Perform AI Analysis\nClaude Sonnet analyzes top posts and provides comprehensive answer"
      },
      "typeVersion": 1
    },
    {
      "id": "b6e59d28-d85c-4394-b1c6-5e64a078a955",
      "name": "Sticky Note - Output",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5424,
        1712
      ],
      "parameters": {
        "color": 7,
        "width": 1034,
        "height": 264,
        "content": "## Generate Output\nCreates Google Doc report with full content, returns HTML summary page"
      },
      "typeVersion": 1
    },
    {
      "id": "026f0247-e4a1-493e-8ba5-283c0b9245d7",
      "name": "Form Trigger",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        2752,
        1632
      ],
      "parameters": {
        "path": "skool-search",
        "options": {},
        "formTitle": "Skool Community Deep Search",
        "formFields": {
          "values": [
            {
              "fieldLabel": "question",
              "placeholder": "e.g., How should I price my first Upwork job?",
              "requiredField": true
            },
            {
              "fieldLabel": "folder_id",
              "placeholder": "Google Drive Folder ID (leave empty for default folder)"
            },
            {
              "fieldLabel": "search_depth",
              "placeholder": "Number of pages to search (1-10, default: 5)"
            }
          ]
        },
        "responseMode": "responseNode",
        "formDescription": "Search community posts with AI analysis. Results saved to Google Drive.\n\nAuto BuildId detection, cookie validation, optimized performance."
      },
      "typeVersion": 2.1
    },
    {
      "id": "1c315902-1c7f-4a17-9304-cd1984148525",
      "name": "Config",
      "type": "n8n-nodes-base.code",
      "position": [
        2912,
        1632
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// CONFIG NODE - All configuration in one place\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst CONFIG = {\n  // \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n  // \u2502 SKOOL CONFIGURATION                                         \u2502\n  // \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n  \n  // Your Skool community slug (from URL: skool.com/YOUR-COMMUNITY)\n  COMMUNITY: \"your-community-slug\",\n  \n  // Cookie - UPDATE THIS when it expires (check browser DevTools)\n  // To get cookie: DevTools \u2192 Application \u2192 Cookies \u2192 www.skool.com \u2192 Copy all\n  COOKIE: \"YOUR_SKOOL_COOKIE_HERE\",\n  \n  // Fallback BuildId (auto-discovered, kept as backup)\n  FALLBACK_BUILD_ID: \"1765216265055\",\n  \n  // \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n  // \u2502 CLAUDE AI CONFIGURATION                                     \u2502\n  // \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n  \n  // Option 1: Use environment variable (recommended for security)\n  // ANTHROPIC_API_KEY: $env.ANTHROPIC_API_KEY,\n  // Option 2: Paste your key directly (not recommended for sharing)\n  ANTHROPIC_API_KEY: \"YOUR_ANTHROPIC_API_KEY\",\n  \n  // Use Haiku for keyword extraction (cheaper & faster)\n  KEYWORD_MODEL: \"claude-3-haiku-20240307\",\n  KEYWORD_MAX_TOKENS: 50,\n  \n  // Use Sonnet for deep analysis\n  ANALYSIS_MODEL: \"claude-sonnet-4-20250514\",\n  ANALYSIS_MAX_TOKENS: 2500,\n  \n  // \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n  // \u2502 GOOGLE DRIVE CONFIGURATION                                  \u2502\n  // \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n  \n  // Your Google Drive folder ID for saving reports\n  DEFAULT_FOLDER_ID: \"YOUR_GOOGLE_DRIVE_FOLDER_ID\",\n  \n  // \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n  // \u2502 SEARCH & PROCESSING LIMITS                                  \u2502\n  // \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n  DEFAULT_SEARCH_DEPTH: 5,\n  MAX_SEARCH_DEPTH: 10,\n  MIN_SEARCH_DEPTH: 1,\n  \n  // Token protection limits\n  MAX_POST_CONTENT_LENGTH: 2000,\n  MAX_COMMENT_LENGTH: 500,\n  MAX_COMMENTS_PER_POST: 5,\n  MAX_POSTS_FOR_ANALYSIS: 20,\n  \n  // Filter old posts (in days) - set to 0 to disable\n  MAX_POST_AGE_DAYS: 730  // 2 years\n};\n\n// Parse form inputs\nlet question = $json.question || $json.body?.question || \"How to price Upwork jobs\";\nlet folderId = $json.folder_id || $json.body?.folder_id || \"\";\nlet searchDepth = parseInt($json.search_depth || $json.body?.search_depth || CONFIG.DEFAULT_SEARCH_DEPTH);\n\n// Validate search depth\nif (isNaN(searchDepth) || searchDepth < CONFIG.MIN_SEARCH_DEPTH) {\n  searchDepth = CONFIG.MIN_SEARCH_DEPTH;\n} else if (searchDepth > CONFIG.MAX_SEARCH_DEPTH) {\n  searchDepth = CONFIG.MAX_SEARCH_DEPTH;\n}\n\n// Use default folder if not provided\nif (!folderId || folderId.trim() === \"\") {\n  folderId = CONFIG.DEFAULT_FOLDER_ID;\n}\n\nreturn {\n  json: {\n    config: CONFIG,\n    question: question,\n    folderId: folderId,\n    searchDepth: searchDepth,\n    timestamp: new Date().toISOString()\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "3bbe918f-e2d7-4866-a705-c194fd09fd1a",
      "name": "Fetch Skool Homepage",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3088,
        1632
      ],
      "parameters": {
        "url": "=https://www.skool.com/{{ $json.config.COMMUNITY }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "text"
            }
          }
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Cookie",
              "value": "={{ $json.config.COOKIE }}"
            },
            {
              "name": "User-Agent",
              "value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
            }
          ]
        }
      },
      "typeVersion": 4.1
    },
    {
      "id": "ffb5a6a5-64bb-48d7-8693-e9a92e2c5f8b",
      "name": "Extract BuildId",
      "type": "n8n-nodes-base.code",
      "position": [
        3328,
        1632
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// EXTRACT BUILD ID & VALIDATE COOKIE\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst html = $json.data || \"\";\nconst config = $('Config').first().json.config;\nconst question = $('Config').first().json.question;\nconst folderId = $('Config').first().json.folderId;\nconst searchDepth = $('Config').first().json.searchDepth;\nconst timestamp = $('Config').first().json.timestamp;\n\n// \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n// \u2502 CHECK FOR COOKIE EXPIRATION                                  \u2502\n// \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\nconst cookieExpired = \n  html.includes('\"isAuthenticated\":false') ||\n  html.includes('Sign in to continue') ||\n  html.includes('Log in to Skool') ||\n  (html.length < 5000 && html.includes('login'));\n\nif (cookieExpired) {\n  return {\n    json: {\n      error: true,\n      errorType: \"COOKIE_EXPIRED\",\n      errorMessage: \"Your Skool session has expired. Please update the cookie in the Config node.\",\n      question: question,\n      folderId: folderId,\n      config: config\n    }\n  };\n}\n\n// \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n// \u2502 EXTRACT BUILD ID FROM HTML                                   \u2502\n// \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\nlet buildId = config.FALLBACK_BUILD_ID;\nlet buildIdSource = \"fallback\";\n\nconst buildIdMatch1 = html.match(/\"buildId\"\\s*:\\s*\"([^\"]+)\"/);\nif (buildIdMatch1 && buildIdMatch1[1]) {\n  buildId = buildIdMatch1[1];\n  buildIdSource = \"extracted-json\";\n}\n\nif (buildIdSource === \"fallback\") {\n  const buildIdMatch2 = html.match(/_next\\/data\\/([^/]+)\\//);\n  if (buildIdMatch2 && buildIdMatch2[1]) {\n    buildId = buildIdMatch2[1];\n    buildIdSource = \"extracted-script\";\n  }\n}\n\nif (buildIdSource === \"fallback\") {\n  const buildIdMatch3 = html.match(/_next\\/static\\/([^/]+)\\/_buildManifest/);\n  if (buildIdMatch3 && buildIdMatch3[1]) {\n    buildId = buildIdMatch3[1];\n    buildIdSource = \"extracted-manifest\";\n  }\n}\n\nreturn {\n  json: {\n    error: false,\n    buildId: buildId,\n    buildIdSource: buildIdSource,\n    question: question,\n    folderId: folderId,\n    searchDepth: searchDepth,\n    timestamp: timestamp,\n    config: config\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "a9d9e410-00d8-49ca-a313-625eb8d27f69",
      "name": "Cookie Valid?",
      "type": "n8n-nodes-base.if",
      "position": [
        3488,
        1632
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cookie-check",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.error }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "49f39aec-4dd1-45bc-ad87-c72b5a85708a",
      "name": "Cookie Error Response",
      "type": "n8n-nodes-base.code",
      "position": [
        3872,
        1296
      ],
      "parameters": {
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// COOKIE EXPIRED - Return Error HTML\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst data = $input.first().json;\n\nconst errorHtml = `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Session Expired - Skool Search</title>\n  <style>\n    * { box-sizing: border-box; margin: 0; padding: 0; }\n    body {\n      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n      line-height: 1.6;\n      background: linear-gradient(135deg, #ff6b6b 0%, #ee5a5a 100%);\n      min-height: 100vh;\n      padding: 20px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n    }\n    .error-card {\n      background: white;\n      border-radius: 16px;\n      padding: 40px;\n      max-width: 600px;\n      text-align: center;\n      box-shadow: 0 10px 40px rgba(0,0,0,0.2);\n    }\n    .error-icon { font-size: 64px; margin-bottom: 20px; }\n    h1 { color: #ee5a5a; margin-bottom: 15px; }\n    p { color: #666; margin-bottom: 20px; }\n    .steps {\n      background: #f8f9ff;\n      border-radius: 8px;\n      padding: 20px;\n      text-align: left;\n      margin: 20px 0;\n    }\n    .steps h3 { color: #333; margin-bottom: 10px; }\n    .steps ol { padding-left: 20px; }\n    .steps li { margin-bottom: 8px; color: #555; }\n    code {\n      background: #eee;\n      padding: 2px 6px;\n      border-radius: 4px;\n      font-size: 13px;\n    }\n  </style>\n</head>\n<body>\n  <div class=\"error-card\">\n    <div class=\"error-icon\">\ud83d\udd10</div>\n    <h1>Session Expired</h1>\n    <p>Your Skool authentication cookie has expired. This typically happens every 7-14 days.</p>\n    \n    <div class=\"steps\">\n      <h3>To fix this:</h3>\n      <ol>\n        <li>Open Skool in your browser</li>\n        <li>Make sure you're logged in</li>\n        <li>Open DevTools (F12) \u2192 Application \u2192 Cookies</li>\n        <li>Copy all cookie values</li>\n        <li>Update the <code>COOKIE</code> in the Config node</li>\n        <li>Try your search again</li>\n      </ol>\n    </div>\n    \n    <p style=\"font-size: 14px; color: #999;\">Question attempted: \"${data.question}\"</p>\n  </div>\n</body>\n</html>`;\n\nreturn [{\n  json: {\n    htmlReport: errorHtml,\n    error: true,\n    errorType: data.errorType,\n    errorMessage: data.errorMessage\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "be03cfad-d594-463a-a779-d073a93beec8",
      "name": "Respond with Error",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        4080,
        1296
      ],
      "parameters": {
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "text/html"
              }
            ]
          }
        },
        "respondWith": "text",
        "responseBody": "={{ $json.htmlReport }}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "db6594aa-bb2e-4c71-a3a7-637f779b0b52",
      "name": "Build Keyword Request",
      "type": "n8n-nodes-base.code",
      "position": [
        3664,
        1648
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// BUILD KEYWORD EXTRACTION REQUEST (Using Claude Haiku - Cheaper)\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst data = $json;\nconst config = data.config;\n\nconst requestBody = {\n  model: config.KEYWORD_MODEL,\n  max_tokens: config.KEYWORD_MAX_TOKENS,\n  messages: [\n    {\n      role: \"user\",\n      content: \"Extract 1-2 main search keywords only. Return ONLY keywords separated by spaces, nothing else. Question: \" + data.question\n    }\n  ]\n};\n\nreturn {\n  json: {\n    requestBody: requestBody,\n    apiKey: config.ANTHROPIC_API_KEY,\n    ...data\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "7409ee1f-ab60-4bea-9342-d7b1b3b994e0",
      "name": "Claude - Extract Keywords",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3824,
        1648
      ],
      "parameters": {
        "url": "https://api.anthropic.com/v1/messages",
        "method": "POST",
        "options": {
          "timeout": 30000
        },
        "jsonBody": "={{ JSON.stringify($json.requestBody) }}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "={{ $json.apiKey }}"
            },
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.1
    },
    {
      "id": "b41dde79-1c0b-484a-9f62-a1680f1d705c",
      "name": "Build Page URLs",
      "type": "n8n-nodes-base.code",
      "position": [
        4064,
        1648
      ],
      "parameters": {
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// BUILD PAGE URLs - Dynamic BuildId, Configurable Depth\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst items = $input.all();\nconst keywordResponse = items[0].json;\n\nconst keywords = keywordResponse.content?.[0]?.text || \"automation agency\";\n\nconst prevData = $('Build Keyword Request').first().json;\nconst config = prevData.config;\nconst buildId = prevData.buildId;\nconst question = prevData.question;\nconst folderId = prevData.folderId;\nconst searchDepth = prevData.searchDepth;\nconst timestamp = prevData.timestamp;\n\nconst baseUrl = `https://www.skool.com/_next/data/${buildId}/${config.COMMUNITY}/-/search.json`;\n\nconst results = [];\nfor (let page = 1; page <= searchDepth; page++) {\n  results.push({\n    json: {\n      url: `${baseUrl}?q=${encodeURIComponent(keywords)}&group=${config.COMMUNITY}&page=${page}`,\n      page: page,\n      keywords: keywords,\n      cookie: config.COOKIE,\n      question: question,\n      folderId: folderId,\n      searchDepth: searchDepth,\n      buildId: buildId,\n      config: config,\n      timestamp: timestamp\n    }\n  });\n}\n\nreturn results;"
      },
      "typeVersion": 2
    },
    {
      "id": "2f3c7218-cdc0-48ba-b986-e0cc166bfe1a",
      "name": "Fetch All Pages",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4224,
        1648
      ],
      "parameters": {
        "url": "={{ $json.url }}",
        "options": {
          "timeout": 15000,
          "allowUnauthorizedCerts": false
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Cookie",
              "value": "={{ $json.cookie }}"
            },
            {
              "name": "User-Agent",
              "value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
            }
          ]
        }
      },
      "typeVersion": 4.1
    },
    {
      "id": "3de6a552-0f6b-49c3-a97f-2d9084a9457b",
      "name": "Aggregate All Posts",
      "type": "n8n-nodes-base.code",
      "position": [
        4384,
        1648
      ],
      "parameters": {
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// AGGREGATE ALL POSTS - With Token Protection & Smart Filtering\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst allItems = $input.all();\nlet allPosts = [];\nlet totalResults = 0;\nlet validPages = 0;\nlet errorPages = 0;\n\nconst firstItem = $('Build Page URLs').first().json;\nconst config = firstItem.config;\nconst question = firstItem.question;\nconst folderId = firstItem.folderId;\nconst searchDepth = firstItem.searchDepth;\nconst buildId = firstItem.buildId;\nconst timestamp = firstItem.timestamp;\nconst keywords = firstItem.keywords;\n\nfor (const item of allItems) {\n  const json = item.json || {};\n  \n  if (json.error || !json.pageProps) {\n    errorPages++;\n    continue;\n  }\n  \n  validPages++;\n  const pageProps = json.pageProps;\n  const postTrees = pageProps.postTrees || [];\n  \n  if (pageProps.totalPosts && pageProps.totalPosts > totalResults) {\n    totalResults = pageProps.totalPosts;\n  }\n  \n  for (const postItem of postTrees) {\n    const post = postItem.post || {};\n    const metadata = post.metadata || {};\n    const user = post.user || {};\n    const children = postItem.children || [];\n    \n    const firstName = user.firstName || \"\";\n    const lastName = user.lastName || \"\";\n    const authorName = (firstName + \" \" + lastName).trim() || \"Anonymous\";\n    \n    const comments = children\n      .slice(0, config.MAX_COMMENTS_PER_POST)\n      .map(function(child) {\n        const c = child.post || {};\n        const cu = c.user || {};\n        const cMeta = c.metadata || {};\n        const content = cMeta.content || \"\";\n        \n        return {\n          author: ((cu.firstName || \"\") + \" \" + (cu.lastName || \"\")).trim() || \"Anonymous\",\n          content: content.length > config.MAX_COMMENT_LENGTH \n            ? content.substring(0, config.MAX_COMMENT_LENGTH) + \"...\"\n            : content,\n          upvotes: cMeta.upvotes || 0,\n          createdAt: c.createdAt || \"\"\n        };\n      });\n    \n    const rawContent = metadata.content || \"\";\n    const truncatedContent = rawContent.length > config.MAX_POST_CONTENT_LENGTH\n      ? rawContent.substring(0, config.MAX_POST_CONTENT_LENGTH) + \"...\"\n      : rawContent;\n    \n    let includePost = true;\n    if (config.MAX_POST_AGE_DAYS > 0 && post.createdAt) {\n      const postDate = new Date(post.createdAt);\n      const cutoffDate = new Date();\n      cutoffDate.setDate(cutoffDate.getDate() - config.MAX_POST_AGE_DAYS);\n      includePost = postDate >= cutoffDate;\n    }\n    \n    if (includePost) {\n      allPosts.push({\n        id: post.id || \"\",\n        title: metadata.title || \"Untitled\",\n        content: truncatedContent,\n        fullContent: rawContent,\n        author: authorName,\n        upvotes: metadata.upvotes || 0,\n        commentCount: metadata.comments || 0,\n        createdAt: post.createdAt || \"\",\n        url: `https://www.skool.com/${config.COMMUNITY}/${post.name || \"\"}`,\n        comments: comments\n      });\n    }\n  }\n}\n\nconst seenIds = {};\nconst uniquePosts = [];\nfor (const post of allPosts) {\n  if (post.id && !seenIds[post.id]) {\n    seenIds[post.id] = true;\n    uniquePosts.push(post);\n  }\n}\n\nuniquePosts.sort((a, b) => (b.upvotes + b.commentCount) - (a.upvotes + a.commentCount));\n\nreturn [{\n  json: {\n    question: question,\n    totalResults: totalResults,\n    pagesSearched: validPages,\n    errorPages: errorPages,\n    posts: uniquePosts,\n    folderId: folderId,\n    buildId: buildId,\n    keywords: keywords,\n    config: config,\n    timestamp: timestamp\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "4759de8d-c014-4f82-8afa-5101f0e30ddd",
      "name": "Has Results?",
      "type": "n8n-nodes-base.if",
      "position": [
        4544,
        1648
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "empty-check",
              "operator": {
                "type": "number",
                "operation": "equals"
              },
              "leftValue": "={{ $json.posts.length }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "b8693d62-65fe-45b2-b997-699278b06b22",
      "name": "No Results Response",
      "type": "n8n-nodes-base.code",
      "position": [
        4832,
        1408
      ],
      "parameters": {
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// NO RESULTS FOUND - Return Helpful HTML\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst data = $input.first().json;\n\nconst noResultsHtml = `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>No Results - Skool Search</title>\n  <style>\n    * { box-sizing: border-box; margin: 0; padding: 0; }\n    body {\n      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n      line-height: 1.6;\n      background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%);\n      min-height: 100vh;\n      padding: 20px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n    }\n    .card {\n      background: white;\n      border-radius: 16px;\n      padding: 40px;\n      max-width: 600px;\n      text-align: center;\n      box-shadow: 0 10px 40px rgba(0,0,0,0.1);\n    }\n    .icon { font-size: 64px; margin-bottom: 20px; }\n    h1 { color: #ff9a56; margin-bottom: 15px; }\n    p { color: #666; margin-bottom: 15px; }\n    .suggestions {\n      background: #f8f9ff;\n      border-radius: 8px;\n      padding: 20px;\n      text-align: left;\n      margin: 20px 0;\n    }\n    .suggestions h3 { color: #333; margin-bottom: 10px; }\n    .suggestions ul { padding-left: 20px; }\n    .suggestions li { margin-bottom: 8px; color: #555; }\n    .keywords {\n      background: #667eea;\n      color: white;\n      padding: 5px 12px;\n      border-radius: 15px;\n      display: inline-block;\n      margin: 5px;\n    }\n  </style>\n</head>\n<body>\n  <div class=\"card\">\n    <div class=\"icon\">\ud83d\udd0d</div>\n    <h1>No Results Found</h1>\n    <p>Your question: \"${data.question}\"</p>\n    <p>Keywords searched: <span class=\"keywords\">${data.keywords}</span></p>\n    <p>Pages checked: ${data.pagesSearched} | Errors: ${data.errorPages}</p>\n    \n    <div class=\"suggestions\">\n      <h3>Try:</h3>\n      <ul>\n        <li>Use different or broader keywords</li>\n        <li>Check spelling</li>\n        <li>Try a more general question</li>\n        <li>Search for related topics</li>\n      </ul>\n    </div>\n  </div>\n</body>\n</html>`;\n\nreturn [{\n  json: {\n    htmlReport: noResultsHtml,\n    noResults: true,\n    question: data.question,\n    keywords: data.keywords\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "a2ab83aa-0d40-4319-8fcf-d23a84f388d3",
      "name": "Respond No Results",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        5024,
        1408
      ],
      "parameters": {
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "text/html"
              }
            ]
          }
        },
        "respondWith": "text",
        "responseBody": "={{ $json.htmlReport }}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "dcc97c16-cfe8-45d8-89d0-e80d091df2ae",
      "name": "Build Analysis Request",
      "type": "n8n-nodes-base.code",
      "position": [
        4800,
        1808
      ],
      "parameters": {
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// BUILD ANALYSIS REQUEST (Using Sonnet for Deep Analysis)\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst data = $input.first().json;\nconst config = data.config;\nconst posts = data.posts || [];\nconst topPosts = posts.slice(0, config.MAX_POSTS_FOR_ANALYSIS);\n\nconst promptContent = `You are analyzing posts from a Skool community.\n\nOriginal Question: ${data.question}\n\nFound ${data.totalResults} total results. Searched ${data.pagesSearched} pages. Analyzing top ${topPosts.length} most engaged posts:\n\n${topPosts.map((p, i) => `\n=== POST ${i+1} ===\nTitle: ${p.title}\nAuthor: ${p.author}\nUpvotes: ${p.upvotes} | Comments: ${p.commentCount}\nURL: ${p.url}\n\nContent:\n${p.content}\n\nTop Comments:\n${p.comments.slice(0, 3).map(c => \"- \" + c.author + \": \" + c.content).join(\"\\n\")}\n`).join(\"\\n\")}\n\nProvide a comprehensive analysis:\n1. Direct answer to the user's question based on community wisdom\n2. Key insights and patterns across posts\n3. Rank the most useful posts (reference by title)\n4. Actionable advice from the community`;\n\nreturn [{\n  json: {\n    requestBody: {\n      model: config.ANALYSIS_MODEL,\n      max_tokens: config.ANALYSIS_MAX_TOKENS,\n      messages: [{role: \"user\", content: promptContent}]\n    },\n    apiKey: config.ANTHROPIC_API_KEY,\n    question: data.question,\n    totalResults: data.totalResults,\n    pagesSearched: data.pagesSearched,\n    posts: posts,\n    folderId: data.folderId,\n    buildId: data.buildId,\n    keywords: data.keywords,\n    config: config,\n    timestamp: data.timestamp\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "531562f4-f6e7-4712-ba68-99d618411454",
      "name": "Claude - Analyze",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        5008,
        1808
      ],
      "parameters": {
        "url": "https://api.anthropic.com/v1/messages",
        "method": "POST",
        "options": {
          "timeout": 60000
        },
        "jsonBody": "={{ JSON.stringify($json.requestBody) }}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "={{ $json.apiKey }}"
            },
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.1
    },
    {
      "id": "277e91fd-de77-45ae-8ce8-eca34d826b4c",
      "name": "Format Response",
      "type": "n8n-nodes-base.code",
      "position": [
        5200,
        1808
      ],
      "parameters": {
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// FORMAT RESPONSE - Prepare data for document and HTML\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst claudeResponse = $input.first().json;\nconst prevData = $('Build Analysis Request').first().json;\n\nconst analysis = (claudeResponse.content && claudeResponse.content[0]) \n  ? claudeResponse.content[0].text \n  : \"Analysis not available\";\n\nconst fullPosts = prevData.posts.map(p => ({\n  title: p.title,\n  url: p.url,\n  author: p.author,\n  upvotes: p.upvotes,\n  commentCount: p.commentCount,\n  createdAt: p.createdAt,\n  content: p.fullContent || p.content,\n  comments: p.comments\n}));\n\nreturn [{\n  json: {\n    success: true,\n    question: prevData.question,\n    searchResultsCount: prevData.totalResults,\n    pagesSearched: prevData.pagesSearched,\n    postsAnalyzed: Math.min(prevData.posts.length, 20),\n    totalPostsFound: prevData.posts.length,\n    aiAnalysis: analysis,\n    posts: fullPosts,\n    folderId: prevData.folderId,\n    buildId: prevData.buildId,\n    keywords: prevData.keywords,\n    timestamp: prevData.timestamp\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "f18a81f0-e52c-409f-af20-f613ce001aa8",
      "name": "Prepare Document Content",
      "type": "n8n-nodes-base.code",
      "position": [
        5488,
        1808
      ],
      "parameters": {
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// PREPARE DOCUMENT CONTENT - Google Doc + HTML Preview\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst data = $input.first().json;\nconst timestamp = new Date().toISOString().split('T')[0];\n\nconst docTitle = `Skool Research - ${data.question.substring(0, 40)} - ${timestamp}`;\nconst targetFolderId = data.folderId;\n\nconst docContent = `SKOOL COMMUNITY SEARCH REPORT\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nQuestion: ${data.question}\nGenerated: ${new Date(data.timestamp).toLocaleString()}\nTotal Results: ${data.searchResultsCount}\nPages Searched: ${data.pagesSearched}\nPosts Found: ${data.totalPostsFound}\nPosts Analyzed by AI: ${data.postsAnalyzed}\nKeywords Used: ${data.keywords}\nBuild ID: ${data.buildId}\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nAI ANALYSIS\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n${data.aiAnalysis}\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nALL POSTS WITH FULL CONTENT\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n${data.posts.map((post, index) => `\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nPOST #${index + 1}: ${post.title}\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nAuthor: ${post.author}\nEngagement: ${post.upvotes} upvotes | ${post.commentCount} comments\nDate: ${post.createdAt ? new Date(post.createdAt).toLocaleDateString() : 'N/A'}\nLink: ${post.url}\n\nFULL CONTENT:\n${post.content || 'No content available'}\n\nCOMMENTS (${post.comments ? post.comments.length : 0}):\n${post.comments && post.comments.length > 0 \n  ? post.comments.map((c, i) => `\n  [${i + 1}] ${c.author}${c.upvotes > 0 ? ' (\u2191' + c.upvotes + ')' : ''}\n  ${c.content}\n`).join('') \n  : '  No comments available'}\n`).join('')}\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nQUICK LINKS SUMMARY\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n${data.posts.map((post, index) => `${index + 1}. ${post.title}\\n   ${post.url}`).join('\\n\\n')}\n\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nEND OF REPORT\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n`;\n\nfunction markdownToHtml(text) {\n  return text\n    .replace(/^### (.*$)/gm, '<h3>$1</h3>')\n    .replace(/^## (.*$)/gm, '<h2>$1</h2>')\n    .replace(/^# (.*$)/gm, '<h1>$1</h1>')\n    .replace(/\\*\\*(.*?)\\*\\*/g, '<strong>$1</strong>')\n    .replace(/\\*(.*?)\\*/g, '<em>$1</em>')\n    .replace(/^- (.*$)/gm, '<li>$1</li>')\n    .replace(/\\n\\n/g, '</p><p>')\n    .replace(/\\n/g, '<br>');\n}\n\nconst analysisHtml = markdownToHtml(data.aiAnalysis || '');\n\nconst postsHtml = data.posts.map((post, index) => `\n  <div class=\"post\">\n    <div class=\"post-header\">\n      <span class=\"post-number\">#${index + 1}</span>\n      <h3><a href=\"${post.url}\" target=\"_blank\">${post.title}</a></h3>\n    </div>\n    <div class=\"post-meta\">\n      <span>\ud83d\udc64 ${post.author}</span>\n      <span>\u2b06\ufe0f ${post.upvotes}</span>\n      <span>\ud83d\udcac ${post.commentCount}</span>\n    </div>\n    <div class=\"post-content\">\n      <p>${(post.content || 'No content').substring(0, 500).replace(/\\n/g, '<br>')}${post.content && post.content.length > 500 ? '...' : ''}</p>\n    </div>\n    ${post.comments && post.comments.length > 0 ? `\n      <div class=\"comments-section\">\n        <h4>Comments (${post.comments.length}):</h4>\n        ${post.comments.slice(0, 3).map(c => `\n          <div class=\"comment\">\n            <strong>${c.author}</strong>: ${(c.content || '').substring(0, 200).replace(/\\n/g, '<br>')}${c.content && c.content.length > 200 ? '...' : ''}\n          </div>\n        `).join('')}\n      </div>\n    ` : ''}\n  </div>\n`).join('');\n\nreturn [{\n  json: {\n    ...data,\n    docTitle: docTitle,\n    docContent: docContent,\n    targetFolderId: targetFolderId,\n    analysisHtml: analysisHtml,\n    postsHtml: postsHtml\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "2a88e3e8-43ae-44b9-a2dd-ee51d8113278",
      "name": "Create Google Doc",
      "type": "n8n-nodes-base.googleDocs",
      "position": [
        5680,
        1808
      ],
      "parameters": {
        "title": "={{ $json.docTitle }}",
        "folderId": "={{ $json.targetFolderId }}"
      },
      "typeVersion": 2
    },
    {
      "id": "e78c39e7-4e0f-4c96-a002-1420132938df",
      "name": "Add Content to Doc",
      "type": "n8n-nodes-base.googleDocs",
      "position": [
        5872,
        1808
      ],
      "parameters": {
        "actionsUi": {
          "actionFields": [
            {
              "text": "={{ $('Prepare Document Content').first().json.docContent }}",
              "action": "insert"
            }
          ]
        },
        "operation": "update",
        "documentURL": "={{ $json.id }}"
      },
      "typeVersion": 2
    },
    {
      "id": "5934a078-d510-45de-a241-9ec53a1b0f14",
      "name": "Generate Final HTML",
      "type": "n8n-nodes-base.code",
      "position": [
        6080,
        1808
      ],
      "parameters": {
        "jsCode": "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// GENERATE FINAL HTML - Beautiful Response\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst docData = $input.first().json;\nconst prepData = $('Prepare Document Content').first().json;\n\nconst docUrl = `https://docs.google.com/document/d/${docData.id}/edit`;\nconst folderUrl = prepData.targetFolderId\n  ? `https://drive.google.com/drive/folders/${prepData.targetFolderId}` \n  : 'https://drive.google.com/drive/my-drive';\n\nconst html = `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Skool Search Results - ${prepData.question}</title>\n  <style>\n    * { box-sizing: border-box; margin: 0; padding: 0; }\n    body {\n      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n      line-height: 1.6;\n      color: #333;\n      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n      min-height: 100vh;\n      padding: 20px;\n    }\n    .container { max-width: 1000px; margin: 0 auto; }\n    .header, .analysis-section, .posts-section, .gdoc-section {\n      background: white;\n      border-radius: 16px;\n      padding: 30px;\n      margin-bottom: 20px;\n      box-shadow: 0 10px 40px rgba(0,0,0,0.2);\n    }\n    .header h1 { color: #667eea; margin-bottom: 10px; }\n    .question-box {\n      background: #f8f9ff;\n      border-left: 4px solid #667eea;\n      padding: 15px 20px;\n      border-radius: 0 8px 8px 0;\n      margin: 15px 0;\n    }\n    .stats { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 15px; }\n    .stat {\n      background: #667eea;\n      color: white;\n      padding: 8px 16px;\n      border-radius: 20px;\n      font-size: 14px;\n    }\n    .stat.success { background: #10b981; }\n    .gdoc-section {\n      background: linear-gradient(135deg, #4285f4 0%, #34a853 100%);\n      color: white;\n      text-align: center;\n    }\n    .gdoc-section h2 { margin-bottom: 15px; }\n    .gdoc-buttons { display: flex; gap: 15px; justify-content: center; flex-wrap: wrap; }\n    .gdoc-btn {\n      display: inline-block;\n      background: white;\n      color: #4285f4;\n      padding: 15px 30px;\n      border-radius: 8px;\n      text-decoration: none;\n      font-weight: bold;\n      font-size: 16px;\n      transition: transform 0.2s;\n    }\n    .gdoc-btn:hover { transform: scale(1.05); }\n    .gdoc-btn.folder { color: #34a853; }\n    .analysis-section h2, .posts-section > h2 {\n      color: #667eea;\n      margin-bottom: 20px;\n      padding-bottom: 10px;\n      border-bottom: 2px solid #eee;\n    }\n    .copy-wrapper { position: relative; }\n    .copy-btn {\n      position: absolute;\n      top: 10px;\n      right: 10px;\n      background: #667eea;\n      color: white;\n      border: none;\n      padding: 8px 16px;\n      border-radius: 6px;\n      cursor: pointer;\n      font-size: 13px;\n    }\n    .copy-btn:hover { background: #5a6fd6; }\n    .copy-btn.copied { background: #10b981; }\n    .analysis-content { line-height: 1.8; }\n    .post {\n      border: 1px solid #eee;\n      border-radius: 12px;\n      padding: 20px;\n      margin-bottom: 15px;\n    }\n    .post:hover { border-color: #667eea; }\n    .post-header { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }\n    .post-number {\n      background: #667eea;\n      color: white;\n      width: 30px;\n      height: 30px;\n      border-radius: 50%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      font-size: 12px;\n      font-weight: bold;\n    }\n    .post-header h3 { margin: 0; font-size: 1.1em; }\n    .post-header a { color: #333; text-decoration: none; }\n    .post-header a:hover { color: #667eea; }\n    .post-meta { display: flex; gap: 15px; font-size: 14px; color: #666; margin-bottom: 10px; }\n    .post-content { background: #f8f9ff; padding: 15px; border-radius: 8px; font-size: 14px; }\n    .comments-section { margin-top: 15px; padding-top: 15px; border-top: 1px solid #eee; }\n    .comments-section h4 { font-size: 14px; color: #667eea; margin-bottom: 10px; }\n    .comment { background: #f0f0f0; padding: 10px; border-radius: 6px; font-size: 13px; margin-bottom: 8px; }\n    .footer { text-align: center; color: white; padding: 20px; font-size: 14px; }\n    .tech-info { font-size: 12px; color: rgba(255,255,255,0.7); margin-top: 10px; }\n  </style>\n</head>\n<body>\n  <div class=\"container\">\n    <div class=\"header\">\n      <h1>\ud83d\udd0d Skool Community Search Results</h1>\n      <div class=\"question-box\">\n        <strong>Your Question:</strong> ${prepData.question}\n      </div>\n      <div class=\"stats\">\n        <span class=\"stat\">\ud83d\udcca ${prepData.searchResultsCount} total results</span>\n        <span class=\"stat\">\ud83d\udcc4 ${prepData.pagesSearched} pages searched</span>\n        <span class=\"stat\">\ud83d\udcdd ${prepData.totalPostsFound} posts found</span>\n        <span class=\"stat\">\ud83e\udd16 ${prepData.postsAnalyzed} posts analyzed</span>\n        <span class=\"stat success\">\ud83d\udd27 BuildId: Auto</span>\n      </div>\n    </div>\n    \n    <div class=\"gdoc-section\">\n      <h2>\ud83d\udcc4 Your Report is Ready!</h2>\n      <p style=\"margin-bottom: 20px;\">Full report saved to your Google Drive</p>\n      <div class=\"gdoc-buttons\">\n        <a href=\"${docUrl}\" target=\"_blank\" class=\"gdoc-btn\">\ud83d\udcdd Open Google Doc</a>\n        <a href=\"${folderUrl}\" target=\"_blank\" class=\"gdoc-btn folder\">\ud83d\udcc1 Open Drive Folder</a>\n      </div>\n    </div>\n    \n    <div class=\"analysis-section\">\n      <div class=\"copy-wrapper\">\n        <h2>\ud83e\udd16 AI Analysis Preview</h2>\n        <button class=\"copy-btn\" onclick=\"copyAnalysis()\">\ud83d\udccb Copy</button>\n        <div class=\"analysis-content\" id=\"analysis-text\">${prepData.analysisHtml}</div>\n      </div>\n    </div>\n    \n    <div class=\"posts-section\">\n      <h2>\ud83d\udcda Posts Preview (${prepData.totalPostsFound} found)</h2>\n      ${prepData.postsHtml}\n    </div>\n    \n    <div class=\"footer\">\n      <p>Generated on ${new Date(prepData.timestamp).toLocaleString()}</p>\n      <p class=\"tech-info\">Keywords: \"${prepData.keywords}\" | BuildId: ${prepData.buildId}</p>\n    </div>\n  </div>\n  \n  <script>\n    function copyAnalysis() {\n      const text = document.getElementById('analysis-text').innerText;\n      navigator.clipboard.writeText(text).then(() => {\n        const btn = document.querySelector('.copy-btn');\n        btn.textContent = '\u2713 Copied!';\n        btn.classList.add('copied');\n        setTimeout(() => {\n          btn.textContent = '\ud83d\udccb Copy';\n          btn.classList.remove('copied');\n        }, 2000);\n      });\n    }\n  </script>\n</body>\n</html>\n`;\n\nreturn [{\n  json: {\n    htmlReport: html,\n    googleDocUrl: docUrl,\n    folderUrl: folderUrl,\n    documentId: docData.id\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "185aa4a5-6681-4aff-8dc8-74ca94137b1b",
      "name": "Respond with HTML",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        6256,
        1808
      ],
      "parameters": {
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "text/html"
              }
            ]
          }
        },
        "respondWith": "text",
        "responseBody": "={{ $json.htmlReport }}"
      },
      "typeVersion": 1.1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "19e46a08-1f3b-4b42-8339-06cbdbeb467b",
  "connections": {
    "Config": {
      "main": [
        [
          {
            "node": "Fetch Skool Homepage",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Form Trigger": {
      "main": [
        [
          {
            "node": "Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Results?": {
      "main": [
        [
          {
            "node": "No Results Response",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Build Analysis Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Cookie Valid?": {
      "main": [
        [
          {
            "node": "Cookie Error Response",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Build Keyword Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Page URLs": {
      "main": [
        [
          {
            "node": "Fetch All Pages",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract BuildId": {
      "main": [
        [
          {
            "node": "Cookie Valid?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch All Pages": {
      "main": [
        [
          {
            "node": "Aggregate All Posts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Response": {
      "main": [
        [
          {
            "node": "Prepare Document Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude - Analyze": {
      "main": [
        [
          {
            "node": "Format Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Google Doc": {
      "main": [
        [
          {
            "node": "Add Content to Doc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Content to Doc": {
      "main": [
        [
          {
            "node": "Generate Final HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate All Posts": {
      "main": [
        [
          {
            "node": "Has Results?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Final HTML": {
      "main": [
        [
          {
            "node": "Respond with HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "No Results Response": {
      "main": [
        [
          {
            "node": "Respond No Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Skool Homepage": {
      "main": [
        [
          {
            "node": "Extract BuildId",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Keyword Request": {
      "main": [
        [
          {
            "node": "Claude - Extract Keywords",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Cookie Error Response": {
      "main": [
        [
          {
            "node": "Respond with Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Analysis Request": {
      "main": [
        [
          {
            "node": "Claude - Analyze",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Document Content": {
      "main": [
        [
          {
            "node": "Create Google Doc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude - Extract Keywords": {
      "main": [
        [
          {
            "node": "Build Page URLs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}