AutomationFlowsSlack & Telegram › Daily Stock Market Report with Twelve Data API Sent via Whatsapp and Email

Daily Stock Market Report with Twelve Data API Sent via Whatsapp and Email

ByOneclick AI Squad @oneclick-ai on n8n.io

This workflow automates the generation of a daily stock market report, identifying the top gainers and losers among the top 100 stocks. It fetches real-time stock data, processes it to highlight significant price movements, and delivers formatted alerts via WhatsApp and email.…

Cron / scheduled trigger★★★★☆ complexity13 nodesHTTP RequestEmail SendWhatsApp
Slack & Telegram Trigger: Cron / scheduled Nodes: 13 Complexity: ★★★★☆ Added:

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

This workflow follows the Emailsend → HTTP Request 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": "z8p6r4MRvb3YWvpa",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Automated Daily Report of Top 100 Stock Price Changes",
  "tags": [],
  "nodes": [
    {
      "id": "e84b9576-6c4a-424c-9f64-0ce3cdca5909",
      "name": "Daily Market Close Trigger\t",
      "type": "n8n-nodes-base.cron",
      "position": [
        -624,
        -32
      ],
      "parameters": {
        "triggerTimes": {
          "item": [
            {
              "hour": 17
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d4544920-d3b4-4928-88c9-435fd82e7cbe",
      "name": "Set Configuration Variables\t",
      "type": "n8n-nodes-base.set",
      "position": [
        -400,
        -32
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "api-key-assignment",
              "name": "twelvedata_api_key",
              "type": "string",
              "value": "your_api_key_add_here"
            },
            {
              "id": "symbols-assignment",
              "name": "top_symbols",
              "type": "string",
              "value": "AAPL,MSFT,GOOGL,AMZN,TSLA"
            },
            {
              "id": "whatsapp-number",
              "name": "whatsapp_number",
              "type": "string",
              "value": "+1234567890"
            },
            {
              "id": "email-recipient",
              "name": "email_recipient",
              "type": "string",
              "value": "user@example.com"
            },
            {
              "id": "fd42d040-23dc-456f-89ee-144be97a1e8c",
              "name": "",
              "type": "string",
              "value": ""
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "30d03cb8-c49a-4eb1-8e58-5cf8434c313b",
      "name": "Fetch Stock Data from Twelve Data\t",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -176,
        -32
      ],
      "parameters": {
        "url": "=https://api.twelvedata.com/quote?symbol={{ $json.top_symbols }}&apikey={{ $json.twelvedata_api_key }}",
        "options": {
          "timeout": 30000
        },
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "interval",
              "value": "1day"
            },
            {
              "name": "outputsize",
              "value": "1"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "9ab66310-6532-4267-bf5e-38131317a677",
      "name": "Process Stock Movements\t",
      "type": "n8n-nodes-base.code",
      "position": [
        48,
        -32
      ],
      "parameters": {
        "jsCode": "const stockData = $input.first().json;\nlet processedStocks = [];\n\n// Check for API error\nif (stockData.error) {\n  throw new Error(`Twelve Data API Error: ${stockData.error.message}`);\n}\n\n// Handle single or multiple stock responses\nlet quotes = [];\nif (Array.isArray(stockData)) {\n  quotes = stockData;\n} else if (stockData.symbol) {\n  quotes = [stockData];\n} else {\n  quotes = Object.values(stockData).filter(item => item.symbol);\n}\n\nfor (let stock of quotes) {\n  if (stock && stock.symbol && stock.percent_change) {\n    const percentChange = parseFloat(stock.percent_change);\n    const price = parseFloat(stock.close || stock.price);\n    const change = parseFloat(stock.change);\n    processedStocks.push({\n      symbol: stock.symbol,\n      name: stock.name || stock.symbol,\n      price: isNaN(price) ? null : price,\n      change: isNaN(change) ? null : change,\n      percent_change: isNaN(percentChange) ? null : percentChange,\n      volume: stock.volume ? parseInt(stock.volume) : null,\n      movement_type: percentChange > 0 ? 'gain' : 'loss',\n      abs_percent_change: Math.abs(percentChange)\n    });\n  }\n}\n\n// Sort by absolute percentage change\nprocessedStocks.sort((a, b) => b.abs_percent_change - a.abs_percent_change);\n\n// Top 5 movers\nconst topMovers = processedStocks.slice(0, 5);\nconst gainers = topMovers.filter(stock => stock.percent_change > 0).slice(0, 3);\nconst losers = topMovers.filter(stock => stock.percent_change < 0).slice(0, 3);\n\nconst currentDate = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });\n\nreturn [{ json: { date: currentDate, total_stocks: processedStocks.length, top_gainers: gainers, top_losers: losers, biggest_movers: topMovers } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "940a5f7c-555d-4eab-8bd1-d4a44060d315",
      "name": "Format WhatsApp Message\t",
      "type": "n8n-nodes-base.code",
      "position": [
        272,
        -112
      ],
      "parameters": {
        "jsCode": "const data = $input.first().json;\nlet message = `\ud83d\udcc8 *DAILY STOCK MARKET REPORT*\\n`;\nmessage += `\ud83d\udcc5 Date: ${data.date}\\n`;\nmessage += `\ud83d\udcca Analyzed: ${data.total_stocks} stocks\\n\\n`;\nmessage += `\ud83d\udfe2 *TOP GAINERS*\\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n`;\ndata.top_gainers.forEach((stock, index) => {\n  message += `${index + 1}. ${stock.symbol}\\n`;\n  message += `   \ud83d\udcb0 $${stock.price?.toFixed(2) || 'N/A'}\\n`;\n  message += `   \ud83d\udcc8 +${stock.percent_change?.toFixed(2) || 'N/A'}% (+$${stock.change?.toFixed(2) || 'N/A'})\\n\\n`;\n});\nmessage += `\ud83d\udd34 *TOP LOSERS*\\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n`;\ndata.top_losers.forEach((stock, index) => {\n  message += `${index + 1}. ${stock.symbol}\\n`;\n  message += `   \ud83d\udcb0 $${stock.price?.toFixed(2) || 'N/A'}\\n`;\n  message += `   \ud83d\udcc9 ${stock.percent_change?.toFixed(2) || 'N/A'}% ($${stock.change?.toFixed(2) || 'N/A'})\\n\\n`;\n});\nmessage += `\\n\u26a1 Generated by Stock Alert Bot`;\nreturn [{ json: { whatsapp_message: message } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "3d3b1981-004c-4ae1-a450-63690b0e9100",
      "name": "Format Email Content\t",
      "type": "n8n-nodes-base.code",
      "position": [
        272,
        48
      ],
      "parameters": {
        "jsCode": "const data = $input.first().json;\nlet htmlContent = `<!DOCTYPE html><html><head><style>body { font-family: Arial, sans-serif; margin: 20px; background-color: #f5f5f5; }.container { max-width: 600px; margin: 0 auto; background: white; padding: 20px; border-radius: 10px; }.header { text-align: center; border-bottom: 2px solid #007bff; padding-bottom: 10px; }.section { margin-bottom: 20px; }.stock-table { width: 100%; border-collapse: collapse; }.stock-table th, .stock-table td { padding: 10px; text-align: left; border-bottom: 1px solid #ddd; }.stock-table th { background-color: #f8f9fa; }.gain { color: #28a745; }.loss { color: #dc3545; }.symbol { font-weight: bold; color: #007bff; }</style></head><body><div class=\"container\"><div class=\"header\"><h2>\ud83d\udcc8 Daily Stock Market Report</h2><p><strong>Date:</strong> ${data.date}</p></div><div class=\"section\"><h3 style=\"color: #28a745;\">\ud83d\udfe2 Top Gainers</h3><table class=\"stock-table\"><thead><tr><th>Symbol</th><th>Price</th><th>Change</th><th>% Change</th></tr></thead><tbody>`;\ndata.top_gainers.forEach((stock) => {\n  htmlContent += `<tr><td class=\"symbol\">${stock.symbol}</td><td>$${stock.price?.toFixed(2) || 'N/A'}</td><td class=\"gain\">+$${stock.change?.toFixed(2) || 'N/A'}</td><td class=\"gain\">+${stock.percent_change?.toFixed(2) || 'N/A'}%</td></tr>`;\n});\nhtmlContent += `</tbody></table></div><div class=\"section\"><h3 style=\"color: #dc3545;\">\ud83d\udd34 Top Losers</h3><table class=\"stock-table\"><thead><tr><th>Symbol</th><th>Price</th><th>Change</th><th>% Change</th></tr></thead><tbody>`;\ndata.top_losers.forEach((stock) => {\n  htmlContent += `<tr><td class=\"symbol\">${stock.symbol}</td><td>$${stock.price?.toFixed(2) || 'N/A'}</td><td class=\"loss\">$${stock.change?.toFixed(2) || 'N/A'}</td><td class=\"loss\">${stock.percent_change?.toFixed(2) || 'N/A'}%</td></tr>`;\n});\nhtmlContent += `</tbody></table></div><div style=\"text-align: center; margin-top: 20px; color: #666;\"><p>\u26a1 Generated by Stock Alert System</p></div></body></html>`;\nconst plainText = `DAILY STOCK MARKET REPORT\\nDate: ${data.date}\\nStocks Analyzed: ${data.total_stocks}\\n\\nTOP GAINERS:\\n${data.top_gainers.map((stock, i) => `${i+1}. ${stock.symbol}: $${stock.price?.toFixed(2) || 'N/A'} (+${stock.percent_change?.toFixed(2) || 'N/A'}%)`).join('\\n')}\\n\\nTOP LOSERS:\\n${data.top_losers.map((stock, i) => `${i+1}. ${stock.symbol}: $${stock.price?.toFixed(2) || 'N/A'} (${stock.percent_change?.toFixed(2) || 'N/A'}%)`).join('\\n')}\\n\\nGenerated by Stock Alert System`;\nreturn [{ json: { email_html: htmlContent, email_text: plainText, email_subject: `Daily Stock Report - ${data.date}` } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "d703c8f4-20c5-4960-8b11-59dd20d8952a",
      "name": "Send Email Alert\t",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        496,
        48
      ],
      "parameters": {
        "html": "={{ $json.email_html }}",
        "options": {},
        "subject": "={{ $json.email_subject }}",
        "toEmail": "={{ $('Set Configuration Variables\t').item.json.email_recipient }}",
        "fromEmail": "user@example.com",
        "emailFormat": "html"
      },
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "a6436b0d-b49e-4186-b9d7-e80177665e8f",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -640,
        -176
      ],
      "parameters": {
        "width": 160,
        "height": 300,
        "content": "Triggers daily at 5:00 PM (after market close) Monday-Friday.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "1b1643d8-294d-457f-9164-9a0990ecef94",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -432,
        -176
      ],
      "parameters": {
        "color": 4,
        "width": 170,
        "height": 300,
        "content": "Sets API key, stock symbols, and alert recipients.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "e1cafd10-344b-4d39-91d6-04588d7e6d67",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -224,
        -176
      ],
      "parameters": {
        "color": 3,
        "width": 170,
        "height": 300,
        "content": "Fetches stock data for selected symbols via Twelve Data API.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "4dcb1252-bcc4-4b6d-8a05-b5d8600bce13",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        -176
      ],
      "parameters": {
        "color": 5,
        "width": 170,
        "height": 300,
        "content": "Processes stock data to identify top gainers and losers.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "444844c9-b1c2-40b6-907e-0b93e08aea6c",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        464,
        -208
      ],
      "parameters": {
        "color": 6,
        "width": 170,
        "height": 332,
        "content": "Sends formatted alerts via WhatsApp and Email.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "26752e0e-0ab8-4f67-858b-c0d954891d9b",
      "name": "Send message",
      "type": "n8n-nodes-base.whatsApp",
      "position": [
        480,
        -112
      ],
      "parameters": {
        "textBody": "={{ $json.whatsapp_message }}",
        "operation": "send",
        "phoneNumberId": "=+919877663344",
        "additionalFields": {},
        "recipientPhoneNumber": "={{ $('Set Configuration Variables\t').item.json.whatsapp_number }}"
      },
      "credentials": {
        "whatsAppApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "e99f69ff-d8ff-4f02-980c-5c27a29d37cb",
  "connections": {
    "Format Email Content\t": {
      "main": [
        [
          {
            "node": "Send Email Alert\t",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format WhatsApp Message\t": {
      "main": [
        [
          {
            "node": "Send message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Stock Movements\t": {
      "main": [
        [
          {
            "node": "Format WhatsApp Message\t",
            "type": "main",
            "index": 0
          },
          {
            "node": "Format Email Content\t",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily Market Close Trigger\t": {
      "main": [
        [
          {
            "node": "Set Configuration Variables\t",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Configuration Variables\t": {
      "main": [
        [
          {
            "node": "Fetch Stock Data from Twelve Data\t",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Stock Data from Twelve Data\t": {
      "main": [
        [
          {
            "node": "Process Stock Movements\t",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

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

This workflow automates the generation of a daily stock market report, identifying the top gainers and losers among the top 100 stocks. It fetches real-time stock data, processes it to highlight significant price movements, and delivers formatted alerts via WhatsApp and email.…

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

More Slack & Telegram workflows → · Browse all categories →

Related workflows

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

Slack & Telegram

Regua-De-Cobrancas. Uses httpRequest, emailSend, whatsApp, twilio. Scheduled trigger; 25 nodes.

HTTP Request, Email Send, WhatsApp +2
Slack & Telegram

This automated n8n workflow delivers daily multi-currency exchange rate updates via API to email and WhatsApp. The system fetches the latest exchange rates, formats the data, and sends alerts to desig

HTTP Request, WhatsApp, Email Send
Slack & Telegram

This workflow automates the generation of a daily crypto market report, identifying the top 24-hour gainers and losers among the top 100 cryptocurrencies. It fetches real-time data, processes it to hi

HTTP Request, Email Send, WhatsApp
Slack & Telegram

This workflow contains community nodes that are only compatible with the self-hosted version of n8n.

N8N Nodes Scrapegraphai, HTTP Request, Google Sheets +2
Slack & Telegram

Simplify financial oversight with this automated n8n workflow. Triggered daily, it fetches cash flow and expense data from a Google Sheet, analyzes inflows and outflows, validates records, and generat

HTTP Request, Google Sheets, Email Send +3