{
  "id": "F7k18n3EINsvaV_TbPP0k",
  "name": "006. ScreenshotOne - Portfolio Screenshots (Custom Sections) - WITH SETUP GUIDE",
  "tags": [],
  "nodes": [
    {
      "id": "b782b725-8c63-47e6-8164-fc634a049c84",
      "name": "Sticky Note - Main Guide",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2064,
        96
      ],
      "parameters": {
        "color": 4,
        "width": 420,
        "height": 808,
        "content": "# \ud83d\udccb Portfolio Screenshot Generator - Setup Guide\n\n## What this workflow does:\n1. Takes a website URL from a form\n2. Renders the page with JavaScript (Firecrawl)\n3. AI analyzes the site structure and content\n4. Takes multiple screenshots (hero, fullpage, sections, mobile)\n5. Uploads to Google Drive\n6. Generates Upwork portfolio description with AI\n7. Saves everything to Google Sheets\n8. Sends Telegram notification\n\n## \u26a0\ufe0f Required Setup Steps:\n1. **Firecrawl API Key** \u2192 Node: \"Firecrawl Scrape\"\n2. **ScreenshotOne API Key** \u2192 Node: \"Site Configuration\"\n3. **OpenAI Credentials** \u2192 Nodes: \"AI Site Analysis\" & \"AI Generate Upwork\"\n4. **Google Drive OAuth** \u2192 Node: \"Upload to Google Drive\"\n5. **Google Sheets OAuth** \u2192 Node: \"Save to Google Sheets\"\n6. **Telegram Bot** \u2192 Node: \"Telegram Notification\"\n\n## \ud83d\udd17 Get API Keys:\n- Firecrawl: https://firecrawl.dev\n- ScreenshotOne: https://screenshotone.com\n- OpenAI: https://platform.openai.com/api-keys"
      },
      "typeVersion": 1
    },
    {
      "id": "bcccb937-d768-44d0-822a-1663987b7ea3",
      "name": "Sticky Note - Firecrawl",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1344,
        -112
      ],
      "parameters": {
        "color": 6,
        "width": 300,
        "height": 444,
        "content": "## \ud83d\udd11 STEP 1: Firecrawl API Key\n\n**What:** Firecrawl renders JavaScript pages\n\n**How to get:**\n1. Go to https://firecrawl.dev\n2. Sign up / Log in\n3. Get your API key\n\n**Where to change:**\nIn the HTTP Request body, replace:\n```\n```\nwith your key in the Authorization header"
      },
      "typeVersion": 1
    },
    {
      "id": "c2fbcf06-511c-4267-8b40-28e8cb5ed0b4",
      "name": "Sticky Note - ScreenshotOne",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -480,
        -176
      ],
      "parameters": {
        "color": 6,
        "width": 300,
        "height": 456,
        "content": "## \ud83d\udd11 STEP 2: ScreenshotOne API Key\n\n**What:** Takes high-quality screenshots\n\n**How to get:**\n1. Go to https://screenshotone.com\n2. Sign up (free tier available)\n3. Copy your Access Key\n\n**Where to change:**\nIn the Code node, find line:\n```javascript\nconst API_KEY = '';\n```\nReplace with your key"
      },
      "typeVersion": 1
    },
    {
      "id": "5512ce93-beea-42ee-9d0c-327fa592d734",
      "name": "Sticky Note - OpenAI",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -880,
        -176
      ],
      "parameters": {
        "color": 6,
        "width": 300,
        "height": 432,
        "content": "## \ud83d\udd11 STEP 3: OpenAI Credentials\n\n**What:** AI analyzes sites & writes Upwork descriptions\n\n**Setup:**\n1. Go to Settings \u2192 Credentials\n2. Add new \"OpenAI API\" credential\n3. Paste your API key from:\n   https://platform.openai.com/api-keys\n\n**Connect to nodes:**\n- AI Site Analysis\n- AI Generate Upwork\n\n**Model used:** gpt-4o-mini\n(Can change in Prepare AI Request node)"
      },
      "typeVersion": 1
    },
    {
      "id": "8b107b06-c832-4384-ae25-54535679b2a6",
      "name": "Sticky Note - Google Drive",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        400,
        640
      ],
      "parameters": {
        "color": 6,
        "width": 348,
        "height": 484,
        "content": "## \ud83d\udcc1 STEP 4: Google Drive Setup\n\n**What:** Stores screenshot images\n\n**Setup OAuth:**\n1. Settings \u2192 Credentials \u2192 Add \"Google Drive OAuth2\"\n2. Follow OAuth flow\n\n**\u26a0\ufe0f CHANGE FOLDER ID:**\nCurrent folder:\n```\n\n```\n\n**To get your folder ID:**\n1. Open Google Drive\n2. Create/open a folder\n3. Copy ID from URL:\n   drive.google.com/drive/folders/**YOUR_ID**"
      },
      "typeVersion": 1
    },
    {
      "id": "6831ed2c-a084-43c7-9101-223bfb271c35",
      "name": "Sticky Note - Google Sheets",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        752,
        -320
      ],
      "parameters": {
        "color": 6,
        "width": 320,
        "height": 552,
        "content": "## \ud83d\udcca STEP 5: Google Sheets Setup\n\n**What:** Logs all results in a spreadsheet\n\n**Setup OAuth:**\n1. Settings \u2192 Credentials \u2192 Add \"Google Sheets OAuth2\"\n2. Follow OAuth flow\n\n**\u26a0\ufe0f CHANGE DOCUMENT ID:**\nCurrent spreadsheet:\n```\n\n```\n\n**Create your spreadsheet:**\n1. Create new Google Sheet\n2. Copy ID from URL:\n   docs.google.com/spreadsheets/d/**YOUR_ID**/edit\n3. First row = headers (auto-created on first run)"
      },
      "typeVersion": 1
    },
    {
      "id": "0558fce0-4bd6-44a3-9b88-89e8a35d6e15",
      "name": "Sticky Note - Telegram",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1104,
        -320
      ],
      "parameters": {
        "color": 6,
        "width": 300,
        "height": 540,
        "content": "## \ud83d\udcf1 STEP 6: Telegram Setup\n\n**What:** Sends notification when done\n\n**Setup Bot:**\n1. Message @BotFather on Telegram\n2. Send /newbot and follow steps\n3. Copy the bot token\n\n**Setup Credential:**\n1. Settings \u2192 Credentials \u2192 Add \"Telegram API\"\n2. Paste bot token\n\n**\u26a0\ufe0f CHANGE CHAT ID:**\nCurrent: ``\n\n**Get your Chat ID:**\n1. Message your bot\n2. Visit: api.telegram.org/bot**TOKEN**/getUpdates\n3. Find \"chat\":{\"id\":**YOUR_ID**}"
      },
      "typeVersion": 1
    },
    {
      "id": "0c755c79-d2d8-4131-b046-01d2143f0867",
      "name": "Sticky Note - Customization",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -320,
        640
      ],
      "parameters": {
        "color": 3,
        "width": 320,
        "height": 452,
        "content": "## \ud83c\udfa8 CUSTOMIZATION OPTIONS\n\n**Screenshot Settings** (Site Configuration node):\n- `viewport_width`: 1920 (desktop) / 375 (mobile)\n- `device_scale_factor`: 2 (retina quality)\n- `delay`: 3 seconds (wait for page load)\n- `format`: png (can use jpg, webp)\n\n**AI Model** (Prepare AI Request):\n- Change `gpt-4o-mini` to `gpt-4o` for better analysis\n- Adjust `max_tokens` for longer responses\n\n**Rate Limiting** (Wait 3s node):\n- Increase if getting rate limited\n- Decrease for faster processing"
      },
      "typeVersion": 1
    },
    {
      "id": "79fb4875-d639-4f97-826f-7438491fbf48",
      "name": "Sticky Note - Flow",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -64,
        -192
      ],
      "parameters": {
        "color": 5,
        "width": 400,
        "height": 368,
        "content": "## \ud83d\udd04 WORKFLOW FLOW\n\n```\nForm \u2192 Firecrawl \u2192 AI Analysis \u2192 Screenshots \u2192 Upload \u2192 AI Upwork \u2192 Save \u2192 Notify\n```\n\n**Loop Logic:**\nScreenshots are processed one-by-one with 3s delay to avoid rate limits.\n\n**Error Handling:**\n- HTTP nodes have retry (3 attempts)\n- Failed screenshots are filtered out\n- Workflow continues even if some fail"
      },
      "typeVersion": 1
    },
    {
      "id": "5b6d24d2-0ba3-4866-b9d2-b476d4c813e3",
      "name": "Sticky Note - Trigger",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1616,
        -48
      ],
      "parameters": {
        "color": 2,
        "width": 260,
        "height": 292,
        "content": "## \ud83d\ude80 TRIGGER\n\n**Form URL:**\nAfter activating, get the form URL from this node.\n\nShare this URL to allow others to submit websites for portfolio generation."
      },
      "typeVersion": 1
    },
    {
      "id": "cf11d329-4716-444f-9bc8-6b49848989f6",
      "name": "Site Configuration",
      "type": "n8n-nodes-base.code",
      "position": [
        -416,
        352
      ],
      "parameters": {
        "jsCode": "// Get data from AI analysis\nconst aiData = $input.first().json;\nconst siteUrl = aiData.siteUrl;\nconst siteName = aiData.siteName;\nconst sectionIds = aiData.sectionIds || [];\n\n// \u26a0\ufe0f REPLACE WITH YOUR SCREENSHOTONE API KEY\nconst API_KEY = 'uSYTkX5PDESZnQ';\nconst timestamp = new Date().toISOString().split('T')[0];\n\n// Base screenshots (always include)\nconst screenshots = [\n  {\n    name: 'hero',\n    description: 'Hero section (above the fold)',\n    viewport_width: 1920,\n    viewport_height: 1080,\n    device_scale_factor: 2,\n    format: 'png'\n  },\n  {\n    name: 'fullpage',\n    description: 'Full page screenshot',\n    full_page: true,\n    viewport_width: 1920,\n    device_scale_factor: 2,\n    format: 'png'\n  }\n];\n\n// Add REAL section IDs from Firecrawl rendered HTML\nif (sectionIds.length > 0) {\n  sectionIds.forEach((sectionId) => {\n    const cleanName = sectionId.replace(/[^a-zA-Z0-9]/g, '_').toLowerCase();\n    const displayName = sectionId.charAt(0).toUpperCase() + sectionId.slice(1).replace(/[-_]/g, ' ');\n    \n    screenshots.push({\n      name: `section_${cleanName}`,\n      description: `${displayName} section`,\n      scroll_into_view: `#${sectionId}`,\n      error_on_selector_not_found: true,\n      viewport_width: 1920,\n      viewport_height: 1080,\n      device_scale_factor: 2,\n      format: 'png'\n    });\n  });\n}\n\n// Mobile at the end\nscreenshots.push({\n  name: 'mobile',\n  description: 'Mobile version',\n  viewport_mobile: true,\n  viewport_width: 375,\n  viewport_height: 812,\n  device_scale_factor: 2,\n  format: 'png'\n});\n\n// Build API URLs\nconst screenshotConfigs = screenshots.map(shot => {\n  const ext = shot.format || 'png';\n  const filename = `${siteName}_${shot.name}_${timestamp}.${ext}`;\n  \n  const params = {\n    access_key: API_KEY,\n    url: siteUrl,\n    format: 'png',\n    viewport_width: shot.viewport_width || 1920,\n    viewport_height: shot.viewport_height || 1080,\n    device_scale_factor: shot.device_scale_factor || 2,\n    block_cookie_banners: true,\n    block_chats: true,\n    block_ads: true,\n    delay: 3\n  };\n  \n  if (shot.full_page) params.full_page = true;\n  if (shot.viewport_mobile) params.viewport_mobile = true;\n  if (shot.scroll_into_view) params.scroll_into_view = shot.scroll_into_view;\n  if (shot.error_on_selector_not_found) params.error_on_selector_not_found = true;\n  \n  const queryString = Object.entries(params)\n    .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)\n    .join('&');\n  \n  return {\n    siteName,\n    baseUrl: siteUrl,\n    screenshotName: shot.name,\n    description: shot.description,\n    filename,\n    format: ext,\n    apiUrl: `https://api.screenshotone.com/take?${queryString}`,\n    aiAnalysis: aiData,\n    usedSectionIds: sectionIds.length > 0,\n    totalScreenshots: screenshots.length\n  };\n});\n\nreturn screenshotConfigs.map(config => ({ json: config }));"
      },
      "typeVersion": 2
    },
    {
      "id": "b06d6ccb-c47c-4357-a2da-51422fc3ae82",
      "name": "Take Screenshot",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "maxTries": 3,
      "position": [
        -16,
        432
      ],
      "parameters": {
        "url": "={{ $json.apiUrl }}",
        "options": {
          "timeout": 120000,
          "response": {
            "response": {
              "neverError": true,
              "responseFormat": "file"
            }
          }
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 5000
    },
    {
      "id": "6408987a-92cd-418e-9180-90d30e80a6e6",
      "name": "Merge Screenshot Data",
      "type": "n8n-nodes-base.code",
      "position": [
        224,
        432
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Get original config data\nconst config = $('Site Configuration').item.json;\nconst inputItem = $input.item;\n\n// Check if screenshot succeeded\n// 1. Must have binary data\nconst hasBinary = inputItem.binary && Object.keys(inputItem.binary).length > 0;\n\n// 2. Check for API error responses\nconst hasJsonError = inputItem.json.is_successful === false || \n                    inputItem.json.error_code || \n                    inputItem.json.error_message;\n\n// 3. Check if binary is actually an image (not error JSON saved as file)\nlet isValidImage = false;\nif (hasBinary) {\n  const binaryKey = Object.keys(inputItem.binary)[0];\n  const binaryData = inputItem.binary[binaryKey];\n  // Check mime type - should be image/png\n  isValidImage = binaryData.mimeType && binaryData.mimeType.startsWith('image/');\n}\n\nif (!hasBinary || hasJsonError || !isValidImage) {\n  // Skip failed screenshots\n  return [];\n}\n\n// Return both json data AND binary\nreturn {\n  json: {\n    siteName: config.siteName,\n    baseUrl: config.baseUrl,\n    screenshotName: config.screenshotName,\n    description: config.description,\n    filename: config.filename,\n    format: config.format,\n    success: true\n  },\n  binary: inputItem.binary\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "e9cec3c5-ac64-4a4c-8947-e48a39d1083b",
      "name": "Upload to Google Drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        464,
        432
      ],
      "parameters": {
        "name": "={{ $json.filename }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": ""
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "fd76a123-5a76-4b5b-adef-2a3be66f9cef",
      "name": "Aggregate All Results",
      "type": "n8n-nodes-base.code",
      "position": [
        -16,
        240
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\n\n// Get data from Site Configuration\nconst configItems = $('Site Configuration').all();\nconst firstConfig = configItems[0].json;\nconst siteName = firstConfig.siteName;\nconst baseUrl = firstConfig.baseUrl;\n\n// Get AI analysis data\nconst aiAnalysis = firstConfig.aiAnalysis;\nconst sectionIds = aiAnalysis.sectionIds || [];\nconst detectedIds = aiAnalysis.detectedIds || [];\n\n// Get Merge Screenshot Data items (only successful ones)\nconst mergeItems = $('Merge Screenshot Data').all();\n\n// Map screenshots with Drive URLs\nconst screenshots = items.map((item, index) => {\n  const mergeItem = mergeItems[index]?.json || {};\n  return {\n    name: mergeItem.screenshotName || `screenshot_${index + 1}`,\n    description: mergeItem.description || '',\n    filename: mergeItem.filename || '',\n    driveUrl: item.json.webViewLink,\n    driveId: item.json.id\n  };\n});\n\n// Count successful vs total attempted\nconst totalAttempted = configItems.length;\nconst totalSuccessful = screenshots.length;\n\n// Build row for Google Sheets\nconst sheetsRow = {\n  siteName,\n  url: baseUrl,\n  timestamp: new Date().toISOString(),\n  \n  // AI Analysis\n  blocks_count: aiAnalysis.blocks_count,\n  blocks_list: aiAnalysis.blocks_list,\n  has_blog: aiAnalysis.has_blog,\n  languages: aiAnalysis.languages,\n  site_topic: aiAnalysis.site_topic,\n  specialization: aiAnalysis.specialization,\n  target_audience: aiAnalysis.target_audience,\n  key_services: aiAnalysis.key_services,\n  \n  // Screenshot info - Firecrawl edition\n  screenshot_method: 'Firecrawl Rendered HTML',\n  detected_ids: detectedIds.join(', ') || 'none',\n  section_ids_used: sectionIds.join(', ') || 'none',\n  screenshots_attempted: totalAttempted,\n  screenshots_successful: totalSuccessful\n};\n\n// Add screenshot URLs dynamically\nscreenshots.forEach((s, i) => {\n  sheetsRow[`img_${i + 1}_${s.name}`] = s.driveUrl || '';\n});\n\nreturn [{\n  json: {\n    ...sheetsRow,\n    screenshots,\n    screenshotCount: totalSuccessful,\n    sectionIds,\n    detectedIds\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "43a9d3b6-5aa4-48bb-bb11-939f10657e87",
      "name": "Save to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        944,
        240
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "siteName",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "siteName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "url",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "timestamp",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "blocks_count",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "blocks_count",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "blocks_list",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "blocks_list",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "has_blog",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "has_blog",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "languages",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "languages",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "site_topic",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "site_topic",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "specialization",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "specialization",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "target_audience",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "target_audience",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "key_services",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "key_services",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "hero",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "hero",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "fullpage",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "fullpage",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "services_section",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "services_section",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "process_timeline",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "process_timeline",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "testimonials",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "testimonials",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "mobile",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "mobile",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "screenshots",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "screenshots",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "screenshotCount",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "screenshotCount",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "upwork_title",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "upwork_title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "upwork_role",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "upwork_role",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "upwork_description",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "upwork_description",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "upwork_skills",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "upwork_skills",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "portfolio_section",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "portfolio_section",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "contact_section",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "contact_section",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "used_anchors",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "used_anchors",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "anchors_found",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "anchors_found",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "screenshot_hero",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "screenshot_hero",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "screenshot_fullpage",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "screenshot_fullpage",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "screenshot_section_home",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "screenshot_section_home",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "screenshot_section_services",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "screenshot_section_services",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "screenshot_section_process",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "screenshot_section_process",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "screenshot_section_whyus",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "screenshot_section_whyus",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "screenshot_mobile",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "screenshot_mobile",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "screenshot_method",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "screenshot_method",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "page_height",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "page_height",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "total_screenshots",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "total_screenshots",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_1_hero",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_1_hero",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_2_fullpage",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_2_fullpage",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_3_section_services",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_3_section_services",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_4_section_process",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_4_section_process",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_5_section_whyus",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_5_section_whyus",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_6_section_results",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_6_section_results",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_7_section_faq",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_7_section_faq",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_8_section_contact",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_8_section_contact",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_9_section_testimonials",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_9_section_testimonials",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_10_section_home",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_10_section_home",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_11_section_problems",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_11_section_problems",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_12_section_solutions",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_12_section_solutions",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_13_mobile",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_13_mobile",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_3_mobile",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_3_mobile",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ai_found_anchors",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "ai_found_anchors",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "anchors_checked",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "anchors_checked",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "screenshots_attempted",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "screenshots_attempted",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "screenshots_successful",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "screenshots_successful",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "aiFoundAnchors",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "aiFoundAnchors",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "allAnchors",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "allAnchors",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_3_section_hero",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_3_section_hero",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_4_section_problem",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_4_section_problem",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_5_section_solution",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_5_section_solution",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_6_section_how_it_works",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_6_section_how_it_works",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_7_section_voice_agent",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_7_section_voice_agent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_8_section_hitl",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_8_section_hitl",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_9_section_results",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_9_section_results",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_10_section_faq",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_10_section_faq",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_11_section_cta",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_11_section_cta",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_12_section_features",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_12_section_features",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_13_section_products",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_13_section_products",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_14_section_industries",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_14_section_industries",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_15_section_about",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_15_section_about",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_16_section_testimonials",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_16_section_testimonials",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_17_section_blog",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_17_section_blog",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_18_section_contact",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_18_section_contact",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_19_section_problems",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_19_section_problems",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_20_section_solutions",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_20_section_solutions",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_21_section_services",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_21_section_services",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_22_section_process",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_22_section_process",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_23_section_stats",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_23_section_stats",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_24_section_why_us",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_24_section_why_us",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_25_mobile",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_25_mobile",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_3_section_main_content",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_3_section_main_content",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_4_section_hero",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_4_section_hero",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_5_section_features",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_5_section_features",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_6_section_products",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_6_section_products",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_7_section_problem",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_7_section_problem",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_8_section_solution",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_8_section_solution",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_9_section_how_it_works",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_9_section_how_it_works",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_10_section_voice_agent",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_10_section_voice_agent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_11_section_hitl",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_11_section_hitl",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_12_section_results",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_12_section_results",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_13_section_faq",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_13_section_faq",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_14_section_cta",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_14_section_cta",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_15_section_industries",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_15_section_industries",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_16_section_about",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_16_section_about",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_17_section_testimonials",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_17_section_testimonials",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_18_section_blog",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_18_section_blog",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_19_section_contact",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_19_section_contact",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_20_section_problems",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_20_section_problems",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_21_section_solutions",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_21_section_solutions",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_22_section_services",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_22_section_services",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_23_section_process",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_23_section_process",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_24_section_stats",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_24_section_stats",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_25_section_why_us",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_25_section_why_us",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_26_mobile",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_26_mobile",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_1_mobile",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_1_mobile",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_2_screenshot_2",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_2_screenshot_2",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_3_screenshot_3",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_3_screenshot_3",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_4_screenshot_4",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_4_screenshot_4",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_5_screenshot_5",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_5_screenshot_5",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_6_screenshot_6",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_6_screenshot_6",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_7_screenshot_7",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_7_screenshot_7",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_8_screenshot_8",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_8_screenshot_8",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_9_screenshot_9",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_9_screenshot_9",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_10_screenshot_10",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_10_screenshot_10",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_11_screenshot_11",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_11_screenshot_11",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_12_screenshot_12",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_12_screenshot_12",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "img_13_screenshot_13",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "img_13_screenshot_13",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1R2sNdQpe6tJt_Fbhed6MGJEPgHFEh7SsGz59RjIsZ6U/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1R2sNdQpe6tJt_Fbhed6MGJEPgHFEh7SsGz59RjIsZ6U",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1R2sNdQpe6tJt_Fbhed6MGJEPgHFEh7SsGz59RjIsZ6U/edit?usp=drivesdk",
          "cachedResultName": "Screenshots Url"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "ceb445a4-221b-48ab-8356-919bea68aa2f",
      "name": "Telegram Notification",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1184,
        240
      ],
      "parameters": {
        "text": "=\u2705 *Portfolio Ready!*\n\n\ud83c\udf10 *Site:* {{ $json.siteName }}\n\ud83d\udd17 {{ $json.url }}\n\n\ud83d\udcca *Analysis:*\n\u2022 Sections: {{ $json.blocks_count }} ({{ $json.blocks_list }})\n\u2022 Blog: {{ $json.has_blog }} | Lang: {{ $json.languages }}\n\u2022 Niche: {{ $json.specialization }}\n\n\ud83d\udd25 *Firecrawl Rendering:*\n\u2022 Detected IDs: {{ $json.detected_ids || 'none' }}\n\u2022 Used sections: {{ $json.section_ids_used || 'none' }}\n\n\ud83d\udcf8 *Screenshots:*\n\u2022 Successful: {{ $json.screenshots_successful }} of {{ $json.screenshots_attempted }}\n\n\ud83d\udcbc *Upwork Portfolio:*\n*Title:* {{ $json.upwork_title }}\n*Role:* {{ $json.upwork_role }}\n*Skills:* {{ $json.upwork_skills }}\n\n*Description:*\n{{ $json.upwork_description }}\n\n\ud83d\uddbc *Screenshots:*\n{{ $json.screenshots.map(function(s, i) { return (i+1) + '. [' + s.description + '](' + s.driveUrl + ')' }).join('\\n') }}",
        "additionalFields": {
          "parse_mode": "Markdown",
          "disable_web_page_preview": true
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "5c913d1b-492a-4aaf-8eb1-c2bdf56f6e88",
      "name": "Firecrawl Scrape",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1296,
        352
      ],
      "parameters": {
        "url": "https://api.firecrawl.dev/v1/scrape",
        "method": "POST",
        "options": {
          "timeout": 60000
        },
        "jsonBody": "={\n  \"url\": \"{{ $json['Website URL'].startsWith('http') ? $json['Website URL'] : 'https://' + $json['Website URL'] }}\",\n  \"formats\": [\"html\"],\n  \"onlyMainContent\": false,\n  \"waitFor\": 3000,\n  \"timeout\": 30000\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "9406854e-fd52-41f7-acd4-3a62a9b05a80",
      "name": "Parse AI Response",
      "type": "n8n-nodes-base.code",
      "position": [
        -576,
        352
      ],
      "parameters": {
        "jsCode": "// Get AI response\nconst response = $input.first().json;\nconst prevData = $('Prepare AI Request').first().json;\nconst aiContent = response.choices[0].message.content;\n\n// Parse JSON\nlet analysis = {};\ntry {\n  const jsonMatch = aiContent.match(/\\{[\\s\\S]*\\}/);\n  if (jsonMatch) {\n    analysis = JSON.parse(jsonMatch[0]);\n  }\n} catch (e) {\n  analysis = {\n    blocks_count: 5,\n    blocks_list: 'Error parsing',\n    has_blog: false,\n    languages: 'N/A',\n    site_topic: 'Could not analyze',\n    specialization: 'N/A',\n    target_audience: 'N/A',\n    key_services: 'N/A',\n    section_ids: []\n  };\n}\n\n// Get validated section IDs from AI\nlet sectionIds = analysis.section_ids || [];\nif (typeof sectionIds === 'string') {\n  sectionIds = sectionIds.split(',').map(a => a.trim()).filter(a => a);\n}\n\n// Clean IDs - remove # if present\nsectionIds = sectionIds\n  .map(id => id.replace(/^#/, '').trim())\n  .filter(id => id && id.length > 0);\n\n// If AI found no sections, use detected IDs as fallback (max 10)\nif (sectionIds.length === 0 && prevData.detectedIds?.length > 0) {\n  sectionIds = prevData.detectedIds.slice(0, 10);\n}\n\nreturn [{\n  json: {\n    siteUrl: prevData.siteUrl,\n    siteName: prevData.siteName,\n    blocks_count: String(analysis.blocks_count || 'N/A'),\n    blocks_list: String(analysis.blocks_list || 'N/A'),\n    has_blog: analysis.has_blog ? 'Yes' : 'No',\n    languages: String(analysis.languages || 'N/A'),\n    site_topic: String(analysis.site_topic || 'N/A'),\n    specialization: String(analysis.specialization || 'N/A'),\n    target_audience: String(analysis.target_audience || 'N/A'),\n    key_services: String(analysis.key_services || 'N/A'),\n    // Real section IDs from rendered HTML\n    sectionIds: sectionIds,\n    detectedIds: prevData.detectedIds || [],\n    firecrawlSuccess: prevData.firecrawlSuccess\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "f6566d3b-9227-4582-99fa-e2431263474e",
      "name": "Prepare AI Request",
      "type": "n8n-nodes-base.code",
      "position": [
        -1056,
        352
      ],
      "parameters": {
        "jsCode": "// Get rendered HTML from Firecrawl\nconst firecrawlResponse = $input.first().json;\nconst formData = $('Portfolio Form').first().json;\nlet inputUrl = formData['Website URL'];\n\n// Add https:// if missing\nconst siteUrl = inputUrl.startsWith('http') ? inputUrl : 'https://' + inputUrl;\n\n// Extract site name from domain\nlet siteName = siteUrl\n  .replace(/^https?:\\/\\//, '')\n  .replace(/^www\\./, '')\n  .split('/')[0]\n  .split('.')[0];\n\n// Get rendered HTML from Firecrawl\nconst html = firecrawlResponse.data?.html || firecrawlResponse.html || '';\n\n// EXTRACT REAL SECTION IDs from rendered HTML\n// This regex finds all id attributes in the HTML\nconst idMatches = html.match(/id=[\"']([^\"']+)[\"']/gi) || [];\nconst allIds = idMatches.map(m => m.match(/id=[\"']([^\"']+)[\"']/i)?.[1]).filter(Boolean);\n\n// Filter to likely section IDs (exclude utility IDs)\nconst excludePatterns = /^(root|app|__next|__nuxt|gatsby|webpack|modal|tooltip|dropdown|menu|nav|header|footer|sidebar|cookie|banner|popup|overlay|backdrop)/i;\nconst sectionIds = allIds.filter(id => {\n  // Keep IDs that look like sections\n  if (excludePatterns.test(id)) return false;\n  if (id.length < 2 || id.length > 50) return false;\n  if (/^[0-9]/.test(id)) return false; // Skip IDs starting with numbers\n  return true;\n});\n\n// Remove duplicates\nconst uniqueSectionIds = [...new Set(sectionIds)];\n\n// Clean and truncate HTML for AI analysis\nconst cleanHtml = html\n  .substring(0, 25000)\n  .replace(/[\\x00-\\x1F\\x7F]/g, ' ')\n  .replace(/\\\\/g, '\\\\\\\\')\n  .replace(/\"/g, \"'\");\n\nconst requestBody = {\n  model: 'gpt-4o-mini',\n  temperature: 0.2,\n  max_tokens: 2000,\n  messages: [\n    {\n      role: 'system',\n      content: `You are a website analyst. Analyze the rendered HTML and identify which section IDs are actual page sections worth screenshotting.\\n\\nYou will receive:\\n1. The rendered HTML\\n2. A list of detected IDs\\n\\nFilter the IDs to only include real content sections (hero, about, services, features, etc).\\nExclude utility elements, navigation, modals, etc.\\n\\nRespond ONLY with valid JSON.`\n    },\n    {\n      role: 'user',\n      content: `Analyze this website and its sections:\\n\\nDetected IDs: ${JSON.stringify(uniqueSectionIds)}\\n\\n{\\n  \"blocks_count\": <number of main sections>,\\n  \"blocks_list\": \"<section names>\",\\n  \"has_blog\": <true/false>,\\n  \"languages\": \"<languages>\",\\n  \"site_topic\": \"<about the site>\",\\n  \"specialization\": \"<niche>\",\\n  \"target_audience\": \"<audience>\",\\n  \"key_services\": \"<services>\",\\n  \"section_ids\": [\"<ONLY the IDs that are real content sections worth screenshotting, from the detected IDs list>\"]\\n}\\n\\nHTML (first 25KB):\\n${cleanHtml}`\n    }\n  ]\n};\n\nreturn [{ \n  json: { \n    requestBody, \n    siteUrl, \n    siteName, \n    detectedIds: uniqueSectionIds,\n    firecrawlSuccess: firecrawlResponse.success || !!firecrawlResponse.data\n  } \n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "1832698b-ca5c-4012-b188-8e3a2b07f6cd",
      "name": "AI Site Analysis",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -816,
        352
      ],
      "parameters": {
        "url": "https://api.openai.com/v1/chat/completions",
        "method": "POST",
        "options": {
          "timeout": 60000
        },
        "jsonBody": "={{ $json.requestBody }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "openAiApi"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "0f06e3f7-47f0-40f8-82c8-fca0354d6251",
      "name": "Prepare Upwork Request",
      "type": "n8n-nodes-base.code",
      "position": [
        224,
        240
      ],
      "parameters": {
        "jsCode": "const data = $input.first().json;\n\n// Gather all info for Upwork portfolio\nconst siteInfo = {\n  siteName: data.siteName,\n  url: data.url,\n  blocks_count: data.blocks_count,\n  blocks_list: data.blocks_list,\n  has_blog: data.has_blog,\n  languages: data.languages,\n  site_topic: data.site_topic,\n  specialization: data.specialization,\n  target_audience: data.target_audience,\n  key_services: data.key_services,\n  screenshotCount: data.screenshotCount\n};\n\nconst requestBody = {\n  model: 'gpt-4o-mini',\n  temperature: 0.4,\n  max_tokens: 800,\n  messages: [\n    {\n      role: 'system',\n      content: `You are an expert freelancer writing Upwork portfolio descriptions. Write compelling, professional content that highlights technical skills and business impact.\n\nRULES:\n1. Project title: Brief but descriptive (max 50 chars)\n2. Project description: Goals, solution, impact (max 600 chars)\n3. Skills: Exactly 5 relevant technical skills\n4. Write in first person as the developer who built this\n5. Respond ONLY in valid JSON, no markdown`\n    },\n    {\n      role: 'user',\n      content: `Based on this website analysis, create an Upwork portfolio project entry:\n\nWebsite: ${siteInfo.siteName} (${siteInfo.url})\nTopic: ${siteInfo.site_topic}\nSpecialization: ${siteInfo.specialization}\nTarget Audience: ${siteInfo.target_audience}\nKey Services: ${siteInfo.key_services}\nSections: ${siteInfo.blocks_count} (${siteInfo.blocks_list})\nHas Blog: ${siteInfo.has_blog}\nLanguages: ${siteInfo.languages}\nScreenshots: ${siteInfo.screenshotCount}\n\nGenerate JSON:\n{\n  \"project_title\": \"<max 50 chars, descriptive title>\",\n  \"your_role\": \"<max 100 chars, e.g. Full-Stack Developer, Lead Designer>\",\n  \"project_description\": \"<max 600 chars. Structure: 1) Project goals 2) My solution 3) Impact/results. Be specific about technologies used.>\",\n  \"skills\": [\"<skill1>\", \"<skill2>\", \"<skill3>\", \"<skill4>\", \"<skill5>\"]\n}`\n    }\n  ]\n};\n\nreturn [{ json: { ...data, upworkRequestBody: requestBody } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "e076f5a6-2a02-4e63-9d76-065c499a7eae",
      "name": "AI Generate Upwork",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        464,
        240
      ],
      "parameters": {
        "url": "https://api.openai.com/v1/chat/completions",
        "method": "POST",
        "options": {
          "timeout": 60000
        },
        "jsonBody": "={{ $json.upworkRequestBody }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "openAiApi"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "79fa1fce-c5be-42ee-91f2-7eeb10734245",
      "name": "Parse Upwork Response",
      "type": "n8n-nodes-base.code",
      "position": [
        704,
        240
      ],
      "parameters": {
        "jsCode": "const prevData = $('Prepare Upwork Request').first().json;\nconst response = $input.first().json;\nconst aiContent = response.choices[0].message.content;\n\n// Parse JSON\nlet upwork = {};\ntry {\n  const jsonMatch = aiContent.match(/\\{[\\s\\S]*\\}/);\n  if (jsonMatch) {\n    upwork = JSON.parse(jsonMatch[0]);\n  }\n} catch (e) {\n  upwork = {\n    project_title: 'Portfolio Website Development',\n    your_role: 'Full-Stack Developer',\n    project_description: 'Error parsing AI response',\n    skills: ['Web Development', 'JavaScript', 'CSS', 'HTML', 'Responsive Design']\n  };\n}\n\n// Ensure 5 skills\nlet skills = upwork.skills || [];\nif (typeof skills === 'string') skills = skills.split(',').map(s => s.trim());\nskills = skills.slice(0, 5);\nwhile (skills.length < 5) skills.push('Web Development');\n\n// Build result\nconst result = {\n  siteName: prevData.siteName,\n  url: prevData.url,\n  timestamp: prevData.timestamp,\n  blocks_count: prevData.blocks_count,\n  blocks_list: prevData.blocks_list,\n  has_blog: prevData.has_blog,\n  languages: prevData.languages,\n  site_topic: prevData.site_topic,\n  specialization: prevData.specialization,\n  target_audience: prevData.target_audience,\n  key_services: prevData.key_services,\n  screenshot_method: prevData.screenshot_method,\n  ai_found_anchors: prevData.ai_found_anchors,\n  anchors_checked: prevData.anchors_checked,\n  screenshots_attempted: prevData.screenshots_attempted,\n  screenshots_successful: prevData.screenshots_successful,\n  \n  // Upwork\n  upwork_title: (upwork.project_title || '').substring(0, 50),\n  upwork_role: (upwork.your_role || '').substring(0, 100),\n  upwork_description: (upwork.project_description || '').substring(0, 600),\n  upwork_skills: skills.join(', '),\n  \n  screenshots: prevData.screenshots,\n  screenshotCount: prevData.screenshotCount,\n  aiFoundAnchors: prevData.aiFoundAnchors,\n  allAnchors: prevData.allAnchors\n};\n\n// Copy dynamic screenshot columns\nObject.keys(prevData).forEach(key => {\n  if (key.startsWith('img_')) result[key] = prevData[key];\n});\n\nreturn [{ json: result }];"
      },
      "typeVersion": 2
    },
    {
      "id": "611d2b2a-744b-43b7-ac0e-e4e002711cbd",
      "name": "Portfolio Form",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -1552,
        352
      ],
      "parameters": {
        "options": {
          "respondWithOptions": {
            "values": {
              "formSubmittedText": "\u2705 Portfolio generation started! You will receive a Telegram notification when ready."
            }
          }
        },
        "formTitle": "Portfolio Screenshot Generator",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Website URL",
              "placeholder": "example.com or https://example.com",
              "requiredField": true
            }
          ]
        },
        "formDescription": "Enter website URL to analyze and generate portfolio screenshots with Upwork description."
      },
      "typeVersion": 2.2
    },
    {
      "id": "bc88d594-f7b5-4bf3-b8fd-b2daf12d2d94",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -240,
        352
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "bea11447-6ffb-4cde-bfaf-404ae5cd6e32",
      "name": "Wait 3s",
      "type": "n8n-nodes-base.wait",
      "position": [
        704,
        432
      ],
      "parameters": {
        "amount": 3
      },
      "typeVersion": 1.1
    }
  ],
  "active": false,
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "17e7a43e-9c95-4b5d-9580-d517fff5a40c",
  "connections": {
    "Wait 3s": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Portfolio Form": {
      "main": [
        [
          {
            "node": "Firecrawl Scrape",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [
          {
            "node": "Aggregate All Results",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Take Screenshot",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Take Screenshot": {
      "main": [
        [
          {
            "node": "Merge Screenshot Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Site Analysis": {
      "main": [
        [
          {
            "node": "Parse AI Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Firecrawl Scrape": {
      "main": [
        [
          {
            "node": "Prepare AI Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Response": {
      "main": [
        [
          {
            "node": "Site Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Generate Upwork": {
      "main": [
        [
          {
            "node": "Parse Upwork Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare AI Request": {
      "main": [
        [
          {
            "node": "AI Site Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Site Configuration": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate All Results": {
      "main": [
        [
          {
            "node": "Prepare Upwork Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Screenshot Data": {
      "main": [
        [
          {
            "node": "Upload to Google Drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Upwork Response": {
      "main": [
        [
          {
            "node": "Save to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save to Google Sheets": {
      "main": [
        [
          {
            "node": "Telegram Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Upwork Request": {
      "main": [
        [
          {
            "node": "AI Generate Upwork",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload to Google Drive": {
      "main": [
        [
          {
            "node": "Wait 3s",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}