{
  "id": "NY5tq9f8iYwpvPC6",
  "name": "Scrape_Upcoming_Events_using_bright_data",
  "tags": [],
  "nodes": [
    {
      "id": "5012cf3e-7fa6-4971-906b-760baeb51396",
      "name": "Trigger - Weekly Run",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -440,
        1160
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 8
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "8962483b-d095-4ade-bf9c-c3bfa5fe1831",
      "name": "Scrape event website using bright data",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -200,
        1160
      ],
      "parameters": {
        "url": "https://api.brightdata.com/request",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "zone",
              "value": "n8n_unblocker"
            },
            {
              "name": "url",
              "value": "https://www.eventbrite.com/d/online/technology--events/"
            },
            {
              "name": "country",
              "value": "us"
            },
            {
              "name": "format",
              "value": "raw"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "12d62c8b-047d-4890-85f7-c9a8097fcc2d",
      "name": "Parse HTML - Extract Event Cards",
      "type": "n8n-nodes-base.html",
      "position": [
        60,
        1160
      ],
      "parameters": {
        "options": {},
        "operation": "extractHtmlContent",
        "extractionValues": {
          "values": [
            {
              "key": "Title",
              "cssSelector": "h3",
              "returnArray": true
            },
            {
              "key": "Date and Time",
              "cssSelector": "div.Stack_root__1ksk7 > p:nth-of-type(1)",
              "returnArray": true
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "df0d0e23-1afe-4c74-b408-e5b3123c13a4",
      "name": "Format Event Data",
      "type": "n8n-nodes-base.code",
      "position": [
        280,
        1160
      ],
      "parameters": {
        "jsCode": "// Get the input data from the previous node\nconst inputData = items[0].json;\n\n// Access the arrays from the input object\nconst titles = inputData.Title;\nconst dates = inputData['Date and Time'];\n\n// Use a Set to track titles we've already processed to remove duplicates\nconst seenTitles = new Set();\nconst cleanedEvents = [];\n\n// Get the number of actual events (the input has duplicates)\nconst eventCount = dates.length;\n\nfor (let i = 0; i < eventCount; i++) {\n  const title = titles[i];\n  const date = dates[i];\n\n  // 1. Skip if the title is empty or we've already processed this event\n  if (!title || seenTitles.has(title)) {\n    continue;\n  }\n\n  // 2. Filter out irrelevant \"Trends\" items that start with a number (e.g., \"1. Tickets\")\n  if (/^\\d+\\.\\s/.test(title)) {\n    continue;\n  }\n  \n  // 3. Add the unique event to our results (without the URL)\n  cleanedEvents.push({\n    \"Title\": title,\n    \"Date and Time\": date\n  });\n\n  // 4. Mark this title as seen to avoid adding it again\n  seenTitles.add(title);\n}\n\n// Return the newly structured and cleaned array of event objects\nreturn cleanedEvents;"
      },
      "typeVersion": 2
    },
    {
      "id": "c58d917f-d756-45ad-a38a-b52254250154",
      "name": "Save to Google Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        580,
        1160
      ],
      "parameters": {
        "columns": {
          "value": {
            "Title": "={{ $json.Title }}",
            "Date & Time": "={{ $json['Date and Time'] }}"
          },
          "schema": [
            {
              "id": "Title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date & Time",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date & Time",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/157HRnzYP9IShr4jTQH7_y3r35cq2NVu0hv7kAW9kqn0/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "157HRnzYP9IShr4jTQH7_y3r35cq2NVu0hv7kAW9kqn0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/157HRnzYP9IShr4jTQH7_y3r35cq2NVu0hv7kAW9kqn0/edit?usp=drivesdk",
          "cachedResultName": "Events"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "ed7d1601-99b4-4191-b75c-cb7060a42bc5",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -480,
        460
      ],
      "parameters": {
        "color": 5,
        "width": 440,
        "height": 880,
        "content": "## \ud83e\udde9 SECTION 1: \ud83d\udd04 **Trigger + Scrape Website Content**\n\n### \ud83e\udded Purpose: Kickstart the automation & fetch data from the web\n\n---\n\n| \ud83d\udd27 **Nodes Involved** | \ud83d\udd39 `Schedule Trigger`<br>\ud83d\udd39 `HTTP Request (Bright Data Web Unlocker)`   |\n| --------------------- | ----------------------------------------------------------------------- |\n| \ud83d\udccc **Goal**           | Automatically fetch webinar details from Eventbrite (or any event site) |\n| \ud83d\udee0\ufe0f **How it works**  |                                                                         |\n\n1. **\u23f0 `Schedule Trigger`**\n   This node runs the entire workflow at a preset time (e.g., daily at 8 AM). It ensures your automation runs hands-free \u2014 no manual clicking.\n\n2. **\ud83c\udf10 `HTTP Request`**\n   This node uses **Bright Data's Web Unlocker** to bypass bot detection and scrape real event pages from protected websites like Eventbrite.\n   The **POST** request is sent to `https://api.brightdata.com/request`, which returns **raw HTML** of the event listings page.\n\n\ud83d\udca1 *Why Bright Data?*\nWebsites like Eventbrite use anti-bot systems. Bright Data safely navigates that with proxies + human-like browsing.\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "24726d95-f802-45e8-868d-575ce6453580",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "color": 6,
        "width": 420,
        "height": 1340,
        "content": "## \ud83e\udde9 SECTION 2: \ud83d\udd0d **Extract & Structure Event Data**\n\n### \ud83e\udde0 Purpose: Turn messy HTML into clean, usable event info\n\n---\n\n| \ud83d\udd27 **Nodes Involved** | \ud83d\udd39 `HTML Extract`<br>\ud83d\udd39 `Code Node`                      |\n| --------------------- | -------------------------------------------------------- |\n| \ud83d\udccc **Goal**           | Isolate event titles, times, and links from the raw HTML |\n| \ud83d\udee0\ufe0f **How it works**  |                                                          |\n\n1. **\ud83e\uddfe `HTML Extract`**\n   This node lets you select elements from the HTML using **CSS selectors**, just like a web developer would.\n   You extract:\n\n   * `.eds-event-card-content__title` \u2192 **Title**\n   * `.eds-event-card-content__sub-title` \u2192 **Date & Time**\n   * `.eds-event-card-content__action-link[href]` \u2192 **Event URL**\n\n2. **\ud83e\uddee `Code Node`**\n   Here, we **loop through the extracted data** and format it into clean JSON objects:\n\n   ```js\n   return items[0].json.titles.map((title, i) => {\n     return {\n       json: {\n         title,\n         date: items[0].json.dates[i],\n         link: items[0].json.links[i]\n       }\n     };\n   });\n   ```\n\n   Result: You now have a list of clean, structured webinar entries.\n\n\ud83d\udca1 *Why use a code node?*\nIt transforms raw scraped chunks into usable pieces ready for storage or integration.\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "834b6789-b284-49e0-86ba-a9d803fb52aa",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        460,
        540
      ],
      "parameters": {
        "color": 3,
        "width": 340,
        "height": 800,
        "content": "## \ud83e\udde9 SECTION 3: \ud83d\udcc4 **Store Events in Google Sheets**\n\n### \ud83d\udcbe Purpose: Save your scraped webinars into a spreadsheet\n\n---\n\n| \ud83d\udd27 **Node Involved** | \ud83d\udd39 `Google Sheets: Append`                      |\n| -------------------- | ----------------------------------------------- |\n| \ud83d\udccc **Goal**          | Automatically log each event into a spreadsheet |\n| \ud83d\udee0\ufe0f **How it works** |                                                 |\n\n* This node appends each structured event entry to a connected **Google Sheet**.\n* Each row includes:\n  \ud83d\udccc `Event Title` | \ud83d\udcc5 `Date & Time` | \ud83d\udd17 `URL`\n* You can filter, sort, or share this sheet as a **database of upcoming webinars**.\n\n\ud83d\udca1 *Why Google Sheets?*\nIt\u2019s universal, easy to search/filter, and sharable with a team. No special tool or database needed.\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "48ecec93-c46c-4398-ab14-bcfe617b0728",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2140,
        480
      ],
      "parameters": {
        "color": 4,
        "width": 1300,
        "height": 320,
        "content": "=======================================\n            WORKFLOW ASSISTANCE\n=======================================\nFor any questions or support, please contact:\n    Yaron@nofluff.online\n\nExplore more tips and tutorials here:\n   - YouTube: https://www.youtube.com/@YaronBeen/videos\n   - LinkedIn: https://www.linkedin.com/in/yaronbeen/\n=======================================\n"
      },
      "typeVersion": 1
    },
    {
      "id": "4bceecb8-56d2-47d7-8833-92f29af8f2fa",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2140,
        820
      ],
      "parameters": {
        "color": 4,
        "width": 1289,
        "height": 2298,
        "content": "### \ud83c\udf93 **Auto-Webinar Harvester**\n\n#### *Scrape Upcoming Events & Save to Google Sheets Automatically*\n\n> **Tagline:** \u201cYour always-on assistant for discovering industry webinars \u2014 no clicks required.\u201d\n> \ud83e\udde0\ud83d\udcbb\u2699\ufe0f\ud83d\udcc5\n\n---\n\n## \ud83e\udde9 SECTION 1: \ud83d\udd04 **Trigger + Scrape Website Content**\n\n### \ud83e\udded Purpose: Kickstart the automation & fetch data from the web\n\n---\n\n| \ud83d\udd27 **Nodes Involved** | \ud83d\udd39 `Schedule Trigger`<br>\ud83d\udd39 `HTTP Request (Bright Data Web Unlocker)`   |\n| --------------------- | ----------------------------------------------------------------------- |\n| \ud83d\udccc **Goal**           | Automatically fetch webinar details from Eventbrite (or any event site) |\n| \ud83d\udee0\ufe0f **How it works**  |                                                                         |\n\n1. **\u23f0 `Schedule Trigger`**\n   This node runs the entire workflow at a preset time (e.g., daily at 8 AM). It ensures your automation runs hands-free \u2014 no manual clicking.\n\n2. **\ud83c\udf10 `HTTP Request`**\n   This node uses **Bright Data's Web Unlocker** to bypass bot detection and scrape real event pages from protected websites like Eventbrite.\n   The **POST** request is sent to `https://api.brightdata.com/request`, which returns **raw HTML** of the event listings page.\n\n\ud83d\udca1 *Why Bright Data?*\nWebsites like Eventbrite use anti-bot systems. Bright Data safely navigates that with proxies + human-like browsing.\n\n---\n\n## \ud83e\udde9 SECTION 2: \ud83d\udd0d **Extract & Structure Event Data**\n\n### \ud83e\udde0 Purpose: Turn messy HTML into clean, usable event info\n\n---\n\n| \ud83d\udd27 **Nodes Involved** | \ud83d\udd39 `HTML Extract`<br>\ud83d\udd39 `Code Node`                      |\n| --------------------- | -------------------------------------------------------- |\n| \ud83d\udccc **Goal**           | Isolate event titles, times, and links from the raw HTML |\n| \ud83d\udee0\ufe0f **How it works**  |                                                          |\n\n1. **\ud83e\uddfe `HTML Extract`**\n   This node lets you select elements from the HTML using **CSS selectors**, just like a web developer would.\n   You extract:\n\n   * `.eds-event-card-content__title` \u2192 **Title**\n   * `.eds-event-card-content__sub-title` \u2192 **Date & Time**\n   * `.eds-event-card-content__action-link[href]` \u2192 **Event URL**\n\n2. **\ud83e\uddee `Code Node`**\n   Here, we **loop through the extracted data** and format it into clean JSON objects:\n\n   ```js\n   return items[0].json.titles.map((title, i) => {\n     return {\n       json: {\n         title,\n         date: items[0].json.dates[i],\n         link: items[0].json.links[i]\n       }\n     };\n   });\n   ```\n\n   Result: You now have a list of clean, structured webinar entries.\n\n\ud83d\udca1 *Why use a code node?*\nIt transforms raw scraped chunks into usable pieces ready for storage or integration.\n\n---\n\n## \ud83e\udde9 SECTION 3: \ud83d\udcc4 **Store Events in Google Sheets**\n\n### \ud83d\udcbe Purpose: Save your scraped webinars into a spreadsheet\n\n---\n\n| \ud83d\udd27 **Node Involved** | \ud83d\udd39 `Google Sheets: Append`                      |\n| -------------------- | ----------------------------------------------- |\n| \ud83d\udccc **Goal**          | Automatically log each event into a spreadsheet |\n| \ud83d\udee0\ufe0f **How it works** |                                                 |\n\n* This node appends each structured event entry to a connected **Google Sheet**.\n* Each row includes:\n  \ud83d\udccc `Event Title` | \ud83d\udcc5 `Date & Time` | \ud83d\udd17 `URL`\n* You can filter, sort, or share this sheet as a **database of upcoming webinars**.\n\n\ud83d\udca1 *Why Google Sheets?*\nIt\u2019s universal, easy to search/filter, and sharable with a team. No special tool or database needed.\n\n---\n\n## \ud83c\udfaf Why This Workflow Is Powerful (Even for Beginners)\n\n| \ud83d\ude80 Benefit                        | \u2705 How It Helps You                                                      |\n| --------------------------------- | ----------------------------------------------------------------------- |\n| Zero manual scraping              | Just set a schedule and forget \u2014 everything updates on its own          |\n| Works with hard-to-scrape sites   | Bright Data + Web Unlocker beats CAPTCHAs and blocks                    |\n| Clean, structured output          | Easy to use data for marketing, lead gen, or syncing to Google Calendar |\n| Google Sheet as a source of truth | Everyone on your team can access and use the data                       |\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "197d2ec1-609e-4905-8671-e41ed6ceb92f",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        900,
        540
      ],
      "parameters": {
        "color": 7,
        "width": 380,
        "height": 240,
        "content": "## I\u2019ll receive a tiny commission if you join Bright Data through this link\u2014thanks for fueling more free content!\n\n### https://get.brightdata.com/1tndi4600b25"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "b59d50da-e665-47a2-975b-432971342df5",
  "connections": {
    "Format Event Data": {
      "main": [
        [
          {
            "node": "Save to Google Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Trigger - Weekly Run": {
      "main": [
        [
          {
            "node": "Scrape event website using bright data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse HTML - Extract Event Cards": {
      "main": [
        [
          {
            "node": "Format Event Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Scrape event website using bright data": {
      "main": [
        [
          {
            "node": "Parse HTML - Extract Event Cards",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}