# templates

name: Automated Investor Intelligence: CrunchBase to Google Sheets Data Harvester
author_name: Yaron Been
author_username: yaron-nofluff
nodes_used: ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.code"]
categories: []
created_at: 2025-06-06T13:41:28.967Z
updated_at: 2025-06-06T13:41:28.967Z
url: https://n8n.io/workflows/4731
scraped_at: 2025-07-06 21:16:30
description:
  🚀 Automated Investor Intelligence: CrunchBase to Google Sheets Data Harvester!

  Workflow Overview
  This cutting-edge n8n automation is a sophisticated investor intelligence tool designed to transform market research into actionable insights. By intelligently connecting CrunchBase, data processing, and Google Sheets, this workflow:

  Discovers Investor Insights: 
     Automatically retrieves latest investor data
     Tracks key investment organizations
     Eliminates manual market research efforts

  Intelligent Data Processing:
     Filters investor-specific organizations
     Extracts critical investment metrics
     Ensures comprehensive market intelligence

  Seamless Data Logging:
     Automatically updates Google Sheets
     Creates real-time investor database
     Enables rapid market trend analysis

  Scheduled Intelligence Gathering:
     Daily automated tracking
     Consistent investor insight updates
     Zero manual intervention required

  Key Benefits
  🤖 Full Automation: Zero-touch investor research
  💡 Smart Filtering: Targeted investment insights
  📊 Comprehensive Tracking: Detailed investor intelligence
  🌐 Multi-Source Synchronization: Seamless data flow

  Workflow Architecture

  🔹 Stage 1: Investor Discovery
  Scheduled Trigger**: Daily market scanning
  CrunchBase API Integration**
  Intelligent Filtering**:
    Investor-specific organizations
    Key investment metrics
    Most recent data

  🔹 Stage 2: Data Extraction
  Comprehensive Metadata Parsing**
  Key Information Retrieval**
  Structured Data Preparation**

  🔹 Stage 3: Data Logging
  Google Sheets Integration**
  Automatic Row Appending**
  Real-Time Database Updates**

  Potential Use Cases
  Venture Capitalists**: Investment ecosystem mapping
  Startup Scouts**: Investor trend analysis
  Market Researchers**: Comprehensive investment insights
  Business Development**: Strategic partnership identification
  Investment Analysts**: Market intelligence gathering

  Setup Requirements
  CrunchBase API
     API credentials
     Configured access permissions
     Investor organization tracking setup

  Google Sheets
     Connected Google account
     Prepared tracking spreadsheet
     Appropriate sharing settings

  n8n Installation
     Cloud or self-hosted instance
     Workflow configuration
     API credential management

  Future Enhancement Suggestions
  🤖 Advanced investment trend analysis
  📊 Multi-source investor aggregation
  🔔 Customizable alert mechanisms
  🌐 Expanded investment stage tracking
  🧠 Machine learning insights generation

  Technical Considerations
  Implement robust error handling
  Use secure API authentication
  Maintain flexible data processing
  Ensure compliance with API usage guidelines

  Ethical Guidelines
  Respect business privacy
  Use data for legitimate research
  Maintain transparent information gathering
  Provide proper attribution

  Hashtag Performance Boost 🚀
  #InvestorIntelligence #VentureCapital #MarketResearch #AIWorkflow #DataAutomation #StartupEcosystem #InvestmentTracking #BusinessIntelligence #TechInnovation #StartupFunding

  Workflow Visualization

  [Daily Trigger]
      ⬇️
  [Fetch Investor Data]
      ⬇️
  [Extract Investor Fields]
      ⬇️
  [Log to Google Sheets]

  Connect With Me

  Ready to revolutionize your investor research?

  📧 Email: Yaron@nofluff.online

  🎥 YouTube: @YaronBeen

  💼 LinkedIn: Yaron Been

  Transform your market intelligence with intelligent, automated workflows!

workflow_json:
  {"id":"8hRFK0iEjVKmthLq","meta":{"instanceId":"84ad02d6104594179f43f1ce9cfe3a81637b2faedb57dafcb9e649b7542988db","templateCredsSetupCompleted":true},"name":"CrunchBase Invester Data","tags":[],"nodes":[{"id":"49130296-ad2e-43f6-8ec4-7f72161a3a1b","name":"Daily Investor Data Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[0,0],"parameters":{"rule":{"interval":[{"triggerAtHour":9}]}},"typeVersion":1.2},{"id":"24caa890-abba-435d-a385-18cdef03dfe2","name":"Fetch Crunchbase Investor Data","type":"n8n-nodes-base.httpRequest","position":[220,0],"parameters":{"url":"https://api.crunchbase.com/api/v4/searches/organizations","method":"POST","options":{},"jsonBody":"{\n  \"field_ids\": [\n    \"identifier\",\n    \"name\",\n    \"short_description\",\n    \"location_identifiers\",\n    \"investment_stage\"\n  ],\n  \"query\": [\n    {\n      \"type\": \"predicate\",\n      \"field_id\": \"organization_types\",\n      \"operator_id\": \"includes\",\n      \"values\": [\n        \"investor\"\n      ]\n    }\n  ],\n  \"limit\": 5\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"},{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"4de0847b-6e11-457d-b04b-d03b4fb1e3c1","name":"Extract Investor Fields","type":"n8n-nodes-base.code","position":[540,0],"parameters":{"jsCode":"const entities = items[0].json.entities;\n\nreturn entities.map(entity => {\n  return {\n    json: {\n      name: entity.name,\n      short_description: entity.short_description,\n      location_identifiers: entity.location_identifiers,\n      investment_stage: entity.investment_stage\n    }\n  };\n});\n"},"typeVersion":2},{"id":"a7d08f10-1fde-4e99-9127-bf12926d4197","name":"Append to Investor Sheet","type":"n8n-nodes-base.googleSheets","position":[780,0],"parameters":{"columns":{"value":{"Name":"={{ $json.name }}","Location":"={{ $json.location_identifiers }}","Investment Stage":"={{ $json.investment_stage }}","Short description":"={{ $json.short_description }}"},"schema":[{"id":"Name","type":"string","display":true,"required":false,"displayName":"Name","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Short description","type":"string","display":true,"required":false,"displayName":"Short description","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Location","type":"string","display":true,"required":false,"displayName":"Location","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Investment Stage","type":"string","display":true,"removed":false,"required":false,"displayName":"Investment Stage","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/1XOUvOgrhDdOorEj0-TL4EiVygMd1wpD3cktI2_bm-Ww/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1XOUvOgrhDdOorEj0-TL4EiVygMd1wpD3cktI2_bm-Ww","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1XOUvOgrhDdOorEj0-TL4EiVygMd1wpD3cktI2_bm-Ww/edit?usp=drivesdk","cachedResultName":"CrunchBase Invester List"}},"credentials":{"googleSheetsOAuth2Api":{"id":"Rp7XiR3hxJfv03ZO","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"45c6eb29-4d24-49a6-b849-938b178b66c9","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-40,-1700],"parameters":{"color":5,"width":420,"height":1900,"content":"### 🔷 **SECTION 1: Getting the Data from Crunchbase**\n\n#### 🧩 Nodes:\n\n1. 🕒 **Daily Investor Data Trigger**\n2. 🌐 **Fetch Crunchbase Investor Data**\n\n---\n\n#### 🔍 What Happens in This Section?\n\nThis section is all about **automatically pulling investor data from Crunchbase** on a scheduled basis, without any manual effort.\n\n---\n\n#### 🕒 1. **Daily Investor Data Trigger**\n\n> *\"When should the automation run?\"*\n\n* This **Schedule Trigger** node starts your workflow automatically at your chosen time.\n* For example, it could run every day at 8 AM.\n* It removes the need to remember to check Crunchbase manually.\n\n✅ *Beginner Benefit:*\n\n> Even if you’re not technical, you just set the schedule and let n8n run this job every day while you sleep ☕📊\n\n---\n\n#### 🌐 2. **Fetch Crunchbase Investor Data**\n\n> *\"Where do we get the data from?\"*\n\n* This **HTTP Request** node sends a **POST request** to [Crunchbase’s API](https://data.crunchbase.com/docs).\n\n* It includes a **filter** for organization types like `investor` and requests fields like:\n\n  * `name`\n  * `short_description`\n  * `location_identifiers`\n  * `investment_stage`\n\n* Crunchbase replies with a **JSON** file full of matching investors.\n\n✅ *Beginner Benefit:*\n\n> You don’t need to open a browser or search anything. This step collects live investor data from Crunchbase and brings it into your workflow for you 🚀\n\n---\n\n### ✅ What This Section Gives You:\n\nA **live, up-to-date snapshot** of investor information, **automatically pulled** from Crunchbase, without coding or clicking.\n\n---\n\n"},"typeVersion":1},{"id":"2dd2de36-770c-4833-884b-1525c1411d46","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[480,-1400],"parameters":{"color":6,"width":460,"height":1600,"content":"### 🔷 **SECTION 2: Processing and Saving the Data**\n\n#### 🧩 Nodes:\n\n3. 🧮 **Extract Investor Fields**\n4. 📄 **Append to Investor Sheet**\n\n---\n\n#### 🔍 What Happens in This Section?\n\nNow that we have raw investor data, this section **cleans it up** and **stores it in a Google Sheet** for easy access and analysis.\n\n---\n\n#### 🧮 3. **Extract Investor Fields**\n\n> *\"Let’s clean and format the response.\"*\n\n* This **Code** node uses JavaScript to loop through the list of investors and extract just what you care about:\n\n  * ✅ Name\n  * 📝 Short description\n  * 🌍 Location\n  * 💰 Investment stage\n\n* Each investor becomes a **separate row-ready item** for Google Sheets.\n\n✅ *Beginner Benefit:*\n\n> You don’t need to look at messy data. This step reshapes it into a clean format automatically ✨\n\n---\n\n#### 📄 4. **Append to Investor Sheet**\n\n> *\"Store it somewhere useful.\"*\n\n* This **Google Sheets** node takes the cleaned data and **adds it to a selected sheet**.\n* It works like a magic assistant, typing the investor data into your spreadsheet row-by-row.\n* You now have a **running list** of investors to use for:\n\n  * 📈 Market research\n  * 🎯 Outreach planning\n  * 💡 Competitor benchmarking\n\n"},"typeVersion":1},{"id":"75231f28-c911-4bdc-a6a2-c6255d293eb3","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-1820,-1680],"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":"c8a8156f-946e-4a50-8789-aff9c66bd9b6","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-1820,-1340],"parameters":{"color":4,"width":1289,"height":3278,"content":"## ✨ n8n Workflow: Investor Data Automation from Crunchbase to Google Sheets\n\n---\n\n### 🔷 **SECTION 1: Getting the Data from Crunchbase**\n\n#### 🧩 Nodes:\n\n1. 🕒 **Daily Investor Data Trigger**\n2. 🌐 **Fetch Crunchbase Investor Data**\n\n---\n\n#### 🔍 What Happens in This Section?\n\nThis section is all about **automatically pulling investor data from Crunchbase** on a scheduled basis, without any manual effort.\n\n---\n\n#### 🕒 1. **Daily Investor Data Trigger**\n\n> *\"When should the automation run?\"*\n\n* This **Schedule Trigger** node starts your workflow automatically at your chosen time.\n* For example, it could run every day at 8 AM.\n* It removes the need to remember to check Crunchbase manually.\n\n✅ *Beginner Benefit:*\n\n> Even if you’re not technical, you just set the schedule and let n8n run this job every day while you sleep ☕📊\n\n---\n\n#### 🌐 2. **Fetch Crunchbase Investor Data**\n\n> *\"Where do we get the data from?\"*\n\n* This **HTTP Request** node sends a **POST request** to [Crunchbase’s API](https://data.crunchbase.com/docs).\n\n* It includes a **filter** for organization types like `investor` and requests fields like:\n\n  * `name`\n  * `short_description`\n  * `location_identifiers`\n  * `investment_stage`\n\n* Crunchbase replies with a **JSON** file full of matching investors.\n\n✅ *Beginner Benefit:*\n\n> You don’t need to open a browser or search anything. This step collects live investor data from Crunchbase and brings it into your workflow for you 🚀\n\n---\n\n### ✅ What This Section Gives You:\n\nA **live, up-to-date snapshot** of investor information, **automatically pulled** from Crunchbase, without coding or clicking.\n\n---\n\n<br/>\n\n---\n\n### 🔷 **SECTION 2: Processing and Saving the Data**\n\n#### 🧩 Nodes:\n\n3. 🧮 **Extract Investor Fields**\n4. 📄 **Append to Investor Sheet**\n\n---\n\n#### 🔍 What Happens in This Section?\n\nNow that we have raw investor data, this section **cleans it up** and **stores it in a Google Sheet** for easy access and analysis.\n\n---\n\n#### 🧮 3. **Extract Investor Fields**\n\n> *\"Let’s clean and format the response.\"*\n\n* This **Code** node uses JavaScript to loop through the list of investors and extract just what you care about:\n\n  * ✅ Name\n  * 📝 Short description\n  * 🌍 Location\n  * 💰 Investment stage\n\n* Each investor becomes a **separate row-ready item** for Google Sheets.\n\n✅ *Beginner Benefit:*\n\n> You don’t need to look at messy data. This step reshapes it into a clean format automatically ✨\n\n---\n\n#### 📄 4. **Append to Investor Sheet**\n\n> *\"Store it somewhere useful.\"*\n\n* This **Google Sheets** node takes the cleaned data and **adds it to a selected sheet**.\n* It works like a magic assistant, typing the investor data into your spreadsheet row-by-row.\n* You now have a **running list** of investors to use for:\n\n  * 📈 Market research\n  * 🎯 Outreach planning\n  * 💡 Competitor benchmarking\n\n✅ *Beginner Benefit:*\n\n> You don’t copy-paste anything — n8n writes investor data into your sheet for you. It’s like having a personal assistant with no salary 📊🤖\n\n---\n\n### ✅ What This Section Gives You:\n\nA fully automated process that **cleans up Crunchbase data** and **stores it neatly** in Google Sheets — ready for analysis, dashboards, or reporting.\n\n---\n\n### 🎁 Final Outcome\n\n✅ No coding needed\n✅ Runs on autopilot\n✅ Clean data in your sheet\n✅ Use for strategy, marketing, or VC tracking\n\n---\n\n\n"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"daeaf695-d4ae-460d-84b1-b4cdba520d28","connections":{"Extract Investor Fields":{"main":[[{"node":"Append to Investor Sheet","type":"main","index":0}]]},"Daily Investor Data Trigger":{"main":[[{"node":"Fetch Crunchbase Investor Data","type":"main","index":0}]]},"Fetch Crunchbase Investor Data":{"main":[[{"node":"Extract Investor Fields","type":"main","index":0}]]}}}


name: Daily Startup Intelligence: Crunchbase Updates to Email Digest with GPT
author_name: Yaron Been
author_username: yaron-nofluff
categories: []
created_at: 2025-06-06T13:43:04.848Z
updated_at: 2025-06-06T13:43:04.848Z
url: https://n8n.io/workflows/4732
scraped_at: 2025-07-06 21:16:30
description:
  🚀 Automated Startup Intelligence: CrunchBase Updates to Email Digest Workflow!

  Workflow Overview
  This cutting-edge n8n automation is a sophisticated startup intelligence tool designed to transform market research into actionable insights. By intelligently connecting CrunchBase, AI processing, and Gmail, this workflow:

  Discovers Startup Updates: 
     Automatically retrieves latest company information
     Tracks recent organizational changes
     Eliminates manual market research efforts

  Intelligent Data Processing:
     Filters and extracts key company details
     Generates AI-powered summaries
     Ensures comprehensive market intelligence

  Smart Summarization:
     Uses AI to create readable company updates
     Transforms complex data into digestible insights
     Provides professional, context-rich summaries

  Seamless Email Distribution:
     Automatically sends daily update digests
     Delivers insights directly to your inbox
     Enables rapid market awareness

  Key Benefits
  🤖 Full Automation: Zero-touch startup research
  💡 Smart Filtering: Targeted company insights
  📊 Comprehensive Tracking: Detailed market intelligence
  🌐 Multi-Source Synchronization: Seamless data flow

  Workflow Architecture

  🔹 Stage 1: Company Discovery
  Manual/Scheduled Trigger**: Market scanning
  CrunchBase API Integration**
  Intelligent Filtering**:
    Recent updates
    Specific time frames
    Key organizational information

  🔹 Stage 2: Data Extraction
  Comprehensive Metadata Parsing**
  Key Information Retrieval**
  Structured Data Preparation**

  🔹 Stage 3: AI Summarization
  OpenAI GPT Processing**
  Professional Summary Generation**
  Contextual Insight Creation**

  🔹 Stage 4: Email Distribution
  Gmail Integration**
  Automated Update Digest**
  Personalized Delivery**

  Potential Use Cases
  Venture Capitalists**: Startup ecosystem tracking
  Market Researchers**: Industry trend analysis
  Startup Founders**: Competitive intelligence
  Business Strategists**: Market opportunity identification
  Investors**: Real-time company insights

  Setup Requirements
  CrunchBase API
     API credentials
     Configured access permissions
     Company update tracking setup

  OpenAI API
     GPT model access
     Summarization configuration
     API key management

  Gmail Account
     Connected email
     Digest email configuration
     Appropriate sending permissions

  n8n Installation
     Cloud or self-hosted instance
     Workflow configuration
     API credential management

  Future Enhancement Suggestions
  🤖 Advanced company trend analysis
  📊 Multi-source intelligence gathering
  🔔 Customizable alert mechanisms
  🌐 Expanded industry tracking
  🧠 Machine learning insights generation

  Technical Considerations
  Implement robust error handling
  Use secure API authentication
  Maintain flexible data processing
  Ensure compliance with API usage guidelines

  Ethical Guidelines
  Respect business privacy
  Use data for legitimate research
  Maintain transparent information gathering
  Provide proper attribution

  Hashtag Performance Boost 🚀
  #StartupIntelligence #MarketResearch #AIWorkflow #CompanyUpdates #BusinessIntelligence #TechInnovation #DataAutomation #StartupEcosystem #InvestorInsights #TrendTracking

  Workflow Visualization

  [Manual/Scheduled Trigger]
      ⬇️
  [Fetch Crunchbase Updates]
      ⬇️
  [Extract Company Details]
      ⬇️
  [AI Summarization]
      ⬇️
  [Send Email Digest]

  Connect With Me

  Ready to revolutionize your startup intelligence?

  📧 Email: Yaron@nofluff.online

  🎥 YouTube: @YaronBeen

  💼 LinkedIn: Yaron Been

  Transform your market research with intelligent, automated workflows!

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.gmail","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.outputParserStructured"]

workflow_json:
  {"id":"wqZWgW8ymv4cC0Dk","meta":{"instanceId":"84ad02d6104594179f43f1ce9cfe3a81637b2faedb57dafcb9e649b7542988db","templateCredsSetupCompleted":true},"name":"Crunchbase Startup Activity Monitor","tags":[],"nodes":[{"id":"99e036b3-48e2-401d-91aa-e16a3b1951c2","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[760,260],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"wYwTjEv45IzlAOAu","name":"OpenAi account 2"}},"typeVersion":1.2},{"id":"815b5136-f670-4302-afd2-48bb799a6085","name":"Structured Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[1000,260],"parameters":{"jsonSchemaExample":"{\n  \"subject\": \"🚀 Crunchbase Company Updates - June 5, 2025\",\n  \"body\": \"🚀 Here's a summary of recent company updates from Crunchbase:\\n\\n🔹 **OpenAI**\\nAI research and deployment company.\\nIndustry: Artificial Intelligence, Machine Learning\\nLocation: San Francisco, USA\\nLast Updated: June 5, 2025\\n\\n🔹 **DeepMind**\\nSolving intelligence to benefit humanity.\\nIndustry: Deep Learning, Healthcare\\nLocation: London, GBR\\nLast Updated: June 5, 2025\"\n}\n"},"typeVersion":1.2},{"id":"c11c92e9-6ec1-42a9-885a-636677735131","name":"Trigger Manual Test","type":"n8n-nodes-base.manualTrigger","position":[0,0],"parameters":{},"typeVersion":1},{"id":"18b76b77-e9ec-4f57-a2d5-74d80daeaa14","name":"Fetch Crunchbase Updates","type":"n8n-nodes-base.httpRequest","position":[220,0],"parameters":{"url":"https://api.crunchbase.com/api/v4/entities/organizations","options":{},"sendQuery":true,"sendHeaders":true,"queryParameters":{"parameters":[{"name":"user_key","value":"YOUR_API_KEY"},{"name":"updated_since","value":"2025-06-05"}]},"headerParameters":{"parameters":[{"name":"Accept","value":"application/json"}]}},"typeVersion":4.2},{"id":"5a5391e9-99f2-4658-879f-8e3c29d10511","name":"Extract Company Details","type":"n8n-nodes-base.set","position":[440,0],"parameters":{"options":{},"assignments":{"assignments":[{"id":"4bebf879-2d02-4fa8-ac71-91b7d83d3ed9","name":"data.items[0].properties.name","type":"string","value":"={{ $json.data.items[0].properties.name }}"},{"id":"31995946-952d-4dc3-ad4d-1bd925c11716","name":"data.items[0].properties.short_description","type":"string","value":"={{ $json.data.items[0].properties.short_description }}"},{"id":"2e3bd9f3-0c2a-49f5-b556-a392bb221790","name":"data.items[0].properties.categories","type":"string","value":"={{ $json.data.items[0].properties.categories }}"},{"id":"6af96090-ee35-49bd-9c08-a41b7f0c2e64","name":"data.items[0].properties.city_name","type":"string","value":"={{ $json.data.items[0].properties.city_name }}"},{"id":"ccb2b151-9184-4a50-8c80-b12ba95a13b3","name":"data.items[0].properties.country_code","type":"string","value":"={{ $json.data.items[0].properties.country_code }}"},{"id":"839bd2ea-e287-4fb7-902c-b7ea702692aa","name":"data.items[0].properties.updated_at","type":"string","value":"={{ $json.data.items[0].properties.updated_at }}"}]}},"typeVersion":3.4},{"id":"76b02289-ec75-4fc1-887e-b2ba0bc4d814","name":"Summarizer Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[800,0],"parameters":{"text":"=Name: {{ $json.data.items[0].properties.name }}\nDescription: {{ $json.data.items[0].properties.short_description }}\ncategories: {{ $json.data.items[0].properties.categories }}\ncity name: {{ $json.data.items[0].properties.city_name }}\ncountry name: {{ $json.data.items[0].properties.country_code }}\nupdated at: {{ $json.data.items[0].properties.updated_at }}","options":{"systemMessage":"You are a helpful assistant that writes email-ready summaries of recent company updates from Crunchbase. \n\nThe input contains data about recently updated organizations including their name, description, categories, location, and update time.\n\nSummarize the companies clearly in a professional tone. Include:\n- Company name (bold or highlighted)\n- One-line description\n- Industry/categories (comma-separated)\n- Location (City, Country)\n- Last updated time (formatted)\n\nFormat it for a human reader in plain text or HTML for email use. Use line breaks or bullet points to separate companies.\nAvoid repeating keys or technical jargon.\n"},"promptType":"define","hasOutputParser":true},"typeVersion":1.9},{"id":"a6cd42af-6785-4b25-bdd9-f66badc98a65","name":"Send Email with Summary","type":"n8n-nodes-base.gmail","position":[1340,0],"webhookId":"99a34399-48a4-4133-a5d0-9852d7e383de","parameters":{"sendTo":"shahkar.genai@gmail.com","message":"={{ $json.output.body }}","options":{"appendAttribution":false},"subject":"={{ $json.output.subject }}"},"credentials":{"gmailOAuth2":{"id":"noKcKj5FEpHHvboL","name":"Gmail account"}},"typeVersion":2.1},{"id":"1036ea4c-3106-406f-b0c4-6b40b70a47f1","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-40,-1280],"parameters":{"color":3,"width":640,"height":1460,"content":"## 🔹 **SECTION 1: Data Collection & Preprocessing**\n\n### 📍 Nodes Involved:\n\n* ✅ `Trigger Manual Test`\n* 🌐 `Fetch Crunchbase Updates`\n* ✏️ `Extract Company Details`\n\n---\n\n### 🧩 1. `Trigger Manual Test` 🖱️\n\n**Purpose:** This node is just for testing. It lets you **manually start** your workflow with a click.\n\n> 💡 In production, replace this with a **cron node** ⏰ if you want this workflow to run **automatically every day**.\n\n---\n\n### 🌐 2. `Fetch Crunchbase Updates` (HTTP Request)\n\n**Purpose:** This node sends a request to the [Crunchbase API](https://data.crunchbase.com/docs) to **fetch companies updated in the last 24 hours**.\n\n🔧 Here's what it does:\n\n* Makes a **GET request** to:\n  `https://api.crunchbase.com/api/v4/entities/organizations`\n* Adds parameters:\n\n  * `user_key`: Your Crunchbase API key 🔐\n  * `updated_since`: Yesterday’s date 📅\n\n> ✅ It returns a **list of updated companies** including names, descriptions, locations, and industries.\n\n---\n\n### ✏️ 3. `Extract Company Details`\n\n**Purpose:** Crunchbase API data can be complex. This node simplifies things.\n\n🛠 It:\n\n* Extracts **essential fields only** like:\n\n  * Name 🏢\n  * Description 📖\n  * Location 📍\n  * Industry 🏭\n  * Last Updated Date 🗓️\n* Prepares this data for the AI summarizer in a clean format.\n\n> 💡 This step ensures only the relevant information is passed forward, saving processing time and cost.\n\n---\n\n"},"typeVersion":1},{"id":"ccbc1ef4-0dbe-40c1-9a33-e6f6787d64d1","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[680,-1220],"parameters":{"color":5,"width":500,"height":1640,"content":"## 🧠 **SECTION 2: AI Summary + Email Delivery**\n\n### 🤖 Nodes Involved:\n\n* 🧠 `Summarize Company Updates`\n* 💬 `OpenAI Chat (GPT-4 or GPT-3.5)`\n* 🔎 `Parse JSON Email Summary`\n\n---\n\n### 🤖 4. `Summarize Company Updates` (AI Agent)\n\n**Purpose:** This is where the **magic happens**. It takes the company data and feeds it to an AI to generate a **plain-English summary**.\n\n🛠 It connects with:\n\n* `OpenAI Chat Model` (GPT-4 / 3.5):\n  Generates clear, readable summaries.\n* `Structured Output Parser`:\n  Forces the AI to return a **valid JSON object** with:\n\n  * `subject`: for the email subject line\n  * `body`: the plain text of the email\n\n📜 **System Prompt Used**:\n\n```txt\nYou are a helpful assistant that summarizes Crunchbase company updates.\n\nOutput your response strictly as valid JSON with two properties: \n- \"subject\": a string for the email subject line.\n- \"body\": a string for the email content formatted in plain text. Use \"\\n\" for new lines inside the string.\n\nDo NOT output anything other than the JSON object.  \nEnsure the JSON is well-formed with no trailing commas or syntax errors.\n```\n\n---\n\n### 🔎 5. `Parse JSON Email Summary` (Structured Output Parser)\n\n**Purpose:** Ensures that the response from the AI is valid JSON and separates `subject` and `body`.\n\n✅ Without this, n8n can't reliably extract the email content from the AI's response.\n\n---\n\n\n"},"typeVersion":1},{"id":"4688303f-35a1-4f0c-bdf8-c66326c46eea","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[1260,-360],"parameters":{"color":6,"width":300,"height":540,"content":"## 🧠 **SECTION 3: Send email with summary (Gmail)\n\n**Purpose:** Finally, this node sends you an email 📨 with the Crunchbase update summaries.\n\n🛠 It uses:\n\n* `{{$json.subject}}` for the email subject\n* `{{$json.body}}` for the content\n\n"},"typeVersion":1},{"id":"735ec384-c931-4ccd-8f10-5140beee552a","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-1460,-1280],"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":"208f299f-4fe1-406e-8014-82e47d0a9a2f","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-1460,-940],"parameters":{"color":4,"width":1289,"height":3278,"content":" 🧠 Automating Crunchbase Insights with n8n\n\n### 📈 Get Daily Company Updates → 🤖 Summarize → 📧 Email Digest\n\nThis workflow helps you stay informed on the latest company activity (from Crunchbase) by automating the entire process — fetching updates, summarizing them with AI, and emailing them to you daily.\n\n---\n\n## 🔹 **SECTION 1: Data Collection & Preprocessing**\n\n### 📍 Nodes Involved:\n\n* ✅ `Trigger Manual Test`\n* 🌐 `Fetch Crunchbase Updates`\n* ✏️ `Extract Company Details`\n\n---\n\n### 🧩 1. `Trigger Manual Test` 🖱️\n\n**Purpose:** This node is just for testing. It lets you **manually start** your workflow with a click.\n\n> 💡 In production, replace this with a **cron node** ⏰ if you want this workflow to run **automatically every day**.\n\n---\n\n### 🌐 2. `Fetch Crunchbase Updates` (HTTP Request)\n\n**Purpose:** This node sends a request to the [Crunchbase API](https://data.crunchbase.com/docs) to **fetch companies updated in the last 24 hours**.\n\n🔧 Here's what it does:\n\n* Makes a **GET request** to:\n  `https://api.crunchbase.com/api/v4/entities/organizations`\n* Adds parameters:\n\n  * `user_key`: Your Crunchbase API key 🔐\n  * `updated_since`: Yesterday’s date 📅\n\n> ✅ It returns a **list of updated companies** including names, descriptions, locations, and industries.\n\n---\n\n### ✏️ 3. `Extract Company Details`\n\n**Purpose:** Crunchbase API data can be complex. This node simplifies things.\n\n🛠 It:\n\n* Extracts **essential fields only** like:\n\n  * Name 🏢\n  * Description 📖\n  * Location 📍\n  * Industry 🏭\n  * Last Updated Date 🗓️\n* Prepares this data for the AI summarizer in a clean format.\n\n> 💡 This step ensures only the relevant information is passed forward, saving processing time and cost.\n\n---\n\n## 🧠 **SECTION 2: AI Summary + Email Delivery**\n\n### 🤖 Nodes Involved:\n\n* 🧠 `Summarize Company Updates`\n* 💬 `OpenAI Chat (GPT-4 or GPT-3.5)`\n* 🔎 `Parse JSON Email Summary`\n* 📬 `Send Email with Summary`\n\n---\n\n### 🤖 4. `Summarize Company Updates` (AI Agent)\n\n**Purpose:** This is where the **magic happens**. It takes the company data and feeds it to an AI to generate a **plain-English summary**.\n\n🛠 It connects with:\n\n* `OpenAI Chat Model` (GPT-4 / 3.5):\n  Generates clear, readable summaries.\n* `Structured Output Parser`:\n  Forces the AI to return a **valid JSON object** with:\n\n  * `subject`: for the email subject line\n  * `body`: the plain text of the email\n\n📜 **System Prompt Used**:\n\n```txt\nYou are a helpful assistant that summarizes Crunchbase company updates.\n\nOutput your response strictly as valid JSON with two properties: \n- \"subject\": a string for the email subject line.\n- \"body\": a string for the email content formatted in plain text. Use \"\\n\" for new lines inside the string.\n\nDo NOT output anything other than the JSON object.  \nEnsure the JSON is well-formed with no trailing commas or syntax errors.\n```\n\n---\n\n### 🔎 5. `Parse JSON Email Summary` (Structured Output Parser)\n\n**Purpose:** Ensures that the response from the AI is valid JSON and separates `subject` and `body`.\n\n✅ Without this, n8n can't reliably extract the email content from the AI's response.\n\n---\n\n### 📧 6. `Send Email with Summary` (Gmail)\n\n**Purpose:** Finally, this node sends you an email 📨 with the Crunchbase update summaries.\n\n🛠 It uses:\n\n* `{{$json.subject}}` for the email subject\n* `{{$json.body}}` for the content\n\n> 💡 You can configure this to send it to your **team**, **investors**, or even yourself daily to stay updated.\n\n---\n\n## 🏁 What This Workflow Does for You\n\n✨ **Effortlessly monitor industry trends**\n📬 **Get a beautifully summarized digest every day**\n⏳ **Save hours of manual research**\n💡 **Perfect for startup founders, analysts, investors, and marketers**\n\n---\n\n## ✅ Bonus Tip for Beginners\n\nTo make this **run automatically every day**, add this node at the top:\n\n* 🕒 `Cron Node`\n  Set schedule: every day at 8 AM (or whenever you like)\n\n---\n"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"5812b502-7fa9-4497-bcaa-3d0866c70c89","connections":{"Summarizer Agent":{"main":[[{"node":"Send Email with Summary","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Summarizer Agent","type":"ai_languageModel","index":0}]]},"Trigger Manual Test":{"main":[[{"node":"Fetch Crunchbase Updates","type":"main","index":0}]]},"Extract Company Details":{"main":[[{"node":"Summarizer Agent","type":"main","index":0}]]},"Fetch Crunchbase Updates":{"main":[[{"node":"Extract Company Details","type":"main","index":0}]]},"Structured Output Parser":{"ai_outputParser":[[{"node":"Summarizer Agent","type":"ai_outputParser","index":0}]]}}}


name: Automated Job Hunter: Upwork Opportunity Aggregator & AI-Powered Notifier
author_name: Yaron Been
author_username: yaron-nofluff
categories: []
created_at: 2025-06-06T13:44:04.045Z
updated_at: 2025-06-06T13:44:04.045Z
url: https://n8n.io/workflows/4733
scraped_at: 2025-07-06 21:16:30
description:
  🚀 Automated Job Hunter: Upwork Opportunity Aggregator & AI-Powered Notifier!

  Workflow Overview
  This cutting-edge n8n automation is a sophisticated job discovery and notification tool designed to transform freelance job hunting into a seamless, intelligent process. By intelligently connecting Apify, OpenAI, Google Sheets, and Gmail, this workflow:

  Discovers Job Opportunities: 
     Automatically scrapes Upwork job listings
     Tracks recent freelance opportunities
     Eliminates manual job searching efforts

  Intelligent Data Processing:
     Filters and extracts key job details
     Structures job information
     Ensures comprehensive opportunity tracking

  AI-Powered Summarization:
     Generates concise job summaries
     Creates human-readable job digests
     Provides quick, actionable insights

  Seamless Notification:
     Automatically logs jobs to Google Sheets
     Sends personalized email digests
     Enables rapid opportunity assessment

  Key Benefits
  🤖 Full Automation: Zero-touch job discovery
  💡 Smart Filtering: Targeted job opportunities
  📊 Comprehensive Tracking: Detailed job market insights
  🌐 Multi-Platform Synchronization: Seamless data flow

  Workflow Architecture

  🔹 Stage 1: Job Discovery
  Scheduled Trigger**: Daily job scanning
  Apify Integration**: Upwork job scraping
  Intelligent Filtering**:
    Recent job postings
    Specific keywords
    Relevant opportunities

  🔹 Stage 2: Data Extraction
  Comprehensive Job Metadata Parsing**
  Key Information Retrieval**
  Structured Data Preparation**

  🔹 Stage 3: AI Summarization
  OpenAI GPT Processing**
  Professional Summary Generation**
  Contextual Job Insight Creation**

  🔹 Stage 4: Multi-Platform Distribution
  Google Sheets Logging**
  Gmail Integration**
  Automated Job Digest Delivery**

  Potential Use Cases
  Freelancers**: Opportunity tracking
  Job Seekers**: Automated job discovery
  Recruitment Agencies**: Market intelligence
  Skill Development Professionals**: Trend monitoring
  Career Coaches**: Client opportunity identification

  Setup Requirements
  Apify
     Upwork scraping actor
     API token
     Configured scraping parameters

  OpenAI API
     GPT model access
     Summarization configuration
     API key management

  Google Sheets
     Connected Google account
     Prepared job tracking spreadsheet
     Appropriate sharing settings

  Gmail Account
     Connected email
     Job digest configuration
     Appropriate sending permissions

  n8n Installation
     Cloud or self-hosted instance
     Workflow configuration
     API credential management

  Future Enhancement Suggestions
  🤖 Advanced job matching algorithms
  📊 Multi-platform job aggregation
  🔔 Customizable alert mechanisms
  🌐 Expanded job category tracking
  🧠 Machine learning job recommendation

  Technical Considerations
  Implement robust error handling
  Use secure API authentication
  Maintain flexible data processing
  Ensure compliance with platform guidelines

  Ethical Guidelines
  Respect job poster privacy
  Use data for legitimate job searching
  Maintain transparent information gathering
  Provide proper attribution

  Hashtag Performance Boost 🚀
  #FreelanceJobHunting #CareerAutomation #JobDiscovery #AIJobSearch #WorkflowAutomation #FreelanceTech #CareerIntelligence #JobMarketInsights #ProfessionalNetworking #TechJobSearch

  Workflow Visualization

  [Daily Trigger]
      ⬇️
  [Fetch Upwork Jobs]
      ⬇️
  [Format Job Fields]
      ⬇️
  [Log to Google Sheets]
      ⬇️
  [AI Summarization]
      ⬇️
  [Send Email Digest]

  Connect With Me

  Ready to revolutionize your job hunting strategy?

  📧 Email: Yaron@nofluff.online

  🎥 YouTube: @YaronBeen

  💼 LinkedIn: Yaron Been

  Transform your job search with intelligent, automated workflows!

nodes_used:
  ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.gmail","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.outputParserStructured"]

workflow_json:
  {"id":"Q4LhFRDraaQuorBs","meta":{"instanceId":"84ad02d6104594179f43f1ce9cfe3a81637b2faedb57dafcb9e649b7542988db","templateCredsSetupCompleted":true},"name":"Upwork Job Aggregator & Notifier","tags":[],"nodes":[{"id":"834d0a42-1398-4cd4-aaf3-b1164e00b4a8","name":"Daily Upwork Job Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[0,0],"parameters":{"rule":{"interval":[{"triggerAtHour":9}]}},"typeVersion":1.2},{"id":"a0d54dfe-fc68-4020-b2ed-d191a57d5897","name":"Fetch Upwork Jobs (Apify)","type":"n8n-nodes-base.httpRequest","position":[220,0],"parameters":{"url":"https://api.apify.com/v2/actor-tasks/<YOUR_TASK_ID>/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>","method":"POST","options":{}},"typeVersion":4.2},{"id":"a9812fc7-0fa5-492a-91aa-392d0c8ee43b","name":"Format Job Fields","type":"n8n-nodes-base.set","position":[440,0],"parameters":{"options":{},"assignments":{"assignments":[{"id":"24bd782a-a34f-4b98-8d8f-21763181677b","name":"title","type":"string","value":"={{ $json.title }}"},{"id":"ee879b3d-339a-44c2-9e11-f653edab2e7f","name":"url","type":"string","value":"={{ $json.url }}"},{"id":"b5ff7975-667b-4997-ac8f-acbe9a3b3b85","name":"description","type":"string","value":"={{ $json.description }}"},{"id":"29051fc3-e4f8-4e39-a024-d7b943271acc","name":"budget","type":"string","value":"={{ $json.budget }}"},{"id":"a6492128-a58a-4735-b427-12265f81da3a","name":"datePosted","type":"string","value":"={{ $json.datePosted }}"}]}},"typeVersion":3.4},{"id":"a996aa35-8f0d-4e1a-997b-4aadd402f65c","name":"Log Jobs to Google Sheet","type":"n8n-nodes-base.googleSheets","position":[740,0],"parameters":{"columns":{"value":{"url":"={{ $json.url }}","title":"={{ $json.title }}","budget":"={{ $json.budget }}","datePosted":"={{ $json.datePosted }}","description":"={{ $json.description }}"},"schema":[{"id":"title","type":"string","display":true,"required":false,"displayName":"title","defaultMatch":false,"canBeUsedToMatch":true},{"id":"url","type":"string","display":true,"required":false,"displayName":"url","defaultMatch":false,"canBeUsedToMatch":true},{"id":"description","type":"string","display":true,"required":false,"displayName":"description","defaultMatch":false,"canBeUsedToMatch":true},{"id":"budget","type":"string","display":true,"required":false,"displayName":"budget","defaultMatch":false,"canBeUsedToMatch":true},{"id":"datePosted","type":"string","display":true,"required":false,"displayName":"datePosted","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/1dEU6uMB4ehiGXjIExjtFQHvUjANRODawKMBGKDaTcEc/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1dEU6uMB4ehiGXjIExjtFQHvUjANRODawKMBGKDaTcEc","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1dEU6uMB4ehiGXjIExjtFQHvUjANRODawKMBGKDaTcEc/edit?usp=drivesdk","cachedResultName":"Upwork Scraper"}},"credentials":{"googleSheetsOAuth2Api":{"id":"v021NCWuTwSSSXPP","name":"Google Sheets account 2"}},"typeVersion":4.5},{"id":"e0cd68e5-4d6d-479a-8a48-1faccc9f3ff7","name":"Summarize Job Listings","type":"@n8n/n8n-nodes-langchain.agent","position":[960,0],"parameters":{"text":"=Provide a summary of the upwork jobs. It should be in email format\n\nTitle: {{ $json.title }}\nURL: {{ $json.url }}\nDescription:{{ $json.description }}\nBudget:{{ $json.budget }}\nDate posted: {{ $json.datePosted }}","options":{},"promptType":"define","hasOutputParser":true},"typeVersion":1.9},{"id":"30002e32-6046-4e5c-a27f-a0d58f380ae9","name":"Send Job Summary Email","type":"n8n-nodes-base.gmail","position":[1500,0],"webhookId":"6937d724-5ede-4c56-83fd-fde84496eabd","parameters":{"sendTo":"shahkar.genai@gmail.com","message":"={{ $json.output.Summary }}","options":{},"subject":"={{ $json.output.subject }}"},"credentials":{"gmailOAuth2":{"id":"YMHjS2nJsRGP7svY","name":"Gmail account"}},"typeVersion":2.1},{"id":"a1fb5d66-b780-4b6b-96be-3391b6196301","name":"OpenAI Job Summarizer","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[900,260],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"wYwTjEv45IzlAOAu","name":"OpenAi account 2"}},"typeVersion":1.2},{"id":"f79a7336-80fc-4832-862b-51d0d737d5a3","name":"Parse Summary Output","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[1160,260],"parameters":{"jsonSchemaExample":"{\n  \"subject\": \"Upwork Job Opportunity: Webflow Expert Needed for Portfolio Website\",\n  \"Summary\": \"The client is seeking a designer with strong experience in Webflow to create a responsive and elegant portfolio site.\"\n}\n"},"typeVersion":1.2},{"id":"85465ead-0a06-455c-9308-866c092d8ef5","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-60,-560],"parameters":{"color":3,"width":640,"height":760,"content":"### 🔁 **Section 1: Job Fetch & Preparation**\n\n📦 **Group Name**: `📥 Fetch & Prepare Upwork Jobs`\n\n#### ✅ **Included Nodes:**\n\n1. `🕒 Daily Upwork Job Trigger`\n2. `🌐 Fetch Upwork Jobs (Apify)`\n3. `🛠️ Format Job Fields`\n\n#### 📋 **What this group does:**\n\nThis group is responsible for automatically triggering the job search, pulling fresh job data from Upwork (via Apify), and formatting that data into a clean, structured format.\n\n#### 📌 **Highlights:**\n\n* Uses Apify’s `run-sync-get-dataset-items` to ensure you get fresh job results in one go.\n* Ensures only the required fields (like title, URL, budget) are passed forward.\n* Keeps your data clean and minimal for logging and summarization.\n\n---"},"typeVersion":1},{"id":"3699ba73-75ee-4bf2-91eb-8d0d05143321","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[680,-620],"parameters":{"color":5,"width":620,"height":1040,"content":"### 📊 **Section 2: Data Logging & Summary Generation**\n\n📦 **Group Name**: `🧾 Log & Summarize Jobs`\n\n#### ✅ **Included Nodes:**\n\n1. `📈 Log Jobs to Google Sheet`\n2. `🤖 Summarize Job Listings`\n\n   * `🧠 OpenAI Job Summarizer`\n   * `📄 Parse Summary Output`\n\n#### 📋 **What this group does:**\n\nThis group handles the dual responsibility of:\n\n* Persistently logging all job entries to a **Google Sheet**\n* Generating a human-friendly **natural language summary** of the fetched jobs using the OpenAI model and parsing the result into clean output\n\n#### 💡 **Why this matters:**\n\n* Keeps historical records in Sheets ✅\n* Makes email digest more meaningful and less overwhelming for the reader 🧠\n\n---\n\n"},"typeVersion":1},{"id":"2289feb5-9ab1-4dbb-a77e-f4742f0f341d","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[1400,-420],"parameters":{"color":6,"width":340,"height":600,"content":"## 📤 **Section 3: Job Summary Notification**\n\n📦 **Group Name**: `✉️ Notify via Email`\n\n#### ✅ **Included Node:**\n\n1. `📧 Send Job Summary Email`\n\n#### 📋 **What this group does:**\n\nSends a **summary email** to the desired recipient(s) with the content generated by the AI agent.\n\n"},"typeVersion":1},{"id":"95727922-4856-4481-acff-519638ac5d23","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-1520,-560],"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":"c161b105-70a6-431a-91e2-9031ccba8fe4","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-1520,-220],"parameters":{"color":4,"width":1289,"height":3058,"content":"# ✅ n8n Automation: \"Upwork Job Aggregator & Notifier\"\n\n> **Purpose**: Automatically fetch job postings from Upwork with specific keywords, save them in Google Sheets, summarize them using AI, and email the results daily (or at any interval you want).\n\n---\n\n## 🧱 HIGH-LEVEL OVERVIEW\n\n| Feature         | Description                                          |\n| --------------- | ---------------------------------------------------- |\n| 🕐 Trigger      | Scheduled (e.g., every 6 hours)                      |\n| 🌐 Source       | [Apify](https://apify.com) actor for Upwork scraping |\n| 📄 Storage      | Google Sheets                                        |\n| 🧠 Summary      | OpenAI model with structured output                  |\n| 📬 Notification | Gmail with formatted job summary                     |\n\n---\n\n## 🧠 GROUP 1: 📥 Fetch & Prepare Upwork Jobs\n\n### 🟢 Nodes:\n\n1. `🕒 Daily Upwork Job Trigger`\n\n   * **Type**: Cron Trigger\n   * **Purpose**: Runs the flow automatically at your set interval (e.g., every 6 hours or daily)\n\n2. `🌐 Fetch Upwork Jobs (Apify)`\n\n   * **Type**: HTTP Request\n   * **Method**: POST\n   * **URL**: `https://api.apify.com/v2/actor-tasks/<TASK_ID>/run-sync-get-dataset-items?token=<API_TOKEN>`\n   * **Purpose**: Calls your Apify Upwork Scraper task to get the latest job listings\n   * **Output**: JSON array of job objects\n\n3. `🛠️ Format Job Fields`\n\n   * **Type**: Edit Fields (Set or Function Node)\n   * **Purpose**: Extracts needed job fields like `title`, `url`, `description`, `budget`, and `datePosted`\n   * **Reason**: Makes data uniform for Sheet storage and AI summary\n\n---\n\n## 📊 GROUP 2: 🧾 Log & Summarize Jobs\n\n### 🟢 Nodes:\n\n4. `📈 Log Jobs to Google Sheet`\n\n   * **Type**: Google Sheets → Append Sheet\n   * **Sheet Setup**: Must have headers like `Title`, `URL`, `Description`, `Budget`, `Date`\n   * **Purpose**: Appends each new job as a row in the sheet for historical tracking\n\n5. `🤖 Summarize Job Listings` (AI Agent node group)\n\n   * **Type**: Tools Agent (LangChain / OpenAI Integration)\n   * **Connected Sub-Nodes**:\n\n     * `🧠 OpenAI Job Summarizer` (OpenAI Chat Model)\n\n       * **Prompt** example:\n\n         ```\n         You are an assistant summarizing freelance job postings. Summarize each job in 1-2 lines. Include title, budget, and a short description.\n         ```\n     * `📄 Parse Summary Output` (Structured Output Parser)\n\n       * **Purpose**: Converts the AI response into structured n8n items\n   * **Input**: Job data from Google Sheets\n   * **Output**: A clear, natural language summary of all jobs\n\n---\n\n## 📤 GROUP 3: ✉️ Notify via Email\n\n### 🟢 Node:\n\n6. `📧 Send Job Summary Email`\n\n   * **Type**: Gmail → Send Message\n\n   * **Authentication**: Google OAuth2\n\n   * **To**: Yourself or your team\n\n   * **Subject**: `\"🚀 New Upwork Jobs Found!\"`\n\n   * **Body**:\n\n     ```\n     Hello,\n\n     Here’s a summary of the latest Upwork jobs matching your criteria:\n\n     {{summary from AI}}\n\n     ➕ View full job list here: [Google Sheet Link]\n\n     Best,  \n     Your Automation Bot 🤖\n     ```\n\n   * **Error Handling**: Add an IF node to prevent email if no jobs were returned (optional)\n\n---\n\n## 🗂 Suggested Color-Coded Groups in n8n:\n\n| Group                          | Nodes                                | Color     | Description                     |\n| ------------------------------ | ------------------------------------ | --------- | ------------------------------- |\n| 📥 Fetch & Prepare Upwork Jobs | Trigger, HTTP Request, Format Fields | 🟢 Green  | Gets data and prepares it       |\n| 🧾 Log & Summarize Jobs        | Google Sheets, AI Agent, Parser      | 🟡 Yellow | Logs + creates smart summaries  |\n| ✉️ Notify via Email            | Gmail                                | 🔴 Red    | Notifies you with clean summary |\n\n---\n\n## 🚀 ADVANTAGES\n\n✅ Completely automated\n✅ Saves all job history\n✅ AI-enhanced summaries\n✅ Instant email alerts\n✅ Easy to expand or customize\n\n---\n\n## 🧩 Bonus Enhancements (Optional)\n\n| Idea                      | Description                                                   |\n| ------------------------- | ------------------------------------------------------------- |\n| 🔍 Add keyword filters    | Add filters before saving to Sheets (e.g., only “React” jobs) |\n| 🕵️‍♂️ Prevent duplicates | Store job IDs and check before saving                         |\n| 📣 Add Slack alerts       | Add Slack node for team notification                          |\n| 📊 Dashboard              | Build Google Data Studio report over the Sheet                |\n\n---\n\n\n"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"8c929fc6-2198-4adf-89c3-ff0a2b296fdd","connections":{"Format Job Fields":{"main":[[{"node":"Log Jobs to Google Sheet","type":"main","index":0}]]},"Parse Summary Output":{"ai_outputParser":[[{"node":"Summarize Job Listings","type":"ai_outputParser","index":0}]]},"OpenAI Job Summarizer":{"ai_languageModel":[[{"node":"Summarize Job Listings","type":"ai_languageModel","index":0}]]},"Summarize Job Listings":{"main":[[{"node":"Send Job Summary Email","type":"main","index":0}]]},"Daily Upwork Job Trigger":{"main":[[{"node":"Fetch Upwork Jobs (Apify)","type":"main","index":0}]]},"Log Jobs to Google Sheet":{"main":[[{"node":"Summarize Job Listings","type":"main","index":0}]]},"Fetch Upwork Jobs (Apify)":{"main":[[{"node":"Format Job Fields","type":"main","index":0}]]}}}


name: AI Blog Generator for Shopify Product listings: Using GPT-4o and Google Sheets
author_name: Kumar Shivam
author_username: shivam840708
categories: []
created_at: 2025-06-06T15:00:32.038Z
updated_at: 2025-06-06T15:00:32.038Z
url: https://n8n.io/workflows/4735
scraped_at: 2025-07-06 21:16:30
description:
  🧠 AI Blog Generator for Shopify Products using GPT-4o

  The AI Blog Generator is an advanced automation workflow powered by n8n, integrating GPT-4o and Google Sheets to generate SEO-rich blog articles for Shopify products. It automates the entire process — from pulling product data, analyzing images for nutritional information, to producing structured HTML content ready for publishing — with zero manual writing.

  💡 Key Advantages

  🔗 Shopify Product Sync**  
    Automatically pulls product data (title, description, images, etc.) via Shopify API.

  🤖 AI-Powered Nutrition Extraction**  
    Uses GPT-4o to intelligently analyze product images and extract nutritional information.

  ✍️ SEO Blog Generation**  
    GPT-4o generates blog titles, meta descriptions, and complete articles using both product metadata and extracted nutritional info.

  🗂️ Structured Content Output**  
    Produces well-formatted HTML with headers, bullet points, and nutrition tables for seamless Shopify blog integration.

  📄 Google Sheets Integration**  
    Tracks blog creation, manages retries, and prevents duplicate publishing using a centralized Google Sheet.

  📤 Shopify Blog API Integration**  
    Publishes the generated blog to Shopify using a two-step blog + article API call.

  ⚙️ How It Works

  Manual Trigger  
     Initiate the process using a test trigger or a scheduler.

  Fetch Products from Shopify  
     Retrieves all product details including descriptions and images.

  Extract Product Images  
     Splits and processes each image individually.

  OCR + Nutrition AI  
     GPT-4o reads nutrition facts from product images. Skips items without valid info.

  Check Existing Logs  
     References a Google Sheet to avoid duplicates and determine retry status.

  AI Blog Generation  
     Creates a blog with headings, bullet points, intro, and a nutrition table.

  Shopify Blog + Article Posting  
     Uses the Shopify API to publish the blog and its content.

  Update Google Sheet  
     Logs the blog URL, HTML content, errors, and status for future reference.

  🛠️ Setup Steps

  Shopify Node**: Connects to your Shopify store and fetches product data.  
  Split Out Node**: Divides product images for individual OCR processing.  
  OpenAI Node**: Uses GPT-4o to extract nutrition data from images.  
  If Node**: Filters for entries with valid nutrition information.  
  Edit Fields Node**: Formats the product data for AI processing.  
  AI Agent Node**: Generates SEO blog content.  
  Google Sheets Nodes**: Reads and updates blog creation status.  
  HTTP Request Nodes**: Posts the blog and article via Shopify’s API.

  🔐 Credentials Required

  Shopify Access Token** – For retrieving product data and posting blogs  
  OpenAI API Key** – For GPT-4o-based AI generation and image processing  
  Google Sheets OAuth** – For accessing the log sheet

  👤 Ideal For

  Ecommerce teams looking to automate content for hundreds of products  
  Shopify store owners aiming to boost organic traffic through blogging  
  Marketing teams building scalable, AI-driven content workflows

  💬 Bonus Tip

  The workflow is modular. You can easily extend it with internal linking, language translation, or even social media sharing — all within the same n8n flow.

nodes_used:
  ["n8n-nodes-base.shopify","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.memoryBufferWindow","@n8n/n8n-nodes-langchain.openAi"]

workflow_json:
  {"meta":{"instanceId":"d73282515b90623d4a8783919a2d772c706425d649e1512792f37ac51e07e4a8","templateCredsSetupCompleted":true},"nodes":[{"id":"096ccd11-0ae4-4e3d-aeac-d180c09512ae","name":"When clicking ‘Test workflow’","type":"n8n-nodes-base.manualTrigger","position":[300,180],"parameters":{},"typeVersion":1},{"id":"c95491ab-6e4e-4671-bfaf-b8a362d2ec01","name":"Shopify","type":"n8n-nodes-base.shopify","position":[580,180],"parameters":{"resource":"product","operation":"getAll","returnAll":true,"authentication":"accessToken","additionalFields":{}},"credentials":{"shopifyAccessTokenApi":{"id":"oPLCxaUiftgs7Mna","name":"Shopify Access Token account"}},"typeVersion":1},{"id":"1620e19b-cd01-4798-858c-8f2fb3d58087","name":"Split Out","type":"n8n-nodes-base.splitOut","position":[840,180],"parameters":{"options":{},"fieldToSplitOut":"images"},"typeVersion":1},{"id":"944ab8ba-6e41-4e04-b442-9468ff341ba0","name":"OpenAI","type":"@n8n/n8n-nodes-langchain.openAi","position":[1060,180],"parameters":{"text":"=You are an expert OCR and nutrition facts extractor. You carefully extract only the exact nutritional data present in the image without fabricating or guessing. You can recognize nutritional facts tables, and you know how to distinguish between actual nutrition data and promotional or partial text. You return null if no clear nutrition facts table or readable nutritional information is present.\n\n\nYou will analyze an image containing a product's nutritional information. Extract all nutritional data exactly as shown in the image, including nutrient names, amounts, units, and daily values if present.\n\n- If the image clearly contains a nutritional facts table or full nutritional data, output it in clean JSON format, where each nutrient is a key and the value contains the amount, unit, and daily value if available.\n- If the image shows only partial, blurry, or promotional text like \"20% protein\" or any incomplete nutritional data, do NOT fabricate any values; instead, return null.\n- If there is no clear nutritional facts table or nutritional data visible in the image, return null.\n- Do not guess or invent any numbers.\n- Only include information that is confidently present and readable in the image.\n\nExample output when nutrition facts are present:\n\n{\n  \"Calories\": \"190\",\n  \"Total Fat\": {\n    \"amount\": \"8g\",\n    \"daily_value\": \"10%\"\n  },\n  \"Cholesterol\": {\n    \"amount\": \"0mg\",\n    \"daily_value\": \"0%\"\n  },\n  ...\n}\n\nExample output when no valid nutritional facts table or data is visible:\n\nnull\n","modelId":{"__rl":true,"mode":"list","value":"chatgpt-4o-latest","cachedResultName":"CHATGPT-4O-LATEST"},"options":{"detail":"auto","maxTokens":900},"resource":"image","imageUrls":"={{ $json.src }}","operation":"analyze"},"credentials":{"openAiApi":{"id":"OizdHUANhz9NIHyd","name":"OpenAi account"}},"typeVersion":1.8},{"id":"390bd7e4-b7bc-4575-9fe4-36a81445c7d3","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[1480,580],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"OizdHUANhz9NIHyd","name":"OpenAi account"}},"typeVersion":1.2},{"id":"de84b88d-e96e-4c3c-a9f9-71cfc413022e","name":"If","type":"n8n-nodes-base.if","position":[1240,180],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"6aa4dfe1-d907-47e8-b97e-3a77bb30c1d0","operator":{"type":"string","operation":"notEquals"},"leftValue":"={{ $json.content }}","rightValue":"null"}]}},"typeVersion":2.2},{"id":"9ef20e21-7ad8-409f-a13e-e1088ec4e4a3","name":"No Operation, do nothing","type":"n8n-nodes-base.noOp","position":[1240,440],"parameters":{},"typeVersion":1},{"id":"0cfadf47-06c7-4b00-b660-87241cc4bf4c","name":"Create Blog id","type":"n8n-nodes-base.httpRequestTool","position":[2500,620],"parameters":{"url":"=https://smartworkflow.myshopify.com/admin/api/2024-01/blogs.json","method":"POST","options":{},"jsonBody":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('JSON', ``, 'json') }}","sendBody":true,"specifyBody":"json","authentication":"predefinedCredentialType","nodeCredentialType":"shopifyAccessTokenApi"},"credentials":{"shopifyAccessTokenApi":{"id":"oPLCxaUiftgs7Mna","name":"Shopify Access Token account"}},"typeVersion":4.2},{"id":"059199d7-0f80-40fc-9f45-ee4ef8d6475b","name":"Create Articles","type":"n8n-nodes-base.httpRequestTool","position":[2060,620],"parameters":{"url":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('URL', ``, 'string') }}","method":"POST","options":{},"jsonBody":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('JSON', ``, 'json') }}","sendBody":true,"specifyBody":"json","authentication":"predefinedCredentialType","nodeCredentialType":"shopifyAccessTokenApi"},"credentials":{"shopifyAccessTokenApi":{"id":"oPLCxaUiftgs7Mna","name":"Shopify Access Token account"}},"typeVersion":4.2},{"id":"60d74f7d-cc66-4af6-bb8d-686c3eb320cb","name":"Read Sheet","type":"n8n-nodes-base.googleSheetsTool","position":[1880,600],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1m4yPuz7d0HYJQ1nC-v_oTN5jmYMoDy38beDGLB273B8/edit#gid=0","cachedResultName":"blog_details"},"documentId":{"__rl":true,"mode":"list","value":"1m4yPuz7d0HYJQ1nC-v_oTN5jmYMoDy38beDGLB273B8","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1m4yPuz7d0HYJQ1nC-v_oTN5jmYMoDy38beDGLB273B8/edit?usp=drivesdk","cachedResultName":"Blog update sheet"}},"credentials":{"googleSheetsOAuth2Api":{"id":"0RSJGMBcFzxY9GkS","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"75976a59-7017-4e2c-ab12-d2e3448b6566","name":"Update Sheet","type":"n8n-nodes-base.googleSheetsTool","position":[2280,600],"parameters":{"columns":{"value":{"Error":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Error', ``, 'string') }}","Retry":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Retry', ``, 'string') }}","Blog url":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Blog_url', ``, 'string') }}","Blog Html":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Blog_Html', ``, 'string') }}","Timestamp":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Timestamp', ``, 'string') }}","Product Id":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Product_Id', ``, 'string') }}","Blog title ":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Blog_title_', ``, 'string') }}","Proudct name":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Proudct_name', ``, 'string') }}"},"schema":[{"id":"Timestamp","type":"string","display":true,"required":false,"displayName":"Timestamp","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Product Id","type":"string","display":true,"removed":false,"required":false,"displayName":"Product Id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Proudct name","type":"string","display":true,"required":false,"displayName":"Proudct name","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Blog title ","type":"string","display":true,"required":false,"displayName":"Blog title ","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Blog url","type":"string","display":true,"required":false,"displayName":"Blog url","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Blog Html","type":"string","display":true,"required":false,"displayName":"Blog Html","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Retry","type":"string","display":true,"required":false,"displayName":"Retry","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Error","type":"string","display":true,"removed":false,"required":false,"displayName":"Error","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["Product Id"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"appendOrUpdate","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1m4yPuz7d0HYJQ1nC-v_oTN5jmYMoDy38beDGLB273B8/edit#gid=0","cachedResultName":"blog_details"},"documentId":{"__rl":true,"mode":"list","value":"1m4yPuz7d0HYJQ1nC-v_oTN5jmYMoDy38beDGLB273B8","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1m4yPuz7d0HYJQ1nC-v_oTN5jmYMoDy38beDGLB273B8/edit?usp=drivesdk","cachedResultName":"Blog update sheet"}},"credentials":{"googleSheetsOAuth2Api":{"id":"0RSJGMBcFzxY9GkS","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"49448095-a73a-4fdb-9354-f3e442f100b4","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[1700,580],"parameters":{"sessionKey":"={{ $('Main Product info').item.json.id }}","sessionIdType":"customKey","contextWindowLength":20},"typeVersion":1.3},{"id":"adc154d2-a1b0-4f27-b1fd-689484132308","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[500,40],"parameters":{"width":260,"height":360,"content":"## Get Products \n\n\nIt get all the product details from the shopify store"},"typeVersion":1},{"id":"d7de0bdd-2544-45fd-b4ac-264fed0d6c25","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[780,-80],"parameters":{"color":3,"height":500,"content":"## Fetches Product Image url \n\nEach Product can have multiple images it fetches image url for further step."},"typeVersion":1},{"id":"f51c03f3-a137-48ae-9b44-dee4505d1bb8","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[1040,-80],"parameters":{"color":6,"width":380,"height":500,"content":"## OCR :\nCollects Nutrients Facts \n\n* It collects Nutrients information from the product image and outputs in json format and send along the true branch of the if node.\n\n* If the image doesn't contain any related info it returns null."},"typeVersion":1},{"id":"486be3b5-dc25-4c5a-bde7-daaeff56308e","name":"Main Product info","type":"n8n-nodes-base.set","position":[1540,160],"parameters":{"options":{},"assignments":{"assignments":[{"id":"93cb8cc0-cdcd-44da-8187-9df85b770293","name":"title","type":"string","value":"={{ $('Shopify').item.json.title }}"},{"id":"95990abc-b64d-4cb4-8d4e-88145395a3fc","name":"id","type":"number","value":"={{ $('Shopify').item.json.id }}"},{"id":"d833cfa1-9abf-4a9d-86ed-a713acbc1974","name":"body_html","type":"string","value":"={{ $('Shopify').item.json.body_html }}"}]},"includeOtherFields":true},"typeVersion":3.4},{"id":"894b47e8-7da2-4a3c-b6ec-afe2e4d6f4cf","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1460,-140],"parameters":{"color":4,"width":920,"height":460,"content":"## Shopify Products Blog Mechanism:\n\n\n* It creates Seo Freindly Blog and Blog Title and post the content or article after creating blog of a       \n   specific category which can be seen on the Shopify blog section inside the store via http calls.\n\n* It first checks whether the product is already available or not in the sheet then checks whether      \n   there is need to retry the posting if there is any error. If there is error it retries posting it \n   change the retry value as no.\n* It takes two http tool call to make a blog one is Blog id creation and other is article posting via \n  Create Articles inside that particular Id.\n* Once the blog is posted all the details are updated via Update Sheet tool. If there is any error it updates it accordingly with the error message in error column"},"typeVersion":1},{"id":"6d708bbb-9c9c-419a-883b-d7e48e89e82a","name":"AI Blog Poster","type":"@n8n/n8n-nodes-langchain.agent","position":[1760,160],"parameters":{"text":"=Product id : {{ $json.id }}\nProduct title : {{ $json.title }}    \n\nProduct Description html : {{ $json.body_html }}\n\nProduct Nutrition Facts : {{ $json.content }}\n\n","options":{"systemMessage":"=You are an AI agent responsible for automating blog creation for Shopify products using Google Sheets as a tracking system.\n\n## Step-by-step Workflow:\n\n### 1. Read Google Sheet\nBefore doing anything, call the Read Sheet tool to check if a blog has already been created for the Product ID. The sheet contains columns:\n\n- Timestamp\n- Product Id\n- Product name\n- Blog title\n- Blog url\n- Blog Html\n- Retry\n- Error\n\nCall this tool first and look up the row with the same Product Id.\n\n### 2. Check Conditions:\n- If the Product Id exists and Retry = No, skip this item.\n- If Retry = Yes, retry blog creation from Step 3.\n- If the Product Id is not found, proceed to Step 3 to generate and post a new blog.\n\n---\n\n### 3. Generate Blog Content\nBased on the following provided in the user message:\n- Product ID\n- Product Title\n- Product Description HTML\n- Product Nutrition Facts \n\nGenerate:\n- SEO-Friendly Blog Title\n- Meta Description\n- Formatted Blog Content in clean, structured HTML:\n  - Introduction summary\n  - H2/H3 subheadings\n  - Bullet points (key benefits, nutrients)\n  - Nutrient callouts or tables (if available)\n  - Closing paragraph or CTA\n  - Add internal keywords (tags)\n\n---\n\n### 4. Create Blog (HTTP Tool Call)\nCall the Shopify API to create a blog:\n\njson\n{\n  \"tool_call\": {\n    \"tool\": \"http\",\n    \"name\": \"Create Blog\",\n    \"method\": \"POST\",\n    \"url\": \"https://smartworkflow.myshopify.com/admin/api/2024-01/blogs.json\",\n    \"body\": {\n      \"blog\": {\n        \"title\": \"[SEO Blog Title]\"\n      }\n    }\n  }\n}\nOnce the blog.id is returned, post the article to:\n\n\nhttps://smartworkflow.myshopify.com/admin/api/2024-01/blogs/{{blog.id}}/articles.json\njson\nCopy\nEdit\n{\n  \"tool_call\": {\n    \"tool\": \"http\",\n    \"name\": \"Create Article\",\n    \"method\": \"POST\",\n    \"url\": \"https://smartworkflow.myshopify.com/admin/api/2024-01/blogs/{{blog.id}}/articles.json\",\n    \"body\": {\n      \"article\": {\n        \"title\": \"[Same Blog Title]\",\n        \"body_html\": \"[Generated HTML content]\",\n        \"tags\": \"nutrition, wellness, product, shopify\",\n        \"published\": false\n      }\n    }\n  }\n}\n6. Update Google Sheet\nIf Blog is Posted Successfully\nCall Update Sheet tool and set:\n\n\n{\n  \"Timestamp\":{{ $now }} ,\n  \"Product Id\": \"{{ $json.id }}\",\n  \"Product name\": \"{{ $json.title }}\",\n  \"Blog title\": \"[SEO Blog Title]\",\n  \"Blog url\": \"[Generated URL from blog.id and article.id]\",\n  \"Blog Html\": \"[Generated HTML]\",\n  \"Retry\": \"No\",\n  \"Error\": \"\"\n}\nIf Blog or Article Fails\nLog the error in Error column and set Retry = Yes.\n\n\n{\n  \"Product Id\": \"{{ $json.id }}\",\n  \"Retry\": \"Yes\",\n  \"Error\": \"[Detailed error message]\"\n}\n\nNotes:\nAlways call Read Sheet first before blog generation.\n\nRetry logic is based strictly on the Retry column.\n\nAll tool call responses should be handled using proper try-catch/error-check patterns.\n\nEnsure HTML is clean and includes correct spacing, paragraphs, H2s, bullet lists, and optionally nutrient tables.\n"},"promptType":"define"},"typeVersion":1.9},{"id":"3538388e-7222-48e1-bec8-daf882e8c316","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-160,-100],"parameters":{"color":4,"width":380,"height":520,"content":"## Author \n## Kumar Shivam\n\n\nI'm an automation specialist who helps startups, agencies, and growth teams save time and scale faster using n8n. I design smart, reliable workflows that connect tools like HubSpot, Slack, OpenAI, Claude, Pipedrive, Google Ads, and vector databases (Qdrant, Pinecone). Whether it's auto-assigning leads, generating AI-powered reports, triggering Slack alerts, or syncing APIs — I build automations that just work. Let’s turn your manual processes into automated systems that scale.\n\nContact for any business enquiries :\n\nhttps://kumarshivam.link"},"typeVersion":1}],"connections":{"If":{"main":[[{"node":"Main Product info","type":"main","index":0}],[{"node":"No Operation, do nothing","type":"main","index":0}]]},"OpenAI":{"main":[[{"node":"If","type":"main","index":0}]]},"Shopify":{"main":[[{"node":"Split Out","type":"main","index":0}]]},"Split Out":{"main":[[{"node":"OpenAI","type":"main","index":0}]]},"Read Sheet":{"ai_tool":[[{"node":"AI Blog Poster","type":"ai_tool","index":0}]]},"Update Sheet":{"ai_tool":[[{"node":"AI Blog Poster","type":"ai_tool","index":0}]]},"Simple Memory":{"ai_memory":[[{"node":"AI Blog Poster","type":"ai_memory","index":0}]]},"Create Blog id":{"ai_tool":[[{"node":"AI Blog Poster","type":"ai_tool","index":0}]]},"Create Articles":{"ai_tool":[[{"node":"AI Blog Poster","type":"ai_tool","index":0}]]},"Main Product info":{"main":[[{"node":"AI Blog Poster","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Blog Poster","type":"ai_languageModel","index":0}]]},"When clicking ‘Test workflow’":{"main":[[{"node":"Shopify","type":"main","index":0}]]}}}


name: Binance Spot Market Quant AI Agent | GPT-4o + Telegram (Main Interface)
author_name: Don Jayamaha Jr
author_username: don-the-gem-dealer
categories: []
created_at: 2025-06-06T17:51:04.546Z
updated_at: 2025-06-06T17:51:04.546Z
url: https://n8n.io/workflows/4739
scraped_at: 2025-07-06 21:16:30
description:
  A professional-grade AI automation system for spot market trading insights on Binance. It analyzes multi-timeframe technical indicators, live price/order data, and crypto sentiment, then delivers fully formatted Telegram-style trading reports.

  🎥 Watch Tutorial:

  🧩 Required Workflows

  You must install and activate all of the following workflows for the system to function correctly:

  | ✅ Workflow Name                                    | 📌 Function Description                                                          |
  | -------------------------------------------------- | -------------------------------------------------------------------------------- |
  | Binance Spot Market Quant AI Agent                 | Final AI orchestrator. Parses user prompt and generates Telegram-ready reports.  |
  | Binance SM Financial Analyst Tool                  | Calls indicator tools and price/order data tools. Synthesizes structured inputs. |
  | Binance SM News and Sentiment Analyst Webhook Tool | Analyzes crypto sentiment, gives summary and headlines via POST webhook.         |
  | Binance SM Price/24hrStats/OrderBook/Kline Tool    | Pulls price, order book, 24h stats, and OHLCV klines for 15m–1d.                 |
  | Binance SM 15min Indicators Tool                   | Calculates 15m RSI, MACD, BBANDS, ADX, SMA/EMA from Binance kline data.          |
  | Binance SM 1hour Indicators Tool                   | Same as above but for 1h timeframe.                                              |
  | Binance SM 4hour Indicators Tool                   | Same as above but for 4h timeframe.                                              |
  | Binance SM 1day Indicators Tool                    | Same as above but for 1d timeframe.                                              |
  | Binance SM Indicators Webhook Tool                 | Technical backend. Handles all webhook logic for each timeframe tool.            |

  ⚙️ Installation Instructions

  Step 1: Import Workflows

  Open your n8n Editor UI
  Import each workflow JSON file one by one
  Activate them or ensure they're called via Execute Workflow

  Step 2: Set Credentials

  OpenAI API Key** (GPT-4o recommended)
  Binance endpoints** are public (no auth required)

  Step 3: Configure Webhook Endpoints

  Deploy Binance SM Indicators Webhook Tool
  Ensure the following paths are reachable:

    /webhook/15m
    /webhook/1h
    /webhook/4h
    /webhook/1d

  Step 4: Telegram Integration

  Create a Telegram bot using @BotFather
  Add your Telegram API token to n8n credentials
  Replace the Telegram ID placeholder with your own

  Step 5: Final Trigger

  Trigger the Binance Spot Market Quant AI Agent manually or from Telegram
  The agent:

    Extracts the trading pair (e.g. BTCUSDT)
    Calls all tools for market data and sentiment
    Generates a clean, HTML-formatted Telegram report

  💬 Telegram Report Output Format

  BTCUSDT Market Report

  Spot Strategy
  • Action: Buy
  • Entry: $63,800 | SL: $61,200 | TP: $66,500
  • Rationale:
   MACD Crossover (1h)
   RSI Rebound from Oversold (15m)
   Sentiment: Bullish

  Leverage Strategy
  • Position: Long 3x
  • Entry: $63,800
  • SL/TP zones same as above

  News Sentiment: Slightly Bullish  
  • "Bitcoin rallies as ETF inflows surge" – CoinDesk  
  • "Whales accumulate BTC at key support" – NewsBTC  

  🧠 System Overview

  [Telegram Trigger]
  → [Session + Auth Logic]
  → [Binance Spot Market Quant AI Agent]
  → [Financial Analyst Tool + News Tool]
  → [All Technical Indicator Tools (15m, 1h, 4h, 1d)]
  → [OrderBook/Price/Kline Fetcher]
  → [GPT-4o Reasoning]
  → [Split & Send Message to Telegram]

  🧾 Licensing & Attribution

  © 2025 Treasurium Capital Limited Company
  Architecture, prompts, and trade report structure are IP-protected.
  No unauthorized rebranding or resale permitted.

  🔗 For support: LinkedIn – Don Jayamaha

nodes_used:
  ["n8n-nodes-base.telegram","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.memoryBufferWindow","@n8n/n8n-nodes-langchain.toolWorkflow"]

workflow_json:
  {"id":"82r122lbmQPWishF","meta":{"instanceId":"a5283507e1917a33cc3ae615b2e7d5ad2c1e50955e6f831272ddd5ab816f3fb6","templateCredsSetupCompleted":true},"name":"Binance Spot Market Quant AI Agent","tags":[],"nodes":[{"id":"6c6238ec-ba3d-4c59-a612-c3b4e9ae8b73","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-440,620],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"yUizd8t0sD5wMYVG","name":"OpenAi account"}},"typeVersion":1.2},{"id":"b8b90061-9d5e-4e48-a0b0-bb6bdb193771","name":"Binance Spot Market Quant AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[-80,160],"parameters":{"text":"={{ $json.message }}","options":{"systemMessage":"You are the **Binance Spot Market Quant AI Agent**, responsible for generating structured, professional swing-trading reports for **any trading pair** on the Binance Spot Market. You use **validated technical indicators**, **order flow data**, and **curated crypto sentiment** to create actionable trading strategies.\n\n---\n\n### 🔗 Connected Tools\n\n1. **🧠 Binance Financial Market Analyst Tool**\n\n   • Aggregates outputs from:\n\n   * `Binance 15min Indicators Tool`\n   * `Binance 1h Indicators Tool`\n   * `Binance 4h Indicators Tool`\n   * `Binance 1d Indicators Tool`\n   * `Binance Price/OrderBook/Kline Tool`\n\n   • Each indicator tool calculates:\n\n   * **RSI, BBANDS, SMA, EMA, ADX, MACD**\n   * Based on the **latest 20 klines** for its interval\n   * Returns both values and signal labels (e.g. overbought, divergence)\n\n   • The Price Tool provides:\n\n   * **Live price**\n   * **24h OHLCV**\n   * **Order book depth (top 100 bids/asks)**\n   * **Klines** for `15m`, `1h`, `4h`, and `1d` intervals\n\n2. **📰 Binance News and Sentiment Analyst Tool**\n\n   • Pulls from sources like:\n\n   * CoinDesk, Cointelegraph, BitcoinMagazine, NewsBTC, CryptoBriefing, and more\n\n   • Returns:\n\n   * **Sentiment Score**: Bullish / Bearish / Neutral\n   * **Summary**: 2–3 sentence market snapshot\n   * **Top 3–5 headlines** (with source links)\n\n---\n\n### 📊 Core Responsibilities\n\nYou always:\n\n1. **Call all tools concurrently** for each query\n\n   * Pass the extracted symbol and sessionId as input\n   * Wait for structured results from each tool\n   * Do not skip any tool even if user prompt is vague\n\n2. **Perform full technical analysis** for the symbol\n\n   * Short-term: `15m + 1h`\n   * Mid-term: `4h`\n   * Long-term: `1d`\n   * Detect breakouts, trend shifts, divergences, and confluence signals\n   * Confirm findings using multiple timeframes and indicator alignment\n\n3. **Synthesize the final report** with:\n\n<b>Spot Trade Strategy</b>\n• Action: Buy / Sell / Hold\n• Entry Price, Stop Loss, Take Profit\n• Rationale:\n - <b>Price Action Signals</b>\n - <b>Lagging Indicator Confirmation</b>\n - <b>Sentiment Alignment</b>\n\n<b>Leverage Strategy</b>\n• Position: Long / Short\n• Leverage: 2x / 3x / 5x\n• Rationale + Risk Zones\n\n4. **Score signal strength**\n   • Confidence Score: `0–100`\n   • Label: Low / Medium / High / Very High\n\n5. **Include sentiment and headlines section**\n   • `<b>News Sentiment:</b>` \\[summary]\n   • `•` Top headlines with clickable links\n\n---\n\n### 📤 Output Format (Telegram HTML)\n\nStart with:\n\n```html\n<b>{{SYMBOL}} Market Report</b>\n```\n\nUse clean formatting:\n\n* `<b>` for headers\n* `•` for bullet lists\n* Logical grouping: price > indicators > strategy > sentiment\n\n---\n\n### ⚠️ Rules\n\nDO NOT:\n\n* Fabricate any values\n* Repeat this system message\n* Output raw JSON or API structure\n\nONLY use **tool-delivered** and **validated** data. Write with clarity and tone of a senior quant analyst.\n"},"promptType":"define"},"typeVersion":1.8},{"id":"13965042-ad03-4108-88b3-250955bdbd28","name":"Telegram Trigger","type":"n8n-nodes-base.telegramTrigger","position":[-1000,160],"webhookId":"944e6f8d-ffcc-4692-a777-7410f2fd4016","parameters":{"updates":["message"],"additionalFields":{}},"credentials":{"telegramApi":{"id":"NRLKuLR7z8vCesub","name":"BinanceSpotTradingAIAgent_Bot"}},"typeVersion":1.2},{"id":"3f98e10f-fe7e-4c87-9e4f-4b6d8bfb805b","name":"User Authentication (Replace Telegram ID)","type":"n8n-nodes-base.code","position":[-680,160],"parameters":{"jsCode":"if ($input.first().json.message.from.id !== <Replace Telegram ID>) { // Replace with your actual ID\n  return {unauthorized: true};\n} else {\n  // Return the original data when authorized\n  return $input.all();\n}"},"typeVersion":2},{"id":"ef715512-2d57-447e-969d-c173a823775b","name":"Adds \"SessionId\"","type":"n8n-nodes-base.set","position":[-400,160],"parameters":{"options":{},"assignments":{"assignments":[{"id":"47598bf1-e55f-4cc0-ae75-272085e7ce02","name":"=sessionId","type":"string","value":"={{ $json.message.chat.id }}"},{"id":"daa49d74-e55e-47bc-ac52-8686d591ab83","name":"message","type":"string","value":"={{ $json.message.text }}"}]}},"typeVersion":3.4},{"id":"876e3ec9-3453-4db9-928a-6163c1c6702b","name":"Telegram","type":"n8n-nodes-base.telegram","position":[900,160],"webhookId":"79d6c29c-1e04-414a-9989-afb1f7a58035","parameters":{"text":"={{ $json.message }}","chatId":"={{ $('Telegram Trigger').item.json.message.chat.id }}","additionalFields":{"appendAttribution":false}},"credentials":{"telegramApi":{"id":"NRLKuLR7z8vCesub","name":"BinanceSpotTradingAIAgent_Bot"}},"typeVersion":1.2},{"id":"70c70549-1c58-478d-a39f-5bccc7b76b04","name":"Splits message is more than 4000 characters","type":"n8n-nodes-base.code","position":[480,160],"parameters":{"jsCode":"// Input: assumes incoming message in `item.json.message`\nconst input = $json.output;\nconst chunkSize = 4000;\n\n// Function to split text\nfunction splitMessage(text, size) {\n  const result = [];\n  for (let i = 0; i < text.length; i += size) {\n    result.push(text.substring(i, i + size));\n  }\n  return result;\n}\n\n// Logic\nif (input.length <= chunkSize) {\n  return [{ json: { message: input } }];\n} else {\n  const chunks = splitMessage(input, chunkSize);\n  return chunks.map(chunk => ({ json: { message: chunk } }));\n}"},"typeVersion":2},{"id":"85e0b819-f722-43ae-93b7-5317ff877804","name":"News and Sentiment Analysis Request","type":"n8n-nodes-base.httpRequestTool","position":[120,600],"parameters":{"url":"https://treasurium.app.n8n.cloud/webhook/newsanalyst","method":"POST","options":{},"sendBody":true,"bodyParameters":{"parameters":[{"name":"message","value":"=={{ $json.message }}"}]},"toolDescription":"It will post the name of the cryptocurrency to get the News and Sentiment Analysis for use in the Binance Quant AI Agent."},"typeVersion":4.2},{"id":"27c27a35-fe83-4c4b-b9b1-90f2e1de8602","name":"Binance SM Financial Analyst Tool","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[380,580],"parameters":{"workflowId":{"__rl":true,"mode":"list","value":"Nm41n4i6VMhrixZs","cachedResultName":"Work Drive — Binance SM Financial Analyst Tool"},"workflowInputs":{"value":{"message":"={{ $fromAI(\"message\",\"Populate this with a relevant message to this subagent\")}}","sessionId":"={{ $json.sessionId }}"},"schema":[{"id":"message","type":"string","display":true,"required":false,"displayName":"message","defaultMatch":false,"canBeUsedToMatch":true},{"id":"sessionId","type":"string","display":true,"required":false,"displayName":"sessionId","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false}},"typeVersion":2.2},{"id":"78c6847a-8449-45dd-8aa6-1ce69e3d4e67","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[-160,620],"parameters":{},"typeVersion":1.3},{"id":"7ded5880-cf83-483c-84b9-dfce5e11d616","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1060,-100],"parameters":{"color":4,"height":460,"content":"## Trigger Incoming Telegram Command\nNode: Telegram Trigger\n**Listens for new Telegram messages** from users.\nTriggers the full agent process and passes raw user input downstream."},"typeVersion":1},{"id":"dfb57705-77b8-4c88-a6b0-aa8128b08400","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-740,-100],"parameters":{"color":2,"height":460,"content":"## Validate User Access\nNode: User **Authentication\nChecks incoming Telegram ID** against the approved user list."},"typeVersion":1},{"id":"37372f5a-db8c-4335-81a4-de437aff4782","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-460,-100],"parameters":{"color":5,"height":460,"content":"## Generate Session Metadata\nNode: Add S**essionId\nCreates a sessionId using the Telegram chat_id**.\nThis is passed into all downstream tools for memory and workflow routing."},"typeVersion":1},{"id":"952adc52-49a1-49c8-8bd5-d31c8277af83","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-180,-220],"parameters":{"color":7,"width":480,"height":580,"content":"## Main AI Agent: Report Generator\nNode: Binance Spot Market Quant AI Agent\nThis is the **core orchestrator**. It uses OpenAI to reason over:\n\n**Multi-timeframe indicator outputs**\n\n**Order book + price data**\n\n**Sentiment and news**\n\nIt calls both tools in parallel:\n\n**Binance Financial Market Analyst Tool**\n\n**Binance News & Sentiment Analyst Tool**\n\nThen it synthesizes a final trading report."},"typeVersion":1},{"id":"a6475e05-c83a-4dce-acd1-19294077912f","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[400,-100],"parameters":{"color":5,"width":260,"height":460,"content":"## Handle Telegram Message Limits\nNode: Code (split logic)\nChecks if the **GPT output exceeds 4000 characters**.\nIf so, it splits the message into safe chunks and passes them on sequentially."},"typeVersion":1},{"id":"413aff1b-43a3-4f81-b82d-eab2f18aed61","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[840,-100],"parameters":{"color":4,"height":460,"content":"## Send Final Report to Telegram\nNode: Telegram sendMessage\nSends **formatted HTML report (or split chunks)** directly to the authenticated user via Telegram bot."},"typeVersion":1},{"id":"8b7687eb-9c5f-4745-8700-cc337a1a2505","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-520,520],"parameters":{"height":540,"content":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## GPT Model for Reasoning\nNode: OpenAI Chat Model\nModel: **gpt-4o-mini**\nUsed to:\n\nInterpret signal values\n\nGenerate structured HTML\n\n**Recommend spot and leverage trades**\n\n"},"typeVersion":1},{"id":"fc0fa082-96d7-4dda-8273-0aa44f6b1f97","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[40,520],"parameters":{"color":6,"height":660,"content":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Binance News & Sentiment Analyst Tool\nNode: ToolWebhook\nSends the symbol to:\n\nPOST https://treasurium.app.n8n.cloud/webhook/newsanalyst\nReturns:\n\n**📈 Sentiment (Bullish / Neutral / Bearish)**\n\n**📰 3–5 crypto headlines**\n\n**🧠 Summary paragraph (1–3 lines)**"},"typeVersion":1},{"id":"becbf326-b8d3-482e-b9c5-7a1bed58b112","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[300,520],"parameters":{"color":6,"height":660,"content":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Binance Financial Market Analyst Tool\nNode: ToolWorkflow\nCalls all connected indicator agents:\n\n**15m, 1h, 4h, 1d**\n\nPrice/Orderbook/Klines agent\n\n**Each indicator (RSI, MACD, BBANDS, SMA, EMA, ADX)** is returned per timeframe, plus order book depth and candle snapshots."},"typeVersion":1},{"id":"46cb7225-7ba9-4270-988e-74e4a30403fc","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-240,520],"parameters":{"color":3,"height":540,"content":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Short-Term Memory Module\nNode: **Simple Memory\nStores the sessionId**, symbol, and other state data.\nUseful for:\n\nMulti-turn Telegram interactions\n\nTracking indicator agreement across timeframes\n\n"},"typeVersion":1},{"id":"238ff914-0c43-4cdf-9506-61e67306300f","name":"Sticky Note10","type":"n8n-nodes-base.stickyNote","position":[1400,-1340],"parameters":{"width":1780,"height":2540,"content":"# 🧠 Binance Spot Market Quant AI Agent – Full System Documentation\n\nA professional-grade AI automation system for **spot market trading insights** on Binance. It analyzes **multi-timeframe technical indicators**, **live price/order data**, and **crypto sentiment**, then delivers fully formatted **Telegram-style trading reports**.\n\n---\n\n## 🧩 Included Workflows\n\n> You must install and activate **all of the following workflows** for the system to function correctly:\n\n| ✅ Workflow Name                                    | 📌 Function Description                                                          |\n| -------------------------------------------------- | -------------------------------------------------------------------------------- |\n| Binance Spot Market Quant AI Agent                 | Final AI orchestrator. Parses user prompt and generates Telegram-ready reports.  |\n| Binance SM Financial Analyst Tool                  | Calls indicator tools and price/order data tools. Synthesizes structured inputs. |\n| Binance SM News and Sentiment Analyst Webhook Tool | Analyzes crypto sentiment, gives summary and headlines via POST webhook.         |\n| Binance SM Price/24hrStats/OrderBook/Kline Tool    | Pulls price, order book, 24h stats, and OHLCV klines for 15m–1d.                 |\n| Binance SM 15min Indicators Tool                   | Calculates 15m RSI, MACD, BBANDS, ADX, SMA/EMA from Binance kline data.          |\n| Binance SM 1hour Indicators Tool                   | Same as above but for 1h timeframe.                                              |\n| Binance SM 4hour Indicators Tool                   | Same as above but for 4h timeframe.                                              |\n| Binance SM 1day Indicators Tool                    | Same as above but for 1d timeframe.                                              |\n| Binance SM Indicators Webhook Tool                 | Technical backend. Handles all webhook logic for each timeframe tool.            |\n\n---\n\n## ⚙️ Installation Instructions\n\n### Step 1: Import Workflows\n\n* Open your **n8n Editor UI**\n* Import each workflow JSON file one by one\n* Activate them or ensure they're called via `Execute Workflow`\n\n### Step 2: Set Credentials\n\n* **OpenAI API Credential**: Add your OpenAI key for GPT-4o or GPT-4.1\n* **Binance Price Data**: No auth needed (public endpoint)\n\n### Step 3: Configure Webhook Endpoints\n\n* Deploy **Binance SM Indicators Webhook Tool**\n* Ensure the following routes are reachable:\n\n  * `/webhook/15m`\n  * `/webhook/1h`\n  * `/webhook/4h`\n  * `/webhook/1d`\n\n### Step 4: Telegram Integration\n\n* Add your Telegram Bot to n8n with correct API token\n* Update the **Telegram ID check node** with your own ID\n* Messages from your ID will trigger the agent\n\n### Step 5: Final Agent Execution\n\n* Trigger `Binance Spot Market Quant AI Agent` manually or from Telegram\n* The agent:\n\n  * Calls all connected tools with symbol and sessionId\n  * Waits for full indicator + sentiment response\n  * Returns a formatted multi-part trading report\n\n---\n\n## 🖥️ System Workflow Overview\n\n```\n[Telegram Trigger]\n→ [Session Memory + ID Check]\n→ [Quant Agent]\n→ [Financial Analyst Tool + Sentiment Tool]\n→ [All Indicators (15m, 1h, 4h, 1d)]\n→ [Price/Kline/OrderBook Tool]\n→ [News and Sentiment Webhook]\n→ [Signal Reasoning + Report Formatting]\n→ [Final Telegram HTML Message]\n```\n\n---\n\n## 📬 Telegram Output Style\n\n```html\n<b>BTCUSDT Market Report</b>\n\n<b>Spot Strategy</b>\n• Action: Buy\n• Entry: $63,800 | SL: $61,200 | TP: $66,500\n• Reason:\n - MACD Crossover (1h)\n - RSI Rebound from Oversold (15m)\n - Sentiment: Bullish\n\n<b>Leverage Strategy</b>\n• Position: Long 3x\n• Entry: $63,800\n• SL/TP zones same as above\n\n<b>News Sentiment:</b> Slightly Bullish\n• \"Bitcoin rallies as ETF inflows surge\" – CoinDesk\n• \"Whales accumulate BTC at key support\" – NewsBTC\n```\n\n---\n\n## 🚀 Support & Licensing\n\n🔗 **Don Jayamaha – LinkedIn**\n[linkedin.com/in/donjayamahajr](http://linkedin.com/in/donjayamahajr)\n\n© 2025 Treasurium Capital Limited Company. All rights reserved.\nThis system architecture, prompts, and workflow structure are proprietary and protected by **U.S. copyright law**. Reuse or resale prohibited without license.\n"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"bb69da16-db3d-4804-ad9d-a3d971f8fa36","connections":{"Simple Memory":{"ai_memory":[[{"node":"Binance Spot Market Quant AI Agent","type":"ai_memory","index":0}]]},"Adds \"SessionId\"":{"main":[[{"node":"Binance Spot Market Quant AI Agent","type":"main","index":0}]]},"Telegram Trigger":{"main":[[{"node":"User Authentication (Replace Telegram ID)","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Binance Spot Market Quant AI Agent","type":"ai_languageModel","index":0}]]},"Binance SM Financial Analyst Tool":{"ai_tool":[[{"node":"Binance Spot Market Quant AI Agent","type":"ai_tool","index":0}]]},"Binance Spot Market Quant AI Agent":{"main":[[{"node":"Splits message is more than 4000 characters","type":"main","index":0}]]},"News and Sentiment Analysis Request":{"ai_tool":[[{"node":"Binance Spot Market Quant AI Agent","type":"ai_tool","index":0}]]},"User Authentication (Replace Telegram ID)":{"main":[[{"node":"Adds \"SessionId\"","type":"main","index":0}]]},"Splits message is more than 4000 characters":{"main":[[{"node":"Telegram","type":"main","index":0}]]}}}


name: Analyze Crypto News Sentiment for Any Token with GPT-4o and Telegram Alerts
author_name: Don Jayamaha Jr
author_username: don-the-gem-dealer
categories: []
created_at: 2025-06-06T17:59:13.026Z
updated_at: 2025-06-06T17:59:13.026Z
url: https://n8n.io/workflows/4740
scraped_at: 2025-07-06 21:16:30
description:
  A sentiment intelligence sub-agent for the Binance Spot Market Quant AI Agent. It aggregates crypto news from major sources, filters by token keyword (e.g., BTC, ETH), and produces a Telegram-ready summary including market sentiment and top headlines—powered by GPT-4o.

  🎥 Live Demo:

  🛠️ Workflow Function

  This tool performs the following steps:

  | 🔧 Step                  | 📌 Description                                                                |
  | ------------------------ | ----------------------------------------------------------------------------- |
  | Webhook Input            | Accepts { "message": "symbol" } via HTTP POST                             |
  | Crypto Keyword Extractor | GPT model extracts the valid crypto symbol (e.g., "SOL", "DOGE", "ETH")       |
  | RSS News Aggregators     | Pulls latest headlines from 9+ crypto sources (CoinDesk, Cointelegraph, etc.) |
  | Merge & Filter Articles  | Keeps only articles containing the specified token                            |
  | Prompt Builder           | Creates prompt for GPT with filtered headlines                                |
  | GPT-4o Summarizer        | Summarizes news into 3-part response: Summary, Sentiment, Headline Links      |
  | Telegram Formatter       | Converts GPT output into a Telegram-friendly message                          |
  | Response Handler         | Returns formatted message to the caller via webhook                           |

  📥 Webhook Trigger Format

  {
    "message": "ETH"
  }

  This triggers a full execution of the workflow and returns output like:

  📣 ETH Sentiment: Neutral

  • BlackRock’s tokenized fund expands to Ethereum mainnet (CoinDesk)  
  • Ethereum fees remain high, analysts call for L2 migration (NewsBTC)  
  • Vitalik warns about centralized risks in staking (Cointelegraph)

  📚 Installation Guide

  1. Import & Enable

  Load the .json into your n8n Editor
  Enable webhook trigger in the top-right corner
  Ensure it's reachable via POST /webhook/custom-path

  2. Required Credentials

  OpenAI API Key** (GPT-4o capable)
  No API keys required for RSS feeds

  3. Connect to Quant Agent

  Add an HTTP Request node in your main AI agent
  Point to this workflow's webhook with body { "message": "symbol" }
  Capture the response to include in your Telegram output

  🔍 Real Use Cases

  | Scenario                           | Result                                                           |
  | ---------------------------------- | ---------------------------------------------------------------- |
  | BTC Sentiment before a key event   | Returns 8–12 filtered articles with bullish/neutral/bearish tone |
  | Daily pulse for altcoins like DOGE | Shows relevant headlines, helpful for intraday trading setups    |
  | Telegram chatbot integration       | Enables user to query sentiment via /sentiment ETH             |
  | Macro context for Quant AI outputs | Adds emotional/news context to technical-based trade decisions   |

  🧾 Licensing & Attribution

  © 2025 Treasurium Capital Limited Company
  Architecture, prompts, and trade report structure are IP-protected.
  No unauthorized rebranding or resale permitted.

  🔗 For support: LinkedIn – Don Jayamaha

nodes_used:
  ["n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.openAi"]

workflow_json:
  {"id":"f8Zow3PmilvRq85m","meta":{"instanceId":"a5283507e1917a33cc3ae615b2e7d5ad2c1e50955e6f831272ddd5ab816f3fb6"},"name":"Binance SM News and Sentiment Analyst Webhook Tool","tags":[],"nodes":[{"id":"1d71285d-a4bf-456a-a356-b9fa8b74c9d3","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-1020,1220],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"yUizd8t0sD5wMYVG","name":"OpenAi account"}},"typeVersion":1.2},{"id":"300cab6c-63ee-4271-a63e-b3afb135bdcf","name":"Set Query","type":"n8n-nodes-base.set","position":[-460,1040],"parameters":{"options":{},"assignments":{"assignments":[{"id":"9128e9e7-d1b8-4e89-8422-849b8dd519d8","name":"query","type":"string","value":"={{ $json.output }}"}]}},"typeVersion":3.4},{"id":"d7307bc3-f7c2-4db1-8674-5c6025ce7e2a","name":"Crypto News & Sentiment Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[-960,1040],"parameters":{"text":"={{$json.body.message}}","options":{"systemMessage":"Your job is to analyze the keyword of the question and output it as a single word.  The keyword will always be the name of a cryptocurrency."},"promptType":"define"},"typeVersion":1.8},{"id":"c4ad1805-cb48-45a3-b850-4960f59299f0","name":"RSS Cointelegraph","type":"n8n-nodes-base.rssFeedRead","position":[160,200],"parameters":{"url":"https://cointelegraph.com/rss","options":{}},"typeVersion":1.1},{"id":"5fc71ef5-a376-41a0-9213-15cc4527b049","name":"RSS Bitcoinmagazine","type":"n8n-nodes-base.rssFeedRead","position":[160,360],"parameters":{"url":"https://bitcoinmagazine.com/.rss/full/","options":{}},"typeVersion":1.1},{"id":"bdbf7bab-c3a6-4f65-bbb9-a6cd83763dc5","name":"RSS Coindesk","type":"n8n-nodes-base.rssFeedRead","position":[160,520],"parameters":{"url":"https://www.coindesk.com/arc/outboundfeeds/rss/","options":{}},"typeVersion":1.1},{"id":"836d7edd-62c5-4819-aa30-c48c4b1f005d","name":"RSS Bitcoinist","type":"n8n-nodes-base.rssFeedRead","position":[160,680],"parameters":{"url":"https://bitcoinist.com/feed/","options":{}},"typeVersion":1.1},{"id":"a0778852-e86b-41e5-a3f8-6d4352e397a1","name":"RSS Newsbtc","type":"n8n-nodes-base.rssFeedRead","position":[160,840],"parameters":{"url":"https://www.newsbtc.com/feed/","options":{}},"typeVersion":1.1},{"id":"d5c5cc4f-ef15-40af-be33-31ce2dbdc45e","name":"RSS Cryptopotato","type":"n8n-nodes-base.rssFeedRead","position":[160,1200],"parameters":{"url":"https://cryptopotato.com/feed/","options":{}},"typeVersion":1.1},{"id":"5f02ad60-9b0a-49fc-afd7-558ac5aeee2d","name":"RSS 99bitcoins","type":"n8n-nodes-base.rssFeedRead","position":[160,1380],"parameters":{"url":"https://99bitcoins.com/feed/","options":{}},"typeVersion":1.1},{"id":"cc5373ab-931a-4b95-a1d4-6d21fa18273a","name":"RSS Cryptobriefing","type":"n8n-nodes-base.rssFeedRead","position":[160,1560],"parameters":{"url":"https://cryptobriefing.com/feed/","options":{}},"typeVersion":1.1},{"id":"e5baa2ef-0455-42b0-a597-dedd551ae1aa","name":"RSS Crypto.news","type":"n8n-nodes-base.rssFeedRead","position":[160,1720],"parameters":{"url":"https://crypto.news/feed/","options":{}},"typeVersion":1.1},{"id":"2cb96040-0e47-41b5-9c32-8362d397333c","name":"Merge All Articles","type":"n8n-nodes-base.merge","position":[840,880],"parameters":{"numberInputs":10},"typeVersion":3.1},{"id":"a1f53681-504a-445a-9aa1-35c40f174e0c","name":"Filter by Query","type":"n8n-nodes-base.code","position":[1080,1020],"parameters":{"jsCode":"const term = $node[\"Set Query\"].json.query.toLowerCase();\nreturn items.filter(item => {\n  const j            = item.json;\n  const title        = (j.title || \"\").toLowerCase();\n  const snippet      = (j.contentSnippet || j.description || \"\").toLowerCase();\n  const fullContent  = (j.content || \"\").toLowerCase();\n  return title.includes(term)\n      || snippet.includes(term)\n      || fullContent.includes(term);\n});"},"typeVersion":2},{"id":"3b886f03-884f-4c9a-bb74-46be78c941fe","name":"Build Prompt","type":"n8n-nodes-base.code","position":[1400,1020],"parameters":{"jsCode":"const q   = $node[\"Set Query\"].json.query;\nconst list = items\n  .map(i => `- ${i.json.title} (${i.json.link})`)\n  .join(\"\\n\");\nconst prompt = `\nYou are a crypto-industry news analyst.\nSummarize current news and market sentiment for **${q}** based on these articles:\n${list}\n\nAnswer in 3 parts:\n1. Summary of News\n2. Market Sentiment\n3. Links to reference news articles\n`;\nreturn [{ json: { prompt } }];"},"typeVersion":2},{"id":"936b9c46-0ea4-498a-9dbb-b4f6b62cf70f","name":"Summarize News & Sentiment (GPT-4o)","type":"@n8n/n8n-nodes-langchain.openAi","position":[1680,1020],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4o","cachedResultName":"GPT-4O"},"options":{},"messages":{"values":[{"content":"={{ $node[\"Build Prompt\"].json.prompt }}"},{"role":"assistant","content":"You are a crypto‐industry news analyst. Summarize sentiment clearly and concisely."}]}},"credentials":{"openAiApi":{"id":"yUizd8t0sD5wMYVG","name":"OpenAi account"}},"typeVersion":1.8},{"id":"2c1b4212-3675-416d-a0f4-f1bce7b1581b","name":"Prepare Telegram Message","type":"n8n-nodes-base.set","position":[2100,1020],"parameters":{"options":{},"assignments":{"assignments":[{"id":"565fb705-ac83-4a96-9343-2e29e348cc4f","name":"summary","type":"string","value":"={{ $json.message.content }}"}]}},"typeVersion":3.4},{"id":"ae4eacc3-281d-4c40-a1c8-fbd580fb49a8","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-1120,900],"parameters":{"color":6,"width":600,"height":460,"content":"##  Extract Keyword \nThis AI agent parses the user input and returns a single-word keyword to help match relevant news articles."},"typeVersion":1},{"id":"ea8734d6-5f17-4587-88aa-fcd342a563c5","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[0,0],"parameters":{"color":5,"width":460,"height":1980,"content":"## News Aggregators\nPulls articles from major crypto news sources. You can add more RSS feeds here to expand coverage."},"typeVersion":1},{"id":"214d3fa9-d3f2-4e8a-bfab-5d4deb2881cf","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[760,680],"parameters":{"color":2,"width":480,"height":760,"content":"## Merge & Filter News\nCombines all RSS articles and filters them using the extracted keyword to match only relevant results."},"typeVersion":1},{"id":"c6942449-1e0b-4bca-b1e0-411a3deaf26d","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[1320,840],"parameters":{"color":7,"width":260,"height":360,"content":"## Prepare AI Prompt\nConstructs the input prompt for GPT-4o with a list of filtered articles. Output includes summary, sentiment, and article links."},"typeVersion":1},{"id":"7f401bd0-f14d-49d6-9d4a-fcb6e01bd64c","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[1640,800],"parameters":{"color":3,"width":340,"height":440,"content":"## Summarize News & Sentiment (GPT-4o)\nUses OpenAI GPT-4o to generate a concise summary of the news, analyze market sentiment, and return formatted results.\n\n"},"typeVersion":1},{"id":"f60cb8e4-8d3f-4112-a200-6affb3b80cb3","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[2040,760],"parameters":{"color":6,"height":460,"content":"## Format for Telegram\n\nExtracts the AI summary and prepares it for Telegram delivery. Change the variable if you want to include other data.\n\n\n"},"typeVersion":1},{"id":"e19e48b4-36cb-4b0b-87c5-0bae7f6068d7","name":"Webhook","type":"n8n-nodes-base.webhook","position":[-1440,1040],"webhookId":"a41af97d-6bd6-44d2-b79e-dca6df1e6e7e","parameters":{"path":"a41af97d-6bd6-44d2-b79e-dca6df1e6e7e","options":{},"httpMethod":"POST","responseMode":"responseNode"},"typeVersion":2},{"id":"7fae635b-2c8d-44e5-ac2a-b8a458653905","name":"Respond to Webhook","type":"n8n-nodes-base.respondToWebhook","position":[2440,1020],"parameters":{"options":{},"respondWith":"allIncomingItems"},"typeVersion":1.2},{"id":"96b562cd-1a55-40ef-aa0c-5d553d7f9818","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1500,740],"parameters":{"color":4,"height":480,"content":"## Webhook Trigger\nNode: Webhook\nAccepts **incoming HTTP POST requests**.\nExpected body format:\n\njson\n{ \"message\": \"<symbol>\" }\n\nThis kicks off the **full news + sentiment analysis process** for a given crypto asset."},"typeVersion":1},{"id":"8422e6bb-320e-4b5b-b392-2ba3adb215b7","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[2380,760],"parameters":{"color":4,"height":480,"content":"## Return Results to Caller\nNode: Respond to Webhook\n**Sends the final formatted message** back to the parent workflow that triggered the call."},"typeVersion":1},{"id":"f323030f-c92f-4bff-a5df-f498aa70d9c4","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[2780,-360],"parameters":{"width":1340,"height":2360,"content":"# 📰 Binance SM News and Sentiment Analyst Webhook Tool – Documentation\n\nA sentiment intelligence sub-agent that aggregates crypto news from top-tier RSS feeds, filters it based on a given token, and generates a market sentiment summary + headline list formatted for Telegram.\n\n---\n\n## 🎯 Purpose\n\nThis tool is responsible for:\n\n* Accepting a webhook request with a token symbol (e.g., `DOGE`, `SOL`)\n* Aggregating recent articles from 9+ major crypto news feeds\n* Filtering for articles relevant to the symbol\n* Summarizing the sentiment and key headlines using GPT-4o\n* Returning a Telegram-friendly formatted response to the caller\n\n---\n\n## 🛠️ Architecture & Key Components\n\n| Component                          | Role                                                           |\n| ---------------------------------- | -------------------------------------------------------------- |\n| 🔗 `Webhook`                       | Triggered externally with `{ message: \"BTC\" }`                 |\n| 🧠 `Crypto News & Sentiment Agent` | Uses GPT to extract the correct crypto keyword                 |\n| 🔄 RSS Feed Readers                | Pull from Cointelegraph, Coindesk, NewsBTC, Bitcoinist, etc.   |\n| 📦 `Merge All Articles`            | Combines articles into one stream                              |\n| 🧹 `Filter by Query`               | Keeps only the news relevant to the requested token            |\n| 📝 `Build Prompt`                  | Builds natural-language prompt to send to GPT                  |\n| 🧠 `Summarize News & Sentiment`    | GPT-4o summarizes the filtered articles with sentiment scoring |\n| 🧾 `Prepare Telegram Message`      | Formats the final summary in clean, Telegram-readable style    |\n| 📤 `Respond to Webhook`            | Returns the message to the triggering parent workflow          |\n\n---\n\n## 📥 Webhook Input\n\n> Expects a simple HTTP POST to the webhook endpoint:\n\n```json\n{\n  \"message\": \"ETH\"\n}\n```\n\nThis triggers a full pipeline execution, resulting in a text summary like:\n\n---\n\n## 📤 Sample Output Format\n\n```\n📣 ETH Sentiment: Neutral\n\n• BlackRock’s tokenized fund expands to Ethereum mainnet (CoinDesk)  \n• Ethereum fees remain high, analysts call for L2 migration (NewsBTC)  \n• Vitalik warns about centralized risks in staking (Cointelegraph)\n```\n\n---\n\n## 🔍 Use Cases\n\n| Scenario                                   | Outcome                                              |\n| ------------------------------------------ | ---------------------------------------------------- |\n| Sentiment summary for BTC                  | Fetches 8–12 filtered headlines, extracts tone       |\n| Daily news pulse for SOL                   | Shows project-related news with brief sentiment flag |\n| Enhances technical analysis interpretation | Adds macro/emotional context to trend setups         |\n| Telegram bot asks for XRP sentiment        | Sends full response back to user instantly           |\n\n---\n\n## 📚 How to Install\n\n### 1. Import & Activate\n\n1. Load the `.json` into your n8n instance\n2. Enable the webhook\n3. Link to parent agent (`Financial Analyst`, `Quant Agent`)\n\n### 2. Set Credentials\n\n* Requires a working **OpenAI API Key** (for GPT-4o)\n* No authentication required for RSS sources\n\n### 3. Connect to Caller\n\nAny external workflow (like your `Quant AI Agent`) can call this by:\n\n* Using HTTP Request Node\n* POSTing to this webhook with `{ message: \"BTC\" }` in the body\n\n---\n\n## 🧾 Licensing & Support\n\n🔗 **Don Jayamaha – LinkedIn**\n[http://linkedin.com/in/donjayamahajr](http://linkedin.com/in/donjayamahajr)\n\n© 2025 Treasurium Capital Limited Company. All rights reserved.\nThis system—including workflow architecture, prompt design, and logic structure—is protected under U.S. copyright law. Unauthorized resale or reproduction is prohibited.\n\n"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"9c17a79d-f8a4-413e-a486-2e89229994cf","connections":{"Webhook":{"main":[[{"node":"Crypto News & Sentiment Agent","type":"main","index":0}]]},"Set Query":{"main":[[{"node":"RSS Cointelegraph","type":"main","index":0},{"node":"RSS Bitcoinmagazine","type":"main","index":0},{"node":"RSS Coindesk","type":"main","index":0},{"node":"RSS Bitcoinist","type":"main","index":0},{"node":"RSS Newsbtc","type":"main","index":0},{"node":"RSS Cryptopotato","type":"main","index":0},{"node":"RSS 99bitcoins","type":"main","index":0},{"node":"RSS Cryptobriefing","type":"main","index":0},{"node":"RSS Crypto.news","type":"main","index":0}]]},"RSS Newsbtc":{"main":[[{"node":"Merge All Articles","type":"main","index":4}]]},"Build Prompt":{"main":[[{"node":"Summarize News & Sentiment (GPT-4o)","type":"main","index":0}]]},"RSS Coindesk":{"main":[[{"node":"Merge All Articles","type":"main","index":2}]]},"RSS 99bitcoins":{"main":[[{"node":"Merge All Articles","type":"main","index":7}]]},"RSS Bitcoinist":{"main":[[{"node":"Merge All Articles","type":"main","index":3}]]},"Filter by Query":{"main":[[{"node":"Build Prompt","type":"main","index":0}]]},"RSS Crypto.news":{"main":[[{"node":"Merge All Articles","type":"main","index":9}]]},"RSS Cryptopotato":{"main":[[{"node":"Merge All Articles","type":"main","index":6}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Crypto News & Sentiment Agent","type":"ai_languageModel","index":0}]]},"RSS Cointelegraph":{"main":[[{"node":"Merge All Articles","type":"main","index":0}]]},"Merge All Articles":{"main":[[{"node":"Filter by Query","type":"main","index":0}]]},"RSS Cryptobriefing":{"main":[[{"node":"Merge All Articles","type":"main","index":8}]]},"RSS Bitcoinmagazine":{"main":[[{"node":"Merge All Articles","type":"main","index":1}]]},"Prepare Telegram Message":{"main":[[{"node":"Respond to Webhook","type":"main","index":0}]]},"Crypto News & Sentiment Agent":{"main":[[{"node":"Set Query","type":"main","index":0}]]},"Summarize News & Sentiment (GPT-4o)":{"main":[[{"node":"Prepare Telegram Message","type":"main","index":0}]]}}}


name: Get Binance Spot Market Financial Analysis via Telegram with GPT-4o
author_name: Don Jayamaha Jr
author_username: don-the-gem-dealer
categories: []
created_at: 2025-06-06T18:03:54.629Z
updated_at: 2025-06-06T18:03:54.629Z
url: https://n8n.io/workflows/4741
scraped_at: 2025-07-06 21:16:30
description:
  This workflow powers the Binance Spot Market Quant AI Agent, acting as the Financial Market Analyst. It fuses real-time market structure data (price, volume, kline) with multiple timeframe technical indicators (15m, 1h, 4h, 1d) and returns a structured trading outlook—perfect for intraday and swing traders who want actionable analysis in Telegram.

  🔗 Requires the following sub-workflows to function:
  • Binance SM 15min Indicators Tool
  • Binance SM 1hour Indicators Tool
  • Binance SM 4hour Indicators Tool
  • Binance SM 1day Indicators Tool
  • Binance SM Price/24hStats/Kline Tool

  ⚙️ How It Works

  Triggered via webhook (typically by the Quant AI Agent).
  Extracts user symbol + timeframe from input (e.g., "DOGE outlook today").
  Calls all linked sub-workflows to retrieve indicators + live price data.
  Merges the data and formats a clean trading report using GPT-4o-mini.
  Returns HTML-formatted message suitable for Telegram delivery.

  📥 Sample Input

  {
    "message": "SOLUSDT",
    "sessionId": "654321123"
  }

  ✅ Telegram Output Format

  📊 SOLUSDT Market Snapshot

  💰 Price: $156.75  
  📉 24h Stats: High $160.10 | Low $149.00 | Volume: 1.1M SOL

  🧪 4h Indicators:
  • RSI: 58.2 (Neutral-Bullish)  
  • MACD: Crossover Up  
  • BB: Squeezing Near Upper Band  
  • ADX: 25.7 (Rising Trend)

  📈 Resistance: $163  
  📉 Support: $148

  🔍 Use Cases

  | Scenario                        | Outcome                                                   |
  | ------------------------------- | --------------------------------------------------------- |
  | User asks for “BTC outlook”     | Returns 1h + 4h + 1d indicators + live price + key levels |
  | Telegram bot prompt: “DOGE now” | Returns short-term 15m + 1h analysis snapshot             |
  | Strategy trigger inside n8n     | Enables other workflows to consume structured signal data |

  🎥 Watch Tutorial:

  🧾 Licensing & Attribution

  © 2025 Treasurium Capital Limited Company
  Architecture, prompts, and trade report structure are IP-protected.
  No unauthorized rebranding or redistribution permitted.

  🔗 For support: LinkedIn – Don Jayamaha

nodes_used:
  ["@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.memoryBufferWindow","@n8n/n8n-nodes-langchain.toolWorkflow"]

workflow_json:
  {"id":"Nm41n4i6VMhrixZs","meta":{"instanceId":"a5283507e1917a33cc3ae615b2e7d5ad2c1e50955e6f831272ddd5ab816f3fb6","templateCredsSetupCompleted":true},"name":"Binance SM Financial Analyst Tool","tags":[],"nodes":[{"id":"76944051-b8a4-4619-a307-3467e545c2d0","name":"When Executed by Another Workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[-640,-100],"parameters":{"workflowInputs":{"values":[{"name":"message"},{"name":"sessionId"}]}},"typeVersion":1.1},{"id":"035ef2de-8f55-4d8e-96fb-17ecefc835b9","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-920,240],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4.1-mini","cachedResultName":"gpt-4.1-mini"},"options":{}},"credentials":{"openAiApi":{"id":"yUizd8t0sD5wMYVG","name":"OpenAi account"}},"typeVersion":1.2},{"id":"8a658740-f8c3-44e2-ae3a-974bf5baec55","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[-660,240],"parameters":{},"typeVersion":1.3},{"id":"ab7672db-5912-4ed5-b9cc-8a64195fb4f1","name":"Binance SM Financial Analyst Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[-200,-100],"parameters":{"text":"={{ $json.message }}","options":{"systemMessage":"You are the **Binance Spot Market Financial Analyst AI Agent**, tasked with interpreting natural-language trading queries and generating **multi-timeframe, indicator-driven market analysis** for any Binance spot symbol.\n\nYour core responsibility is to orchestrate real-time price tools and technical indicator sub-agents to **diagnose trend conditions, volatility shifts, and market momentum**, and return a structured report formatted for Telegram.\n\n---\n\n### 🔗 Connected Tools & Agents\n\n#### 1. **Price & Market Structure Tool**\n\nWorkflow: `Binance SM Price-24hrStats-OrderBook-Kline Tool`\nReturns:\n\n* `getCurrentPrice`\n* `get24hrStats`\n* `getOrderBook`\n* `getKlines`\n  Input:\n\n```json\n{\n  \"message\": \"<SYMBOL>\",\n  \"sessionId\": \"<Telegram Chat ID>\"\n}\n```\n\n#### 2. **Timeframe-Based Technical Indicator Agents**\n\nEach uses the latest Binance kline data (limit: 40) to calculate:\n\n* **RSI** (14)\n* **MACD** (12/26/9)\n* **Bollinger Bands** (20/2)\n* **SMA / EMA** (20)\n* **ADX** (+DI, −DI, 14)\n\nAgents:\n\n* `Binance SM 15min Indicators Agent`\n* `Binance SM 1hour Indicators Agent`\n* `Binance SM 4hour Indicators Agent`\n* `Binance SM 1day Indicators Agent`\n\nInput to each agent:\n\n```json\n{\n  \"message\": \"<SYMBOL>\",\n  \"sessionId\": \"<Telegram Chat ID>\"\n}\n```\n\n---\n\n### 🧠 Decision Engine & Routing Logic\n\nYou must:\n\n* Extract the **symbol** and **implied timeframe** from the user query.\n* If no timeframe is given, default to:\n\n  * **Short-Term**: 15m + 1h\n  * **Mid-Term**: 1h + 4h\n  * **Long-Term**: 1d + 4h\n* Route data requests in parallel across tools\n* Merge raw metrics into a final structured insight\n\n---\n\n### 📤 Telegram Output Template\n\nReturn your final result in this format:\n\n```\n📊 <SYMBOL> Market Snapshot\n\n💰 Price: $63,220  \n📈 24h Change: +2.3%  \n📊 Volume: 45,210 BTC\n\n🧪 Technical Summary:\n• 1h RSI: 68 (Bullish)  \n• MACD: Crossover Up  \n• BB Width: Narrowing (Possible Breakout)  \n• ADX: 32 (Strong Trend)  \n\n📉 Support: $61,900  \n📈 Resistance: $63,800\n```\n\n---\n\n### ✅ Input Handling Notes\n\n* Input: Human questions like \"How’s BTC doing today?\" or \"Is SOL bullish in the 4h chart?\"\n* If timeframe is missing, **infer intent**\n* If symbol is missing, prompt: “Which token would you like me to analyze?”\n* All agents and tools **must return cleaned JSON**, avoid raw API output"},"promptType":"define"},"typeVersion":2},{"id":"f12e6672-bcb5-44af-b7d7-250437d8ba7c","name":"Binance SM Price-24hrStats-OrderBook-Kline Agent","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[-400,220],"parameters":{"workflowId":{"__rl":true,"mode":"list","value":"xAa5vBxhQzEWWFJM","cachedResultName":"Work Drive — Binance SM Price-24hrStats-OrderBook-Kline Tool"},"description":"This tool is a delegated sub-agent workflow that provides low-level market data from the Binance Spot Market in response to upstream AI reasoning. It is used by higher-level agents (e.g. the Financial Analyst Agent) to retrieve structured financial metrics and price data for any cryptocurrency pair.\n\n🔧 What It Does:\nThis agent accepts a symbol-based message input and returns Binance API data for:\n\n✅ getCurrentPrice – Latest market price for a trading pair (e.g., BTCUSDT)\n\n✅ get24hrStats – 24-hour price change, high/low, volume, and close stats\n\n✅ getOrderBook – Real-time order book (bids/asks) with adjustable depth\n\n✅ getKlines – Candlestick OHLCV data for technical analysis","workflowInputs":{"value":{"message":"={{ $fromAI(\"message\",\"Populate this with a relevant message to this subagent\")}}","sessionId":"={{ $json.sessionId }}"},"schema":[{"id":"message","type":"string","display":true,"required":false,"displayName":"message","defaultMatch":false,"canBeUsedToMatch":true},{"id":"sessionId","type":"string","display":true,"required":false,"displayName":"sessionId","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false}},"typeVersion":2.2},{"id":"35936a8a-1bf6-4bfb-8ad7-1d192e6cf655","name":"Binance SM 15min Indicators Agent","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[-120,220],"parameters":{"workflowId":{"__rl":true,"mode":"list","value":"INYtgCEbxdGBDivU","cachedResultName":"Work Drive — Binance SM 15min Indicators Tool"},"description":"This is a 15-minute interval technical indicator agent for Binance Spot Market pairs. It provides AI-driven access to real-time technical signals calculated on the latest 15-minute candlestick data. Designed for use within larger financial analysis workflows, this tool helps detect short-term momentum shifts and trading signals.\n\n🔧 What It Does:\nWhen called with a valid crypto symbol, this agent fetches the latest 15-minute technical indicators, typically including (but not limited to):\n\n✅ Relative Strength Index (RSI)\n\n✅ Bollinger Bands (BBANDS)\n\n✅ Moving Averages (SMA/EMA)\n\n✅ MACD\n\n✅ ADX","workflowInputs":{"value":{"message":"={{ $fromAI(\"message\",\"Populate this with a relevant message to this subagent\")}}","sessionId":"={{ $json.sessionId }}"},"schema":[{"id":"message","type":"string","display":true,"required":false,"displayName":"message","defaultMatch":false,"canBeUsedToMatch":true},{"id":"sessionId","type":"string","display":true,"required":false,"displayName":"sessionId","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false}},"typeVersion":2.2},{"id":"3c15aea8-475e-42e0-b8f7-2295a176e386","name":"Binance SM 1hour Indicators Agent","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[100,220],"parameters":{"workflowId":{"__rl":true,"mode":"list","value":"eXDMxZUrE0tIPcR9","cachedResultName":"Work Drive — Binance SM 1hour Indicators Tool"},"description":"This agent is responsible for analyzing 1-hour interval technical indicators for trading pairs on the Binance Spot Market. It is used to detect mid-range market momentum and potential entry/exit signals based on trend strength and volatility.\n\n🔧 What It Does:\nWhen invoked, this agent queries the Binance SM 1hour Indicators Tool to retrieve AI-processed indicator data including (but not limited to):\n\n✅ RSI (Relative Strength Index)\n\n✅ MACD (Moving Average Convergence Divergence)\n\n✅ Bollinger Bands (BBANDS)\n\n✅ SMA / EMA (Simple & Exponential Moving Averages)\n\n✅ ADX (Average Directional Index)\n\nThese indicators are calculated from the latest 1-hour candlestick data and limited to the most recent data points (typically last 20).","workflowInputs":{"value":{"message":"={{ $fromAI(\"message\",\"Populate this with a relevant message to this subagent\")}}","sessionId":"={{ $json.sessionId }}"},"schema":[{"id":"message","type":"string","display":true,"required":false,"displayName":"message","defaultMatch":false,"canBeUsedToMatch":true},{"id":"sessionId","type":"string","display":true,"required":false,"displayName":"sessionId","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false}},"typeVersion":2.2},{"id":"b2feb013-9d16-4838-bfb5-2035ceb70790","name":"Binance SM 4hour Indicators Agent","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[340,220],"parameters":{"workflowId":{"__rl":true,"mode":"list","value":"6U56ifHxnha9rf2n","cachedResultName":"Work Drive — Binance SM 4hour Indicators Tool"},"description":"This agent focuses on retrieving and analyzing 4-hour timeframe technical indicators for Binance Spot Market trading pairs. It provides a medium-term view of trend strength, volatility, and momentum shifts—ideal for swing trading analysis and macro-level setups.\n\n🔧 What It Does:\nWhen triggered, the agent queries the Binance SM 4hour Indicators Tool workflow and returns a curated set of technical indicator values, such as:\n\n✅ RSI (Relative Strength Index)\n\n✅ MACD (Moving Average Convergence Divergence)\n\n✅ Bollinger Bands\n\n✅ SMA / EMA\n\n✅ ADX (Trend Strength)\n\nThese indicators are derived from recent 4-hour candlestick data (typically the last 20 bars) and formatted for human-readable AI response generation.","workflowInputs":{"value":{"message":"={{ $fromAI(\"message\",\"Populate this with a relevant message to this subagent\")}}","sessionId":"={{ $json.sessionId }}"},"schema":[{"id":"message","type":"string","display":true,"required":false,"displayName":"message","defaultMatch":false,"canBeUsedToMatch":true},{"id":"sessionId","type":"string","display":true,"required":false,"displayName":"sessionId","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false}},"typeVersion":2.2},{"id":"248d63c7-0b95-4f50-acb0-ed2c58dfb4e9","name":"Binance SM 1day Indicators Agent","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[600,220],"parameters":{"workflowId":{"__rl":true,"mode":"list","value":"tZtQVd3nbDgZ1DTZ","cachedResultName":"Work Drive — Binance SM 1day Indicators Tool"},"workflowInputs":{"value":{"message":"={{ $fromAI(\"message\",\"Populate this with a relevant message to this subagent\")}}","sessionId":"={{ $json.sessionId }}"},"schema":[{"id":"message","type":"string","display":true,"required":false,"displayName":"message","defaultMatch":false,"canBeUsedToMatch":true},{"id":"sessionId","type":"string","display":true,"required":false,"displayName":"sessionId","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false}},"typeVersion":2.2},{"id":"823c3ea2-dbee-4da5-a660-8b862e675db1","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-700,-400],"parameters":{"color":4,"height":500,"content":"## Trigger: Parent Workflow Call\nNode: When Executed by Another Workflow\nThis agent does not start on its own. It is always triggered from a higher-level agent, like:\n\n**Binance Quant AI Agent**\n\nCustom multi-timeframe analyzers"},"typeVersion":1},{"id":"61189fe9-31c1-4c03-b185-61ab5847e144","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-720,180],"parameters":{"color":3,"width":220,"height":520,"content":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Memory Context\nNode: **Simple Memory\nStores the session ID, message, and interim indicator values** for cross-tool alignment. Enables:\n\nMulti-turn dialogue logic\n\nTrend comparison across timeframes\n\nReport reuse if repeated query is made"},"typeVersion":1},{"id":"e9347973-3644-47dc-927e-87b480e473d9","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-980,180],"parameters":{"width":220,"height":520,"content":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## AI Engine\nNode: OpenAI Chat Model\nModel: **gpt-4.1-mini** or compatible\nUsed to:\n\nInterpret values from all indicator tools\n\nLabel behavior: **“Overbought,” “MACD Cross Up,” “Volatility Spike”**\n\nOutput final snapshot in clean Telegram format"},"typeVersion":1},{"id":"cee591cc-6c30-4d47-be93-5621315d02e4","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-460,180],"parameters":{"color":6,"width":220,"height":620,"content":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Price & Structure Tool\nNode: **Binance SM Price-24hrStats-OrderBook-Kline Agent**\nReturns raw metrics:\n\n✅ Current Price\n\n✅ 24hr Stats (OHLCV)\n\n✅ Order Book Depth (top 100 bids/asks)\n\n✅ Kline snapshots (15m, 1h, 4h, 1d)\n\nAll data is Telegram-optimized before AI formatting.\n\n"},"typeVersion":1},{"id":"bfdeab4a-a387-41a6-97ca-6719b640b744","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-200,180],"parameters":{"color":6,"width":220,"height":780,"content":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Technical Indicator Agents\nEach tool receives the same inputs:\n\njson\n{\n  \"message\": \"BTCUSDT\",\n  \"sessionId\": \"539847013\"\n}\n\n🔸 **15m Indicator Agent**\nDetects **fast-changing intraday signals** (scalping, fakeouts)\n\n\nEach calculates:\n\nRSI (14)\n\nMACD (12/26/9)\n\nBBANDS (20/2)\n\nSMA/EMA (20)\n\nADX (+DI / −DI, 14)"},"typeVersion":1},{"id":"a79b656a-b38a-4b0e-96c3-70b5282710aa","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[40,180],"parameters":{"color":6,"width":220,"height":780,"content":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Technical Indicator Agents\nEach tool receives the same inputs:\n\njson\n{\n  \"message\": \"BTCUSDT\",\n  \"sessionId\": \"539847013\"\n}\n\n🔸 **1h Indicator Agent**\nBest for **momentum confirmation or breakout acceleration**\n\n\nEach calculates:\n\nRSI (14)\n\nMACD (12/26/9)\n\nBBANDS (20/2)\n\nSMA/EMA (20)\n\nADX (+DI / −DI, 14)"},"typeVersion":1},{"id":"d1656eec-67d4-4ff0-8cf2-ee2040a9d8f2","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[280,180],"parameters":{"color":6,"width":220,"height":780,"content":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Technical Indicator Agents\nEach tool receives the same inputs:\n\njson\n{\n  \"message\": \"BTCUSDT\",\n  \"sessionId\": \"539847013\"\n}\n\n🔸 **4h Indicator Agent**\n**Macro view of medium-term setups and volume confirmation**\n\nEach calculates:\n\nRSI (14)\n\nMACD (12/26/9)\n\nBBANDS (20/2)\n\nSMA/EMA (20)\n\nADX (+DI / −DI, 14)"},"typeVersion":1},{"id":"115e5783-5220-45ac-a80e-bd9dd11d4af1","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[540,180],"parameters":{"color":6,"width":220,"height":780,"content":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Technical Indicator Agents\nEach tool receives the same inputs:\n\njson\n{\n  \"message\": \"BTCUSDT\",\n  \"sessionId\": \"539847013\"\n}\n\n\n🔸 1**d Indicator Agent**\n**High-timeframe sentiment, ideal for swing trade direction**\n\nEach calculates:\n\nRSI (14)\n\nMACD (12/26/9)\n\nBBANDS (20/2)\n\nSMA/EMA (20)\n\nADX (+DI / −DI, 14)"},"typeVersion":1},{"id":"bb184375-fab1-431a-a33f-b3dc0751105d","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[-320,-380],"parameters":{"color":5,"width":500,"height":460,"content":"## Primary Reasoning Agent\nNode: Binance SM Financial Analyst Agent\nThis is the orchestrator that:\n\n**Parses the symbol** and optional timeframe from user input\n\nSelects **tools dynamically**\n\n**Merges all results into one final report**\n\n"},"typeVersion":1},{"id":"396ab0d2-a322-4373-836f-94490acdc9f0","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[940,-920],"parameters":{"width":1060,"height":1900,"content":"# 📊 Binance SM Financial Analyst Tool – Documentation\n\nA central orchestrator that fuses market structure data and technical indicators across all relevant timeframes, preparing them for final trading analysis inside the Quant AI system.\n\n---\n\n## 🎯 Purpose\n\nThis tool is responsible for:\n\n* Parsing Telegram-style prompts from the master agent\n* Routing data requests to all relevant indicator tools (15m, 1h, 4h, 1d)\n* Fetching price, volume, order book, and kline structure\n* Merging all responses and returning a clean, readable summary\n\n---\n\n## 🧩 Connected Sub-Agents\n\n| Sub-Agent Tool                           | Role                                                     |\n| --------------------------------------   | -------------------------------------------------------- |\n| ✅ Binance SM 15min Indicators Tool       | Short-term volatility and reversals                      |\n| ✅ Binance SM 1hour Indicators Tool       | Intraday momentum and trend formation                    |\n| ✅ Binance SM 4hour Indicators Tool       | Swing trend analysis and confirmation                    |\n| ✅ Binance SM 1day Indicators Tool        | Macro trend detection and directional bias               |\n| ✅ Binance SM Price/24hStats/Kline Tool   | Raw market structure: OHLCV, order book, real-time price |\n\n---\n\n## ⚙️ Workflow Architecture\n\n| Section                             | Description                                                     |\n| ----------------------------------- | --------------------------------------------------------------- |\n| 🔄 **Trigger:**                     | Executed by Quant AI Agent or Telegram Bot Handler              |\n| 💬 **LLM Reasoning (gpt-4o-mini):** | Interprets queries, symbol, timeframe, intent                   |\n| 🧠 **Session Memory:**              | Tracks `sessionId`, symbol history, multi-turn intent           |\n| 📥 **Input Format:**                | `{ \\\"message\\\": \\\"SOLUSDT\\\", \\\"sessionId\\\": \\\"123456789\\\" }`    |\n| 🔁 **Tool Calls:**                  | Invokes all indicators and market data tools in parallel        |\n| 📊 **Merge Results:**               | Combines indicators + price + order book into structured output |\n| 📤 **Final Output:**                | Telegram-ready HTML summary (text only, no raw JSON)            |\n\n---\n\n## 📏 Timeframe Logic\n\n| Case           | Action                                            |\n| -------------- | ------------------------------------------------- |\n| No timeframe   | Default to `15m + 1h` (short-term snapshot)       |\n| Broad question | Return `1h + 4h + 1d` data (medium- to long-term) |\n| Symbol missing | Ask user to clarify the token or asset symbol     |\n\n---\n\n## 🖥️ Telegram Output Format\n\n```\n📊 ETHUSDT Market Overview\n\n💰 Price: $3,680  \n📉 24h Stats: High $3,720 | Low $3,580 | Volume: 920,000 ETH\n\n🧪 4h Technical Indicators:\n• RSI: 62.1 → Neutral-Bullish  \n• MACD: Crossover Up  \n• BB: Price near upper band  \n• ADX: 27.9 → Growing Trend\n\n📈 Resistance: $3,740  \n📉 Support: $3,600\n```\n\n---\n\n## ✅ Use Case Scenarios\n\n| Scenario                               | Result                                                     |\n| -------------------------------------- | ---------------------------------------------------------- |\n| User asks: “Show me BTC outlook today” | 15m + 1h + 1d analysis merged and summarized               |\n| User asks: “How is DOGE trending?”     | Indicator agent fetch + live price + structure returned    |\n| Input lacks timeframe                  | Defaults to short + medium scopes with follow-up if needed |\n\n---\n\n## 🚀 Support & Licensing\n\n🔗 **Don Jayamaha – LinkedIn**\n[http://linkedin.com/in/donjayamahajr](http://linkedin.com/in/donjayamahajr)\n\n© 2025 Treasurium Capital Limited Company. All rights reserved.\nThis AI automation system, including logic, code, prompt flows, and architectural structure, is proprietary intellectual property of **Treasurium Capital Limited Company**. Reproduction, redistribution, or resale is strictly prohibited without express license.\n"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"9d7a97dc-1249-4e37-a25a-e003555850b7","connections":{"Simple Memory":{"ai_memory":[[{"node":"Binance SM Financial Analyst Agent","type":"ai_memory","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Binance SM Financial Analyst Agent","type":"ai_languageModel","index":0}]]},"Binance SM 1day Indicators Agent":{"ai_tool":[[{"node":"Binance SM Financial Analyst Agent","type":"ai_tool","index":0}]]},"Binance SM 15min Indicators Agent":{"ai_tool":[[{"node":"Binance SM Financial Analyst Agent","type":"ai_tool","index":0}]]},"Binance SM 1hour Indicators Agent":{"ai_tool":[[{"node":"Binance SM Financial Analyst Agent","type":"ai_tool","index":0}]]},"Binance SM 4hour Indicators Agent":{"ai_tool":[[{"node":"Binance SM Financial Analyst Agent","type":"ai_tool","index":0}]]},"When Executed by Another Workflow":{"main":[[{"node":"Binance SM Financial Analyst Agent","type":"main","index":0}]]},"Binance SM Price-24hrStats-OrderBook-Kline Agent":{"ai_tool":[[{"node":"Binance SM Financial Analyst Agent","type":"ai_tool","index":0}]]}}}


name: ♻️ AI Multi-Stop Planner for Circular Logistics with GPT-4o & Open Route API
author_name: Samir Saci
author_username: samirsaci
categories: []
created_at: 2025-06-07T08:20:33.015Z
updated_at: 2025-06-07T08:20:33.015Z
url: https://n8n.io/workflows/4753
scraped_at: 2025-07-06 21:16:30
description:
  Tags*: AI Agent, Supply Chain, Logistics, Circular Economy, Route Planning, Transportation, GPS API

  Context

  Hi! I’m Samir — a Supply Chain Engineer and Data Scientist based in Paris, and founder of LogiGreen Consulting.

  I help logistics teams reduce operational workload and errors by combining AI automation, route optimization APIs, and workflow automation.

  This workflow is part of a circular economy project, where stores return reusable packaging (bins, crates, containers) to a central warehouse.

  &gt; Let's circular economies with AI-powered automation using n8n!

  📬 For business inquiries, you can add find me on LinkedIn

  Who is this template for?

  This workflow is designed for logistics teams participating in circular economy loops.

  Let us imagine your transportation company receives this pickup request:



  The two AI Agent nodes connected to Openroute Service API will process the information and reply with the detailed route plan.



  The results include driving time and the optimal sequence of stops generated by the multi-stop optimization endpoint of the API.

  How does it work?

  This workflow automates the end-to-end processing of multi-stop pickup requests for reusable packaging:

  📨 Gmail Trigger listens for collection request emails  
  🧠 AI Agent parses the email into structured data (store ID, address, date)  
  📍 Each stop is geocoded into GPS coordinates  
  🗺️ OpenRouteService optimizes the stop sequence using truck-specific routing  
  📄 A second AI Agent formats a confirmation email in HTML with the ordered pickup plan  
  📧 The reply is sent back with all details including duration and route

  Steps:

  💌 Trigger on a new Gmail message  
  🧠 Extract data using AI Agent (e.g., stores, addresses, times)  
  📑 Store raw and processed data in Google Sheets  
  📍 Enrich with GPS coordinates  
  🚚 Optimize route using OpenRouteService (truck profile)  
  📄 Format the confirmation using an AI Agent  
  📬 Send reply to requester with route and timing

  What do I need to get started?

  You’ll need:

  A Gmail account to receive collection requests  
  A Google Sheet to store and review data  
  A free OpenRouteService API key  
  Access to OpenAI for using AI Agent nodes  
  Sample pickup request emails to test

  Next Steps

  🗒️ Use the sticky notes inside the n8n canvas to:

  Plug in your Gmail and OpenRouteService credentials  
  Try with a sample store collection email  
  Validate the confirmation format and route accuracy  

  This template was built using n8n v1.93.0  
  Submitted: June 7, 2025

nodes_used:
  ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.gmail","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.outputParserStructured"]

workflow_json:
  {"meta":{"instanceId":"","templateCredsSetupCompleted":true},"nodes":[{"id":"9f8389be-ac2e-4a1d-bfe3-18a7d9900b36","name":"Gmail Trigger","type":"n8n-nodes-base.gmailTrigger","position":[20,460],"parameters":{"simple":false,"filters":{},"options":{"downloadAttachments":false},"pollTimes":{"item":[{"mode":"everyMinute"}]}},"notesInFlow":true,"typeVersion":1.2},{"id":"5eb9eadc-3836-4cc9-9130-62bc655b9eb0","name":"Structured Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[520,640],"parameters":{"jsonSchemaExample":"[\n  {\n  \"collection_request_id\": \"04-06-4EDW-75\",\n  \"store_id\":\"FRX-001\",\n  \"address\": \"103 Rue du Faubourg Saint-Antoine, 75011 Paris\",\n  \"collection_date\": \"June 7th, 2025\",\n  \"collection_time\": \"10:00\"\n}\n]\n\n\n"},"typeVersion":1.2},{"id":"1a98f859-b7ba-4778-a05b-7bd1c6da29fe","name":"AI Agent Parser","type":"@n8n/n8n-nodes-langchain.agent","position":[300,460],"parameters":{"text":"=Here is an email from a customer requesting a shipment:\n\nSubject: {{ $json.subject }}\nBody: {{ $json.text }}\n\nPlease extract all the structured logistics data based on the format provided.","options":{"systemMessage":"=You are a logistics assistant working for a transportation company.\n\nYour job is to extract **structured data** from collection request emails sent by customers (typically retail chains like Franprix). These emails include a list of pickup addresses, a collection start time, store identifiers, and a unique Collection Request ID.\n\nYou must return an **array of JSON objects**, where each object represents one pickup location.\n\nEach object must contain:\n\n{\n  \"collection_request_id\": \"\",\n  \"store_id\": \"\",\n  \"address\": \"\",\n  \"collection_date\": \"\",\n  \"collection_time\":\"\"\n}\n\n### Instructions:\n- Extract the value of `Collection Request ID` from the email and apply it to each object.\n- For each pickup location:\n  - Extract the **store_id** (e.g., FRX-001)\n  - Extract the full **address**\n  - Use the same **collection_time_start** for all records, as provided in the email\n- If any field is missing, set its value to `null`.\n- Do not infer missing information.\n- Keep the original formatting of the time and date. Do not transform it.\n- Do not add extra fields. The output must be a **JSON array**.\n\nThis output will be processed by another system. Follow the format exactly.\n"},"promptType":"define","hasOutputParser":true},"typeVersion":1.9},{"id":"170e9ffb-23a6-42ce-bca9-ae31d18124f0","name":"Record Email Content","type":"n8n-nodes-base.googleSheets","position":[1360,460],"parameters":{"columns":{"value":{"address":"={{ $json.address }}","store_id":"={{ $json.store_id }}","location_id":"={{ $json.store_id }}_{{ $json.collection_request_id }}","collection_date":"={{ $json.collection_date }}","collection_time":"={{ $json.collection_time }}","collection_request_id":"={{ $json.collection_request_id }}"},"schema":[{"id":"collection_request_id","type":"string","display":true,"removed":false,"required":false,"displayName":"collection_request_id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"store_id","type":"string","display":true,"removed":false,"required":false,"displayName":"store_id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"address","type":"string","display":true,"removed":false,"required":false,"displayName":"address","defaultMatch":false,"canBeUsedToMatch":true},{"id":"location_id","type":"string","display":true,"removed":false,"required":false,"displayName":"location_id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"longitude","type":"string","display":true,"removed":false,"required":false,"displayName":"longitude","defaultMatch":false,"canBeUsedToMatch":true},{"id":"latitude","type":"string","display":true,"removed":false,"required":false,"displayName":"latitude","defaultMatch":false,"canBeUsedToMatch":true},{"id":"gps_coordinates","type":"string","display":true,"removed":false,"required":false,"displayName":"gps_coordinates","defaultMatch":false,"canBeUsedToMatch":true},{"id":"collection_date","type":"string","display":true,"removed":false,"required":false,"displayName":"collection_date","defaultMatch":false,"canBeUsedToMatch":true},{"id":"collection_time","type":"string","display":true,"removed":false,"required":false,"displayName":"collection_time","defaultMatch":false,"canBeUsedToMatch":true},{"id":"sequence","type":"string","display":true,"removed":false,"required":false,"displayName":"sequence","defaultMatch":false,"canBeUsedToMatch":true},{"id":"total_duration","type":"string","display":true,"removed":false,"required":false,"displayName":"total_duration","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["shipment_number"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"list","value":1094697629,"cachedResultUrl":"","cachedResultName":"Multi-Stop"},"documentId":{"__rl":true,"mode":"list","value":"","cachedResultUrl":"","cachedResultName":"Transportation Orders"}},"notesInFlow":true,"typeVersion":4.6},{"id":"4c3c818c-9931-4eed-b145-39190e405b50","name":"5 sec","type":"n8n-nodes-base.wait","position":[2140,460],"webhookId":"8a602c69-d7ab-486c-990a-8d31b5e858f3","parameters":{},"typeVersion":1.1},{"id":"f567d1dd-432b-4e8e-9dec-5f27799ff61f","name":"Query Open Route API Pickup","type":"n8n-nodes-base.httpRequest","position":[1560,460],"parameters":{"url":"https://api.openrouteservice.org/geocode/search","options":{},"sendQuery":true,"sendHeaders":true,"authentication":"genericCredentialType","genericAuthType":"httpQueryAuth","queryParameters":{"parameters":[{"name":"text","value":"={{ $json.address }}"},{"name":"boundary.country","value":"=FR"},{"name":"sources","value":"openstreetmap"},{"name":"size","value":"1"}]},"headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json; charset=utf-8"},{"name":"Accept","value":"application/json, application/geo+json, application/gpx+xml, img/png; charset=utf-8"}]}},"credentials":{"httpQueryAuth":{"id":"CsPXdSa5p7fPrxpp","name":"Query Auth Open Route API"},"httpBearerAuth":{"id":"RwHLRH6TDUJaGZNF","name":"Bearer YOUR_TOKEN_HERE account"},"httpHeaderAuth":{"id":"uoa2pJ22gtZmYRDs","name":"Header Auth account"}},"notesInFlow":true,"typeVersion":4.2},{"id":"a88ca302-325e-4309-b427-a9eb807ab0e9","name":"Save Pickup GPS","type":"n8n-nodes-base.googleSheets","position":[1940,460],"parameters":{"columns":{"value":{"latitude":"={{ $json.latitude }}","sequence":"=","longitude":"={{ $json.longitude }}","location_id":"={{ $('Record Email Content').item.json.location_id }}","gps_coordinates":"={{ $json.longitude }}, {{ $json.latitude }}"},"schema":[{"id":"collection_request_id","type":"string","display":true,"removed":true,"required":false,"displayName":"collection_request_id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"store_id","type":"string","display":true,"removed":true,"required":false,"displayName":"store_id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"address","type":"string","display":true,"removed":true,"required":false,"displayName":"address","defaultMatch":false,"canBeUsedToMatch":true},{"id":"location_id","type":"string","display":true,"removed":false,"required":false,"displayName":"location_id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"longitude","type":"string","display":true,"removed":false,"required":false,"displayName":"longitude","defaultMatch":false,"canBeUsedToMatch":true},{"id":"latitude","type":"string","display":true,"removed":false,"required":false,"displayName":"latitude","defaultMatch":false,"canBeUsedToMatch":true},{"id":"gps_coordinates","type":"string","display":true,"removed":false,"required":false,"displayName":"gps_coordinates","defaultMatch":false,"canBeUsedToMatch":true},{"id":"collection_date","type":"string","display":true,"removed":true,"required":false,"displayName":"collection_date","defaultMatch":false,"canBeUsedToMatch":true},{"id":"collection_time","type":"string","display":true,"removed":true,"required":false,"displayName":"collection_time","defaultMatch":false,"canBeUsedToMatch":true},{"id":"sequence","type":"string","display":true,"removed":false,"required":false,"displayName":"sequence","defaultMatch":false,"canBeUsedToMatch":true},{"id":"total_duration","type":"string","display":true,"removed":false,"required":false,"displayName":"total_duration","defaultMatch":false,"canBeUsedToMatch":true},{"id":"row_number","type":"string","display":true,"removed":true,"readOnly":true,"required":false,"displayName":"row_number","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["location_id"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"update","sheetName":{"__rl":true,"mode":"list","value":1094697629,"cachedResultUrl":"","cachedResultName":"Multi-Stop"},"documentId":{"__rl":true,"mode":"list","value":"17wbroY0w6xmw8AT-p2c_n1WbHzmfesz6d1DJbp39fn8","cachedResultUrl":"","cachedResultName":"Transportation Orders"}},"notesInFlow":true,"typeVersion":4.6},{"id":"e07773a7-dd80-411e-b056-f6eb473d5dcb","name":"GPS Pickup","type":"n8n-nodes-base.set","position":[1740,460],"parameters":{"options":{},"assignments":{"assignments":[{"id":"e4c92077-f294-4e49-8276-20d1441c0c2c","name":"longitude","type":"string","value":"={{ $json.features[0].geometry.coordinates[0] }}"},{"id":"899e5304-e7a1-4ce1-bf9a-f403d74934fb","name":"latitude","type":"string","value":"={{ $json.features[0].geometry.coordinates[1] }}"},{"id":"5b35642b-dda4-42b8-b7bb-1275616bfb59","name":"borough","type":"string","value":"={{ $json.features[0].properties.borough }}"},{"id":"aa74bd9a-f543-48e1-a69b-0e6472bda053","name":"neighbourhood","type":"string","value":"={{ $json.features[0].properties.neighbourhood }}"},{"id":"7f303dc8-4e28-4d46-8e3e-9db00dbcac3a","name":"localadmin","type":"string","value":"={{ $json.features[0].properties.localadmin }}"}]}},"notesInFlow":true,"typeVersion":3.4},{"id":"121aa413-54e5-470a-be3b-ef243f3e9445","name":"Collect Coordinates","type":"n8n-nodes-base.googleSheets","position":[840,700],"parameters":{"options":{},"filtersUI":{"values":[{"lookupValue":"=04-06-4EDW-75","lookupColumn":"collection_request_id"}]},"sheetName":{"__rl":true,"mode":"list","value":1094697629,"cachedResultUrl":"","cachedResultName":"Multi-Stop"},"documentId":{"__rl":true,"mode":"list","value":"17wbroY0w6xmw8AT-p2c_n1WbHzmfesz6d1DJbp39fn8","cachedResultUrl":"","cachedResultName":"Transportation Orders"}},"notesInFlow":true,"typeVersion":4.6},{"id":"eca19e02-596a-47af-a448-b18ba2aa3af7","name":"Request Open Route API","type":"n8n-nodes-base.httpRequest","position":[1360,700],"parameters":{"url":"https://api.openrouteservice.org/optimization","body":"={{ JSON.stringify({\n  jobs: $json.jobs,\n  vehicles: $json.vehicles\n}) }}\n\n","method":"POST","options":{"response":{"response":{}}},"sendBody":true,"contentType":"raw","sendHeaders":true,"authentication":"genericCredentialType","rawContentType":"application/json","genericAuthType":"httpHeaderAuth","headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json; charset=utf-8"},{"name":"Accept","value":"application/json, application/geo+json, application/gpx+xml, img/png; charset=utf-8"}]}},"credentials":{"httpHeaderAuth":{"id":"uoa2pJ22gtZmYRDs","name":"Header Auth Open Route API"}},"notesInFlow":true,"typeVersion":4.2},{"id":"6f0027ec-68f9-495f-8958-14960dde3ccc","name":"Collect Shipment Information","type":"n8n-nodes-base.googleSheets","position":[840,1520],"parameters":{"options":{},"filtersUI":{"values":[{"lookupValue":"=04-06-4EDW-75","lookupColumn":"collection_request_id"}]},"sheetName":{"__rl":true,"mode":"list","value":1094697629,"cachedResultUrl":"","cachedResultName":"Multi-Stop"},"documentId":{"__rl":true,"mode":"list","value":"17wbroY0w6xmw8AT-p2c_n1WbHzmfesz6d1DJbp39fn8","cachedResultUrl":"","cachedResultName":"Transportation Orders"}},"notesInFlow":true,"typeVersion":4.6},{"id":"743b5224-10c1-4629-85e5-f32a57b85926","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[1140,1680],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"typeVersion":1.2},{"id":"93ed811e-041f-4f1b-92eb-b519c5b758f8","name":"AI Agent Reply","type":"@n8n/n8n-nodes-langchain.agent","position":[1200,1520],"parameters":{"text":"={{ $json.formatted_reply }}\n","options":{"systemMessage":"=You are a logistics assistant working for a transportation company.\n\nYour job is to send a clear, professional, and customer-friendly confirmation email summarizing a **multi-stop pickup schedule**.\n\nUse the preformatted HTML content provided via `{{ $json.formatted_reply }}` to structure the message.\n\n✅ Do:\n- Keep a formal and polite tone.\n- Include the pickup request ID, scheduled date & time, and the ordered list of pickup stops.\n- Confirm the estimated total driving duration.\n- Use the content **as-is**. Do not modify or rephrase it.\n\n❌ Do not:\n- Add or invent data.\n- Change the structure or wording of the HTML provided.\n\n⚠️ Format the reply strictly in **HTML** using tags like `<p>`, `<ul>`, `<li>`, and `<strong>`.\n\nAbout you\n[Name]: LogiGreen Bot\n[Position]: Transportation Planner\n[Company]: LogiGreen Transportation\n[Contact]: logigreenbot@gmail.com\n\n"},"promptType":"define"},"typeVersion":1.9},{"id":"5ba3408c-37c7-4d2b-8972-9e753824b21e","name":"Reply","type":"n8n-nodes-base.gmail","position":[1520,1520],"webhookId":"6e50b09c-3988-46ed-b6a6-b644aae2449f","parameters":{"message":"={{ $json.output }}","options":{},"messageId":"={{ $('Gmail Trigger').item.json.id }}","operation":"reply"},"notesInFlow":true,"typeVersion":2.1},{"id":"cfc99cbf-12ae-4c77-be75-99609d3f24d5","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[780,0],"parameters":{"color":7,"width":1560,"height":1100,"content":"### 3. Record Shipment Request Information and fetch distance and driving time using Open Route API\nThis starts by recording all the information parsed by the AI node. Then, we use the **Open Route API** to complete with **geocoding data** *(GPS Coordinates)* that will be used to fetch **driving distance and time**.\n\n#### How to setup?\n- **Setup API Credentials**\n  1. Get your free API key: [Open Route API Documentation](https://openrouteservice.org/dev/#/api-docs)\n  2. Fill the API key in the HTTP request node\n  3. Select the driving mode (**driving-car**: individual truck) or (**driving-hgv**: commercial truck)\n- **Load records in the Google Sheet Node**:\n   1. Add your Google Sheet API credentials to access the Google Sheet file\n   2. Select the file using the list, an URL or an ID\n   3. Select the sheet in which you want to record your working sessions\n   4. Map the fields: **shipment_number**, **pickup_location**, **pickup_address**, **pickup_longitude**, **pickup_latitude**, **expected_pickup_time**,\t**temperature_control**, **destination_store_name**, **destination_address**, **destination_longitude**, **destination_latitude**, **expected_delivery_time**, **driving_distance**, **driving_time**\t\t\t\t\t\t\t\t\t\t\t\t\t\n  [Learn more about the Google Sheet Node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googlesheets)\n\nLongitudes, latitudes, distance and time will be fetched from the **Open Route API**.\n"},"typeVersion":1},{"id":"2bb6e08e-1378-49dd-b3a4-ed68b2923705","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[0,0],"parameters":{"color":7,"width":180,"height":820,"content":"### 1. Workflow Trigger with Gmail Trigger\nThe workflow is triggered by a new email received in your Gmail mailbox dedicated to process **collection request**.\n\n#### How to setup?\n- **Gmail Trigger Node:** set up your Gmail API credentials\n[Learn more about the Gmail Trigger Node](https://docs.n8n.io/integrations/builtin/trigger-nodes/n8n-nodes-base.gmailtrigger)\n"},"typeVersion":1},{"id":"59841c15-7453-4069-9e6b-af0e9b24dbd4","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[200,0],"parameters":{"color":7,"width":440,"height":820,"content":"### 2. AI Agent to parse the collection process\nThis node will analyze the content of the email to extract information about the **sender** *(name, company)* and the **collections** *(address, time window)*.\n\n#### How to setup?\n- **AI Agent with the Chat Model**:\n   1. Add a **chat model** with the required credentials *(Example: Open AI 4o-mini)*\n   2. Adapt the system prompt to the format of emails you expect to receive *(type of information included)*\n  [Learn more about the AI Agent Node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.agent)\n"},"typeVersion":1},{"id":"95067b31-0ab2-48f2-b08f-ef08989c81ac","name":"OpenAI Chat Model2","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[260,660],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"typeVersion":1.2},{"id":"48a5b173-0022-4628-b4c2-acb8a0a19122","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[800,1120],"parameters":{"color":7,"width":680,"height":720,"content":"### 4. Reply with a confirmation of shipment allocation\nWe first collect all the information of the sequence of pickups from the **Google Sheets** the AI Agent will use that to generate a reply by email.\n#### How to setup?\n- **Load records in the Google Sheet Node**:\n   1. Add your Google Sheet API credentials to access the Google Sheet file\n   2. Select the file using the list, an URL or an ID\n   3. Select the sheet in which you want to record your working sessions\t\t\t\t\t\t\t\t\t\t\t\n  [Learn more about the Google Sheet Node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googlesheets)\n- **AI Agent with the Chat Model**:\n   1. Add a **chat model** with the required credentials *(Example: Open AI 4o-mini)*\n   2. Adapt the system prompt with your company information **(name, contact, position)**\n  [Learn more about the AI Agent Node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.agent)\n\n"},"typeVersion":1},{"id":"bb47b105-1f97-4b23-b92c-dbe318ab21f9","name":"Loop Over Items","type":"n8n-nodes-base.splitInBatches","position":[1080,460],"parameters":{"options":{},"batchSize":"=1"},"typeVersion":3},{"id":"60ede508-1b35-4ce3-a316-b23bd8d59ef3","name":"Split by Address","type":"n8n-nodes-base.splitOut","position":[840,460],"parameters":{"options":{},"fieldToSplitOut":"output"},"typeVersion":1},{"id":"5325cb92-2d71-4416-a521-1c911b1f6df3","name":"Extract Job","type":"n8n-nodes-base.code","position":[1580,700],"parameters":{"jsCode":"const steps = items[0].json.routes[0].steps;\n\nconst orderedJobs = steps\n  .filter(step => step.type === \"job\")\n  .map((step, index) => ({\n    id: step.job,\n    sequence: index + 1\n  }));\n\nreturn orderedJobs.map(job => ({ json: job }));\n"},"typeVersion":2},{"id":"6d56227b-9c13-4924-86b3-53573ead3642","name":"Jobs Mapping","type":"n8n-nodes-base.set","position":[1240,920],"parameters":{"options":{},"assignments":{"assignments":[{"id":"1d331865-d691-4f5b-9b6f-c6bac6b52e89","name":"jobs","type":"array","value":"={{ $json.jobs }}"}]}},"notesInFlow":true,"typeVersion":3.4},{"id":"17afe2de-5512-4c23-bc31-a67ebd10a3c8","name":"Format Jobs","type":"n8n-nodes-base.code","position":[1040,700],"parameters":{"jsCode":"// This Function node transforms store pickup data into the OpenRouteService optimization payload\n\nconst inputData = items.map(item => item.json);\n\n// Build the jobs array\nconst jobs = inputData.map((entry, index) => ({\n  id: index + 1,\n  location: [entry.longitude, entry.latitude]\n}));\n\n// Take the second item as the starting location (adjust index if needed)\nconst vehicleStart = [inputData[1].longitude, inputData[1].latitude];\n\nconst vehicles = [\n  {\n    id: 1,\n    start: vehicleStart,\n    capacity: [100],\n    profile: \"driving-hgv\"\n  }\n];\n\nreturn [\n  {\n    json: {\n      jobs,\n      vehicles\n    }\n  }\n];\n"},"typeVersion":2},{"id":"ea3ebcd5-76c6-43cf-a486-bb778d473c0d","name":"Split Jobs","type":"n8n-nodes-base.splitOut","position":[1480,920],"parameters":{"options":{},"fieldToSplitOut":"jobs"},"typeVersion":1},{"id":"1af40684-cb06-455c-b6f5-0684c06438c3","name":"Merge Sequence with coordinates","type":"n8n-nodes-base.merge","position":[1820,780],"parameters":{"mode":"combine","options":{},"fieldsToMatchString":"id"},"notesInFlow":true,"typeVersion":3.1},{"id":"4d77cac0-5d3a-4778-aa98-ad10e3aa33b2","name":"Format GPS Coordinates","type":"n8n-nodes-base.set","position":[2020,780],"parameters":{"options":{},"assignments":{"assignments":[{"id":"ffab2998-7250-4591-a192-f1a2980ea79c","name":"sequence","type":"string","value":"={{ $json.sequence }}"},{"id":"38b7058b-dbd9-4679-b054-5de4b791ce50","name":"gps_coordinates","type":"string","value":"={{ $json.location[0] }}, {{ $json.location[1] }}"}]}},"typeVersion":3.4},{"id":"308f8e6b-ea6a-484f-ac0e-3593fd197360","name":"Save Sequence & Duration","type":"n8n-nodes-base.googleSheets","position":[2200,780],"parameters":{"columns":{"value":{"sequence":"={{ $json.sequence }}","total_duration":"={{ ($('Request Open Route API').item.json.summary.duration/60).toFixed(2) }}","gps_coordinates":"={{ $json.gps_coordinates }}"},"schema":[{"id":"collection_request_id","type":"string","display":true,"removed":true,"required":false,"displayName":"collection_request_id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"store_id","type":"string","display":true,"removed":true,"required":false,"displayName":"store_id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"address","type":"string","display":true,"removed":true,"required":false,"displayName":"address","defaultMatch":false,"canBeUsedToMatch":true},{"id":"location_id","type":"string","display":true,"removed":true,"required":false,"displayName":"location_id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"longitude","type":"string","display":true,"removed":true,"required":false,"displayName":"longitude","defaultMatch":false,"canBeUsedToMatch":true},{"id":"latitude","type":"string","display":true,"removed":true,"required":false,"displayName":"latitude","defaultMatch":false,"canBeUsedToMatch":true},{"id":"gps_coordinates","type":"string","display":true,"removed":false,"required":false,"displayName":"gps_coordinates","defaultMatch":false,"canBeUsedToMatch":true},{"id":"collection_date","type":"string","display":true,"removed":true,"required":false,"displayName":"collection_date","defaultMatch":false,"canBeUsedToMatch":true},{"id":"collection_time","type":"string","display":true,"removed":true,"required":false,"displayName":"collection_time","defaultMatch":false,"canBeUsedToMatch":true},{"id":"sequence","type":"string","display":true,"removed":false,"required":false,"displayName":"sequence","defaultMatch":false,"canBeUsedToMatch":true},{"id":"total_duration","type":"string","display":true,"removed":false,"required":false,"displayName":"total_duration","defaultMatch":false,"canBeUsedToMatch":true},{"id":"row_number","type":"string","display":true,"removed":true,"readOnly":true,"required":false,"displayName":"row_number","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["gps_coordinates"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"update","sheetName":{"__rl":true,"mode":"list","value":1094697629,"cachedResultUrl":"","cachedResultName":"Multi-Stop"},"documentId":{"__rl":true,"mode":"list","value":"17wbroY0w6xmw8AT-p2c_n1WbHzmfesz6d1DJbp39fn8","cachedResultUrl":"","cachedResultName":"Transportation Orders"}},"notesInFlow":true,"typeVersion":4.6},{"id":"d1f64c61-2b7e-4454-b10d-7d9d49998eb7","name":"Format Schedule","type":"n8n-nodes-base.code","position":[1000,1520],"parameters":{"jsCode":"// Sort and format the pickup sequence\nconst sorted = items.sort((a, b) => a.json.sequence - b.json.sequence);\n\nconst pickupList = sorted.map((item, index) => `\n  <li><strong>Stop ${index + 1}</strong>: ${item.json.store_id}<br>\n  Address: ${item.json.address}<br>\n  Coordinates: ${item.json.gps_coordinates}<br>\n  Scheduled Time: ${item.json.collection_time}</li>\n`).join('');\n\nconst htmlReply = `\n<p>We have scheduled your multi-stop pickup request (ID: <strong>${sorted[0].json.collection_request_id}</strong>) for <strong>${sorted[0].json.collection_date}</strong> at <strong>${sorted[0].json.collection_time}</strong>.</p>\n\n<p>Below is the confirmed pickup sequence:</p>\n<ul>${pickupList}</ul>\n\n<p>The total estimated driving duration is <strong>${sorted[0].json.total_duration} minutes</strong>.</p>\n`;\n\nreturn [{ json: { formatted_reply: htmlReply } }];\n"},"typeVersion":2}],"connections":{"5 sec":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"GPS Pickup":{"main":[[{"node":"Save Pickup GPS","type":"main","index":0}]]},"Split Jobs":{"main":[[{"node":"Merge Sequence with coordinates","type":"main","index":1}]]},"Extract Job":{"main":[[{"node":"Merge Sequence with coordinates","type":"main","index":0}]]},"Format Jobs":{"main":[[{"node":"Request Open Route API","type":"main","index":0},{"node":"Jobs Mapping","type":"main","index":0}]]},"Jobs Mapping":{"main":[[{"node":"Split Jobs","type":"main","index":0}]]},"Gmail Trigger":{"main":[[{"node":"AI Agent Parser","type":"main","index":0}]]},"AI Agent Reply":{"main":[[{"node":"Reply","type":"main","index":0}]]},"AI Agent Parser":{"main":[[{"node":"Split by Address","type":"main","index":0},{"node":"Collect Coordinates","type":"main","index":0},{"node":"Collect Shipment Information","type":"main","index":0}]]},"Format Schedule":{"main":[[{"node":"AI Agent Reply","type":"main","index":0}]]},"Loop Over Items":{"main":[[],[{"node":"Record Email Content","type":"main","index":0}]]},"Save Pickup GPS":{"main":[[{"node":"5 sec","type":"main","index":0}]]},"Split by Address":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Agent Reply","type":"ai_languageModel","index":0}]]},"OpenAI Chat Model2":{"ai_languageModel":[[{"node":"AI Agent Parser","type":"ai_languageModel","index":0}]]},"Collect Coordinates":{"main":[[{"node":"Format Jobs","type":"main","index":0}]]},"Record Email Content":{"main":[[{"node":"Query Open Route API Pickup","type":"main","index":0}]]},"Format GPS Coordinates":{"main":[[{"node":"Save Sequence & Duration","type":"main","index":0}]]},"Request Open Route API":{"main":[[{"node":"Extract Job","type":"main","index":0}]]},"Structured Output Parser":{"ai_outputParser":[[{"node":"AI Agent Parser","type":"ai_outputParser","index":0}]]},"Query Open Route API Pickup":{"main":[[{"node":"GPS Pickup","type":"main","index":0}]]},"Collect Shipment Information":{"main":[[{"node":"Format Schedule","type":"main","index":0}]]},"Merge Sequence with coordinates":{"main":[[{"node":"Format GPS Coordinates","type":"main","index":0}]]}}}


name: Post AI Videos to YouTube with Fal AI Veo3, Google Sheets, and YouTube API
author_name: Ari Nakos
author_username: just-aristides
categories: []
created_at: 2025-06-07T08:20:59.571Z
updated_at: 2025-06-07T08:20:59.571Z
url: https://n8n.io/workflows/4754
scraped_at: 2025-07-06 21:16:30
description:
  Auto-Post Veo3 Videos on YouTube

  An automated workflow for creating Veo3 videos and posting them to YouTube. 

  YT Tutorial: https://youtu.be/DXM1VA-vDX4

  Workflow Overview

  The workflow is divided into three main phases:

  Create Veo3 Video
  Wait for Video Processing
  Post on YouTube

  1. Create Veo3 Video

  This phase handles the initial video creation based on user input.

  Type Prompt:** A form trigger allows the user to input details for the video, including:
      Prompt: A simple scenario for the video.
      Video Style: (e.g., Dialogue, Monologue, Advertisement, Documentary)
      Aspect Ratio: (e.g., 16:9, 9:16, 1:1)
      Video Category: A YouTube category for the video.
  Get Specific Prompt:** Based on the selected "Video Style," the workflow fetches specific prompt data from a Google Sheet.
  Videography (AI Refinement):** An AI agent (using OpenRouter's Google Gemini 2.5 Flash model) refines the user's prompt into a detailed "script-to-screen" format suitable for video generation.
  Make FAL.AI Request:** The refined prompt is sent to the Fal.ai Veo 3 model via an HTTP request to generate the video. The video duration is fixed at 8 seconds.
  Store Data:** Details of the video request, including the date requested, the refined prompt, and the request URL, are stored in a Google Sheet.

  2. Wait for Video Processing

  Wait 5 mins:** The workflow pauses for 5 minutes. This waiting period is necessary as it typically takes 3-5 minutes for the video to be ready after the generation request.

  3. Post on YouTube

  This phase focuses on generating YouTube SEO details and uploading the video.

  YT Video SEO (AI Generation):** An AI agent (using OpenRouter's OpenAI GPT-4.1 Mini model) acts as a YouTube SEO specialist and viral content strategist. It generates the following details for the YouTube video:
      Video Title: A compelling title (less than 6 words).
      Video Description: A detailed description.
      Video Tags: Relevant tags to maximize discoverability.
      YouTube Category: The appropriate YouTube category code based on the user's input.
      The AI agent is configured to follow guidelines for virality and YouTube's tag limits.
  Structured Output:** Parses the structured JSON output from the AI agent.
  Get Keywords:** Extracts and formats the video tags into a comma-separated list suitable for YouTube.
  Fetch Video Credentials:** Fetches the video URL and other credentials from Fal.ai.
  Download Video:** Downloads the generated video file.
  Post on YouTube:** The video is uploaded to YouTube using the generated title, description, tags, and category.

  Setup

  To run this workflow, you need to set up credentials in n8n for:

  OpenRouter:** Generate API key from your OpenRouter account.
  Google Sheets:** Uses OAuth 2.0. Connect by authenticating your Google account.
  YouTube Data API:** Configure credentials to allow posting videos to YouTube.

  If you do not have an n8n account, follow the tutorial at https://youtu.be/E2yQelHPUdU?feature=shared to get started.

nodes_used:
  ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.youTube","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.chainLlm","@n8n/n8n-nodes-langchain.outputParserStructured","@n8n/n8n-nodes-langchain.lmChatOpenRouter"]

workflow_json:
  {"id":"LhLjl99uI0KRBmce","meta":{"instanceId":"5b9aff0ecdeb17791c04b93eac72e39e69151cfa63708980e5d936abe9308b8c","templateCredsSetupCompleted":true},"name":"Automatic YT post Veo 3 Video","tags":[],"nodes":[{"id":"73f3c07c-3b0d-41c5-902e-471cb2154a97","name":"Store Data","type":"n8n-nodes-base.googleSheets","position":[200,-80],"parameters":{},"typeVersion":4.5},{"id":"16dc0f5e-4940-4822-8145-903961e239e6","name":"Type Prompt","type":"n8n-nodes-base.formTrigger","position":[-20,-380],"webhookId":"0a2fd6c9-41d2-417b-b127-6ee76b8bf9f9","parameters":{},"typeVersion":2.2},{"id":"22b7e038-266e-4318-ab9d-c785c1f66ad0","name":"Wait 5 mins","type":"n8n-nodes-base.wait","position":[400,-80],"webhookId":"b9936e8b-f3bc-4286-8dc6-6824561bc026","parameters":{},"typeVersion":1.1},{"id":"f145ccec-54ed-4e8b-964f-9242f755500d","name":"Structured Output","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[180,340],"parameters":{},"typeVersion":1.2},{"id":"541336ec-1905-4450-be25-c3e1c87fd4cb","name":"AI Brain","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[-20,340],"parameters":{},"typeVersion":1},{"id":"c6d924d3-e5b3-4b8f-8463-0b69eee36d61","name":"Get Keywords","type":"n8n-nodes-base.code","position":[400,180],"parameters":{},"typeVersion":2},{"id":"649bb0b2-994d-49e2-96be-ec3e3690a5c4","name":"YT Video SEO","type":"@n8n/n8n-nodes-langchain.agent","maxTries":2,"position":[-20,180],"parameters":{},"retryOnFail":true,"typeVersion":1.9,"waitBetweenTries":3000},{"id":"2e170ba3-abc6-46f4-9c2b-bed7a04a2ee7","name":"AI_Brain","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[360,-220],"parameters":{},"typeVersion":1},{"id":"22e836ad-8f4e-4303-bf23-071ec4d6d46b","name":"Post on YouTube","type":"n8n-nodes-base.youTube","position":[400,520],"parameters":{},"typeVersion":1},{"id":"bfaa7f93-843a-4985-983f-3416181ac3b2","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-640,-300],"parameters":{"content":""},"typeVersion":1},{"id":"972b1cc2-4b1d-4aca-9e23-a61d06d67a61","name":"Fetch Video Credentials","type":"n8n-nodes-base.httpRequest","position":[-20,520],"parameters":{},"typeVersion":4.2},{"id":"7f5d89f7-5c0d-4c64-aa03-e708888d1b4b","name":"Get Specific Prompt","type":"n8n-nodes-base.googleSheets","position":[200,-380],"parameters":{},"typeVersion":4.5},{"id":"7e2b0334-7ee4-4ee0-bea1-5722878e59c1","name":"Videography","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[400,-380],"parameters":{},"typeVersion":1.6},{"id":"30ff24ca-6226-4f12-833b-2dac6c52b627","name":"Download Video","type":"n8n-nodes-base.httpRequest","position":[160,520],"parameters":{},"typeVersion":4.2},{"id":"78b7ee1d-c0cd-46f6-93e1-c2ff8c8b8d02","name":"Make FAL.AI Request","type":"n8n-nodes-base.httpRequest","position":[-20,-80],"parameters":{},"typeVersion":4}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"ceb92dd5-4f85-456a-a770-e22db9285a0b","connections":{"AI Brain":{"ai_languageModel":[[{"node":"YT Video SEO","type":"ai_languageModel","index":0}]]},"AI_Brain":{"ai_languageModel":[[{"node":"Videography","type":"ai_languageModel","index":0}]]},"Store Data":{"main":[[{"node":"Wait 5 mins","type":"main","index":0}]]},"Type Prompt":{"main":[[{"node":"Get Specific Prompt","type":"main","index":0}]]},"Videography":{"main":[[{"node":"Make FAL.AI Request","type":"main","index":0}]]},"Wait 5 mins":{"main":[[{"node":"YT Video SEO","type":"main","index":0}]]},"Get Keywords":{"main":[[{"node":"Fetch Video Credentials","type":"main","index":0}]]},"YT Video SEO":{"main":[[{"node":"Get Keywords","type":"main","index":0}]]},"Download Video":{"main":[[{"node":"Post on YouTube","type":"main","index":0}]]},"Post on YouTube":{"main":[[]]},"Structured Output":{"ai_outputParser":[[{"node":"YT Video SEO","type":"ai_outputParser","index":0}]]},"Get Specific Prompt":{"main":[[{"node":"Videography","type":"main","index":0}]]},"Make FAL.AI Request":{"main":[[{"node":"Store Data","type":"main","index":0}]]},"Fetch Video Credentials":{"main":[[{"node":"Download Video","type":"main","index":0}]]}}}


name: Chat with PDF / MD / Text Files using GraphRAG (no vector store needed)
author_name: InfraNodus
author_username: infranodus
categories: []
created_at: 2025-06-07T09:42:46.538Z
updated_at: 2025-06-07T09:42:46.538Z
url: https://n8n.io/workflows/4755
scraped_at: 2025-07-06 21:16:30
description:
  Set up a chat with your documents without the complex vector store setup.

  This templates helps you 
  ingest** your PDF / text / MD documents into a knowledge graph
  use the graph as the knowledge base for your AI chatbots (and other workflows)
  visualize the main topics* and *gaps** in your documents (good for observability and research)


  The knowledge base is provided using the InfraNodus GraphRAG with the knowledge graphs  offering high-quality responses without the need to set up complex RAG vector store workflows.

  The advantages of using GraphRAG instead of the standard vector stores for knowledge are:

  Easy and quick to set up and update** — no complex data import workflows needed
  A knowledge graph offers a holistic and interactive view of your knowledge base (accessible via our API or a web interface — also shareable)
  Better retrieval of relations** between the document chunks = higher quality responses

  How it works
  This template uses the InfraNodus knowledge graph as a knowledge base for your n8n AI agent node.

  The knowledge graph contains the documents you can upload using this template from your Google Drive.

  When the user asks a question via the chat interface, the agent forwards this question to the InfraNodus knowledge graph, retrieves a response, a summary, and a list of matching statements (based advanced Graph RAG), then delivers the final response back the user.

  Here's a description step by step:

  Step 1: Upload your documents
  Put the PDF / text / MD files you want to chat with into a folder on your Google drive
  Authorize access to that folder using the Google drive node in the template. 
  Add the InfraNodus API key to the InfraNodus Save to Graph HTTP node 
  Optional: change the name of the graph you want to save the data to in the InfraNodus HTTP node (in the name field of the HTTP post request).
  Run the workflow to ingest all the files and save them into the graph
  Optional: check the link provided in the Step 1 workflow description to see the visualization of your knowledge base. It will look something like that:



  Note:* you can replace the PDF to Text convertor node with a better quality *PDF convertor* from ConvertAPI which respects the original file layout and doesn't split text into small chunks


  Step 2: Chat with your documents

  Deactive the trigger in the Step 1
  Activate the chat trigger in the Step 2
  Add your InfraNodus API credentials to Knowledge Base GraphRAG InfraNodus node
  Optional: change the graph name in the Knowledge Base node to match the name you provided in the step 1 above
  Run the chat and ask the question
  Watch the magic 

  How to use

  You need an InfraNodus GraphRAG API account and key to use this workflow. 

  Create an InfraNodus account
  Get the API key at https://infranodus.com/api-access and create a Bearer authorization key for the InfraNodus HTTP nodes.

  Requirements

  An InfraNodus account and API key
  An OpenAI (or any other LLM) API key
  A Google Drive OAuth access (follow the n8n instructions)
  Optional: ConvertAPI API key for better quality PDF conversion

  Customizing this workflow

  You can customize this workflow by adding several experts to your AI agent. 

  Check out the complete guide at https://support.noduslabs.com/hc/en-us/articles/20174217658396-Using-InfraNodus-Knowledge-Graphs-as-Experts-for-AI-Chatbot-Agents-in-n8n

  Also check out the video tutorial with a demo:



  For support and feedback, please, contact us at https://support.noduslabs.com

  To learn more about InfraNodus: https://infranodus.com

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.googleDrive","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.memoryBufferWindow"]

workflow_json:
  {"id":"EQVZKxcCDzTNXLRp","meta":{"instanceId":"2a26454b0172ffcb8d70ba77c235b1209f92cd71bf06c79ba609c7173b416d68","templateCredsSetupCompleted":true},"name":"Chat with PDF / MD / Text Files using GraphRAG (no vector store needed)","tags":[{"id":"66wgFoDi9Xjl74M3","name":"Support","createdAt":"2025-05-21T17:06:32.355Z","updatedAt":"2025-05-21T17:06:32.355Z"},{"id":"kRM0hQV2zw7VxrON","name":"Research","createdAt":"2025-05-21T19:44:19.136Z","updatedAt":"2025-05-21T19:44:19.136Z"},{"id":"sJk9cUvmMU8FkJXv","name":"AI","createdAt":"2025-05-20T13:16:15.636Z","updatedAt":"2025-05-20T13:16:15.636Z"}],"nodes":[{"id":"011910a9-c2a0-49eb-b1eb-8043e0c2accc","name":"Search Google Drive","type":"n8n-nodes-base.googleDrive","position":[-220,-120],"parameters":{"filter":{"folderId":{"__rl":true,"mode":"list","value":"13tqp0SaI_v4jG1CFLAZo96isx-UBno4v","cachedResultUrl":"https://drive.google.com/drive/folders/13tqp0SaI_v4jG1CFLAZo96isx-UBno4v","cachedResultName":"GraphRAG"}},"options":{},"resource":"fileFolder","returnAll":true,"queryString":"*"},"credentials":{"googleDriveOAuth2Api":{"id":"oz9iNMxcuQ2pxr1e","name":"Google Drive account"}},"typeVersion":3},{"id":"22872ac5-14e4-4ea7-b792-30e19a02cb88","name":"Loop Over Items","type":"n8n-nodes-base.splitInBatches","position":[260,-120],"parameters":{"options":{}},"typeVersion":3},{"id":"6456b7ac-f936-425a-a0ac-62fe118e985a","name":"Retrieve File","type":"n8n-nodes-base.googleDrive","position":[500,-80],"parameters":{"fileId":{"__rl":true,"mode":"id","value":"={{ $json.id }}"},"options":{},"operation":"download"},"credentials":{"googleDriveOAuth2Api":{"id":"oz9iNMxcuQ2pxr1e","name":"Google Drive account"}},"typeVersion":3},{"id":"8c1f2da9-fff4-457d-bc2e-7c84de3500b3","name":"Switch","type":"n8n-nodes-base.switch","position":[740,-20],"parameters":{"rules":{"values":[{"outputKey":"pdf","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"7b4e792b-ab6d-4b9b-88a1-d8e51bea6853","operator":{"type":"string","operation":"equals"},"leftValue":"={{$binary[\"data\"].mimeType}}","rightValue":"application/pdf"}]},"renameOutput":true},{"outputKey":"text","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"09b7d7c5-5353-4719-b4e2-072e4da39948","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{$binary[\"data\"].mimeType}}","rightValue":"text/plain"}]},"renameOutput":true},{"outputKey":"md","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"cb2e6726-97d8-4541-8383-deafff9b18e6","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{$binary[\"data\"].mimeType}}","rightValue":"text/markdown"}]},"renameOutput":true},{"outputKey":"json","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"d2763a45-a592-47c8-868f-59dfcd17a71c","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{$binary[\"data\"].mimeType}}","rightValue":"application/json"}]},"renameOutput":true},{"outputKey":"docs","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"0d9b561f-89c5-479e-a4e2-1f5f05fa8417","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{$binary[\"data\"].mimeType}}","rightValue":""}]},"renameOutput":true},{"outputKey":"csv","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"6b19deed-5d00-4796-bb9d-b4d87564a751","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{$binary[\"data\"].mimeType}}","rightValue":"csv"}]},"renameOutput":true}]},"options":{}},"typeVersion":3.2},{"id":"fe133ad7-bd7a-43e2-91a7-4b3dd2652490","name":"Extract from PDF","type":"n8n-nodes-base.extractFromFile","position":[1020,-240],"parameters":{"options":{},"operation":"pdf"},"typeVersion":1},{"id":"49f89141-a8ea-46c6-888d-cf9dafcc7c2a","name":"Extract from Text File","type":"n8n-nodes-base.extractFromFile","position":[1020,-60],"parameters":{"options":{},"operation":"text"},"typeVersion":1},{"id":"a47d8f07-917e-44ed-a69e-5d6085981d36","name":"Extract from Markdown","type":"n8n-nodes-base.extractFromFile","position":[1020,140],"parameters":{"options":{},"operation":"text"},"typeVersion":1},{"id":"a2298650-5408-45f8-accf-292ac669002a","name":"InfraNodus Save to Graph","type":"n8n-nodes-base.httpRequest","position":[1480,200],"parameters":{"url":"https://infranodus.com/api/v1/graphAndStatements?doNotSave=false&includeGraph=false&includeGraphSummary=true&includeGraph=false","method":"POST","options":{},"sendBody":true,"authentication":"genericCredentialType","bodyParameters":{"parameters":[{"name":"name","value":"graphrag_from_google_drive"},{"name":"text","value":"={{ $json.data }}"},{"name":"=categories","value":"=[filename: {{ $('Switch').item.json.name }}]"},{"name":"contextSettings","value":"={{{ \"squareBracketsProcessing\":\"IGNORE_BRACKETS\"} }}"}]},"genericAuthType":"httpBearerAuth"},"credentials":{"httpBearerAuth":{"id":"FPDx6PA5CtzGEIQc","name":"InfraNodus DeeMeeTree API Key"}},"typeVersion":4.2},{"id":"bb06d60a-01c7-4a1e-bc7a-901e1f7f175d","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-560,-480],"parameters":{"color":4,"width":2200,"height":980,"content":"# Step 1: Upload Your PDF / MD / Text Files to InfraNodus GraphRAG\n\n## Copy your PDF files to a Google drive and then upload them to your InfraNodus knowledge graph\n\n### InfraNodus visualizes your text as a knowledge graph, showing the main topics and ideas inside. It also provides API access to the knowledge graph, so you can use it as a knowledge base instead of the complex vector store setup\n\n1. You need an [InfraNodus](https://infranodus.com) account to use this workflow. Get the API key at [https://infranodus.com/api-access](https://infranodus.com/api-access)\n2. Also, specify the **name of the graph** you want to save the files to in the InfraNodus HTTP node\n3. When the workflow finishes running, you can get a visualization of your knowledge base at [https://infranodus.com/your_user_name/your_graph_name/edit](https://infranodus.com/your_user_name/your_graph_name/edit)\n\n\n"},"typeVersion":1},{"id":"38707a4d-b397-43e7-b55c-da18a00bb480","name":"Map PDF to Text","type":"n8n-nodes-base.set","position":[1320,-100],"parameters":{"options":{},"assignments":{"assignments":[{"id":"fd160009-0b92-46fc-9e34-a1283b810e91","name":"data","type":"string","value":"={{ $json.text }}"}]}},"typeVersion":3.4},{"id":"49426e56-7d6c-4dc0-a279-348dea59cca2","name":"Convert File to PDF","type":"n8n-nodes-base.httpRequest","disabled":true,"position":[1720,200],"parameters":{"url":"https://v2.convertapi.com/convert/pdf/to/txt","method":"POST","options":{"response":{"response":{"responseFormat":"text"}}},"sendBody":true,"contentType":"multipart-form-data","sendHeaders":true,"authentication":"genericCredentialType","bodyParameters":{"parameters":[{"name":"file","parameterType":"formBinaryData","inputDataFieldName":"data"}]},"genericAuthType":"httpBearerAuth","headerParameters":{"parameters":[{"name":"Accept","value":"application/octet-stream"}]}},"credentials":{"httpBearerAuth":{"id":"mDxLoJUWSmuTJsAC","name":"ConvertAPI"}},"notesInFlow":true,"typeVersion":4.2},{"id":"5d21b250-7b0f-4925-a858-5aa6badf5700","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[1680,-340],"parameters":{"color":2,"width":360,"height":840,"content":"## Optional: Better PDF Conversion\n\n### Standard Map PDF to Text node will split your PDF files into very short chunks, which deteriorates retrieval. \n\nUse can use [ConvertAPI](https://convertapi.com?ref=4l54n) which is a high-quality convertor that will respect the layout of the original document and not cut the paragraphs into short chunks. \n\nHere is an HTTP node that makes a request to their API to convert the PDF into text. If you have a ConvertAPI account, you can replace the \"Map PDF to Text\" node in step 4 with this node. \n"},"typeVersion":1},{"id":"ceda9ea4-963b-4ffb-a741-6e7eb3fc7411","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","disabled":true,"position":[-520,840],"webhookId":"a2cfd3b0-aaa4-4003-940d-e520e64830c6","parameters":{"public":true,"options":{"title":"Talk to PDFs"},"initialMessages":"=Ask any question about the PDFs or write `/question` to generate an interesting question to discuss."},"typeVersion":1.1},{"id":"d78cf21e-753b-44d3-a2b4-493f85aa5129","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[-240,840],"parameters":{"options":{"systemMessage":"You provide information about the topic of user's interest. Always use the knowledge base attached to get the final response. "}},"typeVersion":1.9},{"id":"02497c8b-89d6-4440-bc4d-d3906b9c4872","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-420,1100],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"07wFa8Wa4mMRCHAj","name":"OpenAi account 2"}},"typeVersion":1.2},{"id":"6d77fb59-fb03-4d22-ac40-4cf9bde25909","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[-260,1100],"parameters":{},"typeVersion":1.3},{"id":"978c8309-380d-4fc8-b238-e0d0148b77b9","name":"Knowledge Base GraphRAG","type":"n8n-nodes-base.httpRequestTool","position":[100,1060],"parameters":{"url":"https://infranodus.com/api/v1/graphAndAdvice?doNotSave=true&addStats=true&optimize=develop&includeStatements=true&includeGraphSummary=true&includeGraph=false","method":"POST","options":{},"sendBody":true,"authentication":"genericCredentialType","bodyParameters":{"parameters":[{"name":"name","value":"graphrag_from_google_drive"},{"name":"requestMode","value":"response"},{"name":"prompt","value":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('parameters2_Value', `User query to send to the expert`, 'string') }}"},{"name":"aiTopics","value":"true"}]},"genericAuthType":"httpBearerAuth","toolDescription":"You contain knowledge on the topic of user's interst"},"credentials":{"httpBearerAuth":{"id":"6lSuuSDajZrvI2GM","name":"InfraNodus API Key"}},"typeVersion":4.2},{"id":"b005f83d-3d4a-42c8-b70a-63e267747fcd","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-560,540],"parameters":{"width":2200,"height":700,"content":"# Step 2: Chat with your PDF / MD / Text Files using [InfraNodus](https://infranodus.com) Graph RAG Knowledge Base\n\n## InfraNodus is used instead of the vector store. It combines traditional RAG and GraphRAG, providing a better topical overview of your knowledge base and having a better understanding of relations between entities in your documents.\n\n1. Deactivate the trigger node in Step 1 and activate the trigger Chat node here\n2. Provide your API key at [https://infranodus.com/api-access](https://infranodus.com/api-access) to the HTTP agent tool\n3. Specify the same **name of the graph** as in the Step 1, so you query the graph where saved the files. \n4. If you connect several knowledge bases, make sure to describe them well, so the agent knows what to query. Get the description from the InfraNodus Graph > Project Notes > RAG enhancement"},"typeVersion":1},{"id":"6a6ad150-670d-45d5-a69e-0bafaf8f2ac4","name":"Click ‘Test workflow’ to ingest the documents","type":"n8n-nodes-base.manualTrigger","position":[-500,-120],"parameters":{},"typeVersion":1},{"id":"0a148a3f-e898-4f83-9ebb-82da7f3f4633","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-540,100],"parameters":{"width":680,"height":380,"content":"## [InfraNodus](https://infranodus.com) Knowledege Graph Example\n\n![InfraNodus knowledge graph](https://infranodus.com/images/front/infranodus-overview.jpg)"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"90ea1bad-6d21-4f20-81b4-0ba48cc7e7fa","connections":{"Switch":{"main":[[{"node":"Extract from PDF","type":"main","index":0}],[{"node":"Extract from Text File","type":"main","index":0}],[{"node":"Extract from Markdown","type":"main","index":0}],[],[]]},"Retrieve File":{"main":[[{"node":"Switch","type":"main","index":0}]]},"Simple Memory":{"ai_memory":[[{"node":"AI Agent","type":"ai_memory","index":0}]]},"Loop Over Items":{"main":[[],[{"node":"Retrieve File","type":"main","index":0}]]},"Map PDF to Text":{"main":[[{"node":"InfraNodus Save to Graph","type":"main","index":0}]]},"Extract from PDF":{"main":[[{"node":"Map PDF to Text","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Search Google Drive":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Extract from Markdown":{"main":[[{"node":"InfraNodus Save to Graph","type":"main","index":0}]]},"Extract from Text File":{"main":[[{"node":"InfraNodus Save to Graph","type":"main","index":0}]]},"Knowledge Base GraphRAG":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"InfraNodus Save to Graph":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"When chat message received":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Click ‘Test workflow’ to ingest the documents":{"main":[[{"node":"Search Google Drive","type":"main","index":0}]]}}}


name: Perplexity-Style Iterative Research with Gemini and Google Search
author_name: slow-groovin@api2o.com
author_username: coze
categories: []
created_at: 2025-06-07T15:02:56.126Z
updated_at: 2025-06-07T15:02:56.126Z
url: https://n8n.io/workflows/4758
scraped_at: 2025-07-06 21:16:30
description:
  AI Comprehensive Research on User's Query with Gemini and Web Search

  What is this?
  Perform comprehensive research on a user's query by dynamically generating search terms, querying the web using Google Search (by Gemini) , reflecting on the results to identify knowledge gaps, and iteratively refining its search until it can provide a well-supported answer with citations. (like Perplexity)

  This workflow is a reproduction of gemini-fullstack-langgraph-quickstart in N8N.

  The gemini‑fullstack‑langgraph‑quickstart is a demo by the Google‑Gemini team that showcases how to build a powerful full‑stack AI agent using Gemini and LangGraph

  How It Works

  Generate Query 💬
  generates one or more search queries tasks based on the User's question.
  uses Gemini 2.0 Flash

  Web Research 🌐
  execute web search tasks using the native Google Search API tool in combination with Gemini 2.0 Flash.

  Reflection 📚
  Identifies knowledge gaps and generates potential follow-up queries. 

  Setup

  Configure API Credentials:
     Create Google Gemini(PaLM) Api Credential using you own Gemini key
     Connect the credential with three nodes: Google Gemini Chat Model and GeminiSearch and reflection

  Configure Redis Source:
     prepare a Redis service that can be accessed by n8n
     Create Redis Crediential and connect it with all Redis node

  Customize

  Try using different Gemini models.
  Try modifying the parameters number_of_initial_queries and max_research_loops.

  Why use Redis?

  Use Redis as an external storage to maintain global variables (counter, search results, etc.)

  This workflow contains a loop process, which need global variables (as State in LangGraph).

  It is difficult to achieve global variables management without external storage in n8n.

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.redis","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.chainLlm","@n8n/n8n-nodes-langchain.outputParserStructured","@n8n/n8n-nodes-langchain.lmChatGoogleGemini"]

workflow_json:
  {"id":"edWh6iOQTu7y6486","meta":{"instanceId":"94bbf33a17cc8d29e8a41abfd1860d1aec5b2f143689a453a1982644d2f887ce","templateCredsSetupCompleted":true},"name":"AI Comprehensive Research on User's Query (reproduction of gemini-fullstack-langgraph-quickstart)","tags":[{"id":"9RSNNkJyOaWv8b1W","name":"PROD","createdAt":"2025-06-07T13:12:52.397Z","updatedAt":"2025-06-07T13:12:52.397Z"}],"nodes":[{"id":"c350704e-408a-48a5-8cca-0f3000fd9964","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1580,-280],"parameters":{"color":5,"width":440,"height":620,"content":"### generate_query()\n- generates a search queries based on the User's question.\n- uses Gemini 2.0 Flash \n"},"typeVersion":1},{"id":"81280c83-b194-441b-98cc-0a1e3b32a3a7","name":"Configs","type":"n8n-nodes-base.set","position":[-1880,-60],"parameters":{"options":{},"assignments":{"assignments":[{"id":"0588e9af-ae35-4cc8-ba39-b7f03cd477b3","name":"number_of_initial_queries","type":"number","value":3},{"id":"5e9bcd7d-b9e7-4ddb-9b07-1aea1f19d46a","name":"max_research_loops","type":"number","value":3},{"id":"6e88599b-77f4-4efc-b3dd-a8e6526919c5","name":"current_date","type":"string","value":"={{$now.format('yyyy-LL-dd')}}"},{"id":"174f5bba-de62-4ed5-bc96-a26a7255a2e5","name":"conversation_id","type":"string","value":"=conversation:gemini-fullstack-langgraph-quickstart:{{ $json.sessionId }}:"}]}},"typeVersion":3.4},{"id":"ab01402a-5ae8-46e1-93f0-1297626ac61b","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-1980,-280],"parameters":{"color":4,"width":340,"height":400,"content":"### Configs\n- `number_of_initial_queries` (*The number of initial search queries to generate.*): 3\n- `max_research_loops` (*The maximum number of research loops to perform*): 3\n\n### variables:\n- `current_date`\n- `conversation_id`\n\n\n\n"},"typeVersion":1},{"id":"200465bd-6af2-41dc-9a83-7726b8ea64eb","name":"Google Gemini Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[-1540,200],"parameters":{"options":{},"modelName":"models/gemini-2.0-flash"},"credentials":{"googlePalmApi":{"id":"sUx2BOKL53mwfOJl","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"a124695f-cdd3-4990-bb03-df8ba0efaf9e","name":"Structured Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[-1260,180],"parameters":{"schemaType":"manual","inputSchema":"{\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"query\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"string\"\n      },\n      \"description\": \"A list of google search queries to be used for web research.\"\n    },\n    \"rationale\": {\n      \"type\": \"string\",\n      \"description\": \"A brief explanation of why these queries are relevant to the research topic.\"\n    }\n  },\n  \"required\": [\"query\", \"rationale\"],\n  \"additionalProperties\": false\n}"},"typeVersion":1.2},{"id":"9f6dca8b-0ecd-4957-860e-bd2fd3757804","name":"generate_query","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[-1480,-60],"parameters":{"text":"=Your goal is to generate sophisticated and diverse web search queries. These queries are intended for an advanced automated web research tool capable of analyzing complex results, following links, and synthesizing information.\n\nInstructions:\n- Always prefer a single search query, only add another query if the original question requests multiple aspects or elements and one query is not enough.\n- Each query should focus on one specific aspect of the original question.\n- Don't produce more than {{ $('Configs').item.json.number_of_initial_queries }} queries.\n- Queries should be diverse, if the topic is broad, generate more than 1 query.\n- Don't generate multiple similar queries, 1 is enough.\n- Query should ensure that the most current information is gathered. The current date is {{$('Configs').item.json.current_date}}.\n\nFormat: \n- Format your response as a JSON object with ALL three of these exact keys:\n   - \"rationale\": Brief explanation of why these queries are relevant\n   - \"query\": A list of search queries\n\nExample:\n\nTopic: What revenue grew more last year apple stock or the number of people buying an iphone\n```json\n\\{\\{\n    \"rationale\": \"To answer this comparative growth question accurately, we need specific data points on Apple's stock performance and iPhone sales metrics. These queries target the precise financial information needed: company revenue trends, product-specific unit sales figures, and stock price movement over the same fiscal period for direct comparison.\",\n    \"query\": [\"Apple total revenue growth fiscal year 2024\", \"iPhone unit sales growth fiscal year 2024\", \"Apple stock price growth fiscal year 2024\"],\n\\}\\}\n```\n\nContext: {{ $('When chat message received').item.json.chatInput }}","batching":{},"promptType":"define","hasOutputParser":true},"notesInFlow":true,"typeVersion":1.7},{"id":"444dc185-c6eb-4bb8-910b-6be5425d6e8a","name":"Split Out","type":"n8n-nodes-base.splitOut","position":[-720,-60],"parameters":{"options":{"destinationFieldName":"search_query"},"fieldToSplitOut":"search_query"},"typeVersion":1},{"id":"9a4f9f01-625b-4ae9-8204-39ce085f3a5d","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-760,-420],"parameters":{"color":5,"width":2120,"height":560,"content":"## web_research()\n\nExecutes a web search using the native Google Search API tool in combination with Gemini 2.0 Flash.\n\n- use `HTTP Reqeust` node to send raw Gemini google_search query\n"},"typeVersion":1},{"id":"dd18d2e1-b134-41b4-acd8-04eb18fa0216","name":"attach index as id","type":"n8n-nodes-base.code","position":[-120,-60],"parameters":{"mode":"runOnceForEachItem","jsCode":"let idx=0\nconst obj=$input.item.json\nconst keys=Object.keys(obj)\nfor(const key of keys){\n  if(key.endsWith('web_search_idx')){\n    idx=Number(obj[key])\n  }\n}\nreturn {\n  id: idx,\n  search_query: $('search_query').item.json.search_query\n}"},"typeVersion":2},{"id":"89711398-353a-4183-98a3-0cd706331971","name":"web_search","type":"n8n-nodes-base.code","position":[280,-60],"parameters":{"mode":"runOnceForEachItem","jsCode":"const response= $input.item.json\nconst text=response.candidates[0].content.parts.map(p=>p.text??'').join('\\n');\nconst chunks =response?.candidates[0]?.groundingMetadata?.groundingChunks;\n\nconst resolvedMap=resolve_urls(chunks);\nconst citations=get_citations(response,resolvedMap)\nconst modified_text=insert_citation_markers(text,citations)\nlet sourcesGathered =dedupeByShortUrl(citations.flatMap(citation => citation[\"segments\"]));\n\n return {\n        \"sources_gathered\": sourcesGathered,\n        \"web_research_result\": [modified_text],\n    }\n\n/**\n   Create a map of the vertex ai search urls (very long) to a short url with a unique id for each url.\n  Ensures each original URL gets a consistent shortened form while maintaining uniqueness.\n * @param {Array<Object>} chunks - An array of chunk objects, each containing:\n *   - {Object} web - The web object containing:\n *     - {string} uri - The URI associated with the chunk.\n *     - {string} title - The title of the chunk (not used in the resolution process).\n * @returns {Record<string, {url: string, idx: number}>} - A map where the key is the URL\n *          and the value is an object containing the URL and its original index in the array.\n */\nfunction resolve_urls(chunks) {\n  if(!chunks || chunks.length===0){\n    chunks=[]\n  }\n  const prefix = \"https://vertexaisearch.cloud.google.com/id/\"\n  // Extract the 'uri' from each chunk's 'web' object\n  const urls = chunks?.map((chunk) => chunk?.web?.uri);\n\n  // Initialize an empty object to store the resolved URLs\n  /**\n   * @type {Record<string, {url: string, idx: number}>}\n   */\n  const resolvedMap = {};\n\n  // Populate the resolvedMap with the URLs and their corresponding index\n  for (let i = 0; i < urls.length; i++) {\n    const url = urls[i];\n    resolvedMap[url] = `${prefix}${$('attach index as id').item.json.id}-${i}`;\n  }\n\n  // Return the map of resolved URLs\n  return resolvedMap;\n}\n\n\n/**\n * Extracts and formats citation information from a response object.\n *\n * This function processes the grounding metadata from a response object and constructs a list of citation\n * objects. Each citation includes the start and end indices of the text segment, and a list of related\n * segments with links to external resources.\n *\n * @param {Object} response - The response object containing candidate and grounding metadata.\n * @param {Record<string, {url: string, idx: number}>} resolvedUrlsMap - A map of resolved URLs for each grounding chunk URI.\n * @returns {Array<Object>} citations - A list of citation objects, each containing:\n *   - {number} startIndex - The starting index of the cited segment.\n *   - {number} endIndex - The ending index of the cited segment.\n *   - {Array<Object>} segments - A list of citation segments, each containing:\n *     - {string} label - The title of the citation.\n *     - {string} shortUrl - The resolved URL for the citation.\n *     - {string} value - The original URI for the citation.\n */\nfunction get_citations(response, resolvedUrlsMap) {\n\n  // Initialize an empty array to store citation objects.\n  /**\n   * @type {Array<Object>}\n   */\n  const citations = [];\n\n  // Check if response and candidates exist, if not return an empty citations array.\n  if (!response || !response.candidates) {\n    console.log(\"no candidates in response\");\n    return citations;\n  }\n  const candidate = response?.candidates[0];\n\n  // Ensure that grounding metadata and grounding supports exist in the candidate.\n  if (\n    !candidate.groundingMetadata ||\n    !candidate.groundingMetadata.groundingSupports\n  ) {\n    console.log(\"no groundingMetadata in candidate\");\n    return citations;\n  }\n\n  // Iterate over each grounding support in the candidate's grounding metadata.\n  for (const support of candidate.groundingMetadata.groundingSupports) {\n    const citation = {};\n\n    // Skip if there's no segment information.\n    if (!support.segment) continue;\n\n    // Set the start index, defaulting to 0 if not provided.\n    const startIndex =\n      support.segment.startIndex !== null ? support.segment.startIndex : 0;\n\n    // Ensure that endIndex is provided; skip if missing.\n    if (support.segment.endIndex === null) continue;\n\n    // Set the citation's startIndex and endIndex.\n    citation.startIndex = startIndex;\n    citation.endIndex = support.segment.endIndex;\n\n    citation.segments = [];\n\n    // If grounding chunk indices exist, process each chunk.\n    if (\n      support.groundingChunkIndices &&\n      support.groundingChunkIndices.length > 0\n    ) {\n      for (const ind of support.groundingChunkIndices) {\n        try {\n          const chunk = candidate.groundingMetadata.groundingChunks[ind];\n          const resolvedUrl = resolvedUrlsMap[chunk.web.uri] || null;\n\n          // Push the segment details (title, resolved URL, original URI) to the segments array.\n          citation.segments.push({\n            label: chunk.web.title.split(\".\").slice(0, -1).join(\".\"),\n            shortUrl: resolvedUrl,\n            value: chunk.web.uri,\n          });\n        } catch (error) {\n          // If an error occurs (e.g., index out of bounds or missing fields), skip the chunk.\n          continue;\n        }\n      }\n    }\n\n    // Log the citation object (for debugging purposes).\n    // console.log(\"citation\", citation);\n\n    // Push the processed citation to the citations array.\n    citations.push(citation);\n  }\n\n  // Return the citations array inside an object.\n  return citations;\n}\n\n/**\n * Inserts citation markers into a text string based on start and end indices.\n *\n * This function takes the original text and a list of citations, where each citation contains\n * the start and end indices, as well as the corresponding citation segments. It inserts\n * citation markers at the specified positions in the text.\n *\n * @param {string} text - The original text string.\n * @param {Array<Object>} citationsList - A list of citation objects, each containing:\n *   - {number} startIndex - The starting index of the citation in the original text.\n *   - {number} endIndex - The ending index of the citation in the original text.\n *   - {Array<Object>} segments - An array of objects where each object represents a citation segment containing:\n *     - {string} label - The label for the citation (typically the title).\n *     - {string} shortUrl - The URL to link to for the citation.\n *\n * @returns {string} - The modified text with citation markers inserted.\n */\nfunction insert_citation_markers(text, citationsList) {\n  // Sort the citations first by 'endIndex' in descending order, and then by 'startIndex' in descending order\n  // This ensures that insertions at the end of the string don't affect earlier parts of the text\n  const sortedCitations = citationsList.sort((a, b) => {\n    if (a.endIndex === b.endIndex) {\n      return b.startIndex - a.startIndex; // Secondary sorting by 'startIndex'\n    }\n    return b.endIndex - a.endIndex; // Primary sorting by 'endIndex'\n  });\n\n  let modifiedText = text;\n\n  // Iterate over each sorted citation and insert the corresponding citation markers\n  for (const citationInfo of sortedCitations) {\n    const endIdx = citationInfo.endIndex;\n    let markerToInsert = \"\";\n\n    // Create a citation marker for each segment in the citation\n    for (const segment of citationInfo.segments) {\n      markerToInsert += ` [${segment.label}](${segment.shortUrl})`;\n    }\n\n    // Insert the citation marker at the specified 'endIdx' position in the text\n    modifiedText =\n      modifiedText.slice(0, endIdx) +\n      markerToInsert +\n      modifiedText.slice(endIdx);\n  }\n\n  return modifiedText;\n}\n\nfunction dedupeByShortUrl(array) {\n  const seen = new Set();\n  return array.filter(item => {\n    if (!seen.has(item.shortUrl)) {\n      seen.add(item.shortUrl);\n      return true;\n    }\n    return false;\n  });\n}"},"notesInFlow":true,"typeVersion":2},{"id":"60608a5b-c516-489f-a349-d30d91679f8b","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1680,-440],"parameters":{"color":5,"width":1620,"height":800,"content":"## reflection()\n\nIdentifies knowledge gaps and generates potential follow-up queries. \nAnalyzes the current summary to identify areas for further research \nand generates potential follow-up queries. \n\n#### Why use `HTTP Reuquest` node to send raw gemini chat request insteam of using builtin node ?\nThe output structured feature of builtin node can only attach schema text with prompt, it will not configure the `Structured output schema` of gemini api.\nWhen context becomes large, it will occasionally get wrong results.\n"},"typeVersion":1},{"id":"b72e5a88-6843-40a5-bee0-12aa781006d7","name":"merge web_search_result","type":"n8n-nodes-base.aggregate","onError":"continueRegularOutput","position":[480,-60],"parameters":{"options":{"mergeLists":true},"fieldsToAggregate":{"fieldToAggregate":[{"fieldToAggregate":"sources_gathered"},{"fieldToAggregate":"web_research_result"}]}},"typeVersion":1},{"id":"d7adf3a8-8d06-4e9e-80fa-e4a39b80476c","name":"history_web_research_result","type":"n8n-nodes-base.redis","position":[800,-60],"parameters":{"list":"={{ $('Configs').item.json.conversation_id }}history_web_research_result","tail":true,"operation":"push","messageData":"={{ $json.web_research_result }}"},"credentials":{"redis":{"id":"vkcglu8fjb4a4qC4","name":"Redis account"}},"typeVersion":1,"alwaysOutputData":true},{"id":"5914fadd-6916-4946-84d7-fd8bf4f4a816","name":"history_web_research_result1","type":"n8n-nodes-base.redis","position":[1020,-60],"parameters":{"key":"={{ $('Configs').item.json.conversation_id }}history_web_research_result","keyType":"list","options":{},"operation":"get","propertyName":"web_research_result"},"credentials":{"redis":{"id":"vkcglu8fjb4a4qC4","name":"Redis account"}},"typeVersion":1,"alwaysOutputData":false},{"id":"44ce8a55-9871-4135-bf0e-8321e003dc50","name":"history_sources_gathered","type":"n8n-nodes-base.redis","onError":"continueRegularOutput","position":[920,-220],"parameters":{"list":"={{ $('Configs').item.json.conversation_id }}history_sources_gathered","tail":true,"operation":"push","messageData":"={{ $json.sources_gathered.map(i=>JSON.stringify(i)) }}"},"credentials":{"redis":{"id":"vkcglu8fjb4a4qC4","name":"Redis account"}},"typeVersion":1,"alwaysOutputData":true},{"id":"28cb4f10-7ebe-4ad6-a026-6a758964bd01","name":"research_loop_count","type":"n8n-nodes-base.redis","position":[2400,-180],"parameters":{"key":"={{ $('Configs').item.json.conversation_id }}research_loop_count","operation":"incr"},"credentials":{"redis":{"id":"vkcglu8fjb4a4qC4","name":"Redis account"}},"typeVersion":1},{"id":"01225071-cd0d-4a3b-a31b-fa888fc174b5","name":"retrieve value","type":"n8n-nodes-base.code","position":[2700,-180],"parameters":{"mode":"runOnceForEachItem","jsCode":"\nconst obj=$input.item.json;\nlet research_loop_count=0\nfor(const key in obj){\n  if(key.endsWith(\"research_loop_count\")){\n    research_loop_count=obj[key]\n  }\n}\nlet reflectionOutput=$('reflection_output_parse').item.json;\nreflectionOutput={\n  ...reflectionOutput,\n  'query':reflectionOutput['follow_up_queries']\n}\nreturn {\n  research_loop_count,\n  output:reflectionOutput,\n  \n};"},"typeVersion":2},{"id":"b2ba1a2b-bb80-4f63-9b9c-bd5c48a71b26","name":"If finish","type":"n8n-nodes-base.if","position":[3080,120],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"or","conditions":[{"id":"fb949552-a7e0-4435-952f-616a0f0c6033","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $('reflection_output_parse').item.json.is_sufficient }}","rightValue":""},{"id":"d3bcbc5b-2082-4385-9758-93be8fa726d5","operator":{"type":"number","operation":"gte"},"leftValue":"={{ $json.research_loop_count }}","rightValue":"={{ $('Configs').item.json.max_research_loops }}"}]}},"typeVersion":2.2},{"id":"2cefd8b8-bedc-4648-82cd-dd2d5c587645","name":"search_query","type":"n8n-nodes-base.set","notes":"store search_query","position":[-500,-60],"parameters":{"options":{},"includeOtherFields":true},"notesInFlow":true,"typeVersion":3.4},{"id":"8b9eac0b-790b-4d81-bd03-fe246ec08d12","name":"number_of_ran_queries","type":"n8n-nodes-base.redis","position":[-300,-60],"parameters":{"key":"={{ $('Configs').item.json.conversation_id }}web_search_idx","operation":"incr"},"credentials":{"redis":{"id":"vkcglu8fjb4a4qC4","name":"Redis account"}},"typeVersion":1},{"id":"ede02fed-da90-46f2-b975-8a1dc4f03157","name":"GeminiSearch","type":"n8n-nodes-base.httpRequest","position":[80,-60],"parameters":{"url":"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent","method":"POST","options":{},"jsonBody":"={\n  \"contents\": [\n    {\n      \"role\": \"user\",\n      \"parts\": [\n        {\n          \"text\": \"Conduct targeted Google Searches to gather the most recent, credible information on <topic>{{$json.search_query.replaceAll('\"','\\\\\"')}}</topic> and synthesize it into a verifiable text artifact. \\n Instructions: \\n - Query should ensure that the most current information is gathered. The current date is {{$('Configs').item.json.current_date}}. \\n - Conduct multiple, diverse searches to gather comprehensive information. \\n - Consolidate key findings while meticulously tracking the source(s) for each specific piece of information. \\n - The output should be a well-written summary or report based on your search findings. \\n - Only include the information found in the search results, don't make up any information. \\n Research Topic: \\n  <topic>{{$json.search_query.replaceAll('\"','\\\\\"')}}</topic>\"\n        }\n      ]\n    }\n  ],\n  \"generationConfig\": {\n    \"temperature\":0,\n    \"responseMimeType\": \"text/plain\"\n  },\n  \"tools\": [\n    {\n      \"google_search\": {}\n    }\n  ]\n}","sendBody":true,"specifyBody":"json","authentication":"predefinedCredentialType","nodeCredentialType":"googlePalmApi"},"credentials":{"googlePalmApi":{"id":"K3ZKiouuaNNgrIjp","name":"gemini2"}},"typeVersion":4.2},{"id":"62514275-53d3-4dee-803f-138d79a23bbe","name":"Build reflection request body","type":"n8n-nodes-base.code","position":[1760,-180],"parameters":{"mode":"runOnceForEachItem","jsCode":"const prompt=`You are an expert research assistant analyzing summaries about \"${$('When chat message received').item.json.chatInput}\".\n\nInstructions:\n- Identify knowledge gaps or areas that need deeper exploration and generate a follow-up query. (1 or multiple).\n- If provided summaries are sufficient to answer the user's question, don't generate a follow-up query.\n- If there is a knowledge gap, generate a follow-up query that would help expand your understanding.\n- Focus on technical details, implementation specifics, or emerging trends that weren't fully covered.\n\nRequirements:\n- Ensure the follow-up query is self-contained and includes necessary context for web search.\n\nOutput Format:\n- Format your response as a JSON object with these exact keys:\n   - \"is_sufficient\": true or false\n   - \"knowledge_gap\": Describe what information is missing or needs clarification\n   - \"follow_up_queries\": Write a specific question to address this gap\n\n\n<Example>\n{{\n    \"is_sufficient\": true, // or false\n    \"knowledge_gap\": \"The summary lacks information about performance metrics and benchmarks\", // \"\" if is_sufficient is true\n    \"follow_up_queries\": [\"What are typical performance benchmarks and metrics used to evaluate [specific technology]?\"] // [] if is_sufficient is true\n}}\n</Example>\n\nReflect carefully on the Summaries to identify knowledge gaps and produce a follow-up query. Then, produce your output following this JSON format:\n\nSummaries:\n${$json.web_research_result.join('\\n\\n---\\n\\n')}\n`\n\nconst body={\n  \"contents\": [\n    {\n      \"role\": \"user\",\n      \"parts\": [\n        {\n          \"text\": prompt\n        }\n      ]\n    }\n  ],\n  \"generationConfig\": {\n    \"temperature\":0,\n    \"responseMimeType\": \"text/plain\",\n    \"responseSchema\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"is_sufficient\": {\n              \"type\": \"boolean\"\n            },\n            \"knowledge_gap\": {\n              \"type\": \"string\"\n            },\n            \"follow_up_queries\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"string\"\n              }\n            },\n            \"research_loop_count\": {\n              \"type\": \"integer\"\n            },\n            \"number_of_ran_queries\": {\n              \"type\": \"integer\"\n            }\n          },\n          \"required\": [\n            \"is_sufficient\",\n            \"knowledge_gap\",\n            \"follow_up_queries\",\n            \"research_loop_count\",\n            \"number_of_ran_queries\"\n          ]\n        }\n  }\n}\n\n\nreturn {body};"},"typeVersion":2},{"id":"5e9e6aa7-48fc-49bb-adac-fbaa81aac7fe","name":"reflection","type":"n8n-nodes-base.httpRequest","position":[1940,-180],"parameters":{"url":"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-05-20:generateContent","method":"POST","options":{},"jsonBody":"={{ $json.body.toJsonString() }}","sendBody":true,"specifyBody":"json","authentication":"predefinedCredentialType","nodeCredentialType":"googlePalmApi"},"credentials":{"googlePalmApi":{"id":"K3ZKiouuaNNgrIjp","name":"gemini2"}},"typeVersion":4.2},{"id":"01399baa-cce0-451c-8880-d00ada86b06e","name":"reflection_output_parse","type":"n8n-nodes-base.code","position":[2140,-180],"parameters":{"mode":"runOnceForEachItem","jsCode":"let text=$json.candidates[0].content.parts.map(p=>p.text??'').join()\n\n\nif(text.startsWith('\\`\\`\\`json'))\n  text=text.substring(7)\nif(text.endsWith('\\`\\`\\`'))\n  text=text.substring(0,text.length-3)\n  \nreturn JSON.parse(text);"},"typeVersion":2},{"id":"bca8cd04-3203-4fbe-a848-b87ad4bbb2b8","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[3380,-440],"parameters":{"color":5,"width":1160,"height":800,"content":"## finalize_answer()\nPrepares the final output by deduplicating and formatting sources, then\n    combining them with the running summary to create a well-structured\n    research report with proper citations."},"typeVersion":1},{"id":"2813a76e-10ed-4c8d-91f8-0d76a10aa60e","name":"Google Gemini Chat Model2","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[3440,160],"parameters":{"options":{"temperature":0},"modelName":"models/gemini-2.0-flash"},"credentials":{"googlePalmApi":{"id":"sUx2BOKL53mwfOJl","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"7c2a30b1-2d4a-4302-9584-24bb58d5baea","name":"finalize_answer","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[3500,-80],"parameters":{"text":"=Generate a high-quality answer to the user's question based on the provided summaries.\n\nInstructions:\n- The current date is {{ $('Configs').item.json.current_date }}.\n- You are the final step of a multi-step research process, don't mention that you are the final step. \n- You have access to all the information gathered from the previous steps.\n- You have access to the user's question.\n- Generate a high-quality answer to the user's question based on the provided summaries and the user's question.\n- you MUST include all the citations from the summaries in the answer correctly.\n\nUser Context:\n- {{ $('When chat message received').item.json.chatInput }}\n\nSummaries:\n{{ $('history_web_research_result1').item.json.web_research_result.join('\\n---\\n\\n') }}","batching":{},"promptType":"define"},"notesInFlow":true,"typeVersion":1.7},{"id":"52106115-e901-461f-ae7b-0207ea8e7ac2","name":"get:history_sources_gathered","type":"n8n-nodes-base.redis","position":[3880,-60],"parameters":{"key":"={{ $('Configs').item.json.conversation_id }}history_sources_gathered","keyType":"list","options":{},"operation":"get","propertyName":"sources_gathered"},"credentials":{"redis":{"id":"vkcglu8fjb4a4qC4","name":"Redis account"}},"typeVersion":1},{"id":"beeedb7e-1c37-416b-9535-4a1c78bb871d","name":"format answer","type":"n8n-nodes-base.code","position":[4340,-140],"parameters":{"mode":"runOnceForEachItem","jsCode":"// Add a new field called 'myNewField' to the JSON of the item\n$input.item.json.myNewField = 1;\nlet sources_gathered_list=$json.sources_gathered\nlet sources_gathered=[]\nfor (const str of sources_gathered_list) {\n  sources_gathered.push(JSON.parse(str))\n}\nconsole.log(sources_gathered)\nlet content=`## Answer\n\n`+$('finalize_answer').item.json.text;\n\nfor (let source of sources_gathered) {\n    console.log(typeof source)\n  console.log(source)\n}\nfor (let source of sources_gathered) {\n    if (content.includes(source.shortUrl)) {\n        content = content.replaceAll(\n            source.shortUrl, \n            source.value\n        );\n    }\n}\nlet step=`## steps\n\n\n`+$json.steps.join(`\n\n`)\nreturn {text:step+content};"},"typeVersion":2},{"id":"08544dfa-830e-44cf-b1ed-a8767c10b7ab","name":"web_search step record","type":"n8n-nodes-base.code","position":[520,-340],"parameters":{"mode":"runOnceForEachItem","jsCode":"// Add a new field called 'myNewField' to the JSON of the item\n$input.item.json.myNewField = 1;\nconst labels=$json.sources_gathered.map(s=>s.label);\nconst uniqueLabels=[...new Set(labels)];\nconst step=`##### Web Research\n\nGathered ${labels.length} sources. Related to: ${uniqueLabels.slice(3).map(label=>`\\`${label}\\``).join(', ')}.\n`\nreturn {step};"},"typeVersion":2},{"id":"7f6a3582-9102-43fb-8e83-1a30979f3c19","name":"push web_search step record","type":"n8n-nodes-base.redis","position":[720,-340],"parameters":{"list":"={{ $('Configs').item.json.conversation_id }}steps","tail":true,"operation":"push","messageData":"={{ $json.step }}"},"credentials":{"redis":{"id":"vkcglu8fjb4a4qC4","name":"Redis account"}},"typeVersion":1},{"id":"71962197-cf8d-45c9-877e-128f16b72ab9","name":"push reflection step","type":"n8n-nodes-base.redis","position":[2960,-220],"parameters":{"list":"={{ $('Configs').item.json.conversation_id }}steps","tail":true,"operation":"push","messageData":"=##### Reflection\n\n{{ $json.output.is_sufficient?'provided meterials are sufficient to answer the question':'Need more information, searching for more' }}\n\n{{ $json.research_loop_count>=$('Configs').item.json.max_research_loops?'resesarch loop count has Exceeded ':'' }}\n"},"credentials":{"redis":{"id":"vkcglu8fjb4a4qC4","name":"Redis account"}},"typeVersion":1},{"id":"9da14360-e877-4be9-a17d-7a19532886b8","name":"Merge","type":"n8n-nodes-base.merge","position":[4140,-140],"parameters":{"mode":"combine","options":{},"combineBy":"combineByPosition"},"typeVersion":3.2},{"id":"a3b73cfb-274c-4d1c-bcb2-7c2b74c9e8d0","name":"get:steps","type":"n8n-nodes-base.redis","position":[3860,-260],"parameters":{"key":"={{ $('Configs').item.json.conversation_id }}steps","keyType":"list","options":{},"operation":"get","propertyName":"steps"},"credentials":{"redis":{"id":"vkcglu8fjb4a4qC4","name":"Redis account"}},"typeVersion":1},{"id":"eb254b2b-1fd0-4bde-ad3b-7364e787bdd7","name":"set search_query","type":"n8n-nodes-base.set","position":[-960,-60],"parameters":{"options":{},"assignments":{"assignments":[{"id":"26ea508c-d4e3-4259-84c3-9389a2aaf374","name":"=search_query","type":"array","value":"={{ $json.output.query }}"}]}},"typeVersion":3.4},{"id":"cf181d8a-aad9-4851-9510-acb6c5d85b03","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[-2220,-60],"webhookId":"bd28c7ff-f08f-40a9-a2fc-6bb21de92d77","parameters":{"public":true,"options":{},"initialMessages":"# gemini-fullstack-langgraph-quickstart\nPowered by Google Gemini and n8n"},"typeVersion":1.1},{"id":"ab4f6234-eff9-4621-86fd-7ad3a2d23244","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-1980,-540],"parameters":{"width":800,"height":220,"content":"# gemini-fullstack-langgraph-quickstart-n8n\n\nThis is a reproduction of `gemini-fullstack-langgraph-quickstart` in **N8N**, nearly 1:1\n\nThe [`gemini‑fullstack‑langgraph‑quickstart`](https://github.com/google-gemini/gemini-fullstack-langgraph-quickstart) is a demo by the Google‑Gemini team that showcases how to build a powerful full‑stack AI agent using Gemini 2.5 and LangGraph\n\n- use external redis to maintain some global variables for every search (It is difficult to achieve global state in n8n)\n\n\n\n"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"3a9e9b60-fec5-4a9a-ad44-d69ec21355da","connections":{"Merge":{"main":[[{"node":"format answer","type":"main","index":0}]]},"Configs":{"main":[[{"node":"generate_query","type":"main","index":0}]]},"If finish":{"main":[[{"node":"finalize_answer","type":"main","index":0}],[{"node":"set search_query","type":"main","index":0}]]},"Split Out":{"main":[[{"node":"search_query","type":"main","index":0}]]},"get:steps":{"main":[[{"node":"Merge","type":"main","index":0}]]},"reflection":{"main":[[{"node":"reflection_output_parse","type":"main","index":0}]]},"web_search":{"main":[[{"node":"merge web_search_result","type":"main","index":0},{"node":"web_search step record","type":"main","index":0}]]},"GeminiSearch":{"main":[[{"node":"web_search","type":"main","index":0}]]},"search_query":{"main":[[{"node":"number_of_ran_queries","type":"main","index":0}]]},"generate_query":{"main":[[{"node":"set search_query","type":"main","index":0}]]},"retrieve value":{"main":[[{"node":"If finish","type":"main","index":0},{"node":"push reflection step","type":"main","index":0}]]},"finalize_answer":{"main":[[{"node":"get:history_sources_gathered","type":"main","index":0},{"node":"get:steps","type":"main","index":0}]]},"set search_query":{"main":[[{"node":"Split Out","type":"main","index":0}]]},"attach index as id":{"main":[[{"node":"GeminiSearch","type":"main","index":0}]]},"research_loop_count":{"main":[[{"node":"retrieve value","type":"main","index":0}]]},"number_of_ran_queries":{"main":[[{"node":"attach index as id","type":"main","index":0}]]},"web_search step record":{"main":[[{"node":"push web_search step record","type":"main","index":0}]]},"merge web_search_result":{"main":[[{"node":"history_web_research_result","type":"main","index":0},{"node":"history_sources_gathered","type":"main","index":0}]]},"reflection_output_parse":{"main":[[{"node":"research_loop_count","type":"main","index":0}]]},"Google Gemini Chat Model":{"ai_languageModel":[[{"node":"generate_query","type":"ai_languageModel","index":0}]]},"Structured Output Parser":{"ai_outputParser":[[{"node":"generate_query","type":"ai_outputParser","index":0}]]},"Google Gemini Chat Model2":{"ai_languageModel":[[{"node":"finalize_answer","type":"ai_languageModel","index":0}]]},"When chat message received":{"main":[[{"node":"Configs","type":"main","index":0}]]},"history_web_research_result":{"main":[[{"node":"history_web_research_result1","type":"main","index":0}]]},"get:history_sources_gathered":{"main":[[{"node":"Merge","type":"main","index":1}]]},"history_web_research_result1":{"main":[[{"node":"Build reflection request body","type":"main","index":0}]]},"Build reflection request body":{"main":[[{"node":"reflection","type":"main","index":0}]]}}}


name: Automate LinkedIn Posts with Claude AI, DALL-E Images & Google Sheets Approval
author_name: Usman Liaqat
author_username: usmanliaqat
categories: []
created_at: 2025-06-07T18:34:34.273Z
updated_at: 2025-06-07T18:34:34.273Z
url: https://n8n.io/workflows/4766
scraped_at: 2025-07-06 21:16:30
description:
  How it works

  This workflow automates your entire LinkedIn content strategy, from ideation to publishing.

  Daily Idea Generation:** Every day, the workflow uses an advanced AI agent (Anthropic's Claude model) to generate a new, viral-optimized LinkedIn post idea, complete with a title, full text, and a detailed image description. It analyzes your past posts from a Google Sheet to ensure content is fresh and aligns with one of your four content pillars: timeless principles, case studies, growth hacks, or controversial ads.
  AI Image Creation:** It then uses OpenAI's DALL-E to create a custom, high-quality image based on the generated description and a style reference image you provide, ensuring brand consistency.
  Review & Approval Workflow:** The generated post and its accompanying image are automatically saved as a new row in a Google Sheet, marked with a "review" status. This gives you full editorial control.
  Automated Publishing:** Once you approve a post by changing its status to "ready" in the Google Sheet, a separate part of the workflow picks it up and automatically publishes it to your LinkedIn profile at a scheduled time.
  Status Tracking:** After publishing, the workflow updates the status in your Google Sheet to "posted," so you always have a clear overview of your content pipeline.

  Set up steps

  This workflow integrates several services. Follow these steps to get it running:

  Copy the Google Sheet: Make a copy of the AI Posts Content Machine Google Sheet template and select your copy in the Get Past Ideas, Save Post, Get Ready Posts, and Update Status nodes.
  Set Up Credentials: You will need to create and add API credentials for the following services within the corresponding n8n nodes:
      Google Sheets & Google Drive: Create a Google credential.
      Anthropic: Add your API key in the Anthropic Chat Model node.
      OpenAI: Add your API key as a Header Auth credential in the OpenAI Image node.
      Perplexity AI: Add your API key as a Header Auth credential inside the Perplexity Research sub-workflow.
      LinkedIn: Create a LinkedIn credential.
  Customize Your Content:
      In the Idea Generator node, adjust the system prompt to reflect your specific audience, topics, and content style.
      Create a folder in Google Drive for your post images. Add a reference image to this folder that defines your desired visual style.
      Paste the shareable link to your style reference image into the Image Style node.
  Activate the Workflow: Enable the workflow to start the automated content creation and publishing process.

nodes_used:
  ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.googleDrive","n8n-nodes-base.facebookGraphApi","n8n-nodes-base.twitter","n8n-nodes-base.linkedIn","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatAnthropic","@n8n/n8n-nodes-langchain.outputParserStructured"]

workflow_json:
  {"meta":{"instanceId":"ba46fb650f86474799bdce64bc1a1b13792a092ea60f04bd2b668778ec59d1af","templateCredsSetupCompleted":true},"nodes":[{"id":"1a11e25a-ea01-4adb-a337-3f9a4a79ea64","name":"Idea Generator","type":"@n8n/n8n-nodes-langchain.agent","position":[1740,340],"parameters":{},"retryOnFail":true,"typeVersion":1.7},{"id":"9aa904db-7895-4832-b5c8-eb1d9c90eedd","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[1120,240],"parameters":{"content":""},"typeVersion":1},{"id":"d7935948-a3a3-45e7-ac8e-561bd6ec5498","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[2120,240],"parameters":{"content":""},"typeVersion":1},{"id":"bea82c2c-91ed-4e2c-8c1e-0cf43b4d0c3f","name":"Structured Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[1940,540],"parameters":{},"typeVersion":1.2},{"id":"276bffe0-5a03-40ae-aead-29a673c9035d","name":"Anthropic Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatAnthropic","position":[1600,540],"parameters":{},"typeVersion":1.3},{"id":"e35964d1-637e-48a9-95b7-054ee7a5fa7d","name":"Convert to File","type":"n8n-nodes-base.convertToFile","position":[2600,420],"parameters":{},"typeVersion":1.1},{"id":"10eec8ac-01de-4087-810d-0135161cead2","name":"Schedule","type":"n8n-nodes-base.scheduleTrigger","position":[1200,340],"parameters":{},"typeVersion":1.2},{"id":"d7cc1ac4-325f-4e92-b42b-b041a12e8ca0","name":"Join Ideas","type":"n8n-nodes-base.code","position":[1560,340],"parameters":{},"typeVersion":2},{"id":"56f96df4-d046-4d39-a98f-b7765e1ab4e3","name":"Pick One","type":"n8n-nodes-base.limit","position":[1560,840],"parameters":{},"typeVersion":1},{"id":"1fc65864-7215-4d74-a312-d324b9143c2b","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[1120,740],"parameters":{"content":""},"typeVersion":1},{"id":"c4388b53-6f36-45f3-826c-c54e0c01dd08","name":"X","type":"n8n-nodes-base.twitter","disabled":true,"position":[1780,1120],"parameters":{},"typeVersion":2},{"id":"c7d40512-ea04-4302-b5fa-bbaaac674109","name":"Prepare Data for Instagram API","type":"n8n-nodes-base.set","disabled":true,"position":[2040,1120],"parameters":{},"typeVersion":3.4},{"id":"39a9a9e4-04da-4953-a53e-c0f652749fcb","name":"Create Instagram Media Container","type":"n8n-nodes-base.facebookGraphApi","disabled":true,"position":[2220,1120],"parameters":{},"typeVersion":1},{"id":"0e8c9d4e-9fc9-4894-8046-66ac07c28a7c","name":"Wait for Container Processing","type":"n8n-nodes-base.wait","disabled":true,"position":[2420,1120],"webhookId":"1b14c8bf-151a-4054-8215-093dd5b6cbcc","parameters":{},"typeVersion":1.1},{"id":"2e5993a3-252f-4335-b1f7-6ba37fa9988a","name":"Publish Post to Instagram","type":"n8n-nodes-base.facebookGraphApi","disabled":true,"position":[2620,1120],"parameters":{},"typeVersion":1},{"id":"033dfb23-5e51-4a79-a6e4-f15d9497f0f1","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[1720,1060],"parameters":{"content":""},"typeVersion":1},{"id":"e01b66e9-2759-4509-aded-4028c07c4040","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[380,240],"parameters":{"content":""},"typeVersion":1},{"id":"8eb257ac-92f4-4ba9-93cd-4dac96b0e454","name":"OpenAI Image","type":"n8n-nodes-base.httpRequest","position":[2400,420],"parameters":{},"typeVersion":4.2},{"id":"cb8ed234-9678-46f7-982e-a1fb2b94ed11","name":"Image Style","type":"n8n-nodes-base.googleDrive","position":[2180,420],"parameters":{},"typeVersion":3},{"id":"b92bd35a-61e0-48bf-b092-64de27ecb737","name":"Get Past Ideas","type":"n8n-nodes-base.googleSheets","position":[1380,340],"parameters":{},"typeVersion":4.5,"alwaysOutputData":true},{"id":"84da84a9-f8e5-4e9f-be10-e1b938c5380f","name":"Save Image","type":"n8n-nodes-base.googleDrive","position":[2820,420],"parameters":{},"typeVersion":3},{"id":"3441c86d-3465-447d-af1c-65bf945d6629","name":"Save Post","type":"n8n-nodes-base.googleSheets","position":[3020,420],"parameters":{},"typeVersion":4.5},{"id":"d3421c14-3d77-4074-b3f4-87a2beb83ccd","name":"Schedule 2","type":"n8n-nodes-base.scheduleTrigger","position":[1200,840],"parameters":{},"typeVersion":1.2},{"id":"88aff01a-fedd-465f-987c-1079513871a0","name":"Get Ready Posts","type":"n8n-nodes-base.googleSheets","position":[1380,840],"parameters":{},"typeVersion":4.5},{"id":"797d6646-ff58-4826-a7fd-c474d323e627","name":"Download Image","type":"n8n-nodes-base.googleDrive","position":[1760,840],"parameters":{},"typeVersion":3},{"id":"7fcb5702-0c96-4510-aca8-59eed1bcd095","name":"Publish Post","type":"n8n-nodes-base.linkedIn","position":[1960,840],"parameters":{},"typeVersion":1},{"id":"b211beb9-55a0-4650-b6e2-873e31159f65","name":"Update Status","type":"n8n-nodes-base.googleSheets","position":[2160,840],"parameters":{},"typeVersion":4.5},{"id":"e903c168-b507-4e12-82e0-00519ac7c2fb","name":"Perplexity","type":"n8n-nodes-base.perplexityTool","position":[1800,560],"parameters":{},"typeVersion":1}],"connections":{"Pick One":{"main":[[{"node":"Download Image","type":"main","index":0}]]},"Schedule":{"main":[[{"node":"Get Past Ideas","type":"main","index":0}]]},"Join Ideas":{"main":[[{"node":"Idea Generator","type":"main","index":0}]]},"Perplexity":{"ai_tool":[[{"node":"Idea Generator","type":"ai_tool","index":0}]]},"Save Image":{"main":[[{"node":"Save Post","type":"main","index":0}]]},"Schedule 2":{"main":[[{"node":"Get Ready Posts","type":"main","index":0}]]},"Image Style":{"main":[[{"node":"OpenAI Image","type":"main","index":0}]]},"OpenAI Image":{"main":[[{"node":"Convert to File","type":"main","index":0}]]},"Publish Post":{"main":[[{"node":"Update Status","type":"main","index":0}]]},"Download Image":{"main":[[{"node":"Publish Post","type":"main","index":0}]]},"Get Past Ideas":{"main":[[{"node":"Join Ideas","type":"main","index":0}]]},"Idea Generator":{"main":[[{"node":"Image Style","type":"main","index":0}]]},"Convert to File":{"main":[[{"node":"Save Image","type":"main","index":0}]]},"Get Ready Posts":{"main":[[{"node":"Pick One","type":"main","index":0}]]},"Anthropic Chat Model":{"ai_languageModel":[[{"node":"Idea Generator","type":"ai_languageModel","index":0}]]},"Structured Output Parser":{"ai_outputParser":[[{"node":"Idea Generator","type":"ai_outputParser","index":0}]]},"Wait for Container Processing":{"main":[[{"node":"Publish Post to Instagram","type":"main","index":0}]]},"Prepare Data for Instagram API":{"main":[[{"node":"Create Instagram Media Container","type":"main","index":0}]]},"Create Instagram Media Container":{"main":[[{"node":"Wait for Container Processing","type":"main","index":0}]]}}}


name: VEO3 Video Generator with AI Optimization and Google Drive Storage
author_name: Friedemann Schuetz
author_username: freddy-schuetz
categories: []
created_at: 2025-06-07T18:34:44.834Z
updated_at: 2025-06-07T18:34:44.834Z
url: https://n8n.io/workflows/4767
scraped_at: 2025-07-06 21:16:30
description:
  Welcome to my VEO3 Video Generator Workflow!

  This automated workflow transforms simple text descriptions into professional 8-second videos using Google's cutting-edge VEO3 AI model. Users submit video ideas through a web form, and the system automatically generates optimized prompts, creates high-quality videos with native audio, and delivers them via Google Drive - all powered by Claude 4 Sonnet for intelligent prompt optimization.

  This workflow has the following sequence:
  VEO3 Generator Form - Web form interface for users to input video content, format, and duration
  Video Prompt Generator - AI agent powered by Claude 4 Sonnet that:
     Analyzes user input for video content requirements
     Creates factual, professional video titles
     Generates detailed VEO3 prompts with subject, context, action, style, camera motion, composition, ambiance, and audio elements
     Optimizes prompts for 16:9 landscape format and 8-second duration
  Create VEO3 Video - Submits the optimized prompt to fal.ai VEO3 API for video generation
  Wait 30 seconds - Initial waiting period for video processing to begin
  Check VEO3 Status - Monitors the video generation status via fal.ai API
  Video completed? - Decision node that checks if video generation is finished
     If not completed: Returns to wait cycle
     If completed: Proceeds to video retrieval
  Get VEO3 Video URL - Retrieves the final video download URL from fal.ai
  Download VEO3 Video - Downloads the generated MP4 video file
  Merge - Combines video data with metadata for final processing
  Save Video to Google Drive - Uploads the video to specified Google Drive folder
  Video Output - Displays completion message with Google Drive link to user

  The following accesses are required for the workflow:
  Anthropic API** (Claude 4 Sonnet): Documentation
  Fal.ai API** (VEO3 Model): Create API key at https://fal.ai/dashboard/keys
  Google Drive API**: Documentation

  Workflow Features:
  User-friendly web form**: Simple interface for video content input
  AI-powered prompt optimization**: Claude 4 Sonnet creates professional VEO3 prompts
  Automatic video generation**: Leverages Google's VEO3 model via fal.ai
  Status monitoring**: Real-time tracking of video generation progress
  Google Drive integration**: Automatic upload and sharing of generated videos
  Structured output**: Consistent video titles and professional prompt formatting
  Audio optimization**: VEO3's native audio generation with ambient sounds and music

  Current Limitations:
  Format**: Only 16:9 landscape videos supported
  Duration**: Only 8-second videos supported
  Processing time**: Videos typically take 60-120 seconds to generate

  Use Cases:
  Content creation**: Generate videos for social media, websites, and presentations
  Marketing materials**: Create promotional videos and advertisements
  Educational content**: Produce instructional and explanatory videos
  Prototyping**: Rapid video concept development and testing
  Creative projects**: Artistic and experimental video generation
  Business presentations**: Professional video content for meetings and pitches

  Feel free to contact me via LinkedIn, if you have any questions!

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.googleDrive","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatAnthropic","@n8n/n8n-nodes-langchain.outputParserStructured"]

workflow_json:
  {"id":"iuPhSS8Dr2Dl7Hbo","meta":{"instanceId":"7dfa146768a036d27a67d125f90ea637bfb301bd4fd25d0086548016421d44bd","templateCredsSetupCompleted":true},"name":"VEO3 Video Generator TEMPLATE","tags":[],"nodes":[{"id":"62e94b7e-b516-4cba-8a00-8179e743520f","name":"Anthropic Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatAnthropic","position":[-52,370],"parameters":{"model":{"__rl":true,"mode":"list","value":"claude-sonnet-4-20250514","cachedResultName":"Claude 4 Sonnet"},"options":{}},"credentials":{"anthropicApi":{"id":"WgfLltDtHqUy7q9O","name":"Anthropic account"}},"typeVersion":1.3},{"id":"78444fe1-3289-4f2a-871b-03908ba47553","name":"Structured Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[68,370],"parameters":{"schemaType":"manual","inputSchema":"{\n  \"type\": \"object\",\n  \"properties\": {\n    \"title\": {\n      \"type\": \"string\",\n      \"description\": \"Creative, meaningful title for the video - short, concise and matching the content\",\n      \"minLength\": 5,\n      \"maxLength\": 80\n    },\n    \"prompt\": {\n      \"type\": \"string\",\n      \"description\": \"Detailed VEO3 prompt with Subject, Context, Action, Style, Camera Motion, Composition, Ambiance and Audio elements\",\n      \"minLength\": 50,\n      \"maxLength\": 2000\n    },\n    \"aspect_ratio\": {\n      \"type\": \"string\",\n      \"enum\": [\"16:9\"],\n      \"description\": \"Video aspect ratio - currently only 16:9 Landscape/Cinema supported\"\n    },\n    \"duration\": {\n      \"type\": \"string\",\n      \"enum\": [\"8s\"],\n      \"description\": \"Video duration in seconds - currently only 8s supported\"\n    }\n  },\n  \"required\": [\"title\", \"prompt\", \"aspect_ratio\", \"duration\"],\n  \"additionalProperties\": false\n}"},"typeVersion":1.2},{"id":"6b7fa224-d30c-4acc-84ee-c458c20f2c89","name":"Video Prompt Generator","type":"@n8n/n8n-nodes-langchain.agent","position":[-80,150],"parameters":{"text":"=Video Content: {{ $json['Video Content'] }}\nFormat: {{ $json.Format }}\nDuration: {{ $json['Duration'] }}","options":{"systemMessage":"=You are an expert for VEO3 video prompts and video marketing. Create optimal parameters for high-quality video generation with Google's VEO3 model from user input, including a creative, appealing title.\n\nTITLE CREATION:\n- Factual and objective (5-80 characters)\n- Precisely describes the main content of the video\n- Factual and informative, without exaggeration\n- Uses neutral, descriptive language\n- Avoids emotional words like \"epic\", \"magical\", \"incredible\"\n- Professionally and seriously formulated\n\nTITLE CATEGORIES:\n- Action/Sport: \"Skier on Alpine slope\", \"Winter sports in the mountains\"\n- Dialog/Drama: \"Woman at train station\", \"Waiting scene in vintage setting\"\n- Nature/Landscape: \"Waterfall in rainforest\", \"Nature shot with water drops\"\n- Everyday/People: \"Chef in kitchen\", \"Work scene while cooking\"\n- Technology/Objects: \"Icicles melting\", \"Close-up of ice\"\n- Architecture: \"Modern building architecture\", \"Concrete building with organic forms\"\n\nVEO3 PROMPT STRUCTURE (use all relevant elements):\n\nMANDATORY ELEMENTS:\n- Subject: Main subject (person, object, animal, scenery)\n- Context: Background, setting, environment\n- Action: What happens, movements, actions\n\nOPTIONAL ELEMENTS (for better quality):\n- Style: Specific film styles (cinematic, film noir, documentary, 3D cartoon, realistic, action movie, etc.)\n- Camera Motion: dolly shot, tracking shot, aerial view, eye-level, top-down, low-angle, zoom in/out, pan shot, static shot\n- Composition: wide shot, close-up, extreme close-up, medium shot, over-the-shoulder, single shot, two shot\n- Ambiance: Color palette and lighting (warm golden tones, cool blue tones, natural sunlight, dramatic shadows, soft focus, shallow depth of field)\n- Audio: Dialogues (in quotation marks), Ambient Sounds, Music (VEO3 generates native audio!)\n\nTECHNICAL BEST PRACTICES:\n- Use descriptive adjectives and adverbs for clear images\n- For people: Specify facial details, emotions, clothing, body posture\n- For dialogues: Write exact words in quotation marks for perfect lip-sync\n- For realism: Mention physics, natural movements, realistic interactions\n- Camera work: Use professional film terminology\n- Lighting: Specify light sources and mood\n- Audio: Describe ambient sounds, music and spoken words\n\nASPECT RATIO INTELLIGENCE:\n- FAL.AI VEO3 currently supports ONLY 16:9 (Landscape) format\n- All videos are automatically created in 16:9 format\n- Optimize prompts for Landscape/Cinema presentation\n\nDURATION INTELLIGENCE:\n- FAL.AI VEO3 currently supports ONLY 8s duration\n- All videos are automatically created with 8s length\n- Optimize prompts for 8-second sequences\n\nAUDIO OPTIMIZATION (VEO3's strength!):\n- ALWAYS specify audio elements since VEO3 generates native audio\n- Dialogues: Exact words in quotation marks for perfect lip-sync\n- Ambient: Matching background sounds to the scene (wind, traffic, nature, etc.)\n- Music: Mood-appropriate description (energetic, melancholic, epic, upbeat, dramatic, etc.)\n- Sound Effects: Specific sounds (footsteps, doors, machines, etc.)\n\nSTYLE CATEGORIES (all optimized for 16:9 Landscape):\n- Cinematic: \"Cinematic style\", \"film noir\", \"documentary style\", \"movie scene\"\n- Animation: \"3D cartoon style render\", \"animated style\", \"stylized animation\"\n- Realistic: \"Photorealistic\", \"documentary footage\", \"natural lighting\"\n- Gaming: \"Video game aesthetic\", \"third-person view\", \"FPS perspective\"\n- Commercial: \"Advertisement style\", \"product showcase\", \"commercial photography\"\n- Action/Sport: \"Dynamic wide shots\", \"landscape cinematography\", \"widescreen action\"\n\nEXAMPLE PROMPTS (all optimized for 16:9 Landscape, 8s):\n\nAction/Sport:\nTitle: \"Skier on Alpine slope\"\nPrompt: \"Wide cinematic tracking shot following a professional skier carving down a pristine alpine slope. Camera positioned parallel to slope, capturing skier's full body and dramatic powder sprays against mountain landscape. Skier approaches from distance, passes camera at mid-range and continues down slope. As he passes, he shouts: 'I LOVE SKIING!' Audio captures swoosh of skis, wind rushing, clear English exclamation. Widescreen sports cinematography with motion blur, 8-second sequence showcasing pure skiing joy.\"\n\nDialog/Drama:\nTitle: \"Woman waiting at train station\"\nPrompt: \"Wide cinematic shot of a vintage train station with woman in 1940s dress walking through the bustling scene. Camera dollies alongside in medium wide shot, showing full environment and character. Steam rises from locomotives in background. She checks pocket watch while walking, worry visible on her face. Warm golden lighting filters through tall station windows. She whispers: 'He promised to be here.' Train announcements and steam hissing throughout. Film noir style, 8-second scene building dramatic tension.\"\n\nNature/Landscape:\nTitle: \"Waterfall in rainforest\"\nPrompt: \"Sweeping aerial establishing shot of a majestic waterfall cascading through lush rainforest. Camera starts wide, slowly moving closer to reveal mist and spray details. Full landscape visible with dense canopy and multiple water levels. Dappled sunlight filters through trees creating dynamic lighting. Natural sounds of rushing water, birds chirping, leaves rustling build throughout 8-second sequence. Documentary style with rich green tones and cinematic widescreen composition.\"\n\nEveryday/People:\nTitle: \"Chef preparing meal\"\nPrompt: \"Wide shot of a modern kitchen with chef enthusiastically preparing a meal. Camera circles around showing full cooking environment. Steam rises from multiple pans as chef juggles ingredients with theatrical flair. He declares with passion: 'Cooking is pure magic!' Sounds of sizzling, chopping, and upbeat background music. Bright, colorful lighting with warm kitchen ambiance. 8-second sequence capturing culinary excitement and energy.\"\n\nTransform the user input into a factual title and professional VEO3 prompt with maximum visual and audio quality. Consider all prompt elements for best possible results.\n\nIMPORTANT:\n- Create FIRST an objective, factual title without exaggeration\n- All videos are automatically created in 16:9 Landscape format with 8s duration\n- Optimize prompts accordingly for widescreen presentation and 8-second sequences\n- Title should factually describe what is shown in the video\n- Avoid emotional words like \"epic\", \"magical\", \"incredible\", \"spectacular\""},"promptType":"define","hasOutputParser":true},"typeVersion":2},{"id":"5791f2ee-9e4f-4eae-832f-42b091e6e118","name":"Merge","type":"n8n-nodes-base.merge","position":[1616,150],"parameters":{"mode":"combine","options":{},"combineBy":"combineByPosition"},"typeVersion":3.2},{"id":"2b7ed2cc-bd91-48f1-b2aa-1b77ea4350ae","name":"Create VEO3 Video","type":"n8n-nodes-base.httpRequest","position":[296,75],"parameters":{"url":"https://queue.fal.run/fal-ai/veo3","method":"POST","options":{"timeout":60000,"redirect":{"redirect":{}},"response":{"response":{"responseFormat":"json"}},"allowUnauthorizedCerts":false},"jsonBody":"={\n  \"prompt\": \"{{ $json.output.prompt }}\",\n  \"aspect_ratio\": \"{{ $json.output.aspect_ratio || '16:9' }}\",\n  \"duration\": \"{{ $json.output.duration || '8s' }}\"\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"Authorization","value":"Key <YOUR-FAL.AI API KEY>"},{"name":"Content-Type","value":"application/json"}]}},"typeVersion":4.2},{"id":"997b17c4-5e3c-48fa-8008-e44ead3556c2","name":"Wait 30 seconds","type":"n8n-nodes-base.wait","position":[516,75],"webhookId":"1b6bbe9b-4bfe-4a77-8627-73a05db0de8c","parameters":{"amount":30},"typeVersion":1.1},{"id":"2e94296b-5207-43a8-afe7-4e330df2d838","name":"Check VEO3 Status","type":"n8n-nodes-base.httpRequest","position":[736,0],"parameters":{"url":"=https://queue.fal.run/fal-ai/veo3/requests/{{ $('Create VEO3 Video').first().json.request_id }}/status","options":{},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"Authorization","value":"Key <YOUR-FAL.AI API KEY>"}]}},"typeVersion":4.2},{"id":"3b7d8752-f0c7-4315-bb31-cf0345762ed0","name":"Video completed?","type":"n8n-nodes-base.if","position":[956,75],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"e83af8f6-f0db-47fd-b41a-44c07929b186","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"COMPLETED"}]}},"typeVersion":2.2},{"id":"69760626-baf5-45a9-abe9-86c1b17b893d","name":"Get VEO3 Video URL","type":"n8n-nodes-base.httpRequest","position":[1176,75],"parameters":{"url":"=https://queue.fal.run/fal-ai/veo3/requests/{{ $('Create VEO3 Video').first().json.request_id }}","options":{},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"Authorization","value":"Key <YOUR-FAL.AI API KEY>"}]}},"typeVersion":4.2},{"id":"1f53010b-9041-4849-9e87-387ab1f389f6","name":"Download VEO3 Video","type":"n8n-nodes-base.httpRequest","position":[1396,75],"parameters":{"url":"={{ $json.video.url }}","options":{"response":{"response":{"responseFormat":"file"}}}},"typeVersion":4.2},{"id":"54231111-a879-412d-902d-bf52089f40cd","name":"Save Video to Google Drive","type":"n8n-nodes-base.googleDrive","position":[1836,150],"parameters":{"name":"={{ $json.output.title }}.mp4","driveId":{"__rl":true,"mode":"list","value":"My Drive"},"options":{},"folderId":{"__rl":true,"mode":"list","value":"1Q5slmjwk2tDrhN2BgQeZ6ITD-69dKYnV","cachedResultUrl":"https://drive.google.com/drive/folders/1Q5slmjwk2tDrhN2BgQeZ6ITD-69dKYnV","cachedResultName":"VEO3_Videos"}},"credentials":{"googleDriveOAuth2Api":{"id":"pTaHnocQoftc5pcK","name":"Google Drive account FSEP"}},"typeVersion":3},{"id":"a943c007-a670-419c-956d-7a95277892ab","name":"Video Output","type":"n8n-nodes-base.form","position":[2056,150],"webhookId":"7784e7d1-e01a-4b44-a6af-76811f3c5fca","parameters":{"options":{},"operation":"completion","completionTitle":"Your video has been created!","completionMessage":"=Your video \"{{ $('Merge').first().json.output.title }}\" has been successfully created!\nYou can access it here: {{ $json.webViewLink }}"},"typeVersion":1},{"id":"ed6338f2-edcb-40d0-9f08-dd9c79345ab8","name":"VEO3 Generator Form","type":"n8n-nodes-base.formTrigger","position":[-300,150],"webhookId":"1dea6a1a-8699-4b7a-a1be-0eeb50a10cc1","parameters":{"options":{"path":"veo3-video-generator","buttonLabel":"Create Video","appendAttribution":false},"formTitle":"VEO3 Video Generator","formFields":{"values":[{"fieldLabel":"Video Content","placeholder":"e.g. Magical waterfall in the rainforest","requiredField":true},{"fieldType":"dropdown","fieldLabel":"Format","fieldOptions":{"values":[{"option":"16:9"}]},"requiredField":true},{"fieldType":"dropdown","fieldLabel":"Duration","fieldOptions":{"values":[{"option":"8s"}]},"requiredField":true}]},"formDescription":"Currently only 16:9 and 8s videos are supported via fal.ai!"},"typeVersion":2.2},{"id":"93108f68-f541-4445-8795-007927b621b3","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1120,-420],"parameters":{"width":720,"height":1280,"content":"# Welcome to my VEO3 Video Generator Workflow!\n## This workflow has the following sequence:\n1. **VEO3 Generator Form** - Web form interface for users to input video content, format, and duration\n2. **Video Prompt Generator** - AI agent powered by Claude 4 Sonnet that:\n   - Analyzes user input for video content requirements\n   - Creates factual, professional video titles\n   - Generates detailed VEO3 prompts with subject, context, action, style, camera motion, composition, ambiance, and audio elements\n   - Optimizes prompts for 16:9 landscape format and 8-second duration\n3. **Create VEO3 Video** - Submits the optimized prompt to fal.ai VEO3 API for video generation\n4. **Wait 30 seconds** - Initial waiting period for video processing to begin\n5. **Check VEO3 Status** - Monitors the video generation status via fal.ai API\n6. **Video completed?** - Decision node that checks if video generation is finished\n   - If not completed: Returns to wait cycle\n   - If completed: Proceeds to video retrieval\n7. **Get VEO3 Video URL** - Retrieves the final video download URL from fal.ai\n8. **Download VEO3 Video** - Downloads the generated MP4 video file\n9. **Merge** - Combines video data with metadata for final processing\n10. **Save Video to Google Drive** - Uploads the video to specified Google Drive folder\n11. **Video Output** - Displays completion message with Google Drive link to user\n\n## The following accesses are required for the workflow:\n- **Anthropic API** (Claude 4 Sonnet): [Documentation](https://docs.n8n.io/integrations/builtin/credentials/anthropic/)\n- **Fal.ai API** (VEO3 Model): Create API key at [https://fal.ai/dashboard/keys](https://fal.ai/dashboard/keys)\n- **Google Drive API**: [Documentation](https://docs.n8n.io/integrations/builtin/credentials/google/)\n\n## Workflow Features:\n- **User-friendly web form**: Simple interface for video content input\n- **AI-powered prompt optimization**: Claude 4 Sonnet creates professional VEO3 prompts\n- **Automatic video generation**: Leverages Google's VEO3 model via fal.ai\n- **Status monitoring**: Real-time tracking of video generation progress\n- **Google Drive integration**: Automatic upload and sharing of generated videos\n- **Structured output**: Consistent video titles and professional prompt formatting\n- **Audio optimization**: VEO3's native audio generation with ambient sounds and music\n\n## Current Limitations:\n- **Format**: Only 16:9 landscape videos supported\n- **Duration**: Only 8-second videos supported\n- **Processing time**: Videos typically take 60-120 seconds to generate\n\n## Use Cases:\n- **Content creation**: Generate videos for social media, websites, and presentations\n- **Marketing materials**: Create promotional videos and advertisements\n- **Educational content**: Produce instructional and explanatory videos\n- **Prototyping**: Rapid video concept development and testing\n- **Creative projects**: Artistic and experimental video generation\n- **Business presentations**: Professional video content for meetings and pitches\n\nYou can contact me via LinkedIn, if you have any questions: https://www.linkedin.com/in/friedemann-schuetz"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"ebfd2536-b5dd-4a08-bd6a-0ca0f654ede7","connections":{"Merge":{"main":[[{"node":"Save Video to Google Drive","type":"main","index":0}]]},"Wait 30 seconds":{"main":[[{"node":"Check VEO3 Status","type":"main","index":0}]]},"Video completed?":{"main":[[{"node":"Get VEO3 Video URL","type":"main","index":0}],[{"node":"Wait 30 seconds","type":"main","index":0}]]},"Check VEO3 Status":{"main":[[{"node":"Video completed?","type":"main","index":0}]]},"Create VEO3 Video":{"main":[[{"node":"Wait 30 seconds","type":"main","index":0}]]},"Get VEO3 Video URL":{"main":[[{"node":"Download VEO3 Video","type":"main","index":0}]]},"Download VEO3 Video":{"main":[[{"node":"Merge","type":"main","index":0}]]},"VEO3 Generator Form":{"main":[[{"node":"Video Prompt Generator","type":"main","index":0}]]},"Anthropic Chat Model":{"ai_languageModel":[[{"node":"Video Prompt Generator","type":"ai_languageModel","index":0}]]},"Video Prompt Generator":{"main":[[{"node":"Create VEO3 Video","type":"main","index":0},{"node":"Merge","type":"main","index":1}]]},"Structured Output Parser":{"ai_outputParser":[[{"node":"Video Prompt Generator","type":"ai_outputParser","index":0}]]},"Save Video to Google Drive":{"main":[[{"node":"Video Output","type":"main","index":0}]]}}}


name: Build a Document-based AI Chatbot with Google Drive, Llama 3, and Qdrant RAG
author_name: Mohsin
author_username: mohsinobsidian
categories: []
created_at: 2025-06-08T07:38:46.273Z
updated_at: 2025-06-08T07:38:46.273Z
url: https://n8n.io/workflows/4773
scraped_at: 2025-07-06 21:16:30
description:
  Overview
  This template allows users to set up an AI-powered chatbot that retrieves and processes knowledge from Google Drive documents using Retrieval-Augmented Generation (RAG). By leveraging Llama 3 for natural language responses and Qdrant vector storage for document embeddings, this chatbot provides accurate, context-aware answers based on stored files.

  Problem It Solves
  Standard AI chatbots often rely on predefined models with limited real-time knowledge access. This workflow overcomes that limitation by:

  Automatically fetching new documents from Google Drive.

  Embedding knowledge for fast retrieval using Qdrant.

  Generating human-like responses with Llama 3 AI.

  Providing accurate, source-backed answers in conversations.

  Use Cases
  ✔️ Customer Support – Retrieve and summarize FAQs stored in Google Drive. ✔️ Internal Knowledge Base – Automate document-based query responses. ✔️ AI-powered Research Assistant – Search and generate insights from uploaded files. ✔️ Business Automation – Enhance workflows with document-aware chat interactions.

  Setup Instructions
  1️⃣ Google Drive Trigger: Detect & Fetch New Documents
  Watches for new files added to a specific Google Drive folder.

  Retrieves the latest file metadata and passes it into the workflow.

  2️⃣ Processing & Embedding the Document
  The document is downloaded via the Google Drive node.

  Text data is split into smaller, retrievable chunks using Recursive Text Splitter.

  Embeddings are created using Ollama’s Nomic-Embed Model.

  Knowledge is stored in Qdrant Vector Database for fast AI-powered lookup.

  3️⃣ AI Chatbot & Query Handling
  The Chat Trigger node listens for user queries.

  The AI Agent retrieves context-aware answers by searching Qdrant’s vectorized documents.

  The Llama 3 Model generates human-like responses based on stored knowledge.

  Detailed Workflow Explanation
  🔹 Google Drive Trigger
  ✅ Monitors a specific folder for new documents. ✅ Automatically fetches document metadata when a file is uploaded.

  🔹 Qdrant Vector Store
  ✅ Stores embedded document text, making retrieval instant & accurate. ✅ Allows the chatbot to reference stored knowledge dynamically.

  🔹 Recursive Text Splitter
  ✅ Splits long documents into manageable chunks for efficient embedding. ✅ Improves chatbot response accuracy by organizing document data.

  🔹 Llama 3 Chat Model
  ✅ Generates natural, human-like replies using AI. ✅ Uses retrieved document data for context-aware responses.

  Customization Options
  🔹 Adjust polling frequency for document updates. 🔹 Expand knowledge base by adding more storage sources. 🔹 Refine chatbot responses with prompt tuning in Llama 3.

nodes_used:
  ["n8n-nodes-base.googleDrive","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOllama","@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter","@n8n/n8n-nodes-langchain.documentDefaultDataLoader","@n8n/n8n-nodes-langchain.vectorStoreQdrant","@n8n/n8n-nodes-langchain.embeddingsOllama"]

workflow_json:
  {"id":"Mj1ghjtbl9gF3Zyv","meta":{"instanceId":"558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a","templateCredsSetupCompleted":true},"name":"RAG Pipeline and Chatbot","tags":[],"nodes":[{"id":"f7f16cac-dda3-45df-8725-4b0febd05a41","name":"Google Drive Trigger","type":"n8n-nodes-base.googleDriveTrigger","position":[0,0],"parameters":{},"typeVersion":1},{"id":"ca68784d-cf16-4e34-a069-54af6724b036","name":"Google Drive","type":"n8n-nodes-base.googleDrive","position":[220,0],"parameters":{},"typeVersion":3},{"id":"eb26965d-a53e-4a69-9cb3-a12aecb3c06c","name":"Embeddings Ollama","type":"@n8n/n8n-nodes-langchain.embeddingsOllama","position":[320,200],"parameters":{},"typeVersion":1},{"id":"517e0980-2cf6-43f6-9018-1debe566df18","name":"Default Data Loader","type":"@n8n/n8n-nodes-langchain.documentDefaultDataLoader","position":[440,200],"parameters":{},"typeVersion":1},{"id":"c51bf4a5-e644-46fd-8de5-61d169f55aa3","name":"Recursive Character Text Splitter","type":"@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter","position":[540,420],"parameters":{},"typeVersion":1},{"id":"e215d75e-6138-4c99-97cb-1456a2d96fc0","name":"Qdrant Vector Store","type":"@n8n/n8n-nodes-langchain.vectorStoreQdrant","position":[440,0],"parameters":{},"typeVersion":1.1},{"id":"cf9e6861-3b99-44f2-89d2-15fde5120254","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[1260,0],"parameters":{},"typeVersion":1.9},{"id":"de875567-e2f5-47e8-8145-0d6158a108b1","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[1040,0],"webhookId":"87268963-9b33-45ec-adb3-546e2868baac","parameters":{},"typeVersion":1.1},{"id":"a043f2ce-fd95-4286-8dd1-e3d1c9fd9051","name":"Ollama Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOllama","position":[1300,220],"parameters":{},"typeVersion":1},{"id":"58afa38b-0c7f-46d9-8d2e-a346ab2baf06","name":"Qdrant Vector Store1","type":"@n8n/n8n-nodes-langchain.vectorStoreQdrant","position":[1420,240],"parameters":{},"typeVersion":1.1},{"id":"c3151cb4-e066-40af-9eff-fe975fdffbb7","name":"Embeddings Ollama1","type":"@n8n/n8n-nodes-langchain.embeddingsOllama","position":[1420,460],"parameters":{},"typeVersion":1},{"id":"76717f0e-917a-492f-873e-9dae174ba04e","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[20,-840],"parameters":{"content":""},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"28873c1d-0035-45ba-81a0-02a5b35482da","connections":{"Google Drive":{"main":[[{"node":"Qdrant Vector Store","type":"main","index":0}]]},"Embeddings Ollama":{"ai_embedding":[[{"node":"Qdrant Vector Store","type":"ai_embedding","index":0}]]},"Ollama Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Embeddings Ollama1":{"ai_embedding":[[{"node":"Qdrant Vector Store1","type":"ai_embedding","index":0}]]},"Default Data Loader":{"ai_document":[[{"node":"Qdrant Vector Store","type":"ai_document","index":0}]]},"Google Drive Trigger":{"main":[[{"node":"Google Drive","type":"main","index":0}]]},"Qdrant Vector Store1":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"When chat message received":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Recursive Character Text Splitter":{"ai_textSplitter":[[{"node":"Default Data Loader","type":"ai_textSplitter","index":0}]]}}}


name: Discover & Analyze TikTok Influencers with Bright Data, Claude AI & Email Outreach
author_name: Dvir Sharon
author_username: dvirsharon
categories: []
created_at: 2025-06-08T08:44:40.329Z
updated_at: 2025-06-08T08:44:40.329Z
url: https://n8n.io/workflows/4774
scraped_at: 2025-07-06 21:16:30
description:
  🎯 Automated TikTok Influencer Discovery & Analysis

  A complete n8n automation that discovers TikTok influencers using Bright Data, evaluates their fit using Claude AI, and sends personalized outreach emails. Designed for marketing teams and brands that need a scalable, intelligent way to find and connect with relevant creators.

  📋 Overview

  This workflow provides a full-service influencer discovery pipeline: it finds TikTok profiles using search keywords, uses AI to assess alignment with your brand, and initiates contact with qualified influencers. Ideal for influencer marketing, brand partnerships, and campaign planning.

  ✨ Key Features

  🔍 Keyword-Based Discovery**  
    Locate TikTok influencers by specific niche-related keywords.

  📊 Bright Data Integration**  
    Access accurate TikTok profile data from Bright Data’s datasets.

  🤖 AI-Powered Analysis**  
    Claude AI evaluates each profile's fit with your brand based on bio, content, and more.

  📧 Smart Email Notifications**  
    Sends tailored outreach emails to creators deemed highly relevant.

  📈 Data Storage**  
    Google Sheets stores profile details, AI evaluation results, and outreach status.

  🎯 Intelligent Filtering**  
    Processes only influencers who meet your criteria (e.g., 5000+ followers, industry match).

  ⚡ Fast & Reliable**  
    Uses professional scraping with robust error handling.

  🔄 Batch Processing**  
    Supports bulk influencer processing through a single automated flow.

  🎯 What This Workflow Does

  Input

  Search Keywords** – TikTok terms for finding niche creators  
  Business Info** – Brand description and industry  
  Collaboration Criteria** – Follower count minimum, niche alignment

  Processing Steps

  Form Submission  
  TikTok Discovery via Bright Data  
  Data Extraction and Normalization  
  Save to Google Sheets  
  Relevance Scoring via Claude AI  
  Filtering Based on AI Score + Follower Count  
  Personalized Email Outreach

  Output Data Points

  | Field         | Description                        | Example                          |
  |---------------|------------------------------------|----------------------------------|
  | Profile ID    | TikTok profile identifier          | tiktoker123456                   |
  | Username      | TikTok handle                      | @creativecreator                 |
  | URL           | Profile link                       | https://tiktok.com/@creativecreator |
  | Description   | Creator bio                        | "Fashion & lifestyle content..." |
  | Followers     | Total follower count               | 50,000                           |
  | Collaboration | AI assessment of brand fit         | "Highly Relevant"               |
  | Analysis      | 50-word Claude AI relevance summary| "Strong alignment with fashion..."|

  🚀 Setup Instructions

  Prerequisites

  n8n (cloud or self-hosted)  
  Bright Data account with TikTok access  
  Google Sheets + Gmail  
  Anthropic Claude API key  
  10–15 minutes setup time

  Step-by-Step Setup

  Import Workflow via JSON in n8n  
  Configure Bright Data – Add API credentials and dataset ID  
  Google Sheets – Setup credentials and map columns  
  Claude AI – Insert API key and select desired model  
  Gmail – Authenticate Gmail and update mail node settings  
  Update Variables – Replace placeholders with business info  
  Test & Launch – Submit a sample form and verify all outputs

  📖 Usage Guide

  Adding Search Keywords

  Submit the form with search terms, business description, and industry category to trigger the workflow.

  Understanding AI Analysis

  Emails are sent only if:
    Collaboration status = Highly Relevant
    Follower count ≥ 5000
    Industry alignment confirmed
  Claude AI returns a 50-word analysis justifying the match

  Customizing Filters

  Edit the "Find the Collaborator" prompt to adjust:
  Follower thresholds
  Industry relevance
  Additional metrics (e.g., engagement rate)

  Viewing Results

  Google Sheets log includes:
  Influencer metadata
  AI scores and rationale
  Collaboration status
  Email delivery timestamp

  🔧 Customization Options

  Add More Fields:** Engagement rate, contact email, content themes  
  Email Personalization:** Customize message templates or integrate other mail services  
  Enhanced Filtering:** Use engagement rates, region, content frequency

  🚨 Troubleshooting

  | Issue | Fix |
  |-------|-----|
  | Bright Data fails | Recheck API and dataset ID |
  | No influencer data | Adjust keywords or dataset scope |
  | Sheets permission error | Re-authenticate and check sharing |
  | Claude fails | Validate API key and prompt |
  | Emails not sent | Re-auth Gmail or update recipient field |
  | Form not triggering | Reconfirm webhook URL and permissions |

  Advanced Debugging

  Check n8n execution logs  
  Run individual nodes for pinpointing failures  
  Confirm all data formats  
  Handle API rate limits  
  Add error-catch nodes for retries

  📊 Use Cases & Examples

  Brand Discovery:** Fashion, tech, fitness creators  
  Competitor Insights:** Find influencers used by rival brands  
  Campaign Planning:** Build targeted influencer lists  
  Market Research:** Identify creator trends across regions

  ⚙️ Advanced Configuration

  Batch Execution:** Process multiple keywords with delay logic  
  Engagement Metrics:** Scrape and calculate likes-to-follower ratios  
  CRM Integration:** Sync qualified profiles to HubSpot, Salesforce, or Slack

  📈 Performance & Limits

  Processing Time:** 3–5 minutes per keyword  
  Concurrency:** 3–5 simultaneous fetches (depends on plan)  
  Accuracy:** >95% influencer data reliability  
  Success Rate:** 90%+ for outreach and processing

nodes_used:
  ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.gmail","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatAnthropic"]

workflow_json:
  {"id":"GA1HTM4YyIidEJb3","meta":{"instanceId":"bc8ca75c203589705ae2e446cad7181d6f2a7cc1766f958ef9f34810e53b8cb2","templateCredsSetupCompleted":true},"name":"Automated TikTok Influencer Discovery & Analysis via Bright Data and Anthropic AI and Send Email Notification","tags":[],"nodes":[{"id":"cb75134b-4746-4715-87b4-c2bb596d4366","name":"Anthropic Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatAnthropic","position":[1460,300],"parameters":{"model":{"__rl":true,"mode":"list","value":"claude-sonnet-4-20250514","cachedResultName":"Claude 4 Sonnet"},"options":{}},"credentials":{"anthropicApi":{"id":"YOUR_ANTHROPIC_CREDENTIAL_ID","name":"Anthropic API Account"}},"typeVersion":1.3},{"id":"aef0b016-6017-4b2a-8bcc-56e78b9a5cc1","name":"Code","type":"n8n-nodes-base.code","position":[1680,0],"parameters":{"jsCode":"// N8N Code Node to extract data from AI output\nconst items = $input.all();\n\nreturn items.map(item => {\n  try {\n    // Get the output string from the item\n    const outputString = item.json.output;\n    \n    // Extract JSON from the markdown code block\n    const jsonMatch = outputString.match(/```json\\n([\\s\\S]*?)\\n```/);\n    \n    if (jsonMatch && jsonMatch[1]) {\n      // Parse the extracted JSON\n      const parsedData = JSON.parse(jsonMatch[1]);\n      \n      // Return the extracted data as separate columns\n      return {\n        json: {\n          Collaboration: parsedData.Collaboration || '',\n          Analysis: parsedData.Analysis || '',\n          Profile_ID: parsedData['Profile ID'] || '',\n          // Keep original data as well if needed\n          original_output: outputString\n        }\n      };\n    } else {\n      // If no JSON found, return empty values\n      return {\n        json: {\n          Collaboration: '',\n          Analysis: '',\n          Profile_ID: '',\n          original_output: outputString,\n          error: 'No JSON found in output'\n        }\n      };\n    }\n  } catch (error) {\n    // Handle any parsing errors\n    return {\n      json: {\n        Collaboration: '',\n        Analysis: '',\n        Profile_ID: '',\n        original_output: item.json.output || '',\n        error: `Parsing error: ${error.message}`\n      }\n    };\n  }\n});"},"typeVersion":2},{"id":"51d9eee9-63c0-43a4-bb03-d94a1d9ceb2a","name":"Google Sheets1","type":"n8n-nodes-base.googleSheets","position":[1980,0],"parameters":{"columns":{"value":{"Analysis":"={{ $json.Analysis }}","Profile ID":"={{ $json.Profile_ID }}","Collaboration":"={{ $json.Collaboration }}"},"schema":[{"id":"Profile ID","type":"string","display":true,"removed":false,"required":false,"displayName":"Profile ID","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Username","type":"string","display":true,"required":false,"displayName":"Username","defaultMatch":false,"canBeUsedToMatch":true},{"id":"URL","type":"string","display":true,"required":false,"displayName":"URL","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Description","type":"string","display":true,"required":false,"displayName":"Description","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Followers","type":"string","display":true,"required":false,"displayName":"Followers","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Collaboration","type":"string","display":true,"removed":false,"required":false,"displayName":"Collaboration","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Analysis","type":"string","display":true,"removed":false,"required":false,"displayName":"Analysis","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["Profile ID"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"update","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"YOUR_GOOGLE_SHEET_URL","cachedResultName":"TikTok"},"documentId":{"__rl":true,"mode":"url","value":"YOUR_GOOGLE_SHEET_URL"}},"credentials":{"googleSheetsOAuth2Api":{"id":"YOUR_GOOGLE_SHEETS_CREDENTIAL_ID","name":"Google Sheets OAuth2 Account"}},"typeVersion":4.6},{"id":"4db5fe1f-9038-4746-859b-7b38a2b3056d","name":"Filter","type":"n8n-nodes-base.filter","position":[2240,0],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"7c4c648b-a7df-41d6-bc6c-b6d05221f7bf","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.Collaboration }}","rightValue":"Highly Relevant"}]}},"typeVersion":2.2},{"id":"50db5760-83fe-4119-bb18-27d637acbee9","name":"Gmail","type":"n8n-nodes-base.gmail","position":[2520,0],"webhookId":"76506181-2a59-4275-9277-219134868750","parameters":{"sendTo":"demo@example.com","message":"=Hi,\nI wanted to share some of the best TikTok creators perfectly matched to collaborate with your business. These influencers align closely with your brand and audience, helping you maximize your reach and impact.\nUsername: {{ $('Update Data in the Google Sheet').item.json.Username }}\nTikTok Profile: {{ $('Update Data in the Google Sheet').item.json.URL }}\nFollowers: {{ $('Update Data in the Google Sheet').item.json.Followers }}\n\nLet me know if you'd like more details or to explore specific collaboration opportunities.\n\nBest regards","options":{},"subject":"Top TikTok Influencer Match for Your Business Collaboration","emailType":"text"},"credentials":{"gmailOAuth2":{"id":"YOUR_GMAIL_CREDENTIAL_ID","name":"Gmail OAuth2 Account"}},"typeVersion":2.1},{"id":"a6067955-adf4-4926-8082-81459d5aff1d","name":"Scrape Data from TikTok through Keyword by BrightData","type":"n8n-nodes-base.httpRequest","position":[240,0],"parameters":{"url":"https://api.brightdata.com/datasets/v3/trigger","method":"POST","options":{},"jsonBody":"={\n  \"input\": [\n    {\n      \"search_keyword\": \"{{ $json['Search Keyword'] }}\",\n      \"country\": \"\"\n    }\n  ],\n  \"custom_output_fields\": [\n    \"url\",\n    \"description\",\n    \"profile_id\",\n    \"profile_username\",\n    \"profile_url\",\n    \"profile_followers\"\n  ]\n}","sendBody":true,"sendQuery":true,"sendHeaders":true,"specifyBody":"json","queryParameters":{"parameters":[{"name":"dataset_id","value":"YOUR_BRIGHTDATA_DATASET_ID"},{"name":"include_errors","value":"true"},{"name":"type","value":"discover_new"},{"name":"discover_by","value":"keyword"},{"name":"limit_per_input","value":"5"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"fbc8f8b2-5e63-4914-b4b8-a44fa5163cda","name":"3 Minute Wait Time","type":"n8n-nodes-base.wait","position":[520,0],"webhookId":"168ac9b9-ea3f-4aab-b8f1-a3ef6109c70e","parameters":{"unit":"minutes","amount":3},"typeVersion":1.1},{"id":"9ad6728c-2136-46bb-9ddf-0d445b28be22","name":"Extract Data from Snapshot Generated by BrightData","type":"n8n-nodes-base.httpRequest","position":[800,0],"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":"8e3577fb-1077-44d4-bada-ca9f5f2aa141","name":"Update Data in the Google Sheet","type":"n8n-nodes-base.googleSheets","position":[1040,0],"parameters":{"columns":{"value":{"URL":"={{ $json.profile_url }}","Username":"={{ $json.profile_username }}","Followers":"={{ $json.profile_followers }}","Profile ID":"={{ $json.profile_id }}","Description":"={{ $json.description }}"},"schema":[{"id":"Profile ID","type":"string","display":true,"required":false,"displayName":"Profile ID","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Username","type":"string","display":true,"required":false,"displayName":"Username","defaultMatch":false,"canBeUsedToMatch":true},{"id":"URL","type":"string","display":true,"required":false,"displayName":"URL","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Description","type":"string","display":true,"required":false,"displayName":"Description","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Followers","type":"string","display":true,"required":false,"displayName":"Followers","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Collaboration","type":"string","display":true,"required":false,"displayName":"Collaboration","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Analysis","type":"string","display":true,"required":false,"displayName":"Analysis","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"YOUR_GOOGLE_SHEET_URL","cachedResultName":"TikTok"},"documentId":{"__rl":true,"mode":"url","value":"YOUR_GOOGLE_SHEET_URL"}},"credentials":{"googleSheetsOAuth2Api":{"id":"YOUR_GOOGLE_SHEETS_CREDENTIAL_ID","name":"Google Sheets OAuth2 Account"}},"typeVersion":4.6},{"id":"16bfd75e-fc30-4e6f-94f2-5e554d25cf64","name":"Find the Collaborator","type":"@n8n/n8n-nodes-langchain.agent","position":[1300,0],"parameters":{"text":"=Assume you are a social media expert and you find the best influencers based on the business and industry by analyzing the below data.\nHere are the Details of the Influencers.\nProfile URL: {{ $json.URL }}\nDescription: {{ $json.Description }}\nFollowers: {{ $json.Followers }}\nProfile ID: {{ $json['Profile ID'] }}\n\nMy Business Details:\nAbout my business: {{ $('Submit Form with Keyword, Business Info, Industry').item.json['About My Business'] }}\nIndustry: {{ $('Submit Form with Keyword, Business Info, Industry').item.json.Industry }}\n\nRequirements:\nFollowers should be more than 5000\nand Influencer should be in my industry.\nand Just Provide the Output according to below format\n\nFormat:\nOutput should be in Json\nCollaboration: Not Relevant, Highly Relevant\nAnalysis: Explain in 50 words\nProfile ID: Just add the Profile ID without any change\n","options":{},"promptType":"define"},"typeVersion":2},{"id":"6d482ee5-fd98-4ed3-bfac-dc1ca014769f","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-60,-80],"parameters":{"color":2,"width":220,"height":260,"content":"Triggers the workflow when user submits keyword, business info & industry via form."},"typeVersion":1},{"id":"2b3f2a04-cee9-4fae-8199-2c5cef6969cd","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[180,-80],"parameters":{"color":3,"height":260,"content":"Calls Bright Data API to fetch TikTok profiles by keyword."},"typeVersion":1},{"id":"3aed623a-1827-4641-96dc-d652332946e9","name":"Submit Form with Keyword, Business Info, Industry","type":"n8n-nodes-base.formTrigger","position":[0,0],"webhookId":"f1b746de-9cc3-4218-a9a0-45ff142f5bc7","parameters":{"options":{},"formTitle":"TikTok Profile Scraper","formFields":{"values":[{"fieldLabel":"Search Keyword"},{"fieldLabel":"About My Business"},{"fieldLabel":"Industry"}]}},"typeVersion":2.2},{"id":"c8434c0a-5df9-43e6-924e-6078bbf13c3f","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[460,-80],"parameters":{"color":4,"height":260,"content":"Waits 3 minutes to allow Bright Data to complete scraping."},"typeVersion":1},{"id":"951080be-56e7-4616-a8f3-4bdf6e29be06","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[720,-80],"parameters":{"color":5,"height":260,"content":"Fetches snapshot data (scraped influencer profiles) from Bright Data."},"typeVersion":1},{"id":"2fe42472-7b93-41f3-b2d9-ddf6a1472c32","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[980,-80],"parameters":{"color":6,"height":260,"content":"Stores raw influencer data (ID, followers, description, etc.) in Google Sheets."},"typeVersion":1},{"id":"c6340b5e-bd02-469c-909c-5300430fcba8","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[1260,-80],"parameters":{"color":2,"width":360,"height":260,"content":"Uses Claude AI to evaluate each influencer's relevance to your business. Returns profile ID, relevance, and a 50-word analysis."},"typeVersion":1},{"id":"3c94de79-c64d-4d89-ad9d-387314d84d2b","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[1380,200],"parameters":{"color":6,"height":240,"content":"Claude Sonnet 4 model that powers the influencer analysis."},"typeVersion":1},{"id":"eb61e536-d234-450c-94db-896d24757ad5","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[1640,-80],"parameters":{"color":4,"height":260,"content":"Parses Claude AI's markdown output and extracts structured JSON fields for further use."},"typeVersion":1},{"id":"d08dd360-e26f-421a-bf1f-95976adce3a2","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[1900,-80],"parameters":{"color":3,"width":260,"height":260,"content":"Logs Claude's insights (Profile ID, Collaboration status, Analysis) into Google Sheets."},"typeVersion":1},{"id":"02d41818-b12f-4b45-9e93-f3b7162cd6f6","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[2180,-80],"parameters":{"height":260,"content":"Filters results to retain only Highly Relevant influencers for email outreach."},"typeVersion":1},{"id":"873b1c8a-fb26-40ca-9885-51c80eb1bd61","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[2440,-80],"parameters":{"color":5,"width":260,"height":260,"content":"Sends personalized collaboration email to your target contact with top influencer information."},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"18042508-1631-4802-8863-d015a36bed62","connections":{"Code":{"main":[[{"node":"Google Sheets1","type":"main","index":0}]]},"Filter":{"main":[[{"node":"Gmail","type":"main","index":0}]]},"Google Sheets1":{"main":[[{"node":"Filter","type":"main","index":0}]]},"3 Minute Wait Time":{"main":[[{"node":"Extract Data from Snapshot Generated by BrightData","type":"main","index":0}]]},"Anthropic Chat Model":{"ai_languageModel":[[{"node":"Find the Collaborator","type":"ai_languageModel","index":0}]]},"Find the Collaborator":{"main":[[{"node":"Code","type":"main","index":0}]]},"Update Data in the Google Sheet":{"main":[[{"node":"Find the Collaborator","type":"main","index":0}]]},"Submit Form with Keyword, Business Info, Industry":{"main":[[{"node":"Scrape Data from TikTok through Keyword by BrightData","type":"main","index":0}]]},"Extract Data from Snapshot Generated by BrightData":{"main":[[{"node":"Update Data in the Google Sheet","type":"main","index":0}]]},"Scrape Data from TikTok through Keyword by BrightData":{"main":[[{"node":"3 Minute Wait Time","type":"main","index":0}]]}}}


name: LinkedIn Job Finder Automation using Bright Data API & Google Sheets
author_name: Dvir Sharon
author_username: dvirsharon
nodes_used: ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest"]
categories: []
created_at: 2025-06-08T08:46:42.907Z
updated_at: 2025-06-08T08:46:42.907Z
url: https://n8n.io/workflows/4775
scraped_at: 2025-07-06 21:16:30
description:
  💼 LinkedIn Job Finder Automation using Bright Data API & Google Sheets


  A comprehensive n8n automation that searches LinkedIn job postings using Bright Data’s API and automatically organizes results in Google Sheets for efficient job hunting and recruitment workflows.

  📋 Overview
  This workflow provides an automated LinkedIn job search solution that collects job postings based on your search criteria and organizes them in Google Sheets. Perfect for job seekers, recruiters, HR professionals, and talent acquisition teams.

  ✨ Key Features
  🔍 Smart Job Search:** Form-based input for city, job title, country, and job type
  🛍 LinkedIn Integration:** Uses Bright Data’s LinkedIn dataset for accurate job posting data
  📊 Automated Organization:** Populates Google Sheets with structured job data
  📧 Real-time Processing:** Processes job search requests in real-time
  📈 Data Storage:** Stores job details including company info, locations, and apply links
  🔄 Batch Processing:** Handles multiple job postings efficiently
  ⚡ Fast & Reliable:** Built-in error handling for scraping
  🎯 Customizable Filters:** Advanced job filtering based on criteria

  🎯 What This Workflow Does
  Input

  Job Search Criteria:** City, job title, country, and optional job type
  Search Parameters:** Configurable filters and limits
  Output Preferences:** Google Sheets destination

  Processing Steps

  Form Submission
  Data Request to Bright Data API
  Status Monitoring
  Data Extraction
  Data Filtering
  Sheet Update
  Error Handling

  Output Data Points

  Field

  Description

  Example

  Job Title

  Position title from posting

  Senior Software Engineer

  Company Name

  Employer company name

  Tech Solutions Inc.

  Job Detail

  Job summary/description

  Remote position requiring 5+ years…

  Location

  Job location

  San Francisco, CA

  Company URL

  Company profile link

  View Profile

  Apply Link

  Direct application link

  Apply Now

  🚀 Setup Instructions
  Prerequisites

  n8n instance (self-hosted or cloud)
  Google account with Sheets access
  Bright Data account with LinkedIn dataset access

  Steps

  Import the Workflow: Use JSON import in n8n
  Configure Bright Data: Add API credentials and dataset ID
  Configure Google Sheets: Create sheet, set credentials, map columns
  Update Workflow Settings: Replace placeholders with your actual data
  Test & Activate: Submit test form and verify data in Google Sheets

  📖 Usage Guide
  Submitting Job Searches

  Go to your webhook URL and fill in the form with:

  City:** e.g., New York
  Job Title:** e.g., Software Engineer
  Country:** e.g., US
  Job Type:** Optional (Full-Time, Remote, etc.)

  Understanding Results

  Comprehensive job data
  Company info and profile links
  Direct application links
  Location and job descriptions

  Customizing Search Parameters

  Edit the Create Snapshot ID node to change:

  Time range (e.g., “Past month”)
  Result limits
  Company filters

  🔧 Customization Options
  More Data Points:** Add salary, seniority, applicants, etc.
  Custom Form Fields:** Add filters for salary, experience, industry
  Multiple Sheets:** Route results by job type or location

  🚨 Troubleshooting
  Bright Data connection failed:** Check API credentials and dataset access
  No job data extracted:** Verify search parameters and API limits
  Google Sheets permission denied:** Re-authenticate and check sharing
  Form not working:** Check webhook URL and field mappings
  Filter issues:** Review logic and data types
  Execution failed:** Check logs, retry logic, and network status

  📊 Use Cases & Examples
  Job Seeker Dashboard:** Automate job search and track applications
  Recruitment Pipeline:** Source candidates and monitor hiring trends
  Market Research:** Analyze job trends and salary benchmarks
  HR Analytics:** Support workforce planning and competitive insights

  ⚙️ Advanced Configuration
  Batch Processing:** Queue multiple searches with delays
  Search History:** Track and analyze past searches
  Tool Integration:** Connect to CRM, Slack, databases, BI tools

  📈 Performance & Limits
  Processing Time:** 30–60 seconds per search
  Concurrent Requests:** 2–3 (depends on Bright Data plan)
  Data Accuracy:** 95%+
  Success Rate:** 90%+
  Daily Capacity:** 50–200 searches
  Memory:** ~50MB per execution
  API Calls:** 3–4 Bright Data + 1 Google Sheets per search

  🤝 Support & Community
  n8n Community:** community.n8n.io
  Documentation:** docs.n8n.io
  Bright Data Support:** Via your Bright Data dashboard
  GitHub Issues:** Report bugs and request features

  🎯 Ready to Use!
  Your workflow is ready for automated LinkedIn job searching. Customize it to your recruiting or job search needs.

  Webhook URL: https://your-n8n-instance.com/webhook/linkedin-job-finder

  What Gets Extracted:

     *   ✅ Job Title *   ✅ Company Information *   ✅ Location Data *   ✅ Job Details *   ✅ Application Links *   ✅ Processing Timestamps  ### Use Cases:  *   🔍 Job Search Automation *   📊 Recruitment Intelligence *   📝 Market Research *   🎯 HR Analytics   

workflow_json:
  {"id":"Eo2mqDdtIQFdZhxp","meta":{"instanceId":"bc8ca75c203589705ae2e446cad7181d6f2a7cc1766f958ef9f34810e53b8cb2","templateCredsSetupCompleted":true},"name":"LinkedIn Job Finder Automation using Bright Data API & Google Sheets Integration","tags":[],"nodes":[{"id":"9617d433-62f7-4ddf-bf47-a9a3208aa248","name":"On form submission1","type":"n8n-nodes-base.formTrigger","position":[-660,-460],"webhookId":"37d0e84c-0cda-47f8-826d-9ae5b22ba1d5","parameters":{"options":{},"formTitle":"LinkedIn Job Finder","formFields":{"values":[{"fieldLabel":"City","requiredField":true},{"fieldLabel":"Job Title","requiredField":true},{"fieldLabel":"Country","requiredField":true},{"fieldType":"dropdown","fieldLabel":"Job_type(Optional)","fieldOptions":{"values":[{"option":"Full-Time"},{"option":"Part-Time"},{"option":"Remote"},{"option":"WFH"},{"option":"Contract"},{"option":"Internship"},{"option":"Freelance"}]}}]}},"typeVersion":2.2},{"id":"47c35950-354c-42e4-b707-60ed5b1eeb2f","name":"Check Final Status","type":"n8n-nodes-base.if","position":[320,-460],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"or","conditions":[{"id":"35ed620d-b5d5-4e97-bcc5-52b283d85616","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"ready"}]}},"typeVersion":2.2},{"id":"cef9c86d-98ce-4944-9907-d815cba406f4","name":"Create Snapshot ID","type":"n8n-nodes-base.httpRequest","position":[-360,-460],"parameters":{"url":"https://api.brightdata.com/datasets/v3/trigger","method":"POST","options":{},"jsonBody":"={\n  \"input\": [\n    {\n      \"location\": \"{{$node['On form submission1'].json['City'] ? $node['On form submission1'].json['City'].trim() : ''}}\",\n      \"keyword\": \"{{$node['On form submission1'].json['Job Title'] ? $node['On form submission1'].json['Job Title'].trim() : ''}}\",\n      \"country\": \"{{$node['On form submission1'].json['Country'] ? $node['On form submission1'].json['Country'].slice(0, 2).toUpperCase() : ''}}\",\n      \"time_range\": \"Past week\",\n      \"job_type\": \"{{ ['full-time', 'part-time', 'internship', 'contract', 'temporary'].includes($node['On form submission1'].json['Job_type']?.toLowerCase()) ? $node['On form submission1'].json['Job_type'] : '' }}\"\n    }\n  ],\n  \"custom_output_fields\": [\n    \"url\",\n    \"job_posting_id\",\n    \"job_title\",\n    \"company_name\",\n    \"company_id\",\n    \"job_location\",\n    \"job_summary\",\n    \"job_seniority_level\",\n    \"job_function\",\n    \"job_employment_type\",\n    \"job_industries\",\n    \"job_base_pay_range\",\n    \"company_url\",\n    \"job_posted_time\",\n    \"job_num_applicants\",\n    \"discovery_input\",\n    \"apply_link\",\n    \"country_code\",\n    \"title_id\",\n    \"company_logo\",\n    \"job_posted_date\",\n    \"job_poster\",\n    \"application_availability\",\n    \"job_description_formatted\",\n    \"base_salary\",\n    \"timestamp\",\n    \"error\",\n    \"error_code\",\n    \"warning\",\n    \"warning_code\"\n  ]\n}\n","sendBody":true,"sendQuery":true,"sendHeaders":true,"specifyBody":"json","queryParameters":{"parameters":[{"name":"dataset_id","value":"YOUR_DATASET_ID_HERE"},{"name":"include_errors","value":"true"},{"name":"type","value":"discover_new"},{"name":"discover_by","value":"keyword"},{"name":"limit_per_input","value":"2"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"66705bee-6424-4f6f-8c24-d9aa7a198399","name":"Check Snapshot Status","type":"n8n-nodes-base.httpRequest","position":[20,-460],"parameters":{"url":"=https://api.brightdata.com/datasets/v3/progress/{{ $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":"b5f9e1c9-eace-4a68-a084-dc254b1b9c46","name":"Wait 1 minute","type":"n8n-nodes-base.wait","position":[620,-100],"webhookId":"7047efad-de41-4608-b95c-d3e0203ef620","parameters":{"unit":"minutes","amount":1},"typeVersion":1.1},{"id":"fff887f5-0388-4667-a5e9-7ef72ea36ac0","name":"Scrape Data from SnapID","type":"n8n-nodes-base.httpRequest","position":[900,-500],"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":"57572d1d-3366-447d-8186-62a121824033","name":"Update Job Lists in sheet","type":"n8n-nodes-base.googleSheets","position":[1380,-500],"parameters":{"columns":{"value":{"Location":"={{ $json.job_location }}","Job Title":"={{ $json.job_title }}","Apply Link":"={{ $json.apply_link }}","Job Detail":"={{ $json.job_summary }}","Company URL":"={{ $json.company_url }}","Company Name ":"={{ $json.company_name }}"},"schema":[{"id":"Company URL","type":"string","display":true,"required":false,"displayName":"Company URL","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Job Title","type":"string","display":true,"required":false,"displayName":"Job Title","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Company Name ","type":"string","display":true,"required":false,"displayName":"Company Name ","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Location","type":"string","display":true,"required":false,"displayName":"Location","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Job Detail","type":"string","display":true,"required":false,"displayName":"Job Detail","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Apply Link","type":"string","display":true,"removed":false,"required":false,"displayName":"Apply Link","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/YOUR_GOOGLE_SHEET_ID_HERE/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"YOUR_GOOGLE_SHEET_ID_HERE","cachedResultUrl":"https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID_HERE/edit?usp=drivesdk","cachedResultName":"LinkedIn"}},"credentials":{"googleSheetsOAuth2Api":{"id":"YOUR_GOOGLE_SHEETS_CREDENTIAL_ID","name":"Google Sheets Credential"}},"typeVersion":4.6},{"id":"3afbef52-97fe-4ead-8d57-d8e98e684b47","name":"Filter","type":"n8n-nodes-base.filter","position":[1140,-500],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"eb682420-fc89-4e01-a491-5a4a3f6bf10f","operator":{"type":"string","operation":"contains"},"leftValue":"={{ $json.job_summary }}","rightValue":"={{ $json.shortCommonName }}"}]}},"typeVersion":2.2},{"id":"1badd4f4-4f66-4777-a2b7-3343f2afb2b3","name":"If","type":"n8n-nodes-base.if","position":[620,-480],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"f01bd215-c406-493c-a6e4-2b8ec5686b44","operator":{"type":"number","operation":"notEquals"},"leftValue":"={{ $json.records }}","rightValue":"={{ 0 }}"}]}},"typeVersion":2.2},{"id":"df16ac92-0f96-40cd-ad9c-da17332a3e81","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-760,-620],"parameters":{"color":2,"width":300,"height":340,"content":"🔹 Search by Keyword — Form Trigger\nPurpose:\nCollects the user-submitted job search criteria including city, job title, country, and job type.\nTriggers the workflow when new search parameters are entered."},"typeVersion":1},{"id":"454c5db0-beb7-4a0b-95ca-8308a114e420","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-440,-660],"parameters":{"color":3,"width":320,"height":380,"content":"🔹 LinkedIn Job Search Fetcher — HTTP Request (POST to Bright Data)\nPurpose:\nSends the job search criteria to Bright Data's LinkedIn dataset API.\nInitiates the scraping job to fetch LinkedIn job postings matching the criteria."},"typeVersion":1},{"id":"c68c4da8-6965-45cb-833f-0bb3a99a289c","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-100,-640],"parameters":{"color":4,"width":300,"height":360,"content":"🔹 Check Delivery Status of Snap ID — HTTP Request (GET)\nPurpose:\nChecks the status of the scraping job using the returned snapshot_id.\nEnsures the task is complete before continuing to data extraction."},"typeVersion":1},{"id":"57d2b098-41ce-4ee6-ab1d-130e2645dc3e","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[500,-220],"parameters":{"color":7,"width":380,"height":280,"content":"🔹 Wait 1 minute — Wait Node\nPurpose:\nDelays the workflow execution by 1 minute.\nPrevents frequent polling of Bright Data API to reduce load and errors."},"typeVersion":1},{"id":"47fc7436-1f6b-4bec-b88c-4df12ceddf57","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[220,-640],"parameters":{"color":5,"width":270,"height":360,"content":"🔹 Check Final Status — IF Node #1\nPurpose:\nConditionally checks if snapshot status is \"ready\".\nIf yes → proceed to download scraped data.\nIf no → loop back to Wait Node and recheck."},"typeVersion":1},{"id":"7a978cd2-efad-474d-92b7-3f9f28155f00","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[820,-680],"parameters":{"color":6,"width":260,"height":400,"content":"🔹 Decode Snapshot from Response — HTTP Request (GET)\nPurpose:\nDownloads the final scraped LinkedIn job dataset using the ready snapshot ID.\nContains full job posting data in JSON format."},"typeVersion":1},{"id":"6ff9b0c5-b18c-44e9-b671-86388428927b","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[1300,-660],"parameters":{"color":3,"width":340,"height":400,"content":"🔹 Google Sheets — Google Sheets (AppendOrUpdate)\nPurpose:\nAppends each LinkedIn job result into your Google Sheet.\nCaptures data fields like job title, company name, location, job details, and apply links."},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"57896d29-3f06-44b6-bb08-964875ffc7fb","connections":{"If":{"main":[[{"node":"Scrape Data from SnapID","type":"main","index":0}]]},"Filter":{"main":[[{"node":"Update Job Lists in sheet","type":"main","index":0}]]},"Wait 1 minute":{"main":[[{"node":"Check Snapshot Status","type":"main","index":0}]]},"Check Final Status":{"main":[[{"node":"If","type":"main","index":0}],[{"node":"Wait 1 minute","type":"main","index":0}]]},"Create Snapshot ID":{"main":[[{"node":"Check Snapshot Status","type":"main","index":0}]]},"On form submission1":{"main":[[{"node":"Create Snapshot ID","type":"main","index":0}]]},"Check Snapshot Status":{"main":[[{"node":"Check Final Status","type":"main","index":0}]]},"Scrape Data from SnapID":{"main":[[{"node":"Filter","type":"main","index":0}]]}}}


name: Automated Weekly Google Calendar Summary via Email with AI ✨🗓️📧
author_name: Jez
author_username: jez
categories: []
created_at: 2025-06-08T12:50:39.274Z
updated_at: 2025-06-08T12:50:39.274Z
url: https://n8n.io/workflows/4783
scraped_at: 2025-07-06 21:16:30
description:
  Workflow: Automated Weekly Google Calendar Summary via Email with AI ✨🗓️📧

  Get a personalized, AI-powered summary of your upcoming week's Google Calendar events delivered straight to your inbox! This workflow automates the entire process, from fetching events to generating an intelligent summary and emailing it to you.

  🌟 Overview

  This n8n workflow connects to your Google Calendar, retrieves events for the upcoming week (Monday to Sunday, based on the day the workflow runs), uses Google Gemini AI to create a well-structured and insightful summary, and then emails this summary to you. It's designed to help you start your week organized and aware of your commitments.

  Key Features:

  Automated Weekly Summary:** Runs on a schedule (default: weekly) to keep you updated.
  AI-Powered Insights:** Leverages Google Gemini to not just list events, but to identify important ones and offer a brief weekly outlook.
  Personalized Content:** Uses your specified timezone, locale, name, and city for accurate and relevant information.
  Clear Formatting:** Events are grouped by day and displayed chronologically with start and end times. Important events are highlighted.
  Email Delivery:** Receive your schedule directly in your inbox in a clean HTML format.
  Customizable:** Easily adapt to your specific calendar, AI preferences, and email settings.

  ⚙️ How It Works: Step-by-Step

  The workflow consists of the following nodes, working in sequence:

  weekly_schedule (Schedule Trigger):
      What it does: Initiates the workflow.
      Default: Triggers once a week at 12:00 PM. You can adjust this to your preference (e.g., Sunday evening or Monday morning).

  locale (Set Node):
      What it does: This is a crucial node for you to configure! It sets user-specific parameters like your preferred language/region (users-locale), timezone (users-timezone), your name (users-name), and your home city (users-home-city). These are used throughout the workflow for correct date/time formatting and personalizing the AI prompt.

  date-time (Set Node):
      What it does: Dynamically generates various date and time strings based on the current execution time and the locale settings. This is used to define the precise 7-day window (from the current day to 7 days ahead, ending at midnight) for fetching calendar events.

  get_next_weeks_events (Google Calendar Node):
      What it does: Connects to your specified Google Calendar and fetches all events within the 7-day window calculated by the date-time node.
      Requires: Google Calendar API credentials and the ID of the calendar you want to use.

  simplify_evens_json (Code Node):
      What it does: Runs a small JavaScript snippet to clean up the raw event data from Google Calendar. It removes several fields that aren't needed for the summary (like htmlLink, etag, iCalUID), making the data more concise for the AI.

  aggregate_events (Aggregate Node):
      What it does: Takes all the individual (and now simplified) event items and groups them into a single JSON array called eventdata. This is the format the AI agent expects for processing.

  Google Gemini (LM Chat Google Gemini Node):
      What it does: This node is the connection point to the Google Gemini language model.
      Requires: Google Gemini (or PaLM) API credentials.

  event_summary_agent (Agent Node):
      What it does: This is where the magic happens! It uses the Google Gemini model and a detailed system prompt to generate the weekly schedule summary.
      The Prompt Instructs the AI to:
          Start with a friendly greeting.
          Group events by day (Monday to Sunday) for the upcoming week, using the user's timezone and locale.
          Format event times clearly (e.g., 09:30 AM - 10:30 AM: Event Summary).
          Identify and prefix "IMPORTANT:" to events with keywords like "urgent," "deadline," "meeting," etc., in their summary or description.
          Conclude with a 1-2 sentence helpful insight about the week's schedule.
          Process the input eventdata (the JSON array of calendar events).

  Markdown (Markdown to HTML Node):
      What it does: Converts the text output from the event_summary_agent (which is generated in Markdown format for easy structure) into HTML. This ensures the email body is well-formatted with proper line breaks, lists, and emphasis.

  send_email (Email Send Node):
      What it does: Sends the final HTML summary to your specified email address.
      Requires: SMTP (email sending) credentials and your desired "From" and "To" email addresses.

  🚀 Getting Started: Setup Instructions

  Follow these steps to get the workflow up and running:

  Import the Workflow:
      Download the workflow JSON file.
      In your n8n instance, go to "Workflows" and click the "Import from File" button. Select the downloaded JSON file.

  Configure Credentials:
      You'll need to set up credentials for three services. In n8n, go to "Credentials" on the left sidebar and click "Add credential."
      Google Calendar API:
          Search for "Google Calendar" and create new credentials using OAuth2. Follow the authentication flow.
          Once created, select these credentials in the get_next_weeks_events node.
      Google Gemini (PaLM) API:
          Search for "Google Gemini" or "Google PaLM" and create new credentials. You'll typically need an API key from Google AI Studio or Google Cloud.
          Once created, select these credentials in the Google Gemini node.
      SMTP / Email:
          Search for your email provider (e.g., "SMTP," "Gmail," "Outlook") and create credentials. This usually involves providing your email server details, username, and password/app password.
          Once created, select these credentials in the send_email node.

  ‼️ IMPORTANT: Customize User Settings in the locale Node:
      Open the locale node.
      Update the following values in the "Assignments" section:
          users-locale: Set your locale string (e.g., "en-AU" for English/Australia, "en-US" for English/United States, "de-DE" for German/Germany). This affects how dates, times, and numbers are formatted.
          users-timezone: Set your timezone string (e.g., "Australia/Sydney", "America/New_York", "Europe/London"). This is critical for ensuring event times are displayed correctly for your location.
          users-name: Enter your name (e.g., "Bob"). This is used to personalize the email greeting.
          users-home-city: Enter your home city (e.g., "Sydney"). This can be used for additional context by the AI.

  Configure the get_next_weeks_events (Google Calendar) Node:
      Open the node.
      In the "Calendar" parameter, you need to specify which calendar to fetch events from.
          The default might be a placeholder like c_4d9c2d4e139327143ee4a5bc4db531ffe074e98d21d1c28662b4a4d4da898866@group.calendar.google.com.
          Change this to your primary calendar (often your email address) or the specific Calendar ID you want to use. You can find Calendar IDs in your Google Calendar settings.

  Configure the send_email Node:
      Open the node.
      Set the fromEmail parameter to the email address you want the summary to be sent from.
      Set the toEmail parameter to the email address(es) where you want to receive the summary.
      You can also customize the subject line if desired.

  (Optional) Customize the AI Prompt in event_summary_agent:
      If you want to change how the AI summarizes events (e.g., different keywords for important events, a different tone, or specific formatting tweaks), you can edit the "System Message" within the event_summary_agent node's parameters.

  (Optional) Adjust the Schedule in weekly_schedule:
      Open the weekly_schedule node.
      Modify the "Rule" to change when and how often the workflow runs (e.g., a specific day of the week, a different time).

  Activate the Workflow:
      Once everything is configured, toggle the "Active" switch in the top right corner of the workflow editor to ON.

  📬 What You Get

  You'll receive an email (based on your schedule) with a subject like "Next Week Calendar Summary : [Start Date] - [End Date]". The email body will contain:

  A friendly greeting.
  Your schedule for the upcoming week (Monday to Sunday), with events listed chronologically under each day.
  Event times displayed in your local timezone (e.g., 09:30 AM - 10:30 AM: Team Meeting).
  Priority events clearly marked (e.g., IMPORTANT: 02:00 PM - 03:00 PM: Project Deadline Review).
  A brief, insightful observation about your week's schedule.

  🛠️ Troubleshooting & Notes

  Timezone is Key:** Ensure your users-timezone in the locale node is correct. This is the most common source of incorrect event times.
  Google API Permissions:** When setting up Google Calendar and Gemini credentials, make sure you grant the necessary permissions.
  AI Output Varies:** The AI-generated summary can vary slightly each time. The prompt is designed to guide it, but LLMs have inherent creativity.
  Calendar Event Details:** The quality of the summary (especially for identifying important events) depends on how detailed your calendar event titles and descriptions are. Including keywords like "meeting," "urgent," "prepare for," etc., in your events helps the AI.

  💬 Feedback & Contributions

  Feel free to modify and enhance this workflow! If you have suggestions, improvements, or run into issues, please share them in the n8n community.

  Happy scheduling!

nodes_used:
  ["n8n-nodes-base.emailSend","n8n-nodes-base.googleCalendar","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatGoogleGemini"]

workflow_json:
  {"id":"81UkThrSnnFw6IJo","meta":{"instanceId":"3612a0c89f35a354ddd1216385240db51b4635fde7cae2a0d5004be915b832f3","templateCredsSetupCompleted":true},"name":"Google Calendar Coming Week","tags":[],"nodes":[{"id":"b4c54286-a4c5-4a1b-87ca-a37fa1fcb2aa","name":"weekly_schedule","type":"n8n-nodes-base.scheduleTrigger","position":[-180,-40],"parameters":{"rule":{"interval":[{"field":"weeks","triggerAtHour":12}]}},"typeVersion":1.2},{"id":"57a88176-a291-4d65-bfd2-868d4e50befb","name":"get_next_weeks_events","type":"n8n-nodes-base.googleCalendar","position":[1300,-40],"parameters":{"options":{},"timeMax":"={{ $json['users-current-day-1-minute-before-midnight-plus-7-days-iso'] }}","timeMin":"={{ $json['users-current-day-1-minute-before-midnight-iso'] }}","calendar":{"__rl":true,"mode":"list","value":"c_4d9c2d4e139327143ee4a5bc4db531ffe074e98d21d1c28662b4a4d4da898866@group.calendar.google.com","cachedResultName":"n8n-personal-assistant-demo"},"operation":"getAll","returnAll":true},"credentials":{"googleCalendarOAuth2Api":{"id":"a1DI60kDgcdbIlXb","name":"Google Calendar account"}},"typeVersion":1.3},{"id":"ed2eacbb-453f-4e5b-be3a-0c45e3506e1b","name":"Google Gemini","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[2840,580],"parameters":{"options":{},"modelName":"models/gemini-2.5-flash-preview-05-20"},"credentials":{"googlePalmApi":{"id":"lBQrszvhtstelPlO","name":"Google Gemini(PaLM) Api account 4"}},"typeVersion":1},{"id":"20670d58-0c0a-4f17-9a89-131bb2cd2caa","name":"event_summary_agent","type":"@n8n/n8n-nodes-langchain.agent","position":[2740,-40],"parameters":{"text":"={{ $json.eventdata }}","options":{"systemMessage":"=You have been given a JSON array of Google Calendar events for the upcoming week (Monday to Sunday). Today is Sunday, {{ $('locale').item.json['users-current-date'] ? $('locale').item.json['users-current-date'] : $now.setZone($('locale').item.json['users-timezone'] ?? 'Australia/Sydney').setLocale($('locale').item.json['users-locale'] ?? 'en-AU').toLocaleString({ weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' }) }}.\nEach event object in the array has 'summary', 'start.dateTime', 'end.dateTime', and 'description'. Your designated timezone is '{{ $('locale').item.json['users-timezone'] }}' and locale '{{ $('locale').item.json['users-locale'] }}'.\n\nThe users name is: {{ $('locale').item.json['users-name'] }}\nThe user is located in: {{ $('locale').item.json['users-home-city'] }}\n\nYour task is to create a well-formatted weekly schedule summary for an email.\n\n1.  **Greeting**: Start with a friendly greeting, for example: \"Here's your schedule for the upcoming week:\"\n\n2.  **Daily Schedule**:\n    *   Group events by day (e.g., Monday, June 9, 2025; Tuesday, June 10, 2025). Determine the correct dates for the upcoming week (Monday to Sunday) based on today's date.\n    *   For each day of the upcoming week, list its events chronologically.\n    *   Format each event as: `HH:MM AM/PM - HH:MM AM/PM: Event Summary`. For example: `09:30 AM - 10:30 AM: Team Meeting`.\n    *   Parse the `start.dateTime` and `end.dateTime` (which are ISO strings with timezone offsets like `+10:00`) and display them correctly for the '{{ $('locale').item.json['users-timezone'] }}' timezone.\n    *   If a day has no events, state \"No events scheduled for this day.\"\n\n3.  **Priority Events**:\n    *   Review the 'summary' and 'description' fields for keywords such as \"important\", \"urgent\", \"deadline\", \"meeting\", \"critical\", \"prepare\", or similar terms that indicate significance.\n    *   Mark these priority events by prefixing the event line with \"IMPORTANT: \". For example: `IMPORTANT: 02:00 PM - 03:00 PM: Project Deadline Review`.\n    *   If the 'description' provides actionable context for a priority event (e.g., \"Preparation needed: review X document\"), you can briefly mention this context after the event summary.\n\n4.  **Weekly Insight**:\n    *   Conclude with 1-2 sentences offering a helpful insight, observation, or piece of advice related to the week's schedule. Examples:\n        *   \"Thursday looks like your busiest day, so you might want to plan accordingly.\"\n        *   \"Remember to allocate some time to prepare for the client presentation on Wednesday.\"\n        *   \"This week seems to have a good balance of meetings and free time.\"\n\n5.  **Input Data Structure Reminder**: The calendar events are provided as a JSON array. You need to process this entire array.\n\nPlease generate only the text content suitable for the body of an email. Do not include any preamble (like \"Okay, here is the summary...\") or sign-off beyond the requested content."},"promptType":"define"},"typeVersion":2},{"id":"99885550-0c81-4513-86f0-8e82b0d5e0fb","name":"send_email","type":"n8n-nodes-base.emailSend","position":[3800,-40],"webhookId":"7748b0f5-1a6a-42bf-b1c0-63051d6a62a2","parameters":{"html":"={{ $json['email-html'] }}","options":{"appendAttribution":false},"subject":"=Next Week Calendar Summary : {{ $now.plus({ days: 1 }).day }}-{{ $now.plus({ days: 7 }).toLocaleString(DateTime.DATE_MED) }}"},"credentials":{"smtp":{"id":"AoLopFA5yBSkhbrF","name":"SMTP account"}},"typeVersion":2.1},{"id":"9199043b-2255-4a29-9c76-e6edbda41cc5","name":"locale","type":"n8n-nodes-base.set","position":[300,-40],"parameters":{"options":{},"assignments":{"assignments":[{"id":"2fa6da62-0c1b-4abe-b1d1-45dab7c22ab0","name":"users-locale","type":"string","value":"en-AU"},{"id":"e997127b-a7b1-4684-82b3-3e5d66be07fa","name":"users-timezone","type":"string","value":"Australia/Sydney"},{"id":"082e8d8f-5b20-4fc0-a59e-6deb48cb1406","name":"users-name","type":"string","value":"Bob"},{"id":"4a867353-6d0c-4bad-90f9-e739ff1da010","name":"users-home-city","type":"string","value":"Sydney"}]}},"typeVersion":3.4},{"id":"b92e0c62-d83f-417d-9ed1-839b3f680edd","name":"simplify_evens_json","type":"n8n-nodes-base.code","position":[1800,-40],"parameters":{"jsCode":"// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nfor (const item of $input.all()) {\n  delete item.json.htmlLink\n  delete item.json.etag\n  delete item.json.iCalUID\n  delete item.json.start.timeZone\n  delete item.json.end.timeZone\n  delete item.json.kind\n  delete item.json.reminders\n  delete item.json.organizer\n  delete item.json.creator\n  delete item.json.created\n  delete item.json.updated\n  delete item.json.status\n  delete item.json.eventType\n  delete item.json.id\n}\n\nreturn $input.all();"},"typeVersion":2},{"id":"c3639753-7b59-40ea-b59b-32dc00769146","name":"aggregate_events","type":"n8n-nodes-base.aggregate","position":[2320,-40],"parameters":{"options":{},"aggregate":"aggregateAllItemData","destinationFieldName":"eventdata"},"typeVersion":1},{"id":"bb2804c2-130e-4d53-9eac-cb4f978056d1","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-360,-1100],"parameters":{"color":3,"width":960,"height":520,"content":"### Workflow Overview: Google Calendar Coming Week 🗓️➡️📧\n\nThis n8n workflow automates the process of generating and emailing a summary of your upcoming week's Google Calendar events.\n\n**How it works:**\n1.  **Triggers weekly:** Starts automatically based on a schedule.\n2.  **Sets user context:** Configures your locale, timezone, name, and city.\n3.  **Calculates date ranges:** Determines the start and end dates for the upcoming week.\n4.  **Fetches calendar events:** Retrieves events from your specified Google Calendar for that week.\n5.  **Simplifies data:** Removes unnecessary information from the event data.\n6.  **Aggregates events:** Combines all events into a single list for AI processing.\n7.  **Generates summary:** Uses Google Gemini AI to create a human-readable summary, highlighting important events.\n8.  **Formats for email:** Converts the AI's summary from Markdown to HTML.\n9.  **Sends email:** Emails the formatted summary to you.\n\n**Key User Actions:**\n*   Configure the **`locale`** node with your specific details (timezone, locale, name, city).\n*   Set up credentials for **Google Calendar**, **Google Gemini**, and your **SMTP (Email)** service.\n*   Specify your target Google Calendar ID in the **`get_next_weeks_events`** node.\n*   Update the \"To\" and \"From\" email addresses in the **`send_email`** node."},"typeVersion":1},{"id":"4e8a4adb-fde7-403d-968e-7d15c2fbe770","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[140,-400],"parameters":{"color":4,"width":440,"height":400,"content":"⚙️ **locale (Set)**\n\n*   **Purpose:** Defines essential user-specific settings for personalization and correct date/time processing.\n*   **‼️ USER ACTION REQUIRED ‼️:**\n    *   `users-locale`: (e.g., `en-AU`, `en-US`, `de-DE`) - Affects date/time/number formatting.\n    *   `users-timezone`: (e.g., `Australia/Sydney`, `America/New_York`) - Crucial for accurate event times.\n    *   `users-name`: (e.g., `Bob`) - Used in the email greeting.\n    *   `users-home-city`: (e.g., `Sydney`) - Provides context for the AI.\n*   **Note:** These values are used by downstream nodes."},"typeVersion":1},{"id":"a409ad6d-56be-4b3c-a1e3-b2b3e2c00b63","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-360,-400],"parameters":{"color":4,"width":440,"height":400,"content":"🗓️ **weekly_schedule (Trigger)**\n\n*   **Purpose:** Initiates the workflow automatically.\n*   **Details:** By default, runs once a week at 12:00 PM.\n*   **To Modify:** Adjust the \"Rule\" settings (interval, time, day) if you need a different schedule."},"typeVersion":1},{"id":"714b924c-4cbc-4864-b833-e80b3dcecde8","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[640,-400],"parameters":{"color":4,"width":440,"height":400,"content":"⏰ **date_time (Set)**\n\n*   **Purpose:** Generates various date and time strings based on the current execution time and the settings from the `locale` node.\n*   **Details:** Creates values like \"users-current-date\", \"users-current-day-1-minute-before-midnight-iso\", etc., which are used to define the 7-day window for fetching calendar events.\n*   **To Modify:** Usually no changes needed here; it's dynamic."},"typeVersion":1},{"id":"a31c71e7-98c8-4185-891e-9543ceac217d","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[1140,-400],"parameters":{"color":4,"width":440,"height":400,"content":"📅 **get_next_weeks_events (Google Calendar)**\n\n*   **Purpose:** Fetches events from a specified Google Calendar.\n*   **Details:** Uses `timeMin` and `timeMax` from the `date-time` node to get events for the upcoming 7 days.\n*   **‼️ USER ACTION REQUIRED ‼️:**\n    1.  **Credentials:** Connect your Google Calendar account.\n    2.  **Calendar ID:** Change the `calendar` parameter (currently `c_4d9...group.calendar.google.com`) to *your* desired Google Calendar ID."},"typeVersion":1},{"id":"5e5830c6-9e43-43c7-852e-b9982f6deb6b","name":"date_time","type":"n8n-nodes-base.set","position":[820,-40],"parameters":{"options":{},"assignments":{"assignments":[{"id":"954044f7-3c08-48c2-af9c-59a72690ad76","name":"users-current-date","type":"string","value":"={{\n  $now.setZone($('locale').item.json['users-timezone'] ?? 'UTC').setLocale($('locale').item.json['users-locale'] ?? 'en-US').toLocaleString(DateTime.DATE_FULL)\n}}"},{"id":"2c3a0a1a-cc05-4b5d-b175-20732706aefb","name":"users-current-time","type":"string","value":"={{ $now.setZone($('locale').item.json['users-timezone'] ?? 'UTC').setLocale($('locale').item.json['users-locale'] ?? 'en-US').toLocaleString(DateTime.TIME_SIMPLE) }}"},{"id":"764b3b1a-6a6e-4b92-8f41-ae49405bc72a","name":"users-date-time","type":"string","value":"={{ $now.setZone($('locale').item.json['users-timezone']) }}"},{"id":"4c2851ef-175e-4f81-95af-5671171fdf16","name":"users-date-time-full","type":"string","value":"={{ $now.setZone($('locale').item.json['users-timezone'] ?? 'UTC').setLocale($('locale').item.json['users-locale'] ?? 'en-US').toLocaleString(DateTime.DATETIME_FULL) }}"},{"id":"4ae2c38b-f93a-4b56-9078-d9675a12ec8b","name":"users-date-time-huge","type":"string","value":"={{ $now.setZone($('locale').item.json['users-timezone'] ?? 'UTC').setLocale($('locale').item.json['users-locale'] ?? 'en-US').toFormat('cccc, MMMM d, yyyy, h:mm a') }}"},{"id":"1011c2bf-d311-424d-8537-1788597065d4","name":"users-current-date-plus-1","type":"string","value":"={{   $now.plus({ days: 1 }).setZone($('locale').item.json['users-timezone'] ?? 'UTC').setLocale($('locale').item.json['users-locale'] ?? 'en-US').toLocaleString(DateTime.DATE_FULL) }}"},{"id":"343ec7d5-fcb5-454d-b947-4b0f2e94f930","name":"users-current-date-plus-7","type":"string","value":"={{   $now.plus({ days: 7 }).setZone($('locale').item.json['users-timezone'] ?? 'UTC').setLocale($('locale').item.json['users-locale'] ?? 'en-US').toLocaleString(DateTime.DATE_FULL) }}"},{"id":"ce0de19d-9cb1-4918-ade5-47f22f35f8e8","name":"users-current-day-1-minute-before-midnight","type":"string","value":"={{\n  $now.setZone($('locale').item.json['users-timezone'] ?? 'UTC')\n      .endOf('day')\n      .setLocale($('locale').item.json['users-locale'] ?? 'en-US')\n      .toLocaleString(DateTime.DATETIME_FULL)\n}}"},{"id":"800dff91-469d-4a2b-acb0-a0b79d0b9341","name":"users-current-day-1-minute-before-midnight-plus-7-days","type":"string","value":"={{   $now.setZone($('locale').item.json['users-timezone'] ?? 'UTC')       .plus({ days: 7 })       .endOf('day')       .setLocale($('locale').item.json['users-locale'] ?? 'en-US')       .toLocaleString(DateTime.DATETIME_FULL) }}"},{"id":"d04c43fe-1f6d-4e7e-b82f-70cebb7484a6","name":"users-current-day-1-minute-before-midnight-iso","type":"string","value":"={{\n  $now.setZone($('locale').item.json['users-timezone'] ?? 'UTC')\n      .endOf('day')\n      .toISO()\n}}"},{"id":"5aee9416-0ad6-43b9-936f-edce6a292cce","name":"users-current-day-1-minute-before-midnight-plus-7-days-iso","type":"string","value":"={{   $now.setZone($('locale').item.json['users-timezone'] ?? 'UTC')       .plus({ days: 7 })       .endOf('day')       .toISO() }}"}]}},"typeVersion":3.4},{"id":"f20a83fd-2484-4dc7-92a1-a438c2cf8e02","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[1640,-400],"parameters":{"color":4,"width":440,"height":400,"content":"✨ **simplify_evens_json (Code)**\n\n*   **Purpose:** Cleans the raw event data from Google Calendar.\n*   **Details:** Runs JavaScript to remove fields like `htmlLink`, `etag`, `iCalUID`, etc., to provide a cleaner dataset to the AI.\n*   **To Modify:** Only if you need to keep or remove specific event fields not covered."},"typeVersion":1},{"id":"c5e40e35-8dfa-491c-ba67-21b83f71334b","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[2140,-400],"parameters":{"color":4,"width":440,"height":400,"content":"➕ **aggregate_events (Aggregate)**\n\n*   **Purpose:** Combines all individual simplified event items into a single JSON array.\n*   **Details:** Creates a field named `eventdata` which contains the list of all events. This is necessary for the AI agent to process all events at once.\n*   **To Modify:** Usually no changes needed."},"typeVersion":1},{"id":"db11c407-a238-48ef-9398-1842c1046340","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[2640,220],"parameters":{"color":6,"width":440,"height":400,"content":"🧠 **Google Gemini (Language Model)**\n\n*   **Purpose:** Establishes the connection to the Google Gemini AI model.\n*   **Details:** This node itself doesn't do the processing but provides the AI capability to the `event_summary_agent`.\n*   **‼️ USER ACTION REQUIRED ‼️:**\n    *   **Credentials:** Set up and select your Google Gemini (PaLM) API credentials.\n    *   **Model Name:** Default is `models/gemini-2.5-flash-preview-05-20`. Change if needed."},"typeVersion":1},{"id":"692413bc-58f9-4d09-a7f7-796d50894e3b","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[3140,-400],"parameters":{"color":4,"width":440,"height":400,"content":"📄➡️🌐 **markdown_to_html (Converter)**\n\n*   **Purpose:** Converts the Markdown text generated by the `event_summary_agent` into HTML.\n*   **Details:** Ensures the email body is well-formatted (line breaks, bolding, lists, emojis).\n*   **To Modify:** Usually no changes needed. Options like `emoji` and `simpleLineBreaks` are enabled."},"typeVersion":1},{"id":"d2803020-1f12-4207-a9c3-678fbb472daf","name":"Sticky Note10","type":"n8n-nodes-base.stickyNote","position":[3640,-400],"parameters":{"color":4,"width":440,"height":400,"content":"📧 **send_email (Email)**\n\n*   **Purpose:** Sends the final HTML summary as an email.\n*   **Details:** Uses the HTML output from the `Markdown` node as the email body. The subject is dynamically generated.\n*   **‼️ USER ACTION REQUIRED ‼️:**\n    1.  **Credentials:** Configure and select your SMTP (email sending) account.\n    2.  `fromEmail`: Set your desired sender email address.\n    3.  `toEmail`: Set the recipient email address(es).\n    *   **To Modify (Optional):** Customize the `subject` line format."},"typeVersion":1},{"id":"73c88ce5-9fa6-418f-b4cc-0b646f5708e7","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[2640,-400],"parameters":{"color":4,"width":440,"height":400,"content":"🤖 **event_summary_agent (AI Agent)**\n\n*   **Purpose:** Generates a well-formatted weekly schedule summary using the AI model.\n*   **Details:** Takes the `eventdata` (from `aggregate_events`) and a detailed prompt (under \"System Message\") that instructs the AI on output structure, date formatting, priority event identification, and weekly insights.\n*   **To Modify:** The \"System Message\" can be tweaked to change:\n    *   Greeting style.\n    *   Date/time formats (though largely controlled by `locale`).\n    *   Keywords for \"IMPORTANT\" events (`urgent`, `deadline`, etc.).\n    *   The style or focus of the \"Weekly Insight.\""},"typeVersion":1},{"id":"6febb866-888c-4e72-a6b8-296a826b7e66","name":"markdown_to_html","type":"n8n-nodes-base.markdown","position":[3320,-40],"parameters":{"mode":"markdownToHtml","options":{"emoji":true,"simpleLineBreaks":true},"markdown":"={{ $json.output }}","destinationKey":"email-html"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"db6385a3-bd01-4cc0-be20-cb1388b31cdc","connections":{"locale":{"main":[[{"node":"date_time","type":"main","index":0}]]},"date_time":{"main":[[{"node":"get_next_weeks_events","type":"main","index":0}]]},"Google Gemini":{"ai_languageModel":[[{"node":"event_summary_agent","type":"ai_languageModel","index":0}]]},"weekly_schedule":{"main":[[{"node":"locale","type":"main","index":0}]]},"aggregate_events":{"main":[[{"node":"event_summary_agent","type":"main","index":0}]]},"markdown_to_html":{"main":[[{"node":"send_email","type":"main","index":0}]]},"event_summary_agent":{"main":[[{"node":"markdown_to_html","type":"main","index":0}]]},"simplify_evens_json":{"main":[[{"node":"aggregate_events","type":"main","index":0}]]},"get_next_weeks_events":{"main":[[{"node":"simplify_evens_json","type":"main","index":0}]]}}}


name: Upwork Lead Generation: Extract Client Emails with LinkedIn Scraping and AI
author_name: Yaron Been
author_username: yaron-nofluff
categories: []
created_at: 2025-06-08T14:10:26.119Z
updated_at: 2025-06-08T14:10:26.119Z
url: https://n8n.io/workflows/4794
scraped_at: 2025-07-06 21:16:30
description:
  Automated solution to extract and organize contact information from Upwork job postings, enabling direct outreach to potential clients who post jobs matching your expertise.

  🚀 What It Does

  Scrapes job postings for contact information
  Extracts email addresses and social profiles
  Organizes leads in a structured format
  Enables direct outreach campaigns
  Tracks response rates

  🎯 Perfect For

  Freelancers looking to expand their client base
  Agencies targeting specific industries
  Sales professionals in the gig economy
  Recruiters sourcing clients
  Digital marketing agencies

  ⚙️ Key Benefits

  ✅ Access to hidden contact information  
  ✅ Expand your client base  
  ✅ Beat the competition to opportunities  
  ✅ Targeted outreach campaigns  
  ✅ Higher response rates  

  🔧 What You Need

  Upwork account
  n8n instance
  Email service (for outreach)
  CRM (optional)

  📊 Features

  Email pattern detection
  Social media profile extraction
  Company website discovery
  Lead scoring system
  Outreach tracking

  🛠️ Setup & Support

  Quick Setup

  Start collecting leads in 20 minutes with our step-by-step guide

  📺 Watch Tutorial

  💼 Get Expert Support

  📧 Direct Help



  Take control of your freelance career with direct access to potential clients. Transform how you find and secure projects on Upwork.

nodes_used:
  ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOpenAi"]

workflow_json:
  {"id":"wAomRf96IfSnpTA7","meta":{"instanceId":"84ad02d6104594179f43f1ce9cfe3a81637b2faedb57dafcb9e649b7542988db","templateCredsSetupCompleted":true},"name":"Upwork Job Poster Email","tags":[],"nodes":[{"id":"aa72ce26-28ae-4dab-982f-be16fa123d87","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[420,360],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"wYwTjEv45IzlAOAu","name":"OpenAi account 2"}},"typeVersion":1.2},{"id":"94fba561-bc7e-4180-9b5d-beb9482b28b6","name":"Run Every X Hours","type":"n8n-nodes-base.scheduleTrigger","position":[0,140],"parameters":{"rule":{"interval":[{"field":"hours"}]}},"typeVersion":1.2},{"id":"603403fa-6f4b-4124-90ee-f852954e67a4","name":"Fetch Latest Upwork Jobs (Apify)","type":"n8n-nodes-base.httpRequest","position":[220,140],"parameters":{"url":"https://api.apify.com/v2/actor-tasks/<TASK_ID>/run-sync-get-dataset-items?token=<API_TOKEN>","options":{},"sendBody":true,"bodyParameters":{"parameters":[{}]}},"typeVersion":4.2},{"id":"0ed2ab83-1fcb-459c-aa6d-ef81c8414b45","name":"Extract Company or Person Name from Job","type":"@n8n/n8n-nodes-langchain.agent","position":[440,140],"parameters":{"text":"=Title: {{ $json.title }}\nDescription: {{ $json.description }}","options":{"systemMessage":"\"Extract the client's name or company name if it is mentioned. Return only the name or 'null' if not found.\""},"promptType":"define"},"typeVersion":1.9},{"id":"ccd6cf3c-2666-45eb-8dc3-6575180c897b","name":"Name is Found?","type":"n8n-nodes-base.if","position":[800,140],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"7366a7c6-e767-4aea-96e1-0cbbcbb26100","operator":{"type":"string","operation":"notEquals"},"leftValue":"={{ $json.output }}","rightValue":"null"}]}},"typeVersion":2.2},{"id":"c9721e93-707d-45c1-a06b-68606157f995","name":"No Name Found - End Early","type":"n8n-nodes-base.noOp","position":[1240,320],"parameters":{},"typeVersion":1},{"id":"4164b6e9-9ba7-4fc6-a1b6-c976f626aea5","name":"Is It a Person or Company?","type":"@n8n/n8n-nodes-langchain.agent","position":[1180,40],"parameters":{"text":"={{ $json.output }}","options":{"systemMessage":"\"Extract the client's name or company name. Return only the 'person' if looks like a person's name if not return 'company'.\"\n"},"promptType":"define"},"typeVersion":1.9},{"id":"93c7b341-6257-4ee2-a54f-ecbfcdf0f89b","name":"Person or Company?","type":"n8n-nodes-base.if","position":[1540,40],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"729e7baa-ae94-4661-a061-7d656faf820f","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.output }}","rightValue":"company"}]}},"typeVersion":2.2},{"id":"7dcacf79-eb65-454c-97fd-16ea6aed2f94","name":"Search LinkedIn for Company (Phantombuster)","type":"n8n-nodes-base.httpRequest","position":[1960,-120],"parameters":{"url":"https://api.phantombuster.com/api/v2/agents/<AGENT_ID>/launch","method":"POST","options":{},"jsonBody":"={\n  \"argument\": {\n    \"search\": {{ $json.output }},\n    \"numberOfProfiles\": 5,\n    \"sessionCookie\": \"<LINKEDIN_SESSION_COOKIE>\"\n  },\n  \"saveArguments\": true\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"X-Phantombuster-Key-1","value":"<YOUR_API_KEY>"}]}},"typeVersion":4.2},{"id":"e2f7db77-373e-462a-bc57-57653e067e30","name":"Scrape LinkedIn Company Profile","type":"n8n-nodes-base.httpRequest","position":[2180,-120],"parameters":{"url":"https://api.phantombuster.com/api/v2/agents/<AGENT_ID>/launch","method":"POST","options":{},"jsonBody":"={\n  \"argument\": {\n    \"spreadsheetUrl\": {{ $json.profileUrl }},\n    \"sessionCookie\": \"<LINKEDIN_SESSION_COOKIE>\"\n  },\n  \"saveArguments\": true\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"X-Phantombuster-Key-1","value":"<YOUR_API_KEY>"}]}},"typeVersion":4.2},{"id":"14d7f669-dbc1-484e-b3c0-3d1e83d4c74f","name":"Find Company Email (Hunter.io)","type":"n8n-nodes-base.httpRequest","position":[2400,-120],"parameters":{"url":"=https://api.hunter.io/v2/domain-search?domain{{ $json.website }}=&api_key=<YOUR_API_KEY>","options":{}},"typeVersion":4.2},{"id":"4fd05ce5-495e-4d3a-8998-3120c3456e57","name":"Search LinkedIn for Person (Phantombuster)","type":"n8n-nodes-base.httpRequest","position":[1960,1280],"parameters":{"url":"https://api.phantombuster.com/api/v2/agents/<AGENT_ID>/launch","method":"POST","options":{},"jsonBody":"{\n  \"argument\": {\n    \"search\": {{ $json.output }},\n    \"numberOfProfiles\": 3,\n    \"sessionCookie\": \"<LINKEDIN_SESSION_COOKIE>\"\n  },\n  \"saveArguments\": true\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"X-Phantombuster-Key-1","value":"<YOUR_API_KEY>"}]}},"typeVersion":4.2},{"id":"f048e198-cc4b-4739-be7d-d3d885c6d2bb","name":"Scrape LinkedIn Person Profile","type":"n8n-nodes-base.httpRequest","position":[2180,1280],"parameters":{"url":"https://api.phantombuster.com/api/v2/agents/<AGENT_ID>/launch","method":"POST","options":{},"jsonBody":"={\n  \"argument\": {\n    \"spreadsheetUrl\": {{ $json.profileUrl }},\n    \"sessionCookie\": \"<LINKEDIN_SESSION_COOKIE>\"\n  },\n  \"saveArguments\": true\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"X-Phantombuster-Key-1","value":"<YOUR_API_KEY>"}]}},"typeVersion":4.2},{"id":"dbc8c317-b469-4125-b939-614524a0339b","name":"Find Personal Email (Hunter.io)","type":"n8n-nodes-base.httpRequest","position":[2400,1280],"parameters":{"url":"=https://api.hunter.io/v2/email-finder?domain={{ $json.fullName }}=Ali%20Raza&api_key=<YOUR_API_KEY>","options":{}},"typeVersion":4.2},{"id":"047146a8-2b02-4098-a0e9-f8366c42aa4f","name":"Store Results in Google Sheet","type":"n8n-nodes-base.googleSheets","position":[2760,20],"parameters":{"operation":"append","sheetName":{"__rl":true,"mode":"list","value":""},"documentId":{"__rl":true,"mode":"list","value":""}},"credentials":{"googleSheetsOAuth2Api":{"id":"Rp7XiR3hxJfv03ZO","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"1e9dee68-e0c2-4588-b6ca-666534d14dd4","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-1820,-2200],"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":"2085a7ca-f68b-490a-9dcb-3c96fc6a739d","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-1820,-1860],"parameters":{"color":4,"width":1289,"height":5558,"content":"# 🚀 **Automated Upwork Lead Enrichment Workflow**\n\n> ✨ *Fetch potential clients from Upwork, extract their info using AI, search them on LinkedIn, gather emails, and store all in Google Sheets* ✨\n\n---\n\n## 🧩 **1. Trigger & Data Collection**\n\n---\n\n### ⏰ `Trigger - Run Every X Hours`\n\n**🔧 Node Type**: Schedule Trigger\n**🧠 Purpose**:\nThis node starts your automation periodically. You define how often it runs (e.g., every 6 hours, daily, etc.).\n\n**📚 Why It’s Important**:\nYou don’t want to manually check Upwork every few hours. This node automates it for you.\n\n---\n\n### 🌐 `Fetch Latest Upwork Jobs (Apify)`\n\n**🔧 Node Type**: HTTP Request\n**🧠 Purpose**:\nFetch the latest Upwork jobs by calling the [Apify Upwork Actor API](https://apify.com/).\n\n**⚙️ Tech Behind It**:\nA simple `GET` request pulls in structured job listings (title, description, budget, etc.) as JSON data.\n\n**💡 Beginner Tip**:\nNo coding needed—just copy your Apify API URL with your token and plug it into the node.\n\n---\n\n## 🤖 **2. AI Name Extraction**\n\n---\n\n### 🧠 `AI - Extract Company or Person Name from Job`\n\n**🔧 Node Type**: AI Agent / OpenAI Chat\n**🧠 Purpose**:\nUses GPT to scan the job title + description and extract a **company name or client’s full name**, if present.\n\n**📚 Why It’s Smart**:\nClients sometimes mention names like “Hi, we at DevSync...” or sign with their name at the bottom. This step grabs that.\n\n**🧠 AI Prompt Tip**:\nUse structured prompts like:\n\n> “Extract a full person or company name from this job description. If not found, say 'none’.”\n\n---\n\n### 🧪 `IF - Name is Found?`\n\n**🔧 Node Type**: IF\n**🧠 Purpose**:\nChecks whether the AI returned a name. If not, it skips that job.\n\n**🛑 `No Name Found - End Early`**\nStops further processing and prevents wasted API calls or errors.\n\n---\n\n## 🧭 **3. AI Classification – Person vs Company**\n\n---\n\n### 🧠 `AI - Is It a Person or Company?`\n\n**🔧 Node Type**: AI Agent\n**🧠 Purpose**:\nClassifies the extracted name as either a **company** or a **person** using simple AI logic.\n\n**🔍 Why It Matters**:\nDepending on what it is, the next step—searching LinkedIn—will differ.\n\n---\n\n### 🔀 `IF - Person or Company?`\n\n**🔧 Node Type**: IF\n**🧠 Purpose**:\nRoutes the flow to two different paths:\n\n* Company → Search company profile\n* Person → Search individual profile\n\n---\n\n## 🏢 **4A. Company Path**\n\n---\n\n### 🔍 `Search LinkedIn for Company (Phantombuster)`\n\n**🔧 Node Type**: HTTP Request\n**📡 Purpose**:\nUses [Phantombuster’s LinkedIn Search API](https://phantombuster.com/) to search for the **company name**.\n\n**📦 Input**: `\"DevSync\"`\n**📤 Output**: Company’s LinkedIn URL\n\n---\n\n### 🏭 `Scrape LinkedIn Company Profile`\n\n**🔧 Node Type**: HTTP Request\n**🔍 Purpose**:\nScrapes the company’s LinkedIn page to pull:\n\n* Size\n* Website\n* Industry\n* Location\n* Description\n\n---\n\n### 📬 `Find Company Email (Hunter.io)`\n\n**🔧 Node Type**: HTTP Request\n**🔍 Purpose**:\nUses [Hunter.io](https://hunter.io) to find company-level email addresses like `info@devsync.com`, `hello@devsync.com`, etc.\n\n**📦 Input**: Company’s domain (e.g., `devsync.com`)\n**📤 Output**: Emails + Confidence Score\n\n---\n\n## 👤 **4B. Person Path**\n\n---\n\n### 🔍 `Search LinkedIn for Person (Phantombuster)`\n\n**🔧 Node Type**: HTTP Request\n**📡 Purpose**:\nSearches for the extracted **person’s name** like \"John Smith\" using Phantombuster.\n\n**📤 Output**: LinkedIn profile URL(s)\n\n---\n\n### 🧑‍💼 `Scrape LinkedIn Person Profile`\n\n**🔧 Node Type**: HTTP Request\n**📄 Purpose**:\nScrapes:\n\n* Name\n* Current Job Title\n* Company\n* Location\n* Education\n* LinkedIn URL\n\n---\n\n### ✉️ `Find Personal Email (Hunter.io)`\n\n**🔧 Node Type**: HTTP Request\n**🔍 Purpose**:\nAttempts to find personal emails using the name + company domain.\n\n**📤 Output**: Email (if public), sometimes with confidence score.\n\n---\n\n## 📑 **5. Store Everything in Google Sheets**\n\n---\n\n### 🧾 `Store Results in Google Sheet`\n\n**🔧 Node Type**: Google Sheets (Append Row)\n**🧠 Purpose**:\nSaves:\n\n* Job title\n* Description\n* Client Name\n* Person/Company\n* LinkedIn Profile\n* Scraped Info\n* Emails\n\n**📚 Why It’s Gold**:\nYou now have a **personal CRM of Upwork clients** to reach out to directly or research further.\n\n---\n\n## 🌟 **Summary of Benefits**\n\n| ✅ Feature              | 💡 Benefit                            |\n| ---------------------- | ------------------------------------- |\n| Fully automated        | Save hours of manual research         |\n| Uses AI                | No need to write complex regex or NLP |\n| Phantombuster scraping | Get verified LinkedIn profiles        |\n| Hunter.io              | Helps gather email leads              |\n| Google Sheets          | Easy to filter, review, and manage    |\n\n---\n\n## 📌 **Beginner Tips**\n\n* 🧪 Start with dummy job data and test just the first few nodes.\n* 🔑 Always **secure your API keys** using environment variables or secrets.\n* 🧠 Use **n8n’s execution log** to debug any failures.\n* 🧹 Add rate-limiting or error handling if APIs return errors or limits.\n\n---\n\nWould you like a Notion-ready documentation, downloadable PDF, or HTML guide for your team or clients?\n"},"typeVersion":1},{"id":"5bda85dd-7559-4239-9b38-c887a39dbb54","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-60,-2180],"parameters":{"color":3,"width":1800,"height":2680,"content":"## 🧩 **1. Trigger & Data Collection**\n\n---\n\n### ⏰ `Trigger - Run Every X Hours`\n\n**🔧 Node Type**: Schedule Trigger\n**🧠 Purpose**:\nThis node starts your automation periodically. You define how often it runs (e.g., every 6 hours, daily, etc.).\n\n**📚 Why It’s Important**:\nYou don’t want to manually check Upwork every few hours. This node automates it for you.\n\n---\n\n### 🌐 `Fetch Latest Upwork Jobs (Apify)`\n\n**🔧 Node Type**: HTTP Request\n**🧠 Purpose**:\nFetch the latest Upwork jobs by calling the [Apify Upwork Actor API](https://apify.com/).\n\n**⚙️ Tech Behind It**:\nA simple `GET` request pulls in structured job listings (title, description, budget, etc.) as JSON data.\n\n**💡 Beginner Tip**:\nNo coding needed—just copy your Apify API URL with your token and plug it into the node.\n\n---\n\n## 🤖 **2. AI Name Extraction**\n\n---\n\n### 🧠 `AI - Extract Company or Person Name from Job`\n\n**🔧 Node Type**: AI Agent / OpenAI Chat\n**🧠 Purpose**:\nUses GPT to scan the job title + description and extract a **company name or client’s full name**, if present.\n\n**📚 Why It’s Smart**:\nClients sometimes mention names like “Hi, we at DevSync...” or sign with their name at the bottom. This step grabs that.\n\n**🧠 AI Prompt Tip**:\nUse structured prompts like:\n\n> “Extract a full person or company name from this job description. If not found, say 'none’.”\n\n---\n\n### 🧪 `IF - Name is Found?`\n\n**🔧 Node Type**: IF\n**🧠 Purpose**:\nChecks whether the AI returned a name. If not, it skips that job.\n\n**🛑 `No Name Found - End Early`**\nStops further processing and prevents wasted API calls or errors.\n\n---\n\n## 🧭 **3. AI Classification – Person vs Company**\n\n---\n\n### 🧠 `AI - Is It a Person or Company?`\n\n**🔧 Node Type**: AI Agent\n**🧠 Purpose**:\nClassifies the extracted name as either a **company** or a **person** using simple AI logic.\n\n**🔍 Why It Matters**:\nDepending on what it is, the next step—searching LinkedIn—will differ.\n\n---\n\n### 🔀 `IF - Person or Company?`\n\n**🔧 Node Type**: IF\n**🧠 Purpose**:\nRoutes the flow to two different paths:\n\n* Company → Search company profile\n* Person → Search individual profile"},"typeVersion":1},{"id":"aa30a465-97e4-449f-a0b4-07a97a0f3d2c","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[1880,-1300],"parameters":{"color":5,"width":700,"height":1420,"content":"## 🏢 **4A. Company Path**\n\n---\n\n### 🔍 `Search LinkedIn for Company (Phantombuster)`\n\n**🔧 Node Type**: HTTP Request\n**📡 Purpose**:\nUses [Phantombuster’s LinkedIn Search API](https://phantombuster.com/) to search for the **company name**.\n\n**📦 Input**: `\"DevSync\"`\n**📤 Output**: Company’s LinkedIn URL\n\n---\n\n### 🏭 `Scrape LinkedIn Company Profile`\n\n**🔧 Node Type**: HTTP Request\n**🔍 Purpose**:\nScrapes the company’s LinkedIn page to pull:\n\n* Size\n* Website\n* Industry\n* Location\n* Description\n\n---\n\n### 📬 `Find Company Email (Hunter.io)`\n\n**🔧 Node Type**: HTTP Request\n**🔍 Purpose**:\nUses [Hunter.io](https://hunter.io) to find company-level email addresses like `info@devsync.com`, `hello@devsync.com`, etc.\n\n**📦 Input**: Company’s domain (e.g., `devsync.com`)\n**📤 Output**: Emails + Confidence Score\n\n---\n"},"typeVersion":1},{"id":"7d7ec4da-d52c-4563-94df-3dcf88c85ff0","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1900,160],"parameters":{"color":6,"width":640,"height":1300,"content":"## 👤 **4B. Person Path**\n\n---\n\n### 🔍 `Search LinkedIn for Person (Phantombuster)`\n\n**🔧 Node Type**: HTTP Request\n**📡 Purpose**:\nSearches for the extracted **person’s name** like \"John Smith\" using Phantombuster.\n\n**📤 Output**: LinkedIn profile URL(s)\n\n---\n\n### 🧑‍💼 `Scrape LinkedIn Person Profile`\n\n**🔧 Node Type**: HTTP Request\n**📄 Purpose**:\nScrapes:\n\n* Name\n* Current Job Title\n* Company\n* Location\n* Education\n* LinkedIn URL\n\n---\n\n### ✉️ `Find Personal Email (Hunter.io)`\n\n**🔧 Node Type**: HTTP Request\n**🔍 Purpose**:\nAttempts to find personal emails using the name + company domain.\n\n**📤 Output**: Email (if public), sometimes with confidence score.\n\n---"},"typeVersion":1},{"id":"46f24197-38da-43a1-ba03-1e394169340a","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[2680,-520],"parameters":{"color":6,"width":260,"height":720,"content":"## 📑 **5. Store Everything in Google Sheets**\n\n---\n\n### 🧾 `Store Results in Google Sheet`\n\n**🔧 Node Type**: Google Sheets (Append Row)\n**🧠 Purpose**:\nSaves:\n\n* Job title\n* Description\n* Client Name\n* Person/Company\n* LinkedIn Profile\n* Scraped Info\n* Emails"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"9c24521c-85cb-4dbe-b671-43cb6e038740","connections":{"Name is Found?":{"main":[[{"node":"Is It a Person or Company?","type":"main","index":0}],[{"node":"No Name Found - End Early","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Extract Company or Person Name from Job","type":"ai_languageModel","index":0},{"node":"Is It a Person or Company?","type":"ai_languageModel","index":0}]]},"Run Every X Hours":{"main":[[{"node":"Fetch Latest Upwork Jobs (Apify)","type":"main","index":0}]]},"Person or Company?":{"main":[[{"node":"Search LinkedIn for Company (Phantombuster)","type":"main","index":0}],[{"node":"Search LinkedIn for Person (Phantombuster)","type":"main","index":0}]]},"Is It a Person or Company?":{"main":[[{"node":"Person or Company?","type":"main","index":0}]]},"Find Company Email (Hunter.io)":{"main":[[{"node":"Store Results in Google Sheet","type":"main","index":0}]]},"Scrape LinkedIn Person Profile":{"main":[[{"node":"Find Personal Email (Hunter.io)","type":"main","index":0}]]},"Find Personal Email (Hunter.io)":{"main":[[{"node":"Store Results in Google Sheet","type":"main","index":0}]]},"Scrape LinkedIn Company Profile":{"main":[[{"node":"Find Company Email (Hunter.io)","type":"main","index":0}]]},"Fetch Latest Upwork Jobs (Apify)":{"main":[[{"node":"Extract Company or Person Name from Job","type":"main","index":0}]]},"Extract Company or Person Name from Job":{"main":[[{"node":"Name is Found?","type":"main","index":0}]]},"Search LinkedIn for Person (Phantombuster)":{"main":[[{"node":"Scrape LinkedIn Person Profile","type":"main","index":0}]]},"Search LinkedIn for Company (Phantombuster)":{"main":[[{"node":"Scrape LinkedIn Company Profile","type":"main","index":0}]]}}}


name: Track CVE Vulnerability Details & History with NVD API and Google Sheets
author_name: Niranjan G
author_username: niranjan
nodes_used: ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.code"]
categories: []
created_at: 2025-06-08T15:14:27.731Z
updated_at: 2025-06-08T15:14:27.731Z
url: https://n8n.io/workflows/4797
scraped_at: 2025-07-06 21:16:30
description:
  Who is this for?

  NVD (National Vulnerability Database) data is essential for security analysts, vulnerability managers, and DevSecOps professionals who need to perform both CVE lookups and monitor historical change logs. This workflow helps streamline those efforts by providing structured outputs for audit, triage, or compliance tracking purposes.

  📝 Note: While this example uses Google Sheets as the destination, you can easily modify the final destination node (e.g., send to Slack, email, database, etc.) based on your specific automation needs.?

  What problem is this solving?

  Security teams often manually look up CVE data and track changes across multiple tools. This process is inefficient and error-prone. This workflow automates the CVE lookup and historical change tracking by logging enriched vulnerability data into Google Sheets in real-time.

  What this workflow does

  This workflow is designed for CVE API lookup and change history tracking. In many vulnerability automation pipelines, it is essential to determine not only the metadata of a CVE but also how it has evolved over time. Based on the operational need—whether it's enrichment, risk scoring, or remediation validation—this workflow becomes particularly handy in surfacing both current and historical CVE data. This template performs the following actions:

  Accepts incoming webhook requests containing a CVE ID
  Queries the NVD CVE Lookup API to fetch vulnerability metadata
  Queries the NVD CVE History API to retrieve all historical changes
  Flattens both datasets into a sheet-compatible structure
  Appends vulnerability metadata to one sheet and change history to another within the same Google Spreadsheet

  Setup

  🔑 Request an NVD API Key

  To request an NVD API Key, please provide your organization name, a valid email address, and indicate your organization type at NVD API Key Request. You must scroll to the end of the Terms of Use Agreement and check "I agree to the Terms of Use" to obtain an API Key. After submission, you will receive a single-use hyperlink via email to activate and view your API Key. If not activated within seven days, a new request must be submitted.

  📊 API Rate Limits

  Without an API key, you're limited to 5 requests per 30-second window. With an API key, you’re allowed up to 50 requests in the same period. To prevent request throttling, it's recommended to introduce slight delays between consecutive API calls in production setups.

  Clone or import this workflow into your n8n instance.
  Set up the following credentials:
     Google Sheets OAuth2
     NVD API Key (via HTTP Header Auth)
  The workflow logs data to a Google Sheet titled NVD Database, with Sheet 1 named CVE Lookup and Sheet 2 named CVE History.
  Trigger each workflow using the respective webhook URL, appending ?cveId=CVE-XXXX-XXXX as a query parameter.

  🔍 Example Webhook Request (CVE Change History)

  You can test this workflow with the following example:

  GET https://your-domain.com/webhook/cve-history?cveId=CVE-2023-34362

  How to customize this workflow

  Use the Edit Fields node (optional) to centralize configuration like sheet name or query input
  Extend the CVE flattening logic to include more nested metadata if needed
  Integrate notification systems (e.g., Slack or email) by branching from the processing nodes
  Modify webhook paths for better endpoint organization

  🔐 Production Security Tips

  Use HTTP Header Auth on the webhook for secure access

  &gt; ⚠️ This template uses webhooks and NVD API access with authentication headers.

  This template uses two flows:

  Webhook 1:** NVD CVE Lookup — Lookup CVE vulnerability metadata from NVD and sync to Google Sheet
  Webhook 2:** NVD CVE Change History — Track change history for CVEs via NVD and log each update

  Each flow:

  Hits NVD’s respective endpoint
  Uses custom JS Code node to flatten the nested JSON
  Syncs data to dedicated Google Sheet tabs
  🧩 4 nodes: Webhook → API Call → Parse → Sheet Sync

  Make sure both flows are activated and webhooks exposed for external access. Based on your needs, ensure you have a secure setup—whether hosted internally or in a cloud environment—when running n8n in production.

workflow_json:
  {"id":"YEh1XUHtAwWFvB7z","meta":{"instanceId":"c62c01f3e843893075a10f252ec7d6d69e5ab593af019f50055d506cb3081b99","templateCredsSetupCompleted":true},"name":"Track CVE Details & History from NVD and Sync to Google Sheets","tags":[{"id":"XuoVybTXeUXuim6G","name":"✅ Live","createdAt":"2025-06-08T07:59:43.586Z","updatedAt":"2025-06-08T07:59:43.586Z"},{"id":"MbPHhZHgb39Syuoa","name":"🔐 SecOps","createdAt":"2025-04-20T05:18:20.689Z","updatedAt":"2025-06-08T08:01:56.494Z"}],"nodes":[{"id":"b8e39932-0733-465a-a784-469d36374754","name":"Webhook: Get CVE Details","type":"n8n-nodes-base.webhook","position":[-260,-160],"webhookId":"3a3e9d6c-fbbf-482c-a6e9-88cdd79d404a","parameters":{"path":"3a3e9d6c-fbbf-482c-a6e9-88cdd79d404a","options":{}},"typeVersion":2},{"id":"844af868-d326-4d73-85b8-00de22f2e5ca","name":"Fetch CVE from NVD API","type":"n8n-nodes-base.httpRequest","position":[-40,-160],"parameters":{"url":"https://services.nvd.nist.gov/rest/json/cves/2.0","options":{},"sendQuery":true,"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","queryParameters":{"parameters":[{"name":"cveId","value":"={{ $json.query.cveId }}"}]}},"credentials":{"httpBasicAuth":{"id":"pmJaCcMGEkPDYowB","name":"Basic Auth Webhook credential"},"httpHeaderAuth":{"id":"mHJL7L4nhoBAK9S8","name":"NVD Header Auth account"}},"typeVersion":4.2},{"id":"3ab38c76-33df-44a1-987b-0f668028c4f7","name":"Parse CVE JSON → Flat Format","type":"n8n-nodes-base.code","position":[180,-160],"parameters":{"jsCode":"const results = [];\n\nfor (const item of items) {\n  const vulnerabilities = item.json.vulnerabilities || [];\n\n  for (const vuln of vulnerabilities) {\n    const cve = vuln.cve || {};\n\n    const cvss = cve.metrics?.cvssMetricV31?.[0];\n    const cvssData = cvss?.cvssData || {};\n\n    results.push({\n      json: {\n        CVE_ID: cve.id || '',\n        Source_Identifier: cve.sourceIdentifier || '',\n        Published: cve.published || '',\n        Last_Modified: cve.lastModified || '',\n        Vuln_Status: cve.vulnStatus || '',\n        CVE_Tags: (cve.cveTags || []).join(';'),\n\n        Description: (cve.descriptions || []).find(d => d.lang === 'en')?.value || '',\n\n        CVSS_Version: cvssData.version || '',\n        Vector_String: cvssData.vectorString || '',\n        Base_Severity: cvssData.baseSeverity || '',\n        Base_Score: cvssData.baseScore || '',\n        Attack_Vector: cvssData.attackVector || '',\n        Attack_Complexity: cvssData.attackComplexity || '',\n        Privileges_Required: cvssData.privilegesRequired || '',\n        User_Interaction: cvssData.userInteraction || '',\n        Scope: cvssData.scope || '',\n        Confidentiality_Impact: cvssData.confidentialityImpact || '',\n        Integrity_Impact: cvssData.integrityImpact || '',\n        Availability_Impact: cvssData.availabilityImpact || '',\n        Exploitability_Score: cvss?.exploitabilityScore || '',\n        Impact_Score: cvss?.impactScore || '',\n\n        CWE_ID: cve.weaknesses?.[0]?.description?.[0]?.value || '',\n        Reference_URL: cve.references?.[0]?.url || ''\n      }\n    });\n  }\n}\n\nreturn results;"},"typeVersion":2},{"id":"f96c4bcb-b24e-4e19-9c59-6ed733d0f98b","name":"Log CVE Metadata to Sheet","type":"n8n-nodes-base.googleSheets","position":[400,-160],"parameters":{"columns":{"value":{},"schema":[{"id":"CVE_ID","type":"string","display":true,"removed":false,"required":false,"displayName":"CVE_ID","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Raw_CVE_Data","type":"string","display":true,"removed":false,"required":false,"displayName":"Raw_CVE_Data","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"autoMapInputData","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/abc1234567890/edit#gid=0","cachedResultName":"CVE Lookup"},"documentId":{"__rl":true,"mode":"list","value":"abc1234567890","cachedResultUrl":"https://docs.google.com/spreadsheets/d/abc1234567890/edit?usp=drivesdk","cachedResultName":"NVD Database"}},"credentials":{"googleSheetsOAuth2Api":{"id":"W8E4vruWIsUhkTII","name":"Google Sheets account [abc@mail.com]"}},"typeVersion":4.6},{"id":"11bb7c7e-c7e8-4d1f-98c9-c36d59b9b928","name":"Webhook: Get CVE Change History","type":"n8n-nodes-base.webhook","position":[-260,260],"webhookId":"587c86f4-4a3a-4765-b486-4bed8a0ccad3","parameters":{"path":"587c86f4-4a3a-4765-b486-4bed8a0ccad3","options":{}},"typeVersion":2},{"id":"ac9e845b-4905-43d1-971b-9c93c3ef8f9e","name":"Fetch CVE History from NVD API","type":"n8n-nodes-base.httpRequest","position":[-40,260],"parameters":{"url":"https://services.nvd.nist.gov/rest/json/cvehistory/2.0","options":{},"sendQuery":true,"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","queryParameters":{"parameters":[{"name":"cveId","value":"={{ $json.query.cveId }}"}]}},"credentials":{"httpBasicAuth":{"id":"pmJaCcMGEkPDYowB","name":"Basic Auth Webhook credential"},"httpHeaderAuth":{"id":"mHJL7L4nhoBAK9S8","name":"NVD Header Auth account"}},"typeVersion":4.2},{"id":"8a78a501-352d-4e4a-9ff1-3752e7723d65","name":"Parse CVE History JSON → Flat Format","type":"n8n-nodes-base.code","position":[180,260],"parameters":{"jsCode":"const results = [];\n\nfor (const item of items) {\n  const cveChanges = item.json.cveChanges || [];\n\n  for (const changeEntry of cveChanges) {\n    const change = changeEntry.change || {};\n\n    const cveId = change.cveId || '';\n    const changeId = change.cveChangeId || '';\n    const event = change.eventName || '';\n    const source = change.sourceIdentifier || '';\n    const created = change.created || '';\n\n    const details = change.details || [];\n\n    // If there are details, extract each detail into its own row\n    if (details.length > 0) {\n      for (const detail of details) {\n        results.push({\n          json: {\n            CVE_ID: cveId,\n            Change_ID: changeId,\n            Event: event,\n            Source: source,\n            Timestamp: created,\n            Action: detail.action || '',\n            Type: detail.type || '',\n            Old_Value: detail.oldValue || '',\n            New_Value: detail.newValue || ''\n          }\n        });\n      }\n    } else {\n      // If no details present, still add the change entry\n      results.push({\n        json: {\n          CVE_ID: cveId,\n          Change_ID: changeId,\n          Event: event,\n          Source: source,\n          Timestamp: created,\n          Action: '',\n          Type: '',\n          Old_Value: '',\n          New_Value: ''\n        }\n      });\n    }\n  }\n}\n\nreturn results;"},"typeVersion":2},{"id":"885c9eae-cab8-40ba-8eac-2e920370651f","name":"Log CVE History to Sheet","type":"n8n-nodes-base.googleSheets","position":[400,260],"parameters":{"columns":{"value":{},"schema":[{"id":"CVE_ID","type":"string","display":true,"removed":false,"required":false,"displayName":"CVE_ID","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Change_ID","type":"string","display":true,"removed":false,"required":false,"displayName":"Change_ID","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Event","type":"string","display":true,"removed":false,"required":false,"displayName":"Event","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Source","type":"string","display":true,"removed":false,"required":false,"displayName":"Source","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Timestamp","type":"string","display":true,"removed":false,"required":false,"displayName":"Timestamp","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Action","type":"string","display":true,"removed":false,"required":false,"displayName":"Action","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Type","type":"string","display":true,"removed":false,"required":false,"displayName":"Type","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Old_Value","type":"string","display":true,"removed":false,"required":false,"displayName":"Old_Value","defaultMatch":false,"canBeUsedToMatch":true},{"id":"New_Value","type":"string","display":true,"removed":false,"required":false,"displayName":"New_Value","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"autoMapInputData","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"list","value":185619006,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/abc1234567890/edit#gid=185619006","cachedResultName":"CVE History"},"documentId":{"__rl":true,"mode":"list","value":"abc1234567890","cachedResultUrl":"https://docs.google.com/spreadsheets/d/abc1234567890/edit?usp=drivesdk","cachedResultName":"NVD Database"}},"credentials":{"googleSheetsOAuth2Api":{"id":"W8E4vruWIsUhkTII","name":"Google Sheets account [abc@mail.com]"}},"typeVersion":4.6},{"id":"8d8f4db1-f5fd-499c-ace5-eec99ecb6b9e","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-380,-340],"parameters":{"width":1000,"height":360,"content":"## 🔍 Lookup CVE vulnerability metadata from NVD and sync to Google Sheet"},"typeVersion":1},{"id":"854a2420-e22f-4630-8b97-bd1e8f484158","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-380,100],"parameters":{"color":3,"width":1000,"height":360,"content":"## 🕓 Track change history for CVEs via NVD and log each update"},"typeVersion":1},{"id":"71f9bf5e-5ccd-4752-a583-6f751071b239","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1140,-340],"parameters":{"width":740,"height":800,"content":"# NVD (National Vulnerability Database)\n\n## Setup\n\n- Import this workflow into your n8n instance.\n\n- Set up the following credentials:\n\n-- Google Sheets OAuth2\n\n-- NVD API Key (via HTTP Header Auth)\n\n- The workflow logs data to a Google Sheet titled **NVD Database**, with Sheet 1 named **CVE Lookup** and Sheet 2 named **CVE History**.\n\n- Trigger each workflow using the respective webhook URL, appending ?cveId=CVE-XXXX-XXXX as a query parameter.\n\n## 🔍 Sample Test URL\n\nYou can test this workflow with the following example:\n```\nGET https://your-domain.com/webhook/cve-history?cveId=CVE-2023-34362\n```\n"},"typeVersion":1},{"id":"16151bff-6c9d-441e-9ee5-5c73a2d3135a","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-60,-260],"parameters":{"color":7,"width":150,"height":80,"content":"NVD API Key (via HTTP Header Auth) ⬇️"},"typeVersion":1},{"id":"05222357-d84d-4615-9bfd-635ddc7c68b7","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-60,160],"parameters":{"color":7,"width":150,"height":80,"content":"NVD API Key (via HTTP Header Auth) ⬇️"},"typeVersion":1}],"active":true,"settings":{"executionOrder":"v1"},"versionId":"8c8d7836-7657-435e-bd05-e2223ddc0c1e","connections":{"Fetch CVE from NVD API":{"main":[[{"node":"Parse CVE JSON → Flat Format","type":"main","index":0}]]},"Webhook: Get CVE Details":{"main":[[{"node":"Fetch CVE from NVD API","type":"main","index":0}]]},"Fetch CVE History from NVD API":{"main":[[{"node":"Parse CVE History JSON → Flat Format","type":"main","index":0}]]},"Parse CVE JSON → Flat Format":{"main":[[{"node":"Log CVE Metadata to Sheet","type":"main","index":0}]]},"Webhook: Get CVE Change History":{"main":[[{"node":"Fetch CVE History from NVD API","type":"main","index":0}]]},"Parse CVE History JSON → Flat Format":{"main":[[{"node":"Log CVE History to Sheet","type":"main","index":0}]]}}}


name: Create Character-Consistent Images with FLUX Kontext & Post to Social via Upload Post
author_name: Eduard
author_username: eduard
nodes_used: ["n8n-nodes-base.github","n8n-nodes-base.httpRequest"]
categories: []
created_at: 2025-06-08T15:34:39.639Z
updated_at: 2025-06-08T15:34:39.639Z
url: https://n8n.io/workflows/4798
scraped_at: 2025-07-06 21:16:30
description:
  Create, iterate, and share! Transform a single image through multiple scenes while maintaining consistency.

  ✨ What this workflow does

  This template showcases FLUX.1 Kontext - Black Forest Labs' in-context image generation model that excels at maintaining character features across multiple transformations. Combined with the Upload Post community node for effortless multi-platform social media posting, you can create and share compelling visual stories instantly.

  The workflow demonstrates FLUX Kontext's core strength: character consistency across multiple image generations. Starting with a single input image, it:
  🖼️ Loads an initial character image (example: a cute animal mascot)
  📝 Defines multiple scene transformation prompts 
  🔄 Iteratively generates new scenes while preserving exact character features
  🎯 Maintains visual consistency by reusing binary data from previous generations
  📱 Auto-posts the complete transformation series to multiple social platforms simultaneously

  🚀 Key Features: The Consistency Advantage

  Character Preservation**: FLUX Kontext's signature feature - maintains character features and style across transformations (requires specific prompting techniques)
  Iterative Context Building**: Each generation uses the previous image as context, creating visual continuity
  Binary Data Reuse**: Smart workflow design that feeds output from one generation as input to the next
  Multi-Scene Storytelling**: Transform your character across different environments while keeping them recognizable
  One-Click Multi-Platform Posting*: Upload Post eliminates the tedious process of posting to each platform individually

  📱 Why use Upload Post?

  Posting the same content to TikTok, Instagram, LinkedIn, YouTube, Facebook, X (Twitter), and Threads individually is time-consuming and error-prone. The Upload Post service* simplifies this process:

  ✅ Connect once, post everywhere: Link all your social media accounts to Upload Post  
  ✅ Single API call: Post to multiple platforms with one simple node  
  ✅ No more platform juggling: Skip the endless switching between apps and dashboards  
  ✅ Consistent timing: All platforms get your content simultaneously  
  ✅ Trusted by 3,751+ users: Proven solution for content creators and marketers

  Instead of spending 30+ minutes manually posting to each platform, Upload Post does it all in seconds with a single n8n node!

  🛠️ Prerequisites

  Required Accounts:
  Black Forest Labs API: Create account at dashboard.bfl.ai
     Get your API key for FLUX Kontext Pro access
     
  Upload Post Account: Sign up at upload-post.com*
     Connect your social media profiles (TikTok, Instagram, LinkedIn, YouTube, Facebook, X/Twitter, Threads)
     Get API credentials for automated posting
     Free tier available: 10 uploads/month

  💡 Perfect For:

  Character Designers** maintaining brand character integrity across scenes
  Social Media Managers** creating engaging visual story series without manual posting
  Brand Marketers** ensuring character consistency across campaigns
  Storytellers** building visual narratives with consistent protagonists
  Agencies** managing multiple client accounts efficiently

  🔧 Customization Options:

  Modify transformation prompts** to create your own character journey
  Adjust iteration steps**
  Change initial character image**
  Configure social platform targeting** (choose which platforms to post to)
  Customize post content** and formatting
  Experiment with different consistency scenarios**

  \ Affiliate link*

workflow_json:
  {"id":"AdtCs47Lt1Wtf2Dt","meta":{"instanceId":"fb924c73af8f703905bc09c9ee8076f48c17b596ed05b18c0ff86915ef8a7c4a","templateCredsSetupCompleted":true},"name":"Upload-Post And FLUX Kontext","tags":[],"nodes":[{"id":"ed7d240f-9181-4f23-9e3a-24e7886c7e31","name":"When clicking ‘Execute workflow’","type":"n8n-nodes-base.manualTrigger","position":[-180,0],"parameters":{},"typeVersion":1},{"id":"4656ae65-d58b-4126-ada3-eda97fde5c4e","name":"Is Ready?","type":"n8n-nodes-base.if","position":[500,400],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"or","conditions":[{"id":"3cf5b451-9ff5-4c2a-864f-9aa7d286871a","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"Ready"},{"id":"a9b6d102-bb38-443f-a204-1c07476cb360","operator":{"type":"number","operation":"gt"},"leftValue":"={{ $runIndex }}","rightValue":5}]}},"typeVersion":2.2},{"id":"f8dbc367-1052-4548-b3b8-33f6ede4d0ba","name":"Check FLUX status","type":"n8n-nodes-base.httpRequest","position":[340,400],"parameters":{"url":"https://api.bfl.ml/v1/get_result","options":{},"sendQuery":true,"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","queryParameters":{"parameters":[{"name":"id","value":"={{ $json.id }}"}]}},"credentials":{"httpHeaderAuth":{"id":"4eQN9wBw8SniKcPw","name":"bfl-FLUX"}},"typeVersion":4.2},{"id":"9624cdc6-1f7b-459f-b16a-eab69d23b45c","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-60,320],"parameters":{"color":7,"width":862,"height":282,"content":"# Image processing part"},"typeVersion":1},{"id":"c6393bc7-6b7a-4a25-a524-8a7bd6b2c781","name":"When Executed by Another Workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[-380,400],"parameters":{"inputSource":"passthrough"},"typeVersion":1.1},{"id":"4f3717a6-2580-4664-8182-efa1c8652589","name":"FLUX Kontext","type":"n8n-nodes-base.httpRequest","position":[0,400],"parameters":{"url":"https://api.bfl.ml/v1/flux-kontext-pro","method":"POST","options":{},"sendBody":true,"authentication":"genericCredentialType","bodyParameters":{"parameters":[{"name":"input_image","value":"={{ $json[$('When Executed by Another Workflow').first().json.binaryin] }}"},{"name":"prompt","value":"={{ $('When Executed by Another Workflow').first().json.prompt }}"},{"name":"prompt_upsampling","value":"={{ false }}"},{"name":"output_format","value":"png"},{"name":" aspect_ratio","value":"1:1"}]},"genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"4eQN9wBw8SniKcPw","name":"bfl-FLUX"}},"typeVersion":4.2},{"id":"2a48ecd4-07bc-4202-abe3-3bc0bfbfed6d","name":"Merge","type":"n8n-nodes-base.merge","position":[420,0],"parameters":{"mode":"combine","options":{"includeUnpaired":true},"combineBy":"combineByPosition"},"typeVersion":3.1},{"id":"cc5f96a9-ed87-4526-85c2-074dc5c8e166","name":"Wait 2 sec","type":"n8n-nodes-base.wait","position":[180,400],"webhookId":"3df5a762-edab-49df-ac70-be3b56545212","parameters":{"amount":2},"typeVersion":1.1},{"id":"54cf0d0d-c3a0-4243-b425-ba8cdfaf1063","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-20,-240],"parameters":{"width":380,"height":260,"content":"## Define prompts here\nPrepare an array of prompts that will be used one by one on the next steps. Update limit in the `Number of Steps` node if you need more than 5 iterations."},"typeVersion":1},{"id":"add02353-b31e-4990-83ad-2d936343ab7f","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-20,60],"parameters":{"width":380,"height":220,"content":"## Load the initial image"},"typeVersion":1},{"id":"8367ef9f-cf00-4987-91ec-09fe3ec6918d","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-340,-420],"parameters":{"width":260,"height":400,"content":"## Initial example\n![](https://raw.githubusercontent.com/teds-tech-talks/n8n-community-leaderboard/main/_creators/eduard/mascot.png)"},"typeVersion":1},{"id":"c4a52815-ba73-4f9c-8c44-fca40cab6440","name":"Get File from GitHub","type":"n8n-nodes-base.github","position":[20,120],"webhookId":"e70d0c46-6478-4c11-85a6-8b7e1f9588de","parameters":{"owner":{"__rl":true,"mode":"name","value":"teds-tech-talks"},"filePath":"_creators/eduard/mascot.png","resource":"file","operation":"get","repository":{"__rl":true,"mode":"name","value":"n8n-community-leaderboard"},"authentication":"oAuth2","asBinaryProperty":false,"additionalParameters":{}},"credentials":{"githubOAuth2Api":{"id":"SBUgEkMg70oFZRct","name":"TTT GitHub account"}},"typeVersion":1.1},{"id":"bb48cde8-fc79-407e-8daa-4322398d8385","name":"Download Initial Image","type":"n8n-nodes-base.httpRequest","position":[220,120],"parameters":{"url":"={{ $json.download_url }}","options":{"response":{"response":{"responseFormat":"file","outputPropertyName":"data0"}}}},"typeVersion":4.2},{"id":"ffc484fe-c183-4858-8303-8733596e2afc","name":"If","type":"n8n-nodes-base.if","position":[680,0],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"4d3dcb8f-c435-40fd-aca6-a37647fc3a10","operator":{"type":"number","operation":"lt"},"leftValue":"={{ $runIndex }}","rightValue":"={{ $json.Steps }}"}]}},"typeVersion":2.2},{"id":"6fbd6310-7596-4460-8a85-3cc0b1253509","name":"Number of Steps","type":"n8n-nodes-base.set","position":[220,-120],"parameters":{"options":{},"assignments":{"assignments":[{"id":"9e3d00d0-467a-41c8-aaa1-f1d29694737c","name":"Steps","type":"number","value":"={{ Math.min($json.Prompts.length,5) }}"}]},"includeOtherFields":true},"typeVersion":3.4},{"id":"6bacc1b2-7154-428c-ab0f-76f356c59e35","name":"All Prompts","type":"n8n-nodes-base.set","position":[20,-120],"parameters":{"options":{},"assignments":{"assignments":[{"id":"64e9c28e-a60a-499b-aa89-177bf952959f","name":"Prompts","type":"array","value":"=[\"Make this animal mascot coming out of the builing with wearing an official business suite. Preserve the exact character features and style\",\"Now make this animal mascot sitting in the terrace mediterranian cafe. Preserve the exact character features and style, but wearing hawaii shorts instead of trouses\",\"Now make this animal mascot standing on the beach with a starfish in it's hands, waring only hawaii shorts. Preserve the exact character features and style.\"]"}]}},"typeVersion":3.4},{"id":"913b8c79-e9ed-4221-853a-2ea6071f8c5a","name":"Run FLUX","type":"n8n-nodes-base.executeWorkflow","position":[1120,-100],"parameters":{"options":{},"workflowId":{"__rl":true,"mode":"list","value":"AdtCs47Lt1Wtf2Dt","cachedResultName":"Upload-Post And FLUX Kontext"},"workflowInputs":{"value":{},"schema":[],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":true}},"typeVersion":1.2},{"id":"8c7089e9-45ea-4626-9c7d-01dc9df2137e","name":"Current Step","type":"n8n-nodes-base.set","position":[880,0],"parameters":{"include":"selected","options":{},"assignments":{"assignments":[{"id":"64e9c28e-a60a-499b-aa89-177bf952959f","name":"prompt","type":"string","value":"={{ $json.Prompts[$runIndex] }}"},{"id":"aee3c455-ced2-4520-a088-18ffaf6db11c","name":"binaryin","type":"string","value":"=data{{ $runIndex }}"},{"id":"61cccca2-7b0c-4ea6-82f3-5dc2a377c3cb","name":"binaryout","type":"string","value":"=data{{ Number($runIndex)+1 }}"},{"id":"0cbe4309-e6f0-4c65-87f6-95bf6609aade","name":"currentstep","type":"number","value":"={{ $runIndex }}"}]},"includeFields":"Prompts, Steps","includeOtherFields":true},"typeVersion":3.4},{"id":"8eb4790f-ecf9-4136-813a-a87bd1d40edd","name":"Merge3","type":"n8n-nodes-base.merge","position":[1320,-20],"parameters":{"mode":"combine","options":{},"combineBy":"combineByPosition"},"typeVersion":3.2},{"id":"49eb0be4-4ebc-48bd-a77d-20fb02779ad1","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[620,-200],"parameters":{"width":860,"height":380,"content":"## Iterate over prompts\n- On each step a next prompt it taken from the original array\n- Outputs from the previous FLUX Kontext request are moved forward to the subsequent generation"},"typeVersion":1},{"id":"361cd8ac-29be-40a9-a5f8-d12656373c96","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[1100,220],"parameters":{"color":5,"width":260,"height":280,"content":"## [Post several images via Upload Post](https://www.upload-post.com/?linkId=lp_144414&sourceId=post-now&tenantId=upload-post-app)\n[Click to create your own account](https://www.upload-post.com/?linkId=lp_144414&sourceId=post-now&tenantId=upload-post-app)"},"typeVersion":1},{"id":"af34e5a7-d1cc-446f-a210-5aa96c271640","name":"Upload Post","type":"n8n-nodes-upload-post.uploadPost","position":[1120,340],"parameters":{"user":"Ed","title":"Testing n8n uploads with Upload Post community node hotfix and FLUX1. Kontext","photos":"={{ Array.from({length: $json.Steps}, (_, i) => `data${i + 1}`).join(',') }}","platform":["x"]},"credentials":{"uploadPostApi":{"id":"xLY6thqjSJUCWssD","name":"Upload Post account"}},"typeVersion":1},{"id":"32836601-6a7d-4e1a-9fc4-74d6f5f78187","name":"Image to Base64","type":"n8n-nodes-base.extractFromFile","position":[-200,400],"parameters":{"options":{},"operation":"binaryToPropery","destinationKey":"={{ $('When Executed by Another Workflow').first().json.binaryin }}","binaryPropertyName":"={{ $('When Executed by Another Workflow').first().json.binaryin }}"},"typeVersion":1},{"id":"d40118c7-0ab6-4276-b733-22419e5521d6","name":"Get Image","type":"n8n-nodes-base.httpRequest","position":[680,400],"parameters":{"url":"={{ $json.result.sample }}","options":{"response":{"response":{"responseFormat":"file","outputPropertyName":"={{ $('When Executed by Another Workflow').first().json.binaryout }}"}}}},"typeVersion":4.2},{"id":"e35f7544-b687-4ee5-a59f-3f98d26b1d12","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[620,-620],"parameters":{"width":260,"height":400,"content":"## Step 1\n![](https://pbs.twimg.com/media/Gs7SwU_XYAASZBn?format=jpg&name=medium)"},"typeVersion":1},{"id":"230498f5-69f5-4282-bb25-854720b1d536","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[920,-620],"parameters":{"width":260,"height":400,"content":"## Step 2\n![](https://pbs.twimg.com/media/Gs7SwovWQAAncQT?format=jpg&name=medium)"},"typeVersion":1},{"id":"425c3696-4532-401e-8131-78553358c8c8","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[1220,-620],"parameters":{"width":260,"height":400,"content":"## Step 3\n![](https://pbs.twimg.com/media/Gs7SxHsXYAAkhPF?format=jpg&name=medium)"},"typeVersion":1}],"active":false,"settings":{"callerPolicy":"workflowsFromSameOwner","executionOrder":"v1","saveDataSuccessExecution":"all"},"versionId":"94bff334-aee9-4139-acb9-966013fca4ea","connections":{"If":{"main":[[{"node":"Current Step","type":"main","index":0}],[{"node":"Upload Post","type":"main","index":0}]]},"Merge":{"main":[[{"node":"If","type":"main","index":0}]]},"Merge3":{"main":[[{"node":"If","type":"main","index":0}]]},"Run FLUX":{"main":[[{"node":"Merge3","type":"main","index":0}]]},"Is Ready?":{"main":[[{"node":"Get Image","type":"main","index":0}],[{"node":"Wait 2 sec","type":"main","index":0}]]},"Wait 2 sec":{"main":[[{"node":"Check FLUX status","type":"main","index":0}]]},"All Prompts":{"main":[[{"node":"Number of Steps","type":"main","index":0}]]},"Current Step":{"main":[[{"node":"Run FLUX","type":"main","index":0},{"node":"Merge3","type":"main","index":1}]]},"FLUX Kontext":{"main":[[{"node":"Wait 2 sec","type":"main","index":0}]]},"Image to Base64":{"main":[[{"node":"FLUX Kontext","type":"main","index":0}]]},"Number of Steps":{"main":[[{"node":"Merge","type":"main","index":0}]]},"Check FLUX status":{"main":[[{"node":"Is Ready?","type":"main","index":0}]]},"Get File from GitHub":{"main":[[{"node":"Download Initial Image","type":"main","index":0}]]},"Download Initial Image":{"main":[[{"node":"Merge","type":"main","index":1}]]},"When Executed by Another Workflow":{"main":[[{"node":"Image to Base64","type":"main","index":0}]]},"When clicking ‘Execute workflow’":{"main":[[{"node":"Get File from GitHub","type":"main","index":0},{"node":"All Prompts","type":"main","index":0}]]}}}


name: AI Premium Proposal Generator with OpenAI, Google Slides & PandaDoc
author_name: Nick Saraev
author_username: nicksaraev
categories: []
created_at: 2025-06-08T21:01:29.966Z
updated_at: 2025-06-08T21:01:29.966Z
url: https://n8n.io/workflows/4804
scraped_at: 2025-07-06 21:16:30
description:
  AI Proposal Generator System

  Categories*
  Sales Automation
  Document Generation
  AI Business Tools

  This workflow creates a complete AI-powered proposal generation system that transforms simple form inputs into professional, personalized proposals in under 30 seconds and can be deployed during live sales calls, allowing you to send polished proposals before the call even ends.

  Benefits*
  Instant Proposal Generation - Convert 30-second form inputs into professional proposals automatically
  High-Value Business Tool - Generates $1,500-$5,000 per client implementation
  Live Sales Integration - Generate and send proposals during active sales calls
  Complete Automation Pipeline - From form submission to email delivery with zero manual work
  Professional Presentation - Produces proposals indistinguishable from manually crafted documents
  Dual Platform Support - Works with both Google Slides (free) and PandaDoc (premium) integration

  How It Works*

  Smart Form Interface:

  Simple N8N form captures essential deal information
  Collects prospect details, problems, solutions, scope, timeline, and budget
  Designed for rapid completion during live sales conversations

  Advanced AI Processing:

  Uses sophisticated GPT-4 prompting with example-based training
  Converts basic form inputs into professionally written proposal sections
  Applies consistent tone, formatting, and business language automatically

  Dynamic Document Generation:

  Creates duplicate proposal templates for each new prospect
  Replaces template variables with AI-generated personalized content
  Maintains professional formatting and visual consistency

  Automated Email Delivery:

  Sends personalized email with proposal link immediately after generation
  Includes professional messaging and clear next steps
  Optionally includes invoice for immediate payment processing

  Premium PandaDoc Integration:

  Advanced version includes built-in payment processing
  Combines proposal, agreement, and invoice in single document
  Enables immediate signature and payment collection

  Business Use Cases*
  Service-Based Businesses - Generate proposals for consulting, agencies, and professional services
  Automation Agencies - Offer proposal generation as a high-value service to clients
  Sales Teams - Accelerate proposal creation and improve close rates
  Freelancers - Professionalize client interactions with instant custom proposals
  Consultants - Streamline business development with automated proposal workflows
  B2B Companies - Scale personalized proposal generation across entire sales organization

  Difficulty Level: Intermediate
  Estimated Build Time: 2-3 hours
  Monthly Operating Cost: $20-150 (depending on Google Slides vs PandaDoc)

  Watch My Complete Live Build*
  Want to see me build this entire $2,485 proposal system from scratch? I walk through every component live - including the AI prompting strategies, form design, Google Slides integration, and the advanced PandaDoc setup that enables payment collection.
  🎥 See My Live Build Process: "I Built A $2,485 AI Proposal Generator In N8N (Copy This)"
  This comprehensive tutorial shows the real development process - including advanced AI prompting, template design, API integrations, and the exact pricing strategy that generates $1,500-$5,000 per client.

  Required Template Setup*
  Google Slides Template: Create a professional proposal template with these variable placeholders (wrapped in double curly braces):
  {{proposalTitle}} - Main proposal heading
  {{descriptionName}} - Project subtitle/description
  {{oneParagraphProblemSummary}} - Problem analysis section
  {{solutionHeadingOne}}, {{solutionHeadingTwo}}, {{solutionHeadingThree}} - Solution titles
  {{shortScopeTitleOne}} through {{shortScopeTitleThree}} - Scope sections
  {{milestoneOneDay}} through {{milestoneFourDay}} - Timeline milestones
  {{cost}} - Project pricing
  Form Field Requirements: The N8N form must include these exact field labels:
  First Name, Last Name, Company Name, Email, Website
  Problem (textarea) - Client's current challenges
  Solution (textarea) - Your proposed approach
  Scope (textarea) - Specific deliverables
  Cost - Project pricing
  How soon? - Timeline expectations
  PandaDoc Setup (Premium): Configure PandaDoc template with token placeholders matching the AI-generated content structure. Template must include pricing tables and signature fields for complete proposal-to-payment automation.

  Set Up Steps*

  Form Design & Integration:

  Create N8N form with optimized fields for proposal generation
  Design form flow for rapid completion during sales calls
  Configure form triggers and data validation

  AI Content Generation Setup:

  Configure OpenAI API for sophisticated proposal writing
  Implement example-based training with input/output pairs
  Set up JSON formatting for structured content generation

  Google Slides Integration (Free Version):

  Create professional proposal templates with variable placeholders
  Set up Google Cloud Console API access and credentials
  Configure template duplication and text replacement workflows

  Email Automation Setup:


  Configure Gmail integration for automated proposal delivery
  Design professional email templates with proposal links
  Set up dynamic content insertion and personalization

  PandaDoc Integration (Premium Version):

  Set up PandaDoc API for advanced document generation
  Configure payment processing and signature collection
  Implement proposal-to-payment automation workflows

  Testing & Quality Control:

  Test complete workflow with various proposal scenarios
  Validate AI output quality and professional presentation
  Optimize form fields and content generation based on results

  Advanced Features*

  Premium system includes:
  Payment Processing Integration: Collect payments immediately after proposal acceptance
  Digital Signature Collection: Streamline agreement execution with electronic signatures
  Custom Branding: Apply company branding and visual identity automatically
  Multi-Template Support: Generate different proposal types based on service offerings
  CRM Integration: Automatically sync proposal data with existing sales systems

  Why This System Works*

  The competitive advantage lies in speed and professionalism:
  30-second generation time vs. hours of manual proposal writing
  Professional presentation that matches or exceeds manual proposals
  Live sales integration - send proposals during active conversations
  Consistent quality - eliminates human error and formatting inconsistencies
  Immediate follow-up - maintain sales momentum with instant delivery

  System Architecture*

  The workflow follows a simple but powerful 6-step process:
  Form Trigger - Captures essential deal information
  AI Processing - Converts inputs to professional content
  Template Duplication - Creates unique document for each prospect
  Content Replacement - Populates template with AI-generated content
  Email Delivery - Sends proposal with professional messaging
  Payment Collection (PandaDoc) - Enables immediate signature and payment

  Check Out My Channel*
  For more high-value automation systems and proven business-building strategies, explore my YouTube channel where I share the exact systems used to build successful automation businesses and scale to $72K+ monthly revenue.

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.googleDrive","n8n-nodes-base.gmail","n8n-nodes-base.googleSlides","@n8n/n8n-nodes-langchain.openAi"]

workflow_json:
  {"id":"x6UbWXr0iMgy1TEB","meta":{"instanceId":"d7661a849ead114a9aa6d9ceaf4160465aeb79532a35bde62160c840ffba9fc8"},"name":"AI Proposal Generator System","tags":[{"id":"l8MPK4ZirgwFWMno","name":"N8N Course","createdAt":"2025-01-23T18:12:52.273Z","updatedAt":"2025-01-23T18:12:52.273Z"}],"nodes":[{"id":"sticky-note-1","type":"n8n-nodes-base.stickyNote","position":[-60,-200],"parameters":{"width":350,"height":160,"content":"## 🚀 STEP 1: Sales Call Form\n\nCaptures essential deal information in under 30 seconds:\n\n**Form Fields:** Company details, problem description, proposed solution, project scope, timeline, and budget\n\n**Use Case:** Fill out during live sales calls for instant proposal generation\n\n**Result:** Structured data ready for AI processing"},"typeVersion":1},{"id":"sticky-note-2","type":"n8n-nodes-base.stickyNote","position":[120,-280],"parameters":{"width":380,"height":180,"content":"## 🧠 STEP 2: AI Content Generation\n\nTransforms basic form inputs into professional proposal content:\n\n**OpenAI Processing:** Uses sophisticated GPT-4 prompting with example-based training\n**Output:** 20+ proposal sections including titles, problem analysis, solutions, scope, and timelines\n**Quality:** Professional business language with consistent tone and formatting\n\n**Key:** AI converts 30-second inputs into comprehensive proposals"},"typeVersion":1},{"id":"sticky-note-3","type":"n8n-nodes-base.stickyNote","position":[450,-300],"parameters":{"width":400,"height":200,"content":"## 📄 STEP 3: Document Generation\n\n**Google Slides Path (Free):**\n1. **Google Drive:** Copies proposal template\n2. **Replace Text:** Populates template with AI-generated content\n3. **Gmail:** Sends proposal link via email\n\n**PandaDoc Path (Premium):**\n1. **HTTP Request:** Creates PandaDoc with payment integration\n2. **Gmail:** Sends proposal with signature + payment capabilities\n\n**Result:** Professional proposals ready for client review"},"typeVersion":1},{"id":"sticky-note-4","type":"n8n-nodes-base.stickyNote","position":[800,-200],"parameters":{"width":350,"height":160,"content":"## ⚡ WORKFLOW ADVANTAGES\n\n**Speed:** Generate proposals in under 30 seconds during live calls\n**Quality:** AI ensures consistent, professional presentation\n**Dual Options:** Free Google Slides or premium PandaDoc with payments\n**Revenue:** Proven $1,500-$5,000 per implementation\n\n**Business Impact:** Send proposals before competitors even schedule follow-ups"},"typeVersion":1},{"id":"65eec1e0-5e75-4544-b1d2-ee686d419edd","name":"Replace Text","type":"n8n-nodes-base.googleSlides","position":[700,0],"parameters":{"textUi":{"textValues":[{"text":"{{proposalTitle}}","replaceText":"={{ $('OpenAI').item.json.message.content.proposalTitle }}"},{"text":"{{descriptionName}}","replaceText":"={{ $('OpenAI').item.json.message.content.descriptionName }}"},{"text":"{{oneParagraphProblemSummary}}","replaceText":"={{ $('OpenAI').item.json.message.content.oneParagraphProblemSummary }}"},{"text":"{{solutionHeadingOne}}","replaceText":"={{ $('OpenAI').item.json.message.content.solutionHeadingOne }}"},{"text":"{{solutionHeadingTwo}}","replaceText":"={{ $('OpenAI').item.json.message.content.solutionHeadingTwo }}"},{"text":"{{solutionHeadingThree}}","replaceText":"={{ $('OpenAI').item.json.message.content.solutionHeadingThree }}"},{"text":"{{solutionDescriptionOne}}","replaceText":"={{ $('OpenAI').item.json.message.content.solutionDescriptionOne }}"},{"text":"{{solutionDescriptionTwo}}","replaceText":"={{ $('OpenAI').item.json.message.content.solutionDescriptionTwo }}"},{"text":"{{solutionDescriptionThree}}","replaceText":"={{ $('OpenAI').item.json.message.content.solutionDescriptionThree }}"},{"text":"{{shortScopeTitleOne}}","replaceText":"={{ $('OpenAI').item.json.message.content.shortScopeTitleOne }}"},{"text":"{{shortScopeTitleTwo}}","replaceText":"={{ $('OpenAI').item.json.message.content.shortScopeTitleTwo }}"},{"text":"{{shortScopeTitleThree}}","replaceText":"={{ $('OpenAI').item.json.message.content.shortScopeTitleThree }}"},{"text":"{{shortScopeDescriptionOne}}","replaceText":"={{ $('OpenAI').item.json.message.content.shortScopeDescriptionOne }}"},{"text":"{{shortScopeDescriptionTwo}}","replaceText":"={{ $('OpenAI').item.json.message.content.shortScopeDescriptionTwo }}"},{"text":"{{shortScopeDescriptionThree}}","replaceText":"={{ $('OpenAI').item.json.message.content.shortScopeDescriptionThree }}"},{"text":"{{milestoneOneDay}}","replaceText":"={{ $('OpenAI').item.json.message.content.milestoneOneDay }}"},{"text":"{{milestoneTwoDay}}","replaceText":"={{ $('OpenAI').item.json.message.content.milestoneTwoDay }}"},{"text":"{{milestoneThreeDay}}","replaceText":"={{ $('OpenAI').item.json.message.content.milestoneThreeDay }}"},{"text":"{{milestoneFourDay}}","replaceText":"={{ $('OpenAI').item.json.message.content.milestoneFourDay }}"},{"text":"{{milestoneDescriptionOne}}","replaceText":"={{ $('OpenAI').item.json.message.content.milestoneDescriptionOne }}"},{"text":"{{milestoneDescriptionTwo}}","replaceText":"={{ $('OpenAI').item.json.message.content.milestoneDescriptionTwo }}"},{"text":"{{milestoneDescriptionThree}}","replaceText":"={{ $('OpenAI').item.json.message.content.milestoneDescriptionThree }}"},{"text":"{{milestoneDescriptionFour}}","replaceText":"={{ $('OpenAI').item.json.message.content.milestoneDescriptionFour }}"},{"text":"{{cost}}","replaceText":"$1,850"}]},"options":{},"operation":"replaceText","presentationId":"={{ $json.id }}"},"credentials":{"googleSlidesOAuth2Api":{"id":"ie4yCWIQ8AYXFVxa","name":"YouTube"}},"typeVersion":2},{"id":"618c4452-06f4-4f95-8777-a6e6f204bf33","name":"OpenAI","type":"@n8n/n8n-nodes-langchain.openAi","position":[160,0],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4o","cachedResultName":"GPT-4O"},"options":{},"messages":{"values":[{"role":"system","content":"You are a helpful, intelligent writing assistant."},{"content":"Your task is to generate a proposal using input data from a form. This proposal should be highly customized, specific, and high-quality, considering we're going to be sending it immediately after you're done.\n\nContext: we are an automation/no-code agency that develops systems revolving around growth, revenue ops, etc.\n\nThe proposal template we're using has many fields. You must return these fields in one JSON object.\n\nUse this format:\n\n{\n  \"proposalTitle\": \"\",\n  \"descriptionName\": \"\",\n  \"oneParagraphProblemSummary\": \"\",\n  \"solutionHeadingOne\": \"\",\n  \"solutionDescriptionOne\": \"\",\n  \"solutionHeadingTwo\": \"\",\n  \"solutionDescriptionTwo\": \"\",\n  \"solutionHeadingThree\": \"\",\n  \"solutionDescriptionThree\":\"\",\n  \"shortScopeTitleOne\": \"\",\n  \"shortScopeTitleTwo\": \"\",\n  \"shortScopeTitleThree\": \"\",\n  \"shortScopeDescriptionOne\": \"\",\n  \"shortScopeDescriptionTwo\": \"\",\n  \"shortScopeDescriptionThree\": \"\",\n  \"milestoneOneDay\": \"\",\n  \"milestoneTwoDay\": \"\",\n  \"milestoneThreeDay\": \"\",\n  \"milestoneFourDay\": \"\",\n  \"milestoneDescriptionOne\": \"\",\n  \"milestoneDescriptionTwo\": \"\",\n  \"milestoneDescriptionThree\": \"\",\n  \"milestoneDescriptionFour\": \"\"\n}\n\nRules:\n1. Use a spartan, casual tone of voice.\n2. Be to-the-point but professional—assume you're writing to a sophisticated audience.\n3. Ensure that all fields are filled out. Do not miss a field or leave any variables empty.\n4. Keep things short. If a field contains the term \"Description\" it should be no more than fourteen words. For \"descriptionName\" do not use title case."},{"content":"{\n  \"companyName\":\"1SecondCopy\",\n  \"problem\": \"they can't generate leads. everything is referral based rn.\",\n  \"solution\": \"cold email lead gen system, client reactivation system, and best in class sales training for closing\",\n  \"scope\": \"1k/day cold email infra, 30k email leads, 4 weekly zoom sessions for sales training\",\n  \"currentDate\":\"Feb 4 2025\",\n  \"howSoon\": \"two months\",\n  \"depositCost\": \"$1,845\",\n}"},{"role":"assistant","content":"{\n  \"proposalTitle\": \"Lead Gen System for 1SecondCopy\n\",\n  \"descriptionName\": \"A simple, scalable lead generation system built to help grow your content efforts & connect you with the right people.\n\",\n  \"oneParagraphProblemSummary\": \"Right now, 1SecondCopy is struggling with an inability to generate qualified leads. The majority of your new clients are referral-based, which, while always nice to have, is not scalable nor is it reliable. Building an alternative strategy—one that allows you to take leads from cold -> close—is vital to the health and longevity of the company, and it’s what we’re going to help you with.\n\",\n  \"solutionHeadingOne\": \"Cold Outbound Lead Gen\",\n  \"solutionDescriptionOne\": \"We’ll put in place a robust cold-email-based system for you using best practices.\",\n  \"solutionHeadingTwo\": \"Client Reactivation System\",\n  \"solutionDescriptionTwo\": \"We’ll build a simple, but high-ROI reactivation system to let you extract value from pre-existing clients.\",\n  \"solutionHeadingThree\": \"Best-In-Class Sales Training\",\n  \"solutionDescriptionThree\": \"We’ll train your team with world-class setting & closing mechanisms.\",\n  \"shortScopeTitleOne\": Cold email infrastructure that sends ~1K emails/day\",\n  \"shortScopeTitleTwo\": \"30K high-quality scraped email leads (included)\",\n  \"shortScopeTitleThree\": \"Four weekly one-hour sales training sessions over Zoom\",\n  \"shortScopeDescriptionOne\": \"12 domains, 36 mailboxes, DNS optimization, and warmups included.\",\n  \"shortScopeDescriptionTwo\": \"30,000 leads in your target market, delivered by CSV.\",\n  \"shortScopeDescriptionThree\": \"We’ll take your sales team from 0->1.\",\n  \"milestoneOneDay\": \"February 8th, 2025\",\n  \"milestoneTwoDay\": \"February 28th, 2025\",\n  \"milestoneThreeDay\": \"March 10th, 2025\",\n  \"milestoneFourDay\":\"March 17th-April 1st, 2025\",\n  \"milestoneDescriptionOne\": \"Cold email system done & ready for warmup.\",\n  \"milestoneDescriptionTwo\": \"Cold email system fully warmed up & operational.\",\n  \"milestoneDescriptionThree\": \"10,000 outbound emails sent; analysis & training #1.\"\n  \"milestoneDescriptionFour\":\"One sales training per week alongside iteration & handoff.\"\n}"},{"content":"={\n  \"companyName\":\"{{ $json['Company Name'] }}\",\n  \"problem\": \"{{ $json.Problem }}\",\n  \"solution\": \"{{ $json.Solution}}\",\n  \"scope\": \"{{ $json.Scope }}\",\n  \"currentDate\":\"{{ $now.toLocaleString({ dateStyle: 'medium' }) }}\",\n  \"howSoon\": \"{{ $json['How soon?'] }}\",\n  \"depositCost\": \"{{ $json.Cost }}\",\n}"}]},"jsonOutput":true},"credentials":{"openAiApi":{"id":"oLLACDYfGm4C4ouV","name":"YouTube "}},"typeVersion":1.6},{"id":"850e7d84-2001-421f-a8a2-aa9aa64f06b9","name":"Google Drive","type":"n8n-nodes-base.googleDrive","position":[500,0],"parameters":{"name":"={{ $json.message.content.proposalTitle }}","fileId":{"__rl":true,"mode":"id","value":"1fHzjDQtZouAwfv4kn5uvgpTWqwhTAlPrGkdtkbYBkNE"},"options":{"copyRequiresWriterPermission":false},"operation":"copy"},"credentials":{"googleDriveOAuth2Api":{"id":"8R2NiLt8owCA0E2O","name":"Google Drive account"}},"typeVersion":3},{"id":"dda7e0fa-e8cc-40a8-8af5-9f22b70f4752","name":"Gmail","type":"n8n-nodes-base.gmail","position":[900,0],"webhookId":"b989215e-e975-44a7-9dc7-fd51e7310cba","parameters":{"sendTo":"={{ $('On form submission').item.json.Email }}","message":"=Hey Nick,\n\nThanks for the great call earlier. I had a moment after our chat to put together a detailed proposal for you—please take a look at your earliest convenience and let me know your thoughts.\n\nYou'll find it here: https://docs.google.com/presentation/d/{{ $json.presentationId }}/edit\n\nIf you have any questions, just shout. I've also sent over an invoice for the project (just to keep things convenient) and can get started anytime that's sorted.\n\nThanks,\nNick","options":{"appendAttribution":false},"subject":"Re: Proposal for LeftClick","emailType":"text"},"credentials":{"gmailOAuth2":{"id":"YqmvyP5s2u0IHOHB","name":"Gmail account 3"}},"typeVersion":2.1},{"id":"2d9e8695-d112-40a7-810a-94f3b3919382","name":"On form submission","type":"n8n-nodes-base.formTrigger","position":[-20,0],"webhookId":"24fd835d-9132-4faf-b715-755e75aee9be","parameters":{"options":{"appendAttribution":false},"formTitle":"Sales Call Logging Form","formFields":{"values":[{"fieldLabel":"First Name","requiredField":true},{"fieldLabel":"Last Name","requiredField":true},{"fieldLabel":"Company Name","requiredField":true},{"fieldType":"email","fieldLabel":"Email"},{"fieldLabel":"Website","requiredField":true},{"fieldType":"textarea","fieldLabel":"Problem","requiredField":true},{"fieldType":"textarea","fieldLabel":"Solution","requiredField":true},{"fieldType":"textarea","fieldLabel":"Scope","requiredField":true},{"fieldLabel":"Cost","requiredField":true},{"fieldLabel":"How soon?","requiredField":true}]},"formDescription":"This form logs a sales call & automatically generates a proposal."},"typeVersion":2.2},{"id":"bc1bf3dd-7261-4f56-a71b-236fbde109ff","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-60,-100],"parameters":{"width":1220,"height":280,"content":"## Google Slides AI Proposal Generator\n**This flow generates proposals using the free Google Slides solution**."},"typeVersion":1},{"id":"d59a6b99-e112-424c-b6e5-3eeb92a1c784","name":"OpenAI1","type":"@n8n/n8n-nodes-langchain.openAi","position":[160,460],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4o","cachedResultName":"GPT-4O"},"options":{},"messages":{"values":[{"role":"system","content":"You are a helpful, intelligent writing assistant."},{"content":"=Your task is to generate a proposal using input data from a form. This proposal should be highly customized, specific, and high-quality, considering we're going to be sending it immediately after you're done.\n\nContext: we are an automation/no-code agency that develops systems revolving around growth, revenue ops, etc.\n\nThe proposal template we're using has many fields. You must return these fields in one JSON object.\n\nUse this format:\n\n{\n  \"proposalTitle\": \"\",\n  \"descriptionName\": \"\",\n  \"problemTitle\": \"\",\n  \"oneParagraphProblemSummary\": \"\",\n  \"solutionTitle\": \"\",\n  \"solutionText\": \"\",\n  \"scopeOne\": \"\",\n  \"scopeTwo\": \"\",\n  \"scopeThree\": \"\",\n  \"scopeFour\": \"\",\n  \"scopeFive\": \"\",\n  \"timelineOne\": \"\",\n  \"timelineTwo\": \"\",\n  \"timelineThree\": \"\",\n  \"timelineFour\": \"\"\n}\n\nRules:\n1. Use a spartan, casual tone of voice.\n2. Be to-the-point but professional—assume you're writing to a sophisticated audience.\n3. Ensure that all fields are filled out. Do not miss a field or leave any variables empty.\n4. For oneParagraphProblemSummary and solutionText, make sure to number the responses (usually 3, make sure they're inside of the string)."},{"content":"={\n  \"companyName\":\"1SecondCopy\",\n  \"problem\": \"they can't generate leads. everything is referral based rn.\",\n  \"solution\": \"cold email lead gen system, client reactivation system, and best in class sales training for closing\",\n  \"scope\": \"1k/day cold email infra, 30k email leads, 4 weekly zoom sessions for sales training\",\n  \"currentDate\":\"Feb 4 2025\",\n  \"howSoon\": \"two months\",\n  \"depositCost\": \"$1,845\",\n}"},{"role":"assistant","content":"={\n  \"proposalTitle\": \"Lead Gen System for 1SecondCopy\n\",\n  \"descriptionName\": \"A simple, scalable lead generation system built to help grow your content efforts & connect you with the right people.\n\",\n  \"problemTitle\":\"Inability to generate leads\"\n  \"oneParagraphProblemSummary\": \"Right now, 1SecondCopy is struggling with:\\n\\n 1. An inability to generate qualified leads.\\nThe majority of your new clients are referral-based, which, while always nice to have, is not scalable nor is it reliable. Building an alternative strategy—one that allows you to take leads from cold -> close—is vital to the health and longevity of the company, and it’s what we’re going to help you with.\\n\\n 2. No standardized followup mechanism.\\nWithout a way to follow up with leads, you're leaving the majority of the money that one of those leads could produce for you on the table.\n\",\n  \"solutionTitle\": \"Sales & Lead Generation Solutions\",\n  \"solutionText\": \"1. Cold Outbound Lead Gen\\nIn order to generate leads efficiently, we’ll put in place a robust cold-email-based system for you using best practices.\\n\\n2. Client Reactivation System\\nIn order to extract value from pre-existing clients, we’ll build a simple but high-ROI reactivation system.\\n\\n3. Best-In-Class Sales Training\\nIn order to improve conversion rates, we’ll train your team with world-class setting & closing mechanisms.\"\n  \"scopeOne\":\"We'll create a database to store both videos and competitors.\",\n  \"scopeTwo\":\"We'll create a simple form to quickly add competitors to your database.\",\n  \"scopeThree\":\"We'll build a daily flow that automatically generates video outlines based on the scrapes.\",\n  \"scopeFour\":\"We'll record documentation showing you how to manage and update the system.\",\n  \"scopeFive\":\"We'll provide one, two-hour team training session to teach your company how to use the system.\",\n  \"timelineOne\": \"Cold email system done & ready for warmup: February 8th, 2025\",\n  \"timelineTwo\": \"Cold email system fully warmed up & operational: February 28th, 2025\",\n  \"timelineThree\": \"10,000 outbound emails sent; analysis & training #1: March 10th, 2025\",\n  \"timelineFour\":\"One sales training per week alongside iteration & handoff: March 17th-April 1st, 2025\",\n}"},{"content":"={\n  \"companyName\":\"{{ $json['Company Name'] }}\",\n  \"problem\": \"{{ $json.Problem }}\",\n  \"solution\": \"{{ $json.Solution}}\",\n  \"scope\": \"{{ $json.Scope }}\",\n  \"currentDate\":\"{{ $now.toLocaleString({ dateStyle: 'medium' }) }}\",\n  \"howSoon\": \"{{ $json['How soon?'] }}\",\n  \"depositCost\": \"{{ $json.Cost }}\",\n}"}]},"jsonOutput":true},"credentials":{"openAiApi":{"id":"oLLACDYfGm4C4ouV","name":"YouTube "}},"typeVersion":1.6},{"id":"66ec15ea-ba46-4aad-993a-e0b9cefde871","name":"Gmail1","type":"n8n-nodes-base.gmail","position":[740,460],"webhookId":"470caaaa-62ff-4468-973d-4b1082cfe57a","parameters":{"sendTo":"={{ $('On form submission1').item.json.Email }}","message":"=Hey Nick,\n\nThanks for the great call earlier. I had a moment after our chat to put together a detailed proposal for you—please take a look at your earliest convenience and let me know your thoughts.\n\nYou'll find it here: https://docs.google.com/presentation/d/{{ $json.presentationId }}/edit\n\nIf you have any questions, just shout. I've also sent over an invoice for the project (just to keep things convenient) and can get started anytime that's sorted.\n\nThanks,\nNick","options":{"appendAttribution":false},"subject":"Re: Proposal for LeftClick","emailType":"text"},"credentials":{"gmailOAuth2":{"id":"YqmvyP5s2u0IHOHB","name":"Gmail account 3"}},"typeVersion":2.1},{"id":"89833949-672b-4120-94fe-2f5b9b8b21de","name":"On form submission1","type":"n8n-nodes-base.formTrigger","position":[-20,460],"webhookId":"f0e8d4a0-8002-4804-aa90-4566fef26283","parameters":{"options":{"appendAttribution":false},"formTitle":"Sales Call Logging Form","formFields":{"values":[{"fieldLabel":"First Name","requiredField":true},{"fieldLabel":"Last Name","requiredField":true},{"fieldLabel":"Company Name","requiredField":true},{"fieldType":"email","fieldLabel":"Email"},{"fieldLabel":"Website","requiredField":true},{"fieldType":"textarea","fieldLabel":"Problem","requiredField":true},{"fieldType":"textarea","fieldLabel":"Solution","requiredField":true},{"fieldType":"textarea","fieldLabel":"Scope","requiredField":true},{"fieldLabel":"Cost","requiredField":true},{"fieldLabel":"How soon?","requiredField":true}]},"formDescription":"This form logs a sales call & automatically generates a proposal."},"typeVersion":2.2},{"id":"5cf9ca5e-2ffa-492f-899f-4668786dabbd","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-60,360],"parameters":{"width":1220,"height":280,"content":"## PandaDoc AI Proposal Generator\n**This flow generates proposals using the paid PandaDoc solution, and also sends an invoice alongside it**."},"typeVersion":1},{"id":"6b8e90ef-c520-40b6-9ec6-a7d422763d8a","name":"HTTP Request","type":"n8n-nodes-base.httpRequest","position":[520,460],"parameters":{"url":"https://api.pandadoc.com/public/v1/documents/","method":"POST","options":{},"jsonBody":"={\n    \"name\": \"{{ $json.message.content.proposalTitle }}\",\n    \"fields\": {\n        \"Initials\": {\n            \"value\": \"EI\"\n        }\n    },\n    \"tokens\": [\n        {\n            \"name\": \"Client.Email\",\n            \"value\": \"{{ $('On form submission1').item.json.Email }}\"\n        },\n        {\n            \"name\": \"Sender.Email\",\n            \"value\": \"nick@leftclick.ai\"\n        },\n        {\n            \"name\": \"Client.Scope1\",\n            \"value\": \"{{ $json.message.content.scopeOne }}\"\n        },\n        {\n            \"name\": \"Client.Scope2\",\n            \"value\": \"{{ $json.message.content.scopeTwo }}\"\n        },\n        {\n            \"name\": \"Client.Scope3\",\n            \"value\": \"{{ $json.message.content.scopeThree }}\"\n        },\n        {\n            \"name\": \"Client.Scope4\",\n            \"value\": \"{{ $json.message.content.scopeFour }}\"\n        },\n        {\n            \"name\": \"Client.Scope5\",\n            \"value\": \"{{ $json.message.content.scopeFive }}\"\n        },\n        {\n            \"name\": \"Client.Company\",\n            \"value\": \"{{ $('On form submission1').item.json['Company Name'] }}\"\n        },\n        {\n            \"name\": \"Sender.Company\",\n            \"value\": \"WorkflowLoop\"\n        },\n        {\n            \"name\": \"Client.LastName\",\n            \"value\": \"{{ $('On form submission1').item.json['Last Name'] }}\"\n        },\n        {\n            \"name\": \"Sender.LastName\",\n            \"value\": \"Saraev\"\n        },\n        {\n            \"name\": \"Client.FirstName\",\n            \"value\": \"{{ $('On form submission1').item.json['First Name'] }}\"\n        },\n        {\n            \"name\": \"Client.Timeline1\",\n            \"value\": \"{{ $json.message.content.timelineOne }}\"\n        },\n        {\n            \"name\": \"Client.Timeline2\",\n            \"value\": \"{{ $json.message.content.timelineTwo }}\"\n        },\n        {\n            \"name\": \"Client.Timeline3\",\n            \"value\": \"{{ $json.message.content.timelineThree }}\"\n        },\n        {\n            \"name\": \"Client.Timeline4\",\n            \"value\": \"{{ $json.message.content.timelineFour }}\"\n        },\n        {\n            \"name\": \"Sender.FirstName\",\n            \"value\": \"Nick\"\n        },\n        {\n            \"name\": \"Client.ProblemText\",\n            \"value\": \"{{ $json.message.content.oneParagraphProblemSummary }}\"\n        },\n        {\n            \"name\": \"Client.ProblemTitle\",\n            \"value\": \"{{ $json.message.content.problemTitle }}\"\n        },\n        {\n            \"name\": \"Client.SolutionText\",\n            \"value\": {{ JSON.stringify($json.message.content.solutionText) }}\n        },\n        {\n            \"name\": \"Client.ProposalTitle\",\n            \"value\": \"{{ $json.message.content.proposalTitle }}\"\n        },\n        {\n            \"name\": \"Client.SolutionTitle\",\n            \"value\": \"{{ $json.message.content.solutionTitle }}\"\n        }\n    ],\n    \"metadata\": {},\n    \"recipients\": [\n        {\n            \"email\": \"{{ $('On form submission1').item.json.Email }}\",\n            \"role\": \"Client\"\n        },\n        {\n            \"email\": \"nick@leftclick.ai\",\n            \"company\": \"WorkflowLoop\",\n            \"last_name\": \"Saraev\",\n            \"first_name\": \"Nick\",\n            \"role\": \"Sender\"\n        }\n    ],\n    \"template_uuid\": \"yxge9HxfgWhvqKjFXwWEpS\",\n    \"pricing_tables\": [\n        {\n            \"name\": \"Pricing Table 1\",\n            \"options\": {\n                \"currency\": \"USD\"\n            },\n            \"sections\": [\n                {\n                    \"rows\": [\n                        {\n                            \"data\": {\n                                \"qty\": 1,\n                                \"name\": \"{{ $json.message.content.proposalTitle }}\",\n                                \"price\": {{ $('On form submission1').item.json.Cost.replace(\"$\",\"\").replace(\",\",\"\").toNumber() }}\n                            },\n                            \"options\": {\n                                \"optional\": false,\n                                \"qty_editable\": false,\n                                \"optional_selected\": false\n                            }\n                        }\n                    ],\n                    \"title\": \"Pricing Section\",\n                    \"default\": true\n                }\n            ]\n        }\n    ]\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"Authorization","value":"API-Key {yourApiKeyGoesHere}"},{"name":"accept","value":"application/json"}]}},"typeVersion":4.2}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"2452f9ed-c796-4e03-89c6-f7c735b77966","connections":{"OpenAI":{"main":[[{"node":"Google Drive","type":"main","index":0}]]},"OpenAI1":{"main":[[{"node":"HTTP Request","type":"main","index":0}]]},"Google Drive":{"main":[[{"node":"Replace Text","type":"main","index":0}]]},"HTTP Request":{"main":[[{"node":"Gmail1","type":"main","index":0}]]},"Replace Text":{"main":[[{"node":"Gmail","type":"main","index":0}]]},"On form submission":{"main":[[]]},"On form submission1":{"main":[[{"node":"OpenAI1","type":"main","index":0}]]}}}


