AutomationFlowsAI & RAG › Automated Daily Stock Market Report with Bright Data, Gpt-4.1, Airtable/gmail

Automated Daily Stock Market Report with Bright Data, Gpt-4.1, Airtable/gmail

ByBaptiste Fort @baptistefort on n8n.io

Wake up to a clean, analyst-style stock digest in your inbox—top gainers/losers, a readable performance table, 3–5 insights, and upcoming events—no spreadsheets, no manual scraping, no copy-paste. This article explains, step by step, how to build a robust, daily, end-to-end…

Cron / scheduled trigger★★★★☆ complexityAI-powered27 nodesMemory Buffer WindowOpenAI ChatHTTP RequestAgentGmail ToolAirtable
AI & RAG Trigger: Cron / scheduled Nodes: 27 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #8724 — we link there as the canonical source.

This workflow follows the Agent → Airtable recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "dnw1cvGPaYS9dCog",
  "meta": {
    "templateId": "5305",
    "templateCredsSetupCompleted": true
  },
  "name": "Automated Daily Stock Market Report with Bright Data, GPT, Airtable, and Gmail",
  "tags": [],
  "nodes": [
    {
      "id": "0a0def72-9c6f-43fb-8db5-268da98f82dd",
      "name": "Simple Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        3904,
        656
      ],
      "parameters": {},
      "typeVersion": 1.3
    },
    {
      "id": "e13cbed2-0837-4b4b-82b4-49c61510dff5",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        3760,
        656
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "cf744498-62bf-4e6a-8570-dda7fea35fe5",
      "name": "Daily Run Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        208,
        576
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "d0ee4823-0536-415e-8fa9-861c1701665d",
      "name": "Set Stock List",
      "type": "n8n-nodes-base.set",
      "position": [
        528,
        576
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "8d1bd0c8-37bf-4028-a20c-ac214ec06d7b",
              "name": "json",
              "type": "array",
              "value": "=[\n  {\n    \"ticker\": \"SHEL\",\n    \"name\": \"Shell plc\",\n    \"market_cap\": \"\u2248 $250B\"\n  },\n  {\n    \"ticker\": \"NESN.SW\",\n    \"name\": \"Nestl\u00e9 S.A.\",\n    \"market_cap\": \"\u2248 $320B\"\n  },\n  {\n    \"ticker\": \"SAP\",\n    \"name\": \"SAP SE\",\n    \"market_cap\": \"\u2248 $210B\"\n  },\n  {\n    \"ticker\": \"ASML\",\n    \"name\": \"ASML Holding N.V.\",\n    \"market_cap\": \"\u2248 $470B\"\n  },\n  {\n    \"ticker\": \"SONY\",\n    \"name\": \"Sony Group Corporation\",\n    \"market_cap\": \"\u2248 $110B\"\n  },\n  {\n    \"ticker\": \"TCEHY\",\n    \"name\": \"Tencent Holdings Ltd.\",\n    \"market_cap\": \"\u2248 $420B\"\n  },\n  {\n    \"ticker\": \"BABA\",\n    \"name\": \"Alibaba Group Holding Ltd.\",\n    \"market_cap\": \"\u2248 $190B\"\n  },\n  {\n    \"ticker\": \"7203.T\",\n    \"name\": \"Toyota Motor Corporation\",\n    \"market_cap\": \"\u2248 $270B\"\n  },\n  {\n    \"ticker\": \"RHHBY\",\n    \"name\": \"Roche Holding AG\",\n    \"market_cap\": \"\u2248 $210B\"\n  },\n  {\n    \"ticker\": \"NFLX\",\n    \"name\": \"Netflix Inc.\",\n    \"market_cap\": \"\u2248 $260B\"\n  }\n]\n"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "88b7e912-af0c-4527-baa3-4f8cf0b072d1",
      "name": "Split Stocks",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        816,
        576
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "json"
      },
      "typeVersion": 1
    },
    {
      "id": "2aab292f-0287-4da6-86ee-83c5a9aee30a",
      "name": "Prepare Stock Keyword",
      "type": "n8n-nodes-base.set",
      "position": [
        1104,
        576
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "8d9e80d9-16dd-4658-928f-d94735209bfd",
              "name": "keyword",
              "type": "string",
              "value": "={{ $json.ticker }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "13f81727-f586-4fb6-be73-4880c9efd165",
      "name": "Bright Data Scraper",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1456,
        576
      ],
      "parameters": {
        "url": "https://api.brightdata.com/datasets/v3/trigger",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ $('Prepare Stock Keyword').all().map(item => item.json)}}",
        "sendBody": true,
        "sendQuery": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "queryParameters": {
          "parameters": [
            {
              "name": "dataset_id",
              "value": "gd_lmrpz3vxmz972ghd7"
            },
            {
              "name": "include_errors",
              "value": "true"
            },
            {
              "name": "type",
              "value": "discover_new"
            },
            {
              "name": "discover_by",
              "value": "keyword"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer YOUR_TOKEN_HERE"
            }
          ]
        }
      },
      "executeOnce": true,
      "typeVersion": 4.2
    },
    {
      "id": "2cc8d35f-f255-4adc-b1d7-7f9ab34dde66",
      "name": "Check Scraper Progress",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1936,
        576
      ],
      "parameters": {
        "url": "=https://api.brightdata.com/datasets/v3/progress/{{ $json.snapshot_id }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "eb6ab86c-3e8b-4dc6-8d70-3346531905fa",
      "name": "Scraper Status Switch",
      "type": "n8n-nodes-base.switch",
      "position": [
        2368,
        576
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "ready",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "4712e222-2bad-4d91-be87-ab0e0693c0c6",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.status }}",
                    "rightValue": "ready"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "running",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "9a473960-6ba5-4f1b-afc6-396348bd338d",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.status }}",
                    "rightValue": "=running"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "e27afbc7-8cae-44b6-b506-474bb2692f08",
      "name": "Wait for Data",
      "type": "n8n-nodes-base.wait",
      "position": [
        2480,
        1088
      ],
      "parameters": {
        "amount": 20
      },
      "typeVersion": 1.1
    },
    {
      "id": "5e828381-8268-4114-b16c-a60c4ca23e80",
      "name": "Fetch Scraper Results",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2848,
        560
      ],
      "parameters": {
        "url": "=https://api.brightdata.com/datasets/v3/snapshot/{{ $json.snapshot_id }}",
        "options": {},
        "sendQuery": true,
        "sendHeaders": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "format",
              "value": "json"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "4c2826ee-30bb-4438-a531-c370edbe2103",
      "name": "Aggregate Stock Data",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        3312,
        560
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "ef5165a4-0452-4b20-b2fa-994429f3bc5b",
      "name": "Generate Daily Summary (AI)",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        3792,
        416
      ],
      "parameters": {
        "text": "=## \ud83c\udfaf ROLE\nYou are an **AI-powered financial analyst agent** integrated inside an n8n workflow.  \nYour responsibilities are to:  \n- Parse incoming JSON datasets of U.S. equities (typically top 10 by market cap).  \n- Detect **market trends, anomalies, and investor-relevant signals** from the data.  \n- Convert raw JSON into a **professionally written HTML email digest**, with clear structure, styling, and actionable insights.  \n- Act as if you were a **senior analyst writing for institutional investors**, keeping the tone sharp, concise, and technical.  \n- Output only **clean HTML content** ready for use inside an email body (no markdown, no plaintext, no metadata).  \n\n---\n\n## \ud83d\udce5 INPUT FORMAT (JSON)\n\nYou will receive daily input structured like this:\n\n```\nThe day and date today is {{ $now.format('cccc yyyy-MM-dd t') }}\n\nHere is today\u2019s stock market data: =\n\n{{ $json.data.toJsonString() }}\n```\n\nWhere each stock object may contain:  \n- `ticker` \u2192 Stock symbol (e.g., AAPL, NVDA)  \n- `name` \u2192 Company name (e.g., Apple Inc.)  \n- `market_cap` \u2192 Market capitalization  \n- `price` \u2192 Current price or last close price  \n- `change` \u2192 Daily percentage change (can be positive or negative)  \n- `sentiment` \u2192 Qualitative sentiment (optional: \ud83d\udfe2 Positive, \ud83d\udfe1 Neutral, \ud83d\udd34 Negative)  \n- `news` \u2192 Associated news snippets (optional)  \n\n---\n\n## \u2705 TASKS\n\n1. **Market Context**  \n   - Start with a headline summary of the day (general trend: bullish, bearish, or mixed).  \n   - Mention notable **macro events** or **sector-specific highlights** if derivable from input.  \n\n2. **Top Movers**  \n   - Identify and highlight the **2 biggest gainers** and **2 biggest losers**.  \n   - Give context if available (based on percentage change or attached news).  \n\n3. **Stock Data Table**  \n   - Generate a professional `<table>` with the following columns:  \n     - Ticker  \n     - Company Name  \n     - Daily % Change (with \u2191/\u2193 and colored formatting)  \n     - Market Cap  \n     - Sentiment Icon (\ud83d\udfe2 \ud83d\udfe1 \ud83d\udd34)  \n\n4. **Insights Section**  \n   - Provide **3\u20135 key takeaways**:  \n     - Example: \u201cTech continues outperforming with NVDA +X% and AAPL +Y%\u201d  \n     - Highlight any **sector rotation, unusual volatility, or outlier performance**.  \n     - Mention if the **trend diverges** from broader market sentiment.  \n\n5. **Upcoming Catalysts**  \n   - If `news` mentions future events (earnings calls, product launches, Fed meetings), list them in a dedicated section.  \n   - If no events are available, skip gracefully.  \n\n6. **Professional Formatting**  \n   - Use inline CSS to ensure email compatibility.  \n   - Use clear hierarchy:  \n     - `<h2>` for main title (\u201cDaily U.S. Stock Market Digest \u2013 {Date}\u201d)  \n     - `<h3>` for sub-sections (e.g., \u201cTop Gainers & Losers\u201d, \u201cMarket Insights\u201d, \u201cUpcoming Events\u201d)  \n     - `<ul>` for bullet point insights  \n     - `<table>` for stock performance data  \n   - Add color indicators for sentiment:  \n     - \ud83d\udfe2 Positive = green text  \n     - \ud83d\udfe1 Neutral = gold text  \n     - \ud83d\udd34 Negative = red text  \n\n---\n\n## \u2728 OUTPUT FORMAT (HTML Only)\n\n- Produce **only** HTML, no markdown.  \n- Must be **email-client safe**:  \n  - Inline styles only (no external CSS).  \n  - Avoid JavaScript or advanced CSS.  \n- Structure example:  \n\n```html\n<h2>Daily U.S. Stock Market Digest \u2013 Thursday 2025-09-18</h2>\n\n<h3>\ud83d\udcc8 Top Gainers & Losers</h3>\n<ul>\n  <li>NVDA +4.2% \ud83d\udfe2 \u2014 driven by strong chip demand</li>\n  <li>TSLA -3.1% \ud83d\udd34 \u2014 impacted by regulatory concerns</li>\n</ul>\n\n<h3>\ud83d\udcca Market Overview</h3>\n<table style=\"border-collapse:collapse;width:100%;\">\n  <tr style=\"background:#f2f2f2;\">\n    <th>Ticker</th><th>Company</th><th>Change %</th><th>Market Cap</th><th>Sentiment</th>\n  </tr>\n  <tr>\n    <td>NVDA</td><td>NVIDIA Corporation</td><td style=\"color:green;\">+4.2%</td><td>$3.6T</td><td>\ud83d\udfe2</td>\n  </tr>\n  <tr>\n    <td>TSLA</td><td>Tesla Inc.</td><td style=\"color:red;\">-3.1%</td><td>$830B</td><td>\ud83d\udd34</td>\n  </tr>\n</table>\n\n<h3>\ud83d\udca1 Key Insights</h3>\n<ul>\n  <li>Tech leads with NVDA and MSFT posting strong gains.</li>\n  <li>Healthcare sector showed weakness with JNJ down 2%.</li>\n  <li>Overall sentiment remained mixed ahead of Fed decision.</li>\n</ul>\n\n<h3>\ud83d\udcc5 Upcoming Events</h3>\n<ul>\n  <li>Fed interest rate decision \u2014 Sept 20</li>\n  <li>Apple iPhone launch event \u2014 Sept 21</li>\n</ul>\n\n<footer style=\"margin-top:20px;font-size:12px;color:#888;\">\n  Generated automatically by your AI-powered stock monitor.\n</footer>\n```\n\n---\n\n## \u26a0\ufe0f CONSTRAINTS\n\n- Do **not** include email subject or headers.  \n- Do **not** output explanations, reasoning, or markdown.  \n- Always output **clean HTML only**.  \n- Ensure the HTML is **ready-to-send** in an email body without manual edits.  \n- If data is missing, skip the section gracefully without placeholders.  \n\n---\n\n## \ud83d\udcec GOAL\n\nDeliver a **polished, mobile-friendly, and insight-rich stock market digest email**.  \nFinal output must require zero manual edits, look professional for finance users, and be directly usable in n8n\u2019s Gmail/SMTP nodes.  \n",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 2
    },
    {
      "id": "3f953ffd-4faa-4cd5-bd3a-b3a6d021eebf",
      "name": "Send Report via Gmail",
      "type": "n8n-nodes-base.gmailTool",
      "position": [
        4064,
        624
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "={{ $('Generate Daily Summary (AI)').first().json.output }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "=Daily Stock Market Digest "
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "ae4e0ac6-1afb-463a-a273-7dac2dc975e3",
      "name": "Save to Airtable (Daily Stocks)",
      "type": "n8n-nodes-base.airtable",
      "position": [
        2944,
        -288
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appqPdjbR45flhdgT",
          "cachedResultUrl": "https://airtable.com/appqPdjbR45flhdgT",
          "cachedResultName": "Untitled Base"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tblvIkbZriGaCrfzP",
          "cachedResultUrl": "https://airtable.com/appqPdjbR45flhdgT/tblvIkbZriGaCrfzP",
          "cachedResultName": "Daily Stocks"
        },
        "columns": {
          "value": {
            "Price": "={{ $json.price }}",
            "Ticker": "={{ $json.ticker }}",
            "Company": "={{ $json.name }}",
            "Change %": "={{ $json.change }}",
            "Sentiment": "={{ $json.sentiment }}",
            "Market Cap": "={{ $json.market_cap }}"
          },
          "schema": [
            {
              "id": "Ticker",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Ticker",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Company",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Market Cap",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Market Cap",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Price",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Price",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Change %",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Change %",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Sentiment",
              "type": "options",
              "display": true,
              "options": [
                {
                  "name": "\ud83d\udfe2 Positive",
                  "value": "\ud83d\udfe2 Positive"
                },
                {
                  "name": "\ud83d\udfe1 Neutral",
                  "value": "\ud83d\udfe1 Neutral"
                },
                {
                  "name": "\ud83d\udd34 Negative",
                  "value": "\ud83d\udd34 Negative"
                }
              ],
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Sentiment",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "dateTime",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "create"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "ae35f4c3-6d12-440e-9cf5-c465a7c7d3ee",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        144,
        160
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 592,
        "content": "## \u23f0 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- **Trigger Type**: `Time Interval` or `Cron`\n- **Every X**: `1 Day` (or custom interval)\n- **Timezone**: `UTC` or your local timezone\n- **Start Time**: optional (e.g., `09:00`)"
      },
      "typeVersion": 1
    },
    {
      "id": "faa08484-c83e-49dd-bc8a-c29a0c9a95ce",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        432,
        96
      ],
      "parameters": {
        "color": 6,
        "width": 288,
        "height": 656,
        "content": "## \ud83d\udcdd Set Stock List (Set Node \u2013 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`\n- **Keep Only Set**: `true`\n- **JSON Example**:\n  ```json\n  [\n    { \"ticker\": \"AAPL\", \"name\": \"Apple Inc.\", \"market_cap\": \"\u2248 $3.0T\" },\n    { \"ticker\": \"MSFT\", \"name\": \"Microsoft Corporation\", \"market_cap\": \"\u2248 $3.6T\" }\n  ]"
      },
      "typeVersion": 1
    },
    {
      "id": "57ff48b7-fb7a-4c8e-b122-ff8878a46a97",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        720,
        208
      ],
      "parameters": {
        "color": 4,
        "width": 288,
        "height": 544,
        "content": "## \ud83d\udd00 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- **Operation**: `Split Out Items`\n- **Field to Split**: `stocks[]` (array field from Set node)\n"
      },
      "typeVersion": 1
    },
    {
      "id": "04a19b0a-1d0f-4fc3-9b5a-a1dbe39daf8e",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1008,
        160
      ],
      "parameters": {
        "color": 6,
        "width": 288,
        "height": 592,
        "content": "## \ud83c\udff7 Prepare Stock Keyword (Set Node)\n\n### Purpose\nAdds a `keyword` field for each stock item.  \nThis keyword is used by Bright Data\u2019s scraper to identify which stock to fetch.\n\n### Parameters\n- **Values to Set**: `Add Field`\n- **Field Name**: `keyword`\n- **Value**: `{{ $json[\"ticker\"] }}`"
      },
      "typeVersion": 1
    },
    {
      "id": "a24344d1-ef9c-4333-83b8-b8e1055667ed",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1296,
        160
      ],
      "parameters": {
        "color": 2,
        "width": 480,
        "height": 592,
        "content": "## \ud83d\udd78 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- **Method**: `POST`\n- **Endpoint**: `https://api.brightdata.com/datasets/v1/trigger`\n- **Authentication**: `API Token`  \n  (Header: `Authorization: Bearer <token>`)\n- **Body Fields**:\n  - `dataset_id`: Bright Data dataset ID\n  - `discover_by`: `keyword`\n  - `keyword`: stock ticker\n"
      },
      "typeVersion": 1
    },
    {
      "id": "608e6709-2b53-4b85-8a6f-04339d4f7029",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1776,
        160
      ],
      "parameters": {
        "color": 4,
        "width": 432,
        "height": 592,
        "content": "## \ud83d\udd04 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- **Endpoint**: `https://api.brightdata.com/datasets/v1/snapshots/{snapshot_id}`\n- **Authentication**: `API Token`\n- **Query Params**:\n  - `snapshot_id`: returned from Bright Data Scraper\n  - `status`: current job status (`running`, `ready`)"
      },
      "typeVersion": 1
    },
    {
      "id": "8e82b0a8-1682-4b7f-b12d-a5569ac1e70a",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2208,
        752
      ],
      "parameters": {
        "color": 6,
        "width": 432,
        "height": 512,
        "content": "## \u23f3 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 the job.\n\n### Parameters\n- **Mode**: `Wait a fixed amount of time`\n- **Time**: e.g., `30 seconds`"
      },
      "typeVersion": 1
    },
    {
      "id": "6350cebc-4794-49df-a637-a982ab96a7fe",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2208,
        160
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 592,
        "content": "## \ud83d\udd00 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`, it continues to fetch the snapshot.\n\n### Parameters\n- **Value to Check**: `status`\n- **Rules**:\n  - Equals `running` \u2192 go to Wait\n  - Equals `ready` \u2192 go to Fetch Scraper Results\n"
      },
      "typeVersion": 1
    },
    {
      "id": "93becc4b-e2ea-42e8-8eca-9e9e0f79d0c8",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2640,
        160
      ],
      "parameters": {
        "width": 512,
        "height": 608,
        "content": "## \ud83d\udce5 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 %, sentiment, and more.\n\n### Parameters\n- **Method**: `GET`\n- **Endpoint**: `https://api.brightdata.com/datasets/v1/snapshots/{snapshot_id}/data`\n- **Authentication**: `API Token`\n- **Query Params**:\n  - `snapshot_id`: ID from Bright Data Scraper\n  - `format`: `json`"
      },
      "typeVersion": 1
    },
    {
      "id": "867cf6ea-2a5f-45fa-98a7-68d194df1dfc",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3152,
        112
      ],
      "parameters": {
        "color": 3,
        "width": 512,
        "height": 656,
        "content": "## \ud83d\udcca 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.\n\n### Parameters\n- **Mode**: `Aggregate`\n- **Fields to Include**:  \n  - `ticker`  \n  - `name`  \n  - `price`  \n  - `change`  \n  - `sentiment`  \n- **Output**: Single JSON object with all stock records\n"
      },
      "typeVersion": 1
    },
    {
      "id": "8e741c22-987f-4f7a-9e2b-d1d2158ec074",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3664,
        -240
      ],
      "parameters": {
        "color": 6,
        "width": 880,
        "height": 1008,
        "content": "## \ud83e\udd16 Generate Daily Summary (AI Node \u2013 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 upcoming events.\n\n### Parameters\n- **Model**: `gemini-2.0-flash-lite` (or `gpt-4.1` if using OpenAI)\n- **Input**: JSON data from Aggregate node\n- **Prompt**:  \n  - Analyze market trends  \n  - Identify top gainers/losers  \n  - Generate stock performance table  \n  - Add 3\u20135 insights  \n  - Format everything as **HTML email body**\n\n## \ud83d\udce7 Send Report via Gmail (Gmail Node)\n\n### Purpose\nDelivers the generated HTML stock market digest directly to the recipient\u2019s inbox.  \nThis is the final step that sends the daily summary email.\n\n### Parameters\n- **Operation**: `Send Email`\n- **Send To**: recipient email (e.g., `investor@domain.com`)\n- **Subject**:   \n"
      },
      "typeVersion": 1
    },
    {
      "id": "e03b89d9-d530-4c7f-8b9e-b85a39a1fa11",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2784,
        -752
      ],
      "parameters": {
        "color": 6,
        "width": 512,
        "height": 656,
        "content": "## \ud83d\uddc2 Save to Airtable (Airtable \u2013 Create Record)\n\n### Purpose\nStores each day\u2019s stock data in Airtable for historical tracking.  \nActs as a database of all reports.\n\n### Parameters\n- **Operation**: `Create Record`\n- **Base ID**: `appXXXXXX` (from Airtable URL)\n- **Table**: `Daily Stocks`\n- **Field Mapping**:\n  - `Ticker` \u2192 `{{ $json.ticker }}`\n  - `Company` \u2192 `{{ $json.name }}`\n  - `Price` \u2192 `{{ $json.price }}`\n  - `Change %` \u2192 `{{ $json.change }}`\n  - `Sentiment` \u2192 `{{ $json.sentiment }}`\n  - `Date` \u2192 `{{ $now.toISO() }}`\n"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "ccdfd109-9fd2-40e4-981e-f85eef7cfba6",
  "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": [
        []
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Wake up to a clean, analyst-style stock digest in your inbox—top gainers/losers, a readable performance table, 3–5 insights, and upcoming events—no spreadsheets, no manual scraping, no copy-paste. This article explains, step by step, how to build a robust, daily, end-to-end…

Source: https://n8n.io/workflows/8724/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Template Name: AI Personal Assistant - Task & Email Management Price: $27 Category: Productivity & Automation Difficulty: Intermediate Use Case: Personal productivity automation for busy professionals

Telegram, HTTP Request, OpenAI +8
AI & RAG

Schedules automated vendor pricing analysis across multiple sources. Fetches delivery reliability and contract data, analyzes vendor performance using Claude AI, then distributes consolidated reports

HTTP Request, Airtable, OpenAI Chat +9
AI & RAG

This n8n automation workflow automates the creation, scripting, production, and posting of YouTube videos. It leverages AI (OpenAI), image generation (PIAPI), video rendering (Shotstack), and platform

Agent, OpenAI Chat, Airtable Tool +7
AI & RAG

What this workflow does

OpenAI Chat, Memory Buffer Window, Output Parser Structured +4
AI & RAG

This workflow is for beauty salons who want consistent, high‑quality social media content without writing every post manually. It also suits agencies and automation builders who manage multiple beauty

Telegram, Google Sheets Trigger, Agent +26