{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "9a5b0b7d-995d-4190-b83b-dc1c3d0fe18c",
      "name": "Market Open Scheduler",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        4096,
        3296
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 9,
              "triggerAtMinute": 30
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "d6f52824-4007-49c6-a6aa-77c929ee83ac",
      "name": "Fetch Market News",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4304,
        3392
      ],
      "parameters": {
        "url": "=https://api.tradient.org/v1/api/market/news",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {}
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "356d2a81-352a-4f34-b8d4-6b6d61978911",
      "name": "Extract Price Data",
      "type": "n8n-nodes-base.set",
      "position": [
        4480,
        3200
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "adf6bcc2-eddb-4e12-adf1-dee394b25ced",
              "name": "prices",
              "type": "object",
              "value": "={{ $json.prices }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "01c7951d-659a-4425-9a58-c9923b5cfbf7",
      "name": "Normalize Price Data",
      "type": "n8n-nodes-base.code",
      "position": [
        4656,
        3200
      ],
      "parameters": {
        "jsCode": "const arr = Object.values($input.first().json.prices);\n\nreturn [\n  {\n    json: {\n      data: arr\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "3ab16a21-7280-4ebe-81b9-d172fe63e893",
      "name": "Calculate Gainers & Losers",
      "type": "n8n-nodes-base.code",
      "position": [
        4800,
        3200
      ],
      "parameters": {
        "jsCode": "const data = $input.first().json.data;\n\nconst sorted = data.sort((a, b) => b.pchange - a.pchange);\n\nconst gainers = sorted.slice(0, 10);\nconst losers = sorted.slice(-10).reverse();\n\nreturn [\n  {\n    json: {\n      top_gainers: gainers,\n      top_losers: losers\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "74e5d301-06e0-47d5-a29b-3cdd1a26b283",
      "name": "Analyze News Sentiment (AI)",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        4512,
        3392
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-3.1-flash-lite-preview",
          "cachedResultName": "models/gemini-3.1-flash-lite-preview"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=Analyze the following financial news.\n\nReturn:\nEvery news object with added keys\nNews Title:\nStock Name: \nSentiment: Bullish / Bearish / Mixed\nReason: (max 50 words)\n\nNews:\n{{ JSON.stringify($json) }}"
            }
          ]
        },
        "jsonOutput": true,
        "builtInTools": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "33fdea47-9469-4191-ac17-519542e98403",
      "name": "Parse News Response",
      "type": "n8n-nodes-base.code",
      "position": [
        4800,
        3392
      ],
      "parameters": {
        "jsCode": "\nreturn {\n  json:{\n     \"news\": JSON.parse($input.first().json.content.parts[0].text)\n  }\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "4ddcd2cb-b617-4f68-8be5-15b30753bf19",
      "name": "Merge Market Data",
      "type": "n8n-nodes-base.merge",
      "position": [
        5008,
        3312
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "ccce92c4-5c71-420f-ac53-69dfa4c09e17",
      "name": "Validate Data",
      "type": "n8n-nodes-base.if",
      "position": [
        5168,
        3312
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "411446eb-5de6-4015-8c63-5a772036e98a",
              "operator": {
                "type": "object",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json }}",
              "rightValue": "={{ null }}"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "8d4e476e-b195-4369-bf15-dbdcf3269c19",
      "name": "Aggregate Dataset",
      "type": "n8n-nodes-base.code",
      "position": [
        5376,
        3296
      ],
      "parameters": {
        "jsCode": "const allItems = $input.all();\n\nreturn [\n  {\n    json: {\n      combinedData: allItems.map(item => item.json)\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "54a4d0c4-ce22-4ce2-b971-e52c48a425e6",
      "name": "Structure Final Payload",
      "type": "n8n-nodes-base.set",
      "position": [
        5552,
        3296
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "d9023914-6817-4ae1-a3b1-853fbfe469ec",
              "name": "top_gainers",
              "type": "array",
              "value": "={{ $json.combinedData[0].top_gainers }}"
            },
            {
              "id": "6c050545-abe7-441b-b25c-2e6bbfa07312",
              "name": "top_losers",
              "type": "array",
              "value": "={{ $json.combinedData[0].top_losers }}"
            },
            {
              "id": "fb4e3707-477e-42b8-bffb-3d8c5cb15d37",
              "name": "news",
              "type": "string",
              "value": "={{ $json.combinedData[1].news }}"
            },
            {
              "id": "944b3afa-0bc6-4fad-8784-4c55747bbeec",
              "name": "",
              "type": "string",
              "value": ""
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "91021c53-b5d3-4c81-a907-b6df1f9f11a0",
      "name": "Generate Market Brief (AI)",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        5760,
        3296
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-3.1-flash-lite-preview",
          "cachedResultName": "models/gemini-3.1-flash-lite-preview"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "role": "model",
              "content": "You are a professional stock market analyst. \nWrite concise, insightful and human-friendly summaries."
            },
            {
              "content": "=You are a professional Indian stock market analyst.\n\nWrite a clean email.\n\nFormat:\nDaily Market Brief\n\n- Mention Nifty trend\n- Market News: {{ JSON.stringify($json.combinedData[1].news) }}\n- Mention top gainers\n- Mention top losers\n\nKeep:\n- Max 120 words\n- Crisp bullet style\n- No fluff\n\nTop Gainers:\n{{ JSON.stringify($json.top_gainers) }}\n\nTop Losers:\n{{ JSON.stringify($json.top_losers) }}\n"
            }
          ]
        },
        "builtInTools": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "ec6feba2-ac5f-4556-a11f-9405ab93e00b",
      "name": "Send Email Report",
      "type": "n8n-nodes-base.gmail",
      "position": [
        6080,
        3296
      ],
      "parameters": {
        "sendTo": "",
        "message": "={{ $json.content.parts[0].text }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "Daily Market Brief (AI Summary)",
        "emailType": "text"
      },
      "retryOnFail": false,
      "typeVersion": 2.2
    },
    {
      "id": "3360b7dd-4c5b-4e04-a2bf-8535cc57da95",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4480,
        3376
      ],
      "parameters": {
        "color": 7,
        "width": 464,
        "height": 304,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n### NEWS ANALYSIS (AI)\nProcesses financial news using AI.\nExtracts stock names, sentiment (bullish/bearish/mixed) and concise reasoning for each news item."
      },
      "typeVersion": 1
    },
    {
      "id": "2167e217-e5da-4eac-b95b-928061c778c6",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5744,
        3056
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 416,
        "content": "### AI SUMMARY GENERATION & DELIVERY\nUses AI to generate a crisp, email-ready market brief.\nFocuses on trend, news highlights and key movers in \u2264120 words.\nSends the generated market summary via email.\nEnsures consistent daily delivery without manual intervention."
      },
      "typeVersion": 1
    },
    {
      "id": "08384d8a-4ce4-45f9-a272-6f0de94c6ffe",
      "name": "Fetch Nifty 50 Stock Prices1",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4304,
        3200
      ],
      "parameters": {
        "url": "=https://memic-nse-quotes-api.hf.space/quotes",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ \n  JSON.stringify({\"symbols\": [\n  \"ADANIENT\",\"ADANIPORTS\",\"APOLLOHOSP\",\"ASIANPAINT\",\"AXISBANK\",\n  \"BAJAJ-AUTO\",\"BAJFINANCE\",\"BAJAJFINSV\",\"BEL\",\"BHARTIARTL\",\n  \"BPCL\",\"BRITANNIA\",\"CIPLA\",\"COALINDIA\",\"DIVISLAB\",\n  \"DRREDDY\",\"EICHERMOT\",\"GRASIM\",\"HCLTECH\",\"HDFCBANK\",\n  \"HDFCLIFE\",\"HEROMOTOCO\",\"HINDALCO\",\"HINDUNILVR\",\"ICICIBANK\",\n  \"INDUSINDBK\",\"INFY\",\"ITC\",\"JSWSTEEL\",\"KOTAKBANK\",\n  \"LT\",\"M&M\",\"MARUTI\",\"NESTLEIND\",\"NTPC\",\n  \"ONGC\",\"POWERGRID\",\"RELIANCE\",\"SBILIFE\",\"SBIN\",\n  \"SHRIRAMFIN\",\"SUNPHARMA\",\"TATACONSUM\",\"TMCV\",\"TATASTEEL\",\n  \"TCS\",\"TECHM\",\"TITAN\",\"ULTRACEMCO\",\"WIPRO\"\n]})\n}}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {}
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "17ef1798-a23e-4e52-a4bf-05642d409b44",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3424,
        2816
      ],
      "parameters": {
        "width": 432,
        "height": 624,
        "content": "### DAILY MARKET BRIEF AUTOMATION\n\nThis workflow automatically generates and delivers a concise stock market summary every morning at market open.\n\n### How it works:\nAt 9:30 AM, the scheduler triggers the workflow. It fetches real-time Nifty 50 stock prices and latest financial news from APIs. Stock data is cleaned, converted into structured format and used to identify top gainers and losers. Meanwhile, news data is analyzed using AI to extract sentiment and key insights. Both datasets are merged and passed to an AI model, which generates a short, human-friendly market brief. The final summary is then emailed automatically.\n\n### Setup steps:\nConfigure schedule trigger (9:30 AM)\nConnect stock quotes API\nConnect market news API\nAdd Gemini API credentials\nConfigure Gmail node\nActivate workflow\n\n### Goal:\nDeliver a ready-to-read daily market summary with zero manual effort."
      },
      "typeVersion": 1
    },
    {
      "id": "694837fc-a5bd-403f-9501-f43bcf1047a8",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4048,
        3040
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 528,
        "content": "### DATA COLLECTION\nFetches raw inputs from external sources.\nIncludes Nifty 50 stock prices and latest market news APIs.\nThis layer ensures the workflow starts with fresh, real-time data."
      },
      "typeVersion": 1
    },
    {
      "id": "e6c003a9-da4d-4dc0-b0bd-f29d75850d3b",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4464,
        3056
      ],
      "parameters": {
        "color": 7,
        "width": 464,
        "height": 304,
        "content": "### DATA PROCESSING\nTransforms raw stock API response into structured format.\nConverts objects into arrays and calculates top gainers and losers based on percentage change.."
      },
      "typeVersion": 1
    },
    {
      "id": "77d4f660-af59-478d-b12b-e4eb5837f392",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4960,
        3152
      ],
      "parameters": {
        "color": 7,
        "width": 708,
        "height": 320,
        "content": "### DATA MERGING , VALIDATION & DATA STRUCTURING\nCombines stock insights and analyzed news into a single dataset.\nValidates data integrity before passing it forward for final processing.\nPrepares the final payload for AI summarization.\nEnsures only required fields (gainers, losers, news) are cleanly formatted."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Validate Data": {
      "main": [
        [
          {
            "node": "Aggregate Dataset",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Dataset": {
      "main": [
        [
          {
            "node": "Structure Final Payload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Market News": {
      "main": [
        [
          {
            "node": "Analyze News Sentiment (AI)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Market Data": {
      "main": [
        [
          {
            "node": "Validate Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Price Data": {
      "main": [
        [
          {
            "node": "Normalize Price Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse News Response": {
      "main": [
        [
          {
            "node": "Merge Market Data",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Normalize Price Data": {
      "main": [
        [
          {
            "node": "Calculate Gainers & Losers",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Market Open Scheduler": {
      "main": [
        [
          {
            "node": "Fetch Market News",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Nifty 50 Stock Prices1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structure Final Payload": {
      "main": [
        [
          {
            "node": "Generate Market Brief (AI)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Gainers & Losers": {
      "main": [
        [
          {
            "node": "Merge Market Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Market Brief (AI)": {
      "main": [
        [
          {
            "node": "Send Email Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze News Sentiment (AI)": {
      "main": [
        [
          {
            "node": "Parse News Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Nifty 50 Stock Prices1": {
      "main": [
        [
          {
            "node": "Extract Price Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}