{
  "name": "Automated daily stock market report with Bright Data, GPT-4.1, Airtable/Gmail",
  "nodes": [
    {
      "id": "0a0def72-9c6f-43fb-8db5-268da98f82dd",
      "name": "Simple Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        3904,
        656
      ]
    },
    {
      "id": "e13cbed2-0837-4b4b-82b4-49c61510dff5",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        3760,
        656
      ]
    },
    {
      "id": "cf744498-62bf-4e6a-8570-dda7fea35fe5",
      "name": "Daily Run Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        208,
        576
      ]
    },
    {
      "id": "d0ee4823-0536-415e-8fa9-861c1701665d",
      "name": "Set Stock List",
      "type": "n8n-nodes-base.set",
      "position": [
        528,
        576
      ]
    },
    {
      "id": "88b7e912-af0c-4527-baa3-4f8cf0b072d1",
      "name": "Split Stocks",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        816,
        576
      ]
    },
    {
      "id": "2aab292f-0287-4da6-86ee-83c5a9aee30a",
      "name": "Prepare Stock Keyword",
      "type": "n8n-nodes-base.set",
      "position": [
        1104,
        576
      ]
    },
    {
      "id": "13f81727-f586-4fb6-be73-4880c9efd165",
      "name": "Bright Data Scraper",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1456,
        576
      ]
    },
    {
      "id": "2cc8d35f-f255-4adc-b1d7-7f9ab34dde66",
      "name": "Check Scraper Progress",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1936,
        576
      ]
    },
    {
      "id": "eb6ab86c-3e8b-4dc6-8d70-3346531905fa",
      "name": "Scraper Status Switch",
      "type": "n8n-nodes-base.switch",
      "position": [
        2368,
        576
      ]
    },
    {
      "id": "e27afbc7-8cae-44b6-b506-474bb2692f08",
      "name": "Wait for Data",
      "type": "n8n-nodes-base.wait",
      "position": [
        2480,
        1088
      ]
    },
    {
      "id": "5e828381-8268-4114-b16c-a60c4ca23e80",
      "name": "Fetch Scraper Results",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2848,
        560
      ]
    },
    {
      "id": "4c2826ee-30bb-4438-a531-c370edbe2103",
      "name": "Aggregate Stock Data",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        3312,
        560
      ]
    },
    {
      "id": "ef5165a4-0452-4b20-b2fa-994429f3bc5b",
      "name": "Generate Daily Summary (AI)",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        3792,
        416
      ]
    },
    {
      "id": "3f953ffd-4faa-4cd5-bd3a-b3a6d021eebf",
      "name": "Send Report via Gmail",
      "type": "n8n-nodes-base.gmailTool",
      "position": [
        4064,
        624
      ]
    },
    {
      "id": "ae4e0ac6-1afb-463a-a273-7dac2dc975e3",
      "name": "Save to Airtable (Daily Stocks)",
      "type": "n8n-nodes-base.airtable",
      "position": [
        2944,
        -288
      ]
    },
    {
      "id": "ae35f4c3-6d12-440e-9cf5-c465a7c7d3ee",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        144,
        160
      ],
      "parameters": {
        "width": 288,
        "height": 592,
        "content": "## ⏰ Daily Run Trigger (Schedule Trigger)\n\n### Purpose\nStarts the workflow automatically at fixed intervals.  \nThis ensures the stock digest runs daily without manual input.\n\n### Parameters\n- **Trigge"
      }
    },
    {
      "id": "faa08484-c83e-49dd-bc8a-c29a0c9a95ce",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        432,
        96
      ],
      "parameters": {
        "width": 288,
        "height": 656,
        "content": "## 📝 Set Stock List (Set Node – SAMPLE DATA)\n\n### Purpose\nDefines the list of stocks to track.  \nThis acts as the **seed data** for the scraping step.\n\n### Parameters\n- **Values to Set**: `Fixed JSON`"
      }
    },
    {
      "id": "57ff48b7-fb7a-4c8e-b122-ff8878a46a97",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        720,
        208
      ],
      "parameters": {
        "width": 288,
        "height": 544,
        "content": "## 🔀 Split Stocks (Split Out)\n\n### Purpose\nTakes the stock list (array) and splits it into **individual items**,  \nso each stock can be processed separately in the workflow.\n\n### Parameters\n- **Operat"
      }
    },
    {
      "id": "04a19b0a-1d0f-4fc3-9b5a-a1dbe39daf8e",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1008,
        160
      ],
      "parameters": {
        "width": 288,
        "height": 592,
        "content": "## 🏷 Prepare Stock Keyword (Set Node)\n\n### Purpose\nAdds a `keyword` field for each stock item.  \nThis keyword is used by Bright Data’s scraper to identify which stock to fetch.\n\n### Parameters\n- **Val"
      }
    },
    {
      "id": "a24344d1-ef9c-4333-83b8-b8e1055667ed",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1296,
        160
      ],
      "parameters": {
        "width": 480,
        "height": 592,
        "content": "## 🕸 Bright Data Scraper (HTTP Request)\n\n### Purpose\nSends a request to **Bright Data API** to launch a stock scraping job.  \nIt returns a `snapshot_id` used later to fetch results.\n\n### Parameters\n- "
      }
    },
    {
      "id": "608e6709-2b53-4b85-8a6f-04339d4f7029",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1776,
        160
      ],
      "parameters": {
        "width": 432,
        "height": 592,
        "content": "## 🔄 Check Scraper Progress (HTTP Request)\n\n### Purpose\nChecks if the Bright Data scraping job is finished or still running.  \nLoops until results are ready.\n\n### Parameters\n- **Method**: `GET`\n- **En"
      }
    },
    {
      "id": "8e82b0a8-1682-4b7f-b12d-a5569ac1e70a",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2208,
        752
      ],
      "parameters": {
        "width": 432,
        "height": 512,
        "content": "## ⏳ Wait for Data (Wait Node)\n\n### Purpose\nPauses the workflow for a fixed time before checking the scraper progress again.  \nThis prevents API rate limits and ensures Bright Data has time to finish "
      }
    },
    {
      "id": "6350cebc-4794-49df-a637-a982ab96a7fe",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2208,
        160
      ],
      "parameters": {
        "width": 432,
        "height": 592,
        "content": "## 🔀 Scraper Status Switch (Switch Node)\n\n### Purpose\nRoutes the workflow based on the scraper job status.  \nIf the status is `running`, it loops back to **Wait for Data**.  \nIf the status is `ready`,"
      }
    },
    {
      "id": "93becc4b-e2ea-42e8-8eca-9e9e0f79d0c8",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2640,
        160
      ],
      "parameters": {
        "width": 512,
        "height": 608,
        "content": "## 📥 Fetch Scraper Results (HTTP Request)\n\n### Purpose\nRetrieves the completed stock market data from Bright Data once the job is finished.  \nThe results are returned as JSON and include price, change"
      }
    },
    {
      "id": "867cf6ea-2a5f-45fa-98a7-68d194df1dfc",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3152,
        112
      ],
      "parameters": {
        "width": 512,
        "height": 656,
        "content": "## 📊 Aggregate Stock Data (Aggregate Node)\n\n### Purpose\nMerges the stock data from multiple items (each ticker) into one consolidated dataset.  \nThis is used as input for the AI to generate a summary."
      }
    },
    {
      "id": "8e741c22-987f-4f7a-9e2b-d1d2158ec074",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3664,
        -240
      ],
      "parameters": {
        "width": 880,
        "height": 1008,
        "content": "## 🤖 Generate Daily Summary (AI Node – OpenAI/Gemini)\n\n### Purpose\nUses an AI model to analyze the aggregated stock data.  \nGenerates an HTML-formatted email with trends, top movers, insights, and upc"
      }
    },
    {
      "id": "e03b89d9-d530-4c7f-8b9e-b85a39a1fa11",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2784,
        -752
      ],
      "parameters": {
        "width": 512,
        "height": 656,
        "content": "## 🗂 Save to Airtable (Airtable – Create Record)\n\n### Purpose\nStores each day’s stock data in Airtable for historical tracking.  \nActs as a database of all reports.\n\n### Parameters\n- **Operation**: `C"
      }
    }
  ],
  "connections": {
    "Split Stocks": {
      "main": [
        [
          {
            "node": "Prepare Stock Keyword",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "Generate Daily Summary (AI)",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Wait for Data": {
      "main": [
        [
          {
            "node": "Check Scraper Progress",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Stock List": {
      "main": [
        [
          {
            "node": "Split Stocks",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily Run Trigger": {
      "main": [
        [
          {
            "node": "Set Stock List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Daily Summary (AI)",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Bright Data Scraper": {
      "main": [
        [
          {
            "node": "Check Scraper Progress",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Stock Data": {
      "main": [
        [
          {
            "node": "Generate Daily Summary (AI)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Scraper Results": {
      "main": [
        [
          {
            "node": "Aggregate Stock Data",
            "type": "main",
            "index": 0
          },
          {
            "node": "Save to Airtable (Daily Stocks)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Stock Keyword": {
      "main": [
        [
          {
            "node": "Bright Data Scraper",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Scraper Status Switch": {
      "main": [
        [
          {
            "node": "Fetch Scraper Results",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait for Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Report via Gmail": {
      "ai_tool": [
        [
          {
            "node": "Generate Daily Summary (AI)",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Check Scraper Progress": {
      "main": [
        [
          {
            "node": "Scraper Status Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Daily Summary (AI)": {
      "main": [
        []
      ]
    }
  }
}