# templates

name: Process Legal Documents with Ollama AI & Generate HTML Reports (100% Local)
author_name: Rish
author_username: b2brish
nodes_used: ["@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOllama"]
categories: []
created_at: 2025-06-11T08:09:42.500Z
updated_at: 2025-06-11T08:09:42.500Z
url: https://n8n.io/workflows/4869
scraped_at: 2025-07-06 21:16:30
description:
  TUTORIAL VIDEO

  Key Features
  🧠 AI-Powered Analysis - Use any Ollama-compatible model (Llama, Mistral, CodeLlama, etc.)
  🔧 Flexible Input - Supports PDFs, Word docs, text files, and more
  📊 Structured Output - Generates clean HTML reports and summaries
  🔄 Automated Pipeline - Set-and-forget document processing

  Perfect For:
  Enterprise Environments - Where data privacy is paramount
  Research Organizations - Processing sensitive or proprietary documents
  Small Teams - Cost-effective alternative to cloud AI services
  Compliance-Heavy Industries - Healthcare, finance, legal where data must stay local
  Developers - Experimenting with different open-source models
  Content Teams - Batch processing large document libraries

  Prerequisites

  n8n instance (self-hosted recommended)
  Ollama server running locally
  Compatible AI models downloaded (Llama 3.1, Mistral, etc.)
  Local file system access
  Documents to process

  Customization Ideas
  🎯 Multi-Model Pipeline - Route different document types to specialized models
  🌐 Language Detection - Automatically select appropriate language models
  ⚡ Batch Processing - Handle multiple files simultaneously
  🎖️ Quality Scoring - Use multiple models to cross-validate outputs
  ✏️ Custom Prompts - Tailor analysis for specific document types or industries
  🔗 Integration Hooks - Connect to databases, CMS, or notification systems

  Why Choose Local Processing?
  🏆 Data Sovereignty - Your sensitive documents never leave your control
  💰 Predictable Costs - No surprise API bills or usage limits
  🎨 Customization Freedom - Fine-tune models for your specific use cases
  📶 Offline Capability - Works without internet connectivity
  ✅ Compliance Ready - Meets strict data residency requirements

  Conclusion
  This workflow represents the future of document processing - combining the convenience of automation with the security and control of local AI models. It's particularly valuable for organizations that need to balance AI capabilities with strict data governance requirements.
  Ready to build your own private AI document processing pipeline? This workflow shows you exactly how to get started with local Ollama integration! 🏠🤖

workflow_json:
  {"id":"rqu4dt6kaPwKplr3","meta":{"instanceId":"060085c5d2eea8c0bf2c51c6e5fdf206613403cbbbc1f8a472a4dcb6e3e29fdf","templateCredsSetupCompleted":true},"name":"Local PDF","tags":[],"nodes":[{"id":"cffc6896-7d35-4183-af3b-4e139199f2e2","name":"Extract from File","type":"n8n-nodes-base.extractFromFile","position":[-600,-80],"parameters":{},"typeVersion":1},{"id":"a0b0bbe8-796d-4ea5-9eaf-d958f72cc79f","name":"Local File Trigger","type":"n8n-nodes-base.localFileTrigger","position":[-1040,-80],"parameters":{},"typeVersion":1},{"id":"f79e5605-677d-4205-8d6d-1b7b4c3bda04","name":"Read/Write Files from Disk","type":"n8n-nodes-base.readWriteFile","position":[-820,-80],"parameters":{},"typeVersion":1},{"id":"5c5b052c-5e09-423c-b5c4-27408986f36b","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[-380,-80],"parameters":{},"typeVersion":2},{"id":"8e5108d3-8041-4032-ba14-65c385def2cd","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-360,200],"parameters":{},"typeVersion":1.2},{"id":"f10e2d2f-c21b-46ed-a36c-2fcc883846ff","name":"Convert to File","type":"n8n-nodes-base.convertToFile","position":[-4,-80],"parameters":{},"typeVersion":1.1},{"id":"73f9871a-a759-4de0-8561-68418e2c1e91","name":"Read/Write Files from Disk1","type":"n8n-nodes-base.readWriteFile","position":[216,-80],"parameters":{},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"84fddb7f-1243-4894-903c-024e89c3b9cb","connections":{"AI Agent":{"main":[[{"node":"Convert to File","type":"main","index":0}]]},"Convert to File":{"main":[[{"node":"Read/Write Files from Disk1","type":"main","index":0}]]},"Extract from File":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Local File Trigger":{"main":[[{"node":"Read/Write Files from Disk","type":"main","index":0}]]},"Read/Write Files from Disk":{"main":[[{"node":"Extract from File","type":"main","index":0}]]},"Read/Write Files from Disk1":{"main":[[]]}}}


name: Automated Multilingual Gmail Draft Reply with OpenAI GPT-4o
author_name: Henry
author_username: henry
categories: []
created_at: 2025-06-11T08:11:17.450Z
updated_at: 2025-06-11T08:11:17.450Z
url: https://n8n.io/workflows/4870
scraped_at: 2025-07-06 21:16:30
description:
  Automated Multilingual Gmail Draft Reply with OpenAI GPT-4o in n8n

  Who is this for?
  This workflow is ideal for anyone who receives a high volume of Gmail inquiries, especially those providing multilingual customer support or handling diverse client 
  communications.

  What problem is this workflow solving? 
  Managing frequent emails in multiple languages can be overwhelming. This workflow reduces manual drafting by automatically generating context-aware replies using OpenAI GPT-4o, letting users focus on personalization and quality assurance.

  What this workflow does
  Monitors your Gmail inbox for new emails with a specific label (e.g., "Inquiry").
  Uses OpenAI GPT-4o for message assessment and language detection.
  Parses information using a JSON parser.
  Generates an AI-powered draft reply in the detected language via OpenAI GPT-4o.
  Converts the reply to HTML and saves it as a draft in the original Gmail thread for your review.

  Setup
  Connect your Gmail account and set up relevant labels in both Gmail and the workflow.
  Integrate your OpenAI credentials in n8n.
  Configure the workflow trigger for your desired labels.

  How to customize this workflow to your needs
  Adjust label names in both Gmail and the workflow for different email categories.
  Define custom starting and ending phrases for draft replies per supported language.
  Expand supported languages or modify AI prompt instructions to suit your brand’s tone.

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

workflow_json:
  {"id":"OskjNtIb2AnxHXP2","meta":{"instanceId":"1af8a0dc0d2f537b7c08209af728c271b5a03806bdf309bedf99d668f2608ee6","templateCredsSetupCompleted":true},"name":"Automated Multilingual Gmail Draft Reply with OpenAI GPT-4o in n8n","tags":[{"id":"UXY9NrpVC8pjYHmK","name":"n8n Template","createdAt":"2025-06-05T07:41:37.020Z","updatedAt":"2025-06-05T07:41:37.020Z"}],"nodes":[{"id":"579d54f2-8c04-4624-890a-c432d96f3911","name":"If Needs Reply","type":"n8n-nodes-base.if","position":[1500,220],"parameters":{"options":{},"conditions":{"options":{"version":1,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"53849246-ad32-4845-9976-9f9688f5a6f2","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.needsReply }}","rightValue":"true"}]}},"typeVersion":2},{"id":"526ab96e-bf2a-44f5-9e1b-3b1a10b5f55b","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[580,0],"parameters":{"width":444,"height":434,"content":"### Gmail Trigger\n\nGet new incoming messages from Gmail with a specific label.\n\nIn this example, the \"Inquiry\" label is used. Feel free to set it up using other Gmail filters.\n\n⚠️ Adjust the time (polling) interval according to your needs.\n"},"typeVersion":1},{"id":"7289a14b-225e-4399-aa6c-cb56158f450d","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[1100,0],"parameters":{"width":576,"height":577,"content":"### Assess the email contents that need a reply\n\nThis assessment uses OpenAI GPT-4o and a JSON parser to determine whether a response is necessary and to identify the message’s language."},"typeVersion":1},{"id":"d10724dd-406c-4143-9c22-2c3ecd45e6be","name":"Gmail - Create Draft","type":"n8n-nodes-base.gmail","position":[2760,160],"webhookId":"a39b80e1-12c5-4569-aa46-63a2c2bd2d13","parameters":{"message":"={{ $json.text.replace(/\\n/g, \"<br />\\n\") }}","options":{"sendTo":"={{ $('Gmail trigger').item.json.headers.from }}","threadId":"={{ $('Gmail trigger').item.json.threadId }}"},"subject":"=Re: {{ $('Gmail trigger').item.json.headers.subject }}","resource":"draft","emailType":"html"},"credentials":{"gmailOAuth2":{"id":"2pW13S2GyP5GCdoP","name":"Gmail account"}},"typeVersion":2.1},{"id":"b805dfdb-a68e-458f-9af9-8a9e773a951d","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[2660,0],"parameters":{"width":326,"height":395,"content":"### Create a Draft in the conversation\n\nDraft Integration: after converting the text to html, it places the draft into the Gmail thread as a reply to the first message"},"typeVersion":1},{"id":"cbb5c6a6-a445-474b-890f-54d1a546c28a","name":"Switch based on email language","type":"n8n-nodes-base.switch","position":[1840,200],"parameters":{"rules":{"values":[{"outputKey":"Japanese version","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"b9788587-ad2a-4d44-bf01-f31c9412a48d","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.message_language }}","rightValue":"Japanese"}]},"renameOutput":true},{"outputKey":"English version","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"429c0f4a-b5f8-4730-9609-40fe20acd496","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.message_language }}","rightValue":"English"}]},"renameOutput":true}]},"options":{"fallbackOutput":1}},"typeVersion":3.2},{"id":"a720280e-7c5f-4f83-ad2e-b13572cba762","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1760,0],"parameters":{"width":813,"height":740,"content":"### Generate a Reply\n\nDefine the output from the Switch node. Then, generate a draft reply using OpenAI GPT-4 Turbo based on the message’s detected language. Establish the rules and conventions for each supported language, including appropriate greetings, closings, tone, and any other cultural considerations."},"typeVersion":1},{"id":"a107790b-f883-469e-8763-61ec92bf1d8e","name":"Generate email for a Japanese client","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[2080,160],"parameters":{"text":"=Subject: {{ $('Gmail trigger').item.json.subject }}\nMessage: {{ $('Gmail trigger').item.json.textAsHtml }}","messages":{"messageValues":[{"message":"You're a helpful personal assistant and your task is to draft replies on my behalf to my incoming emails. Whenever I provide some text from an email, return an appropriate draft reply for it and nothing else.\nEnsure that the reply is suitable for a professional email setting and addresses the topic in a clear, structured, and detailed manner.\nDo not make things up.\n\nDetailed instructions:\n- Be concise and maintain a business tone (desu-masu).\n- Follow the following content \n[INSERT CLIENT NAME] 様\nお世話になっております。\n株式会社 [INSERT YOUR COMPANY NAME] の[INSERT YOUR NAME]です。\n\nBODY (main content)\n\n引き続き、何卒どうぞ宜しくお願いいたします。\n\n- When replying to yes-no questions, draft 2 responses: one affirmative and one negative separated by \" - - - - - - - OR - - - - - - - \"\n- If you don't know an answer, you can leave placeholders like \"[YOUR_ANSWER_HERE]\".\n- Don't use any special formatting, only plain text.\n- Make sure each request is separated with a new line break\n- Reply in the same language as the inbound email."}]},"promptType":"define"},"typeVersion":1.4},{"id":"a548fcdd-1f5e-4a75-b136-07ecf4e96d3d","name":"Generate email reply for an English client","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[2080,440],"parameters":{"text":"=Subject: {{ $('Gmail trigger').item.json.subject }}\nMessage: {{ $('Gmail trigger').item.json.textAsHtml }}","messages":{"messageValues":[{"message":"You're a helpful personal assistant and your task is to draft replies on my behalf to my incoming emails. Whenever I provide some text from an email, return an appropriate draft reply for it and nothing else.\nEnsure that the reply is suitable for a professional email setting and addresses the topic in a clear, structured, and detailed manner.\nDo not make things up.\n\nDetailed instructions:\n- Be concise and maintain a business casual tone.\n- Start with \"Dear,\", and end with \"Best regards,\"\n- When replying to yes-no questions, draft 2 responses: one affirmative and one negative separated by \" - - - - - - - OR - - - - - - - \"\n- If you don't know an answer, you can leave placeholders like \"[YOUR_ANSWER_HERE]\".\n- Don't use any special formatting, only plain text.\n- Reply in the same language as the inbound email."}]},"promptType":"define"},"typeVersion":1.4},{"id":"dcdf44aa-b313-4a22-ae45-0774e5a85add","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-40,0],"parameters":{"color":4,"width":560,"height":941,"content":"## Automated Multilingual Gmail Draft Reply with OpenAI GPT-4o in n8n\n\n### Who is this for?\nThis workflow is ideal for anyone who receives a high volume of Gmail inquiries, especially those providing multilingual customer support or handling diverse client \ncommunications.\n\n### What problem is this workflow solving? \nManaging frequent emails in multiple languages can be overwhelming. This workflow reduces manual drafting by automatically generating context-aware replies using OpenAI GPT-4o, letting users focus on personalization and quality assurance.\n\n### What this workflow does\n- Monitors your Gmail inbox for new emails with a specific label (e.g., \"Inquiry\").\n- Uses OpenAI GPT-4o for message assessment and language detection.\n- Parses information using a JSON parser.\n- Generates an AI-powered draft reply in the detected language via OpenAI GPT-4o.\n- Converts the reply to HTML and saves it as a draft in the original Gmail thread for your review.\n\n### Setup\n- Connect your Gmail account and set up relevant labels in both Gmail and the workflow.\n- Integrate your OpenAI credentials in n8n.\n- Configure the workflow trigger for your desired labels.\n\n## How to customize this workflow to your needs\n- Adjust label names in both Gmail and the workflow for different email categories.\n- Define custom starting and ending phrases for draft replies per supported language.\n- Expand supported languages or modify AI prompt instructions to suit your brand’s tone."},"typeVersion":1},{"id":"323eb990-e7c4-4495-811a-a3c5b26c27f0","name":"Gmail trigger","type":"n8n-nodes-base.gmailTrigger","position":[740,220],"parameters":{"simple":false,"filters":{"q":""},"options":{},"pollTimes":{"item":[{"mode":"everyMinute"}]}},"credentials":{"gmailOAuth2":{"id":"2pW13S2GyP5GCdoP","name":"Gmail account"}},"typeVersion":1},{"id":"1659ef58-d317-4260-99a8-f1de50d50839","name":"OpenAI GPT-4o","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[1140,420],"parameters":{"model":"gpt-4o","options":{"temperature":0,"responseFormat":"json_object"}},"credentials":{"openAiApi":{"id":"8cWUJS0NExv35YHi","name":"OpenAi account"}},"typeVersion":1},{"id":"aeb51aac-0706-4a0e-8a21-cc09147a6e87","name":"Assess if a message needs a reply and identify the language","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[1140,220],"parameters":{"prompt":"=Subject: {{ $json.subject }}\nMessage:\n{{ $json.textAsHtml }} ","messages":{"messageValues":[{"message":"Your task is to :\n- identify the language of the message and set the value to field \"message_language\" : \"English\", \"Japanese\" or \"Other\"\n- assess if the message requires a response and set the value to field \"needsReply\" : true if it does, false otherwise.\nReturn in JSON format.\nMarketing emails don't require a response."}]}},"typeVersion":1.3},{"id":"7e8a17a4-fc57-4f8f-9755-3984547bfcce","name":"Parser Result","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[1300,420],"parameters":{"jsonSchema":"={\n  \"type\": \"array\",\n  \"items\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"needsReply\": {\n        \"type\": \"boolean\"\n      },\n      \"message_language\": {\n        \"type\": \"string\"\n      }\n    },\n    \"required\": [\"needsReply\", \"message_language\"]\n  }\n}"},"typeVersion":1},{"id":"79600a11-8038-48d7-a7a5-5c0ffdb6d412","name":"OpenAI GPT 4o - For English","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[2100,580],"parameters":{"model":"gpt-4o","options":{}},"credentials":{"openAiApi":{"id":"8cWUJS0NExv35YHi","name":"OpenAi account"}},"typeVersion":1},{"id":"e0e0ef36-5a52-4d77-ba51-270693ce893f","name":"OpenAI GPT-4o - for Japanese","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[2060,300],"parameters":{"model":"gpt-4o","options":{}},"credentials":{"openAiApi":{"id":"8cWUJS0NExv35YHi","name":"OpenAi account"}},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"d9b8e365-5baa-47e6-bafb-8b138266a6f7","connections":{"Gmail trigger":{"main":[[{"node":"Assess if a message needs a reply and identify the language","type":"main","index":0}]]},"OpenAI GPT-4o":{"ai_languageModel":[[{"node":"Assess if a message needs a reply and identify the language","type":"ai_languageModel","index":0}]]},"Parser Result":{"ai_outputParser":[[{"node":"Assess if a message needs a reply and identify the language","type":"ai_outputParser","index":0}]]},"If Needs Reply":{"main":[[{"node":"Switch based on email language","type":"main","index":0}]]},"OpenAI GPT 4o - For English":{"ai_languageModel":[[{"node":"Generate email reply for an English client","type":"ai_languageModel","index":0}]]},"OpenAI GPT-4o - for Japanese":{"ai_languageModel":[[{"node":"Generate email for a Japanese client","type":"ai_languageModel","index":0}]]},"Switch based on email language":{"main":[[{"node":"Generate email for a Japanese client","type":"main","index":0}],[{"node":"Generate email reply for an English client","type":"main","index":0}]]},"Generate email for a Japanese client":{"main":[[{"node":"Gmail - Create Draft","type":"main","index":0}]]},"Generate email reply for an English client":{"main":[[{"node":"Gmail - Create Draft","type":"main","index":0}]]},"Assess if a message needs a reply and identify the language":{"main":[[{"node":"If Needs Reply","type":"main","index":0}]]}}}


name: 🏠 Find your Home with Real Estate Agent and Bright Data
author_name: Miquel Colomer
author_username: mcolomer
categories: []
created_at: 2025-06-11T09:15:41.161Z
updated_at: 2025-06-11T09:15:41.161Z
url: https://n8n.io/workflows/4872
scraped_at: 2025-07-06 21:16:30
description:
  📝 Overview
  This workflow transforms n8n into a smart real-estate concierge by combining an AI chat interface with Bright Data’s marketplace datasets. Users interact via chat to specify city, price, bedrooms, and bathrooms—and receive a curated list of three homes for sale, complete with images and briefings.

  🎥 Workflow in Action
  Want to see this workflow in action? Play the video


  🔑 Key Features

  AI-Powered Chat Trigger:** Instantly start conversations using LangChain’s Chat Trigger node.
  Contextual Memory:** Retain up to 30 recent messages for coherent back-and-forth.
  Bright Data Integration:** Dynamically filter “FOR\_SALE” properties by city, price, bedrooms, and bathrooms (limit = 3).
  Automated Snapshot Retrieval:** Poll for dataset readiness and fetch full snapshot content.
  HTML-Formatted Output:** Present results as a ` of ` items, embedding property images.

  🚀 How It Works (Step-by-Step)

  Prerequisites:

     n8n ≥ v1.0
     Community nodes: install n8n-nodes-brightdata (the unverified community node)
     API credentials: OpenAI, Bright Data
     Webhook endpoint to receive chat messages

  Node Configuration:

     Chat Trigger: Listens for incoming chat messages; shows a welcome screen.
     Memory Buffer: Stores the last 30 messages for context.
     OpenAI Chat Model: Uses GPT-4o-mini to interpret user intent.
     Real Estate AI Agent: Orchestrates filtering logic, calls tools, and formats responses.
     Bright Data “Filter Dataset” Tool: Applies user-defined filters plus homeStatus = FOR_SALE.
     Wait & Recover Snapshot: Polls until snapshot is ready, then fetches content.
     Get Snapshot Content: Converts raw JSON into a structured list.

  Workflow Logic:

     User sends search criteria → Agent validates inputs.
     Agent invokes “Filter Dataset” once all filters are present.
     Upon dataset readiness, the snapshot is retrieved and parsed.
     Final output rendered as a bullet list with property images.

  Testing & Optimization:

     Use the built-in Execute Workflow trigger for rapid dry runs.
     Inspect node outputs in n8n’s UI; adjust filter defaults or snapshot limits.
     Tune OpenAI model parameters (e.g., maxIterations) for faster responses.

  Deployment & Monitoring:

     Activate the main workflow and expose its webhook URL.
     Monitor executions in the “Executions” panel; set up alerts for errors.
     Archive or duplicate workflows as needed; update credentials via credential manager.

  ✅ Pre-requisites

  Bright Data Account:** API key for marketplaceDataset.
  OpenAI Account:** Access to GPT-4o-mini model.
  n8n Version:** v1.0 or later with community node support.
  Permissions:** Webhook access, credential vault read/write.

  👤 Who Is This For?

  Real-estate agencies and brokers seeking to automate client queries.
  PropTech startups building conversational search tools.
  Data analysts who want on-demand property snapshots without manual scraping.

  📈 Benefits & Use Cases

  Time Savings:** Replace manual MLS searches with an AI-driven chat.
  Scalability:** Serve multiple clients simultaneously via webchat or embedded widget.
  Consistency:** Always report exactly three properties, ensuring concise results.
  Engagement:** Visual listings with images boost user satisfaction and conversion.


  Workflow created and verified by Miquel Colomer https://www.linkedin.com/in/miquelcolomersalas/ and N8nHackers https://n8nhackers.com

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

workflow_json:
  {"meta":{"instanceId":"b1f85eae352fde76d801a1a612661df6824cc2e68bfd6741e31305160a737e6e","templateCredsSetupCompleted":true},"nodes":[{"id":"d9e07286-a8be-4c28-8519-acf7cd35ad86","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[-900,-40],"webhookId":"57251efe-e57c-43e2-ac58-bf27f1ec639d","parameters":{"public":true,"options":{"showWelcomeScreen":true},"initialMessages":"Hi there! 👋\n\nMy name is Miquel and I am your personal Real Estate agent. I help you to find your new home.\n\nWhat are you looking for?"},"typeVersion":1.1},{"id":"7ca48714-3c65-4f32-9491-7b7b621aaa00","name":"Simple Memory1","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[-420,140],"parameters":{"contextWindowLength":30},"typeVersion":1.3},{"id":"79bea812-5a33-40a1-aa74-fe202d39dded","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-580,140],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"oKzfvOwieOm4upQ2","name":"OpenAi account"}},"typeVersion":1.2},{"id":"30ef3cfc-56db-4092-af0d-304afdad94f0","name":"Filter Dataset","type":"n8n-nodes-brightdata.brightDataTool","position":[-260,140],"parameters":{"resource":"marketplaceDataset","operation":"filterDataset","dataset_id":{"__rl":true,"mode":"list","value":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Dataset', ``, 'string') }}"},"filter_type":"filters_group","filters_group":"={{ $fromAI('Filters_Group') }}","records_limit":"=3","descriptionType":"manual","toolDescription":"Create a dataset snapshot based on a provided filter in BrightData. use always filter homeStatus = FOR_SALE. We have the next operators: =, >, >=, in, <, <=, not_array_includes, !=, not_in, not_includes\n\nFilter must follow the next format:\n{\n    \"operator\": \"and\",\n    \"filters\": [\n        {\n            \"name\": \"homeStatus\",\n            \"operator\": \"=\",\n            \"value\": \"FOR_SALE\"\n        },\n        {\n            \"name\": \"price\",\n            \"operator\": \"=\",\n            \"value\": 1000000\n        },\n        {\n            \"name\": \"city\",\n            \"operator\": \"=\",\n            \"value\": \"new york\"\n        },\n        {\n            \"name\": \"bathrooms\",\n            \"operator\": \"=\",\n            \"value\": 2\n        },\n        {\n            \"name\": \"bedrooms\",\n            \"operator\": \"=\",\n            \"value\": 4\n        }\n    ]\n}"},"credentials":{"brightdataApi":{"id":"jk945kIuAFAo9bcg","name":"BrightData account"}},"typeVersion":1},{"id":"6c4c4338-e4d2-40ee-89c0-89e1dd1dc330","name":"When Executed by Another Workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[-660,-340],"parameters":{"inputSource":"passthrough"},"typeVersion":1.1},{"id":"9db2680e-8bad-4b91-9cd6-8240f53081a0","name":"Snapshot is ready?","type":"n8n-nodes-base.if","position":[-120,-340],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"or","conditions":[{"id":"3e99082f-412a-4e33-ab77-c99ddd4d7ff5","operator":{"type":"string","operation":"exists","singleValue":true},"leftValue":"={{ $json.items[0].abbreviatedAddress }}","rightValue":"NodeApiError"}]}},"typeVersion":2.2},{"id":"75f66a3a-7738-4a1c-af8a-29385ad41749","name":"Wait","type":"n8n-nodes-base.wait","position":[100,-260],"webhookId":"7d5607bb-7cbd-439e-a95e-dfe326486b74","parameters":{},"typeVersion":1.1},{"id":"19beba9e-6089-443f-a384-4be3ec821423","name":"Real Estate AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[-460,-40],"parameters":{"text":"={{ $json.chatInput }}","options":{"maxIterations":10,"systemMessage":"=You are an expert AI Real Estate Agent.\n\nFollow the next guidelines always:\n\n1) If you have no memory, recover the metadata from the next databases:\n- Zillow properties listing information gd_lfqkr8wm13ixtbd8f5\nWe have the next filters:\n- city: City name where entity is located. Contains valid US city names as text strings.\n- bedrooms: Column stores the number of bedrooms in properties. Values are positive integers ranging from 1 to 7, with most properties having 2-4 bedrooms and no null values.\n- bathrooms: Number of bathrooms in residential properties. Values are positive integers ranging from 1 to 7, with most properties having 2-3 bathrooms and no null values.\n- price: Property price in US dollars. Format sample: 180,000\n\nInform user that only 3 houses will be reported.\nOnly call filterDataset if user completes city, bedrooms, bathrooms and price filters.\n\n2) Use filterDataset to generate a snapshot of the requested houses by mapping filter of the user.\nOnly allow one call to tool \"Filter Dataset\", \n\n3) After calling \"filter Dataset\" tool, use tool \"Get Snapshot Content\". Pass snapshot_id parameter.\n\n4) Use output from tool \"Get Snapshot Content\" to convert json to a list of properties with ul > li\nuse returned images to present home briefing"},"promptType":"define"},"typeVersion":1.9},{"id":"679e5b92-7b52-4230-a395-f3840d167756","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-960,-600],"parameters":{"width":1260,"height":880,"content":"# Real Estate AI Agent with Bright Data\n\n## TODO\n- After pasting this workflow, update node \"Get Snapshot Content\" tool and add current Workflow ID (for instance, if your workflow in n8n has the next url https://n8n-ai.cr.vps2.clients.killia.com/workflow/fjEIEQ1L6n2IKqlx your workflow Id is fjEIEQ1L6n2IKqlx).\n- Add your Bright Data api key to \"Filter Dataset\" tool and \"Recover Snapshot Content\" node."},"typeVersion":1},{"id":"118c60c3-3a46-4ca2-be84-997218949bde","name":"Recover Snapshot Content","type":"n8n-nodes-brightdata.brightData","position":[-340,-340],"parameters":{"resource":"marketplaceDataset","operation":"getSnapshotContent","snapshot_id":"={{ $('When Executed by Another Workflow').item.json.query }}"},"credentials":{"brightdataApi":{"id":"jk945kIuAFAo9bcg","name":"BrightData account"}},"typeVersion":1},{"id":"5cc00806-6995-4d82-a832-f3159a66e31a","name":"Get Snapshot Content","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[-100,140],"parameters":{"workflowId":{"__rl":true,"mode":"id","value":"Ky9jD15PJgT7PIgP"},"workflowInputs":{"value":{},"schema":[],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false}},"typeVersion":2.2}],"connections":{"Wait":{"main":[[{"node":"Recover Snapshot Content","type":"main","index":0}]]},"Filter Dataset":{"ai_tool":[[{"node":"Real Estate AI Agent","type":"ai_tool","index":0}]]},"Simple Memory1":{"ai_memory":[[{"node":"Real Estate AI Agent","type":"ai_memory","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Real Estate AI Agent","type":"ai_languageModel","index":0}]]},"Snapshot is ready?":{"main":[[],[{"node":"Wait","type":"main","index":0}]]},"Get Snapshot Content":{"ai_tool":[[{"node":"Real Estate AI Agent","type":"ai_tool","index":0}]]},"Recover Snapshot Content":{"main":[[{"node":"Snapshot is ready?","type":"main","index":0}]]},"When chat message received":{"main":[[{"node":"Real Estate AI Agent","type":"main","index":0}]]},"When Executed by Another Workflow":{"main":[[{"node":"Recover Snapshot Content","type":"main","index":0}]]}}}


name: 🎯 Precision Prospecting: Automate LinkedIn Lead Gen with Bright Data
author_name: Miquel Colomer
author_username: mcolomer
categories: []
created_at: 2025-06-11T09:26:01.909Z
updated_at: 2025-06-11T09:26:01.909Z
url: https://n8n.io/workflows/4873
scraped_at: 2025-07-06 21:16:30
description:
  🎯 Precision Prospecting: Automate LinkedIn Lead Gen with n8n & Bright Data

  📝 Overview
  This workflow turns n8n into an AI-powered prospector, automatically searching Google for LinkedIn profiles, scraping profile data via Bright Data, and summarizing key details. Ideal for sales and recruitment teams seeking targeted lead lists without manual research.

  🎥 Workflow in Action
  Want to see this workflow in action? You have a chat window output below:


  🔑 Key Features

  AI Chat Trigger**: Start prospecting via conversational prompts.
  Contextual Memory**: Retains the last 20 messages for coherent dialogue.
  Automated Google Search**: Generates site-restricted queries and fetches the top result.
  Bright Data Scraping**: Synchronously scrapes LinkedIn profile details by URL.
  Intelligent Filtering**: Extracts only valid LinkedIn profile links.
  Limit Control**: Returns a single, most relevant profile per request.
  LLM Summary**: Uses GPT-4o-mini to interpret and present scraped data.

  🚀 How It Works (Step-by-Step)

  Prerequisites:

     n8n ≥ v1.0 with community nodes: install n8n-nodes-brightdata (not verified community node).
     API credentials: OpenAI, Bright Data (web unlocker zone “web\_unlocker1”).
     Webhook endpoint for chat trigger.

  Node Configuration:

     When chat message received (chatTrigger): Fires on user prompt.
     Simple Memory1 (memoryBufferWindow): Stores the last 20 chat messages.
     AI Prospector Agent (agent): Orchestrates search logic.
     Get 1 Google Result (brightData): Performs a Google search with site:linkedin.com/in.
     Get Links from Body (html): Extracts all `` hrefs from the search result page.
     Extract Links (splitOut): Splits out individual link entries.
     Filter only LinkedIn Profiles (filter): Ensures the URL contains “linkedin.com/” and starts with “https\://”.
     Limit (limit): Restricts output to the first valid profile URL.
     Search LinkedIn URI (toolWorkflow): Passes the URL to a secondary workflow to fetch the first link.
     Get LinkedIn Profile Data (brightDataTool): Scrapes the profile JSON.
     OpenAI Chat Model (lmChatOpenAi): Summarizes and formats the scraped data.

  Workflow Logic:

     User asks for a person by company & name, company & position, or LinkedIn URL.
     Agent builds a Google query (e.g., site:linkedin.com/in bright data cmo) and calls “Get 1 Google Result.”
     Extracted links are filtered and limited to the top valid profile.
     If user provided a direct LinkedIn URL, Agent skips search and scrapes immediately.
     Scraped profile JSON is passed to GPT-4o-mini to generate a concise summary.

  Testing & Optimization:

     Trigger via Execute Workflow for dry runs.
     Inspect intermediate node outputs in n8n’s Execution panel.
     Adjust maxIterations or memory window length for performance.
     Tune Bright Data zone or country settings to optimize scraping speed.

  Deployment & Monitoring:

     Activate the workflow and expose its webhook URL.
     Use n8n’s built-in Alerts or external monitoring (e.g., Slack notifications) on failures.
     Rotate credentials via n8n’s Credential Vault when needed.
     Version-control workflow via duplicates or Git-backed n8n instances.

  ✅ Pre-requisites

  OpenAI Account**: API key for GPT-4o-mini.
  Bright Data Account**: Zone “web\_unlocker1” and dataset gd_l1viktl72bvl7bjuj0.
  n8n Version**: v1.0+ with community nodes installed.
  Permissions**: Webhook access, Credential Vault read/write.

  👤 Who Is This For?

  Sales teams automating outbound LinkedIn prospecting.
  Recruiters sourcing candidates without manual scraping.
  Marketing ops looking to enrich CRM with accurate profile data.

  📈 Benefits & Use Cases

  Efficiency**: Reduces hours of manual search and data entry to seconds.
  Accuracy**: Filters out non-LinkedIn links and ensures high-quality results.
  Scalability**: Handle multiple prospect requests concurrently via chat or API.
  Integration**: Easily hook into CRMs or email sequencers downstream.

  Workflow created and verified by Miquel Colomer https://www.linkedin.com/in/miquelcolomersalas/ and N8nHackers https://n8nhackers.com

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

workflow_json:
  {"meta":{"instanceId":"b1f85eae352fde76d801a1a612661df6824cc2e68bfd6741e31305160a737e6e","templateCredsSetupCompleted":true},"nodes":[{"id":"0f2da238-9741-4019-a691-ddf17b523ca3","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[-880,-20],"webhookId":"22c79cd1-0bd1-4bd1-bde0-88e0b3dcf553","parameters":{"options":{}},"typeVersion":1.1},{"id":"a02120f5-aa93-4269-92af-2e7486768736","name":"Simple Memory1","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[-320,140],"parameters":{"contextWindowLength":20},"typeVersion":1.3},{"id":"ac560c1c-2e1e-4985-a398-6b837b89a7f3","name":"When Executed by Another Workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[-880,-240],"parameters":{"inputSource":"passthrough"},"typeVersion":1.1},{"id":"1bd808f6-bba4-43f5-b28c-d2c9a3dd0003","name":"Search LinkedIn URI","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[-100,140],"parameters":{"workflowId":{"__rl":true,"mode":"id","value":"fjEIEQ1L6n2IKqlx"},"description":"Pass the google uri to get first linkedin link from Google Search","workflowInputs":{"value":{},"schema":[],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false}},"typeVersion":2.2},{"id":"a7a7269a-e091-4327-ac67-a6f5f7946b25","name":"Get LinkedIn Profile Data","type":"n8n-nodes-brightdata.brightDataTool","position":[120,140],"parameters":{"urls":"={{ $fromAI('URLs') }}","resource":"webScrapper","dataset_id":{"__rl":true,"mode":"list","value":"=gd_l1viktl72bvl7bjuj0"},"descriptionType":"manual","toolDescription":"Scrape data synchronously by URL in BrightData\nURLs parameter must follow the next format:\n[{\"url\":\"https://www.linkedin.com/in/dvirsharon/\"}]"},"credentials":{"brightdataApi":{"id":"jk945kIuAFAo9bcg","name":"BrightData account"}},"typeVersion":1},{"id":"b84107a5-0a56-4ec9-82c9-3ef674613bb8","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-500,140],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"oKzfvOwieOm4upQ2","name":"OpenAi account"}},"typeVersion":1.2},{"id":"27165580-6ed9-428e-a7dc-3c119519894c","name":"Extract Links","type":"n8n-nodes-base.splitOut","position":[40,-240],"parameters":{"options":{"destinationFieldName":"url"},"fieldToSplitOut":"link"},"typeVersion":1},{"id":"2d0f43b7-4818-4f4d-aac4-862cd1bb8729","name":"Get Links from Body","type":"n8n-nodes-base.html","position":[-180,-240],"parameters":{"options":{"trimValues":true,"cleanUpText":true},"operation":"extractHtmlContent","dataPropertyName":"body","extractionValues":{"values":[{"key":"link","attribute":"href","cssSelector":"a","returnArray":true,"returnValue":"attribute"}]}},"typeVersion":1.2},{"id":"c61dd9c4-9c64-4bdb-aaf4-0e7dcf6f340f","name":"Filter only LinkedIn Profiles","type":"n8n-nodes-base.filter","position":[260,-240],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"7ccbfe62-09f0-44d1-aa72-c65a2d1750b2","operator":{"type":"string","operation":"contains"},"leftValue":"={{ $json.url }}","rightValue":"linkedin.com/"},{"id":"de368fe2-6559-4316-97c5-2c6bb0a72a51","operator":{"type":"string","operation":"startsWith"},"leftValue":"={{ $json.url }}","rightValue":"https://"}]}},"typeVersion":2.2},{"id":"a689a9f6-d7a1-4e4c-8265-7753bbc41bdb","name":"Limit","type":"n8n-nodes-base.limit","position":[480,-240],"parameters":{},"typeVersion":1},{"id":"424f2539-c0ae-4228-ba9c-86ad15e24654","name":"AI Prospector Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[-400,-80],"parameters":{"text":"={{ $json.chatInput }}","options":{"maxIterations":10,"systemMessage":"=You are an expert AI Prospector Agent.\nYou return information about any person using LinkedIn profiles.\n\nFollow the next guidelines always:\n\n1) User can ask your for people in two ways:\n- by company and first name\n- by company and position\n- by linkedin company\n\n2) if user searches by company and first, do a google search and scrape links matching request. Sample url generated for this case:\n- if company = bright data\n- fullname = dvir\nThe url generated is\nhttps://www.google.com/search?q=site%3Alinkedin.com%2Fin+bright%20data+dvir\n\nCall \"Search LinkedIn URI\", pass as query property the generated url, and get first https:// linkedin.com link\n\n3) if user searches by company and position, do a google search and scrape links matching request. Sample url generated for this case:\n- if company = bright data\n- position = cmo\nThe url generated is\nhttps://www.google.com/search?q=site%3Alinkedin.com%2Fin+bright%20data+cmo\n\nCall \"Search LinkedIn URI\", pass as query property the generated url, and get first https:// linkedin.com link\n\n4) if user searches by LinkedIn URI, pass link to tool \"Get LinkedIn Profile Data\".\n\n5) Present a summary for all data returned by \"Get LinkedIn Profile Data\" tool\n"},"promptType":"define"},"typeVersion":1.9},{"id":"3d0ee963-ed48-4bd1-b7d5-ae8009bfb1d7","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-1000,-480],"parameters":{"width":1680,"height":760,"content":"# Precision Prospector with Bright Data\n\n## TODO\n- After pasting this workflow, update node \"Search LinkedIn URI\" tool and add current Workflow ID (for instance, if your workflow in n8n has the next url https://n8n-ai.cr.vps2.clients.killia.com/workflow/fjEIEQ1L6n2IKqlx your workflow Id is fjEIEQ1L6n2IKqlx).\n- Add your Bright Data api key to \"Get LinkedIn Profile Data\" tool and \"Get 1 Google Result\" node."},"typeVersion":1},{"id":"df94a25c-a03e-46d9-92c8-5f0f3a5097f7","name":"Get 1 Google Result","type":"n8n-nodes-brightdata.brightData","position":[-480,-240],"parameters":{"url":"={{ $json.query }}&num=1","zone":{"__rl":true,"mode":"list","value":"web_unlocker1"},"format":"json","country":{"__rl":true,"mode":"list","value":"us"}},"credentials":{"brightdataApi":{"id":"jk945kIuAFAo9bcg","name":"BrightData account"}},"typeVersion":1}],"connections":{"Extract Links":{"main":[[{"node":"Filter only LinkedIn Profiles","type":"main","index":0}]]},"Simple Memory1":{"ai_memory":[[{"node":"AI Prospector Agent","type":"ai_memory","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Prospector Agent","type":"ai_languageModel","index":0}]]},"Get 1 Google Result":{"main":[[{"node":"Get Links from Body","type":"main","index":0}]]},"Get Links from Body":{"main":[[{"node":"Extract Links","type":"main","index":0}]]},"Search LinkedIn URI":{"ai_tool":[[{"node":"AI Prospector Agent","type":"ai_tool","index":0}]]},"Get LinkedIn Profile Data":{"ai_tool":[[{"node":"AI Prospector Agent","type":"ai_tool","index":0}]]},"When chat message received":{"main":[[{"node":"AI Prospector Agent","type":"main","index":0}]]},"Filter only LinkedIn Profiles":{"main":[[{"node":"Limit","type":"main","index":0}]]},"When Executed by Another Workflow":{"main":[[{"node":"Get 1 Google Result","type":"main","index":0}]]}}}


name: Create a Telegram Customer Support Bot with GPT4-mini and Google Docs Knowledge
author_name: Automate With Marc
author_username: marconi
categories: []
created_at: 2025-06-11T14:02:23.307Z
updated_at: 2025-06-11T14:02:23.307Z
url: https://n8n.io/workflows/4875
scraped_at: 2025-07-06 21:16:30
description:
  🤖 AI Customer Support Agent with Google Docs Knowledge (Telegram + OpenAI)

  This no-code workflow turns your Telegram bot into an intelligent, always-on AI support agent that references your business documentation in Google Docs to respond to customer queries—instantly and accurately.

  Watch full step-by-step video tutorial of the build here:
  https://youtu.be/Mlv7CjGO7wI

  🔧 How it works:
  Telegram Trigger – Captures incoming messages from users on your Telegram bot

  Langchain AI Agent (OpenAI GPT) – Interprets the message and uses RAG (retrieval-augmented generation) techniques to craft an answer

  Google Docs Tool – Connects to and retrieves context from your specified Google Doc (e.g. FAQ, SOPs, policies)

  Memory Buffer – Keeps track of recent chat history for more human-like conversations

  Telegram Reply Node – Sends the AI-generated response back to the user

  💡 Use Cases:
  E-commerce customer service

  SaaS product onboarding

  Internal helpdesk bot for teams

  WhatsApp-style support for digital businesses

  🧠 What makes this powerful:
  Supports complex questions by referencing a live Google Doc knowledge base

  Works in plain conversational language (no buttons or forms needed)

  Runs 24/7 with zero code

  Easily extendable to Slack, WhatsApp, or email support

  🛠️ Tools used:
  Telegram Node (trigger + send)

  Langchain Agent with OpenAI GPT

  Google Docs Tool

  Memory Buffer

  Sticky Notes for easy understanding

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

workflow_json:
  {"id":"","meta":{},"name":"My workflow","tags":[],"nodes":[{"id":"f611e34d-0de9-42b7-b438-bc522817f9ba","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[180,180],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini","cachedResultName":"gpt-4o-mini"},"options":{}},"credentials":{},"typeVersion":1.2},{"id":"7c968986-dcc4-4a26-bedf-5a5f9c75d2dc","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[340,180],"parameters":{"sessionKey":"={{ $json.message.chat.id }}","sessionIdType":"customKey"},"typeVersion":1.3},{"id":"fd291678-8522-4e00-94bc-7033689f14b3","name":"Google Docs","type":"n8n-nodes-base.googleDocsTool","position":[480,180],"parameters":{"operation":"get","documentURL":"https://docs.google.com/document/d/1os02TMG0h74DYE_mmv5utPr68LtV946otozP1YZTNr0/edit?tab=t.0"},"credentials":{},"typeVersion":2},{"id":"d3e871cb-48b9-4921-8376-359f53e40942","name":"Telegram Trigger","type":"n8n-nodes-base.telegramTrigger","position":[-100,0],"webhookId":"d546870e-898a-4d37-b290-a4b3e3eac311","parameters":{"updates":["message"],"additionalFields":{}},"credentials":{},"typeVersion":1.2},{"id":"8deb9aa3-4b45-4737-a6a5-4311fb460b04","name":"Telegram","type":"n8n-nodes-base.telegram","position":[680,0],"webhookId":"cfeeb7fc-6dad-4482-b8c7-73998bfc613f","parameters":{"text":"={{ $json.output }}","chatId":"={{ $('Telegram Trigger').item.json.message.chat.id }}","additionalFields":{"appendAttribution":false}},"credentials":{},"typeVersion":1.2},{"id":"eac2e88c-0c0f-4451-bbe2-915de6e9ab1a","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-200,-100],"parameters":{"width":300,"height":500,"content":"Telegram Trigger"},"typeVersion":1},{"id":"c99be9a9-7368-4b22-be65-26108f8dc23a","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[120,-100],"parameters":{"color":4,"width":500,"height":500,"content":"Telegram Trigger"},"typeVersion":1},{"id":"ba596aa6-e6fb-4df4-9bdb-7b75536cfbf6","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[640,-100],"parameters":{"color":3,"width":280,"height":500,"content":"Telegram Trigger"},"typeVersion":1},{"id":"ccf10ec2-eae2-47be-9be7-7bf7b3d974cb","name":"Customer Support AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[220,0],"parameters":{"text":"={{ $json.message.text }}","options":{"systemMessage":"You are a helpful Customer Support Agent, cross-reference the Google Doc for any customer queries for relevant information. If relevant information is not found, do not make up facts. Plainly let the user know that the information isn't available. \n\n#Tonality\nFriendly, casual and helpful. if user or customer says hi, inform them that you are a Friendly Customer Support Agent"},"promptType":"define"},"typeVersion":2},{"id":"ac9ffbcd-0b7a-421e-92f4-5e367d6ba4c9","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-600,-100],"parameters":{"color":5,"width":360,"height":500,"content":"🤖 AI Customer Support Agent with Google Docs Knowledge (Telegram + OpenAI)\n\nThis no-code workflow turns your Telegram bot into an intelligent, always-on AI support agent that references your business documentation in Google Docs to respond to customer queries—instantly and accurately.\n\nWatch full step-by-step video tutorial of the build here:\nhttps://www.youtube.com/@Automatewithmarc\n\n🔧 How it works:\nTelegram Trigger – Captures incoming messages from users on your Telegram bot\n\nLangchain AI Agent (OpenAI GPT) – Interprets the message and uses RAG (retrieval-augmented generation) techniques to craft an answer\n\nGoogle Docs Tool – Connects to and retrieves context from your specified Google Doc (e.g. FAQ, SOPs, policies)\n\nMemory Buffer – Keeps track of recent chat history for more human-like conversations\n\nTelegram Reply Node – Sends the AI-generated response back to the user\n\n💡 Use Cases:\nE-commerce customer service\n\nSaaS product onboarding\n\nInternal helpdesk bot for teams\n\nWhatsApp-style support for digital businesses\n\n🧠 What makes this powerful:\nSupports complex questions by referencing a live Google Doc knowledge base\n\nWorks in plain conversational language (no buttons or forms needed)\n\nRuns 24/7 with zero code\n\nEasily extendable to Slack, WhatsApp, or email support\n\n🛠️ Tools used:\nTelegram Node (trigger + send)\n\nLangchain Agent with OpenAI GPT\n\nGoogle Docs Tool\n\nMemory Buffer\n\nSticky Notes for easy understanding"},"typeVersion":1}],"active":true,"settings":{"executionOrder":"v1"},"versionId":"","connections":{"Google Docs":{"ai_tool":[[{"node":"Customer Support AI Agent","type":"ai_tool","index":0}]]},"Simple Memory":{"ai_memory":[[{"node":"Customer Support AI Agent","type":"ai_memory","index":0}]]},"Telegram Trigger":{"main":[[{"node":"Customer Support AI Agent","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Customer Support AI Agent","type":"ai_languageModel","index":0}]]},"Customer Support AI Agent":{"main":[[{"node":"Telegram","type":"main","index":0}]]}}}


name: Auto-classify Gmail emails with AI and apply labels for inbox organization
author_name: Alex Dunlop
author_username: alexdunlop
categories: []
created_at: 2025-06-11T14:08:25.008Z
updated_at: 2025-06-11T14:08:25.008Z
url: https://n8n.io/workflows/4876
scraped_at: 2025-07-06 21:16:30
description:
  Who is this for?
  Professionals and individuals who receive high volumes of emails, those who want to automatically organize their Gmail inbox using AI classification.

  What problem is this workflow solving?

  Manual email sorting is time-consuming and inconsistent. This workflow automatically categorizes incoming emails into 8 predefined labels (To respond, FYI, Comment, Notification, Meeting update, Awaiting reply, Actioned, Marketing) to help maintain inbox zero and prioritize responses.

  What this workflow does

  Monitors Gmail for new incoming emails
  Uses AI to analyze email content and classify into appropriate categories
  Automatically applies the corresponding Gmail label
  Runs on a schedule to process emails consistently

  Setup

  Prerequisites

  n8n instance (cloud or self-hosted)
  Gmail account with API access enabled
  Access to an LLM provider (OpenAI, Anthropic Claude, or similar)

  Step-by-Step

  Configure Gmail Credentials
  Create Gmail Labels
  Configure LLM Chain
  Set Email Polling Schedule
  Test the Workflow

  Create Gmail Labels
  Before running the workflow, create these 8 labels in your Gmail account:

  To respond
  FYI
  Comment
  Notification
  Meeting update
  Awaiting reply
  Actioned
  Marketing

  How to customize this workflow to your needs

  Modify Classification Categories


  To change the email categories, update two places:

  In the AI prompt (Basic LLM Chain node):

  Your new category - Description of what emails fit here
  Another category - Description
  [... continue with your categories]

  In Gmail labels:
  Create corresponding labels in your Gmail account with the exact same names and numbering.

  Adjust Classification Rules

  The AI prompt contains specific rules for each category. To modify:

  Edit the "Key classification rules" section in the LLM prompt
  Add examples of emails that should go into each category
  Specify edge cases and how they should be handled

  Change Email Sources

  Currently monitors all incoming emails. To filter specific emails:

  In the Gmail Trigger node, add filters such as:

  from:specific-sender@domain.com
  subject:contains-keyword
  -label:already-processed

  You can also change this use Outlook

  Modify Polling Frequency

  More frequent**: Add multiple poll times (e.g., 9 AM, 12 PM, 6 PM)
  Less frequent**: Change to once daily or weekly
  Real-time**: Switch to webhook-based triggering (requires Gmail API setup)

  I choose daily for cost.

nodes_used:
  ["n8n-nodes-base.gmail","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.chainLlm","@n8n/n8n-nodes-langchain.lmChatOpenRouter"]

workflow_json:
  {"meta":{"instanceId":"5a90cf25b26f3375705646dd979ac7968c2f7780e9cb14036112ef363426c72c","templateCredsSetupCompleted":true},"nodes":[{"id":"37166e51-ffb6-43fe-8bd5-fe5eb1249366","name":"OpenRouter Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[540,540],"parameters":{"model":"google/gemini-2.5-flash-preview-05-20","options":{}},"credentials":{"openRouterApi":{"id":"ogejgDjpnXZzGonu","name":"OpenRouter account"}},"typeVersion":1},{"id":"067f6b55-dc4c-4757-b19e-2d539b8b2526","name":"Aggregate Gmail Messages","type":"n8n-nodes-base.aggregate","position":[-360,220],"parameters":{"options":{},"aggregate":"aggregateAllItemData"},"typeVersion":1},{"id":"7807ff72-49f7-4a7b-9d75-24746d0dfdb7","name":"Merge Labels & Messages","type":"n8n-nodes-base.merge","position":[240,320],"parameters":{"mode":"combine","options":{},"combineBy":"combineAll"},"typeVersion":3.1},{"id":"8c51f04b-3415-4d53-8624-ce8d484145b9","name":"Classify Email with AI","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[520,320],"parameters":{"text":"=You are an email classification assistant. Your task is to analyze Gmail email snippets and categorize them into one of the following labels:\n\n1. To respond - Emails requiring a direct personal response from you (questions from individuals, personal conversations, NOT automated feedback requests)\n2. FYI - Emails requesting you to take action, reminders, or alerts about issues (add money requests, payment failures, action needed)\n3. Comment - Emails specifically asking for your feedback, review, or opinion in a professional/collaborative context\n4. Notification - Automated updates about completed or ongoing events (successful payments, transfers sent, deployments, shipments, security alerts)\n5. Meeting update - Calendar invites, meeting changes, or meeting-related communications\n6. Awaiting reply - Follow-up emails or reminders about your pending responses\n7. Actioned - Confirmations of actions YOU specifically took (not automated system actions)\n8. Marketing - Promotional content, sales emails, feature announcements, newsletters, or automated customer feedback surveys\n\nKey classification rules:\n- Automated status updates (deployments, transfers, payments processed) → Notification\n- Requests to add money or take action → FYI\n- Payment failure alerts → FYI\n- Security alert digests → Notification\n- Shipment updates → Notification\n- Direct Debit payment confirmations → Notification\n- Balance update confirmations → Notification\n- Customer satisfaction surveys or feedback requests → Marketing\n- Automated \"how was your experience\" emails → Marketing\n- Only use \"Actioned\" for confirmations of YOUR manual actions\n- Only use \"Marketing\" for promotional content, including feedback surveys\n\nInstructions:\n1. Read the email snippet carefully\n2. Note the sender (if provided) for context\n3. Choose the single most appropriate label based on the rules above\n4. IMPORTANT: Respond ONLY with the number and label (e.g., \"2. FYI\")\n5. Do not include any other text, explanation, or repeat the email content\n\nEmail From:\n{{ $json.From }}\nEmail To:\n{{ $json.To }}\nEmail subject:\n{{ $json.Subject }}\nEmail snippet:\n{{ $json.snippet }}\n\nYour response must be exactly one of these 8 options:\n1. To respond\n2. FYI\n3. Comment\n4. Notification\n5. Meeting update\n6. Awaiting reply\n7. Actioned\n8. Marketing","batching":{},"promptType":"define"},"typeVersion":1.7},{"id":"ddbdc31a-ea27-415e-b9e2-954959cfcb7a","name":"New Gmail Email Received","type":"n8n-nodes-base.gmailTrigger","position":[-560,340],"parameters":{"filters":{},"pollTimes":{"item":[{"hour":12}]}},"credentials":{"gmailOAuth2":{"id":"V5NiRamelad0WTXx","name":"Gmail account"}},"typeVersion":1.2},{"id":"52b3a1d8-3be8-4f57-8759-7ae9abcdb5cb","name":"Fetch Available Gmail Labels","type":"n8n-nodes-base.gmail","position":[-140,220],"webhookId":"8574ca24-b439-4bc3-aa28-ae2b539a8d8e","parameters":{"resource":"label","returnAll":true},"credentials":{"gmailOAuth2":{"id":"V5NiRamelad0WTXx","name":"Gmail account"}},"typeVersion":2.1},{"id":"2d15670f-5735-4110-a1eb-d5b6b8abef89","name":"Map Label Names to IDs","type":"n8n-nodes-base.code","position":[60,220],"parameters":{"jsCode":"const items = $input.all();\nconst combinedObject = items.reduce((acc, item) => {\n  return { ...acc, [item.json.name]: item.json.id };\n}, {});\n\nreturn { combinedObject };\n"},"typeVersion":2},{"id":"4c5d1e4a-93ce-4f78-b0ce-8b94aff99498","name":"Apply Classification Label","type":"n8n-nodes-base.gmail","position":[960,320],"webhookId":"2ffe45e7-a0e3-4304-a6bf-e217c15ea6cc","parameters":{"labelIds":"={{ $('Map Label Names to IDs').item.json.combinedObject[$json.text] }}","messageId":"={{ $('Merge Labels & Messages').item.json.id }}","operation":"addLabels"},"credentials":{"gmailOAuth2":{"id":"V5NiRamelad0WTXx","name":"Gmail account"}},"typeVersion":2.1}],"connections":{"OpenRouter Chat Model":{"ai_languageModel":[[{"node":"Classify Email with AI","type":"ai_languageModel","index":0}]]},"Classify Email with AI":{"main":[[{"node":"Apply Classification Label","type":"main","index":0}]]},"Map Label Names to IDs":{"main":[[{"node":"Merge Labels & Messages","type":"main","index":0}]]},"Merge Labels & Messages":{"main":[[{"node":"Classify Email with AI","type":"main","index":0}]]},"Aggregate Gmail Messages":{"main":[[{"node":"Fetch Available Gmail Labels","type":"main","index":0}]]},"New Gmail Email Received":{"main":[[{"node":"Aggregate Gmail Messages","type":"main","index":0},{"node":"Merge Labels & Messages","type":"main","index":1}]]},"Fetch Available Gmail Labels":{"main":[[{"node":"Map Label Names to IDs","type":"main","index":0}]]}}}


name: Automated video creation using Google Veo3 and n8n workflow
author_name: Lakshit Ukani
author_username: lakshit1996
categories: []
created_at: 2025-06-11T14:24:53.629Z
updated_at: 2025-06-11T14:24:53.629Z
url: https://n8n.io/workflows/4877
scraped_at: 2025-07-06 21:16:30
description:
  Who is this for?
  Content creators, social media managers, digital marketers, and businesses looking to automate video production without expensive equipment or technical expertise.

  What problem is this workflow solving?
  Traditional video creation requires cameras, editing software, voice recording equipment, and hours of post-production work. This workflow eliminates all these barriers by automatically generating professional videos with audio using just text prompts.

  What this workflow does
  This automated workflow takes video ideas from Google Sheets, generates optimized prompts using AI, creates videos through Google's V3 model via Fal AI, monitors the generation progress, and saves the final video URLs back to your spreadsheet for easy access and management.

  Setup
  Sign up for Fal AI account and obtain API key
  Create Google Sheet with video ideas and status columns
  Configure n8n with required credentials (Google Sheets, Fal AI API)
  Import the workflow template
  Set up authentication for all connected services
  Test with sample video idea

  How to customize this workflow to your needs
  Modify the AI prompts to match your brand voice, adjust video styles and camera movements, change polling intervals for video generation status, customize Google Sheet column mappings, and add additional processing steps like thumbnail generation or social media posting.

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

workflow_json:
  {"meta":{"instanceId":"353ac65d120d2007b8a1503e85a96651a9b2cbb94b0334693ebac2129fa6a7ee","templateCredsSetupCompleted":true},"nodes":[{"id":"d790575f-b251-4431-b993-b5b23ac98ed8","name":"When clicking ‘Execute workflow’","type":"n8n-nodes-base.manualTrigger","position":[-500,140],"parameters":{},"typeVersion":1},{"id":"ebd26e9d-956e-49d5-9819-f560c443163f","name":"📊 Fetch Ready Ideas from Sheet","type":"n8n-nodes-base.googleSheets","position":[-280,140],"parameters":{"options":{"returnFirstMatch":true},"filtersUI":{"values":[{"lookupValue":"ready","lookupColumn":"Status"}]},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1VHJFdJjqKWT973NK4TVTdzodAiHM4Zzb4tIkK-kqqGc/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1VHJFdJjqKWT973NK4TVTdzodAiHM4Zzb4tIkK-kqqGc","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1VHJFdJjqKWT973NK4TVTdzodAiHM4Zzb4tIkK-kqqGc/edit?usp=drivesdk","cachedResultName":"VEO3 Video Generation"}},"credentials":{"googleSheetsOAuth2Api":{"id":"uvQG3YEEXtu5NVSj","name":"Freelance Account"}},"typeVersion":4.6},{"id":"d47052aa-2bd9-4273-99f0-2d3b8cb593f9","name":"🤖 VEO3 Prompt Generator (GPT-4.1)","type":"@n8n/n8n-nodes-langchain.agent","position":[100,120],"parameters":{"text":"=User Idea: {{ $json.Idea }}","options":{"systemMessage":"=SYSTEM PROMPT TO GENERATE PROMPT FOR VEO3\n\nThe key to crafting a strong prompt in Veo 3 is understanding what truly matters in a video. To ensure you include all the essential details, we recommend starting by breaking your prompt down into clear categories:\n\nScene description: Overall description of the scene you want to create — what’s happening, who’s involved, and the general atmosphere.\nVisual style: Defines the overall look and feel of the video — for example, cinematic, realistic, animated, stylized, or surreal.\nCamera movement: Describes how the camera should move during the scene — for instance, slow pan, static shot, tracking shot, or aerial zoom. Avoid using slang terms (eg ‘robo-arm’ or ‘lens crack’). Be clear and descriptive.\nMain subject: The primary person, character, or object that should be the focus of the video. Clearly describe who is doing what in the scene.\nBackground setting: The specific location or environment where the scene takes place — such as a city street at night, a forest during sunrise, or a futuristic lab., traditional village, etc.\nLighting/mood: Describes the type of lighting and the emotional tone you want — for example, soft natural light with a warm tone, or harsh lighting for a dramatic or tense mood.\nAudio cue (optional): Any specific sound or music that should be heard during the scene — such as a song starting when the character dances, or ambient sounds like rain, footsteps, or birdsong.\nColor palette: The dominant colors or tones used in the video — such as bold and bright, pastel, muted earth tones, or monochrome. This influences the emotional and visual impact.\nDialog / Background Noise (optional): If characters are speaking, specify exactly what they should say and when. You can also include environmental sounds like crowds, wind, or traffic.\nSubtitles and Language : Clearly state whether you want subtitles included or not (e.g., “Do not include subtitles” or “Include subtitles in English”). Note that mentioning a language can influence cultural context (clothing, signs, architecture) even if no spoken language is rendered. To imply language or culture, you can write things like: dialogue in Spanish, with English subtitles, on-screen text in Japanese, Arabic calligraphy visible on walls, Korean street signs in the background, etc.\nAdditional Planning Notes\nUsing ” or ” or ( ) or [ ] for the dialogue may generate subtitles – avoid these if you don’t want them.\nUse natural language\nUse long prompts. The more information and direction you can give, the better your output.\nUse a solid prompting structure, like the one outlined above.\nWriting Your Prompt\nOnce you’ve outlined the key information you want to include using the above structure (or something similar), you need to write your prompt. You can write this prompt yourself, or use a tool like Chat GPT to transform your dot point plan into a fully fledged prompt.\n\nCheck out the examples below to see how your prompt should look before hitting ‘Generate’!\n\nExample\nPrompt Plan:\n\nScene description: A glamorous woman with an afro hairstyle and gold jewellery shares a pool at night with a calm alligator, surrounded by dimly lit classical decor and blue ceramic vases.\nVisual style: Cinematic\nCamera movement: Slow zoom-in on the woman’s face from water level\nMain subject: Elegant woman in the pool next to an alligator, making intense eye contact with the camera\nBackground setting: Luxurious outdoor pool area with classical statues and large ceramic vases\nLighting/mood: Moody and soft, with candlelight reflections and subtle fill light on the face\nAudio cue: Slow ambient electronic music with occasional water ripple sounds\nColor palette: Deep slate gray, ocean blue, and warm gold tones\nDialog: “I’m not afraid of anything… except Sundays without drama.\nSubtitles: Off\nComplete Prompt:\n\nA cinematic scene set at night: a glamorous woman with an afro hairstyle and gold jewellery shares a luxurious outdoor pool with a calm alligator. The pool area is surrounded by classical statues and large blue ceramic vases, all dimly lit. The camera starts at water level and slowly zooms in on the woman’s face as she makes intense eye contact with the camera. The lighting is moody and soft, with candlelight reflections on the water and a subtle fill light on her face. The audio features slow ambient electronic music, with occasional water ripple sounds. The color palette includes deep slate gray, ocean blue, and warm gold tones. The woman says, “I’m not afraid of anything… except Sundays without drama.” No subtitles.\n\n\nNote:\n- At the end just provide me single prompt which contain every details just like \"Complete Prompt above\"\n- Make sure no double qoute is there in the response"},"promptType":"define","hasOutputParser":true},"typeVersion":2},{"id":"45c5196e-37ad-4db2-aa2f-50b79d7d4db2","name":"🧠 OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[80,320],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4.1-mini","cachedResultName":"gpt-4.1-mini"},"options":{}},"credentials":{"openAiApi":{"id":"69W0MY1rH5ycGoOb","name":"OpenAi account 2"}},"typeVersion":1.2},{"id":"fb2f6780-f6b4-43fb-93f3-199c33bbdc92","name":"📝 Structured Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[320,280],"parameters":{"schemaType":"manual","inputSchema":"{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"prompt\": {\n\t\t\t\"type\": \"string\"\n\t\t}\n\t}\n}"},"typeVersion":1.2},{"id":"bbc4704f-5f9d-4c05-a5b2-1da96c5dd8e7","name":"🎬 Create Video with VEO3 (Fal AI)","type":"n8n-nodes-base.httpRequest","position":[740,120],"parameters":{"url":"https://queue.fal.run/fal-ai/veo3","body":"={\n\"prompt\": \"{{ $json.output.prompt }}\"\n}","method":"POST","options":{"batching":{"batch":{"batchSize":1,"batchInterval":2000}}},"sendBody":true,"contentType":"raw","authentication":"genericCredentialType","rawContentType":"application/json","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"YC8HR4kSfpRBSFrp","name":"Fal AI Accounts"}},"typeVersion":4.2},{"id":"afa88152-0a60-4fb7-b765-7f737df81636","name":"🔍 Check Video Generation Status","type":"n8n-nodes-base.httpRequest","position":[960,120],"parameters":{"url":"=https://queue.fal.run/fal-ai/veo3/requests/{{ $json.request_id }}/status","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"YC8HR4kSfpRBSFrp","name":"Fal AI Accounts"}},"typeVersion":4.2},{"id":"93fda276-8061-4a20-a302-0aecc929a2ec","name":"✅ Is Video Generation Complete?","type":"n8n-nodes-base.if","position":[1180,60],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"571d2dfe-8a0c-416a-8780-3f47b17286b3","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"COMPLETED"}]}},"typeVersion":2.2},{"id":"c5803650-1462-41e2-bbf2-2b9f1a26bf98","name":"⏰ Wait Before Retry","type":"n8n-nodes-base.wait","position":[1400,220],"webhookId":"0f17aa86-f5f6-424c-b302-91bc70001367","parameters":{"amount":30},"typeVersion":1.1},{"id":"2ebccd28-fba3-4bb0-9e1a-386e4b71fd05","name":"📥 Download Generated Video","type":"n8n-nodes-base.httpRequest","position":[1400,0],"parameters":{"url":"=https://queue.fal.run/fal-ai/veo3/requests/{{ $json.request_id }}","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"YC8HR4kSfpRBSFrp","name":"Fal AI Accounts"}},"typeVersion":4.2},{"id":"3ab5da68-d834-41f9-aef3-9de8fa81b0b9","name":"📊 Update Sheet with Video URL","type":"n8n-nodes-base.googleSheets","position":[1860,140],"parameters":{"columns":{"value":{"Status":"completed","Video URL":"={{ $json.video.url }}","row_number":"={{ $('📊 Fetch Ready Ideas from Sheet').item.json.row_number }}"},"schema":[{"id":"Idea","type":"string","display":true,"removed":true,"required":false,"displayName":"Idea","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Status","type":"string","display":true,"required":false,"displayName":"Status","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Video URL","type":"string","display":true,"required":false,"displayName":"Video URL","defaultMatch":false,"canBeUsedToMatch":true},{"id":"row_number","type":"string","display":true,"removed":false,"readOnly":true,"required":false,"displayName":"row_number","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["row_number"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"update","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1VHJFdJjqKWT973NK4TVTdzodAiHM4Zzb4tIkK-kqqGc/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1VHJFdJjqKWT973NK4TVTdzodAiHM4Zzb4tIkK-kqqGc","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1VHJFdJjqKWT973NK4TVTdzodAiHM4Zzb4tIkK-kqqGc/edit?usp=drivesdk","cachedResultName":"VEO3 Video Generation"}},"credentials":{"googleSheetsOAuth2Api":{"id":"uvQG3YEEXtu5NVSj","name":"Freelance Account"}},"typeVersion":4.6},{"id":"b5bc4902-7953-4f5e-8ad1-65218fe5bb45","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[420,-660],"parameters":{"color":6,"width":500,"height":320,"content":"## 🎬 VEO3 AI Video Generation Pipeline\n**Automated video creation from ideas to final output**\n\n### 🔄 Workflow Steps:\n1. **Data Input** → Fetch video ideas from Google Sheets\n2. **Prompt Engineering** → AI generates optimized VEO3 prompts  \n3. **Video Creation** → Submit to VEO3 via Fal AI platform\n4. **Status Monitoring** → Poll until video generation completes\n5. **Result Storage** → Save video URL back to Google Sheets\n\n### 📝 Useful Docs\nVeo 3 Model Link - [Fal.ai](https://fal.ai/models/fal-ai/veo3)\n\n⚡ **Auto-retry system included for reliable video generation**"},"typeVersion":1},{"id":"e47be290-c70d-4972-8286-67267eca3302","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-640,-100],"parameters":{"width":520,"height":480,"content":"## 📊 Data Input & Trigger System\n**Fetches ready video ideas from Google Sheets**\n\n### 🔧 Configuration Required:\n- Set correct Google Sheets document ID\n- Filter for \"Status = ready\" rows\n- Ensure \"Idea\" column contains video concepts"},"typeVersion":1},{"id":"ece8e050-bc22-4d6c-ac88-178b60f68fe6","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-80,-240],"parameters":{"color":2,"width":700,"height":740,"content":"## 🤖 AI-Powered Prompt Engineering\n**Transforms simple ideas into detailed VEO3 prompts**\n\n### 🎯 Process:\n1. **Input:** Basic video idea from sheet\n2. **AI Analysis:** GPT-4 enhances with VEO3 best practices\n3. **Output:** Structured prompt with all required elements\n\n### 📝 Prompt Elements Generated:\n- Scene description & visual style\n- Camera movements & lighting\n- Main subjects & background settings\n- Color palette & audio cues\n- Subtitle preferences"},"typeVersion":1},{"id":"13f89c59-6c96-4d3f-a83a-55901ecbca1a","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[680,-240],"parameters":{"color":3,"width":980,"height":740,"content":"## 🎬 VEO3 Video Generation & Monitoring\n**Handles video creation with smart retry system**\n\n### ⚙️ Generation Settings:\n- **Aspect Ratio:** 9:16 (Mobile optimized)\n- **Duration:** 5 seconds\n- **Audio:** Generated automatically\n- **Prompt Enhancement:** Enabled\n\n### 🔄 Smart Monitoring:\n- Checks status every 30 seconds\n- Auto-retries until \"COMPLETED\"\n- Downloads final video when ready"},"typeVersion":1},{"id":"9c9e1dc4-afc5-4b90-8a22-acd2b68e86f8","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[1720,-240],"parameters":{"color":4,"width":400,"height":740,"content":"## 📥 Results Processing & Storage\n**Saves generated video URLs back to Google Sheets**\n\n### 💾 What Gets Saved:\n- Final video download URL\n- Updates same row where idea was fetched\n- Status automatically changes to \"completed\"\n\n### ✅ Success Indicators:\n- Video URL populated in sheet\n- File accessible via direct link\n- Ready for download/sharing"},"typeVersion":1},{"id":"360fb8b0-7a99-4bb3-8b0e-44c58fd15790","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-780,-900],"parameters":{"color":6,"width":520,"height":680,"content":"## 👨‍💻 Creator Information\n\n**Created by:** Lakshit Ukani  \n🔗 **LinkedIn:** [Connect with me](https://www.linkedin.com/in/lakshit-ukani/)\n🔗 **Youtube:** [Subscribe to my Channel](https://www.youtube.com/@lakshit-ukani?sub_confirmation=1)\n\n### Youtube Tutorial\n[![Thumbnail](https://i.ytimg.com/vi/kMRTaVRPwTw/hqdefault.jpg?s…BACGAY4AUAB&rs=AOn4CLCW0jAAbexQ34U3892BoCxYgrpDTw)](https://www.youtube.com/watch?v=kMRTaVRPwTw)\n\n### 🤝 Community & Support\n💬 **Join Community:** [Skool Community Link](https://www.skool.com/ai-automation-club-7843)   \n📚 **Documentation:** [VEO3 API Guide](https://docs.fal.ai/models/kling-video)  \n\n### 📞 Need Help?\n- **Quick Questions:** Comment on the YouTube video\n- **Workflow Issues:** Post in our community  \n- **Business Inquiries:** Connect via LinkedIn"},"typeVersion":1}],"connections":{"⏰ Wait Before Retry":{"main":[[{"node":"🔍 Check Video Generation Status","type":"main","index":0}]]},"🧠 OpenAI Chat Model":{"ai_languageModel":[[{"node":"🤖 VEO3 Prompt Generator (GPT-4.1)","type":"ai_languageModel","index":0}]]},"📝 Structured Output Parser":{"ai_outputParser":[[{"node":"🤖 VEO3 Prompt Generator (GPT-4.1)","type":"ai_outputParser","index":0}]]},"📥 Download Generated Video":{"main":[[{"node":"📊 Update Sheet with Video URL","type":"main","index":0}]]},"✅ Is Video Generation Complete?":{"main":[[{"node":"📥 Download Generated Video","type":"main","index":0}],[{"node":"⏰ Wait Before Retry","type":"main","index":0}]]},"📊 Fetch Ready Ideas from Sheet":{"main":[[{"node":"🤖 VEO3 Prompt Generator (GPT-4.1)","type":"main","index":0}]]},"🔍 Check Video Generation Status":{"main":[[{"node":"✅ Is Video Generation Complete?","type":"main","index":0}]]},"When clicking ‘Execute workflow’":{"main":[[{"node":"📊 Fetch Ready Ideas from Sheet","type":"main","index":0}]]},"🎬 Create Video with VEO3 (Fal AI)":{"main":[[{"node":"🔍 Check Video Generation Status","type":"main","index":0}]]},"🤖 VEO3 Prompt Generator (GPT-4.1)":{"main":[[{"node":"🎬 Create Video with VEO3 (Fal AI)","type":"main","index":0}]]}}}


name: Personalized Outreach for Lawyers with LinkedIn Scraping, GPT-4o, Google Sheets
author_name: Ibrahim Malick
author_username: imalick
categories: []
created_at: 2025-06-11T16:50:07.774Z
updated_at: 2025-06-11T16:50:07.774Z
url: https://n8n.io/workflows/4879
scraped_at: 2025-07-06 21:16:30
description:
   ⚠️ This template uses only official n8n nodes. No community nodes required.

  🧑‍💼 Who is this for?

  This workflow is designed for:
  Legal tech founders
  Marketing freelancers or consultants
  Agencies supporting lawyers and small law firms
  Anyone doing outbound outreach in the legal niche

  ❓ What problem is this solving?

  LinkedIn is a goldmine for targeting legal professionals — but scraping and personalizing outreach is tedious and expensive. Most tools either:
  Require paid LinkedIn Sales Navigator
  Can’t personalize at scale
  Violate LinkedIn’s TOS

  This workflow solves that by using free Google Search, OpenRouter AI, and GPT-4o to find, enrich, and message up to 1,000 solo lawyers per day — without using browser automation or scrapers.

  ⚙️ What this workflow does

  Uses Google Programmable Search to find solo lawyers and small firm founders on LinkedIn
  Parses each profile’s name, title, profile URL, and snippet
  Saves raw lead data to Google Sheets
  Uses OpenRouter Sonar Pro to enrich each profile with external content
  Generates a personalized, 1-line message using GPT-4o
  Appends the final message into Google Sheets for outreach

  🛠️ Setup

  Estimated time: 15–20 minutes

  ✅ Google Programmable Search
  Enable the Custom Search API on Google Cloud
  Create a programmable search engine set to search the full web
  Copy your API key and CX ID

  ✅ Google Sheets
  Create a sheet with columns: Name, Title, Profile URL, Outreach Message
  Share the sheet with your OAuth-connected Google account

  ✅ OpenRouter
  Sign up at openrouter.ai
  Fund with at least $5 and generate your API key
  Use the model perplexity/sonar-pro for real-time research

  ✅ GPT-4o (optional)
  You can use your OpenAI key or route GPT-4o via OpenRouter

  All setup-specific values are marked clearly in sticky notes and placeholders.

  🛠️ How to customize this workflow to your needs

  Change the Google search query to match your industry (e.g., "founder" AND "therapist" site:linkedin.com/in)
  Modify the AI prompt to match your tone (formal, casual, humorous)
  Connect the final output to your CRM (like HubSpot, Airtable, etc.)
  Add a second outreach message variant to A/B test performance

  📌 Sticky Notes & Annotations

  All nodes are clearly renamed for understandability (e.g., Find Lawyer Profiles, Parse LinkedIn Search Results)
  Color-coded sticky notes explain:
    Setup instructions
    Required credentials
    Use case

  🗂 Category

  AI
  Sales
  Marketing

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

workflow_json:
  {"id":"3gnnZ2YIkY7KtWGV","meta":{"instanceId":"a291c80784279d62713fb417464bee8a26739f051557bd426c15958e91c2a5b2","templateCredsSetupCompleted":true},"name":"Linkedin Leads Automation","tags":[{"id":"3wP6uU6SFbrRYs5q","name":"youtube","createdAt":"2025-05-17T22:21:11.653Z","updatedAt":"2025-05-17T22:21:11.653Z"}],"nodes":[{"id":"62e62e1f-e71d-4869-bceb-370e4ab853e2","name":"Set Fields","type":"n8n-nodes-base.set","position":[-1280,80],"parameters":{"options":{},"assignments":{"assignments":[{"id":"cc27b2d9-8de7-43ca-a741-2d150084f78e","name":"currentStartIndex","type":"number","value":1}]}},"typeVersion":3.4},{"id":"c762fb3b-5574-4a25-ac2a-aa6f007bf79e","name":"Add to Google","type":"n8n-nodes-base.googleSheets","position":[0,0],"parameters":{"columns":{"value":{"Name":"={{ $json.name }}","title":"={{ $json.position }}","profile_url":"={{ $json.link }}"},"schema":[{"id":"Name","type":"string","display":true,"required":false,"displayName":"Name","defaultMatch":false,"canBeUsedToMatch":true},{"id":"title","type":"string","display":true,"required":false,"displayName":"title","defaultMatch":false,"canBeUsedToMatch":true},{"id":"profile_url","type":"string","display":true,"required":false,"displayName":"profile_url","defaultMatch":false,"canBeUsedToMatch":true},{"id":"about","type":"string","display":true,"required":false,"displayName":"about","defaultMatch":false,"canBeUsedToMatch":true},{"id":"outreach message 1","type":"string","display":true,"required":false,"displayName":"outreach message 1","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/1jajDVL6_sMlrK6cQNkKPqPpUVOPUst_A7hyMg0cuyrM/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1jajDVL6_sMlrK6cQNkKPqPpUVOPUst_A7hyMg0cuyrM","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1jajDVL6_sMlrK6cQNkKPqPpUVOPUst_A7hyMg0cuyrM/edit?usp=drivesdk","cachedResultName":"linkedin"}},"credentials":{},"typeVersion":4.5},{"id":"b9ce466d-8080-40ec-8f3d-99e446ddee54","name":"OpenRouter Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[260,180],"parameters":{"model":"perplexity/sonar-pro","options":{}},"credentials":{},"typeVersion":1},{"id":"9451edb8-a7a6-4840-9eea-e799f4bf0721","name":"Research Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[280,0],"parameters":{"text":"=Name: {{ $json.name }}\nTitle: {{ $json.title }}\nAbout: {{ $json.about }}","options":{"systemMessage":"Your job is to research this lawyer or law firm founder as much as possible. The goal is to find relevant public information to help generate personalized outreach. This workflow is targeting solo practice lawyers and small law firms — not large firms or government attorneys. Avoid irrelevant sources. Focus on anything that reflects their legal focus (e.g., family law, criminal defense, small business law), local community involvement, or their firm’s branding. Include source references (e.g., LinkedIn posts, website articles, etc.). No intros or conclusions."},"promptType":"define"},"typeVersion":1.7},{"id":"b5855a64-d62c-401e-8596-99888ff3a8b6","name":"Google Search","type":"n8n-nodes-base.httpRequest","position":[-780,80],"parameters":{"url":"https://www.googleapis.com/customsearch/v1","options":{},"sendQuery":true,"queryParameters":{"parameters":[{"name":"key","value":"YOUR_API_KEY_OR_CX_ID"},{"name":"cx","value":"YOUR_API_KEY_OR_CX_ID"},{"name":"q","value":"(\"solo practitioner\" OR \"founder\" OR \"managing partner\") lawyer \"law firm\" site:linkedin.com/in -government -gov -biglaw"},{"name":"start","value":"={{ $json.startIndex || 1 }}"}]}},"typeVersion":4.2},{"id":"f36fb9ae-dcd3-44dd-8096-5ae6efd0f83b","name":"Results ","type":"n8n-nodes-base.code","position":[-440,80],"parameters":{"jsCode":"// Get the response data\nconst response = $input.first().json;\nconst items = response.items || [];\n\n// Track pagination info\nlet nextStartIndex = 1;\nif (response.queries && response.queries.nextPage && response.queries.nextPage[0]) {\n  nextStartIndex = response.queries.nextPage[0].startIndex;\n}\n\n// Calculate if we should continue (Google only allows up to 100 results)\nconst hasMoreResults = nextStartIndex <= 100;\n\n// Process the items and include pagination info in each item\nconst results = items.map(item => {\n  const titleParts = item.title.split(\" - \");\n  return {\n    name: titleParts[0] || null,\n    position: titleParts.slice(1).join(\" - \") || null,\n    link: item.link || null,\n    about: item.snippet || null,\n    image: item.pagemap?.cse_thumbnail?.[0]?.src || null,\n    // Add pagination info to each item\n    startIndex: nextStartIndex,\n    hasMoreResults: hasMoreResults\n  };\n});\n\n// If there are no results, return at least one item with pagination info\nif (results.length === 0) {\n  return [{ \n    json: {\n      name: null,\n      position: null,\n      link: null,\n      about: null,\n      image: null,\n      startIndex: nextStartIndex,\n      hasMoreResults: false\n    }\n  }];\n}\n\n// Return the processed results\nreturn results.map(r => ({ json: r }));\n"},"typeVersion":2},{"id":"e3cbad5a-2022-4c67-bde1-87ac77687539","name":"Pages","type":"n8n-nodes-base.code","position":[0,200],"parameters":{"jsCode":"// Get all input items\nconst inputItems = $input.all();\nconsole.log(\"Input items count:\", inputItems.length);\n\n// Extract pagination values with correct field names\nlet nextStartIndex = 1;\nlet hasMoreResults = false;\n\nif (inputItems && inputItems.length > 0) {\n  const firstItem = inputItems[0];\n\n  if (firstItem.json) {\n    console.log(\"First item JSON:\", JSON.stringify(firstItem.json));\n\n    // Look for \"startIndex\" instead of \"index\"\n    if (firstItem.json.startIndex !== undefined) {\n      nextStartIndex = firstItem.json.startIndex;\n      console.log(\"Found startIndex:\", nextStartIndex);\n    }\n\n    // Look for \"hasMoreResults\" instead of \"results\"\n    if (firstItem.json.hasMoreResults !== undefined) {\n      hasMoreResults = firstItem.json.hasMoreResults;\n      console.log(\"Found hasMoreResults:\", hasMoreResults);\n    }\n  }\n}\n\n// Return pagination control info\nreturn {\n  json: {\n    continueLoop: hasMoreResults,\n    startIndex: nextStartIndex\n  }\n};\n"},"typeVersion":2},{"id":"94b87b0b-0bff-4e13-a710-b2f2b9702cd9","name":"Pages Check","type":"n8n-nodes-base.if","position":[-1040,200],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"faef2862-80a4-465b-9e0b-be5b9753dcbd","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $('Pages').item.json.continueLoop }}","rightValue":"true"}]}},"typeVersion":2.2},{"id":"e41547c3-ed14-4882-906a-d0005f85ca4b","name":"Google Sheets","type":"n8n-nodes-base.googleSheets","position":[1340,0],"parameters":{"columns":{"value":{"name":"={{ $('Results ').all()[ $itemIndex ].json.name }}","outreach message 1":"={{ $json.message.content }}"},"schema":[{"id":"name","type":"string","display":true,"removed":false,"required":false,"displayName":"name","defaultMatch":false,"canBeUsedToMatch":true},{"id":"title","type":"string","display":true,"required":false,"displayName":"title","defaultMatch":false,"canBeUsedToMatch":true},{"id":"profile_url","type":"string","display":true,"required":false,"displayName":"profile_url","defaultMatch":false,"canBeUsedToMatch":true},{"id":"about","type":"string","display":true,"required":false,"displayName":"about","defaultMatch":false,"canBeUsedToMatch":true},{"id":"outreach message 1","type":"string","display":true,"required":false,"displayName":"outreach message 1","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["name"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"appendOrUpdate","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1smDBk1Eh50sRyTEzEhzWkDnaWaexZHiHTxYlp2M6_J0/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1smDBk1Eh50sRyTEzEhzWkDnaWaexZHiHTxYlp2M6_J0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1smDBk1Eh50sRyTEzEhzWkDnaWaexZHiHTxYlp2M6_J0/edit?usp=drivesdk","cachedResultName":"linkedin"}},"credentials":{},"typeVersion":4.5},{"id":"5dccf520-fe74-458a-8e9d-34bc69cd5f54","name":"Outreach Agent","type":"@n8n/n8n-nodes-langchain.openAi","position":[700,0],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4o","cachedResultName":"GPT-4O"},"options":{},"messages":{"values":[{"role":"system","content":"Your job is to create a short, personalized outreach icebreaker for solo lawyers or small law firm owners. Keep it genuine, professional, and brief — one line max. You may refer to their practice area, years in practice, recent content, community involvement, or anything that reflects their personal brand. Avoid generic statements. Do not ask about location. Do not mention large law firms or government service. Use a business-casual tone, and start with: \"Hey [name] ...\""},{"content":"=Name: {{ $('Results ').all()[ $itemIndex ].json.name }}\nPosition: {{ $('Results ').all()[ $itemIndex ].json.position }}\nAbout: {{ $('Results ').all()[ $itemIndex ].json.about }}\n"}]}},"credentials":{},"typeVersion":1.8},{"id":"8340fc87-c844-4861-a4ff-75f7da7274a3","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-1480,80],"parameters":{"rule":{"interval":[{}]}},"typeVersion":1.2}],"active":true,"settings":{"executionOrder":"v1"},"versionId":"69a6fdbc-0653-4c7a-8258-17146dd20530","connections":{"Pages":{"main":[[{"node":"Pages Check","type":"main","index":0}]]},"Results ":{"main":[[{"node":"Add to Google","type":"main","index":0},{"node":"Pages","type":"main","index":0}]]},"Set Fields":{"main":[[{"node":"Google Search","type":"main","index":0}]]},"Pages Check":{"main":[[{"node":"Google Search","type":"main","index":0}]]},"Add to Google":{"main":[[{"node":"Research Agent","type":"main","index":0}]]},"Google Search":{"main":[[{"node":"Results ","type":"main","index":0}]]},"Outreach Agent":{"main":[[{"node":"Google Sheets","type":"main","index":0}]]},"Research Agent":{"main":[[{"node":"Outreach Agent","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Set Fields","type":"main","index":0}]]},"OpenRouter Chat Model":{"ai_languageModel":[[{"node":"Research Agent","type":"ai_languageModel","index":0}]]}}}


name: Turn Google Sheets Ideas into AI Videos with GPT-4o and Fal.AI Veo 3
author_name: Maximiliano Rojas-Delgado
author_username: maxr
nodes_used: ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","@n8n/n8n-nodes-langchain.openAi"]
categories: []
created_at: 2025-06-11T19:54:02.502Z
updated_at: 2025-06-11T19:54:02.502Z
url: https://n8n.io/workflows/4881
scraped_at: 2025-07-06 21:16:30
description:
  Turn Your Ideas into Videos—Right from Google Sheets!

  This workflow helps you make cool 8-second videos using Fal.AI and Veo 3, just by typing your idea into a Google Sheet. You can even choose if you want your video to have sound or not. It’s super easy—no tech skills needed!

  Why use this?

  Just type your idea in a sheet—no fancy tools or uploads.

  Get a video link back in the same sheet.

  Works with or without sound—your choice!

  How does it work?

  You write your idea, pick the video shape, and say if you want sound (true or false) in the Google Sheet.

  n8n reads your idea and asks Fal.AI to make your video.

  When your video is ready, the link shows up in your sheet.

  What do you need?

  A Google account and Google Sheets connected with service account (check this link for reference)
  A copy of the following Google Spreadsheet:
  Spreadsheet to copy

  An OpenAI API key

  A Fal.AI account with some money in it

  That’s it! Just add your ideas and let the workflow make the videos for you. Have fun creating!

  if you have any questions, just contact me at max@nervoai.com

workflow_json:
  {"id":"wGQOrU5qak5K99FT","meta":{"instanceId":"d59922ccaab8f9a216dbe3eacc226c7a17998a61f6c4177822cd8e33edb224d7"},"name":"Google Sheets to Veo 3: Instantly Create Videos with n8n & Fal.AI","tags":[{"id":"fElGhCk9TINqseuM","name":"templates","createdAt":"2025-06-11T19:44:28.283Z","updatedAt":"2025-06-11T19:44:28.283Z"},{"id":"I8yfdg9mSqeqo4nX","name":"creator","createdAt":"2025-06-11T19:44:30.157Z","updatedAt":"2025-06-11T19:44:30.157Z"}],"nodes":[{"id":"7beb408f-128b-4e4c-8d03-e5625fbcb2eb","name":"Wait 5s","type":"n8n-nodes-base.wait","position":[340,620],"webhookId":"150069ed-885b-497f-a32a-09e7088136e6","parameters":{},"typeVersion":1.1},{"id":"77d6a74f-b704-40f2-b054-fbf91c93726a","name":"Check if video is ready","type":"n8n-nodes-base.if","position":[160,620],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"ac50759b-e2f3-4efd-a2af-f28b7d209b45","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"COMPLETED"}]}},"typeVersion":2.2},{"id":"cd94d480-3562-4ce3-aff0-9caf5dee9f72","name":"Get video url","type":"n8n-nodes-base.httpRequest","position":[0,940],"parameters":{"url":"={{ $json.response_url }}","options":{},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"Authorization","value":"Key <YOUR_API_KEY>"}]}},"typeVersion":4.2},{"id":"5267ac1d-36ad-449a-9f5f-cae01a090b33","name":"Generate prompt for Veo 3 model","type":"@n8n/n8n-nodes-langchain.openAi","position":[180,-20],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"chatgpt-4o-latest","cachedResultName":"CHATGPT-4O-LATEST"},"options":{},"messages":{"values":[{"role":"assistant","content":"=You are a creative prompt engineer for Google's Veo 3 video generation model. For any concept provided, craft a detailed, visually immersive prompt that specifies the subject, setting, lighting, mood, era or style, object details, composition, and background elements. Use evocative, sensory-rich language and guide the model to produce authentic, high-quality images. Match the style and depth of the following example:\n\nA casual street interview on a busy New York City sidewalk in the afternoon. The interviewer holds a plain, unbranded microphone and asks: Have you seen Google's new Veo3 model It is a super good model. Person replies: Yeah I saw it, it's already available on fal. It's crazy good.\n\nRespond only with the crafted prompt."},{"content":"=the input is: {{ $json.Idea }}"}]}},"credentials":{"openAiApi":{"id":"6iZ86Vz38pnHnAuF","name":"OpenAi account"}},"typeVersion":1.8},{"id":"a5864945-030e-4d80-83cb-2f558399d8bf","name":"Submit Request to generate video","type":"n8n-nodes-base.httpRequest","position":[340,300],"parameters":{"url":"https://queue.fal.run/fal-ai/veo3","method":"POST","options":{},"jsonBody":"={\n  \"prompt\": \"{{ $json.prompt }}\",\n  \"aspect_ratio\": \"{{ $json.ratio }}\",\n  \"enhance_prompt\": true,\n  \"generate_audio\": {{ $json.audio }}\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json"},{"name":"authorization","value":"Key <YOUR_API_KEY>"}]}},"typeVersion":4.2},{"id":"00f339c8-f6e3-42b3-aa56-abe34268c68a","name":"Set variables for Video generation","type":"n8n-nodes-base.set","position":[0,300],"parameters":{"options":{},"assignments":{"assignments":[{"id":"4807c116-ed98-4a0e-8dba-aab1dd2ee971","name":"prompt","type":"string","value":"={{ $json.message.content }}"},{"id":"32437b05-fa7a-4f3b-bad0-fc7201cc7371","name":"ratio","type":"string","value":"={{ $('Google Sheets Trigger').item.json.Ratio }}"},{"id":"4cf00dd2-9057-4868-93ac-7f9725750d77","name":"audio","type":"string","value":"={{ $('Google Sheets Trigger').item.json.Audio }}"}]}},"typeVersion":3.4},{"id":"88429b78-fe9f-42ca-81e1-0b364703ab2a","name":"Check video status","type":"n8n-nodes-base.httpRequest","position":[0,620],"parameters":{"url":"=https://queue.fal.run/fal-ai/veo3/requests/{{ $json.request_id }}/status","options":{},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"Authorization","value":"Key <YOUR_API_KEY>"}]}},"typeVersion":4.2},{"id":"26e74f30-575f-407a-99ee-f75daad9a2e4","name":"Google Sheets Trigger","type":"n8n-nodes-base.googleSheetsTrigger","position":[0,-20],"parameters":{"event":"rowAdded","options":{},"pollTimes":{"item":[{"mode":"everyMinute"}]},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/100ur8DnU_q2YIAx15ccMfEWC43Di_G7hj19csjxg73A/edit#gid=0","cachedResultName":"Results"},"documentId":{"__rl":true,"mode":"list","value":"100ur8DnU_q2YIAx15ccMfEWC43Di_G7hj19csjxg73A","cachedResultUrl":"https://docs.google.com/spreadsheets/d/100ur8DnU_q2YIAx15ccMfEWC43Di_G7hj19csjxg73A/edit?usp=drivesdk","cachedResultName":"Veo 3 template"}},"credentials":{"googleSheetsTriggerOAuth2Api":{"id":"CUMqe7iFy7F1KIF9","name":"Google Sheets account NervoAI"}},"typeVersion":1},{"id":"57f0306d-3b12-4717-afc6-c548863c2f7f","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-780,-80],"parameters":{"color":5,"width":700,"height":1140,"content":"## Google Sheets to Veo 3: Instantly Create Videos with n8n & Fal.AI\n\nEasily generate 8-second videos using Fal.AI’s Veo 3 model—just add a row to your Google Sheet with your idea, the video ratio, and whether you want audio (true/false).\n\nHere’s what Fal.AI charges:\n\n1s video: $0.50\n\n1s video with audio: $0.75\n\n8s video (default): $4.00\n\n8s video with audio: $6.00\n\nHere are the execution times:\n\n8s video (default): 3 minutes\n\n8s video with audio: 15 minutes\n\n**Step 1: Connect Google Sheets**\n\nAdd your Google service account credentials and make sure Google Sheets API is enabled in your Google Cloud project.\n\nCopy the shared template sheet in the description.\n\nDouble-check that your n8n Google Sheets nodes are linked to the correct spreadsheet.\n\n**Step 2: Connect OpenAI**\n\nGet your OpenAI API key.\n\nAdd your OpenAI credentials in n8n.\n\n**Step 3: Set Up Fal.ai**\n\nSign up at fal.ai and top up your account.\n\nGrab your API key from the Fal.ai dashboard.\n\nIn n8n, update the \"Submit Request to generate video,\" \"Check video status,\" and \"Get video url\" nodes. Replace the authorization header with your API key: 'Key <YOUR_API_KEY>'\n\n**Step 4: View Results in the Sheet**\n\nOnce your sheet updates, you’ll see the prompt used and the video URL.\n\n** Troubleshoot**\nIf the “Audio” column shows as a boolean instead of text and gives error generating the video, enter it as '=\"true\"' or '=\"false\"' in the spreadsheet.\n\nif any other issue, please contact me at max@nervoai.com\n\n\nThat’s it! You’re ready to create Veo 3 videos straight from Google Sheets.\n"},"typeVersion":1},{"id":"9dc75bc3-25a7-4c3c-bb65-8372acb2703b","name":"Update sheet with video url and prompt used in Veo3","type":"n8n-nodes-base.googleSheets","position":[340,940],"parameters":{"columns":{"value":{"Idea":"={{ $('Google Sheets Trigger').item.json.Idea }}","Video Generated":"={{ $json.video.url }}","Prompt Generated":"={{ $('Generate prompt for Veo 3 model').item.json.message.content }}"},"schema":[{"id":"Idea","type":"string","display":true,"removed":false,"required":false,"displayName":"Idea","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Ratio","type":"string","display":true,"required":false,"displayName":"Ratio","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Audio","type":"string","display":true,"required":false,"displayName":"Audio","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Prompt Generated","type":"string","display":true,"required":false,"displayName":"Prompt Generated","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Video Generated","type":"string","display":true,"required":false,"displayName":"Video Generated","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":["Idea"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"update","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/100ur8DnU_q2YIAx15ccMfEWC43Di_G7hj19csjxg73A/edit#gid=0","cachedResultName":"Results"},"documentId":{"__rl":true,"mode":"list","value":"100ur8DnU_q2YIAx15ccMfEWC43Di_G7hj19csjxg73A","cachedResultUrl":"https://docs.google.com/spreadsheets/d/100ur8DnU_q2YIAx15ccMfEWC43Di_G7hj19csjxg73A/edit?usp=drivesdk","cachedResultName":"Veo 3 template"}},"credentials":{"googleSheetsOAuth2Api":{"id":"f8o05SKiFZmuFhu9","name":"Google Sheets account nervoAI"}},"typeVersion":4.6},{"id":"774b9b76-4cd8-4d5a-8b8b-587ee1cae464","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-40,-140],"parameters":{"color":3,"width":540,"height":300,"content":"## Stage 1: Trigger & Prompt Generation\nStarts the workflow when a new row is added in Google Sheets, then when the workflow is actioned, it generates a prompt for the Veo 3 video model based on the sheet data."},"typeVersion":1},{"id":"169699a3-6208-4586-8c3c-a3df7f3cdaf2","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-40,180],"parameters":{"color":6,"width":540,"height":300,"content":"## Stage 2: Prepare & Submit Video Request\nSets up all necessary variables for video creation and sends a request to Fal.AI to generate the video."},"typeVersion":1},{"id":"739cdf63-5e11-4364-b4f8-3b65e962ce3e","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-40,500],"parameters":{"width":540,"height":300,"content":"## Stage 3: Monitor Video Status\nChecks the status of the video generation. Waits and repeatedly checks every 5 seconds until the video is ready."},"typeVersion":1},{"id":"49c27097-de0e-4516-8ee0-8936507d7455","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-40,820],"parameters":{"color":4,"width":540,"height":300,"content":"## Stage 4: Retrieve & Update Results\nGets the final video URL and updates the Google Sheet with the video link and the prompt used."},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"9f0cad2c-2edc-4ab2-9a10-0ae019069b35","connections":{"Wait 5s":{"main":[[{"node":"Check video status","type":"main","index":0}]]},"Get video url":{"main":[[{"node":"Update sheet with video url and prompt used in Veo3","type":"main","index":0}]]},"Check video status":{"main":[[{"node":"Check if video is ready","type":"main","index":0}]]},"Google Sheets Trigger":{"main":[[{"node":"Generate prompt for Veo 3 model","type":"main","index":0}]]},"Check if video is ready":{"main":[[{"node":"Get video url","type":"main","index":0}],[{"node":"Wait 5s","type":"main","index":0}]]},"Generate prompt for Veo 3 model":{"main":[[{"node":"Set variables for Video generation","type":"main","index":0}]]},"Submit Request to generate video":{"main":[[{"node":"Check video status","type":"main","index":0}]]},"Set variables for Video generation":{"main":[[{"node":"Submit Request to generate video","type":"main","index":0}]]}}}


name: Convert PDF Documents to AI Podcasts with Google Gemini and Text-to-Speech
author_name: Mathis
author_username: iamthis
categories: []
created_at: 2025-06-11T20:48:43.573Z
updated_at: 2025-06-11T20:48:43.573Z
url: https://n8n.io/workflows/4883
scraped_at: 2025-07-06 21:16:30
description:
  Convert PDF documents to AI-generated podcasts with Google Gemini and Text-to-Speech

  Transform any PDF document into an engaging, natural-sounding podcast using Google's Gemini AI and advanced Text-to-Speech technology. This automated workflow extracts text content, generates conversational scripts, and produces high-quality audio files.

  Who is this for?

  This workflow template is perfect for content creators, educators, researchers, and marketing professionals who want to repurpose written content into audio format. Ideal for creating podcast episodes, educational content, or making documents more accessible.

  What problem does this solve?

  Converting written documents to engaging audio content manually is time-consuming and requires scriptwriting skills. This workflow automates the entire process, turning static PDFs into dynamic, conversational podcasts that sound natural and engaging.

  What this workflow does

  Extracts text from uploaded PDF documents
  Generates podcast script using Google Gemini AI with conversational tone
  Converts script to speech using Google's advanced TTS with customizable voices
  Processes audio into properly formatted WAV files
  Saves final podcast ready for distribution

  Setup

  Obtain API credentials:
     Get Google Gemini API key from AI Studio
     Configure credentials in n8n as "Google Gemini(PaLM) Api account"

  Configure voice settings:
     Choose from available voices: Kore (professional), Aoede (conversational), Laomedeia (energetic)
     Customize script generation prompts if needed

  Test the workflow:
     Upload a sample PDF file
     Verify audio output quality
     Adjust voice settings as preferred

  How to customize this workflow

  Modify script style:** Edit the prompt in the "Generate Podcast Script" node to change tone, length, or format
  Change voice:** Update the voice name in "Prepare TTS Request" node
  Add preprocessing:** Insert text cleaning nodes before script generation
  Integrate with storage:** Connect to Google Drive, Dropbox, or other storage services
  Add notifications:** Include Slack or email notifications when podcasts are ready

  Note: This template requires Google Gemini API access and works best with text-based PDF files under 10MB.

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

workflow_json:
  {"meta":{"instanceId":"3b439b2efefd3a3727fcde770e801989ddd80f304fce43a46dd089f21c19f2fb","templateCredsSetupCompleted":true},"nodes":[{"id":"37a9addb-a90e-4491-8b7a-a42fad57329a","name":"🎬 Start: Upload PDF File","type":"n8n-nodes-base.manualTrigger","position":[-340,-60],"parameters":{},"typeVersion":1},{"id":"dd475138-a5fa-4818-aeaa-27e8e0969367","name":"📄 Extract Text from PDF","type":"n8n-nodes-base.extractFromFile","position":[-120,-60],"parameters":{"options":{},"operation":"pdf","binaryPropertyName":"data0"},"typeVersion":1},{"id":"9a24fae8-ac8c-48a0-a985-69e0b4a3e0b8","name":"🤖 Generate Podcast Script","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[100,-160],"parameters":{"text":"={{ $json.text }}","batching":{},"messages":{"messageValues":[{"message":"=Create an engaging podcast script based on the following content. The script should be exactly 5-7 minutes when read aloud (approximately 750-1000 words).  CONTENT TO DISCUSS: {content}  STYLE: {style}  PODCAST SCRIPT REQUIREMENTS: 1. Start with: \"Welcome to our AI-generated podcast. Today we're diving into...\" 2. Structure: Introduction, 2-3 main discussion points, conclusion 3. Use natural conversational language 4. Include smooth transitions between topics 5. Add brief pauses with periods and commas for natural speech 6. Avoid complex punctuation that might confuse TTS 7. End with: \"Thanks for listening! This has been your AI podcast.\" 8. Write ONLY the spoken content (no stage directions) 9. Keep sentences moderate length for clear speech 10. Use engaging storytelling techniques"}]},"promptType":"define"},"typeVersion":1.7},{"id":"87891658-777b-47bf-9a86-9c23076a7477","name":"Google Gemini Flash 2.0","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[188,60],"parameters":{"options":{},"modelName":"models/gemini-2.0-flash-001"},"credentials":{"googlePalmApi":{"id":"ssUBiwRgjxx0Dj8n","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"8ebba81a-a42e-48cf-aeaa-1263fe59ed90","name":"⚙️ Prepare TTS Request","type":"n8n-nodes-base.code","position":[480,-60],"parameters":{"jsCode":"const script = $input.first().json.text;\nconst voiceName = $input.first().json.voiceName || \"Kore\";\n\nreturn {\n  json: {\n    requestBody: {\n      contents: [{\n        parts: [{\n          text: script\n        }]\n      }],\n      generationConfig: {\n        responseModalities: [\"AUDIO\"],\n        speechConfig: {\n          voiceConfig: {\n            prebuiltVoiceConfig: {\n              voiceName: voiceName\n            }\n          }\n        }\n      }\n    }\n  }\n};"},"typeVersion":2},{"id":"78e3f968-ec21-4d85-a802-688f1d33b48c","name":"🎙️ Convert Text to Speech With Gemini","type":"n8n-nodes-base.httpRequest","position":[696,-60],"parameters":{"url":"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-tts:generateContent","method":"POST","options":{},"jsonBody":"={{ $json.requestBody }}","sendBody":true,"sendHeaders":true,"specifyBody":"json","authentication":"predefinedCredentialType","headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json"}]},"nodeCredentialType":"googlePalmApi"},"credentials":{"googlePalmApi":{"id":"ssUBiwRgjxx0Dj8n","name":"Google Gemini(PaLM) Api account"},"httpCustomAuth":{"id":"wGstDoq0x8ov0ube","name":"Tavily Custom Auth account"}},"typeVersion":4.2},{"id":"1baddfca-84c4-4ffd-beb8-5acb919112fe","name":"🔧 Process Audio Response","type":"n8n-nodes-base.code","position":[916,-60],"parameters":{"jsCode":"const response = $input.all()[0].json;\n\nconsole.log('=== GEMINI TTS DEBUG ===');\nconsole.log('Response status:', response.candidates?.[0]?.finishReason);\n\nif (response.candidates?.[0]?.finishReason === 'STOP') {\n  try {\n    // Get the base64 audio data\n    const base64AudioData = response.candidates[0].content.parts[0].inlineData.data;\n    const mimeType = response.candidates[0].content.parts[0].inlineData.mimeType;\n    \n    console.log('Audio data length:', base64AudioData.length);\n    console.log('Mime type:', mimeType);\n    \n    // CRITICAL FIX: Properly decode base64 to actual audio bytes\n    const actualAudioBytes = Buffer.from(base64AudioData, 'base64');\n    \n    console.log('Decoded audio size:', actualAudioBytes.length);\n    \n    // Create WAV file with proper PCM16 format\n    const sampleRate = 24000;\n    const channels = 1;\n    const bitsPerSample = 16;\n    \n    // Create WAV header\n    const wavHeader = createWavHeader(actualAudioBytes.length, sampleRate, channels, bitsPerSample);\n    const wavFile = Buffer.concat([wavHeader, actualAudioBytes]);\n    \n    const filename = `tts_fixed_${Date.now()}.wav`;\n    \n    return {\n      json: {\n        success: true,\n        filename: filename,\n        audioSize: wavFile.length,\n        audioSizeMB: (wavFile.length / 1024 / 1024).toFixed(2),\n        originalBase64Length: base64AudioData.length,\n        decodedAudioLength: actualAudioBytes.length\n      },\n      binary: {\n        audio: {\n          data: wavFile,\n          mimeType: 'audio/wav',\n          fileName: filename\n        }\n      }\n    };\n    \n  } catch (error) {\n    return {\n      json: {\n        success: false,\n        error: error.message,\n        step: 'audio_processing'\n      }\n    };\n  }\n} else {\n  return {\n    json: {\n      success: false,\n      error: 'TTS generation failed',\n      finishReason: response.candidates?.[0]?.finishReason || 'unknown',\n      response: response\n    }\n  };\n}\n\n// Helper function to create WAV header\nfunction createWavHeader(dataLength, sampleRate, channels, bitsPerSample) {\n  const byteRate = sampleRate * channels * bitsPerSample / 8;\n  const blockAlign = channels * bitsPerSample / 8;\n  const header = Buffer.alloc(44);\n  \n  // \"RIFF\" chunk descriptor\n  header.write('RIFF', 0);\n  header.writeUInt32LE(36 + dataLength, 4);\n  header.write('WAVE', 8);\n  \n  // \"fmt \" sub-chunk\n  header.write('fmt ', 12);\n  header.writeUInt32LE(16, 16); // Sub-chunk size\n  header.writeUInt16LE(1, 20);  // Audio format (PCM)\n  header.writeUInt16LE(channels, 22);\n  header.writeUInt32LE(sampleRate, 24);\n  header.writeUInt32LE(byteRate, 28);\n  header.writeUInt16LE(blockAlign, 32);\n  header.writeUInt16LE(bitsPerSample, 34);\n  \n  // \"data\" sub-chunk\n  header.write('data', 36);\n  header.writeUInt32LE(dataLength, 40);\n  \n  return header;\n}"},"typeVersion":2},{"id":"36978e98-5d80-4859-868f-5f8e6ddcb569","name":"💾 Save Podcast Audio","type":"n8n-nodes-base.writeBinaryFile","position":[1136,-60],"parameters":{"options":{},"fileName":"={{ $json.filename }}","dataPropertyName":"audio"},"typeVersion":1},{"id":"0deff03c-60f7-4fd0-84e2-96527caba405","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-360,-680],"parameters":{"width":320,"height":400,"content":"## 🎯 Main Template Overview\nWhat this workflow does:\n- Extracts text from uploaded PDF files\n- Generates conversational podcast script using AI\n- Converts script to natural-sounding audio\n- Saves final podcast as WAV file\n\nSetup required:\n- Google Gemini API key (for AI script generation)\n- Google PaLM API credentials (for TTS)\n- File upload capability"},"typeVersion":1},{"id":"b867911c-8add-450c-89d8-906cace883ad","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-20,-680],"parameters":{"color":5,"width":300,"height":400,"content":"## 🔧 Setup Instructions\nBefore You Start:\n\nGet API Keys:\n- Gemini API: https://aistudio.google.com/\n- Add to n8n credentials as \"Google Gemini(PaLM) Api account\"\n\n\nTest the workflow:\n- Use the manual trigger\n- Upload a PDF file\n- Check that audio file is generated"},"typeVersion":1}],"connections":{"Google Gemini Flash 2.0":{"ai_languageModel":[[{"node":"🤖 Generate Podcast Script","type":"ai_languageModel","index":0}]]},"⚙️ Prepare TTS Request":{"main":[[{"node":"🎙️ Convert Text to Speech With Gemini","type":"main","index":0}]]},"📄 Extract Text from PDF":{"main":[[{"node":"🤖 Generate Podcast Script","type":"main","index":0}]]},"🎬 Start: Upload PDF File":{"main":[[{"node":"📄 Extract Text from PDF","type":"main","index":0}]]},"🔧 Process Audio Response":{"main":[[{"node":"💾 Save Podcast Audio","type":"main","index":0}]]},"🤖 Generate Podcast Script":{"main":[[{"node":"⚙️ Prepare TTS Request","type":"main","index":0}]]},"🎙️ Convert Text to Speech With Gemini":{"main":[[{"node":"🔧 Process Audio Response","type":"main","index":0}]]}}}


name: AI Icebreaker Builder: Scrape Sites with Dumpling AI and Save to Airtable
author_name: Yang
author_username: yang
nodes_used: ["n8n-nodes-base.airtable","n8n-nodes-base.httpRequest","@n8n/n8n-nodes-langchain.openAi"]
categories: []
created_at: 2025-06-11T21:52:55.601Z
updated_at: 2025-06-11T21:52:55.601Z
url: https://n8n.io/workflows/4885
scraped_at: 2025-07-06 21:16:30
description:
  Who is this for?

  This workflow is ideal for sales teams, marketers, and virtual assistants who manage outbound campaigns and want to improve their cold outreach personalization. It helps automate the research and writing process for each lead, saving time while improving quality.

  What problem is this workflow solving?

  Cold outreach often lacks personalization because manually reviewing each lead's website takes time. This workflow eliminates that bottleneck by using AI to auto-generate personalized icebreakers, summaries, and outreach emails based on a lead’s website—without human research.

  What this workflow does

  This n8n workflow runs on a schedule and pulls leads from Airtable who don't yet have an "Ice breaker" field filled out. For each lead, it does the following:

  Trigger: Scheduled daily via the Run Daily to Process New Leads node.
  Search Airtable: Finds leads in Airtable where the Ice breaker field is empty using the Search Cold Leads Without Icebreaker node.
  Split in Batches: Iterates through each lead one by one using Loop Through Each Lead.
  Rate Limiting: Waits briefly before each request using Wait Before Making Request to avoid rate limits.
  Scrape Website: Sends each lead’s website to Dumpling AI's /scrape endpoint via the Scrape Lead Website with Dumpling AI HTTP request.
  Generate AI Copy: Sends the scraped content to GPT-4o using the Generate Icebreaker, Summary & Email (GPT-4o) node. It asks the LLM to create:
     A short personalized icebreaker
     A 2–3 line website summary
     A short email body for cold outreach
  Save Results: Updates the original Airtable record with the generated content using the Save AI Output Back to Airtable node.
  Sticky Note: Provides an overview of the workflow and usage instructions for future editors or collaborators.

  This loop continues for all leads found, updating Airtable with fresh AI-generated outreach content.

  Integration Requirements

  Airtable (Personal Access Token)
  Dumpling AI API Key (Header Auth)
  OpenAI (GPT-4o)

workflow_json:
  {"id":"FQ3d3ucbw3NXgnUo","meta":{"instanceId":"a1ae5c8dc6c65e674f9c3947d083abcc749ef2546dff9f4ff01de4d6a36ebfe6","templateCredsSetupCompleted":true},"name":"AI Icebreaker Builder: Scrape Sites with Dumpling AI and Save to Airtable","tags":[],"nodes":[{"id":"40c158ab-6e9c-4296-873c-c879714b65a6","name":"No Operation, do nothing","type":"n8n-nodes-base.noOp","position":[100,-140],"parameters":{},"typeVersion":1},{"id":"d63720a5-9785-45d1-a8ba-a9c961031095","name":"Run Daily to Process New Leads","type":"n8n-nodes-base.scheduleTrigger","position":[-560,60],"parameters":{"rule":{"interval":[{}]}},"typeVersion":1.2},{"id":"e5804c37-2a8d-4574-852a-f885c6941e31","name":"Search Cold Leads Without Icebreaker","type":"n8n-nodes-base.airtable","position":[-340,60],"parameters":{"base":{"__rl":true,"mode":"list","value":"","cachedResultUrl":"https://airtable.com/appPSvSKdA6075xJC","cachedResultName":"Testing n8n"},"table":{"__rl":true,"mode":"list","value":"","cachedResultUrl":"https://airtable.com/appPSvSKdA6075xJC/tbl1KgkRF2EEMc2Fq","cachedResultName":"cold leads"},"options":{},"operation":"search","filterByFormula":"{Ice breaker} = ''"},"credentials":{"airtableTokenApi":{"id":"H8PVkBgUPCcUhhRC","name":"Airtable Personal Access Token account"}},"typeVersion":2.1},{"id":"839fd20b-5a5d-4419-85b0-9b82223c8b95","name":"Loop Through Each Lead","type":"n8n-nodes-base.splitInBatches","position":[-120,60],"parameters":{"options":{}},"typeVersion":3},{"id":"78b197e2-6028-49a0-9100-5cc44838a9cd","name":"Wait Before Making Request","type":"n8n-nodes-base.wait","position":[100,60],"webhookId":"d6b29fad-724c-49ad-93ed-6ebfe17d3a4c","parameters":{},"typeVersion":1.1},{"id":"de96d330-006b-4410-8b75-83c3b9658045","name":"Scrape Lead Website with Dumpling AI","type":"n8n-nodes-base.httpRequest","position":[320,60],"parameters":{"url":"https://app.dumplingai.com/api/v1/scrape","method":"POST","options":{},"jsonBody":"={\n  \"url\": \"{{ $json.Website }}\"\n}\n","sendBody":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"RLFzAcGRepr5eXZB","name":"Dumpling AI-n8n"}},"typeVersion":4.2},{"id":"5d5675b6-4245-4562-a9d2-7cf54fe20b75","name":"Generate Icebreaker, Summary & Email (GPT-4o)","type":"@n8n/n8n-nodes-langchain.openAi","position":[540,60],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"chatgpt-4o-latest","cachedResultName":"CHATGPT-4O-LATEST"},"options":{},"messages":{"values":[{"role":"system","content":"=You are a smart assistant helping write personalized outreach. Below is content scraped from a lead’s website, along with the lead’s name.\n\nUsing this, please generate the following:\n\nIcebreaker: A short, friendly opening line that shows we took time to look at their business.\n\nEmail Body: A short cold outreach email that introduces what we do and how we can help, referencing their business or needs where relevant.\n\nWebsite Summary: A short summary (2 or 3 lines) of what their website is about, written in plain English.\n\nPlease return your response in this JSON format:\n\n{\n  \"icebreaker\": \"string\",\n  \"email_body\": \"string\",\n  \"website_summary\": \"string\"\n}"},{"content":"=Lead Name: {{ $('Search Cold Leads Without Icebreaker').item.json.Name }}\nScraped Website Content:{{ $json.content }}"}]},"jsonOutput":true},"credentials":{"openAiApi":{"id":"dd8NvMC6rvx8RITo","name":"OpenAi account 2"}},"typeVersion":1.8},{"id":"05a2b673-8e2a-41cf-9a01-eb19b2e584ea","name":"Save AI Output Back to Airtable","type":"n8n-nodes-base.airtable","position":[960,60],"parameters":{"base":{"__rl":true,"mode":"list","value":"","cachedResultUrl":"https://airtable.com/appPSvSKdA6075xJC","cachedResultName":"Testing n8n"},"table":{"__rl":true,"mode":"list","value":"","cachedResultUrl":"https://airtable.com/appPSvSKdA6075xJC/tbl1KgkRF2EEMc2Fq","cachedResultName":"cold leads"},"columns":{"value":{"id":"={{ $('Search Cold Leads Without Icebreaker').item.json.id }}","Name":"={{ $('Search Cold Leads Without Icebreaker').item.json.Name }}","Phone":"={{ $('Search Cold Leads Without Icebreaker').item.json.Phone }}","Website":"={{ $('Search Cold Leads Without Icebreaker').item.json.Website }}","Email body":"={{ $json.message.content.email_body }}","Ice breaker":"={{ $json.message.content.icebreaker }}","website summary":"={{ $json.message.content.website_summary }}"},"schema":[{"id":"id","type":"string","display":true,"removed":false,"readOnly":true,"required":false,"displayName":"id","defaultMatch":true},{"id":"Name","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Name","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Website","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Website","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Phone","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Phone","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Ice breaker","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Ice breaker","defaultMatch":false,"canBeUsedToMatch":true},{"id":"website summary","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"website summary","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Email body","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Email body","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["id"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"update"},"credentials":{"airtableTokenApi":{"id":"H8PVkBgUPCcUhhRC","name":"Airtable Personal Access Token account"}},"typeVersion":2.1},{"id":"cd8dac4b-6575-45fc-95fd-3052b244b0a2","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-640,-260],"parameters":{"width":810,"height":480,"content":"### 🔄 Automated Cold Email Writing from Lead Websites\n\nThis workflow runs on a schedule and pulls new cold leads from Airtable that have no \"Ice breaker\" yet. For each lead, it waits briefly to prevent API overuse, then sends the lead’s website URL to Dumpling AI's scraping endpoint.\n\nThe scraped content is passed to GPT-4o to generate:\n- A personalized icebreaker\n- A website summary\n- A tailored cold email body\n\nFinally, all generated results are saved back into Airtable for each lead record.\n"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"710a2065-24ec-4681-aaa4-43028ec8acee","connections":{"Loop Through Each Lead":{"main":[[{"node":"No Operation, do nothing","type":"main","index":0}],[{"node":"Wait Before Making Request","type":"main","index":0}]]},"Wait Before Making Request":{"main":[[{"node":"Scrape Lead Website with Dumpling AI","type":"main","index":0}]]},"Run Daily to Process New Leads":{"main":[[{"node":"Search Cold Leads Without Icebreaker","type":"main","index":0}]]},"Save AI Output Back to Airtable":{"main":[[{"node":"Loop Through Each Lead","type":"main","index":0}]]},"Scrape Lead Website with Dumpling AI":{"main":[[{"node":"Generate Icebreaker, Summary & Email (GPT-4o)","type":"main","index":0}]]},"Search Cold Leads Without Icebreaker":{"main":[[{"node":"Loop Through Each Lead","type":"main","index":0}]]},"Generate Icebreaker, Summary & Email (GPT-4o)":{"main":[[{"node":"Save AI Output Back to Airtable","type":"main","index":0}]]}}}


name: Auto-Create Podcast from YouTube Transcript using Dumpling AI and GPT-4o
author_name: Yang
author_username: yang
nodes_used: ["n8n-nodes-base.airtable","n8n-nodes-base.httpRequest","@n8n/n8n-nodes-langchain.openAi"]
categories: []
created_at: 2025-06-11T22:06:28.989Z
updated_at: 2025-06-11T22:06:28.989Z
url: https://n8n.io/workflows/4887
scraped_at: 2025-07-06 21:16:30
description:
  🔎 Who is this for?
  This workflow is designed for podcast creators, content marketers, and video producers who want to convert YouTube videos into podcast-ready scripts. It's perfect for anyone repurposing long-form content to reach audio-first audiences without manual effort.

  🧠 What problem is this workflow solving?
  Creating podcast scripts from YouTube videos manually is time-consuming. This workflow automates the process by pulling transcripts, cleaning the text, organizing the dialogue, summarizing the key points, and saving everything in one place. It removes the need for manual transcription, formatting, and structuring.

  ⚙️ What this workflow does

  This workflow uses Dumpling AI and GPT-4o to automate the transformation of YouTube video transcripts into polished podcast scripts. Here's how it works:

  RSS Feed Trigger
     Monitors a YouTube RSS feed for new video uploads. When a new video is detected, the workflow begins automatically.

  Get YouTube Transcript (Dumpling AI)
     Uses Dumpling AI's get-youtube-transcript endpoint to extract the full transcript from the video URL.

  Generate Podcast Script with GPT-4o
     GPT-4o receives the transcript and generates a structured JSON output including:
       Cleaned transcript with filler words removed
       Speaker labels for clarity
       A short, engaging podcast title
       A concise summary of the episode

  Save to Airtable
     The structured data (title, summary, cleaned transcript) is saved to Airtable for easy review, editing, or publishing.

  This automation is an ideal workflow for repurposing video content into audio-friendly formats, cutting down production time while increasing content output across platforms.

workflow_json:
  {"id":"I4j3HnFGPa5UWkIO","meta":{"instanceId":"a1ae5c8dc6c65e674f9c3947d083abcc749ef2546dff9f4ff01de4d6a36ebfe6","templateCredsSetupCompleted":true},"name":"Auto-Create Podcast from YouTube Video Transcript using Dumpling AI and GPT-4o","tags":[],"nodes":[{"id":"d95bcf10-2bb4-4bfd-a8ad-4128a792deb8","name":" Watch for New YouTube Video via RSS","type":"n8n-nodes-base.rssFeedReadTrigger","position":[-500,-20],"parameters":{"feedUrl":"https://rss.app/feeds/Vw076Uzh7bIinpci.xml","pollTimes":{"item":[{"mode":"everyMinute"}]}},"typeVersion":1},{"id":"a5492dab-f400-48d9-abd7-6c832d9d6816","name":"Get Transcript from YouTube Video using Dumpling AI","type":"n8n-nodes-base.httpRequest","position":[-280,-20],"parameters":{"url":"https://app.dumplingai.com/api/v1/get-youtube-transcript","method":"POST","options":{},"jsonBody":"={\n  \"videoUrl\": \"{{ $json.link }}\",\n  \"preferredLanguage\": \"en\"\n}\n","sendBody":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"RLFzAcGRepr5eXZB","name":"Dumpling AI-n8n"}},"typeVersion":4.2},{"id":"bce2bb18-c9ee-4165-ac27-5d300e354c7e","name":"Transform Transcript into Podcast Script using GPT-4o","type":"@n8n/n8n-nodes-langchain.openAi","position":[-60,-20],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"chatgpt-4o-latest","cachedResultName":"CHATGPT-4O-LATEST"},"options":{},"messages":{"values":[{"role":"system","content":"=Instructions:\nYou are a professional transcript editor and podcast summarizer. For the transcript below, complete these tasks:\n\nLabel each speaker (e.g., Speaker 1:) and remove all filler words such as \"um,\" \"uh,\" \"you know,\" \"like,\" \"basically,\" \"actually,\" \"so.\"\n\nCombine the cleaned speaker labels and their text into one single string, clearly formatted.\n\nSummarize the key points of the conversation in 2–4 concise sentences.\n\nExtract or infer a short, relevant title based on the content.\n\nReturn your response strictly in the following JSON format:\n{\n  \"title\": \"Relevant podcast title here\",\n  \"cleaned_transcript\": \"Speaker 1: Cleaned text. Speaker 2: Cleaned text. (Continue in this format.)\",\n  \"summary\": \"Concise summary of the key points here.\"\n}"},{"content":"=\nHere’s the transcript:{{ $json.transcript }}"}]},"jsonOutput":true},"credentials":{"openAiApi":{"id":"dd8NvMC6rvx8RITo","name":"OpenAi account 2"}},"typeVersion":1.8},{"id":"7782b5a6-c842-41be-a5c5-9eaa28a0abd0","name":"Save Podcast Script and Metadata to Airtable","type":"n8n-nodes-base.airtable","position":[300,-20],"parameters":{"base":{"__rl":true,"mode":"list","value":"","cachedResultUrl":"https://airtable.com/appPSvSKdA6075xJC","cachedResultName":"Testing n8n"},"table":{"__rl":true,"mode":"list","value":"","cachedResultUrl":"https://airtable.com/appPSvSKdA6075xJC/tbl4MDOqdNZweqXU9","cachedResultName":"podcast"},"columns":{"value":{"Title":"={{ $json.message.content.title }}","summary":"={{ $json.message.content.summary }}","podcast transcript":"={{ $json.message.content.cleaned_transcript }}"},"schema":[{"id":"Title","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Title","defaultMatch":false,"canBeUsedToMatch":true},{"id":"podcast transcript","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"podcast transcript","defaultMatch":false,"canBeUsedToMatch":true},{"id":"summary","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"summary","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"create"},"credentials":{"airtableTokenApi":{"id":"H8PVkBgUPCcUhhRC","name":"Airtable Personal Access Token account"}},"typeVersion":2.1},{"id":"af143efd-be64-48fc-a405-173575289ed3","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-500,-220],"parameters":{"width":640,"height":280,"content":"### 🎙️ Auto-Create Podcast Script from YouTube Videos\n\nThis workflow starts by monitoring a YouTube RSS feed for new uploads. Once a new video is detected, Dumpling AI extracts the full transcript. GPT-4o then converts that transcript into a well-formatted podcast script, ensuring it’s clean, structured, and engaging. The final script along with the video title and summary is saved into Airtable, where it can be reviewed, edited, or used to produce an actual podcast episode.\n\nIdeal for creators repurposing video content into audio format.\n"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"0c39768f-93c9-42d7-8b9f-ca4e0ede2312","connections":{" Watch for New YouTube Video via RSS":{"main":[[{"node":"Get Transcript from YouTube Video using Dumpling AI","type":"main","index":0}]]},"Get Transcript from YouTube Video using Dumpling AI":{"main":[[{"node":"Transform Transcript into Podcast Script using GPT-4o","type":"main","index":0}]]},"Transform Transcript into Podcast Script using GPT-4o":{"main":[[{"node":"Save Podcast Script and Metadata to Airtable","type":"main","index":0}]]}}}


name: Voice-Powered Marketing Assistant with ElevenLabs, OpenAI & Content Generation
author_name: David Olusola
author_username: dae221
categories: []
created_at: 2025-06-12T00:20:50.025Z
updated_at: 2025-06-12T00:20:50.025Z
url: https://n8n.io/workflows/4888
scraped_at: 2025-07-06 21:16:30
description:
  🧠 Gwen – The AI Voice Marketing Agent
  Gwen is your intelligent voice-powered marketing assistant built in n8n. She combines the power of OpenAI, ElevenLabs, and automation workflows to handle content creation, image generation, and voice delivery — all from a single agent interface.

  This template shows a graphical illustration of how Gwen will work with subworkflows. These subworkflows are modular placeholders and need to be linked into Gwen for full deployment.

  ✨ What Gwen Can Do
  📝 Generate Voice-Optimized Blog Posts
  Tailored for your target audience with engaging intros, real-time research, and polished structure.
  🖼️ Create AI-Generated Visuals
  From simple concepts to detailed image prompts and Google Drive uploads.
  🧑‍🎨 Edit Images On Demand
  Modify past images with a few words — powered by OpenAI's image editing API.
  🔍 Search Image Database
  Quickly find past content using title or intent.
  🧠 Think Tool
  Gwen uses this to clarify uncertain tasks or analyze complex requests.
  🔊 Deliver Results in Natural Voice
  With ElevenLabs, Gwen transforms all responses into human-like audio, perfect for marketing, social content, or voice interfaces.
  🛠️ Setup Instructions
  Estimated Time: 15–30 mins

  ✅ Step 1: Subworkflows

  Import These Workflows
  Blog Post, Create Image, Edit Image, Search Images
  Connect Them to Gwen
  Assign as tools inside the Gwen agent node (Langchain AI Agent in n8n).
  🎙️ Step 2: Enable ElevenLabs Voice Agent

  Sign up or log in: https://try.elevenlabs.io
  Copy your API key
  In the ElevenLabs interface, create a new tool:
  Method: POST
  URL: https://your-n8n-domain/webhook/042cc868-28b7-42a2-ab65-bc2944fc5a54
  Under Body Parameters, add:
  prompt → value type: LLM Prompt
  sessionId → value type: Dynamic variable, name: system__conversation_id
  Save and connect this tool to your ElevenLabs agent
  Run a test and check n8n execution logs to confirm Gwen’s voice integration is active
  🔐 Step 3: Credentials to Set

  OpenAI – For text and image generation
  ElevenLabs – For voice output
  Tavily – For real-time research in blog generation
  Telegram – For sending content to users
  Google Sheets – To log all outputs like blogs and images

nodes_used:
  ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.telegram","n8n-nodes-base.googleDrive","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.memoryBufferWindow","@n8n/n8n-nodes-langchain.outputParserStructured","@n8n/n8n-nodes-langchain.toolWorkflow","@n8n/n8n-nodes-langchain.toolHttpRequest","@n8n/n8n-nodes-langchain.toolThink"]

workflow_json:
  {"id":"YEuoA3Cq84m057vt","meta":{"instanceId":"2000c64071c20843606b95c63795bb0797c41036047055a6586498e855b96efc"},"name":"ELEVEN LABS WITH MULTI AGENTS","tags":[],"nodes":[{"id":"130f11d3-e09a-4913-84e4-eaa0dd2964f0","name":"Webhook","type":"n8n-nodes-base.webhook","position":[-1820,440],"webhookId":"042cc868-28b7-42a2-ab65-bc2944fc5a54","parameters":{},"typeVersion":2},{"id":"7d672479-775a-4322-ac6d-dd19002a7fab","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[-3020,-520],"parameters":{"content":""},"typeVersion":1},{"id":"d21ab3c4-cdbe-4622-910e-0b12d1409485","name":"ElevenLabs Setup","type":"n8n-nodes-base.stickyNote","position":[-3020,1040],"parameters":{"content":""},"typeVersion":1},{"id":"25af0cf7-9623-4d8c-82ff-d319728b4a40","name":"Create Image","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[-1180,740],"parameters":{},"typeVersion":2.1},{"id":"062fcb06-a6d4-46ca-b5a3-03f9f4cac6c3","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[-1460,760],"parameters":{},"typeVersion":1.3},{"id":"1bed5d7a-f88b-445d-af03-9197f3c1007a","name":"Edit Image","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[-920,760],"parameters":{},"typeVersion":2.1},{"id":"08bdced3-7113-433b-8996-a8f3b0830792","name":"Search Images","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[-1320,760],"parameters":{},"typeVersion":2.1},{"id":"5e385186-d38d-41c4-8178-aded256ec2e9","name":"Blog Post","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[-1620,760],"parameters":{},"typeVersion":2.1},{"id":"9f0dcfb9-523c-4fce-b0a9-2177e8ad305d","name":"Marketing Team Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[-1560,440],"parameters":{},"typeVersion":1.9},{"id":"762f673c-54aa-41e9-9414-e8331cb139c8","name":"Think","type":"@n8n/n8n-nodes-langchain.toolThink","position":[-1080,740],"parameters":{},"typeVersion":1},{"id":"b643093a-cbcf-4ebd-b628-08421735c70f","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-1760,740],"parameters":{},"typeVersion":1.2},{"id":"6d5de957-96ee-48de-8bd2-25e27ef6d0ed","name":"Respond to Webhook","type":"n8n-nodes-base.respondToWebhook","position":[-1120,440],"parameters":{},"typeVersion":1.4},{"id":"16c4ef2c-a1aa-40cd-aa66-482e9495a097","name":"Convert to File","type":"n8n-nodes-base.convertToFile","position":[1356,960],"parameters":{},"typeVersion":1.1},{"id":"37fc4987-50d4-4b61-a6ef-0388ea35692f","name":"Generate Image","type":"n8n-nodes-base.httpRequest","position":[1136,960],"parameters":{},"typeVersion":4.2},{"id":"3a5b7abd-a55e-428c-b86c-5e13a7d5071c","name":"Image Prompt","type":"@n8n/n8n-nodes-langchain.agent","position":[760,960],"parameters":{},"typeVersion":1.9},{"id":"a35b782f-9cea-4a22-ad54-73b61941fe4e","name":"Google Drive","type":"n8n-nodes-base.googleDrive","position":[1576,1060],"parameters":{},"typeVersion":3},{"id":"0c4d9982-0962-49a6-b493-c3599d45cf37","name":"Image Log","type":"n8n-nodes-base.googleSheets","position":[1796,1060],"parameters":{},"typeVersion":4.5},{"id":"2b8359bf-6efd-4e03-a4b7-03b0ad372dbe","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[698,680],"parameters":{"content":""},"typeVersion":1},{"id":"8dd7a0fe-03f8-452c-af92-7fb9510ac0ea","name":"Send Photo","type":"n8n-nodes-base.telegram","position":[1576,860],"webhookId":"8fcbda9c-8396-41f7-8f2d-39e4ae4337c7","parameters":{},"typeVersion":1.2},{"id":"cb36b8dc-8bd7-4e82-959b-4d6909b59ae6","name":"OpenAI Chat Model1","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[848,1180],"parameters":{},"typeVersion":1.2},{"id":"cb748f5e-ae93-458d-8c10-a7a4037fc56f","name":"When Executed by Another Workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[80,1820],"parameters":{},"typeVersion":1.1},{"id":"d1ba7187-e428-4c32-9041-0ef1e3d213d3","name":"Upload Image","type":"n8n-nodes-base.googleDrive","position":[1420,1520],"parameters":{},"typeVersion":3},{"id":"83cdd5e7-3d8d-4b64-8b98-e009e12325a9","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[428,1060],"parameters":{"content":""},"typeVersion":1},{"id":"1dac3089-7593-4ae8-9ac8-d3b24f50b24d","name":"Download","type":"n8n-nodes-base.googleDrive","position":[760,1420],"parameters":{},"typeVersion":3},{"id":"9e6ed86b-956d-4465-acd2-800b663ca868","name":"Edit Image1","type":"n8n-nodes-base.httpRequest","position":[980,1420],"parameters":{},"typeVersion":4.2},{"id":"c49919d7-9548-4ef6-8697-180dc5471788","name":"Convert to File1","type":"n8n-nodes-base.convertToFile","position":[1200,1420],"parameters":{},"typeVersion":1.1},{"id":"abbc8451-6365-4d6f-8801-e511f3cf4d1c","name":"Image Log1","type":"n8n-nodes-base.googleSheets","position":[1640,1520],"parameters":{},"typeVersion":4.5},{"id":"79324f1a-272d-4de4-b415-1fdadcf5f8aa","name":"Send Photo1","type":"n8n-nodes-base.telegram","position":[1420,1320],"webhookId":"85dc0064-e5c5-45a9-91a5-60e5b2bc4f1e","parameters":{},"typeVersion":1.2},{"id":"2ef66da8-4df4-4d98-ae00-9e9d78c69940","name":"Tavily","type":"@n8n/n8n-nodes-langchain.toolHttpRequest","position":[908,2000],"parameters":{},"typeVersion":1.1},{"id":"7c192389-5203-49c8-821d-d6b2ea18f610","name":"Image Prompt Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[1136,1780],"parameters":{},"typeVersion":1.9},{"id":"8d1612d2-6216-4cd7-9b05-e1e31c72dc09","name":"Convert to Binary","type":"n8n-nodes-base.convertToFile","position":[1732,1880],"parameters":{},"typeVersion":1.1},{"id":"98fa6795-d31a-49e2-9440-64dc415c7ba3","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[200,1460],"parameters":{"content":""},"typeVersion":1},{"id":"0a61fdec-b42d-4e14-98a4-6a679773d45e","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[698,1900],"parameters":{"content":""},"typeVersion":1},{"id":"070ebd2b-08ea-4020-b321-3a7d2892e7cc","name":"Blog Post Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[760,1780],"parameters":{},"typeVersion":1.9},{"id":"3cf78814-14ba-477d-96f9-ff2e84198778","name":"Image & Title","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[1224,2000],"parameters":{},"typeVersion":1.2},{"id":"b7790843-68e1-4e77-a537-be9cba0c8c97","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1104,1900],"parameters":{"content":""},"typeVersion":1},{"id":"7b853910-8415-4d14-8075-ad2d336f9ec8","name":"Send Blog","type":"n8n-nodes-base.telegram","position":[2172,1780],"webhookId":"94fa70af-f2fc-4c05-8fa1-d9f55637485f","parameters":{},"typeVersion":1.2},{"id":"0992b8b3-d481-407d-8979-e1a8719c254c","name":"Upload","type":"n8n-nodes-base.googleDrive","position":[1952,1980],"parameters":{},"typeVersion":3},{"id":"97d5c498-24a3-447a-83c9-8683c1f1903a","name":"Generate Image1","type":"n8n-nodes-base.httpRequest","position":[1512,1880],"parameters":{},"typeVersion":4.2},{"id":"ebe5b6c3-bfbe-4c0b-aa4b-52e6d520937d","name":"Image Log2","type":"n8n-nodes-base.googleSheets","position":[2172,1980],"parameters":{},"typeVersion":4.5},{"id":"d9da5605-28b9-4b0f-b74a-65cfebdb0d17","name":"Send Photo2","type":"n8n-nodes-base.telegram","position":[1952,1780],"webhookId":"8fcbda9c-8396-41f7-8f2d-39e4ae4337c7","parameters":{},"typeVersion":1.2},{"id":"ba985b89-8be6-4e79-b56d-0f5688fdb9a2","name":"OpenAI Chat Model2","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[788,2000],"parameters":{},"typeVersion":1.2},{"id":"e17ef6b0-1151-4035-b157-c282d84bcc8e","name":"Image Database","type":"n8n-nodes-base.googleSheetsTool","position":[880,2560],"parameters":{},"typeVersion":4.5},{"id":"5c383fa5-3cdf-4f83-91e4-49772496daa0","name":"Image Search Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[792,2340],"parameters":{},"typeVersion":1.9},{"id":"a6614f96-f944-4e19-95c7-4b31fdafcdca","name":"Not Found","type":"n8n-nodes-base.set","position":[1420,2240],"parameters":{},"typeVersion":3.4},{"id":"810cfba2-c96a-4d16-8b78-847715e67b57","name":"Get?","type":"n8n-nodes-base.if","position":[1420,2440],"parameters":{},"typeVersion":2.2},{"id":"3acb5f29-87e6-48b3-a30f-8d29eb161230","name":"Not Found?","type":"n8n-nodes-base.if","position":[1200,2340],"parameters":{},"typeVersion":2.2},{"id":"4b351945-b69f-4631-bec7-9a4abf3b0185","name":"Download File","type":"n8n-nodes-base.googleDrive","position":[1640,2340],"parameters":{},"typeVersion":3},{"id":"2c380825-054c-4a83-a298-7bca3048aaa9","name":"Name, ID, & Link","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[1000,2560],"parameters":{},"typeVersion":1.2},{"id":"3b04334b-6e5b-47c2-9aae-08a481e98188","name":"Edit","type":"n8n-nodes-base.set","position":[1640,2540],"parameters":{},"typeVersion":3.4},{"id":"c85da303-2572-4c66-88f2-5393d5fa8398","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[1600,2500],"parameters":{"content":""},"typeVersion":1},{"id":"1822eab5-a432-476a-b0c1-516112ab05d5","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[420,2240],"parameters":{"content":""},"typeVersion":1},{"id":"f7a2595e-254b-4bc7-b3df-bf7233af4a06","name":"Sticky Note14","type":"n8n-nodes-base.stickyNote","position":[1380,2200],"parameters":{"content":""},"typeVersion":1},{"id":"e80112f7-0e8a-4003-9bbd-01aff4277fd5","name":"Send Photo3","type":"n8n-nodes-base.telegram","position":[1860,2340],"webhookId":"85dc0064-e5c5-45a9-91a5-60e5b2bc4f1e","parameters":{},"typeVersion":1.2},{"id":"1b1bf2ad-fc9f-4d0d-84ab-4cc8cd98c2b5","name":"OpenAI Chat Model3","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[760,2560],"parameters":{},"typeVersion":1.2},{"id":"2aab7466-16e3-4164-8282-e13b97554950","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-2000,200],"parameters":{"content":""},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"7c64f75e-3f59-4abf-a9d6-58526fd9f71d","connections":{"Get?":{"main":[[{"node":"Download File","type":"main","index":0}],[{"node":"Edit","type":"main","index":0}]]},"Think":{"ai_tool":[[{"node":"Marketing Team Agent","type":"ai_tool","index":0}]]},"Tavily":{"ai_tool":[[{"node":"Blog Post Agent","type":"ai_tool","index":0}]]},"Upload":{"main":[[{"node":"Image Log2","type":"main","index":0}]]},"Webhook":{"main":[[{"node":"Marketing Team Agent","type":"main","index":0}]]},"Download":{"main":[[{"node":"Edit Image1","type":"main","index":0}]]},"Blog Post":{"ai_tool":[[{"node":"Marketing Team Agent","type":"ai_tool","index":0}]]},"Edit Image":{"ai_tool":[[{"node":"Marketing Team Agent","type":"ai_tool","index":0}]]},"Not Found?":{"main":[[{"node":"Not Found","type":"main","index":0}],[{"node":"Get?","type":"main","index":0}]]},"Edit Image1":{"main":[[{"node":"Convert to File1","type":"main","index":0}]]},"Send Photo2":{"main":[[{"node":"Send Blog","type":"main","index":0}]]},"Create Image":{"ai_tool":[[{"node":"Marketing Team Agent","type":"ai_tool","index":0}]]},"Google Drive":{"main":[[{"node":"Image Log","type":"main","index":0}]]},"Image Prompt":{"main":[[{"node":"Generate Image","type":"main","index":0}]]},"Upload Image":{"main":[[{"node":"Image Log1","type":"main","index":0}]]},"Download File":{"main":[[{"node":"Send Photo3","type":"main","index":0}]]},"Image & Title":{"ai_outputParser":[[{"node":"Image Prompt Agent","type":"ai_outputParser","index":0}]]},"Search Images":{"ai_tool":[[{"node":"Marketing Team Agent","type":"ai_tool","index":0}]]},"Simple Memory":{"ai_memory":[[{"node":"Marketing Team Agent","type":"ai_memory","index":0}]]},"Generate Image":{"main":[[{"node":"Convert to File","type":"main","index":0}]]},"Image Database":{"ai_tool":[[{"node":"Image Search Agent","type":"ai_tool","index":0}]]},"Blog Post Agent":{"main":[[{"node":"Image Prompt Agent","type":"main","index":0}]]},"Convert to File":{"main":[[{"node":"Google Drive","type":"main","index":0},{"node":"Send Photo","type":"main","index":0}]]},"Generate Image1":{"main":[[{"node":"Convert to Binary","type":"main","index":0}]]},"Convert to File1":{"main":[[{"node":"Send Photo1","type":"main","index":0},{"node":"Upload Image","type":"main","index":0}]]},"Name, ID, & Link":{"ai_outputParser":[[{"node":"Image Search Agent","type":"ai_outputParser","index":0}]]},"Convert to Binary":{"main":[[{"node":"Send Photo2","type":"main","index":0},{"node":"Upload","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Marketing Team Agent","type":"ai_languageModel","index":0}]]},"Image Prompt Agent":{"main":[[{"node":"Generate Image1","type":"main","index":0}]]},"Image Search Agent":{"main":[[{"node":"Not Found?","type":"main","index":0}]]},"OpenAI Chat Model1":{"ai_languageModel":[[{"node":"Image Prompt","type":"ai_languageModel","index":0}]]},"OpenAI Chat Model2":{"ai_languageModel":[[{"node":"Image Prompt Agent","type":"ai_languageModel","index":0},{"node":"Blog Post Agent","type":"ai_languageModel","index":0}]]},"OpenAI Chat Model3":{"ai_languageModel":[[{"node":"Image Search Agent","type":"ai_languageModel","index":0}]]},"Marketing Team Agent":{"main":[[{"node":"Respond to Webhook","type":"main","index":0}]]},"When Executed by Another Workflow":{"main":[[{"node":"Image Prompt","type":"main","index":0},{"node":"Image Search Agent","type":"main","index":0},{"node":"Blog Post Agent","type":"main","index":0},{"node":"Download","type":"main","index":0}]]}}}


name: LinkedIn Auto Message Router and Responder with Request Detection
author_name: Angel Menendez
author_username: djangelic
categories: []
created_at: 2025-06-12T00:34:35.995Z
updated_at: 2025-06-12T00:34:35.995Z
url: https://n8n.io/workflows/4889
scraped_at: 2025-07-06 21:16:30
description:
  Who is this for?

  Public-facing professionals (developer advocates, founders, marketers, content creators) who get bombarded with LinkedIn messages that aren't actually for them - support requests when you're in marketing, sales inquiries when you're a devrel, partnership pitches when you handle content, etc.

  What problem is this workflow solving?

  When you're visible online, people assume you handle everything at your company. You end up spending hours daily playing human router, forwarding messages like "How do I reset my password?" or "What's your enterprise pricing?" to the right teams. This LinkedIn automation workflow stops you from being your company's unofficial customer service representative.

  What this workflow does

  This AI-powered LinkedIn DM management workflow automatically assesses incoming LinkedIn messages and routes them intelligently:

  Automated Message Assessment: Receives inbound LinkedIn messages via UniPile and looks up sender details from both personal and company LinkedIn profiles.

  Smart Route Matching: Compares the message content against your message routing workflow table in Notion, which contains:
    Question: "How can I become an n8n ambassador?"
    Description: "Route here when a user is requesting to become an n8n ambassador. Also when they're asking how they could do more to evangelize n8n in their city, or to start organizing n8n meetups and events in their city."
    Action: "Tell the user to open the following notion page which has details on ambassador program including how to apply, as well as perks of the program: https://www.notion.so/n8n-Ambassador-Program-d883b2a130e5448faedbebe5139187ea?pvs=21"

  AI Response Generation: When a message matches an existing route, this AI assistant generates a personalized response draft based on the "Action" instructions from your routing table.

  Human-in-the-Loop Approval: Sends the draft response to Slack with approve/reject buttons, so you maintain control while saving time. Draft can be edited from within Slack on desktop and mobile.

  Automated LinkedIn Responses: Once approved, sends the reply back via LinkedIn and marks the original message as handled.

  The result: You stop being a human switchboard and can focus on your actual job while people still get helpful, timely responses through automated customer service. You can also add routes for things you do handle but get asked about daily (like 'How do I join your beta?' or 'What's your content strategy?') to standardize your responses.

  Setup

  Sign up for a UniPile account and create a webhook under the Messaging section
  Set the callback URL to this workflow's production URL
  Generate a UniPile API key with all required scopes and store it in your n8n credentials
  Create a Slack app and enable interactive message buttons and webhooks

  Here is a slack App manifest template for easy deployment in slack:

  {
      "display_information": {
          "name": "Request Router",
          "description": "A bot that alerts when a new linkedin question comes in.",
          "background_color": "#12575e"
      },
      "features": {
          "bot_user": {
              "display_name": "Request Router",
              "always_online": false
          }
      },
      "oauth_config": {
          "scopes": {
              "bot": [
                  "chat:write",
                  "chat:write.customize",
                  "chat:write.public",
                  "links:write",
                  "im:history",
                  "im:read",
                  "im:write"
              ]
          }
      },
      "settings": {
          "interactivity": {
              "is_enabled": true,
              "request_url": "Your webhook url here"
          },
          "org_deploy_enabled": false,
          "socket_mode_enabled": false,
          "token_rotation_enabled": false
      }
  }


  Set up your Notion database with the three-column structure (Question, Description, Action)
  Configure the AI node with your preferred provider (OpenAI, Gemini, Ollama etc)
  Replace placeholder LinkedIn user and organization IDs with your own

  How to customize this workflow to your needs

  Database Options**: Swap Notion with Google Sheets, Airtable, or another database
  Filtering Logic**: Add custom filters based on keywords, message length, follower count, or business logic
  AI Customization**: Adjust the system prompt to match your brand tone and response goals
  Approval Platform**: Replace Slack with email, Discord, or another review platform
  Team Routing**: Use Slack metadata to route approvals to specific team members based on message category
  Enrichment**: Add secondary data enrichment using tools like Clearbit or FullContact
  Response Rules**: Create conditional logic for different response types based on sender profile or message content

  Perfect for anyone who's tired of being their company's accidental customer service department while trying to do their real job.

  This LinkedIn automation template was inspired by a live build done by Max Tkacz and Angel Menendez for The Studio.

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

workflow_json:
  {"meta":{"instanceId":"cb484ba7b742928a2048bf8829668bed5b5ad9787579adea888f05980292a4a7","templateCredsSetupCompleted":true},"nodes":[{"id":"5f71a0e6-d5ec-4712-9feb-2b10a1b0a3ea","name":"Webhook","type":"n8n-nodes-base.webhook","position":[0,0],"webhookId":"12a0b328-1d39-44b4-b29d-9ac465cf134b","parameters":{"path":"12a0b328-1d39-44b4-b29d-9ac465cf134b","options":{},"httpMethod":"POST"},"typeVersion":2},{"id":"bd66537c-6fe5-4877-9127-3b78af08c499","name":"Check if from me","type":"n8n-nodes-base.if","position":[440,0],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"or","conditions":[{"id":"711303bb-aef2-4cff-b4c7-c2a898e454ac","operator":{"type":"string","operation":"notEquals"},"leftValue":"={{ $json.sender_id }}","rightValue":"OzJlgZHDXWi0PmxVdqnPOQ"},{"id":"d115500d-8e14-4b8e-b0ed-4e26a895bb37","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.sender_id }}","rightValue":"9va5ul-NUYejvzb7ADJzuw"}]}},"typeVersion":2.2},{"id":"e14aedab-47e9-4811-b991-ee0d00290c39","name":"Response, No action","type":"n8n-nodes-base.noOp","position":[700,120],"parameters":{},"typeVersion":1},{"id":"8adbb07e-4897-4421-b581-c963b754aa2b","name":"New Message","type":"n8n-nodes-base.noOp","position":[680,-140],"parameters":{},"typeVersion":1},{"id":"39865ae2-a266-47ba-a6fd-c9b1f5d5a931","name":"Global Variables","type":"n8n-nodes-base.set","position":[220,0],"parameters":{"options":{},"assignments":{"assignments":[{"id":"5483f235-49d0-404d-82dd-fd5688671044","name":"type","type":"string","value":"={{ $json.body.account_info.type }}"},{"id":"d737da4a-cc6f-4dc5-a8b7-0fd60f6a45b5","name":"message","type":"string","value":"={{ $json.body.message }}"},{"id":"924bd124-4ef1-4f41-8a3d-819d97f053e2","name":"message_id","type":"string","value":"={{ $json.body.message_id }}"},{"id":"c05786b0-b2af-4d87-a111-aae969ce50e9","name":"chat_id","type":"string","value":"={{ $json.body.chat_id }}"},{"id":"342fd20c-81be-42c7-aa85-a525fa9760fb","name":"sender","type":"string","value":"={{ $json.body.sender.attendee_name }}"},{"id":"b40f55d7-928e-436f-90b7-b4048cd80423","name":"sender_profile","type":"string","value":"={{ $json.body.sender.attendee_profile_url }}"},{"id":"efb12c87-42f5-4087-82b8-8dbda5aaf465","name":"sender_id","type":"string","value":"={{ $json.body.sender.attendee_id }}"}]}},"typeVersion":3.4},{"id":"3c58401c-cb83-4d71-9469-7563d6ce9c16","name":"Slack Button Press","type":"n8n-nodes-base.webhook","position":[0,800],"webhookId":"e3182811-630a-4959-b91c-71d8c8093e1c","parameters":{"path":"e3182811-630a-4959-b91c-71d8c8093e1c","options":{},"httpMethod":"POST","responseMode":"responseNode"},"typeVersion":2},{"id":"b87d4806-423b-4656-bbd6-9d0808242cc4","name":"Parse Webhook","type":"n8n-nodes-base.set","position":[480,800],"parameters":{"options":{},"assignments":{"assignments":[{"id":"94e30709-cf7a-4131-bc89-dbe56f8f3b16","name":"body.payload","type":"object","value":"={{ $json.body.payload }}"}]}},"typeVersion":3.4},{"id":"ee147347-1a88-4e96-9580-d08285e901c0","name":"Verify Webhook","type":"n8n-nodes-base.respondToWebhook","position":[240,800],"parameters":{"options":{"responseCode":200,"responseHeaders":{"entries":[{"name":"Content-type","value":"application/json"}]}},"respondWith":"json","responseBody":"={\"challenge\":\"{{ $json.body.challenge }}\"}"},"typeVersion":1},{"id":"ac2cb5e1-394a-4a5c-a999-a56d315bc3ff","name":"Check if approved","type":"n8n-nodes-base.if","position":[1140,580],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"cf275c3e-347d-4028-8209-682f52d540e3","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.body.payload.actions[0].value.action }}","rightValue":"approve"}]}},"typeVersion":2.2},{"id":"3812b521-2e15-4c24-9883-79ef04fc6cb3","name":"Send User Message","type":"n8n-nodes-base.slack","position":[4080,-100],"webhookId":"e3624af3-3604-4d6a-b776-e3860b51b24e","parameters":{"text":"=New LinkedIn Message from {{ $('Webhook').item.json.body.sender.attendee_name }}","user":{"__rl":true,"mode":"id","value":"U07G1JBR76W"},"select":"user","blocksUi":"={\n  \"blocks\": [\n    {\n      \"type\": \"section\",\n      \"block_id\": \"profile_card\",\n      \"text\": {\n        \"type\": \"mrkdwn\",\n        \"text\": \"👤*<{{ $('Webhook').item.json.body.sender.attendee_profile_url }}|{{ $('Webhook').item.json.body.sender.attendee_name }}>*\\n\\n💼 {{ $('Set all potential Inputs').item.json.linkedinprofile[0].headline }}\\n\\n📍 {{ $('Set all potential Inputs').item.json.linkedinprofile[0].location }}\\n👥 {{ $('Set all potential Inputs').item.json.linkedinprofile[0].follower_count }} followers | 🔗 {{ $('Set all potential Inputs').item.json.linkedinprofile[0].connections_count }} connections\"\n      },\n      \"accessory\": {\n        \"type\": \"image\",\n        \"image_url\": \"{{ $('Set all potential Inputs').item.json.linkedinprofile[0].profile_picture_url }}\",\n        \"alt_text\": \"LinkedIn Profile Picture\"\n      }\n    },\n    {\n      \"type\": \"section\",\n      \"block_id\": \"incoming_message\",\n      \"text\": {\n        \"type\": \"mrkdwn\",\n        \"text\": \"*📩 <https://www.linkedin.com/messaging/thread/{{ $('Webhook').item.json.body.provider_chat_id }}/|New LinkedIn Message>:*\\n> {{ $('Global Variables').item.json.message.replace(/\\n/g, '\\\\n').replace(/\\\"/g, '\\\\\"') }}\"\n      }\n    },\n    {\n      \"type\": \"input\",\n      \"block_id\": \"ai_response\",\n      \"element\": {\n        \"type\": \"plain_text_input\",\n        \"action_id\": \"response_input\",\n        \"multiline\": true,\n        \"initial_value\": \"{{ $('AI Agent').item.json.output.output.replace(/\\n/g, '\\\\n').replace(/\\\"/g, '\\\\\"') }}\",\n        \"placeholder\": {\n          \"type\": \"plain_text\",\n          \"text\": \"Edit the AI-generated response before approving...\"\n        }\n      },\n      \"label\": {\n        \"type\": \"plain_text\",\n        \"text\": \"🤖 Suggested Reply\"\n      }\n    },\n    {\n      \"type\": \"actions\",\n      \"block_id\": \"actions_block\",\n      \"elements\": [\n        {\n          \"type\": \"button\",\n          \"action_id\": \"approve_response\",\n          \"text\": {\n            \"type\": \"plain_text\",\n            \"text\": \"✅ Approve\"\n          },\n          \"style\": \"primary\",\n          \"value\": \"{\\\"action\\\":\\\"approve\\\",\\\"message_id\\\":\\\"{{ $('Global Variables').item.json.message_id }}\\\",\\\"channel_id\\\":\\\"{{ $('Global Variables').item.json.chat_id }}\\\"}\"\n        },\n        {\n          \"type\": \"button\",\n          \"action_id\": \"archive_message\",\n          \"text\": {\n            \"type\": \"plain_text\",\n            \"text\": \"🗃️ Archive\"\n          },\n          \"style\": \"danger\",\n          \"value\": \"{\\\"action\\\":\\\"archive\\\",\\\"message_id\\\":\\\"{{ $('Global Variables').item.json.message_id }}\\\",\\\"channel_id\\\":\\\"{{ $('Global Variables').item.json.chat_id }}\\\"}\"\n        }\n      ]\n    }\n  ]\n}\n","messageType":"block","otherOptions":{}},"credentials":{"slackApi":{"id":"6xKmxBfKWNPnre2E","name":"Request Router"}},"typeVersion":2.3},{"id":"7470b927-8a4d-4421-b6d3-cc55623d77dd","name":"Send Org Message","type":"n8n-nodes-base.slack","position":[4080,60],"webhookId":"9a621f5a-854e-4725-81c4-3ce075d87d96","parameters":{"text":"=New LinkedIn Message from {{ $('Webhook').item.json.body.sender.attendee_name }}","user":{"__rl":true,"mode":"id","value":"U07G1JBR76W"},"select":"user","blocksUi":"={\n  \"blocks\": [\n    {\n      \"type\": \"section\",\n      \"block_id\": \"profile_card_org\",\n      \"text\": {\n        \"type\": \"mrkdwn\",\n        \"text\": \"🏢*<{{ $('Webhook').item.json.body.sender.attendee_profile_url }}|{{ $('Webhook').item.json.body.sender.attendee_name }}>*\\n\\n💼 {{ $('Set all potential Inputs').item.json.linkedinprofile[0].headline }}\\n\\n📍 {{ $('Set all potential Inputs').item.json.linkedinprofile[0].location }}\\n👥 {{ $('Set all potential Inputs').item.json.linkedinprofile[0].follower_count }} followers | 🧑‍💼 {{ $('Set all potential Inputs').item.json.linkedinprofile[0].employee_count }} employees\"\n      },\n      \"accessory\": {\n        \"type\": \"image\",\n        \"image_url\": \"{{ $('Set all potential Inputs').item.json.linkedinprofile[0].profile_picture_url }}\",\n        \"alt_text\": \"Organization Profile Picture\"\n      }\n    },\n    {\n      \"type\": \"section\",\n      \"block_id\": \"incoming_message\",\n      \"text\": {\n        \"type\": \"mrkdwn\",\n        \"text\": \"*📩 New LinkedIn Message:*\\n> {{ $('Global Variables').item.json.message.replace(/\\n/g, '\\\\n').replace(/\\\"/g, '\\\\\"') }}\"\n      }\n    },\n    {\n      \"type\": \"input\",\n      \"block_id\": \"ai_response\",\n      \"element\": {\n        \"type\": \"plain_text_input\",\n        \"action_id\": \"response_input\",\n        \"multiline\": true,\n        \"initial_value\": \"{{ $('AI Agent').item.json.output.output.replace(/\\n/g, '\\\\n').replace(/\\\"/g, '\\\\\"') }}\",\n        \"placeholder\": {\n          \"type\": \"plain_text\",\n          \"text\": \"Edit the AI-generated response before approving...\"\n        }\n      },\n      \"label\": {\n        \"type\": \"plain_text\",\n        \"text\": \"🤖 Suggested Reply\"\n      }\n    },\n    {\n      \"type\": \"actions\",\n      \"block_id\": \"actions_block\",\n      \"elements\": [\n        {\n          \"type\": \"button\",\n          \"action_id\": \"approve_response\",\n          \"text\": {\n            \"type\": \"plain_text\",\n            \"text\": \"✅ Approve\"\n          },\n          \"style\": \"primary\",\n          \"value\": \"{\\\"action\\\":\\\"approve\\\",\\\"message_id\\\":\\\"{{ $('Global Variables').item.json.message_id }}\\\",\\\"channel_id\\\":\\\"{{ $('Global Variables').item.json.chat_id }}\\\"}\"\n        },\n        {\n          \"type\": \"button\",\n          \"action_id\": \"archive_message\",\n          \"text\": {\n            \"type\": \"plain_text\",\n            \"text\": \"🗃️ Archive\"\n          },\n          \"style\": \"danger\",\n          \"value\": \"{\\\"action\\\":\\\"archive\\\",\\\"message_id\\\":\\\"{{ $('Global Variables').item.json.message_id }}\\\",\\\"channel_id\\\":\\\"{{ $('Global Variables').item.json.chat_id }}\\\"}\"\n        }\n      ]\n    }\n  ]\n}\n","messageType":"block","otherOptions":{}},"credentials":{"slackApi":{"id":"6xKmxBfKWNPnre2E","name":"Request Router"}},"typeVersion":2.3},{"id":"0c63c0e7-752d-4bd7-ab78-23a1ff4d70ae","name":"Send Nothing Found Message","type":"n8n-nodes-base.slack","position":[4080,220],"webhookId":"64dddbb2-1bf6-4a5a-884b-057b82596ef1","parameters":{"user":{"__rl":true,"mode":"id","value":"U07G1JBR76W"},"select":"user","blocksUi":"={\n  \"blocks\": [\n    {\n      \"type\": \"section\",\n      \"block_id\": \"incoming_message\",\n      \"text\": {\n        \"type\": \"mrkdwn\",\n        \"text\": \"*New LinkedIn Message:*\\n> {{ $('Global Variables').item.json.message.replace(/\\n/g, '\\\\n').replace(/\"/g, '\\\\\"') }}\"\n      }\n    },\n    {\n      \"type\": \"input\",\n      \"block_id\": \"ai_response\",\n      \"element\": {\n        \"type\": \"plain_text_input\",\n        \"action_id\": \"response_input\",\n        \"multiline\": true,\n        \"initial_value\": \"{{ $json.output.output.replace(/\\n/g, '\\\\n').replace(/\"/g, '\\\\\"') }}\",\n        \"placeholder\": {\n          \"type\": \"plain_text\",\n          \"text\": \"Edit the AI-generated response before approving...\"\n        }\n      },\n      \"label\": {\n        \"type\": \"plain_text\",\n        \"text\": \"Suggested Reply\"\n      }\n    },\n    {\n      \"type\": \"actions\",\n      \"block_id\": \"actions_block\",\n      \"elements\": [\n        {\n          \"type\": \"button\",\n          \"action_id\": \"approve_response\",\n          \"text\": {\n            \"type\": \"plain_text\",\n            \"text\": \"✅ Approve\"\n          },\n          \"style\": \"primary\",\n          \"value\": \"{\\\"action\\\":\\\"approve\\\",\\\"message_id\\\":\\\"{{ $('Global Variables').item.json.message_id }}\\\",\\\"channel_id\\\":\\\"{{ $('Global Variables').item.json.chat_id }}\\\"}\"\n        },\n        {\n          \"type\": \"button\",\n          \"action_id\": \"archive_message\",\n          \"text\": {\n            \"type\": \"plain_text\",\n            \"text\": \"🗃️ Archive\"\n          },\n          \"style\": \"danger\",\n          \"value\": \"{\\\"action\\\":\\\"archive\\\",\\\"message_id\\\":\\\"{{ $('Global Variables').item.json.message_id }}\\\",\\\"channel_id\\\":\\\"{{ $('Global Variables').item.json.chat_id }}\\\"}\"\n        }\n      ]\n    }\n  ]\n}\n","messageType":"block","otherOptions":{}},"credentials":{"slackApi":{"id":"6xKmxBfKWNPnre2E","name":"Request Router"}},"typeVersion":2.3},{"id":"fb29432d-7603-4b42-902f-7784459dd40d","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-80,-420],"parameters":{"color":7,"width":980,"height":720,"content":"![unipile](https://uploads.n8n.io/templates/unipile.png)\n## LinkedIn Message Processing\nReceives the LinkedIn message via Unipile api webhook."},"typeVersion":1},{"id":"388d621c-7339-4d74-a2c4-4da9c41a441f","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[-80,320],"parameters":{"color":7,"width":2097,"height":693,"content":"![Slack](https://uploads.n8n.io/templates/slack.png)\n## Slack Bot Button Press\nThis workflow gets the button presses from the Slack interface and passes it along to Unipile for processing."},"typeVersion":1},{"id":"13ed0034-df98-46a8-931c-4e87667e624c","name":"Decide on Message Type","type":"n8n-nodes-base.switch","position":[3760,-80],"parameters":{"rules":{"values":[{"outputKey":"User","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"4670af46-5774-4fec-8b12-a608aefa3d89","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $('Set all potential Inputs').item.json.linkedinprofile[0].type }}","rightValue":"user"}]},"renameOutput":true},{"outputKey":"Organization","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"0a484630-343d-4b9a-9bf0-6ef5bd9b1b4b","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $('Set all potential Inputs').item.json.linkedinprofile[0].type }}","rightValue":"organization"}]},"renameOutput":true}]},"options":{"fallbackOutput":"extra"}},"typeVersion":3.2},{"id":"e4c36cc2-9ad1-4ceb-8698-05079c9c6509","name":"User Switcher","type":"n8n-nodes-base.switch","position":[680,800],"parameters":{"rules":{"values":[{"outputKey":"angel","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"27c0a3cc-b768-4aba-bab0-19971fb2d38d","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.body.payload.user.id }}","rightValue":"U07G1JBR76W"}]},"renameOutput":true},{"outputKey":"max","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"b16b07b2-c77b-439f-9acb-e7799dceaa6b","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.body.payload.user.id }}","rightValue":"U035CE97JGM"}]},"renameOutput":true}]},"options":{}},"typeVersion":3.2},{"id":"f84186be-8ded-47c5-8bdb-9366c8be59fa","name":"Isolate Message and Payload","type":"n8n-nodes-base.set","position":[920,580],"parameters":{"options":{},"assignments":{"assignments":[{"id":"2a9278cb-3f2a-4f90-852a-3ca16b404c58","name":"message","type":"string","value":"={{ $json.body.payload.state.values.ai_response.response_input.value }}"},{"id":"3c16c98d-a7db-42e9-aacd-9ede379b1f49","name":"body.payload.actions[0].value","type":"object","value":"={{ $json.body.payload.actions[0].value }}"}]}},"typeVersion":3.4},{"id":"7dc03482-8c14-4494-a475-3f958a1fd445","name":"Isolate Payload","type":"n8n-nodes-base.set","position":[920,820],"parameters":{"options":{},"assignments":{"assignments":[{"id":"f334a7f4-4c85-466c-8278-3da5dd5a2486","name":"body","type":"object","value":"={{ $('Slack Button Press').item.json.body.payload }}"}]}},"typeVersion":3.4},{"id":"425b2b79-447d-4736-9edf-0033969d64b4","name":"Send webhook to Coworker Workflow","type":"n8n-nodes-base.httpRequest","position":[1140,820],"parameters":{"url":"https://n8n.cloud/webhook/89659f10-574e-s42c-530d-e7dd9158d177","method":"POST","options":{}},"typeVersion":4.2},{"id":"4c36fc5c-75a5-4279-9555-13fdfa033510","name":"Send Message to LinkedIn via Unipile","type":"n8n-nodes-base.httpRequest","position":[1380,520],"parameters":{"url":"=https://api9.unipile.com:13976/api/v1/chats/{{ $json.body.payload.actions[0].value.channel_id }}/messages","method":"POST","options":{},"sendBody":true,"contentType":"form-urlencoded","sendHeaders":true,"authentication":"genericCredentialType","bodyParameters":{"parameters":[{"name":"text","value":"={{ $('Isolate Message and Payload').item.json.message }}"}]},"genericAuthType":"httpHeaderAuth","headerParameters":{"parameters":[{"name":"accept","value":"application/json"}]}},"credentials":{"httpHeaderAuth":{"id":"VfYHlcsosNuUS2YD","name":"unipile angel"}},"typeVersion":4.2},{"id":"bed8608b-b474-4472-87ad-1e3454799a81","name":"Delete Approved Message from Slack","type":"n8n-nodes-base.slack","position":[1680,520],"webhookId":"08e7c073-569a-4400-aa60-80c7cddf8b03","parameters":{"select":"channel","channelId":{"__rl":true,"mode":"id","value":"={{ $('User Switcher').item.json.body.payload.channel.id }}"},"operation":"delete","timestamp":"={{ $('User Switcher').item.json.body.payload.container.message_ts }}"},"credentials":{"slackApi":{"id":"6xKmxBfKWNPnre2E","name":"Request Router"}},"typeVersion":2.3},{"id":"b79429a6-3b46-4898-a933-3b6ec77a1f97","name":"Delete Denied Message from Slack","type":"n8n-nodes-base.slack","position":[1680,720],"webhookId":"70630dad-c2a5-4c40-aef3-070994ce4b83","parameters":{"select":"channel","channelId":{"__rl":true,"mode":"id","value":"={{ $('User Switcher').item.json.body.payload.channel.id }}"},"operation":"delete","timestamp":"={{ $('User Switcher').item.json.body.payload.container.message_ts }}"},"credentials":{"slackApi":{"id":"6xKmxBfKWNPnre2E","name":"Request Router"}},"typeVersion":2.3},{"id":"9a475e01-a250-44f2-8cc6-4ef60aedaa36","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[3220,-80],"parameters":{"text":"=Sender Name: {{ $('Isolate parent workflow data for AI').item.json.sender }}\nSender Message: {{ $('Isolate parent workflow data for AI').item.json.message }}\nMy Name: Your Name\n\nIf found, the linkedin profile will be below, pay close attention to the number of followers and connections: \n{{ $('Set all potential Inputs').item.json.linkedinprofile.toJsonString() }}","options":{"systemMessage":"=You are an expert professional assistant designed to help generate smart, personalized responses to LinkedIn messages.\n\nYou will be provided with:\n1. The **incoming message** and name from a LinkedIn user.\n2. A **database of past requests and responses**. These are known message types and the preferred replies.\n3. Context about the assistant's voice and tone.\n\n### Your Objective:\n- First, scan the database for any message that closely matches the incoming LinkedIn message. If a match is found, use the **corresponding response** as a base — you may slightly tailor it if needed (e.g., change names or dates).\n- If no close match is found, generate a **new, thoughtful reply** based on the message content, tone guidelines, and best practices in business networking. If you do not have a direct link or URL to provide from the Request Database, do not reference a website or URL. Instead say a variation of let me get back to you on that and see what I can find. \n\n### Tone Guidelines:\n- Friendly, confident, and professional — but never robotic.\n- Lightly personalized. Use the sender’s name if available.\n- Avoid sounding like a sales pitch.\n- Keep replies concise and natural, like something you'd actually send on LinkedIn.\n\n### When generating a new message:\n- Acknowledge the sender’s message.\n- Add a relevant, helpful comment or question to continue the conversation.\n- Keep the tone warm and open-ended.\n\n### Output format:\nOnly output the message text that should be sent to the user. Do not explain your reasoning. If you do not have a direct link to provide, do not reference a website or URL. Instead say let me get back to you on that and see what I can find. \n\nLet’s begin.\nRequest Database:\n\n{{ $json.dbObject.join('\\n\\n----\\n\\n') }}\n\nWhen responding, use the following format:\n{\n\t\"output\": \"message response\",\n\t\"found\": true\n}\nFor output output the message response, for found output a boolean, true if an example is found in the Request Database, false if a response is not found. The output is going to slack so ensure you escape your outputs like new lines. "},"promptType":"define","hasOutputParser":true},"typeVersion":1.9},{"id":"53011c4c-b9aa-4b47-84c8-060e4b7a2db9","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[3340,160],"parameters":{"sessionKey":"={{ $('Isolate parent workflow data for AI').item.json.chatid }}","sessionIdType":"customKey"},"typeVersion":1.3},{"id":"b5eb7520-c887-4a72-89d0-d616c24fdfca","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[3120,180],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o","cachedResultName":"gpt-4o"},"options":{}},"credentials":{"openAiApi":{"id":"QpFZ2EiM3WGl6Zr3","name":"Marketing OpenAI"}},"typeVersion":1.2},{"id":"b405f410-4d76-43f9-b21c-b6cb363daa43","name":"Structured Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[3500,160],"parameters":{"jsonSchemaExample":"{\n\t\"output\": \"message response\",\n\t\"found\": true\n}"},"typeVersion":1.2},{"id":"8ad9d20b-07a4-46f2-9dbb-5d3d8d502641","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[3020,-400],"parameters":{"color":7,"width":668,"height":718,"content":"![hctiapi](https://uploads.n8n.io/templates/openai.png)\n## Generate Automated response\nThe AI bot receives not only the message from LinkedIn, but also LinkedIn user context, such as the number of followers and connections, allowing for tailored responses. For example if a user asks to meet, but they don't meet a certain number of followers threshold, they are politely declined. However if an influencer reaches out, they are automatically given a booking link to ensure that high priority requests are immediately followed up on. "},"typeVersion":1},{"id":"8d593035-111a-45dc-93ea-950aad7b0ebb","name":"Isolate parent workflow data for AI","type":"n8n-nodes-base.set","position":[2260,20],"parameters":{"options":{},"assignments":{"assignments":[{"id":"91a1191e-bac0-4b8b-b263-a03c63435470","name":"sender","type":"string","value":"={{ $('Global Variables').item.json.sender }}"},{"id":"0f8c17c8-d598-4840-8b89-8dbdcd529231","name":"message","type":"string","value":"={{ $('Global Variables').item.json.message }}"},{"id":"c9132b69-5e0e-4ccf-86bb-0e4cfa734860","name":"chatid","type":"string","value":"={{ $('Global Variables').item.json.chat_id }}"}]}},"typeVersion":3.4},{"id":"d267a541-a739-49b8-a2f6-b8afbb6cc837","name":"Get Request Router Directory Database","type":"n8n-nodes-base.notion","position":[2460,20],"parameters":{"options":{},"resource":"databasePage","operation":"getAll","databaseId":{"__rl":true,"mode":"list","value":"1da5b6e0-c94f-8086-80b6-eab8e340d60e","cachedResultUrl":"https://www.notion.so/1da5b6e0c94f808680b6eab8e340d60e","cachedResultName":"RequestRouterDB"}},"credentials":{"notionApi":{"id":"2B3YIiD4FMsF9Rjn","name":"Angelbot Notion"}},"typeVersion":2.2},{"id":"af762a13-5774-4608-a221-7860dce3f27c","name":"Format DB data for AI Context","type":"n8n-nodes-base.set","position":[2660,20],"parameters":{"options":{},"assignments":{"assignments":[{"id":"c4ac8c33-a220-4c07-bc0d-dc7ba7cc068e","name":"dbObject","type":"string","value":"=Request Example: {{ $json.name }}\n--\nRequest Description: {{ $json.property_request_description }}\n--\nRequest Action: {{ $json.property_request_action }}"}]}},"typeVersion":3.4},{"id":"88da9528-2a4c-426a-bd27-8caa47bed3f5","name":"Aggregate DB objects into one item","type":"n8n-nodes-base.aggregate","position":[2860,20],"parameters":{"options":{},"fieldsToAggregate":{"fieldToAggregate":[{"fieldToAggregate":"dbObject"}]}},"typeVersion":1},{"id":"204ce89b-9443-4ece-8385-cb3b59bd5a0b","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[2180,-400],"parameters":{"color":7,"width":826,"height":700,"content":"![notion](https://uploads.n8n.io/templates/notionlogo.png)\n## Get routing Database data\nAn AI bot that does not get smarter over time is not a useful bot. That is why this bot references a shared internal database where requests routing can be updated without having to touch the n8n workflows. When a request comes in that does not have a standardized process, the AI will generate a response based on its model training. You can use this as a starting point, but when this becomes a pattern, simply updating the notion database instantly upgrades the AI bot. Not only that, but others can update the database, not only giving the AI context, but also creating a centralized location for standardized processes for handling different request types. This can be adapted for any platform, not just linkedIn, such as shared email inboxes, shared social media pages, and even for support requests. "},"typeVersion":1},{"id":"d4a894d6-334b-4abe-9d1a-0e449da46b6f","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[920,-540],"parameters":{"color":7,"width":1246,"height":840,"content":"![Linkedin](https://uploads.n8n.io/templates/linkedinlogo.png))\n## Enrich LinkedIn Data with User or Org Data from Unipile\nLinkedIn messages arrive from one of two object types, users or organizations. This workflow extracts the user data and passes it along. If the user is not found, then the Organization endpoint is searched instead. If it's found, it send that, otherwise it sends a not found object. "},"typeVersion":1},{"id":"ec186db1-e7e8-480e-a94a-d4c1de5ee420","name":"Get Linkedin User Data from Unipile","type":"n8n-nodes-base.httpRequest","onError":"continueErrorOutput","position":[980,-140],"parameters":{"url":"=https://api9.unipile.com:13976/api/v1/users/{{ $('Webhook').item.json.body.sender.attendee_provider_id }}","options":{},"sendQuery":true,"sendHeaders":true,"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","queryParameters":{"parameters":[{"name":"account_id","value":"-oWmWRkASjKGUZadYcjcyg"}]},"headerParameters":{"parameters":[{"name":"accept","value":"application/json"}]}},"credentials":{"httpHeaderAuth":{"id":"VfYHlcsosNuUS2YD","name":"unipile angel"}},"typeVersion":4.2},{"id":"d3fb953a-f3cf-4005-934c-b091bb784d84","name":"Set User Data from Unipile","type":"n8n-nodes-base.set","position":[1240,-280],"parameters":{"options":{},"assignments":{"assignments":[{"id":"aee91408-b68d-472e-8c3e-89260dd38c1c","name":"first_name","type":"string","value":"={{ $json.first_name }}"},{"id":"57b3be6f-ba76-48c3-8f2e-1d9bb03d0dd5","name":"last_name","type":"string","value":"={{ $json.last_name }}"},{"id":"75167f30-96d6-4442-9542-9d1b8e17fcb6","name":"headline","type":"string","value":"={{ $json.headline }}"},{"id":"3e8bccc1-04a9-49f6-8053-eba22fe8d2f4","name":"websites","type":"array","value":"={{ $json.websites }}"},{"id":"2e3dd2fe-5f71-4d19-bee8-085dd9bfc18c","name":"follower_count","type":"number","value":"={{ $json.follower_count }}"},{"id":"ac5cc567-3c4f-481c-b229-9dc1e48d39fb","name":"connections_count","type":"number","value":"={{ $json.connections_count }}"},{"id":"6bad07a6-4641-48cb-b436-fb735319865f","name":"location","type":"string","value":"={{ $json.location }}"},{"id":"029fa351-f49f-4388-a59e-5719fcf8a506","name":"profile_picture_url","type":"string","value":"={{ $json.profile_picture_url }}"},{"id":"2f96dca6-acee-41c0-83b5-00cd406d3301","name":"is_influencer","type":"boolean","value":"={{ $json.is_influencer }}"},{"id":"4278e070-ce56-4993-b637-57ac60e83a49","name":"is_premium","type":"boolean","value":"={{ $json.is_premium }}"},{"id":"b92c38f1-1423-4b7e-a807-320d13e0a944","name":"shared_connections_count","type":"number","value":"={{ $json.shared_connections_count }}"},{"id":"96b24500-e6a4-444a-806c-0b61a1f00407","name":"type","type":"string","value":"user"}]}},"typeVersion":3.4},{"id":"c6077ddb-362d-45f4-a497-2529348148ab","name":"Group in one object - User","type":"n8n-nodes-base.aggregate","position":[1420,-280],"parameters":{"options":{},"aggregate":"aggregateAllItemData","destinationFieldName":"linkedinprofile"},"typeVersion":1},{"id":"1eb09bf7-fb93-4c19-bc41-86330c7b33e6","name":"Get Linkedin Org Data from Unipile","type":"n8n-nodes-base.httpRequest","onError":"continueErrorOutput","position":[1240,80],"parameters":{"url":"=https://api9.unipile.com:13976/api/v1/linkedin/company/{{ $('Webhook').item.json.body.sender.attendee_provider_id }}","options":{},"sendQuery":true,"sendHeaders":true,"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","queryParameters":{"parameters":[{"name":"account_id","value":"-oWmWRkASjKGUZadYcjcyg"}]},"headerParameters":{"parameters":[{"name":"accept","value":"application/json"}]}},"credentials":{"httpHeaderAuth":{"id":"VfYHlcsosNuUS2YD","name":"unipile angel"}},"typeVersion":4.2},{"id":"38f5ed6f-9302-4979-b964-c1d231a344b6","name":"Set Linkedin Org Data from Unipile","type":"n8n-nodes-base.set","position":[1520,-80],"parameters":{"options":{},"assignments":{"assignments":[{"id":"aee91408-b68d-472e-8c3e-89260dd38c1c","name":"first_name","type":"string","value":"={{ $json.name }}"},{"id":"57b3be6f-ba76-48c3-8f2e-1d9bb03d0dd5","name":"last_name","type":"string","value":"="},{"id":"75167f30-96d6-4442-9542-9d1b8e17fcb6","name":"headline","type":"string","value":"={{ $json.description }}"},{"id":"3e8bccc1-04a9-49f6-8053-eba22fe8d2f4","name":"websites","type":"string","value":"={{ $json.website }}"},{"id":"2e3dd2fe-5f71-4d19-bee8-085dd9bfc18c","name":"follower_count","type":"number","value":"={{ $json.followers_count }}"},{"id":"ac5cc567-3c4f-481c-b229-9dc1e48d39fb","name":"employee_count","type":"number","value":"={{ $json.employee_count_range.from }}"},{"id":"6bad07a6-4641-48cb-b436-fb735319865f","name":"location","type":"string","value":"={{ $json.locations[0].street.join(' ') }}, {{ $json.locations[0].city }} {{ $json.locations[0].area }}, {{ $json.locations[0].postalCode }} {{ $json.locations[0].country }}."},{"id":"89035aa7-e7bb-46eb-9f4b-633e2c17478a","name":"hashtags","type":"array","value":"={{ $json.hashtags }}"},{"id":"25b0abe6-aef7-4d6f-88ea-5fcbd3472089","name":"profile_picture_url","type":"string","value":"={{ $json.logo }}"},{"id":"decf44b7-520e-4977-9df5-276c5117d8e4","name":"type","type":"string","value":"organization"}]}},"typeVersion":3.4},{"id":"45bd4b50-01e6-468b-815a-58073c137693","name":"Group in one object - Org","type":"n8n-nodes-base.aggregate","position":[1720,-80],"parameters":{"options":{},"aggregate":"aggregateAllItemData","destinationFieldName":"linkedinprofile"},"typeVersion":1},{"id":"c97c50b6-b491-43cd-8eb6-e48b368c862e","name":"Set unable to find data object","type":"n8n-nodes-base.set","position":[1640,120],"parameters":{"options":{},"assignments":{"assignments":[{"id":"438518ca-d55a-45d5-9210-0c53de7ae108","name":"linkedinprofile","type":"string","value":"Unable to find LinkedIn Data"},{"id":"2d0595aa-bdd4-46e3-9f4d-e13e69c5a7a9","name":"type","type":"string","value":"none"}]}},"typeVersion":3.4},{"id":"b42b967a-b127-458c-94b6-7a81052e6ba1","name":"Sticky Note12","type":"n8n-nodes-base.stickyNote","position":[3700,-400],"parameters":{"color":7,"width":857,"height":813,"content":"![Slack](https://uploads.n8n.io/templates/slack.png)\n## Slack Bot Button Press\nThis workflow gets the button presses from the Slack interface and passes it along to Unipile for processing."},"typeVersion":1},{"id":"48da88b3-beac-4c52-bf0c-460bc4d525fb","name":"Set all potential Inputs","type":"n8n-nodes-base.set","position":[2020,-80],"parameters":{"options":{},"includeOtherFields":true},"typeVersion":3.4},{"id":"7e091689-7905-4101-8dc9-0609b4f80233","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-60,-180],"parameters":{"color":3,"height":360,"content":"#### Add me to Unipile Webhook Dashboard\nEnsure that you have created a webhook in the Unipile dashboard that links to this node. [Link to Webhook Dashboard](https://dashboard.unipile.com/webhooks)"},"typeVersion":1},{"id":"97da9488-0e37-42c0-8dbf-912731fc5091","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-60,540],"parameters":{"color":3,"height":420,"content":"#### Add me to your Slack App Interactivity and Shortcuts\nTo receive button presses in this webhook, ensure that you've created a slack app and then set the webhook URL in the Interactivity & Shortcuts tab to this production URL. Use our App Manifest template to quickly deploy the app with the correct scopes. [Link to template with App Manifest](https://dashboard.unipile.com/webhooks)"},"typeVersion":1},{"id":"c9be1dca-da24-4f18-b2a4-36f89b7520a1","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[940,-300],"parameters":{"width":180,"height":320,"content":"#### Update Credentials\nEnsure to use generic header auth. The name for the header is X-API-KEY. [Link to access token page on Unipile Site](https://dashboard.unipile.com/access-tokens)"},"typeVersion":1},{"id":"6e81a9bf-1c50-4366-9bae-be6241fc7875","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[1200,-80],"parameters":{"width":180,"height":320,"content":"#### Update Credentials\nEnsure to use generic header auth. The name for the header is X-API-KEY. [Link to access token page on Unipile Site](https://dashboard.unipile.com/access-tokens)"},"typeVersion":1},{"id":"d8d5d5d1-6fe4-4f03-95cb-4d3cb6182f59","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[2400,-80],"parameters":{"width":220,"height":280,"content":"#### Update Credentials\nDoes not have to be notion, can be any database type node like Google sheets. "},"typeVersion":1},{"id":"6a8202e9-e3c0-48db-b894-a009d801bddd","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[380,-180],"parameters":{"width":220,"height":340,"content":"#### Update with your Unipile UserID\nEasiest way to do this is to send a message to someone so it triggers this workflow and then copy the senderID that shows in this node"},"typeVersion":1},{"id":"36b271d3-53f6-4548-bf3f-8dea39e05b05","name":"Sticky Note10","type":"n8n-nodes-base.stickyNote","position":[3060,60],"parameters":{"width":220,"height":240,"content":"#### Update Credentials"},"typeVersion":1},{"id":"2391f630-e071-4720-81c8-7937452e0523","name":"Sticky Note13","type":"n8n-nodes-base.stickyNote","position":[4020,-160],"parameters":{"width":220,"height":560,"content":"#### Update Credentials"},"typeVersion":1},{"id":"c533f8ea-1391-4b2f-81ba-2caa8a919e3b","name":"Sticky Note14","type":"n8n-nodes-base.stickyNote","position":[1320,360],"parameters":{"width":220,"height":340,"content":"#### Update Credentials\nEnsure to use generic header auth. The name for the header is X-API-KEY. [Link to access token page on Unipile Site](https://dashboard.unipile.com/access-tokens)"},"typeVersion":1},{"id":"6f0ef5cc-ef53-4a02-bdd9-5931c9ba8a0e","name":"Sticky Note15","type":"n8n-nodes-base.stickyNote","position":[1620,460],"parameters":{"width":220,"height":460,"content":"#### Update Credentials"},"typeVersion":1}],"connections":{"Webhook":{"main":[[{"node":"Global Variables","type":"main","index":0}]]},"AI Agent":{"main":[[{"node":"Decide on Message Type","type":"main","index":0}]]},"New Message":{"main":[[{"node":"Get Linkedin User Data from Unipile","type":"main","index":0}]]},"Parse Webhook":{"main":[[{"node":"User Switcher","type":"main","index":0}]]},"Simple Memory":{"ai_memory":[[{"node":"AI Agent","type":"ai_memory","index":0}]]},"User Switcher":{"main":[[{"node":"Isolate Message and Payload","type":"main","index":0}],[{"node":"Isolate Payload","type":"main","index":0}]]},"Verify Webhook":{"main":[[{"node":"Parse Webhook","type":"main","index":0}]]},"Isolate Payload":{"main":[[{"node":"Send webhook to Coworker Workflow","type":"main","index":0}]]},"Check if from me":{"main":[[{"node":"New Message","type":"main","index":0}],[{"node":"Response, No action","type":"main","index":0}]]},"Global Variables":{"main":[[{"node":"Check if from me","type":"main","index":0}]]},"Check if approved":{"main":[[{"node":"Send Message to LinkedIn via Unipile","type":"main","index":0}],[{"node":"Delete Denied Message from Slack","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Slack Button Press":{"main":[[{"node":"Verify Webhook","type":"main","index":0}]]},"Decide on Message Type":{"main":[[{"node":"Send User Message","type":"main","index":0}],[{"node":"Send Org Message","type":"main","index":0}],[{"node":"Send Nothing Found Message","type":"main","index":0}]]},"Set all potential Inputs":{"main":[[{"node":"Isolate parent workflow data for AI","type":"main","index":0}]]},"Structured Output Parser":{"ai_outputParser":[[{"node":"AI Agent","type":"ai_outputParser","index":0}]]},"Group in one object - Org":{"main":[[{"node":"Set all potential Inputs","type":"main","index":0}]]},"Group in one object - User":{"main":[[{"node":"Set all potential Inputs","type":"main","index":0}]]},"Set User Data from Unipile":{"main":[[{"node":"Group in one object - User","type":"main","index":0}]]},"Isolate Message and Payload":{"main":[[{"node":"Check if approved","type":"main","index":0}]]},"Format DB data for AI Context":{"main":[[{"node":"Aggregate DB objects into one item","type":"main","index":0}]]},"Set unable to find data object":{"main":[[{"node":"Set all potential Inputs","type":"main","index":0}]]},"Aggregate DB objects into one item":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Get Linkedin Org Data from Unipile":{"main":[[{"node":"Set Linkedin Org Data from Unipile","type":"main","index":0}],[{"node":"Set unable to find data object","type":"main","index":0}]]},"Set Linkedin Org Data from Unipile":{"main":[[{"node":"Group in one object - Org","type":"main","index":0}]]},"Get Linkedin User Data from Unipile":{"main":[[{"node":"Set User Data from Unipile","type":"main","index":0}],[{"node":"Get Linkedin Org Data from Unipile","type":"main","index":0}]]},"Isolate parent workflow data for AI":{"main":[[{"node":"Get Request Router Directory Database","type":"main","index":0}]]},"Send Message to LinkedIn via Unipile":{"main":[[{"node":"Delete Approved Message from Slack","type":"main","index":0}]]},"Get Request Router Directory Database":{"main":[[{"node":"Format DB data for AI Context","type":"main","index":0}]]}}}


name: Personalized LinkedIn Responses with OpenAI GPT & Notion-based Routing
author_name: Angel Menendez
author_username: djangelic
categories: []
created_at: 2025-06-12T00:44:08.589Z
updated_at: 2025-06-12T00:44:08.589Z
url: https://n8n.io/workflows/4891
scraped_at: 2025-07-06 21:16:30
description:
  Who is this for?

  This workflow is for professionals and teams who want to automate LinkedIn message replies with intelligent, human-like responses — without losing control over tone or accuracy. Ideal for founders, sales teams, DevRel, or community managers handling high-volume inbound messages.

  What problem is this workflow solving?

  Responding to every LinkedIn message manually is slow and inconsistent. Basic AI bots generate replies without context or nuance. This subworkflow solves both problems by using structured message routing from Notion and profile insights from UniPile to craft smart, context-aware responses.

  What this workflow does

  This workflow takes the sender’s message and profile (from LinkedIn Auto Message Router with Request Detection) and references your centralized Notion database of message types. It uses that to either match the message to a known response or generate a new one using OpenAI's GPT model — all while following professional tone guidelines.

  This is the third workflow in a 3-part automation system:

  Receives data from LinkedIn Auto Message Router with Request Detection
  Uses UniPile LinkedIn Profile Lookup Subworkflow to enrich responses based on follower count or org data

  Example Use Case

  If a message comes from someone with low reach (e.g., under 1,000 followers), the AI politely deflects a meeting request. If an influencer reaches out, the AI immediately offers a booking link. Your team controls this logic by updating the Notion database — no edits to the workflow required.

  Setup

  Connect this workflow as a subworkflow in your router or Slack approval flow
  Store your Notion API key and database ID in n8n
  Provide the following parent inputs:
     message – The LinkedIn message text
     sender – Name of the sender
     chatid – Session ID (optional for memory)
     linkedinprofile – Enriched array with LinkedIn context (follower count, connection info, etc.)

  Add your preferred AI model credentials (supports OpenAI, Gemini, or Ollama)
  Optional: Customize system prompt to better match your brand voice

  How to customize this workflow to your needs

  Update the Notion schema to include industry-specific categories or actions
  Change the AI tone (e.g., humorous, more corporate, etc.)
  Add conditional logic for auto-sending messages without Slack approval
  Extend to support multiple platforms (e.g., email, X/Twitter, Instagram DMs)

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

workflow_json:
  {"meta":{"instanceId":"cb484ba7b742928a2048bf8829668bed5b5ad9787579adea888f05980292a4a7"},"nodes":[{"id":"ae3cbbb0-1987-4457-b91f-d1a766e09fb7","name":"When Executed by Another Workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[-180,-60],"parameters":{"workflowInputs":{"values":[{"name":"message"},{"name":"sender"},{"name":"chatid"},{"name":"linkedinprofile","type":"array"}]}},"typeVersion":1.1},{"id":"0c10e97f-1de0-493e-9eda-a36507f40429","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[980,-60],"parameters":{"text":"=Sender Name: {{ $('Isolate parent workflow data for AI').item.json.sender }}\nSender Message: {{ $('Isolate parent workflow data for AI').item.json.message }}\nMy Name: Your Name\n\nIf found, the linkedin profile will be below, pay close attention to the number of followers and connections: \n{{ $('When Executed by Another Workflow').item.json.linkedinprofile.toJsonString() }}","options":{"systemMessage":"=You are an expert professional assistant designed to help generate smart, personalized responses to LinkedIn messages.\n\nYou will be provided with:\n1. The **incoming message** and name from a LinkedIn user.\n2. A **database of past requests and responses**. These are known message types and the preferred replies.\n3. Context about the assistant's voice and tone.\n\n### Your Objective:\n- First, scan the database for any message that closely matches the incoming LinkedIn message. If a match is found, use the **corresponding response** as a base — you may slightly tailor it if needed (e.g., change names or dates).\n- If no close match is found, generate a **new, thoughtful reply** based on the message content, tone guidelines, and best practices in business networking. If you do not have a direct link or URL to provide from the Request Database, do not reference a website or URL. Instead say a variation of let me get back to you on that and see what I can find. \n\n### Tone Guidelines:\n- Friendly, confident, and professional — but never robotic.\n- Lightly personalized. Use the sender’s name if available.\n- Avoid sounding like a sales pitch.\n- Keep replies concise and natural, like something you'd actually send on LinkedIn.\n\n### When generating a new message:\n- Acknowledge the sender’s message.\n- Add a relevant, helpful comment or question to continue the conversation.\n- Keep the tone warm and open-ended.\n\n### Output format:\nOnly output the message text that should be sent to the user. Do not explain your reasoning. If you do not have a direct link to provide, do not reference a website or URL. Instead say let me get back to you on that and see what I can find. \n\nLet’s begin.\nRequest Database:\n\n{{ $json.dbObject.join('\\n\\n----\\n\\n') }}\n\nWhen responding, use the following format:\n{\n\t\"output\": \"message response\",\n\t\"found\": true\n}\nFor output output the message response, for found output a boolean, true if an example is found in the Request Database, false if a response is not found. The output is going to slack so ensure you escape your outputs like new lines. "},"promptType":"define","hasOutputParser":true},"typeVersion":1.9},{"id":"46cefba2-2107-4d41-b270-8442d2aae09b","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[1100,180],"parameters":{"sessionKey":"={{ $('Isolate parent workflow data for AI').item.json.chatid }}","sessionIdType":"customKey"},"typeVersion":1.3},{"id":"3a1e8f2d-5ea9-4f31-b489-93fca3c8442e","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[920,180],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o","cachedResultName":"gpt-4o"},"options":{}},"credentials":{"openAiApi":{"id":"QpFZ2EiM3WGl6Zr3","name":"Marketing OpenAI"}},"typeVersion":1.2},{"id":"2a69d1d4-5c30-4cc1-930b-7b72cd1c0ed1","name":"Structured Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[1260,180],"parameters":{"jsonSchemaExample":"{\n\t\"output\": \"message response\",\n\t\"found\": true\n}"},"typeVersion":1.2},{"id":"bb9a7e05-d641-4caa-9fcc-7b1d39dd62d7","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[780,-380],"parameters":{"color":7,"width":668,"height":718,"content":"![hctiapi](https://uploads.n8n.io/templates/openai.png)\n## Generate Automated response\nThe AI bot receives not only the message from LinkedIn, but also LinkedIn user context, such as the number of followers and connections, allowing for tailored responses. For example if a user asks to meet, but they don't meet a certain number of followers threshold, they are politely declined. However if an influencer reaches out, they are automatically given a booking link to ensure that high priority requests are immediately followed up on. "},"typeVersion":1},{"id":"a7f5f2b3-bc0c-450e-bbd8-60a01dc4b202","name":"Isolate parent workflow data for AI","type":"n8n-nodes-base.set","position":[20,-60],"parameters":{"options":{},"assignments":{"assignments":[{"id":"91a1191e-bac0-4b8b-b263-a03c63435470","name":"sender","type":"string","value":"={{ $json.sender }}"},{"id":"0f8c17c8-d598-4840-8b89-8dbdcd529231","name":"message","type":"string","value":"={{ $json.message }}"},{"id":"c9132b69-5e0e-4ccf-86bb-0e4cfa734860","name":"chatid","type":"string","value":"={{ $json.chatid }}"}]}},"typeVersion":3.4},{"id":"ca7625b3-2c2a-48c5-82b5-61a00ac95c81","name":"Get Request Router Directory Database","type":"n8n-nodes-base.notion","position":[220,-60],"parameters":{"options":{},"resource":"databasePage","operation":"getAll","databaseId":{"__rl":true,"mode":"list","value":"1da5b6e0-c94f-8086-80b6-eab8e340d60e","cachedResultUrl":"https://www.notion.so/1da5b6e0c94f808680b6eab8e340d60e","cachedResultName":"RequestRouterDB"}},"credentials":{"notionApi":{"id":"2B3YIiD4FMsF9Rjn","name":"Angelbot Notion"}},"typeVersion":2.2},{"id":"ffa17cbf-a9ae-4427-8aa4-a07ab97bf60b","name":"Format DB data for AI Context","type":"n8n-nodes-base.set","position":[420,-60],"parameters":{"options":{},"assignments":{"assignments":[{"id":"c4ac8c33-a220-4c07-bc0d-dc7ba7cc068e","name":"dbObject","type":"string","value":"=Request Example: {{ $json.name }}\n--\nRequest Description: {{ $json.property_request_description }}\n--\nRequest Action: {{ $json.property_request_action }}"}]}},"typeVersion":3.4},{"id":"96980e0e-632a-49dc-9cbb-a487d117e2af","name":"Aggregate DB objects into one item","type":"n8n-nodes-base.aggregate","position":[620,-60],"parameters":{"options":{},"fieldsToAggregate":{"fieldToAggregate":[{"fieldToAggregate":"dbObject"}]}},"typeVersion":1},{"id":"d66e6cc9-2955-4d45-a65b-ffc734f9a4cf","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-240,-380],"parameters":{"color":7,"width":1006,"height":640,"content":"![notion](https://uploads.n8n.io/templates/notionlogo.png)\n## Get routing Database data\nAn AI bot that does not get smarter over time is not a useful bot. That is why this bot references a shared internal database where requests routing can be updated without having to touch the n8n workflows. When a request comes in that does not have a standardized process, the AI will generate a response based on its model training. You can use this as a starting point, but when this becomes a pattern, simply updating the notion database instantly upgrades the AI bot. Not only that, but others can update the database, not only giving the AI context, but also creating a centralized location for standardized processes for handling different request types. This can be adapted for any platform, not just linkedIn, such as shared email inboxes, shared social media pages, and even for support requests. "},"typeVersion":1}],"connections":{"Simple Memory":{"ai_memory":[[{"node":"AI Agent","type":"ai_memory","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Structured Output Parser":{"ai_outputParser":[[{"node":"AI Agent","type":"ai_outputParser","index":0}]]},"Format DB data for AI Context":{"main":[[{"node":"Aggregate DB objects into one item","type":"main","index":0}]]},"When Executed by Another Workflow":{"main":[[{"node":"Isolate parent workflow data for AI","type":"main","index":0}]]},"Aggregate DB objects into one item":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Isolate parent workflow data for AI":{"main":[[{"node":"Get Request Router Directory Database","type":"main","index":0}]]},"Get Request Router Directory Database":{"main":[[{"node":"Format DB data for AI Context","type":"main","index":0}]]}}}


name: Analyze Stock Charts with GPT-4 Vision and Send Results via Telegram
author_name: Fenngbrotalk
author_username: yihaohuang
categories: []
created_at: 2025-06-12T01:53:49.406Z
updated_at: 2025-06-12T01:53:49.406Z
url: https://n8n.io/workflows/4892
scraped_at: 2025-07-06 21:16:30
description:
  n8n Workflow: AI-Powered Stock Chart Analysis Bot for Telegram

  This is a powerful n8n automation workflow that integrates a Telegram bot with OpenAI's multimodal large language model (GPT-4 Vision) to provide users with real-time stock chart analysis.

  Workflow Breakdown

  Receive Image:** The workflow is initiated by a Telegram Trigger. It activates whenever a user sends an image (e.g., a stock's candlestick chart) to a designated Telegram chat, automatically downloading the file.
  Image Pre-processing:** To optimize the AI's performance and efficiency, the Edit Image node resizes the incoming image to a standard 512x512 pixel format.
  AI Vision Analysis:** The processed image is then passed to a LangChain Chain, which utilizes the OpenAI GPT-4 Vision model. A sophisticated system prompt instructs the AI to act as a professional stock analyst.
  Intelligent Interpretation:** The AI analyzes the image to identify the stock's name, price trend (uptrend, downtrend, or sideways), key support/resistance levels, and volume changes. It then generates a comprehensive analysis report combining technical indicators and market sentiment.
  Structured Output:** To ensure reliability and consistency, the AI's output is parsed into a specific JSON format. This structure includes a search_word (for the industry/sector) and the main content (the analysis text).
  Send Response:** Finally, the workflow extracts the content field from the JSON output and uses the Telegram node to send this professional analysis back to the user as a text message in the same chat.

  Key Features

  User-Friendly:** Users simply send an image to get an analysis, requiring no complex commands.
  Instant & Efficient:** The entire analysis and response process is fully automated and completed within moments.
  Professional-Grade Analysis:** Leverages the advanced image recognition and reasoning capabilities of GPT-4 Vision to deliver insights comparable to those of a human analyst.
  Reliable & Consistent:** The use of structured output ensures that the format of the response is always consistent and easy to read or process further.

nodes_used:
  ["n8n-nodes-base.editImage","n8n-nodes-base.telegram","@n8n/n8n-nodes-langchain.chainLlm","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.outputParserStructured"]

workflow_json:
  {"id":"yBjR5afdjZNtPifv","meta":{"instanceId":"5f9764ce8ade9ce9b31164c3b692a0c825a999b46f96de953f9cdad63881e1ab","templateCredsSetupCompleted":true},"name":"Image_anlysis","tags":[],"nodes":[{"id":"fb1046cf-d558-4874-a749-8f03b9f7ad3e","name":"Telegram Trigger","type":"n8n-nodes-base.telegramTrigger","position":[-720,-200],"webhookId":"69c98bf3-aed0-4b73-ba6f-15879fb2378b","parameters":{"updates":["message"],"additionalFields":{"download":true}},"credentials":{"telegramApi":{"id":"jqN4zt7cRMB5sO0P","name":"image_anlsis"}},"typeVersion":1.2},{"id":"381f813f-1d16-4e31-a12f-0ad36155bc05","name":"Basic LLM Chain","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[140,-360],"parameters":{"text":"这只股票怎么样","batching":{},"messages":{"messageValues":[{"message":"# 股票图表分析提示词\n\n## 角色定义\n您的角色是分析股票价格图表。\n\n## 分析要求\n对于每个股票图表，请提供：\n- 股票名称和当前价格趋势（上涨/下跌/横盘）\n- 关键价位或百分比变化\n- 简要趋势分析\n\n\n## 输出格式（JSON）\n{\n  \"search_word\": \"与股票所属行业或公司业务相关的核心检索词\",\n  \"content\": \"股票名称 + 趋势分析 + 关键价格信息 + 技术面解读\"\n}\n\n## 注意事项\n- **search_word**: 匹配股票所属行业关键词，同时也能是一些细分行业关键词\n- **content**: 趋势分析要富含逻辑，因为你的决策决定了用户能否赚钱，包含技术面和市场情绪信息\n- 价格信息要准确，包括具体数值和百分比变化，同时可以提醒用户可能的止损或者止盈的价格\n- search_word要能准确反映该股票的核心业务领域或行业属性"},{"type":"HumanMessagePromptTemplate","messageType":"imageBinary"}]},"promptType":"define","hasOutputParser":true},"typeVersion":1.7},{"id":"453589be-36f3-4022-8306-ba54b2d6bbcf","name":"Edit Image","type":"n8n-nodes-base.editImage","position":[-220,-360],"parameters":{"width":512,"height":512,"options":{},"operation":"resize","dataPropertyName":"=data"},"typeVersion":1},{"id":"28b88eeb-da05-4a17-ac2c-4fdf846296fb","name":"Telegram","type":"n8n-nodes-base.telegram","position":[740,-440],"webhookId":"41cfac39-0bd2-474b-a1a2-83fc4115e257","parameters":{"text":"={{ $json.output.content }}","chatId":"={{ $('Telegram Trigger').item.json.message.chat.id }}","additionalFields":{}},"credentials":{"telegramApi":{"id":"jqN4zt7cRMB5sO0P","name":"image_anlsis"}},"typeVersion":1.2},{"id":"0f7f2636-d90e-4ea1-8f4f-ad528ef8db50","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[100,-160],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4-vision-preview","cachedResultName":"gpt-4-vision-preview"},"options":{}},"credentials":{"openAiApi":{"id":"rRrVLkLnJIVGp3tN","name":"geminiapi"}},"typeVersion":1.2},{"id":"c88d1439-c1fb-4411-9996-6cd5f22d980a","name":"Structured Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[460,-140],"parameters":{"jsonSchemaExample":"{\n  \"search_word\": \"与股票所属行业或公司业务相关的核心检索词\",\n  \"content\": \"股票名称 + 趋势分析 + 关键价格信息 + 技术面解读\"\n}"},"typeVersion":1.2}],"active":true,"settings":{"executionOrder":"v1"},"versionId":"6c6c21e5-3ee4-48b9-9330-4c42367722c5","connections":{"Edit Image":{"main":[[{"node":"Basic LLM Chain","type":"main","index":0}]]},"Basic LLM Chain":{"main":[[{"node":"Telegram","type":"main","index":0}]]},"Telegram Trigger":{"main":[[{"node":"Edit Image","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Basic LLM Chain","type":"ai_languageModel","index":0}]]},"Structured Output Parser":{"ai_outputParser":[[{"node":"Basic LLM Chain","type":"ai_outputParser","index":0}]]}}}


name: Automated Daily Email Analysis & Summary with GPT-4o and Gmail
author_name: Zach @Ajenta
author_username: ajenta
categories: []
created_at: 2025-06-12T04:19:38.502Z
updated_at: 2025-06-12T04:19:38.502Z
url: https://n8n.io/workflows/4893
scraped_at: 2025-07-06 21:16:30
description:
  Daily Email Pulse Summary:

  This agent summarizes a user's daily emails into a clean, actionable summary. It uses OpenAI to analyze content and sends a formatted "Daily Pulse" email at the end of each day.

  Main use cases:
  Keep track of open loops and next steps across all email conversations

  Identify high-potential leads and flag conversations going nowhere

  Eliminate the need to manually review your inbox at day’s end

  Build a smart summary layer using AI without hallucination or noise

  How it works
  This workflow can be divided into eight core nodes, each serving a distinct purpose in helping a user stay on top of their day. The result is a curated, AI-generated summary delivered to your inbox — crafted from real message content, not guesswork.

  Schedule Trigger (Trigger Node – Runs Daily at Set Time)

  Kicks off the workflow at a specific time each day (e.g. 6:00 PM).
  Ensures you receive your Daily Pulse consistently, without needing to run it manually.

  Date Transformer (Function Node – Define Today & Tomorrow Range)
  Uses JavaScript to calculate the current day’s date range:
  	 today: Start of day (00:00:00)
  	 tomorrow: Start of next day (used as a cutoff)
  This ensures only emails from today are analyzed, keeping the summary focused and current.

  Get All Messages (Gmail Node – Fetch Filtered Emails)
  Pulls in all Gmail messages with internalDate between today and tomorrow.
  Outputs structured data: from, subject, and body text of each email.
  This forms the raw data for the daily business pulse.

  Aggregator (Function or Item Lists Node – Combine Message Fields)
  Aggregates each message into a readable format:

  From: John@example.com  
  Subject: Demo Follow-up  
  Body: Let’s schedule a time this week...

  All messages are stitched together into a single combinedText string for analysis.
  This gives the AI model full context for the day in one unified document.

  Email Cleanup (Function Node – Remove Noise & Normalize Text)
  Cleans the combinedText blob to remove:
  	HTML tags
  	Marketing footers (e.g., unsubscribe links)
  	Redundant whitespace or formatting artifacts
  Ensures GPT gets clean, relevant message content with no distractions.

  Agent (OpenAI Node – Generate Structured Summary)
  Uses a System Prompt to define its role as an AI Chief of Staff.
  Uses a User Prompt that instructs it to categorize messages into sections:

  	📝 Open Loops / Pending Follow-Up
  	🚀 Next Steps You’ve Committed To
  	🧲 Leads Worth Following Up On
  	🛑 Conversations That Aren’t Leading Anywhere
  	🧠 Strategy Notes
  	✅ Top 3 Tasks for Tomorrow

  Built-in guardrails ensure the model only uses real content (no hallucination).
  Sections with no relevant data are omitted to keep it concise.

  HTML Formatter (Function Node – Wrap Markdown in Email-Ready HTML)
  Wraps the GPT-generated markdown summary in a simple &lt;html&gt;&lt;body&gt; structure.
  Applies white-space: pre-wrap to preserve formatting and spacing.
  The result is a clean, readable email that renders well across all inboxes (especially Gmail).

  Email Send (Email Node – Deliver the Final Pulse)
  Sends the formatted summary to your email inbox.
  Subject: Your Daily Business Pulse – {{today}}
  HTML body: Uses the formatted output from the previous step.
  Final output: a well-organized, scannable summary of the day’s communication — focused on what matters.

  Why It Works
  Automates the end-of-day review ritual without effort
  Prioritizes follow-ups, action items, and time-sensitive leads
  Filters out noise and low-value conversations
  Leverages GPT without risk of hallucination or irrelevant output
  Delivers clarity, helping you focus on tomorrow’s most important tasks

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

workflow_json:
  {"id":"Ucu10DYuMwYdLLVk","meta":{"instanceId":"159ec2e1d690fe685084d28de8ca73848642bf563457a19b94cfc00f23a0d9a9","templateCredsSetupCompleted":true},"name":"Scheduled Daily Email Pulse","tags":[],"nodes":[{"id":"908a85db-7b15-4ece-8dab-19398e0c1871","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-80,-80],"parameters":{"rule":{"interval":[{"triggerAtHour":18}]}},"typeVersion":1.2},{"id":"8cadc5e6-193e-42e9-b2fc-54a2025191c2","name":"Gmail","type":"n8n-nodes-base.gmail","position":[360,-80],"webhookId":"6fbdcf54-7d41-4fb0-aa17-07edb33cd5d0","parameters":{"simple":false,"filters":{"receivedAfter":"={{ $json.today}}","receivedBefore":"={{ $json.tomorrow }}"},"options":{},"operation":"getAll"},"credentials":{"gmailOAuth2":{"id":"gUrhTlOlNSEw7OKA","name":"Gmail account"}},"typeVersion":2.1,"alwaysOutputData":true},{"id":"62ab4e36-b42f-4aff-8ec5-4456f4827ca3","name":"Date Transformer","type":"n8n-nodes-base.code","position":[140,-80],"parameters":{"jsCode":"const now = new Date();\nconst today = new Date(now.getFullYear(), now.getMonth(), now.getDate());\nconst tomorrow = new Date(today);\ntomorrow.setDate(today.getDate() + 1);\n\nconst isoDate = (d) => d.toISOString().split('.')[0] + 'Z';\n\nreturn [\n  {\n    json: {\n      today: isoDate(today),\n      tomorrow: isoDate(tomorrow),\n    },\n  },\n];\n"},"typeVersion":2},{"id":"c25a964f-6d41-4c97-b90f-f5ce15cadaa7","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[1020,160],"parameters":{"text":"You are an AI Chief of Staff for a small business owner. Your job is to review a day’s worth of emails, texts, and calls and produce a concise, structured summary that helps them stay focused and effective.\n\nYou must only surface tasks, people, and opportunities that appear in the message content. Do not invent next steps, leads, or strategy notes.\n\nIf a section has no relevant content, leave it out entirely. It’s better to report nothing than to guess.","options":{"systemMessage":"=Below is a transcript of today’s messages — including email, text, and call summaries.\n\nAnalyze the content and generate a markdown-formatted **Daily Business Pulse**, using only what appears in the messages. Do not assume, extrapolate, or fabricate any details.\n\nMessages:\n{{ $json.combinedText }}\n\nUse the structure below. Omit any section that has no relevant content.\n\n---\n\n👋 **Here’s what matters from your day**\n\n---\n\n📝 **Open Loops / Pending Follow-Ups**  \n_List any conversations that require a response or action._\n\n---\n\n🚀 **Next Steps You've Committed To**  \n_List anything the user said they would do._\n\n---\n\n🧲 **Leads or Conversations Worth Following Up On**  \n_Only include if the person expressed interest or asked for help._\n\n---\n\n🛑 **Conversations That Aren’t Leading Anywhere**  \n_Include if there are back-and-forths with no progress, spam, or promotional threads._\n\n---\n\n🧠 **Strategy Notes**  \n_Only add notes if there are clear, recurring themes or opportunities based on the content._\n\n---\n\n✅ **Top 3 Tasks for Tomorrow**  \n_If tasks were mentioned and clearly matter, list the top 3. Otherwise, leave this out._"},"promptType":"define"},"typeVersion":2},{"id":"fe2552ce-48be-44bd-b975-cde379b46b51","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[1020,360],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"qiPWoGhtEMQi7AWs","name":"OpenAi account"}},"typeVersion":1.2},{"id":"d2410164-fde8-46f1-8df1-6cbf3874d397","name":"Aggregate","type":"n8n-nodes-base.aggregate","position":[580,60],"parameters":{"options":{},"fieldsToAggregate":{"fieldToAggregate":[{"fieldToAggregate":"headers.from"},{"fieldToAggregate":"headers.subject"},{"fieldToAggregate":"text"}]}},"typeVersion":1},{"id":"9c3c28f5-35d5-4164-a694-8a9bc26354d5","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-120,-120],"parameters":{"color":4,"width":620,"height":200,"content":""},"typeVersion":1},{"id":"476d2f5a-c0da-4683-89a2-9cbe9d93c638","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[520,40],"parameters":{"color":6,"width":420,"content":""},"typeVersion":1},{"id":"f9301bfa-2cd7-4eaf-9798-729604a6b49a","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[980,140],"parameters":{"width":540,"content":""},"typeVersion":1},{"id":"5cdda71c-ba41-41ba-aae1-66d39caf75c9","name":"Email Cleanup","type":"n8n-nodes-base.code","position":[780,60],"parameters":{"jsCode":"const cleanMessages = items.map(item => {\n  const from = item.json.header?.from || \"Unknown sender\";\n  const subject = item.json.header?.subject || \"No subject\";\n  const rawBody = item.json.text || \"\"; // fall back to empty string\n  const body = String(rawBody); // ensure it's a string\n\n  const cleaned = body\n    .replace(/<\\/?[^>]+(>|$)/g, \"\")             // Remove HTML\n    .replace(/(Unsubscribe|View in browser)/gi, \"\") // Strip only promo triggers\n    .replace(/\\n{3,}/g, \"\\n\\n\")                 // Collapse excess breaks\n    .trim();                                    // Clean up\n\n  return `📩 **From:** ${from}\\n**Subject:** ${subject}\\n**Preview:**\\n${cleaned}\\n\\n---\\n`;\n});\n\nreturn [{\n  json: {\n    combinedText: cleanMessages.join('\\n')\n  }\n}];"},"typeVersion":2},{"id":"0807cef5-876f-433d-a94a-2db7f86d844d","name":"Format HTML","type":"n8n-nodes-base.code","position":[1380,160],"parameters":{"jsCode":"const markdown = $input.all().map((item) => item.json.output);\nlet html = markdown.map((md) =>\n  md\n    .replace(/(\\*\\*|__)(.*?)\\1/g, \"<b>$2</b>\")\n    .replace(/(\\*|_)(.*?)\\1/g, \"<i>$2</i>\")\n    .replace(/~~(.*?)~~/g, \"<del>$1</del>\")\n    .replace(/`([^`\\n]+)`/g, \"<code>$1</code>\")\n    .replace(/!\\[([^\\]]+)\\]\\(([^\\)]+)\\)/g, '<img src=\"$2\" alt=\"$1\">')\n    .replace(/\\[([^\\]]+)\\]\\(([^\\)]+)\\)/g, '<a href=\"$2\">$1</a>')\n    .replace(/(\\r\\n|\\n|\\r)/gm, \"<br>\"),\n);\n\nreturn { html };\n"},"typeVersion":2},{"id":"bfc39659-9e36-4dde-9536-558d491f965c","name":"Send Message","type":"n8n-nodes-base.gmail","position":[1580,320],"webhookId":"39d8fc4a-0fa4-4a13-a123-2f1373787a79","parameters":{"sendTo":"youremail@gmail.com","message":"={{ $json.html[0] }}","options":{},"subject":"Here's Your Daily Pulse"},"credentials":{"gmailOAuth2":{"id":"gUrhTlOlNSEw7OKA","name":"Gmail account"}},"typeVersion":2.1}],"active":true,"settings":{"executionOrder":"v1"},"versionId":"fa9af357-4a58-4540-94d4-7228678ea75b","connections":{"Gmail":{"main":[[{"node":"Aggregate","type":"main","index":0}]]},"AI Agent":{"main":[[{"node":"Format HTML","type":"main","index":0}]]},"Aggregate":{"main":[[{"node":"Email Cleanup","type":"main","index":0}]]},"Format HTML":{"main":[[{"node":"Send Message","type":"main","index":0}]]},"Email Cleanup":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Date Transformer":{"main":[[{"node":"Gmail","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Date Transformer","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]}}}


name: Scheduled YouTube Video Uploads with Google Sheets & Drive Integration
author_name: Rahul Joshi
author_username: rahul08
nodes_used: ["n8n-nodes-base.googleSheets","n8n-nodes-base.googleDrive","n8n-nodes-base.youTube"]
categories: []
created_at: 2025-06-12T08:34:05.302Z
updated_at: 2025-06-12T08:34:05.302Z
url: https://n8n.io/workflows/4900
scraped_at: 2025-07-06 21:16:30
description:
  Description:

  Effortlessly automate YouTube video uploads with this ready-to-use n8n workflow. Integrated with Google Sheets, Google Drive, and YouTube API, this template streamlines your video publishing process based on scheduled metadata entries.

  Key Features:

  🗓️ Scheduled Uploads (Mon–Fri at 9 AM, 12 PM, 3 PM)
  📋 Reads video metadata (title, description, filename) from Google Sheets
  🔍 Locates video files in Google Drive by filename
  ⬇️ Downloads and uploads videos to YouTube with the correct metadata
  ✅ Updates the status in the sheet to avoid duplicates
  📂 Moves uploaded files to a specified archive folder for organization

  Requirements:

  Google Sheets with metadata (Title, Description, File Name, Status)
  Google Drive with video files
  YouTube API access and OAuth credentials
  A pre-set folder structure for organization

  Perfect For:

  Content creators, YouTube channel managers, marketers, and editors who want to automate repetitive upload tasks, maintain consistent publishing schedules, and organize video assets—without manual effort.

workflow_json:
  {"id":"06o12GkCUGklKpVj","meta":{"instanceId":"18c9b77a7db94bab09d77f4a9c44dd94853695bba1618cb7bc3c4bc412c07c1e"},"name":"YouTube Upload Automation","tags":[],"nodes":[{"id":"3f79bd90-93f0-4a86-ac1e-d770167b9cc2","name":"Google Sheets","type":"n8n-nodes-base.googleSheets","position":[60,-20],"parameters":{},"typeVersion":4.5},{"id":"017f682c-3ffd-440a-bb86-c250f996d65b","name":"Get Video File Id","type":"n8n-nodes-base.googleDrive","position":[280,-20],"parameters":{},"typeVersion":3},{"id":"2fc17cbe-3df4-4f8f-b1d4-7d461d56ed95","name":"Download Video Data","type":"n8n-nodes-base.googleDrive","position":[-160,200],"parameters":{},"typeVersion":3},{"id":"6ba6bb57-dbe4-4cda-9d72-e20f17f46bf4","name":"Upload to YouTube","type":"n8n-nodes-base.youTube","position":[60,200],"parameters":{},"typeVersion":1},{"id":"a442d21f-9d29-4434-bbf7-0b4959da2a74","name":"Update Status","type":"n8n-nodes-base.googleSheets","position":[280,200],"parameters":{},"typeVersion":4.5},{"id":"55c915d6-6096-4cf3-89b1-93720a2ee615","name":"Get Folder Name","type":"n8n-nodes-base.googleDrive","position":[-160,420],"parameters":{},"typeVersion":3},{"id":"b7ca1715-b0e7-429c-b112-f858c83f4b78","name":"Move Video File to Folder","type":"n8n-nodes-base.googleDrive","position":[60,420],"parameters":{},"typeVersion":3},{"id":"7b91cb20-b006-4e60-9e4d-97be63566942","name":"M-F 9am,12pm,3pm","type":"n8n-nodes-base.scheduleTrigger","position":[-160,-20],"parameters":{},"typeVersion":1.2},{"id":"d2b07579-7240-4992-b4dd-432cde8b5cfa","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-860,-20],"parameters":{"content":""},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"18782e6c-c7db-4968-8d06-b9fdc8398b20","connections":{"Google Sheets":{"main":[[{"node":"Get Video File Id","type":"main","index":0}]]},"Update Status":{"main":[[{"node":"Get Folder Name","type":"main","index":0}]]},"Get Folder Name":{"main":[[{"node":"Move Video File to Folder","type":"main","index":0}]]},"M-F 9am,12pm,3pm":{"main":[[{"node":"Google Sheets","type":"main","index":0}]]},"Get Video File Id":{"main":[[{"node":"Download Video Data","type":"main","index":0}]]},"Upload to YouTube":{"main":[[{"node":"Update Status","type":"main","index":0}]]},"Download Video Data":{"main":[[{"node":"Upload to YouTube","type":"main","index":0}]]}}}


name: Daily Business Idea Insights Aggregator from IdeaBrowser to Google Docs
author_name: mahavishnu
author_username: mahavishnu
nodes_used: ["n8n-nodes-base.httpRequest","n8n-nodes-base.googleDocs","n8n-nodes-base.code"]
categories: []
created_at: 2025-06-12T08:54:41.448Z
updated_at: 2025-06-12T08:54:41.448Z
url: https://n8n.io/workflows/4901
scraped_at: 2025-07-06 21:16:30
description:
  This automation runs daily at 8:00 AM to automatically collect and organize business idea insights from IdeaBrowser.com into a structured Google Docs document.
  The workflow performs the following actions:
  Data Collection: Fetches the "idea of the day" content from ideabrowser.com/idea-of-the-day using authenticated HTTP requests.
  Content Processing: Extracts the base idea path and generates links to all related insight pages including value ladder, market analysis, proof signals, execution plans, and community insights. The workflow also cleans the HTML content to extract readable text.
  Document Creation: Creates a new Google Docs document in a specified folder with a timestamp and idea name in the title format.
  Content Aggregation: Systematically visits each insight page (main idea page, value ladder, why now, proof signals, market gap, execution plan, value equation, value matrix, ACP, community signals, and keywords) and collects their content.
  Document Population: Processes the collected content through markdown formatting and appends it to the Google Docs document, creating a comprehensive report of the daily business idea with all its associated insights.
  Automated Scheduling: Runs automatically every day at 8 AM, ensuring you have fresh business idea analysis delivered to your Google Drive without manual intervention.
  This automation is perfect for entrepreneurs, business analysts, or anyone who wants to stay updated with curated business ideas and their detailed market analysis in an organized, searchable format.

workflow_json:
  {"id":"eGHpM6RNrSQcTJRt","meta":{"instanceId":"40392649eb66ba0250ac182a67ce909ef092ff6b0050f4035d702b8166f4f79a","templateCredsSetupCompleted":true},"name":"ideabrowser-scraper","tags":[],"nodes":[{"id":"a19357ec-0bff-4f07-b403-fa18f82abf86","name":"Markdown1","type":"n8n-nodes-base.markdown","position":[2040,800],"parameters":{"html":"={{ $json.data }}","options":{}},"typeVersion":1},{"id":"7fbca587-d982-4800-b559-6e01008af711","name":"Get the links","type":"n8n-nodes-base.code","position":[580,800],"parameters":{"jsCode":"for (const item of $input.all()) {\n    const rawData = item.json.data;\n\n    // Step 1: Extract base path for idea\n    const basePathRegex = /\\/idea\\/[^\"\\/]+/;\n    const basePathMatch = rawData.match(basePathRegex);\n\n    if (!basePathMatch) {\n        item.json.error = \"No valid idea path found in rawData\";\n        continue;\n    }\n\n    const basePath = basePathMatch[0]; // e.g., /idea/ai-powered-historical-ad-style-generator\n\n    // Step 2: Generate insight links\n    const insightPages = [\n        \"\",\n        \"/value-ladder\",\n        \"/why-now\",\n        \"/proof-signals\",\n        \"/market-gap\",\n        \"/execution-plan\",\n        \"/value-equation\",\n        \"/value-matrix\",\n        \"/acp\",\n        \"/community-signals\",\n        \"/keywords\"\n    ];\n\n    const insightLinks = insightPages.map(page => {\n        return `https://www.ideabrowser.com${basePath}${page}`; \n    });\n\n    // Step 3: Extract only readable text by removing HTML tags\n    const cleanText = rawData.replace(/<[^>]+>/g, '').trim();\n\n    // Step 4: Update item with results\n    item.json.insightLinks = insightLinks;\n    item.json.ideaPath = basePath;\n    item.json.cleanText = cleanText; // 👈 This is the new key with only readable text\n}\n\nreturn $input.all();"},"typeVersion":2},{"id":"10bfccb0-c5d3-4002-ad31-9e6d00d710a3","name":"Get URL data of idea","type":"n8n-nodes-base.httpRequest","position":[380,800],"parameters":{"url":"https://ideabrowser.com/idea-of-the-day ","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"1CfzTn6kYUUoa3Im","name":"cookie-for-idea-browser"}},"typeVersion":4.2},{"id":"2ac9f703-006b-494d-b53f-372c8dbd8233","name":"Create google doc","type":"n8n-nodes-base.googleDocs","position":[780,580],"parameters":{"title":"={{ $today.toLocaleString().concat(\"-\",$json.ideaPath.split(\"/\")[2] )}}","folderId":"10Lxy7-UbLzEGcTnDk12n8pOiWyyu1EE4"},"credentials":{"googleDocsOAuth2Api":{"id":"mtchxt5piVMUOdin","name":"mvasi"}},"typeVersion":2},{"id":"bf9d318c-310e-4c49-bbb0-3cfbc1e16f7d","name":"Merge the data","type":"n8n-nodes-base.merge","position":[1000,800],"parameters":{"mode":"combine","options":{},"combineBy":"combineAll"},"typeVersion":3.2},{"id":"286f31e3-d9e5-4a3a-8590-7c11e82c6e78","name":"Split the url","type":"n8n-nodes-base.splitOut","position":[1260,800],"parameters":{"options":{},"fieldToSplitOut":"insightLinks"},"typeVersion":1},{"id":"7ac224d8-4eb9-429a-bae3-607e49f2d498","name":"Loop over URL","type":"n8n-nodes-base.splitInBatches","position":[1580,780],"parameters":{"options":{}},"typeVersion":3},{"id":"82e59148-8aa9-4eb7-a65b-37c375d63ef0","name":"Get URL content of each page","type":"n8n-nodes-base.httpRequest","position":[1820,800],"parameters":{"url":"={{ $json.insightLinks }}","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"1CfzTn6kYUUoa3Im","name":"cookie-for-idea-browser"}},"typeVersion":4.2},{"id":"c5902af1-187e-4471-8833-8c3b68732d36","name":"Update the google docs with the data","type":"n8n-nodes-base.googleDocs","position":[2240,800],"parameters":{"actionsUi":{"actionFields":[{"text":"={{ $json.data }}","action":"insert"}]},"operation":"update","documentURL":"={{ $('Create google doc').item.json.id }}"},"credentials":{"googleDocsOAuth2Api":{"id":"mtchxt5piVMUOdin","name":"mvasi"}},"typeVersion":2},{"id":"0cd82b9e-1b64-4853-aaab-3036fe33aa5d","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[200,800],"parameters":{"rule":{"interval":[{"triggerAtHour":8}]}},"typeVersion":1.2}],"active":false,"settings":{"timezone":"Asia/Kolkata","callerPolicy":"workflowsFromSameOwner","executionOrder":"v1","executionTimeout":-1},"versionId":"a1e9d613-2210-4565-a36c-c483d51130fb","connections":{"Markdown1":{"main":[[{"node":"Update the google docs with the data","type":"main","index":0}]]},"Get the links":{"main":[[{"node":"Create google doc","type":"main","index":0},{"node":"Merge the data","type":"main","index":1}]]},"Loop over URL":{"main":[[],[{"node":"Get URL content of each page","type":"main","index":0}]]},"Split the url":{"main":[[{"node":"Loop over URL","type":"main","index":0}]]},"Merge the data":{"main":[[{"node":"Split the url","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Get URL data of idea","type":"main","index":0}]]},"Create google doc":{"main":[[{"node":"Merge the data","type":"main","index":0}]]},"Get URL data of idea":{"main":[[{"node":"Get the links","type":"main","index":0}]]},"Get URL content of each page":{"main":[[{"node":"Markdown1","type":"main","index":0}]]},"Update the google docs with the data":{"main":[[{"node":"Loop over URL","type":"main","index":0}]]}}}


name: Telegram AI Assistant with Gmail, Google Calendar, Google Sheets & MCP Tools
author_name: David Olusola
author_username: dae221
categories: []
created_at: 2025-06-12T14:17:02.535Z
updated_at: 2025-06-12T14:17:02.535Z
url: https://n8n.io/workflows/4902
scraped_at: 2025-07-06 21:16:30
description:
  ✨ What It Is
  Automate your professional communication directly from Telegram using this powerful AI assistant built with n8n.

  This no-code agent understands natural language and integrates seamlessly with:

  Gmail (send, receive, draft emails)
  Google Calendar (create, delete, get events)
  Google Sheets (contact database)
  MCP Tools (agent framework for dynamic tool routing)
  Perfect for:

  Virtual Assistants
  Freelancers & Teams
  Sales & Outreach Professionals
  Calendar Managers
  Customer Support Teams
  🔧 What It Can Do
  Just send a message like:

  “Send email to Jane at Acme about pricing”
  “Create a Zoom meeting with Victor next Friday at 3pm”
  “Cancel meeting with Alex”
  “Follow up with Sarah tomorrow”
  ✅ Features:

  🔄 Understands natural language Telegram messages
  📧 Sends or drafts emails using Gmail
  📅 Creates/deletes/syncs calendar events with Google Calendar
  📊 Fetches contact info from Google Sheets
  🤖 Powered by a lightweight LLM (Gemini 2.0)
  💼 Smart memory & session context via MCP tools
  📥 Telegram replies with formatted confirmation (e.g., ✅, 📧, 📅)
  🛠️ Setup Guide (Step-by-Step)

  Prerequisites
  An n8n.cloud or self-hosted n8n instance
  Telegram Bot (create one via @BotFather)
  Gmail, Google Calendar, and Google Sheets accounts
  Access to MCP tools (optional: Daex AI Cloud or equivalent)
  Authorize Accounts
  Connect Gmail, Google Calendar, and Google Sheets credentials in n8n under "Credentials".
  Authorize your Telegram bot via n8n's Telegram Trigger node.
  Configure Your Google Sheet
  Create a Google Sheet titled Contact Data with these columns:

  Name
  Email
  Company
  Role
  Make sure the Google Sheets node points to the correct documentId and gid.

  Connect MCP Tools (Optional)
  If you're using Daex MCP, input the SSE path and trigger ID in the MCP Client Tool and MCP Server Trigger.

  Enable Telegram Bot
  Deploy your workflow in n8n
  Send any command to your Telegram bot like:
  “Send email to Lisa about invoice update”
  The AI agent will understand the command, fetch the contact, and either send/draft an email or update the calendar accordingly.

  Customize Prompts or Actions (Optional)
  Edit the system prompt in the AI Agent node to:

  Add company branding
  Adjust supported commands
  Modify language or tone
  💬 Example Prompts

  “Send email to Sam about project delay”
  “Schedule call with Mabel next Monday at 10am”
  “Delete event with Kevin”
  “Follow up with Clara at noon tomorrow”
  📦 What’s Included

  🧠 Preconfigured n8n Workflow
  🔗 Connected nodes: Telegram, Gmail, Google Calendar, Google Sheets, MCP Tools
  🗂️ AI Memory Context (via MCP memory buffer)
  ✍️ Ready-to-use prompt template
  🎯 Tested commands and use cases
  🛍️ License

  ✅ Commercial use included
  🚫 Do not resell the template without modifications

nodes_used:
  ["n8n-nodes-base.telegram","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.memoryBufferWindow","@n8n/n8n-nodes-langchain.lmChatGoogleGemini","@n8n/n8n-nodes-langchain.mcpClientTool"]

workflow_json:
  {"id":"huYO1F7i4gBmKLV6","meta":{"instanceId":"2000c64071c20843606b95c63795bb0797c41036047055a6586498e855b96efc","templateCredsSetupCompleted":true},"name":"Telegram AI  Assistant with Gmail, Google Calendar, Google Sheets","tags":[],"nodes":[{"id":"ae2d7249-fd1c-434e-8a84-8d3cdb88b2b9","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[220,0],"parameters":{},"typeVersion":1.8},{"id":"1ee01ee2-9940-48a6-a3af-4550bbd95021","name":"MCP Client","type":"@n8n/n8n-nodes-langchain.mcpClientTool","position":[440,240],"parameters":{},"typeVersion":1},{"id":"827ee703-f4d0-4c42-bc3a-47dc292866bf","name":"MCP Server Trigger","type":"@n8n/n8n-nodes-langchain.mcpTrigger","position":[660,140],"webhookId":"17e4eb47-0a40-46bd-a013-9bd844c79491","parameters":{},"typeVersion":1},{"id":"3deadc24-76d0-4ddf-954e-4dd811f0ef3c","name":"Gmail","type":"n8n-nodes-base.gmailTool","position":[520,460],"webhookId":"8fdcbcce-8b08-484f-8198-d9f197e6beec","parameters":{},"typeVersion":2.1},{"id":"0f1178e2-f7bb-4127-a3c3-5c1f00c0c95e","name":"Gmail1","type":"n8n-nodes-base.gmailTool","position":[620,460],"webhookId":"ad715b5e-52c7-405a-a756-621a39ad1015","parameters":{},"typeVersion":2.1},{"id":"ca9d6ff3-e082-4583-ba2a-9c78ff6dee0a","name":"Gmail2","type":"n8n-nodes-base.gmailTool","position":[720,460],"webhookId":"ca587842-8a75-4f9a-a00a-40e4233e1da4","parameters":{},"typeVersion":2.1},{"id":"f416af64-036e-4d5b-addf-159f763bd1e3","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[500,400],"parameters":{"content":""},"typeVersion":1},{"id":"cf9ed6e3-a644-46fb-9fc2-a684595c48d5","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[880,400],"parameters":{"content":""},"typeVersion":1},{"id":"aafc628e-577a-4478-bc2d-56676788f937","name":"Google Calendar","type":"n8n-nodes-base.googleCalendarTool","position":[900,460],"parameters":{},"typeVersion":1.3},{"id":"1cdf4f20-3348-4635-992d-0ad64f7697e9","name":"Google Calendar1","type":"n8n-nodes-base.googleCalendarTool","position":[1020,460],"parameters":{},"typeVersion":1.3},{"id":"e3b9f739-d768-4a8b-8028-5d5f01be8c4b","name":"Google Calendar2","type":"n8n-nodes-base.googleCalendarTool","position":[1120,440],"parameters":{},"typeVersion":1.3},{"id":"67a5a7eb-f690-4c59-bccd-023bc3262899","name":"Google Gemini Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[100,220],"parameters":{},"typeVersion":1},{"id":"a02893db-bb2b-412a-b66a-700cfa846d1c","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[320,220],"parameters":{},"typeVersion":1.3},{"id":"61c3bce9-fcd2-4711-a31e-d2e1d5fbc4c6","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[1040,120],"parameters":{"content":""},"typeVersion":1},{"id":"a4395531-c404-4ea4-a0df-dc919a54cf17","name":"contact data","type":"n8n-nodes-base.googleSheetsTool","position":[1100,180],"parameters":{},"typeVersion":4.6},{"id":"a2059e87-e39f-4dab-a19a-4030ed04e269","name":"Telegram Trigger","type":"n8n-nodes-base.telegramTrigger","position":[-20,0],"webhookId":"e9d9dcb0-c0b8-47a5-b034-f6c63e73507f","parameters":{},"typeVersion":1.2},{"id":"eba9deef-2dd0-4662-9b50-3c35c42fa549","name":"Telegram","type":"n8n-nodes-base.telegram","position":[580,0],"webhookId":"06cc6fce-2eb7-4eb2-bab4-a7ed13e81854","parameters":{},"typeVersion":1.2}],"active":true,"settings":{"executionOrder":"v1"},"versionId":"ae83d16a-d907-482e-8793-e519f1228e14","connections":{"Gmail":{"ai_tool":[[{"node":"MCP Server Trigger","type":"ai_tool","index":0}]]},"Gmail1":{"ai_tool":[[{"node":"MCP Server Trigger","type":"ai_tool","index":0}]]},"Gmail2":{"ai_tool":[[{"node":"MCP Server Trigger","type":"ai_tool","index":0}]]},"AI Agent":{"main":[[{"node":"Telegram","type":"main","index":0}]]},"MCP Client":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"contact data":{"ai_tool":[[{"node":"MCP Server Trigger","type":"ai_tool","index":0}]]},"Simple Memory":{"ai_memory":[[{"node":"AI Agent","type":"ai_memory","index":0}]]},"Google Calendar":{"ai_tool":[[{"node":"MCP Server Trigger","type":"ai_tool","index":0}]]},"Google Calendar1":{"ai_tool":[[{"node":"MCP Server Trigger","type":"ai_tool","index":0}]]},"Google Calendar2":{"ai_tool":[[{"node":"MCP Server Trigger","type":"ai_tool","index":0}]]},"Telegram Trigger":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Google Gemini Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]}}}


name: Pyragogy AI-Driven Handbook Generator with Multi-Agent Orchestration
author_name: Fabrizio Terzi
author_username: org
categories: []
created_at: 2025-06-12T15:46:54.341Z
updated_at: 2025-06-12T15:46:54.341Z
url: https://n8n.io/workflows/4904
scraped_at: 2025-07-06 21:16:30
description:
  AI-Driven Handbook Generator with Multi-Agent Orchestration (Pyragogy AI Village)

  This n8n workflow is a modular, multi-agent AI orchestration system designed for the collaborative generation of Markdown-based handbooks. Inspired by peer learning and open publishing workflows, it simulates a content pipeline where specialized AI agents act in defined roles, enabling true AI–human co-creation and iterative refinement.

  This project is a core component of Pyragogy, an open framework dedicated to ethical cognitive co-creation, peer AI–human learning, and human-in-the-loop automation for open knowledge systems. It implements the master orchestration architecture for the Pyragogy AI Village, managing a complex sequence of AI agents to process input, perform review, synthesis, and archiving, with a crucial human oversight step for final approval.

  How It Works: A Deep Dive into the Workflow's Architecture

  The workflow orchestrates a sophisticated content generation and review process, ideal for creating AI-driven knowledge bases or handbooks with human oversight.

  Webhook Trigger & Input:* The process begins when the workflow receives a JSON input via a *Webhook** (specifically at /webhook/pyragogy/process). This input typically includes details like the handbook's title, initial text, and relevant tags.

  Database Verification:* It first verifies the connection to a *PostgreSQL database** to ensure data persistence.

  Meta-Orchestrator:* A powerful *Meta-Orchestrator** (powered by gpt-4o from OpenAI) analyzes the initial request. Its role is to dynamically determine and activate the optimal sequence of specialized AI agents required to fulfill the input, ensuring tasks are dynamically routed and assigned based on each agent’s responsibility.

  Agent Execution & Iteration:** Each activated agent executes its step using OpenAI or custom endpoints. This involves:

      Content Generation: Agents like the Summarizer and the Synthesizer generate new content or refine existing text.

      Peer Review Board: A crucial aspect is the Peer Review Board, comprised of AI agents like the Peer Reviewer, the Sensemaking Agent, and the Prompt Engineer. This board evaluates the output for quality, coherence, and accuracy.

      Reprocessing & Redrafting: If the review agents flag a major_issue, they trigger redrafting loops by generating specific feedback for the Synthesizer. This mechanism ensures iterative refinement until the content meets the required standards.

  Human-in-the-Loop (HITL) Review:* For final approval, particularly for the Archivist agent's output, a *human review process* is initiated. An email is sent to a human reviewer, prompting them to approve, reject, or comment via a "Wait for Webhook" node. This ensures *human oversight** and quality control.

  Content Persistence & Versioning:** If the content is approved by the human reviewer:

      It's saved to a PostgreSQL database (specifically to the handbook_entries and agent_contributions tables).

      Optionally, the content can be committed to a GitHub repository for version control, provided the necessary environment variables are configured.

  Notifications:* The final output and the sequence of executed agents can be sent as a notification to *Slack**, if configured.

  Observe the dynamic loop: orchestrate → assign → generate → review (AI/human) → store

  Included AI Agents

  This workflow leverages a suite of specialized AI agents, each with a distinct role in the content pipeline:

  Meta-Orchestrator:** Determines the optimal sequence of agents to execute based on the input.

  Summarizer Agent:** Summarizes text into key points (e.g., 3 key points).

  Synthesizer Agent:** Synthesizes new text and effectively incorporates reprocessing feedback from review agents.

  Peer Reviewer Agent:** Reviews generated text, highlighting strengths, weaknesses, and suggestions, and indicates major_issue flags.

  Sensemaking Agent:** Analyzes input within existing context, identifying patterns, gaps, and areas for improvement.

  Prompt Engineer Agent:** Refines or generates prompts for subsequent agents, optimizing their output.

  Onboarding/Explainer Agent:** Provides explanations of the process or offers guidance to users.

  Archivist Agent:** Prepares content for the handbook, manages the human review process, and handles archiving to the database and GitHub.

  Setup Steps & Prerequisites

  To get this powerful workflow up and running, follow these steps:

  Import the Workflow: Import the pyragogy_master_workflow.json (or generate-collaborative-handbooks-with-gpt4o-multi-agent-orchestration-human-review.json) into your n8n instance.

  Connect Credentials:

      Postgres: Set up a Postgres Pyragogy DB credential (ID: pyragogy-postgres).

      OpenAI: Configure an OpenAI Pyragogy credential (ID: pyragogy-openai) for all OpenAI agents. GPT-4o is highly suggested for optimal performance.

      Email Send: Set up a configured email credential (e.g., for sending human review requests).

  Define Environment Variables: Define essential environment variables (an .env.template is included in the repository). These include:

      API base for OpenAI.

      Database connection details.

      (Optional) GitHub: For content persistence and versioning, configure GITHUB_ACCESS_TOKEN, GITHUB_REPOSITORY_OWNER, and GITHUB_REPOSITORY_NAME.

      (Optional) Slack: For notifications, configure SLACK_WEBHOOK_URL.

  Send a sample payload to your webhook URL (/webhook/pyragogy/process):

  {
  "title": "History of Peer Learning",
  "text": "Peer learning is an educational approach where students learn from and with each other...",
  "tags": ["education", "pedagogy"],
  "requireHitl": true
  }

  Ideal For

  This workflow is perfectly suited for:

  Educators and researchers exploring AI-assisted publishing and co-authoring with AI.

  Knowledge teams looking to automate content pipelines for internal or external documentation.

  Anyone building collaborative Markdown-driven tools or AI-powered knowledge bases.

  Documentation & Contributions: An Open Source and Collaborative Project

  This workflow is an open-source project and community-driven. Its development is transparent and open to everyone.

  We warmly invite you to:

  Review it:** Contribute your analysis, identify potential improvements, or report issues.

  Remix it:** Adapt it to your specific needs, integrate new features, or modify it for a different use case.

  Improve it:** Propose and implement changes that enhance its efficiency, robustness, or capabilities.

  Share it back:** Return your contributions to the community, either through pull requests or by sharing your implementations.

  Every contribution is welcome and valued! All relevant information for verification, improvement, and collaboration can be found in the official repository:

  🔗 GitHub – pyragogy-handbook-n8n-workflow

nodes_used:
  ["n8n-nodes-base.emailSend","n8n-nodes-base.github","n8n-nodes-base.postgres","n8n-nodes-base.slack","n8n-nodes-base.openAi"]

workflow_json:
  {"id":"eTfM9cjV0i7PQtsZ","meta":{"instanceId":"59d894873e0437e59dde7eeb7a4a896fa57f47f2baf669a3f0fabefee671c695"},"name":"AI-Driven Handbook Generator with Multi-Agent Orchestration (Pyragogy AI Village)","tags":[{"id":"cPTJEblSALLWTPH5","name":"Pyragogy","createdAt":"2025-06-12T12:35:25.060Z","updatedAt":"2025-06-12T12:35:25.060Z"},{"id":"6QE2GMT2wg7PfNjo","name":"Multi-Agent","createdAt":"2025-06-12T12:35:25.071Z","updatedAt":"2025-06-12T12:35:25.071Z"},{"id":"NRBaVI2WatxRn6jb","name":"Orchestration","createdAt":"2025-06-12T12:35:25.064Z","updatedAt":"2025-06-12T12:35:25.064Z"},{"id":"Fz7qIHTqqiYux3E1","name":"Human-in-Loop","createdAt":"2025-06-12T12:35:25.065Z","updatedAt":"2025-06-12T12:35:25.065Z"}],"nodes":[{"id":"907e30c8-87e4-46f8-8863-9e3abf429415","name":"Start","type":"n8n-nodes-base.start","position":[-1600,300],"parameters":{},"typeVersion":1},{"id":"ae6910fd-9244-4bab-a0f7-c91a4ad84f28","name":"Webhook Trigger","type":"n8n-nodes-base.webhook","position":[-1400,300],"webhookId":"pyragogy-master-trigger","parameters":{"path":"pyragogy/process","options":{},"httpMethod":"POST"},"typeVersion":1},{"id":"a782c52f-b296-4477-8cf4-454a7df0c8a5","name":"Check DB Connection","type":"n8n-nodes-base.postgres","position":[-1200,300],"parameters":{"query":"SELECT 1; -- Verifica connessione DB","operation":"executeQuery","additionalFields":{}},"typeVersion":1},{"id":"3df503dd-db5e-4bd1-8925-e715b8bbe03c","name":"Meta-Orchestrator","type":"n8n-nodes-base.openAi","position":[-1000,300],"parameters":{"model":"gpt-4o","options":{},"resource":"chat","requestOptions":{}},"typeVersion":1},{"id":"a4c7eb13-bd36-4c9d-8927-2e6fe54c32a3","name":"Parse Orchestration Plan","type":"n8n-nodes-base.function","position":[-800,300],"parameters":{"functionCode":"// Analizza il piano di orchestrazione e imposta per il looping\nlet rawPlan = $json.choices[0].message.content;\nlet plan;\n\ntry {\n  plan = JSON.parse(rawPlan);\n} catch (e) {\n  // Se il parsing fallisce, assumi che sia una stringa di array grezza\n  plan = rawPlan;\n}\n\n// Estrai in modo sicuro la sequenza degli agenti:\n// Se 'plan' è un oggetto e ha una chiave 'agents', usala.\n// Altrimenti, se 'plan' è un array, usalo direttamente.\n// Altrimenti, predefinisci un array vuoto.\nconst agentSequence = Array.isArray(plan) ? plan : (plan && plan.agents && Array.isArray(plan.agents) ? plan.agents : []);\n\n// Memorizza la sequenza e l'indice corrente per il loop\n$workflow.agentSequence = agentSequence;\n$workflow.currentAgentIndex = 0;\n$workflow.redraftLoopCount = 0; // Inizializza il contatore dei cicli di rielaborazione\n\n// Passa i dati di input al primo agente, assicurandosi che $items[0].json.body esista\nconst initialInput = $items[0] && $items[0].json && $items[0].json.body ? $items[0].json.body : {};\n\nreturn [{ json: { ...initialInput, agentToRun: agentSequence[0] || null } }];"},"typeVersion":1},{"id":"915e18ea-1540-4059-883f-739f77f41cc2","name":"More Agents to Run?","type":"n8n-nodes-base.if","position":[-600,300],"parameters":{"conditions":{"boolean":[{"value1":"={{ $workflow.currentAgentIndex < $workflow.agentSequence.length }}","value2":true}]}},"typeVersion":1},{"id":"6f478d71-791e-4f6b-b5e3-5b7b842181b0","name":"Prepare Agent Input","type":"n8n-nodes-base.function","position":[-400,200],"parameters":{"functionCode":"// Ottieni il nome dell'agente corrente\nconst agentName = $workflow.agentSequence[$workflow.currentAgentIndex];\n\n// Prepara i dati per l'esecuzione dell'agente\n// Passa l'output del passo precedente (o l'input iniziale).\n// Se stiamo rielaborando, l'input dell'agente dovrebbe includere il feedback di rielaborazione.\nconst previousOutput = $json.output || $json.body.input; // Assumendo che l'output dell'agente sia memorizzato nella chiave 'output'\nconst agentInput = $json.redraftInput || previousOutput; // Usa redraftInput se presente, altrimenti previousOutput\n\nreturn [{ json: { ...$json, agentToRun: agentName, agentInput: agentInput } }];"},"typeVersion":1},{"id":"d575e9c9-2d58-4061-944b-61b32d15eefb","name":"Route Agents with Switch","type":"n8n-nodes-base.switch","position":[-200,200],"parameters":{"mode":"json"},"typeVersion":1},{"id":"3711824c-5a58-4e3d-95dd-3ca16cc551ca","name":"Summarizer Agent","type":"n8n-nodes-base.openAi","position":[0,0],"parameters":{"model":"gpt-4o","options":{},"resource":"chat","requestOptions":{}},"typeVersion":1},{"id":"67b23742-e3bd-4437-99eb-957e6bc0912e","name":"Synthesizer Agent","type":"n8n-nodes-base.openAi","position":[0,100],"parameters":{"model":"gpt-4o","options":{},"resource":"chat","requestOptions":{}},"typeVersion":1},{"id":"8bfe179e-ed05-43df-b9c6-862f86c1189c","name":"Peer Reviewer Agent","type":"n8n-nodes-base.openAi","position":[0,200],"parameters":{"model":"gpt-4o","options":{},"resource":"chat","requestOptions":{}},"typeVersion":1},{"id":"2dc73ca6-f17f-4214-acbb-3ea3ed470f13","name":"Sensemaking Agent","type":"n8n-nodes-base.openAi","position":[0,300],"parameters":{"model":"gpt-4o","options":{},"resource":"chat","requestOptions":{}},"typeVersion":1},{"id":"ec3b9cc0-a039-4cac-90ca-7de54f41f5d4","name":"Prompt Engineer Agent","type":"n8n-nodes-base.openAi","position":[0,400],"parameters":{"model":"gpt-4o","options":{},"resource":"chat","requestOptions":{}},"typeVersion":1},{"id":"bc382e04-9c5d-4ab9-b874-2da213499614","name":"Onboarding/Explainer Agent","type":"n8n-nodes-base.openAi","position":[0,500],"parameters":{"model":"gpt-4o","options":{},"resource":"chat","requestOptions":{}},"typeVersion":1},{"id":"03017738-b11e-4016-8c05-65204ef7e8c3","name":"Add Handbook Metadata","type":"n8n-nodes-base.function","position":[0,600],"parameters":{"functionCode":"// Prepara i metadati per il contenuto dell'Handbook.\n// Assicurati che l'input originale contenga 'title' e 'tags' o imposta dei valori predefiniti.\nconst title = $json.body.title || 'Untitled Handbook Entry';\nconst tags = $json.body.tags || [];\nconst phase = $json.body.phase || 'draft'; // Fase iniziale, può essere 'final' dopo l'approvazione\nconst rhythm = $json.body.rhythm || 'on-demand'; // Ritmo cognitivo\n\nreturn [{ json: { ...$json, handbookTitle: title, handbookTags: tags, handbookPhase: phase, handbookRhythm: rhythm } }];"},"typeVersion":1},{"id":"d183d513-00a3-4a38-9ef8-37a646d2ad15","name":"Generate Content for Review","type":"n8n-nodes-base.function","position":[200,600],"parameters":{"functionCode":"// Prepara il contenuto proposto dall'Archivista per la revisione umana, inclusa la formattazione YAML.\n// Assicurati che l'input dell'agente (il contenuto generato) sia disponibile.\nconst proposedContent = $json.agentInput;\nconst title = $json.handbookTitle;\nconst tags = $json.handbookTags;\nconst phase = $json.handbookPhase;\nconst rhythm = $json.handbookRhythm;\n\n// Costruisci il front-matter YAML\nconst yamlFrontMatter = `---\ntitle: \"${title.replace(/\"/g, '\\\"')}\"\ntags: [${tags.map(t => `\"${t.replace(/\"/g, '\\\"')}\"`).join(', ')}]\nphase: \"${phase}\"\nrhythm: \"${rhythm}\"\n---\n\n`;\n\nconst finalMarkdownContent = yamlFrontMatter + proposedContent;\n\nreturn [{ json: { ...$json, proposedContent: proposedContent, reviewTitle: title, reviewTags: tags, finalMarkdownContent: finalMarkdownContent } }];"},"typeVersion":1},{"id":"41919337-0762-47d0-9c7c-d51fa966caae","name":"Generate Review ID","type":"n8n-nodes-base.function","position":[400,600],"parameters":{"functionCode":"// Genera un ID univoco per questa richiesta di revisione.\n// Questo ID verrà usato per correlare la risposta del revisore con questa istanza del workflow.\nconst reviewId = crypto.randomUUID();\n\nreturn [{ json: { ...$json, reviewId: reviewId } }];"},"typeVersion":1},{"id":"6fb5b6d5-4ea8-49c9-9ebc-3c37eb2897b8","name":"Send Review Request Email","type":"n8n-nodes-base.emailSend","position":[600,600],"parameters":{"html":"<h3>Revisione Contenuto Pyragogy Handbook: {{ $json.reviewTitle }}</h3>\n<p>Ciao revisore,</p>\n<p>È stato proposto un nuovo contenuto per l'Handbook:</p>\n<hr>\n<pre>{{ $json.proposedContent }}</pre>\n<hr>\n<p><strong>Titolo:</strong> {{ $json.reviewTitle }}</p>\n<p><strong>Tags:</strong> {{ $json.reviewTags.join(', ') }}</p>\n<p>Per favore, clicca su uno dei seguenti link per approvare o rifiutare:</p>\n<p><a href=\"your_n8n_url/webhook/pyragogy/review-feedback?reviewId={{ $json.reviewId }}&status=approved\">Approva</a></p>\n<p><a href=\"your_n8n_url/webhook/pyragogy/review-feedback?reviewId={{ $json.reviewId }}&status=rejected\">Rifiuta</a></p>\n<p>Grazie!</p>","text":"Ciao revisore,\n\nÈ stato proposto un nuovo contenuto per l'Handbook:\n\n---\n{{ $json.proposedContent }}\n---\n\nTitolo: {{ $json.reviewTitle }}\nTags: {{ $json.reviewTags.join(', ') }}\n\nPer favore, clicca su uno dei seguenti link per approvare o rifiutare:\n\nApprova: your_n8n_url/webhook/pyragogy/review-feedback?reviewId={{ $json.reviewId }}&status=approved\nRifiuta: your_n8n_url/webhook/pyragogy/review-feedback?reviewId={{ $json.reviewId }}&status=rejected\n\nGrazie!","options":{},"subject":"Revisione Contenuto Pyragogy Handbook: {{ $json.reviewTitle }}","toEmail":"human-reviewer@example.com","fromEmail":"your-email@example.com"},"typeVersion":1},{"id":"e69480df-aab3-4b05-8c2b-5ec369966084","name":"Wait for Human Approval","type":"n8n-nodes-base.wait","position":[800,600],"webhookId":"7eeea69b-5e91-469e-b874-1a8eb5bb49e2","parameters":{},"typeVersion":1},{"id":"80fca66e-fdc6-49b1-9873-b10c03409926","name":"Human Decision Split","type":"n8n-nodes-base.if","position":[1000,600],"parameters":{"conditions":{"boolean":[{"value1":"={{ $json.query.status === 'approved' }}","value2":true}]}},"typeVersion":1},{"id":"ed575c60-32e2-411e-9619-ac40ac647e3b","name":"Save to handbook_entries","type":"n8n-nodes-base.postgres","position":[1200,500],"parameters":{"table":"handbook_entries","columns":"title, content, version, created_by, tags, phase, rhythm","additionalFields":{}},"typeVersion":1},{"id":"a43a61ae-0062-4705-8ef2-a65d8bd65fb7","name":"Prepare Approved Contribution Data","type":"n8n-nodes-base.function","position":[1400,500],"parameters":{"functionCode":"// Registra il contributo dell'agente dopo l'approvazione umana\nconst entryId = $json.id; // ID dall'inserimento in handbook_entries\nconst agentName = 'Archivist';\nconst contributionType = 'Archiving (Approved)';\nconst details = { input: $json.proposedContent, metadata: { title: $json.reviewTitle, version: $json.version, tags: $json.reviewTags, phase: $json.handbookPhase, rhythm: $json.handbookRhythm }, reviewStatus: 'approved' };\n\n$items[0].json.contribution = { entryId, agentName, contributionType, details };\nreturn $items;"},"typeVersion":1},{"id":"4a03b029-e65f-4844-a605-f668c39f05f7","name":"Save Agent Contribution (Approved)","type":"n8n-nodes-base.postgres","position":[1600,500],"parameters":{"table":"agent_contributions","columns":"entry_id, agent_name, contribution_type, details","additionalFields":{}},"typeVersion":1},{"id":"9a3b2bdc-b894-4b5d-a783-003c1d0cbac5","name":"Generate GitHub File Path","type":"n8n-nodes-base.function","position":[1800,500],"parameters":{"functionCode":"// Genera il percorso del file GitHub con slug e timestamp per il versioning.\nconst chapterSlug = ($json.reviewTitle || 'untitled').replace(/[^a-zA-Z0-9]/g, '-').toLowerCase();\nconst timestamp = new Date().toISOString().replace(/[:.-]/g, ''); // Rimuove caratteri non validi per i nomi di file\nconst filePathWithVersion = `content/${chapterSlug}_v${timestamp}.md`;\n\nreturn [{ json: { ...$json, githubFilePath: filePathWithVersion } }];"},"typeVersion":1},{"id":"42831df9-f694-43fa-8612-b9aee95bef6c","name":"GitHub Enabled?","type":"n8n-nodes-base.if","position":[2000,500],"parameters":{"conditions":{"boolean":[{"value1":"={{ $env.GITHUB_ACCESS_TOKEN }}","value2":true}]}},"typeVersion":1},{"id":"2049ac7d-bf01-4d9b-a222-ca988892d1e6","name":"Commit to GitHub (Approved)","type":"n8n-nodes-base.github","position":[2200,500],"webhookId":"409bfa11-5bef-4207-a181-1a736120f698","parameters":{"owner":"={{ $env.GITHUB_REPOSITORY_OWNER }}","filePath":"={{ $json.githubFilePath }}","resource":"file","operation":"createUpdate","repository":"={{ $env.GITHUB_REPOSITORY_NAME }}"},"typeVersion":1},{"id":"352599e9-8b68-412c-bd28-f92844e9c712","name":"Log Human Rejection","type":"n8n-nodes-base.function","position":[1200,700],"parameters":{"functionCode":"// Registra il rifiuto umano del contenuto\nconst agentName = 'Archivist';\nconst reviewId = $json.reviewId;\nconst reviewStatus = 'rejected';\nconst reviewComments = $json.query.comments || 'Nessun commento fornito.';\nconst proposedContent = $json.proposedContent;\nconst title = $json.reviewTitle;\n\nconsole.log(`Contenuto proposto dall'Archivista (ID: ${reviewId}, Titolo: ${title}) rifiutato dall'umano. Commenti: ${reviewComments}`);\n\n// Prepara l'output per indicare il rifiuto e consentire al flusso di continuare.\nreturn [{ json: { ...$json, reviewStatus: reviewStatus, reviewComments: reviewComments, output: { message: `Archivista: Contenuto rifiutato dall'umano.`, status: 'rejected', comments: reviewComments } } }];"},"typeVersion":1},{"id":"6f0ea479-d689-40fc-a72f-d1ad161f8743","name":"Merge Archivist Paths","type":"n8n-nodes-base.merge","position":[2400,600],"parameters":{"mode":"mergeByPropertyName"},"typeVersion":1},{"id":"ffd0ab23-cb9d-4ac1-ad3d-6fe856ca1fad","name":"Evaluate Board Consensus","type":"n8n-nodes-base.function","position":[200,300],"parameters":{"functionCode":"// Valuta i flag 'major_issue' dagli agenti di revisione per determinare se è necessaria una rielaborazione.\nlet majorIssueCount = 0;\nlet redraftFeedback = '';\n\n// Assumi che gli output degli agenti di revisione siano accessibili tramite $node\n// (Ad esempio, se Peer Reviewer -> Sensemaking -> Prompt Engineer sono sequenziali prima di questo nodo)\n\nif ($node[\"Peer Reviewer Agent\"] && $node[\"Peer Reviewer Agent\"].json && $node[\"Peer Reviewer Agent\"].json.choices && $node[\"Peer Reviewer Agent\"].json.choices[0] && $node[\"Peer Reviewer Agent\"].json.choices[0].message && $node[\"Peer Reviewer Agent\"].json.choices[0].message.content) {\n    const peerReviewOutput = JSON.parse($node[\"Peer Reviewer Agent\"].json.choices[0].message.content);\n    if (peerReviewOutput.major_issue) majorIssueCount++;\n    redraftFeedback += `Peer Reviewer: ${peerReviewOutput.suggestions || ''}\\n`;\n}\n\nif ($node[\"Sensemaking Agent\"] && $node[\"Sensemaking Agent\"].json && $node[\"Sensemaking Agent\"].json.choices && $node[\"Sensemaking Agent\"].json.choices[0] && $node[\"Sensemaking Agent\"].json.choices[0].message && $node[\"Sensemaking Agent\"].json.choices[0].message.content) {\n    const sensemakingOutput = JSON.parse($node[\"Sensemaking Agent\"].json.choices[0].message.content);\n    if (sensemakingOutput.major_issue) majorIssueCount++;\n    redraftFeedback += `Sensemaking Agent: ${sensemakingOutput.suggestions || ''}\\n`;\n}\n\nif ($node[\"Prompt Engineer Agent\"] && $node[\"Prompt Engineer Agent\"].json && $node[\"Prompt Engineer Agent\"].json.choices && $node[\"Prompt Engineer Agent\"].json.choices[0] && $node[\"Prompt Engineer Agent\"].json.choices[0].message && $node[\"Prompt Engineer Agent\"].json.choices[0].message.content) {\n    const promptEngineerOutput = JSON.parse($node[\"Prompt Engineer Agent\"].json.choices[0].message.content);\n    if (promptEngineerOutput.major_issue) majorIssueCount++;\n    redraftFeedback += `Prompt Engineer: ${promptEngineerOutput.suggestions || ''}\\n`;\n}\n\nconst redraftNeeded = majorIssueCount >= 2; // Voto a maggioranza\n\nreturn [{ json: { ...$json, redraftNeeded: redraftNeeded, redraftFeedback: redraftFeedback } }];"},"typeVersion":1},{"id":"f2ec87e5-0a06-4d8f-896b-a3d203fcea41","name":"Check Redraft Needed","type":"n8n-nodes-base.if","position":[400,300],"parameters":{"conditions":{"boolean":[{"value1":"={{ $json.redraftNeeded && $workflow.redraftLoopCount < 2 }}","value2":true}]}},"typeVersion":1},{"id":"413074bb-38ad-42d6-8d63-402e33528a5b","name":"Handle Redraft","type":"n8n-nodes-base.function","position":[600,200],"parameters":{"functionCode":"// Gestisce la logica di rielaborazione: incrementa il contatore e reindirizza al Synthesizer.\n\n$workflow.redraftLoopCount += 1; // Incrementa il contatore del ciclo di rielaborazione\n\n// Trova l'indice del Synthesizer nella sequenza degli agenti\nconst synthesizerIndex = $workflow.agentSequence.indexOf(\"Synthesizer\");\n\n// Se il Synthesizer non è il prossimo agente, imposta l'indice corrente per farlo ripartire dal Synthesizer.\n// Questo garantisce che il Synthesizer venga eseguito successivamente per la rielaborazione.\nif ($workflow.currentAgentIndex !== synthesizerIndex) {\n    $workflow.currentAgentIndex = synthesizerIndex;\n} else {\n    // Se siamo già sul Synthesizer (es. dopo il primo passaggio del loop), assicurati che l'indice vada avanti normalmente nel prossimo ciclo.\n    // Questo è un caso limite, di solito il Prepare Agent Input lo gestirà.\n}\n\n// Passa il feedback di rielaborazione come input per il Synthesizer.\n// Il nodo 'Prepare Agent Input' utilizzerà questo campo per aggiornare 'agentInput'.\nreturn [{ json: { ...$json, redraftInput: $json.output + \"\\n\\nFeedback per la rielaborazione dal Peer Review Board:\\n\" + $json.redraftFeedback } }];"},"typeVersion":1},{"id":"6508f0f9-09c2-4fe6-8cae-eb90ea58d875","name":"Process Agent Output","type":"n8n-nodes-base.function","position":[400,200],"parameters":{"functionCode":"// Ottieni il nome dell'agente appena eseguito\nconst agentName = $json.agentToRun;\nlet agentOutput = '';\n\n// Costruisci dinamicamente il nome del nodo per il recupero dell'output\nlet actualNodeName;\n\n// Gestione speciale per l'Archivista dopo la revisione umana\nif (agentName === 'Archivist') {\n    if ($json.query && $json.query.status === 'approved') {\n        agentOutput = { message: 'Contenuto archiviato con successo dopo l'approvazione umana.', entryId: $json.id || 'N/A', handbookMetadata: { title: $json.reviewTitle, tags: $json.reviewTags, phase: $json.handbookPhase, rhythm: $json.handbookRhythm } };\n    } else if ($json.query && $json.query.status === 'rejected') {\n        agentOutput = { message: 'Archiviazione rifiutata dall'umano.', reviewComments: $json.query.comments || 'Nessun commento' };\n    } else if ($json.reviewStatus === 'rejected') {\n        // Caso in cui la revisione umana è stata rifiutata e si proviene dal ramo di rifiuto\n        agentOutput = { message: 'Archiviazione rifiutata dall'umano (tramite ramo di rifiuto).', reviewComments: $json.reviewComments || 'Nessun commento' };\n    } else {\n        agentOutput = { message: 'Processo Archivista: Attesa revisione umana o stato inatteso.', status: 'pending_review' };\n    }\n} else {\n    // Logica originale per gli altri agenti OpenAI\n    if (agentName === 'Onboarding/Explainer') {\n        actualNodeName = 'Onboarding/Explainer Agent';\n    } else {\n        actualNodeName = agentName + ' Agent';\n    }\n\n    // Tenta in modo sicuro di recuperare l'output dal nodo determinato dinamicamente\n    // Tenta anche di analizzare il JSON se l'output dell'agente è un oggetto JSON (come per gli agenti di revisione)\n    let rawContent = '';\n    if ($node[actualNodeName] && $node[actualNodeName].json && $node[actualNodeName].json.choices && $node[actualNodeName].json.choices[0] && $node[actualNodeName].json.choices[0].message && $node[actualNodeName].json.choices[0].message.content) {\n        rawContent = $node[actualNodeName].json.choices[0].message.content;\n    } else {\n        console.warn(`Impossibile trovare l'output chat OpenAI standard per il nodo: ${actualNodeName}. Ritorno al JSON grezzo.`);\n        agentOutput = $node[actualNodeName] ? $node[actualNodeName].json : `Nessun output specifico trovato per ${agentName}`;\n    }\n\n    // Tenta di analizzare il contenuto come JSON se l'agente è un agente di revisione\n    if (agentName === 'Peer Reviewer' || agentName === 'Sensemaking Agent' || agentName === 'Prompt Engineer') {\n        try {\n            agentOutput = JSON.parse(rawContent);\n        } catch (e) {\n            console.warn(`Impossibile analizzare l'output di ${agentName} come JSON. Trattato come stringa.`);\n            agentOutput = rawContent;\n        }\n    } else {\n        agentOutput = rawContent;\n    }\n}\n\n// Registra il contributo\nconst contribution = {\n    agent: agentName,\n    output: agentOutput,\n    timestamp: new Date().toISOString()\n};\n\n// Assicurati che l'array dei contributi esista e aggiungi il nuovo contributo\nconst existingContributions = Array.isArray($json.contributions) ? $json.contributions : [];\n\n// Incrementa l'indice dell'agente per il loop (solo se non siamo in rielaborazione e questo non è un agente di revisione che porta a rielaborazione)\n// Questo è gestito dalla logica di 'Handle Redraft' che forza l'indice per il riavvio.\nif (!($json.redraftNeeded && $workflow.redraftLoopCount < 2 && agentName !== 'Synthesizer')) { // Evita doppio incremento se riavvia il Synthesizer\n    $workflow.currentAgentIndex += 1;\n}\n\n// Restituisce l'elemento aggiornato, preservando l'input originale, aggiungendo l'output corrente e tutti i contributi\nreturn [{ json: { ...$items[0].json, output: agentOutput, contributions: [...existingContributions, contribution] } }];"},"typeVersion":1},{"id":"2fd3c340-a2d0-489c-a098-42530fdb4c61","name":"Slack Enabled?","type":"n8n-nodes-base.if","position":[-400,500],"parameters":{"conditions":{"boolean":[{"value1":"={{ $env.SLACK_WEBHOOK_URL }}","value2":true}]}},"typeVersion":1},{"id":"314c7a11-493a-4550-9cd0-f1fc5e5b2994","name":"Notify Slack","type":"n8n-nodes-base.slack","position":[-200,500],"parameters":{"text":"Pyragogy AI Village Workflow Completato!\nInput: {{ $json.body.input }}\nOutput Finale: {{ JSON.stringify($json.output) }}\nAgenti Eseguiti: {{ $workflow.agentSequence.join(', ') }}","attachments":[],"otherOptions":{}},"typeVersion":1},{"id":"564a52df-8f4f-4be6-a219-b8c965eccd3b","name":"Final Response","type":"n8n-nodes-base.respondToWebhook","position":[-400,400],"parameters":{"options":{},"respondWith":"json","responseBody":"={{ { finalOutput: $json.output, contributions: $json.contributions, agentSequence: $workflow.agentSequence } }}"},"typeVersion":1},{"id":"generated-ce444b1c-b361-43c8-a0b6-29a1324993c5","name":"Workflow Overview","type":"n8n-nodes-base.stickyNote","position":[-1600,-140],"parameters":{"width":1100,"height":400,"content":"## Pyragogy AI Village Workflow\n\nThis workflow orchestrates an AI Village process for generating, reviewing, and publishing content to a handbook.\n\n**Key Stages:**\n1.  **Trigger & DB Check:** Initiates the workflow via webhook and verifies database connection.\n2.  **Orchestration:** Meta-Orchestrator plans agent execution.\n3.  **Agent Execution Loop:** Dynamically runs various AI agents (Summarizer, Synthesizer, Peer Reviewer, Sensemaking, Prompt Engineer, Onboarding/Explainer) based on the orchestration plan. Includes a redraft mechanism for iterative improvements.\n4.  **Human Review:** Content generated by agents (specifically Archivist) undergoes human approval.\n5.  **Publishing:** Approved content is saved to a PostgreSQL database and committed to GitHub.\n6.  **Notifications:** Sends final response and Slack notifications.\n\n**Note:** Several nodes have credential issues (Postgres, OpenAI, SMTP, GitHub, Slack) and require configuration to function correctly."}}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"a46219cb-1681-4236-bc4b-9c0c4f58389f","connections":{"Notify Slack":{"main":[[{"node":"Final Response","type":"main","index":0}]]},"Handle Redraft":{"main":[[{"node":"More Agents to Run?","type":"main","index":0}]]},"Slack Enabled?":{"main":[[{"node":"Notify Slack","type":"main","index":0}],[{"node":"Final Response","type":"main","index":0}]]},"GitHub Enabled?":{"main":[[{"node":"Commit to GitHub (Approved)","type":"main","index":0}],[{"node":"Merge Archivist Paths","type":"main","index":0}]]},"Webhook Trigger":{"main":[[{"node":"Check DB Connection","type":"main","index":0}]]},"Summarizer Agent":{"main":[[{"node":"Process Agent Output","type":"main","index":0}]]},"Meta-Orchestrator":{"main":[[{"node":"Parse Orchestration Plan","type":"main","index":0}]]},"Sensemaking Agent":{"main":[[{"node":"Prompt Engineer Agent","type":"main","index":0}]]},"Synthesizer Agent":{"main":[[{"node":"Process Agent Output","type":"main","index":0}]]},"Generate Review ID":{"main":[[{"node":"Send Review Request Email","type":"main","index":0}]]},"Check DB Connection":{"main":[[{"node":"Meta-Orchestrator","type":"main","index":0}]]},"Log Human Rejection":{"main":[[{"node":"Merge Archivist Paths","type":"main","index":0}]]},"More Agents to Run?":{"main":[[{"node":"Prepare Agent Input","type":"main","index":0}],[{"node":"Slack Enabled?","type":"main","index":0}]]},"Peer Reviewer Agent":{"main":[[{"node":"Sensemaking Agent","type":"main","index":0}]]},"Prepare Agent Input":{"main":[[{"node":"Route Agents with Switch","type":"main","index":0}]]},"Check Redraft Needed":{"main":[[{"node":"Handle Redraft","type":"main","index":0}],[{"node":"Process Agent Output","type":"main","index":0}]]},"Human Decision Split":{"main":[[{"node":"Save to handbook_entries","type":"main","index":0}],[{"node":"Log Human Rejection","type":"main","index":0}]]},"Process Agent Output":{"main":[[{"node":"More Agents to Run?","type":"main","index":0}]]},"Add Handbook Metadata":{"main":[[{"node":"Generate Content for Review","type":"main","index":0}]]},"Merge Archivist Paths":{"main":[[{"node":"Process Agent Output","type":"main","index":0}]]},"Prompt Engineer Agent":{"main":[[{"node":"Evaluate Board Consensus","type":"main","index":0}]]},"Wait for Human Approval":{"main":[[{"node":"Human Decision Split","type":"main","index":0}]]},"Evaluate Board Consensus":{"main":[[{"node":"Check Redraft Needed","type":"main","index":0}]]},"Parse Orchestration Plan":{"main":[[{"node":"More Agents to Run?","type":"main","index":0}]]},"Route Agents with Switch":{"main":[[{"node":"Summarizer Agent","type":"main","index":0}]]},"Save to handbook_entries":{"main":[[{"node":"Prepare Approved Contribution Data","type":"main","index":0}]]},"Generate GitHub File Path":{"main":[[{"node":"GitHub Enabled?","type":"main","index":0}]]},"Send Review Request Email":{"main":[[{"node":"Wait for Human Approval","type":"main","index":0}]]},"Onboarding/Explainer Agent":{"main":[[{"node":"Process Agent Output","type":"main","index":0}]]},"Commit to GitHub (Approved)":{"main":[[{"node":"Merge Archivist Paths","type":"main","index":0}]]},"Generate Content for Review":{"main":[[{"node":"Generate Review ID","type":"main","index":0}]]},"Prepare Approved Contribution Data":{"main":[[{"node":"Save Agent Contribution (Approved)","type":"main","index":0}]]},"Save Agent Contribution (Approved)":{"main":[[{"node":"Generate GitHub File Path","type":"main","index":0}]]}}}


name: Generate and Publish SEO-Optimized Blog Posts to Blogger with OpenAI & DALL-E
author_name: Khairul Muhtadin
author_username: khmuhtadin
categories: []
created_at: 2025-06-12T16:01:16.042Z
updated_at: 2025-06-12T16:01:16.042Z
url: https://n8n.io/workflows/4905
scraped_at: 2025-07-06 21:16:30
description:
  This n8n workflow, BlogBlizt: Blogger Edition, automates the complete creation and publishing of long-form blog posts to Blogger, saving you hours of content creation time. Simply send a blog title via Telegram, and it generates comprehensive 10,000+ word articles with custom conceptual images and publishes everything to your Blogger site with proper SEO structure and custom URLs.

  Who is this for?
  Blogger users, content creators, and digital marketers who want to automate high-quality, SEO-optimized blog content creation without manual writing or formatting. Perfect for those using Google's Blogger platform instead of WordPress.

  What problem is this workflow solving?
  Creating engaging, long-form content with proper SEO optimization is extremely time-consuming and requires expertise. Most automation tools focus on WordPress, leaving Blogger users behind. BlogBlizt: Blogger Edition solves this by automating the entire Blogger publishing process—from generating SEO metadata and writing comprehensive articles to creating custom images and publishing with proper URL structure.

  What this workflow does
  Triggers**: Receives blog title input via Telegram message
  AI-Powered Content**: Uses OpenAI GPT-4.1-mini to generate SEO metadata (title, slug, labels) and comprehensive articles
  Advanced Image Generation**: Creates custom conceptual images using DALL-E that visually represent your article's theme
  SEO Features**: Generates custom URLs with date structure, meta descriptions, and proper HTML formatting
  Reference Features**: Utilizing GPT 4.1 could reference valid and credible resource into great citation
  Blogger Integration**: Rare automated publishing directly to Blogger (not WordPress) with full API integration
  Image Hosting**: Automatically uploads generated images to Imgur and embeds them properly
  Instant Notifications**: Sends published blog link back via Telegram with mobile-optimized URLs

  Setup
  n8n Instance: Ensure you have a cloud or self-hosted n8n instance
  Credentials:
    Google OAuth2: For Blogger API access with https://www.googleapis.com/auth/blogger scope
    OpenAI API: For GPT-4.1-mini text generation and DALL-E image creation
    Telegram Bot: For receiving titles and sending notifications
    Imgur Client-ID: For image hosting and embedding
  Google Cloud Configuration:
    Enable Blogger API in Google Cloud Console
    Configure OAuth consent screen and create OAuth client ID
  Telegram Bot Setup:
    Create bot via @BotFather and get API token
    Test workflow to capture chat_id for notifications
  Test: Send any blog title via Telegram to generate your first automated post

  How to customize this workflow to your needs
  Change Writing Style**: Modify prompts for formal, casual, technical, or any specific tone
  Adjust Article Length**: Change minimum word count (currently 10,000+ words) to fit your needs
  SEO Optimization**: Customize keyword density and focus phrases in the writing prompts
  Image Aesthetics**: Modify DALL-E prompts for different visual styles (minimalist, corporate, artistic)
  URL Structure**: Edit JavaScript code to change custom URL formatting patterns
  Multi-Language**: Adapt prompts for any language or regional dialect
  Content Categories**: Add automatic categorization and tagging based on topics

  Pre-Requirements
  n8n Instance**: Cloud or self-hosted with LangChain nodes available
  API Access**:
   OpenAI API key for GPT-4.1-mini and DALL-E access
   Google OAuth2 credentials with Blogger API enabled
   Telegram Bot API token
   Imgur Client-ID for anonymous image uploads
  Blogger Setup**: Active Blogger blog with proper permissions
  Network**: Stable internet connection for AI generation and publishing

  Category: Marketing, Content Creation  
  Nodes Used: Telegram Trigger, LangChain LLM Chain, OpenAI (GPT-4.1-mini), OpenAI (DALL-E), HTTP Request, Google OAuth2, Blogger API, JavaScript Code

  Made by: Khaisa Studio  
  Tag: youtube, summarizer, telegram, openai  
  Category: AI Automation, Video Tools
  Need a custom? Contact Me 

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.telegram","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.chainLlm","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.outputParserStructured","@n8n/n8n-nodes-langchain.openAi"]

workflow_json:
  {"id":"eXhBHiSdeLyGHFzS","meta":{"instanceId":"c2650793f644091dc80fb900fe63448ad1f4b774008de9608064d67294f8307c","templateCredsSetupCompleted":true},"name":"Blog Blitz: Blogger Edition","tags":[],"nodes":[{"id":"0662e539-26b3-41ec-b8a9-d0660dec86cd","name":"🖼️ Generate Blog Image","type":"@n8n/n8n-nodes-langchain.openAi","position":[-460,620],"parameters":{},"typeVersion":1.8},{"id":"84450a41-1377-42e5-a225-9cd96ecddbd1","name":"☁️ Upload Image to Imgur","type":"n8n-nodes-base.httpRequest","position":[-240,620],"parameters":{},"typeVersion":4.2,"alwaysOutputData":true},{"id":"dccb695c-ad43-49ca-8038-4ced549890c4","name":"\t🟢 Start: Telegram Input","type":"n8n-nodes-base.telegramTrigger","position":[-820,-120],"webhookId":"69c62591-71fe-4d8e-8039-ba3e8c12b676","parameters":{},"typeVersion":1.2},{"id":"a5b36c49-f986-4157-96ca-fe109ddcc601","name":"\t📨 Notify: Title Received","type":"n8n-nodes-base.telegram","position":[-600,-120],"webhookId":"913313df-ba77-4d62-a6a7-f9ed9b00b216","parameters":{},"typeVersion":1.2},{"id":"ab40a618-b920-4a9b-bcd6-1f36ad68f9a1","name":"🔑 Get Blogger Profile","type":"n8n-nodes-base.httpRequest","position":[-380,-120],"parameters":{},"typeVersion":4.2},{"id":"11a280a5-9d8d-40e8-b6ec-b7c9b54c8ee3","name":"\t🧠 Generate Blog Metadata","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[-160,-120],"parameters":{},"retryOnFail":true,"typeVersion":1.6},{"id":"9b42b432-0e53-411d-bd79-a1996f60e5cc","name":"\t📄 Extract Metadata Structure","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[0,100],"parameters":{},"typeVersion":1.2},{"id":"887e93de-0902-4ee8-a8b8-3be11d3d3f9e","name":"🧠 AI Model: Metadata Generator","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-160,100],"parameters":{},"typeVersion":1.2},{"id":"25890b52-4833-4451-a9f8-bda9f476a38e","name":"\t✍️ Write Full Blog Content","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[220,-120],"parameters":{},"retryOnFail":true,"typeVersion":1.6},{"id":"095d7031-cb99-459c-b070-dd7908bc3fd9","name":"🧠 AI Model: Article Writer","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[220,100],"parameters":{},"typeVersion":1.2},{"id":"e1cabb9d-311f-4df9-ad2a-0803af1e201f","name":"🔗 Create Custom Blog Post URL","type":"n8n-nodes-base.code","position":[-680,620],"parameters":{},"typeVersion":2},{"id":"c987917d-c8d7-4780-a1b7-82fa571e0547","name":"🧷 Embed Image in HTML","type":"n8n-nodes-base.set","position":[-20,620],"parameters":{},"typeVersion":3.4},{"id":"9c4c580d-1447-4a5a-97ed-4928ed4fb1df","name":"\t🚀 Publish Article to Blogger","type":"n8n-nodes-base.httpRequest","position":[300,620],"parameters":{},"typeVersion":4.2,"alwaysOutputData":true},{"id":"64f51b33-e518-472d-b849-505ccf69727a","name":"\t📬 Send Blog Link to User","type":"n8n-nodes-base.telegram","position":[500,620],"webhookId":"b50ba0b0-77ca-47ae-82ae-ac6d179c50f2","parameters":{},"typeVersion":1.2},{"id":"7726e17f-c786-4974-854e-722bf7c50b53","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1340,140],"parameters":{"content":""},"typeVersion":1},{"id":"1bd39260-ae6c-4703-a489-484762102487","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-200,-420],"parameters":{"content":""},"typeVersion":1},{"id":"b7805d48-9d95-41be-bdac-28c4cf4b9780","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-520,260],"parameters":{"content":""},"typeVersion":1},{"id":"759a7e5f-1b5e-4ec6-8d20-aca26d660b10","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[200,260],"parameters":{"content":""},"typeVersion":1},{"id":"6208b35b-7721-4bf9-a49d-cfaf65d68344","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-920,-420],"parameters":{"content":""},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"05f9cbde-9689-4207-9501-f3d2cfb6d958","connections":{"🔑 Get Blogger Profile":{"main":[[{"node":"\t🧠 Generate Blog Metadata","type":"main","index":0}]]},"🧷 Embed Image in HTML":{"main":[[{"node":"\t🚀 Publish Article to Blogger","type":"main","index":0}]]},"\t🟢 Start: Telegram Input":{"main":[[{"node":"\t📨 Notify: Title Received","type":"main","index":0}]]},"🖼️ Generate Blog Image":{"main":[[{"node":"☁️ Upload Image to Imgur","type":"main","index":0}]]},"\t📨 Notify: Title Received":{"main":[[{"node":"🔑 Get Blogger Profile","type":"main","index":0}]]},"\t🧠 Generate Blog Metadata":{"main":[[{"node":"\t✍️ Write Full Blog Content","type":"main","index":0}]]},"☁️ Upload Image to Imgur":{"main":[[{"node":"🧷 Embed Image in HTML","type":"main","index":0}]]},"🧠 AI Model: Article Writer":{"ai_languageModel":[[{"node":"\t✍️ Write Full Blog Content","type":"ai_languageModel","index":0}]]},"\t✍️ Write Full Blog Content":{"main":[[{"node":"🔗 Create Custom Blog Post URL","type":"main","index":0}]]},"\t📄 Extract Metadata Structure":{"ai_outputParser":[[{"node":"\t🧠 Generate Blog Metadata","type":"ai_outputParser","index":0}]]},"\t🚀 Publish Article to Blogger":{"main":[[{"node":"\t📬 Send Blog Link to User","type":"main","index":0}]]},"🔗 Create Custom Blog Post URL":{"main":[[{"node":"🖼️ Generate Blog Image","type":"main","index":0}]]},"🧠 AI Model: Metadata Generator":{"ai_languageModel":[[{"node":"\t🧠 Generate Blog Metadata","type":"ai_languageModel","index":0}]]}}}


name: Discover Business Leads with Gemini, Brave Search and Web Scraping
author_name: Jez
author_username: jez
categories: []
created_at: 2025-06-13T02:32:46.657Z
updated_at: 2025-06-13T02:32:46.657Z
url: https://n8n.io/workflows/4910
scraped_at: 2025-07-06 21:16:30
description:
  This workflow contains community nodes that are only compatible with the self-hosted version of n8n. 

  Uncover new business leads with this AI-Powered Prospect Discovery Agent! This n8n workflow acts as a specialized intelligent assistant that, given a business type and location, uses multiple search strategies to identify a list of potential prospect companies and their websites.

  Stop manually trawling through search results! This agent automates the initial phase of lead generation by:
  Understanding your target business profile (type, location, keywords).
  Strategically using web search tools (Brave Search, Google Gemini Search) to find relevant businesses.
  Performing quick validations to confirm relevance.
  Returning a clean, structured JSON list of prospect names and their website URLs.

  How it Works:

  The workflow is built around an AI agent powered by Google Gemini. This agent is equipped with tools like:

  Brave Web Search:** For broad initial sourcing of potential business candidates.
  Google Gemini Search:** For advanced, context-aware discovery and finding businesses mentioned in various online sources.
  Brave Local Search (Selective):** For quick verification of local presence or finding website URLs for identified names.
  Jina AI Web Page Scraper (Very Selective):** For extremely rapid relevance checks on uncertain websites by scanning page content for keywords.

  The agent's system prompt guides it to use these tools efficiently to build a list of prospects without getting bogged down in deep research on any single one at this discovery stage.

  Use Cases:

  Lead Generation:** Automatically generate lists of potential clients based on industry and location.
  Market Research:** Identify key players or types of businesses in a specific geographical area.
  Sales Development:** Provide SDRs with initial lists of companies to research further.
  Called as a Sub-Workflow:** Designed to be easily integrated as a "tool" into more complex orchestrating AI agents (e.g., a BNI Pitch Planner that first needs to identify who to target).

  Setup:

  Import the workflow.
  Configure Credentials: You'll need n8n credentials for:
      Google Gemini (for the Chat model and the Gemini Search/Vertex AI Search tool).
      Brave Search (e.g., via Smithery MCP, or adapt if you have direct API access).
      Jina AI (for the web scraper).
      Assign these to the respective nodes.
  Review System Prompt: The prospect_discovery_agent node contains a detailed system prompt. You can fine-tune this to adjust its search strategies or the strictness of its matching.
  Inputs: This workflow is triggered by an "Execute Workflow Trigger" node (prospect_discovery_workflow). It expects the following inputs:
      business_type (string): e.g., "artisan bakery"
      location_query (string): e.g., "Portland, Oregon"
      desired_num_prospects (number): e.g., 5
      additional_keywords (string, optional): e.g., "organic, gluten-free"

  To Use (as a Sub-Workflow/Tool):

  This workflow is typically called by another n8n workflow (e.g., using a "Tool Workflow" node from the Langchain nodes). The calling workflow would provide the inputs listed above. The "Prospect Discovery" workflow will then execute and its final node (the prospect_discovery_agent) will output a JSON array of found prospects, like:

  [
    {
      "business_name": "Rose Petal Bakery",
      "website_url": "https://rosepetalbakerypdx.com"
    },
    {
      "business_name": "The Daily Bread Artisans",
      "website_url": "https://dailybreadpdx.com"
    }
  ]
  If no prospects are found, it returns an empty array [].

  This template provides a powerful and focused tool for automating the initial stages of prospect identification.

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

workflow_json:
  {"id":"tqyzrnyfFxB3x8LO","meta":{"instanceId":"3612a0c89f35a354ddd1216385240db51b4635fde7cae2a0d5004be915b832f3","templateCredsSetupCompleted":true},"name":"Prospect Discovery","tags":[],"nodes":[{"id":"dc30089e-2dea-4cba-ae74-f043240b5176","name":"Google Gemini Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[-40,1560],"parameters":{"options":{},"modelName":"models/gemini-2.5-flash-preview-05-20"},"credentials":{"googlePalmApi":{"id":"c8jj7D6oz6RJ81qp","name":"Google Gemini Context7"}},"typeVersion":1},{"id":"27d02a47-659e-4b6a-8c5f-50253fc5be1c","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[820,1620],"parameters":{"sessionKey":"={{ $execution.id }}","sessionIdType":"customKey"},"typeVersion":1.3},{"id":"b791c4dd-bdc8-4d38-a301-ababb9ff129f","name":"brave_web_search","type":"n8n-nodes-mcp.mcpClientTool","position":[1160,1300],"parameters":{"toolName":"brave_web_search","operation":"executeTool","connectionType":"http","toolParameters":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Tool_Parameters', `Generate a JSON object with the parameters for the 'brave_web_search' tool.\nThe tool expects a JSON object with the following keys:\n- \"query\": (string, **required**) The search terms designed to find multiple examples of a business type in a given area. Examples: \"list of crane hire companies in Newcastle NSW\", \"artisan bakeries Sydney CBD reviews\", \"marketing agencies California specializing in tech startups\".\n- \"count\": (number, optional) Number of results. For prospect discovery, a higher count (e.g., 10-20) might be useful to cast a wider net.\n- \"offset\": (number, optional) For pagination if analyzing multiple pages of results.\n\nExample:\n{\"query\": \"top rated plumbing services in Bristol UK\", \"count\": 15}`, 'json') }}","descriptionType":"manual","toolDescription":"Performs a general web search using Brave Search. Primarily used to find lists, directories, articles, or multiple mentions of businesses matching a specified type and location. The goal is to identify several potential prospect company names and their websites, not just one official site. Effective for initial broad sweeps to gather candidate businesses. Parameters: 'query' (required string), 'count' (optional number, max 20), 'offset' (optional number)."},"credentials":{"mcpClientHttpApi":{"id":"izP58157WoLmqx5y","name":"smithery brave search"}},"typeVersion":1},{"id":"d33f89c7-ed40-427e-9f2c-b699194e860e","name":"brave_local_search","type":"n8n-nodes-mcp.mcpClientTool","position":[1720,1300],"parameters":{"toolName":"brave_local_search","operation":"executeTool","connectionType":"http","toolParameters":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Tool_Parameters', `Generate a JSON object with the parameters for the 'brave_local_search' tool.\nThe tool expects a JSON object with the following keys:\n- \"query\": (string, **required**) The search terms, typically a specific business name and its suspected city/area, to get a quick local listing check. Example: \"ABC Cranes Newcastle\", \"The Corner Bakery Springfield\".\n- \"count\": (number, optional) Usually 1 or a small number (e.g., 3) is sufficient, as you're checking a specific entity.\n\nExample:\n{\"query\": \"Summit Logistics, Dallas TX\", \"count\": 1}`, 'json') }}","descriptionType":"manual","toolDescription":"Searches for local business listings using Brave Local Search. In prospect discovery, this tool can be used sparingly to quickly verify if a business name found through broader searches has a local presence or to find a website URL if it's not immediately apparent from web search results. Not the primary tool for initial discovery of types, but useful for quick validation of individual potential prospects from a list. Parameters: 'query' (required string), 'count' (optional number, usually 1-3 for this purpose)."},"credentials":{"mcpClientHttpApi":{"id":"izP58157WoLmqx5y","name":"smithery brave search"}},"typeVersion":1},{"id":"d2cd00e1-bb22-4a6d-a7c5-bcf299883396","name":"jina_ai_web_page_scraper","type":"n8n-nodes-base.jinaAiTool","position":[2880,1300],"parameters":{"url":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('URL', `Provide the full URL of a potential prospect's homepage or 'About Us' page. Use this only if you need to quickly verify from the website's text if the business matches the desired type before finalizing it as a prospect. Example: 'https://potentialprospect.com/about'.`, 'string') }}","options":{"outputFormat":"markdown","enableImageCaptioning":true},"requestOptions":{},"descriptionType":"manual","toolDescription":"Extracts main textual content from a given web page URL. In prospect discovery, use this very selectively and sparingly. If a promising business website is found but it's unclear if they are the correct business type, a quick scrape of their homepage or 'About Us' page can help confirm relevance before adding them to the prospect list. Not for deep information extraction at this stage. Parameter: 'url' (required string). Critical: Use for 1-2 URLs max for quick validation if needed, due to time limits."},"credentials":{"jinaAiApi":{"id":"Ds8w0d9HhKCi6twc","name":"Jina AI account"}},"typeVersion":1},{"id":"27045509-9f22-4fd8-a753-5d5e2109caa7","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[680,-940],"parameters":{"color":7,"width":940,"height":460,"content":"## 📞 MCP Client Configuration (for Prospect Discovery Service)\n\nExternal clients can configure this agent as a tool to discover lists of potential business prospects.\n\n    **Example Client Tool Configuration (e.g., for Roo Code/Cline):**\n\n\n    \"prospect-discovery\": {\n      \"url\": \"https://SERVER/mcp/PATHTOYOURMCP/sse\",\n      \"alwaysAllow\": [\n        \"discover_prospect\"\n      ]\n    }\n\n\n*Note: The tool_name here (prospect-discovery) is how the client would refer to this entire MCP service. The alwaysAllow refers to the tool exposed by this Prospect Discovery MCP server.*"},"typeVersion":1},{"id":"4cc52e11-b88f-44ec-8411-4e6f8cdb725c","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-860,-420],"parameters":{"color":4,"width":840,"height":420,"content":"## 📡 prospect_discovery (MCP Server Trigger - Optional Endpoint)\n\n🚪 **Optional Entry Point for External Prospect Discovery Requests**\n*   **Purpose:** If this workflow is exposed as a direct MCP service, this node receives requests from external clients (e.g., other n8n workflows, applications) looking to get a list of business prospects.\n*   **Function:** Listens for HTTP POST requests formatted according to the MCP (Multi-Capability Peer) protocol.\n*   **Tool Exposed:** Would expose the `discover_prospect` tool capability (defined by the connected Tool Workflow node) to the external caller.\n*   **Typical Input:** A JSON payload from the client specifying `tool_name: \"discover_prospect\"` (or similar, matching the exposed tool) and `tool_input` containing `business_type`, `location_query`, `desired_num_prospects`, and `additional_keywords`.\n*   **Typical Output:** Parses the incoming request and passes the `tool_input` to the `discover_prospect` (Tool Workflow) node, initiating the Prospect Discovery Agent's process.\n*   **Note:** This workflow is also designed to be called as a sub-workflow directly (e.g., by the \"60s Referral Planner\"), which might be its primary use case."},"typeVersion":1},{"id":"e69f1690-e3f8-43a4-b258-a562db2d4338","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-860,60],"parameters":{"color":4,"width":840,"height":320,"content":"## ➡️ discover_prospect (Tool Workflow Node)\n\n📞 **Invokes the Prospect Discovery Agent Logic**\n*   **Purpose:** This node acts as the bridge, formally calling the `prospect_discovery_agent`'s core logic.\n*   **Triggered by:**\n    1.  The `prospect_discovery` (MCP Trigger) node, if this workflow is called as an external MCP service.\n    2.  A parent workflow (like \"60s Referral Planner\") that uses this \"Prospect Discovery\" workflow as a tool/sub-workflow.\n*   **Action:** Calls the \"Prospect Discovery\" workflow itself by triggering the `prospect_discovery_workflow` (Execute Workflow Trigger node within this same n8n workflow).\n*   **Inputs:** Receives `business_type`, `location_query`, `desired_num_prospects`, and `additional_keywords` from the calling source (either MCP Trigger or parent workflow's tool call).\n*   **Outputs:** Passes these inputs to the `prospect_discovery_workflow` (Execute Workflow Trigger). The final JSON list of prospects, compiled by the `prospect_discovery_agent`, will be the result of this tool call."},"typeVersion":1},{"id":"cebaa441-7072-42f4-abb6-52dff61d38ae","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[680,-460],"parameters":{"color":7,"width":940,"height":400,"content":"## 🗺️ Main MCP Server Workflow Overview (Prospect Discovery Service)\n\n**Agent Name:** Prospect Discovery Agent\n*   **Gateway Function (If Exposed):** This workflow *could* act as an MCP Server, making the \"Prospect Discovery Agent\" directly callable by external systems.\n*   **Trigger (If Exposed):** A dedicated `prospect_discovery_mcp_trigger` (MCP Trigger node) would receive external requests to find lists of prospects.\n*   **Tool Workflow Node (If Exposed):** A `discover_prospects_mcp_tool` (Tool Workflow node) would package the incoming request (business type, location, etc.) and invoke this agent's core logic.\n*   **Data Flow (If Exposed):** External Request -> `prospect_discovery_mcp_trigger` -> `discover_prospects_mcp_tool` -> `prospect_discovery_workflow` (Execute Workflow Trigger, starts agent logic).\n*   **Primary Design:** Note that this workflow is primarily designed as a sub-workflow. Exposing it directly as an MCP service is an optional extension."},"typeVersion":1},{"id":"44491f1b-4042-45b3-9fb7-87a96212d2c2","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[1680,-1240],"parameters":{"color":3,"width":740,"height":280,"content":"## 📄 Workflow Information: Prospect Discovery Agent\n\n*   **Workflow Name:** Prospect Discovery Agent\n*   **Version:** 1.0.0\n*   **Last Updated:** 2025-06-12\n*   **👤 Author:** Jeremy Dawes, Jezweb ([www.jezweb.com.au](https://www.jezweb.com.au/))\n*   **Description:** This workflow functions as a specialized AI agent dedicated to identifying a list of potential business prospects (names and website URLs). It takes a business type, location query, and other criteria as input, uses search tools to find matching businesses, and returns a structured list. It's designed to be called as a tool by other orchestrating agents (like the \"60s Referral Planner\")."},"typeVersion":1},{"id":"4805790c-b4e7-4f37-949a-2d9a62bce598","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[2480,-80],"parameters":{"color":2,"width":740,"height":560,"content":"## ✅ TODO / Future Enhancements (Prospect Discovery Agent)\n\n*   [ ] **Improve Location Disambiguation:** Add more sophisticated logic if the `location_query` is ambiguous or very broad.\n*   [ ] **Confidence Scoring:** Could the agent assign a confidence score to each prospect found based on how well it matches the criteria?\n*   [ ] **Negative Keywords:** Allow input for negative keywords (e.g., \"find bakeries, NOT specializing in wedding cakes\").\n*   [ ] **Alternative Directory Searching:** Explicitly add a tool or logic to search specific online business directories if relevant for certain `business_type` inputs.\n*   [ ] **Batching/Pagination for Large Areas:** If a `location_query` is very large (e.g., \"all of USA\"), implement a strategy to break down the search.\n*   [ ] **Allow specifying number of results per search tool call** to better control the initial pool of candidates.\n*   [ ] **Refine criteria for using `jina_ai_web_page_scraper`:** Make the conditions for its use even more stringent in the system prompt."},"typeVersion":1},{"id":"249f9bfb-b92f-4bf5-ad59-300271da9bff","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-740,720],"parameters":{"color":4,"width":640,"height":520,"content":"## 🏁 Sub-Workflow Start: Prospect Discovery Logic\n(Node: `prospect_discovery_workflow` - Execute Workflow Trigger)\n\n🎯 **Initiates the Prospect Identification Process**\n*   **Purpose:** This is the internal entry point for the \"Prospect Discovery Agent's\" core logic. It's triggered when the `discover_prospect` tool (from the \"60s Referral Planner\" workflow) is called.\n*   **Receives:**\n    *   `business_type`: The category of business to find.\n    *   `location_query`: The geographical area for the search.\n    *   `desired_num_prospects`: How many prospects to aim for.\n    *   `additional_keywords`: Optional search refinements.\n*   **Passes Data To:** The `prospect_discovery_agent` (AI Agent) node to begin the process of identifying potential business leads."},"typeVersion":1},{"id":"89ff4b9f-d13a-4ec4-af43-77f56fd2de03","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[20,620],"parameters":{"color":4,"width":740,"height":620,"content":"## 🧠 prospect_discovery_agent (Core Logic)\n\n🔍 **The Prospect Identification Engine**\n*   **Purpose:** Processes the request to find a list of potential business prospects (names and websites) based on type, location, and other criteria, using available search tools and LLM reasoning.\n*   **Model:** `models/gemini-2.5-flash-preview-05-20` (or your chosen model, via the connected `Google Gemini Chat Model` node).\n*   **System Prompt:** Defined within this agent node. This prompt is CRITICAL and guides the AI on:\n    *   Its specific mission (finding a list of prospects).\n    *   How to interpret input parameters (`business_type`, `location_query`, etc.).\n    *   Strategic use of its tools (`brave_web_search`, `google_gemini_business_search`, selective `brave_local_search`, and very rare `jina_ai_web_page_scraper` for quick validation).\n    *   The precise JSON output format required (an array of business objects).\n*   **Tools Used (with a Prospect Discovery focus):**\n    *   `brave_web_search`: For broad sourcing of potential candidates.\n    *   `google_gemini_business_search`: For advanced and contextual discovery of multiple businesses.\n    *   `brave_local_search`: Selectively for quick URL finding for an already identified name.\n    *   `jina_ai_web_page_scraper`: VERY sparingly for rapid relevance checks on uncertain websites.\n*   **Memory Setup:** Uses `Planner Memory` (or your named `Simple Memory` node for this workflow) to retain short-term context for the LLM during its multi-step search process.\n*   **Input:** Receives `business_type`, `location_query`, `desired_num_prospects`, and `additional_keywords` from the `prospect_discovery_workflow` trigger.\n*   **Output:** A JSON array of prospect objects, each containing `business_name` and `website_url`. This output becomes the result of the `discover_prospect` tool call in the parent workflow."},"typeVersion":1},{"id":"b73ca6ea-094f-487f-ab64-4a9c08d8d6d5","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[260,1660],"parameters":{"color":6,"width":620,"height":340,"content":"## 💾 Agent Memory (Planner Memory / Simple Memory)\n\n🧠 **Short-Term Recall for Prospect Search**\n*   **Purpose:** Provides conversational memory to the `prospect_discovery_agent`, allowing it to remember previous tool calls and results within a single execution of its task (e.g., remembering businesses already found to avoid duplicates, or recalling search strategies that were or weren't effective).\n*   **Type:** Window Buffer Memory (keeps a limited history of interactions for the current discovery task).\n*   **Session Key:** `={{ $execution.id }}` (Ensures memory is unique to each specific prospect discovery request).\n*   **Importance:** Helps the agent conduct a more coherent multi-step search process to build its list of prospects."},"typeVersion":1},{"id":"923fa510-9f62-4295-a604-72d02406d01a","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[960,720],"parameters":{"color":5,"width":460,"height":620,"content":"## 🛠️ Tool: brave_web_search (Prospect Discovery Context)\n\n🌐 **Broad Prospect Sourcing & List Generation**\n*   **Connection:** Uses `smithery brave search` credential.\n*   **Purpose for Prospect Discovery:** Performs general web searches to identify multiple potential businesses matching a given type, location, and keywords. Used to find directories, articles listing companies, or general search results that indicate several candidate businesses.\n*   **AI Interaction (Prospect Discovery Agent):**\n    *   Agent formulates queries to cast a wide net, e.g., `\"list of [business_type] in [location_query]\"`, `\"top [business_type] [location_query] [keywords]\"`.\n    *   Agent analyzes search snippets for company names and potential website URLs.\n    *   Aims to gather a pool of initial candidates. It might use a higher `count` (e.g., 10-20) in its parameters for this tool.\n    *   Example AI-generated params: `{\"query\": \"artisan coffee roasters in Portland Oregon\", \"count\": 15}`\n*   **Output:** Search results (list of URLs, snippets) used to compile an initial list of potential prospect names and websites."},"typeVersion":1},{"id":"69d2a0c8-6535-424e-8663-7d99e225d441","name":"Sticky Note10","type":"n8n-nodes-base.stickyNote","position":[1540,720],"parameters":{"color":5,"width":460,"height":620,"content":"## 🛠️ Tool: brave_local_search (Prospect Discovery Context - Limited Use)\n\n📍 **Quick Validation & URL Sniffing for Potential Prospects**\n*   **Connection:** Uses `smithery brave search` credential.\n*   **Purpose for Prospect Discovery:** Used very selectively. If a promising company name is found via `brave_web_search` or `google_gemini_prospect_finder` but its website isn't immediately clear, this tool can quickly check for a local listing in the target area to try and find an official website URL or confirm its local presence.\n*   **AI Interaction (Prospect Discovery Agent):**\n    *   Agent uses this for specific company names identified in earlier, broader searches.\n    *   Example: After finding \"Acme Widgets\" as a potential, agent might query `{\"query\": \"Acme Widgets [location_query]\"}` to find its website from a local result.\n    *   NOT used for the initial broad discovery of business types. Usually, `count: 1` is sufficient.\n*   **Output:** Local search results, primarily to extract a website URL or confirm the existence of a *specific, already identified* potential prospect."},"typeVersion":1},{"id":"376c605e-7453-43b4-8d86-ebc701165e0a","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[2120,720],"parameters":{"color":5,"width":460,"height":620,"content":"## 🛠️ Tool: google_gemini_prospect_finder (Prospect Discovery Context)\n\n✨ **Advanced Prospect Sourcing & Contextual Discovery**\n*   **Connection:** Uses `Gemini Credentials account` credential.\n*   **Purpose for Prospect Discovery:** Leverages Google Gemini's advanced search to identify potential businesses based on type, location, and nuanced criteria. Useful for discovering businesses mentioned in context (articles, discussions) or when broader queries are needed to identify multiple candidates. Can supplement `brave_web_search`.\n*   **AI Interaction (Prospect Discovery Agent):**\n    *   Agent uses this for queries like: `\"Find examples of [business_type] serving [location_query] with a focus on [keywords]\"`, `\"companies in [industry] in [region]\"`.\n    *   Helps identify businesses that might not appear in simple directory listings.\n    *   Agent scans results for multiple company names and their websites.\n    *   Example AI-generated params: `{\"query\": \"eco-friendly packaging suppliers in Northern Europe\"}`\n*   **Output:** Rich search results, from which the agent extracts potential business names and website URLs for the prospect list."},"typeVersion":1},{"id":"38df04af-6a16-48b9-b028-3025c74131f5","name":"Sticky Note12","type":"n8n-nodes-base.stickyNote","position":[2700,720],"parameters":{"color":5,"width":460,"height":620,"content":"## 🛠️ Tool: jina_ai_web_page_scraper (Prospect Discovery Context - VERY Limited Use)\n\n📄 **Rapid Relevance Check for Uncertain Prospects**\n*   **Connection:** Uses `Jina AI account` credential.\n*   **Purpose for Prospect Discovery:** Used EXTREMELY SPARINGLY and only as a final check. If a website is found for a potential prospect, but it's highly unclear from the URL or search snippet if they truly match the `business_type`, this tool can scrape the homepage or \"About Us\" page. The agent then quickly scans the text for keywords to confirm relevance before adding to the final prospect list.\n*   **AI Interaction (Prospect Discovery Agent):**\n    *   Agent provides URL of a single, uncertain prospect's page (e.g., homepage or about page).\n    *   Agent instructs itself (via its system prompt) to look for specific keywords related to `business_type` in the scraped text.\n    *   **NOT for detailed information extraction or profiling at this stage.** Goal is quick go/no-go relevance validation.\n    *   Example AI-generated params: `{\"url\": \"https://ambiguouscompany.com/about\"}`\n*   **Output:** Markdown content of the scraped page. **CRITICAL: Use for 1-2 URLs MAX per run for quick validation only due to time limits and the discovery phase's need for speed.**"},"typeVersion":1},{"id":"6c8a16f5-cb1d-46f3-8a75-688914e3a6c5","name":"Sticky Note13","type":"n8n-nodes-base.stickyNote","position":[1680,-900],"parameters":{"color":2,"width":740,"height":500,"content":"## 💡 n8n AI Agent as a Specialized Sub-Workflow (Prospect Discovery Pattern)\n\n**This workflow implements a specialized n8n AI Agent designed to be called as a tool or sub-workflow by another parent agent.**\n*   **What this \"Agent Logic\" part does:** Implements the core intelligence for discovering potential business prospects. It receives criteria (business type, location, etc.), uses its LLM (`Google Gemini Chat Model`) and a suite of search tools (`brave_web_search`, `google_gemini_business_search`, and very selectively `brave_local_search`, `jina_ai_web_page_scraper`) to identify a list of businesses, and then formats this list as a structured JSON output.\n*   **How it works internally:** The `prospect_discovery_agent` node orchestrates tool calls based on its system prompt and the input criteria. Its primary goal is to generate a list of relevant business names and websites, not deep profiles.\n*   **Why this pattern is useful:**\n    1.  **Modularity & Specialization:** Complex tasks (like broad prospect discovery vs. specific business lookup) are broken down into specialized agents, making each agent simpler and more effective at its specific job.\n    2.  **Reusability:** This Prospect Discovery agent could potentially be called by other workflows in the future that need to identify types of businesses.\n    3.  **Clarity:** Separating discovery logic from detailed research logic keeps each workflow cleaner."},"typeVersion":1},{"id":"c8cd4af9-911a-4175-ae49-98b27c1f1558","name":"Sticky Note14","type":"n8n-nodes-base.stickyNote","position":[1680,-360],"parameters":{"color":2,"width":740,"height":460,"content":"## 🔑 External Service Credentials (Prospect Discovery Agent Logic)\n\nList of credentials used by tools within this Prospect Discovery agent:\n\n1.  **Tool Nodes:** `brave_web_search`, `brave_local_search` (selective use)\n    *   **n8n Credential Name:** `smithery brave search`\n    *   **Target Service (Example):** Smithery MCP for Brave Search\n2.  **Tool Node:** `Google Gemini Chat Model` (LLM for the `prospect_discovery_agent`)\n    *   **n8n Credential Name:** `Google Gemini Context7` (or your specific Gemini credential)\n    *   **Target Service:** Google AI (Generative Language API)\n3.  **Tool Node:** `google_gemini_business_search`\n    *   **n8n Credential Name:** `Gemini Credentials account` (or your specific Gemini credential for search)\n    *   **Target Service:** Google AI (Gemini Search API / Vertex AI Search)\n4.  **Tool Node:** `jina_ai_web_page_scraper` (very selective use for relevance check)\n    *   **n8n Credential Name:** `Jina AI account`\n    *   **Target Service:** Jina AI API"},"typeVersion":1},{"id":"31a06a5a-c805-48c0-889a-e72a4192b341","name":"Sticky Note15","type":"n8n-nodes-base.stickyNote","position":[-720,1600],"parameters":{"color":6,"width":740,"height":260,"content":"## ⚙️ Key LLM & Agent Settings (Prospect Discovery Logic Area)\n\n*   **LLM Model:** `models/gemini-2.5-flash-preview-05-20` (Configured in the `Google Gemini Chat Model` node connected to the `prospect_discovery_agent`).\n*   **System Prompt Location:** Crucially defined within the `prospect_discovery_agent` node, in the \"Options\" -> \"System Message\" parameter. This prompt dictates the agent's specialized behavior for finding lists of prospects.\n*   **Memory Type/Key:** Window Buffer Memory (using the `Planner Memory` or your named `Simple Memory` node for this workflow), with the Session Key typically set to `={{ $execution.id }}` to ensure memory is isolated for each run of the prospect discovery task."},"typeVersion":1},{"id":"d982e681-f48e-4020-9d6b-cf862f24ace7","name":"Sticky Note16","type":"n8n-nodes-base.stickyNote","position":[2480,-900],"parameters":{"color":2,"width":740,"height":360,"content":"## 🎯 Sub-Workflow: Business Finder Core Logic (Agent Logic Area)\n\n*   **Purpose:** This section of the workflow is dedicated to understanding the user's business search request, strategically utilizing search and scraping tools, and synthesizing the findings into a comprehensive and helpful formatted response for sales prospecting.\n*   **Expected Input Details (from `business_finder_workflow` trigger, originating from the `find_business` tool call):**\n    *   `query`: (string) A natural language query describing the business to find. This can include business name, type, industry, location hints, known website, or specific information sought (e.g., \"Acme Corp New York contact details\", \"find owner of bestlocalplumber.com\", \"tech startups in Austin with less than 50 employees\")."},"typeVersion":1},{"id":"f23b12e0-a347-4b85-ae2c-17f50f2b2e98","name":"Sticky Note17","type":"n8n-nodes-base.stickyNote","position":[2480,-500],"parameters":{"color":2,"width":740,"height":400,"content":"## 🛠️ Troubleshooting Tips (Prospect Discovery Agent Logic)\n\n*   **Check `prospect_discovery_agent` Logs:** Examine execution logs for tool call details (especially the queries sent to search tools), LLM interactions, and any errors during the list generation.\n*   **Test Search Tools Individually:** If the agent struggles to find prospects, manually test the `brave_web_search` and `google_gemini_business_search` nodes with the types of queries the agent *should* be making to see if the underlying search services can find relevant businesses.\n*   **Review System Prompt:** Ensure the system prompt for `prospect_discovery_agent` clearly guides its search strategy, its interpretation of `business_type` and `location_query`, and its use of tools for list generation (not deep dives).\n*   **Input Specificity:** The quality of prospects found will heavily depend on the clarity of the `business_type` and `location_query` inputs it receives. Test with various inputs.\n*   **`jina_ai_web_page_scraper` Timeouts:** This tool should be used extremely rarely by this agent. If timeouts occur, it's likely being overused; its role here is only for quick validation of uncertain website relevance.\n*   **Output Format:** Ensure the agent is consistently returning the JSON array as specified. Issues here will break the calling workflow."},"typeVersion":1},{"id":"a7f54d15-946f-4712-94ca-97a360adc9bc","name":"Sticky Note18","type":"n8n-nodes-base.stickyNote","position":[3440,-1160],"parameters":{"color":7,"width":860,"height":1640,"content":"### n8n Community Template Submission Description (for \"Prospect Discovery\" Workflow)\n\nThis description is for the \"Prospect Discovery\" workflow itself, highlighting its specific capabilities.\n\n**Workflow Title:** AI-Powered Prospect Discovery Agent\n\n**Description:**\n\nUncover new business leads with this AI-Powered Prospect Discovery Agent! This n8n workflow acts as a specialized intelligent assistant that, given a business type and location, uses multiple search strategies to identify a list of potential prospect companies and their websites.\n\nStop manually trawling through search results! This agent automates the initial phase of lead generation by:\n*   Understanding your target business profile (type, location, keywords).\n*   Strategically using web search tools (Brave Search, Google Gemini Search) to find relevant businesses.\n*   Performing quick validations to confirm relevance.\n*   Returning a clean, structured JSON list of prospect names and their website URLs.\n\n**How it Works:**\n\nThe workflow is built around an AI agent powered by Google Gemini. This agent is equipped with tools like:\n\n*   **Brave Web Search:** For broad initial sourcing of potential business candidates.\n*   **Google Gemini Search:** For advanced, context-aware discovery and finding businesses mentioned in various online sources.\n*   **Brave Local Search (Selective):** For quick verification of local presence or finding website URLs for identified names.\n*   **Jina AI Web Page Scraper (Very Selective):** For extremely rapid relevance checks on uncertain websites by scanning page content for keywords.\n\nThe agent's system prompt guides it to use these tools efficiently to build a list of prospects without getting bogged down in deep research on any single one at this discovery stage.\n\n**Use Cases:**\n\n*   **Lead Generation:** Automatically generate lists of potential clients based on industry and location.\n*   **Market Research:** Identify key players or types of businesses in a specific geographical area.\n*   **Sales Development:** Provide SDRs with initial lists of companies to research further.\n*   **Called as a Sub-Workflow:** Designed to be easily integrated as a \"tool\" into more complex orchestrating AI agents (e.g., a BNI Pitch Planner that first needs to identify who to target).\n\n**Setup:**\n\n1.  **Import the workflow.**\n2.  **Configure Credentials:** You'll need n8n credentials for:\n    *   Google Gemini (for the Chat model and the Gemini Search/Vertex AI Search tool).\n    *   Brave Search (e.g., via Smithery MCP, or adapt if you have direct API access).\n    *   Jina AI (for the web scraper).\n    Assign these to the respective nodes.\n3.  **Review System Prompt:** The `prospect_discovery_agent` node contains a detailed system prompt. You can fine-tune this to adjust its search strategies or the strictness of its matching.\n4.  **Inputs:** This workflow is triggered by an \"Execute Workflow Trigger\" node (`prospect_discovery_workflow`). It expects the following inputs:\n    *   `business_type` (string): e.g., \"artisan bakery\"\n    *   `location_query` (string): e.g., \"Portland, Oregon\"\n    *   `desired_num_prospects` (number): e.g., 5\n    *   `additional_keywords` (string, optional): e.g., \"organic, gluten-free\"\n\n**To Use (as a Sub-Workflow/Tool):**\n\nThis workflow is typically called by another n8n workflow (e.g., using a \"Tool Workflow\" node from the Langchain nodes). The calling workflow would provide the inputs listed above. The \"Prospect Discovery\" workflow will then execute and its final node (the `prospect_discovery_agent`) will output a JSON array of found prospects, like:\n\n```json\n[\n  {\n    \"business_name\": \"Rose Petal Bakery\",\n    \"website_url\": \"https://rosepetalbakerypdx.com\"\n  },\n  {\n    \"business_name\": \"The Daily Bread Artisans\",\n    \"website_url\": \"https://dailybreadpdx.com\"\n  }\n]\n```\nIf no prospects are found, it returns an empty array `[]`.\n\nThis template provides a powerful and focused tool for automating the initial stages of prospect identification."},"typeVersion":1},{"id":"71869bea-8ed4-4aa6-a8d3-6a19be1af7e8","name":"prospect_discovery","type":"@n8n/n8n-nodes-langchain.mcpTrigger","position":[-220,-80],"webhookId":"5de5d0b6-7f58-47df-8d2c-4096f61212c8","parameters":{"path":"5de5d0b6-7f58-47df-8d2c-4096f61212c8"},"typeVersion":1},{"id":"617b4a64-691a-4850-9b2c-f38c9580869c","name":"discover_prospect","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[-60,320],"parameters":{"workflowId":{"__rl":true,"mode":"list","value":"tqyzrnyfFxB3x8LO","cachedResultName":"Prospect Discovery"},"description":"=This tool calls the specialized \"Prospect Discovery\" AI agent to find a list of potential business prospects (names and website URLs) based on specified criteria. Use this when the user's 'Ideal Referral' input describes a TYPE of business rather than a specific company name. This tool helps identify examples of businesses that match the desired profile in a given location. The output will be a list of potential businesses that can then be further researched individually if needed.","workflowInputs":{"value":{"business_type":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('business_type', `Specify the category or type of business to search for. This should be derived from the user's 'Ideal Referral' input when it describes a general business category. Examples: \"crane hire company\", \"artisan bakery\", \"SaaS provider for HR\", \"boutique marketing agency\".`, 'string') }}","location_query":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('location_query', `Provide a description of the target geographical area for the prospect search. This should be inferred from the user's own business location (e.g., if the user is in Newcastle, search for prospects in Newcastle or surrounding areas, unless otherwise specified). Examples: \"Newcastle NSW Australia\", \"downtown San Francisco\", \"Midlands UK\", \"businesses operating primarily online globally\".`, 'string') }}","additional_keywords":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('additional_keywords', `(Optional) Include any other relevant terms or specializations mentioned by the user for their ideal referral, or that you infer might refine the search for the business type. Examples: \"specializing in commercial projects\", \"eco-friendly products\", \"B2B focus\", \"serves small businesses\". Leave empty if no specific refinements are needed beyond type and location.`, 'string') }}","desired_num_prospects":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('desired_num_prospects', `Set the target number of unique prospect examples to find. A small number (e.g., 2 or 3) is usually sufficient at this stage, as the goal is to get a few good examples that can then be used to craft a more targeted referral ask or for further specific research.`, 'string') }}"},"schema":[{"id":"business_type","type":"string","display":true,"removed":false,"required":false,"displayName":"business_type","defaultMatch":false,"canBeUsedToMatch":true},{"id":"location_query","type":"string","display":true,"removed":false,"required":false,"displayName":"location_query","defaultMatch":false,"canBeUsedToMatch":true},{"id":"desired_num_prospects","type":"string","display":true,"removed":false,"required":false,"displayName":"desired_num_prospects","defaultMatch":false,"canBeUsedToMatch":true},{"id":"additional_keywords","type":"string","display":true,"removed":false,"required":false,"displayName":"additional_keywords","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false}},"typeVersion":2.2},{"id":"2b29393a-1ffe-494c-9ab3-803da13efbc9","name":"prospect_discovery_agent","type":"@n8n/n8n-nodes-langchain.agent","position":[240,1180],"parameters":{"text":"=Based on the provided business type, location, desired number of prospects, and any additional keywords, identify a list of potential business prospects including their names and website URLs.\n\nbusiness_type: {{ $('prospect_discovery_workflow').item.json.business_type || 'Not specified' }}\nlocation_query: {{ $('prospect_discovery_workflow').item.json.location_query || 'Not specified' }}\ndesired_num_prospects: {{ Number($('prospect_discovery_workflow').item.json.desired_num_prospects) || 1 }}\nadditional_keywords: {{ $('prospect_discovery_workflow').item.json.additional_keywords || 'None' }}","options":{"systemMessage":"=You are an AI Prospecting Specialist. Your mission is to identify a specified number of potential business prospects. For EACH prospect you identify, you must gather key details including their official name, website URL, a brief description of their services, a key contact person/owner (if discoverable), and a business phone number (if discoverable). This process is guided by the `business_type`, `location_query`, `desired_num_prospects`, and optional `additional_keywords` you receive. Your final output must be a structured JSON array of these detailed prospect profiles.\n\n**Inputs You Will Receive:**\n*   `business_type`: (string) The category or type of business to search for (e.g., \"crane hire company\", \"artisan bakery\").\n*   `location_query`: (string) A description of the target geographical area (e.g., \"Newcastle NSW Australia\", \"downtown San Francisco\"). This is crucial.\n*   `desired_num_prospects`: (number) The target number of unique, well-profiled prospects.\n*   `additional_keywords`: (string, optional) Other terms to refine the search.\n\n**Your Operational Protocol:**\n\n**Phase 1: Initial Prospect Candidate Identification**\n1.  **Formulate Broad Search Queries:** Combine `business_type`, `location_query`, and `additional_keywords`. Examples: \"list of `[business_type]` in `[location_query]` `[additional_keywords]`\", \"top `[business_type]` `[location_query]`\".\n2.  **Use Search Tools for Candidate List:**\n    *   Primarily use `brave_web_search` (e.g., with `count: 10` or `15`) and/or `google_gemini_prospect_finder` for these broad queries.\n    *   **Goal:** From search result snippets and titles, extract a working list of potential company names and their website URLs. Aim for slightly more candidates than `desired_num_prospects` initially (e.g., if targeting 3, find 5-7).\n\n**Phase 2: Detailed Profiling of Selected Candidates**\nIterate through your initial list of candidates. For each candidate, attempt to build a detailed profile until you have successfully profiled up to `desired_num_prospects` businesses.\n\nFor each candidate business from Phase 1:\n1.  **Confirm Official Name & Primary Website URL:**\n    *   If not perfectly clear, use a targeted `brave_web_search` (e.g., `{\"query\": \"[Candidate Company Name from initial list] official website\"}`) or `brave_local_search` (e.g., `{\"query\": \"[Candidate Company Name from initial list] [location_query]\"}`).\n    *   If a clear official website cannot be confidently found, consider skipping this candidate for detailed profiling.\n\n2.  **Gather Key Business Details (once website is confirmed):**\n    *   **Website Content Analysis (`jina_ai_web_page_scraper`):**\n        *   **Tool Input:** `{\"url\": \"[Prospect's Confirmed Website URL]\"}`. Prioritize scraping 'About Us', 'Contact Us', or 'Services' pages if their URLs are identifiable or inferable. If not, scrape the homepage.\n        *   **Information to Extract:** A brief description of their services/business focus; contact phone numbers; general email addresses (like info@, sales@); names of owners, founders, or key management.\n        *   **Usage Note:** Be judicious. If a site is very large, focus on 1-2 key pages.\n    *   **Targeted Information Search (using `google_gemini_prospect_finder` or `brave_local_search`):**\n        *   **Tool Inputs:** Formulate precise queries.\n            *   `google_gemini_prospect_finder`: e.g., `{\"query\": \"owner of [Prospect Name]\"}` or `{\"query\": \"contact phone [Prospect Name] [location_query]\"}`. If a key person's name is found from scraping: `{\"query\": \"[Key Person Name] [Prospect Name] LinkedIn\"}`.\n            *   `brave_local_search`: e.g., `{\"query\": \"[Prospect Name] [location_query]\"}` (can yield listed phone, address).\n        *   **Goal:** Find/confirm phone numbers, identify contact persons, and verify service descriptions.\n\n3.  **Synthesize and Construct Profile for Current Prospect:**\n    *   Compile all verified information for the current prospect.\n    *   If essential details (e.g., a verifiable phone number or a clear description of services that matches the `business_type`) cannot be found after reasonable attempts, you may discard this candidate and move to the next from your initial list. Aim for quality profiles.\n\n**Phase 3: Final Output Generation**\n1.  **Format as JSON Array:** Your final output MUST be a JSON array containing one object for each successfully profiled prospect.\n    ```json\n    [\n      {\n        \"business_name\": \"Example Crane Hire Pty Ltd\",\n        \"website_url\": \"https://www.examplecrane.com.au\",\n        \"description\": \"Provides crane rental and lifting services for construction projects in Newcastle.\",\n        \"key_contact_owner\": \"John Smith (Owner/Operator)\", // Or \"Contact: Operations Manager\", or \"N/A\" if not found\n        \"phone_number\": \"02-1234-5678\", // Or \"N/A\" if not found\n        \"contact_email\": \"info@examplecrane.com.au\", // Or \"N/A\" if not found\n        \"linkedin_profile\": \"https://linkedin.com/in/johnsmithcrane\" // Or \"N/A\" if not found\n      }\n      // ... up to desired_num_prospects objects\n    ]\n    ```\n2.  **Return ONLY the JSON Array:** No introductory text, no \"Here is the list:\", just the array itself.\n3.  **Empty Array for No Valid Results:** If no prospects can be adequately profiled up to `desired_num_prospects`, return an empty array: `[]`.\n\n**Critical: Tool Input Precision:**\n*   When preparing to call ANY tool (`brave_web_search`, `google_gemini_prospect_finder`, `brave_local_search`, `jina_ai_web_page_scraper`), the JSON input you generate for that tool MUST strictly match its expected schema.\n    *   `brave_web_search`: Expects `{\"query\": \"string\", \"count\": number (optional), \"offset\": number (optional)}`.\n    *   `google_gemini_prospect_finder`: Expects `{\"query\": \"string\", \"organization\": \"string (optional)\", \"restrictUrls\": \"string (optional)\"}`.\n    *   `brave_local_search`: Expects `{\"query\": \"string\", \"count\": number (optional)}`.\n    *   `jina_ai_web_page_scraper`: Expects `{\"url\": \"string\"}`.\n*   **Always ensure all required parameters for a tool are present in your generated input, and that data types are correct (strings are quoted, numbers are not).** Mistakes here will cause schema errors.\n\n**Priorities:**\n*   **Actionable Contact Details:** For each profiled prospect, strive to find a business phone number. A key contact/owner is highly desirable.\n*   **Relevance:** Profiled businesses must genuinely match the `business_type` in the `location_query`.\n*   **Accuracy:** Verify information where possible. If a detail is uncertain or cannot be found, use \"N/A\" or a similar indicator in the output JSON."},"promptType":"define"},"typeVersion":2},{"id":"d54d6483-54bc-45b3-9a2b-05767176aa08","name":"prospect_discovery_workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[-500,1180],"parameters":{"workflowInputs":{"values":[{"name":"business_type"},{"name":"location_query"},{"name":"desired_num_prospects"},{"name":"additional_keywords"}]}},"typeVersion":1.1},{"id":"4c2d5725-1e5b-4ca5-b030-6be6cb28638c","name":"google_gemini_prospect_finder","type":"n8n-nodes-gemini-search.geminiSearchToolTool","position":[2300,1300],"parameters":{"model":"gemini-2.5-flash-preview-05-20","query":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Query', `Formulate a search query aimed at discovering multiple businesses of a certain type within a geographical area or industry. Examples: \"Find crane hire companies operating in Newcastle, Australia\", \"List software development agencies in London focusing on fintech\", \"What are some popular artisan bakeries in San Francisco's Mission District?\".`, 'string') }}","options":{"extractSourceUrl":true},"organization":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Organization_Context', `(Optional) Provide an industry or general business type as context if not already clear in the main query. Example: 'logistics companies', 'eco-friendly retail'. Less about a specific business name here, more about the category.`, 'string') }}","restrictUrls":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Restrict_Search_to_URLs', `(Optional and use sparingly for discovery) Provide a comma-separated list of specific website URLs ONLY if you are trying to find businesses listed on a known, relevant directory (e.g., 'yellowpages.com.au', 'clutch.co'). Generally, for broad discovery, leave blank.`, 'string') }}","toolDescription":"Leverages Google's Gemini model for advanced, context-aware searching to identify potential business prospects. Use this to find lists of businesses by type and location, discover companies mentioned in relevant articles, or to perform more nuanced queries for business discovery when standard search isn't sufficient. Can help identify multiple potential leads rather than a single specific entity. Key Parameters: 'query' (string), 'organization' (can be used for industry context), 'restrictUrls' (rarely used for discovery unless searching specific directories)."},"credentials":{"geminiSearchApi":{"id":"grHOyabfaEb2A17I","name":"Gemini Credentials account"}},"typeVersion":1},{"id":"f5d70acc-c6f9-4ce9-85d0-35c3c6403725","name":"Sticky Note19","type":"n8n-nodes-base.stickyNote","position":[-1940,-780],"parameters":{"color":7,"width":940,"height":1760,"content":"![MCP Usage Example](https://www.jezweb.com.au/wp-content/uploads/2025/06/prospect-discovery-01.png#full-width)"},"typeVersion":1}],"active":true,"settings":{"executionOrder":"v1"},"versionId":"fa334835-a924-4cd6-9835-73a02b7c3f02","connections":{"Simple Memory":{"ai_memory":[[{"node":"prospect_discovery_agent","type":"ai_memory","index":0}]]},"brave_web_search":{"ai_tool":[[{"node":"prospect_discovery_agent","type":"ai_tool","index":0}]]},"discover_prospect":{"ai_tool":[[{"node":"prospect_discovery","type":"ai_tool","index":0}]]},"brave_local_search":{"ai_tool":[[{"node":"prospect_discovery_agent","type":"ai_tool","index":0}]]},"Google Gemini Chat Model":{"ai_languageModel":[[{"node":"prospect_discovery_agent","type":"ai_languageModel","index":0}]]},"jina_ai_web_page_scraper":{"ai_tool":[[{"node":"prospect_discovery_agent","type":"ai_tool","index":0}]]},"prospect_discovery_workflow":{"main":[[{"node":"prospect_discovery_agent","type":"main","index":0}]]},"google_gemini_prospect_finder":{"ai_tool":[[{"node":"prospect_discovery_agent","type":"ai_tool","index":0}]]}}}


name: Generate Summaries from Uploaded Files using OpenAI Assistants API
author_name: Sam Robertson
author_username: samrobertson
nodes_used: ["n8n-nodes-base.httpRequest"]
categories: []
created_at: 2025-06-13T03:33:27.446Z
updated_at: 2025-06-13T03:33:27.446Z
url: https://n8n.io/workflows/4911
scraped_at: 2025-07-06 21:16:30
description:
  Generate Summaries from Uploaded Files using OpenAI Assistants API

  📑 Overview  
  Upload a document (PDF, DOCX, PPTX, TXT, CSV, JSON, or Markdown) and receive an AI-generated summary containing:

  title** – 5-10 words  
  summary** – 1-2 sentences  
  bullets** – 3-5 key points  
  tags** – 3-6 short keywords  

  The workflow:

  Stores the file in OpenAI.  
  Runs an Assistant with File Search and Code Interpreter enabled.  
  Polls until the run finishes.  
  Retrieves the summary JSON.

  ✅ Prerequisites  

  OpenAI Assistant
  Create one at &lt;https://platform.openai.com/assistants&gt;
  Enable File Search and Code Interpreter
  Note: The assistant ID starts with asst_

  OpenAI API credential setup in n8n
  Go to Credentials → New → HTTP Header Auth
  Header name: Authorization
  Value: Bearer YOUR-OPENAI-API-KEY (replace YOUR-OPENAI-API-KEY with your OpenAI API secret key for your assistant, starts with sk-)
  Name it: openAIApiHeader

  🔧 Setup  

  Import the workflow JSON.  
  When n8n prompts for a credential, choose openAIApiHeader for every HTTP Request node.  
  Open Run Assistant → Body and replace  

        "assistant_id": "REPLACE_WITH_YOUR_ASSISTANT_ID"
     
     with your real ID (starts with asst_…). Save.

  🚀 How it works  

  | # | Node | Purpose |
  |---|------|---------|
  | 1 | On form submission | User uploads a file (File). |
  | 2 | Upload File | POST /v1/files (multipart) → returns file_id. |
  | 3 | Create Thread | Creates a thread and attaches the uploaded file. |
  | 4 | Run Assistant | Starts the run using your assistant_id. |
  | 5 | Poll Run Status → Wait 2 s → IF | Loops until status = completed. |
  | 6 | Fetch Summary | GET /v1/threads/{thread_id}/messages → summary JSON. |

  🖌️ Customisation ideas  

  Edit the user prompt in Create Thread to change summary length, tone, or language.  
  Add an HTTP Response node after Fetch Summary to return plaintext to the uploader.  
  Replace the polling loop with OpenAI’s forthcoming wait-for-run endpoint when available.

  No community nodes required. Works on any n8n Cloud plan (Starter, Pro, Enterprise) or self-hosted Community Edition.

workflow_json:
  {"id":"fXtw0Iqzc5X1fyPf","meta":{"instanceId":"ff48f7ccab544841a640404b50e0fa0da433887df04172f71a32d80a79b0fa7d","templateCredsSetupCompleted":true},"name":"Generate Summaries From Uploaded Files","tags":[],"nodes":[{"id":"e8d5aaf3-8ef3-4b66-8d61-1a8eedde36ca","name":"On form submission","type":"n8n-nodes-base.formTrigger","position":[140,100],"webhookId":"2c3f820b-8b84-41d8-bc1a-1e33f9bb7bfd","parameters":{"path":"2c3f820b-8b84-41d8-bc1a-1e33f9bb7bfd","options":{},"formTitle":"Upload Form","formFields":{"values":[{"fieldType":"file","fieldLabel":"File","multipleFiles":false,"requiredField":true}]}},"typeVersion":2},{"id":"d7817690-47d2-491d-8819-373bb5402daf","name":"Create Thread","type":"n8n-nodes-base.httpRequest","position":[540,100],"parameters":{"url":"https://api.openai.com/v1/threads","options":{},"requestMethod":"POST","authentication":"headerAuth","jsonParameters":true,"bodyParametersJson":"={\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"Summarize the attached file.\",\n      \"attachments\": [\n        {\n          \"file_id\": \"{{$node['Upload File'].json['id']}}\",\n          \"tools\": [ { \"type\": \"file_search\" } ]\n        }\n      ]\n    }\n  ]\n}","headerParametersJson":"{\n  \"OpenAI-Beta\": \"assistants=v2\"\n}"},"credentials":{"httpHeaderAuth":{"name":"openAIApiHeader"}},"typeVersion":1},{"id":"5b93297d-c354-410a-a19e-5f7e3993ba32","name":"Poll Run Status","type":"n8n-nodes-base.httpRequest","position":[140,320],"parameters":{"url":"=https://api.openai.com/v1/threads/{{$node[\"Create Thread\"].json[\"id\"]}}/runs/{{$node[\"Run Assistant\"].json[\"id\"]}}","options":{},"authentication":"headerAuth","headerParametersUi":{"parameter":[{"name":"OpenAI-Beta","value":"assistants=v2"}]}},"credentials":{"httpHeaderAuth":{"name":"openAIApiHeader"}},"typeVersion":1},{"id":"d6b28a0e-1468-4dbc-b193-7a7f5b6c7e99","name":"Is Not Complete?","type":"n8n-nodes-base.if","position":[340,320],"parameters":{"conditions":{"string":[{"value1":"={{ $node[\"Poll Run Status\"].json[\"status\"] }}","value2":"completed","operation":"notEqual"}]}},"typeVersion":1},{"id":"88db0070-35f4-4fd7-9e51-8a30bd18bc23","name":"Wait 2s","type":"n8n-nodes-base.wait","position":[540,300],"webhookId":"b4801f60-2351-4ffb-9d70-da37524204fa","parameters":{"unit":"seconds","amount":2},"typeVersion":1},{"id":"9ea51b21-08e3-4a28-b8f5-fd85758e46f9","name":"Fetch Summary","type":"n8n-nodes-base.httpRequest","position":[720,340],"parameters":{"url":"=https://api.openai.com/v1/threads/{{$node[\"Create Thread\"].json[\"id\"]}}/messages","options":{},"authentication":"headerAuth","jsonParameters":true,"headerParametersJson":"{\n  \"OpenAI-Beta\": \"assistants=v2\"\n}"},"credentials":{"httpHeaderAuth":{"name":"openAIApiHeader"}},"typeVersion":1},{"id":"14fdac82-a66a-493e-a8ed-74bdda5ea316","name":"Run Assistant","type":"n8n-nodes-base.httpRequest","position":[720,100],"parameters":{"url":"=https://api.openai.com/v1/threads/{{$node[\"Create Thread\"].json[\"id\"]}}/runs","method":"POST","options":{},"jsonBody":"{\n  \"assistant_id\": \"REPLACE_WITH_YOUR_ASSISTANT_ID\",\n  \"instructions\": \"You are an AI knowledge-base assistant.\\n\\nFor every file provided (PDF, DOCX, slides, or an audio/video transcript) return a single, valid JSON object with exactly these keys:\\n{\\n  \\\"title\\\": string,\\n  \\\"summary\\\": string,\\n  \\\"bullets\\\": string[],\\n  \\\"tags\\\": string[]\\n}\\n• Read or transcribe the entire file first.\\n• Do not add any extra keys, comments, or explanatory text.\\n• If the file is audio or video, transcribe it before summarizing.\\n• If the file type is unsupported (e.g., pure image), reply with:\\n  { \\\"error\\\": \\\"unsupported_file_type\\\" }\\n• Return **only** the JSON object—nothing else.\"\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","headerParameters":{"parameters":[{"name":"OpenAI-Beta","value":"assistants=v2"}]}},"credentials":{"httpHeaderAuth":{"name":"openAIApiHeader"}},"typeVersion":4.2},{"id":"fabdc95f-4bfd-41c3-8f1b-3b74ee6513fd","name":"Upload File","type":"n8n-nodes-base.httpRequest","position":[340,100],"parameters":{"url":"https://api.openai.com/v1/files","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","sendHeaders":true,"authentication":"genericCredentialType","bodyParameters":{"parameters":[{"name":"file","parameterType":"formBinaryData","inputDataFieldName":"File"},{"name":"purpose","value":"assistants"}]},"genericAuthType":"httpHeaderAuth","headerParameters":{"parameters":[{"name":"OpenAI-Beta","value":"assistants=v2"}]}},"credentials":{"httpHeaderAuth":{"name":"openAIApiHeader"}},"typeVersion":4.2}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"a9a89fc0-37bf-43ba-bae3-97b159f84a27","connections":{"Wait 2s":{"main":[[{"node":"Poll Run Status","type":"main","index":0}]]},"Upload File":{"main":[[{"node":"Create Thread","type":"main","index":0}]]},"Create Thread":{"main":[[{"node":"Run Assistant","type":"main","index":0}]]},"Run Assistant":{"main":[[{"node":"Poll Run Status","type":"main","index":0}]]},"Poll Run Status":{"main":[[{"node":"Is Not Complete?","type":"main","index":0}]]},"Is Not Complete?":{"main":[[{"node":"Wait 2s","type":"main","index":0}],[{"node":"Fetch Summary","type":"main","index":0}]]},"On form submission":{"main":[[{"node":"Upload File","type":"main","index":0}]]}}}


name: Lead Workflow: Yelp & Trustpilot Scraping + OpenAI Analysis via BrightData
author_name: Incrementors
author_username: incrementors
categories: []
created_at: 2025-06-13T04:57:33.354Z
updated_at: 2025-06-13T04:57:33.354Z
url: https://n8n.io/workflows/4912
scraped_at: 2025-07-06 21:16:30
description:
  🛒 Lead Workflow: Yelp & Trustpilot Scraping + OpenAI Analysis via BrightData

  &gt; Description: Automated lead generation workflow that scrapes business data from Yelp and Trustpilot based on location and category, analyzes credibility, and sends personalized outreach emails using AI.

  &gt; ⚠️ Important: This template requires a self-hosted n8n instance to run.

  📋 Overview

  This workflow provides an automated lead generation solution that identifies high-quality prospects from Yelp and Trustpilot, analyzes their credibility through reviews, and sends personalized outreach emails. Perfect for digital marketing agencies, sales teams, and business development professionals.

  ✨ Key Features

  🎯 Smart Location Analysis**  
    AI breaks down cities into sub-locations for comprehensive coverage

  🛍 Yelp Integration**  
    Scrapes business details using BrightData's Yelp dataset

  ⭐ Trustpilot Verification**  
    Validates business credibility through review analysis

  📊 Data Storage**  
    Automatically saves results to Google Sheets

  🤖 AI-Powered Outreach**  
    Generates personalized emails using Claude AI

  📧 Automated Sending**  
    Sends emails directly through Gmail integration

  🔄 How It Works

  User Input: Submit location, country, and business category through a form  
  AI Location Analysis: Gemini AI identifies sub-locations within the specified area  
  Yelp Scraping: BrightData extracts business information from multiple locations  
  Data Processing: Cleans and stores business details in Google Sheets  
  Trustpilot Verification: Scrapes reviews and company details for credibility check  
  Email Generation: Claude AI creates personalized outreach messages  
  Automated Outreach: Sends emails to qualified prospects via Gmail

  📊 Data Output

  | Field         | Description                      | Example                          |
  |---------------|----------------------------------|----------------------------------|
  | Company Name  | Business name from Yelp/Trustpilot | Best Local Restaurant            |
  | Website       | Company website URL              | https://example-restaurant.com   |
  | Phone Number  | Business contact number          | (555) 123-4567                   |
  | Email         | Business email address           | demo@example.com                 |
  | Address       | Physical business location       | 123 Main St, City, State         |
  | Rating        | Overall business rating          | 4.5/5                            |
  | Categories    | Business categories/tags         | Restaurant, Italian, Fine Dining |

  🚀 Setup Instructions

  ⏱️ Estimated Setup Time: 10–15 minutes

  Prerequisites

  n8n instance (self-hosted or cloud)
  Google account with Sheets access
  BrightData account with Yelp and Trustpilot datasets
  Google Gemini API access
  Anthropic API key for Claude
  Gmail account for sending emails

  Step 1: Import the Workflow

  Copy the JSON workflow code  
  In n8n: Workflows → + Add workflow → Import from JSON  
  Paste JSON and click Import

  Step 2: Configure Google Sheets Integration

  Create two Google Sheets:  
     Yelp data: Name, Categories, Website, Address, Phone, URL, Rating  
     Trustpilot data: Company Name, Email, Phone Number, Address, Rating, Company About
  Copy Sheet IDs from URLs  
  In n8n: Credentials → + Add credential → Google Sheets OAuth2 API  
  Complete OAuth setup and test connection  
  Update all Google Sheets nodes with your Sheet IDs

  Step 3: Configure BrightData

  Set up BrightData credentials in n8n  
  Replace API token with: BRIGHT_DATA_API_KEY  
  Verify dataset access:  
     Yelp dataset: gd_lgugwl0519h1p14rwk  
     Trustpilot dataset: gd_lm5zmhwd2sni130p  
  Test connections

  Step 4: Configure AI Models

  Google Gemini (Location Analysis)**  
    Add Google Gemini API credentials  
    Configure model: models/gemini-1.5-flash

  Claude AI (Email Generation)**  
    Add Anthropic API credentials  
    Configure model: claude-sonnet-4-20250514

  Step 5: Configure Gmail Integration

  Set up Gmail OAuth2 credentials in n8n  
  Update "Send Outreach Email" node  
  Test email sending

  Step 6: Test & Activate

  Activate the workflow  
  Test with sample data:  
     Country: United States  
     Location: Dallas  
     Category: Restaurants  
  Verify data appears in Google Sheets  
  Check that emails are generated and sent

  📖 Usage Guide

  Starting a Lead Generation Campaign

  Access the form trigger URL  
  Enter your target criteria:  
     Country: Target country  
     Location: City or region  
     Category: Business type (e.g., restaurants)  
  Submit the form to start the process

  Monitoring Results

  Yelp Data Sheet:** View scraped business information  
  Trustpilot Sheet:** Review credibility data  
  Gmail Sent Items:** Track outreach emails sent

  🔧 Customization Options

  Modifying Email Templates

  Edit the "AI Generate Email Content" node to customize:

  Email tone and style  
  Services mentioned  
  Call-to-action messages  
  Branding elements

  Adjusting Data Filters

  Modify rating thresholds  
  Set minimum review counts  
  Add geographic restrictions  
  Filter by business size

  Scaling the Workflow

  Increase batch sizes  
  Add delays between requests  
  Use parallel processing  
  Add error handling

  🚨 Troubleshooting

  Common Issues & Solutions

  1. BrightData Connection Failed  
  Cause: Invalid API credentials or dataset access  
  Solution: Verify credentials and dataset permissions

  2. No Data Extracted  
  Cause: Invalid location or changed page structure  
  Solution: Verify location names and test other categories

  3. Gmail Authentication Issues  
  Cause: Expired OAuth tokens  
  Solution: Re-authenticate and check permissions

  4. AI Model Errors  
  Cause: API quota exceeded or invalid keys  
  Solution: Check usage limits and API key

  Performance Optimization

  Rate Limiting:** Add delays  
  Error Handling:** Retry failed requests  
  Data Validation:** Check for malformed data  
  Memory Management:** Process in smaller batches

  📈 Use Cases & Examples

  1. Digital Marketing Agency Lead Generation

  Goal:** Find businesses needing marketing  
  Target:** Restaurants, retail stores  
  Approach:** Focus on good-rated but low-online-presence businesses

  2. B2B Sales Prospecting

  Goal:** Find software solution clients  
  Target:** Growing businesses  
  Approach:** Focus on recent positive reviews

  3. Partnership Development

  Goal:** Find complementary businesses  
  Target:** Established businesses  
  Approach:** Focus on reputation and satisfaction scores

  ⚡ Performance & Limits

  Expected Performance

  Processing Time:** 5–10 minutes/location  
  Data Accuracy:** 90%+  
  Success Rate:** 85%+  
  Daily Capacity:** 100–500 leads

  Resource Usage

  API Calls:** ~10–20 per business  
  Storage:** Minimal (Google Sheets)  
  Execution Time:** 3–8 minutes/10 businesses  
  Network Usage:** ~5–10MB/business

  🤝 Support & Community

  Getting Help

  n8n Community Forum:** community.n8n.io  
  Docs:** docs.n8n.io  
  BrightData Support:** Via dashboard

  Contributing

  Share improvements  
  Report issues and suggestions  
  Create industry-specific variations  
  Document best practices

  &gt; 🔒 Privacy & Compliance: Ensure GDPR/CCPA compliance. Always respect robots.txt and terms of service of scraped sites.

  🎯 Ready to Generate Leads!

  This workflow provides a complete solution for automated lead generation and outreach. Customize it to fit your needs and start building your pipeline today!

  For any questions or support, please contact:  
  📧 info@incrementors.com  
  or fill out this form: Contact Us

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","@n8n/n8n-nodes-langchain.lmChatGoogleGemini"]

workflow_json:
  {"id":"bCzsdWA9ELzYNPUy","meta":{"instanceId":"bc8ca75c203589705ae2e446cad7181d6f2a7cc1766f958ef9f34810e53b8cb2","templateCredsSetupCompleted":true},"name":"Lead Workflow: Yelp & Trustpilot Scraping + OpenAI Analysis via BrightData","tags":[],"nodes":[{"id":"607d9645-e0ef-47a3-985d-15b50ffc522a","name":"Form Trigger - Get User Input","type":"n8n-nodes-base.formTrigger","position":[-640,-3320],"webhookId":"37d0e84c-0cda-47f8-826d-9ae5b22ba1d5","parameters":{"options":{},"formTitle":"YelpDataScraper","formFields":{"values":[{"fieldLabel":"country"},{"fieldLabel":"category "},{"fieldLabel":"location"}]}},"typeVersion":2.2},{"id":"80bd12f9-5fd0-4255-9834-d80838dfcba2","name":"AI Location Analyzer","type":"@n8n/n8n-nodes-langchain.agent","position":[-340,-3460],"parameters":{"text":"=You are an intelligent assistant helping to guide in location like i will give me some details like country location and business category so what you have to do give me some location names based in location (city).\n\nhere are some details:\n- Country: {{ $json.country }}\n- Location: {{ $json.location }}\n- Category: {{ $json['category '] }}\n\nnow analyse this city and find some sub placeces in this city and give me their name commas seperated for example we have a city Fort Worth so in Fort Worth there are many famous location or areas so you have to give some location and area name in this city.\n\n- ouput should be comma seperated.\n- do not include intro outro supporting text.\n- dont use special characters like $,*,# and more.","options":{},"promptType":"define"},"typeVersion":2},{"id":"7b6d4d3d-a76e-4b2f-8e75-d4a68da0b572","name":"Split Sub-locations","type":"n8n-nodes-base.code","position":[160,-3520],"parameters":{"jsCode":"// Get the input data\nconst category = $('Form Trigger - Get User Input').first().json['category '];\nconst country = $('Form Trigger - Get User Input').first().json.country;\nconst aiOutput = $input.first().json.output;\n\n// Clean and split the AI output to get individual locations\nconst locationsString = aiOutput.replace(/[{}]/g, '').trim(); // Remove curly braces\nconst locations = locationsString\n  .split(',')\n  .map(location => location.trim())\n  .filter(location => location.length > 0); // Remove empty strings\n\n// Create output array with each location as a separate item\nconst output = locations.map((location, index) => {\n  return {\n    id: index + 1,\n    category: category,\n    country: country,\n    location: location\n  };\n});\n\n// Return the transformed data\nreturn output;"},"typeVersion":2},{"id":"a82eeee9-66df-45ce-8604-4685bab3a67f","name":"Loop Yelp Locations","type":"n8n-nodes-base.splitInBatches","position":[460,-3520],"parameters":{"options":{}},"typeVersion":3},{"id":"304e8b0e-6c0d-48aa-b67a-2f37dd5a2c49","name":"Yelp Scraper","type":"n8n-nodes-base.httpRequest","position":[560,-3360],"parameters":{"url":"https://api.brightdata.com/datasets/v3/trigger","method":"POST","options":{},"jsonBody":"={\n  \"input\": [\n    {\n      \"country\": \"{{ $json.country }}\",\n      \"location\": \"{{ $json.location }}\",\n      \"category\": \"{{ $json.category }}\"\n    }\n  ],\n  \"custom_output_fields\": [\n    \"name\",\n    \"overall_rating\",\n    \"reviews_count\",\n    \"categories\",\n    \"website\",\n    \"phone_number\",\n    \"address\",\n    \"url\"\n  ]\n}\n","sendBody":true,"sendQuery":true,"sendHeaders":true,"specifyBody":"json","queryParameters":{"parameters":[{"name":"dataset_id","value":"gd_lgugwl0519h1p14rwk"},{"name":"include_errors","value":"true"},{"name":"type","value":"discover_new"},{"name":"discover_by","value":"search_filters"},{"name":"limit_per_input","value":"10"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"2afb35ee-9881-4bff-9267-eb754203e232","name":"Check Yelp Scrape Progress","type":"n8n-nodes-base.httpRequest","position":[760,-3360],"parameters":{"url":"=https://api.brightdata.com/datasets/v3/progress/{{ $json.snapshot_id }}","options":{},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2,"alwaysOutputData":true},{"id":"892f2e2e-9171-4c87-99e3-468c4621ee28","name":"Wait (1 min) Yelp Completion","type":"n8n-nodes-base.wait","position":[960,-3360],"webhookId":"10b45556-5e91-4387-abd0-f9078b220286","parameters":{"unit":"minutes","amount":1},"typeVersion":1.1},{"id":"a2deac3d-eb34-49bd-9c1b-f940ec59887b","name":"Verify Yelp Ready","type":"n8n-nodes-base.if","position":[1200,-3360],"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":"3557f70e-29e6-4655-919a-997b9b905450","name":"If Yelp Has Records","type":"n8n-nodes-base.if","position":[1420,-3380],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"80b55138-4007-47ce-9e4a-bf001c875047","operator":{"type":"number","operation":"notEquals"},"leftValue":"={{ $json.records }}","rightValue":0}]}},"typeVersion":2.2},{"id":"53b7ba95-719c-4161-a8c2-ccd45aaa9768","name":"Fetch Yelp Results","type":"n8n-nodes-base.httpRequest","position":[1660,-3400],"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":"430f7f49-c0b8-4e0e-b217-d5b5831062e0","name":"Save Yelp Data to Sheet","type":"n8n-nodes-base.googleSheets","position":[1820,-3260],"parameters":{"columns":{"value":{"URL":"={{ $json.url }}","name":"={{ $json.name }}","address":"={{ $json.address }}","Phone No":"={{ $json.phone_number }}","categories":"={{ $json.categories }}","overall_rating":"={{ $json.name }}","Company Website":"={{ $json.website }}"},"schema":[{"id":"overall_rating","type":"string","display":true,"required":false,"displayName":"overall_rating","defaultMatch":false,"canBeUsedToMatch":true},{"id":"URL","type":"string","display":true,"required":false,"displayName":"URL","defaultMatch":false,"canBeUsedToMatch":true},{"id":"name","type":"string","display":true,"required":false,"displayName":"name","defaultMatch":false,"canBeUsedToMatch":true},{"id":"categories","type":"string","display":true,"required":false,"displayName":"categories","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Phone No","type":"string","display":true,"required":false,"displayName":"Phone No","defaultMatch":false,"canBeUsedToMatch":true},{"id":"address","type":"string","display":true,"required":false,"displayName":"address","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Company Website","type":"string","display":true,"required":false,"displayName":"Company Website","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/GOOGLE_SHEET_ID_PLACEHOLDER/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1hJD3mDpa93IvPrnvo29FFfqQWEAjGHA_wGG5hfIlqlk","cachedResultUrl":"https://docs.google.com/spreadsheets/d/GOOGLE_SHEET_ID_PLACEHOLDER/edit?usp=drivesdk","cachedResultName":"Lead Generator Finder"}},"credentials":{"googleSheetsOAuth2Api":{"id":"3GynTMfjoyPl1MTl","name":"Google Sheets-Aksh"}},"typeVersion":4.6},{"id":"70d7b107-8722-4269-8aaa-40c1c2f01ad6","name":"Clean Unique Websites","type":"n8n-nodes-base.code","position":[1760,-3540],"parameters":{"jsCode":"// Set to collect unique non-empty websites\nconst websites = new Set();\n\nfor (const item of items) {\n  const website = item.json[\"Company Website\"];\n  if (website && website.toString().trim() !== \"\") {\n    websites.add(website.toString().trim());\n  }\n}\n\n// Return one item per website\nreturn Array.from(websites).map(site => {\n  return {\n    json: {\n      website: site\n    }\n  };\n});\n"},"typeVersion":2,"alwaysOutputData":true},{"id":"1fa4c014-2c1b-4d9a-978f-cf16423fc88d","name":"Read Yelp Sheet Websites","type":"n8n-nodes-base.googleSheets","position":[2020,-3540],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/GOOGLE_SHEET_ID_PLACEHOLDER/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1hJD3mDpa93IvPrnvo29FFfqQWEAjGHA_wGG5hfIlqlk","cachedResultUrl":"https://docs.google.com/spreadsheets/d/GOOGLE_SHEET_ID_PLACEHOLDER/edit?usp=drivesdk","cachedResultName":"Lead Generator Finder"}},"credentials":{"googleSheetsOAuth2Api":{"id":"3GynTMfjoyPl1MTl","name":"Google Sheets-Aksh"}},"typeVersion":4.6,"alwaysOutputData":true},{"id":"092a5d61-79a4-4a73-8633-05d2a6482efc","name":"Make Trustpilot URLs","type":"n8n-nodes-base.code","position":[2200,-3540],"parameters":{"jsCode":"return items.map(item => {\n  const rawUrl = item.json[\"Company Website\"] || \"\";\n  const cleanDomain = rawUrl.replace(/^https?:\\/\\//, \"\").replace(/\\/$/, \"\");\n  const trustpilotUrl = `https://www.trustpilot.com/review/${cleanDomain}`;\n\n  return {\n    json: {\n      \"Trustpilot Website URL\": trustpilotUrl\n    }\n  };\n});\n"},"typeVersion":2},{"id":"6116588d-cb2c-4bc4-af6c-1a0b400f9cc4","name":"Remove Duplicate TP URLs","type":"n8n-nodes-base.code","position":[2440,-3180],"parameters":{"jsCode":"const seen = new Set();\nconst output = [];\n\nfor (const item of items) {\n  const url = item.json[\"Trustpilot Website URL\"];\n  \n  if (!seen.has(url)) {\n    seen.add(url);\n    output.push({ json: { \"Trustpilot Website URL\": url } });\n  }\n}\n\nreturn output;\n"},"typeVersion":2},{"id":"c0e0112a-d61a-4241-adaa-08844c77f3bc","name":"Loop Trustpilot URLs","type":"n8n-nodes-base.splitInBatches","position":[-420,-2740],"parameters":{"options":{}},"typeVersion":3},{"id":"1260b1be-baf0-4d4c-bde2-5a0479704730","name":"Trigger Trustpilot Scraper","type":"n8n-nodes-base.httpRequest","position":[-60,-2940],"parameters":{"url":"https://api.brightdata.com/datasets/v3/trigger","method":"POST","options":{},"jsonBody":"={\n  \"input\": [\n    {\n      \"url\": \"{{ $json[\"Trustpilot Website URL\"] }}\",\n      \"date_posted\": \"\"\n    }\n  ],\n  \"custom_output_fields\": [\n    \"company_name\",\n    \"review_id\",\n    \"review_date\",\n    \"review_rating\",\n    \"review_title\",\n    \"review_content\",\n    \"is_verified_review\",\n    \"review_date_of_experience\",\n    \"reviewer_location\",\n    \"reviews_posted_overall\",\n    \"review_replies\",\n    \"review_useful_count\",\n    \"reviewer_name\",\n    \"company_logo\",\n    \"url\",\n    \"company_rating_name\",\n    \"company_overall_rating\",\n    \"is_verified_company\",\n    \"company_total_reviews\",\n    \"5_star\",\n    \"4_star\",\n    \"3_star\",\n    \"2_star\",\n    \"1_star\",\n    \"company_about\",\n    \"company_email\",\n    \"company_phone\",\n    \"company_location\",\n    \"company_country\",\n    \"breadcrumbs\",\n    \"company_category\",\n    \"company_id\",\n    \"company_website\",\n    \"company activity\",\n    \"company_other_categories\",\n    \"review_url\",\n    \"date_posted\"\n  ]\n} ","sendBody":true,"sendQuery":true,"sendHeaders":true,"specifyBody":"json","queryParameters":{"parameters":[{"name":"dataset_id","value":"gd_lm5zmhwd2sni130p"},{"name":"include_errors","value":"true"},{"name":"limit_multiple_results","value":"2"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"7cae1204-b356-42e6-80cb-8333e676cb49","name":"Check Trustpilot Scrape Progress","type":"n8n-nodes-base.httpRequest","position":[200,-2940],"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":"d915bb86-bc43-4a7a-afb4-e5264b24e3a1","name":"Verify Trustpilot Scraper Ready","type":"n8n-nodes-base.if","position":[400,-2940],"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":"74fd5339-ef01-4aa2-9646-6ef9e65c9c31","name":"Wait (1 min) Trustpilot Completion","type":"n8n-nodes-base.wait","position":[560,-2840],"webhookId":"7047efad-de41-4608-b95c-d3e0203ef620","parameters":{"unit":"minutes","amount":1},"typeVersion":1.1},{"id":"e57b97a7-3904-453c-9fa9-a95e455a77c7","name":"If Trustpilot Has Records","type":"n8n-nodes-base.if","position":[940,-2820],"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":"40ff595d-c011-4cf8-8353-a97ecf2ecdde","name":"Download Trustpilot Data","type":"n8n-nodes-base.httpRequest","position":[1180,-2840],"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":"0b535959-7c31-44c9-8d2d-4f3428f4e8dc","name":"Save Trustpilot Data to Sheet","type":"n8n-nodes-base.googleSheets","position":[1460,-2840],"parameters":{"columns":{"value":{"Email":"={{ $json.company_email }}","Rating":"={{ $json.review_rating }}","Address":"={{ $json.company_location }}","Company Name":"={{ $json.company_name }}","Phone Number":"={{ $json.company_phone }}","Company About":"={{ $json.company_about }}"},"schema":[{"id":"Email","type":"string","display":true,"removed":false,"required":false,"displayName":"Email","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Phone Number","type":"string","display":true,"required":false,"displayName":"Phone Number","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Address","type":"string","display":true,"required":false,"displayName":"Address","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Rating","type":"string","display":true,"required":false,"displayName":"Rating","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Company Name","type":"string","display":true,"removed":false,"required":false,"displayName":"Company Name","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Company About","type":"string","display":true,"removed":false,"required":false,"displayName":"Company About","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"list","value":972788573,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/GOOGLE_SHEET_ID_PLACEHOLDER/edit#gid=972788573","cachedResultName":"Mail Scrap"},"documentId":{"__rl":true,"mode":"list","value":"1xkNBckPDGf4YR74bJQN07tAr3qlEoA-70pQc63nBqZ8","cachedResultUrl":"https://docs.google.com/spreadsheets/d/GOOGLE_SHEET_ID_PLACEHOLDER/edit?usp=drivesdk","cachedResultName":"Job Finder sheet"}},"credentials":{"googleSheetsOAuth2Api":{"id":"3GynTMfjoyPl1MTl","name":"Google Sheets-Aksh"}},"typeVersion":4.6,"alwaysOutputData":true},{"id":"7e4768b9-0932-4b7c-bdf5-5348cbecb2eb","name":"Read Emails from Trustpilot Sheet","type":"n8n-nodes-base.googleSheets","position":[1680,-2840],"parameters":{"options":{},"filtersUI":{"values":[{"lookupValue":"=demo@example.com","lookupColumn":"Email"}]},"sheetName":{"__rl":true,"mode":"list","value":972788573,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/GOOGLE_SHEET_ID_PLACEHOLDER/edit#gid=972788573","cachedResultName":"Mail Scrap"},"documentId":{"__rl":true,"mode":"list","value":"1xkNBckPDGf4YR74bJQN07tAr3qlEoA-70pQc63nBqZ8","cachedResultUrl":"https://docs.google.com/spreadsheets/d/GOOGLE_SHEET_ID_PLACEHOLDER/edit?usp=drivesdk","cachedResultName":"Job Finder sheet"}},"credentials":{"googleSheetsOAuth2Api":{"id":"3GynTMfjoyPl1MTl","name":"Google Sheets-Aksh"}},"typeVersion":4.6,"alwaysOutputData":true},{"id":"80e0f93f-5a25-40c5-9413-261781ddca4b","name":"Get Unique Emails","type":"n8n-nodes-base.code","position":[1880,-2840],"parameters":{"jsCode":"const seen = new Set();\nconst output = [];\n\nfor (const item of items) {\n  const email = item.json.Email;\n  if (!email || seen.has(email)) continue;\n\n  seen.add(email);\n\n  output.push({\n    json: {\n      email: email\n    }\n  });\n}\n\nreturn output;\n"},"typeVersion":2,"alwaysOutputData":true},{"id":"d7301840-e464-4394-ae16-c479a1508bb7","name":"AI Generate Email Content","type":"@n8n/n8n-nodes-langchain.agent","position":[2080,-2840],"parameters":{"text":"=`Write a friendly and professional outreach message from a digital marketing agency to the business\n\nThe message should offer services to help them boost their sales and services, such as SEO, ads, and website optimization.\n\nReturn the result in JSON format with:\n{\n  \"email\": \"{{ $json.email }}\"\n}`\n","options":{},"promptType":"define"},"typeVersion":2,"alwaysOutputData":true},{"id":"a1d9596c-c9cd-4111-8b78-8d101020dfa7","name":"Parse Email JSON","type":"n8n-nodes-base.code","position":[2480,-2840],"parameters":{"jsCode":"// Fix for parsing AI email output\ntry {\n    const output = $input.first().json.output;\n    \n    // Remove the ```json\\n prefix and ```\\n suffix if present\n    let cleanOutput = output;\n    if (output.startsWith('```json\\n')) {\n        cleanOutput = output.replace(/^```json\\n/, '').replace(/\\n```$/, '');\n    }\n    \n    // Parse the JSON\n    const parsed = JSON.parse(cleanOutput);\n    \n    // Return the email details as separate fields\n    return {\n        email: parsed.email || '',\n        subject: parsed.subject || '',\n        content: parsed.message || parsed.content || ''\n    };\n    \n} catch (error) {\n    // If JSON parsing fails, try to extract info using regex from the raw output\n    const output = $input.first().json.output;\n    \n    const emailMatch = output.match(/\"email\":\\s*\"([^\"]*)\"/);\n    const subjectMatch = output.match(/\"subject\":\\s*\"([^\"]*)\"/);\n    const messageMatch = output.match(/\"message\":\\s*\"([^\"]*(?:\\\\.[^\"]*)*)\"/);\n    \n    return {\n        email: emailMatch ? emailMatch[1] : '',\n        subject: subjectMatch ? subjectMatch[1] : '',\n        content: messageMatch ? messageMatch[1].replace(/\\\\n/g, '\\n').replace(/\\\\\"/g, '\"') : ''\n    };\n}"},"typeVersion":2},{"id":"38e46cfe-4fda-4b3d-9921-19a9f73848c1","name":"Send Outreach Email","type":"n8n-nodes-base.gmail","position":[2720,-2720],"webhookId":"51b5a9b3-7d26-4ea9-b507-206129cf9646","parameters":{"sendTo":"={{ $json.email }}","message":"={{ $json.content }}","options":{},"subject":"={{ $json.subject }}","emailType":"text"},"credentials":{"gmailOAuth2":{"id":"gVmVsyjENjEeeaq9","name":"Gmail - sender@example.com"}},"typeVersion":2.1},{"id":"ae6ec720-694f-43de-be99-fc9baee03622","name":"Gemini - Location AI Model","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[-360,-3260],"parameters":{"options":{},"modelName":"models/gemini-1.5-flash"},"credentials":{"googlePalmApi":{"id":"QEE7fHoS8DGBZLp5","name":"Google Gemini(PaLM) Api account 2"}},"typeVersion":1},{"id":"4882a0ef-e8f3-4954-b7bc-5aaaf9566d11","name":"Claude - Email AI Model","type":"@n8n/n8n-nodes-langchain.lmChatAnthropic","position":[2020,-2680],"parameters":{"model":{"__rl":true,"mode":"list","value":"claude-sonnet-4-20250514","cachedResultName":"Claude 4 Sonnet"},"options":{}},"credentials":{"anthropicApi":{"id":"ipIAoB1BlqWHYhi2","name":"Anthropic account 5"}},"typeVersion":1.3},{"id":"e7cfac25-d88e-4504-aaa6-1f74ac04b819","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[200,-3920],"parameters":{"color":4,"width":340,"content":"Make a Copy of This Google Sheet.\n\n(https://docs.google.com/spreadsheets/d/1hX0MD_BLVWuEaXwOjKtwrWsjsBzc32ZtFVjP7wVGQYI/edit?usp=drive_link)"},"typeVersion":1},{"id":"c2c6abba-589f-4e26-a5fc-a563ad3ee3ef","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[0,-4200],"parameters":{"color":7,"width":880,"height":520,"content":"Optimized Workflow Summary:\nThis automation identifies high-quality leads from Yelp and Trustpilot based on a user-submitted location and business category. It uses AI to break down the area into sub-locations, scrapes business details via BrightData, checks credibility through Trustpilot reviews, and stores the best matches in Google Sheets. Finally, AI generates personalized outreach emails, which are automatically sent via Gmail — enabling fully automated lead generation and email marketing with zero manual effort."},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"a4b1073a-b560-481c-9208-535aace8da01","connections":{"Yelp Scraper":{"main":[[{"node":"Check Yelp Scrape Progress","type":"main","index":0}]]},"Parse Email JSON":{"main":[[{"node":"Send Outreach Email","type":"main","index":0}]]},"Get Unique Emails":{"main":[[{"node":"AI Generate Email Content","type":"main","index":0}]]},"Verify Yelp Ready":{"main":[[{"node":"If Yelp Has Records","type":"main","index":0}],[{"node":"Check Yelp Scrape Progress","type":"main","index":0}]]},"Fetch Yelp Results":{"main":[[{"node":"Save Yelp Data to Sheet","type":"main","index":0}]]},"If Yelp Has Records":{"main":[[{"node":"Fetch Yelp Results","type":"main","index":0}],[]]},"Loop Yelp Locations":{"main":[[{"node":"Clean Unique Websites","type":"main","index":0}],[{"node":"Yelp Scraper","type":"main","index":0}]]},"Send Outreach Email":{"main":[[{"node":"Loop Trustpilot URLs","type":"main","index":0}]]},"Split Sub-locations":{"main":[[{"node":"Loop Yelp Locations","type":"main","index":0}]]},"AI Location Analyzer":{"main":[[{"node":"Split Sub-locations","type":"main","index":0}]]},"Loop Trustpilot URLs":{"main":[[],[{"node":"Trigger Trustpilot Scraper","type":"main","index":0}]]},"Make Trustpilot URLs":{"main":[[{"node":"Remove Duplicate TP URLs","type":"main","index":0}]]},"Clean Unique Websites":{"main":[[{"node":"Read Yelp Sheet Websites","type":"main","index":0}]]},"Claude - Email AI Model":{"ai_languageModel":[[{"node":"AI Generate Email Content","type":"ai_languageModel","index":0}]]},"Save Yelp Data to Sheet":{"main":[[{"node":"Loop Yelp Locations","type":"main","index":0}]]},"Download Trustpilot Data":{"main":[[{"node":"Save Trustpilot Data to Sheet","type":"main","index":0}]]},"Read Yelp Sheet Websites":{"main":[[{"node":"Make Trustpilot URLs","type":"main","index":0}]]},"Remove Duplicate TP URLs":{"main":[[{"node":"Loop Trustpilot URLs","type":"main","index":0}]]},"AI Generate Email Content":{"main":[[{"node":"Parse Email JSON","type":"main","index":0}]]},"If Trustpilot Has Records":{"main":[[{"node":"Download Trustpilot Data","type":"main","index":0}],[{"node":"Loop Trustpilot URLs","type":"main","index":0}]]},"Check Yelp Scrape Progress":{"main":[[{"node":"Wait (1 min) Yelp Completion","type":"main","index":0}]]},"Gemini - Location AI Model":{"ai_languageModel":[[{"node":"AI Location Analyzer","type":"ai_languageModel","index":0}]]},"Trigger Trustpilot Scraper":{"main":[[{"node":"Check Trustpilot Scrape Progress","type":"main","index":0}]]},"Wait (1 min) Yelp Completion":{"main":[[{"node":"Verify Yelp Ready","type":"main","index":0}]]},"Form Trigger - Get User Input":{"main":[[{"node":"AI Location Analyzer","type":"main","index":0}]]},"Save Trustpilot Data to Sheet":{"main":[[{"node":"Read Emails from Trustpilot Sheet","type":"main","index":0}]]},"Verify Trustpilot Scraper Ready":{"main":[[{"node":"If Trustpilot Has Records","type":"main","index":0}],[{"node":"Wait (1 min) Trustpilot Completion","type":"main","index":0}]]},"Check Trustpilot Scrape Progress":{"main":[[{"node":"Verify Trustpilot Scraper Ready","type":"main","index":0}]]},"Read Emails from Trustpilot Sheet":{"main":[[{"node":"Get Unique Emails","type":"main","index":0}]]},"Wait (1 min) Trustpilot Completion":{"main":[[{"node":"Check Trustpilot Scrape Progress","type":"main","index":0}]]}}}


name: Auto-Publish PR News Articles with Featured Images to WordPress from RSS
author_name: The Higher Pitch
author_username: digvijay
nodes_used: ["n8n-nodes-base.httpRequest","n8n-nodes-base.wordpress","n8n-nodes-base.code"]
categories: []
created_at: 2025-06-13T06:01:06.664Z
updated_at: 2025-06-13T06:01:06.664Z
url: https://n8n.io/workflows/4913
scraped_at: 2025-07-06 21:16:30
description:
  This workflow automates the process of publishing PR News articles to the WordPress website.

  🔧 How it works:

  Uses an RSS Feed Trigger to monitor new PR News articles.

  Extracts the article content and parses the featured image URL.

  Uploads the image to WordPress as a media item.

  Creates a new draft post on the WordPress site using the article's content and sets the uploaded image as the featured image.

  ✅ Features:

  Polls RSS feed every minute.

  Automatically extracts and sets featured images.

  Posts are created as drafts for editorial review.

  📝 Requirements:

  WordPress REST API access with media upload permission.

  Active WordPress credentials in n8n.

  Perfect for teams who want to streamline PR content publishing without manual effort.

workflow_json:
  {"id":"88x49jmELpXBXgy8","meta":{"instanceId":"ca7e4439d37f2d7ddaa363ea2b029357e1ee59824d58b9533ac05bf57f803d9d","templateCredsSetupCompleted":true},"name":"PR news post to Techeela Website","tags":[],"nodes":[{"id":"c762fb88-f496-4ff6-80fc-3da2047096d6","name":"RSS Feed Trigger","type":"n8n-nodes-base.rssFeedReadTrigger","position":[0,0],"parameters":{"feedUrl":"","pollTimes":{"item":[{"mode":"everyMinute"}]}},"typeVersion":1},{"id":"572e403a-ee70-46ee-ac24-45faf8fe1d98","name":"Wordpress","type":"n8n-nodes-base.wordpress","position":[440,0],"parameters":{"title":"={{ $json.title }}","additionalFields":{"format":"standard","status":"draft","content":"={{ $json.content }}","authorId":3,"categories":[1057],"postTemplate":{"values":{}}}},"credentials":{"wordpressApi":{"id":"","name":""}},"typeVersion":1},{"id":"2ff6ba75-5c55-4203-a670-f6688acf8520","name":"Code","type":"n8n-nodes-base.code","position":[220,0],"parameters":{"jsCode":"const items = $input.all();\nconst updatedItems = items.map((item) => {\n  const content = item?.json?.content;\n  const srcMatch = content.match(/src=\"(.*?)\"/);\n  item.json.imageSrc = srcMatch ? srcMatch[1] : \"\";\n  return item;\n});\nreturn updatedItems;\n"},"typeVersion":2},{"id":"1c0c60e0-0f1f-4f64-9186-5640599f62a7","name":"Upload Image to Wordpress","type":"n8n-nodes-base.httpRequest","position":[1040,0],"parameters":{"url":"https://xyz.com/wp-json/wp/v2/media","method":"POST","options":{},"sendBody":true,"contentType":"binaryData","sendHeaders":true,"authentication":"predefinedCredentialType","headerParameters":{"parameters":[{"name":"Content-Disposition","value":"=attachment; filename=\"cover-image-{{ $('Wordpress').item.json.id }}.jpeg\""}]},"inputDataFieldName":"data","nodeCredentialType":"wordpressApi"},"credentials":{"wordpressApi":{"id":"","name":"Wordpress Account"}},"typeVersion":4.2},{"id":"38326346-0f38-4491-b786-ee1e06b65f96","name":"Set Image on Wordpress Post","type":"n8n-nodes-base.httpRequest","position":[1240,0],"parameters":{"url":"=https://xyz.com/wp-json/wp/v2/posts/{{ $('Wordpress').item.json.id }}","method":"POST","options":{},"sendQuery":true,"authentication":"predefinedCredentialType","queryParameters":{"parameters":[{"name":"featured_media","value":"={{ $json.id }}"}]},"nodeCredentialType":"wordpressApi"},"credentials":{"wordpressApi":{"id":"","name":"Wordpress Account"}},"typeVersion":4.2},{"id":"45505c71-ff36-4f4c-be2c-bf705ae0a902","name":"GET Image","type":"n8n-nodes-base.httpRequest","position":[840,0],"parameters":{"url":"={{ $json['image-url'] }}","options":{}},"typeVersion":4.2},{"id":"6f1ff8bc-622d-49bb-a172-bf23b6e1baa3","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[200,-80],"parameters":{"width":1240,"height":280,"content":"## Set Image and Content In Techeela Wordpress Post"},"typeVersion":1},{"id":"8272d49e-cf24-43a0-b948-db29adf5a95f","name":"Set Image URL","type":"n8n-nodes-base.set","position":[640,0],"parameters":{"options":{},"assignments":{"assignments":[{"id":"1f0541df-05ab-4e3d-a5d8-3904579fc8a9","name":"image-url","type":"string","value":"={{ $('Code').item.json.imageSrc }}"}]}},"typeVersion":3.4},{"id":"f6685e58-6c23-495d-9b75-a8066eab8829","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-120,-80],"parameters":{"color":4,"width":280,"height":280,"content":"## Feed from PR Newswire\n"},"typeVersion":1}],"active":true,"settings":{"executionOrder":"v1"},"versionId":"71481a3f-f3d0-45aa-b039-5f2cdb2e5267","connections":{"Code":{"main":[[{"node":"Wordpress","type":"main","index":0}]]},"GET Image":{"main":[[{"node":"Upload Image to Wordpress","type":"main","index":0}]]},"Wordpress":{"main":[[{"node":"Set Image URL","type":"main","index":0}]]},"Set Image URL":{"main":[[{"node":"GET Image","type":"main","index":0}]]},"RSS Feed Trigger":{"main":[[{"node":"Code","type":"main","index":0}]]},"Upload Image to Wordpress":{"main":[[{"node":"Set Image on Wordpress Post","type":"main","index":0}]]}}}


name: Transform Images with AI Prompts using FLUX Kontext, Google Sheets and Drive
author_name: Davide
author_username: n3witalia
nodes_used: ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.googleDrive"]
categories: []
created_at: 2025-06-13T08:19:08.504Z
updated_at: 2025-06-13T08:19:08.504Z
url: https://n8n.io/workflows/4916
scraped_at: 2025-07-06 21:16:30
description:
  This workflow automates the generation of AI-enhanced, contextualized images using FLUX Kontext, based on prompts stored in a Google Sheet. The generated images are then saved to Google Drive, and their URLs are written back to the spreadsheet for easy access.

  Example

  Image:


  Prompt:
  The girl is lying on the bed and sleeping

  Result:

  Perfect for E-commerce and Social Media

  This workflow is especially useful for e-commerce businesses:

  Generate product images with dynamic backgrounds based on the use-case or season.
  Create contextual marketing visuals for ads, newsletters, or product pages.
  Scale visual content creation without the need for manual design work.

  How It Works  

  Trigger**: The workflow can be started manually (via "Test workflow") or scheduled at regular intervals (e.g., every 5 minutes) using the "Schedule Trigger" node.  
  Data Fetch**: The "Get new image" node retrieves a row from a Google Sheet where the "RESULT" column is empty. It extracts the prompt, image URL, output format, and aspect ratio for processing.  
  Image Generation**: The "Create Image" node sends a request to the FLUX Kontext API (fal.run) with the provided parameters to generate a new AI-contextualized image.  
  Status Check**: The workflow waits 60 seconds ("Wait 60 sec." node) before checking the status of the image generation request via the "Get status" node. If the status is "COMPLETED," it proceeds; otherwise, it loops back to wait.  
  Result Handling**: Once completed, the "Get Image Url" node fetches the generated image URL, which is then downloaded ("Get Image File"), uploaded to Google Drive ("Upload Image"), and the Google Sheet is updated with the result ("Update result").  

  Set Up Steps  
  To configure this workflow, follow these steps:  

  Google Sheet Setup:  
     Create a Google Sheet with columns for PROMPT, IMAGE URL, ASPECT RATIO, OUTPUT FORMAT, and RESULT (leave this empty).  
     Link the sheet in the "Get new image" and "Update result" nodes.  

  API Key Configuration:  
     Sign up at fal.ai to obtain an API key.  
     In the "Create Image" node, set the Header Auth with:  
       Name: Authorization  
       Value: Key YOURAPIKEY  

  Google Drive Setup:  
     Specify the target folder ID in the "Upload Image" node where generated images will be saved.  

  Schedule Trigger (Optional):  
     Adjust the "Schedule Trigger" node to run the workflow at desired intervals (e.g., every 5 minutes).  

  Test Execution:  
     Run the workflow manually via the "Test workflow" node to verify all steps function correctly.  

  Once configured, the workflow will automatically process pending prompts, generate images, and update the Google Sheet with results.

  Need help customizing?  
  Contact me for consulting and support or add me on Linkedin. 

workflow_json:
  {"id":"IctMuVMXlEownJe1","meta":{"instanceId":"a4bfc93e975ca233ac45ed7c9227d84cf5a2329310525917adaf3312e10d5462","templateCredsSetupCompleted":true},"name":"Generate AI Contextualize Images with FLUX Kontext","tags":[],"nodes":[{"id":"b0f612bd-9665-4607-81fd-5b6fbd9cb562","name":"When clicking ‘Test workflow’","type":"n8n-nodes-base.manualTrigger","position":[-140,660],"parameters":{},"typeVersion":1},{"id":"8f02f950-7ea3-4dfe-be9e-989f675080e0","name":"Get status","type":"n8n-nodes-base.httpRequest","position":[800,660],"parameters":{"url":"=https://queue.fal.run/fal-ai/flux-pro/requests/{{ $('Create Image').item.json.request_id }}/status ","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"daOZafXpRXLtoLUV","name":"Fal.run API"}},"typeVersion":4.2},{"id":"ec42f3a9-f489-4dcd-b606-e5dee097eea9","name":"Wait 60 sec.","type":"n8n-nodes-base.wait","position":[580,660],"webhookId":"8d37a81d-c373-479f-9cc6-42598c4f37e5","parameters":{"amount":60},"typeVersion":1.1},{"id":"8c927df4-9f70-4e91-940c-9c3a08394a8b","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-140,520],"parameters":{"rule":{"interval":[{"field":"minutes"}]}},"typeVersion":1.2},{"id":"19b6b133-842d-49e6-9fe4-3acb2afeac78","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-220,-500],"parameters":{"color":3,"width":740,"height":320,"content":"# Generate AI Contextualize Images with FLUX Kontext\n\n## Generate AI Contextualize Images in a scenario with FLUX Kontext and Save to Google Drive\n\nThis workflow automates the generation of **AI-enhanced, contextualized images using FLUX Kontext**, based on prompts stored in a Google Sheet. The generated images are then s**aved to Google Drive**, and their URLs are written back to the spreadsheet for easy access.\n\n\n\n\n"},"typeVersion":1},{"id":"de86c0a1-ad6f-4037-83a1-099b52b8ed8b","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-220,-140],"parameters":{"width":740,"height":220,"content":"## STEP 1 - GOOGLE SHEET\nCreate a [Google Sheet like this](https://docs.google.com/spreadsheets/d/1N1Yg7FA4tQ8mDll5HLKqwPBuHj31AGDKwzAOg8mLQKs/edit?usp=sharing).\n\nPlease insert:\n- in the \"PROMPT\" column the accurate description of the image you want to generate\n- in the \"IMAGE_URL\" starting image\n- in the \"ASPECT RATIO\" select the aspect ratio\n- in the \"OUTPU FORMAT\" select jpeg or png"},"typeVersion":1},{"id":"74a1a103-a662-4b03-97e6-1d557731c43e","name":"Completed?","type":"n8n-nodes-base.if","position":[1020,660],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"383d112e-2cc6-4dd4-8985-f09ce0bd1781","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"COMPLETED"}]}},"typeVersion":2.2},{"id":"8410d765-7507-4b14-b64c-429cb962db0a","name":"Update result","type":"n8n-nodes-base.googleSheets","position":[820,1000],"parameters":{"columns":{"value":{"RESULT":"={{ $('Get Image Url').item.json.images[0].url }}","row_number":"={{ $('Get new image').item.json.row_number }}"},"schema":[{"id":"IMAGE URL","type":"string","display":true,"removed":false,"required":false,"displayName":"IMAGE URL","defaultMatch":false,"canBeUsedToMatch":true},{"id":"PROMPT","type":"string","display":true,"removed":false,"required":false,"displayName":"PROMPT","defaultMatch":false,"canBeUsedToMatch":true},{"id":"ASCPECT RATIO","type":"string","display":true,"removed":false,"required":false,"displayName":"ASCPECT RATIO","defaultMatch":false,"canBeUsedToMatch":true},{"id":"OUTPUT FORMAT","type":"string","display":true,"removed":false,"required":false,"displayName":"OUTPUT FORMAT","defaultMatch":false,"canBeUsedToMatch":true},{"id":"RESULT","type":"string","display":true,"removed":false,"required":false,"displayName":"RESULT","defaultMatch":false,"canBeUsedToMatch":true},{"id":"row_number","type":"string","display":true,"removed":false,"readOnly":true,"required":false,"displayName":"row_number","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["row_number"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"update","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/11ebWJvwwXHgvQld9kxywKQUvIoBw6xMa0g0BuIqHDxE/edit#gid=0","cachedResultName":"Foglio1"},"documentId":{"__rl":true,"mode":"list","value":"1N1Yg7FA4tQ8mDll5HLKqwPBuHj31AGDKwzAOg8mLQKs","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1N1Yg7FA4tQ8mDll5HLKqwPBuHj31AGDKwzAOg8mLQKs/edit?usp=drivesdk","cachedResultName":"Flux Kontext"}},"credentials":{"googleSheetsOAuth2Api":{"id":"JYR6a64Qecd6t8Hb","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"b3087b1a-f9c9-4674-a894-0290768b0c9b","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-220,300],"parameters":{"width":740,"height":100,"content":"## STEP 4 - MAIN FLOW\nStart the workflow manually or periodically by hooking the \"Schedule Trigger\" node. It is recommended to set it at 5 minute intervals."},"typeVersion":1},{"id":"9b149100-99eb-4b6a-9335-ee4888a97c25","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-220,120],"parameters":{"width":740,"height":140,"content":"## STEP 2 - GET API KEY (YOURAPIKEY)\nCreate an account [here](https://fal.ai/) and obtain API KEY.\nIn the node \"Create Image\" set \"Header Auth\" and set:\n- Name: \"Authorization\"\n- Value: \"Key YOURAPIKEY\""},"typeVersion":1},{"id":"8a34a1a2-3f39-4cc5-9739-0cad1d811f10","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[280,600],"parameters":{"width":180,"height":200,"content":"Set API Key created in Step 2"},"typeVersion":1},{"id":"d8240bd8-f127-40a7-aa3a-29211befe2e3","name":"Get Image Url","type":"n8n-nodes-base.httpRequest","position":[100,1000],"parameters":{"url":"=https://queue.fal.run/fal-ai/flux-pro/requests/{{ $json.request_id }}","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"daOZafXpRXLtoLUV","name":"Fal.run API"}},"typeVersion":4.2},{"id":"987ce6a8-13ac-4516-9a3a-a71fa8b513b1","name":"Upload Image","type":"n8n-nodes-base.googleDrive","position":[580,1000],"parameters":{"name":"={{ $now.format('yyyyLLddHHmmss') }}.{{ $('Get new image').item.json[\"OUTPUT FORMAT\"] }}","driveId":{"__rl":true,"mode":"list","value":"My Drive"},"options":{},"folderId":{"__rl":true,"mode":"list","value":"1aHRwLWyrqfzoVC8HoB-YMrBvQ4tLC-NZ","cachedResultUrl":"https://drive.google.com/drive/folders/1aHRwLWyrqfzoVC8HoB-YMrBvQ4tLC-NZ","cachedResultName":"Fal.run"}},"credentials":{"googleDriveOAuth2Api":{"id":"HEy5EuZkgPZVEa9w","name":"Google Drive account (n3w.it)"}},"typeVersion":3},{"id":"1d6b21c5-429e-4095-b74d-fd12ca62afca","name":"Create Image","type":"n8n-nodes-base.httpRequest","position":[320,660],"parameters":{"url":"https://queue.fal.run/fal-ai/flux-pro/kontext","method":"POST","options":{},"jsonBody":"={\n  \"prompt\": \"{{ $json.PROMPT }}\",\n  \"image_url\": \"{{ $json['IMAGE URL'] }}\",\n  \"output_format\": \"{{ $json['OUTPUT FORMAT'] }}\",\n  \"aspect_ratio\": \"{{ $json['ASCPECT RATIO'] }}\"\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json"}]}},"credentials":{"httpHeaderAuth":{"id":"daOZafXpRXLtoLUV","name":"Fal.run API"}},"typeVersion":4.2},{"id":"c350e744-bf61-4837-bc97-8b35ff1c6755","name":"Get new image","type":"n8n-nodes-base.googleSheets","position":[80,660],"parameters":{"options":{},"filtersUI":{"values":[{"lookupColumn":"RESULT"}]},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1N1Yg7FA4tQ8mDll5HLKqwPBuHj31AGDKwzAOg8mLQKs/edit#gid=0","cachedResultName":"Foglio1"},"documentId":{"__rl":true,"mode":"list","value":"1N1Yg7FA4tQ8mDll5HLKqwPBuHj31AGDKwzAOg8mLQKs","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1N1Yg7FA4tQ8mDll5HLKqwPBuHj31AGDKwzAOg8mLQKs/edit?usp=drivesdk","cachedResultName":"Flux Kontext"}},"credentials":{"googleSheetsOAuth2Api":{"id":"JYR6a64Qecd6t8Hb","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"6f5181b9-300f-4214-a19b-f0f717c9db29","name":"Get Image File","type":"n8n-nodes-base.httpRequest","position":[320,1000],"parameters":{"url":"={{ $json.images[0].url }}","options":{}},"typeVersion":4.2},{"id":"539eb1dc-e439-42ad-b313-943d1dbc1937","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[560,-500],"parameters":{"color":5,"width":360,"height":900,"content":"## Example\n\n**Image**:\n![image](https://n3wstorage.b-cdn.net/n3witalia/model.jpg)\n\n**Prompt**:\nThe girl is lying on the bed and sleeping\n\n**Result**:\n![image](https://n3wstorage.b-cdn.net/n3witalia/flux_output.jpeg)"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"0efa8e9f-21d0-45ce-b557-03620f3fc771","connections":{"Completed?":{"main":[[{"node":"Get Image Url","type":"main","index":0}],[{"node":"Wait 60 sec.","type":"main","index":0}]]},"Get status":{"main":[[{"node":"Completed?","type":"main","index":0}]]},"Create Image":{"main":[[{"node":"Wait 60 sec.","type":"main","index":0}]]},"Upload Image":{"main":[[{"node":"Update result","type":"main","index":0}]]},"Wait 60 sec.":{"main":[[{"node":"Get status","type":"main","index":0}]]},"Get Image Url":{"main":[[{"node":"Get Image File","type":"main","index":0}]]},"Get new image":{"main":[[{"node":"Create Image","type":"main","index":0}]]},"Update result":{"main":[[]]},"Get Image File":{"main":[[{"node":"Upload Image","type":"main","index":0}]]},"When clicking ‘Test workflow’":{"main":[[{"node":"Get new image","type":"main","index":0}]]}}}


name: Automatic Travel Itinerary Generation via Email with Llama AI
author_name: OneClick IT Consultancy P Limited
author_username: oneclick-it
categories: []
created_at: 2025-06-13T09:12:39.320Z
updated_at: 2025-06-13T09:12:39.320Z
url: https://n8n.io/workflows/4917
scraped_at: 2025-07-06 21:16:30
description:
  Travel Agent that Auto Response on Mail

  In this guide, we’ll break down how to set up an AI-powered auto-reply system that works while you sleep. Ready to 10X your efficiency? Let’s dive in!

  What’s the Goal?
   AI-driven auto-responses for Email.
   Instant replies to FAQs, order confirmations, and support queries.
   24/7 availability - no more “We’ll get back to you soon” delays.
   Seamless integration with existing business tools.

  By the end, you’ll have a self-running communication assistant that never takes a coffee break.

  Why Does It Matter?
  Why automate replies? Because time = money and manual typing is so 2010. Here’s why this workflow is a game changer:
   Zero Human Error: AI doesn’t get tired or make typos.
   Lightning-Fast Replies: Customers get instant answers, improving satisfaction.
   24/7 Availability: No more “Out of Office” replies.
   Focus on High-Value Work: Free your team from mundane tasks.
  Think of it as hiring a super efficient virtual assistant - minus the salary.

  How It Works
  Here’s the step by step magic behind the automation
  Step 1: Trigger the Workflow
   Detect new messages from WhatsApp, Email, or Slack.
   Use n8n’s webhook or API integration to capture incoming queries.

  Step 2: Process the Message with AI
   Send the message to an AI model (like OpenAI GPT-4 or Gemini).
   Generate a context-aware, human-like response.

  Step 3: Send the Automated Reply
   Route the AI-generated response back to the original platform.
   Ensure personalization (e.g., “Hi [Name], thanks for reaching out!”).

  Step 4: Log & Optimize
   Store interactions in a database (Airtable, Google Sheets).
   Continuously improve AI responses based on past data.

  How to use the workflow?
  Importing a workflow in n8n is a straightforward process that allows you to use pre-built or shared workflows to save time. Below is a step-by-step guide to importing a workflow in n8n, based on the official documentation and community resources.

  Steps to Import a Workflow in n8n
  1. Obtain the Workflow JSON
  Source the Workflow:**
  	Workflows are typically shared as JSON files or code snippets. You might receive them from:
  	The n8n community (e.g., n8n.io workflows page).
  	A colleague or tutorial (e.g., a .json file or copied JSON code).
  	Exported from another n8n instance (see export instructions below if needed).
  Format:** Ensure you have the workflow in JSON format, either as a file (e.g., workflow.json) or as text copied to your clipboard.

  2. Access the n8n Workflow Editor
  Log in to n8n:**
  	Open your n8n instance (via n8n Cloud or your self-hosted instance).
  	Navigate to the Workflows tab in the n8n dashboard.
  Open a New Workflow:**
  	Click Add Workflow to create a blank workflow, or open an existing workflow if you want to merge the imported workflow.

  3. Import the Workflow
  Option 1: Import via JSON Code (Clipboard):
  In the n8n editor, click the three dots (⋯) in the top-right corner to open the menu.
  Select Import from Clipboard.
  Paste the JSON code of the workflow into the provided text box.
  Click Import to load the workflow into the editor.

  Option 2: Import via JSON File:
  In the n8n editor, click the three dots (⋯) in the top-right corner.
  Select Import from File.
  Choose the .json file from your computer.
  Click Open to import the workflow.

nodes_used:
  ["n8n-nodes-base.emailSend","@n8n/n8n-nodes-langchain.chainLlm","@n8n/n8n-nodes-langchain.lmOllama"]

workflow_json:
  {"id":"UlSHcKupAZfb0FZt","meta":{"instanceId":"dd69efaf8212c74ad206700d104739d3329588a6f3f8381a46a481f34c9cc281","templateCredsSetupCompleted":true},"name":"AI Travel Agent","tags":[],"nodes":[{"id":"6f0a745d-aa01-4edd-ac2a-444de56e8c60","name":"Ollama Model","type":"@n8n/n8n-nodes-langchain.lmOllama","position":[-300,80],"parameters":{"model":"llama3.2-16000:latest","options":{}},"credentials":{"ollamaApi":{"id":"h9CEBFmYALm3FvZf","name":"Ollama account"}},"typeVersion":1},{"id":"261ba61b-5c01-4cd3-8033-41db9ad2b625","name":"Trigger From Mail (IMAP)","type":"n8n-nodes-base.emailReadImap","position":[-500,-120],"parameters":{"options":{"customEmailConfig":"[\"UNSEEN\", [\"SUBJECT\", \"itinerary\"]]"}},"credentials":{"imap":{"id":"D3nLrSlP1dHWcIDE","name":"IMAP account"}},"typeVersion":2},{"id":"750101d2-7fc0-44d7-a615-d98803669ff2","name":"Basic LLM","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[-300,-120],"parameters":{"text":"={{ $json.textPlain }}","messages":{"messageValues":[{"message":"=Create a friendly, human-style travel itinerary based on the email content in {{ $json.textPlain }}. The itinerary should be casual, easy to read, and feel like it was written by a person — not a robot.\n\nInclude the following elements:\n\nA short, warm greeting at the top\n\nA one-line summary of the destination and a few top highlights mentioned in the email\n\nAlways Daily breakdowns starting with \"Day 1:\", \"Day 2:\", etc., matching the number of days specified in the email (e.g., if the email says 4 days, include only Day 1 to Day 4, with Day 4 as the departure day).This thing is important so keep it in mind.\n\nFor each day, include key activities, hotel info, flight times, and transport details — in simple language\n\nKeep the tone conversational, light, and informative — like you're helping a friend plan their trip\n\nAvoid using markdown, emojis, special characters, or extra spacing\n\n\"\"\"\"Use this exact structure, do not add any extra words, and match the number of days to the email content and highlights imp things\"\"\"\"\":\n\nHello Traveller,\n\nHere’s your itinerary for your [destination] adventure! Get ready to explore amazing places like [a few highlights based on the email].\n\nDay 1: [Arrival details, flight info, hotel check-in, maybe a light activity or dinner nearby]\nDay 2: [Activities, any planned tours, transport details if moving around]\nDay 3: [Activities, hotel name if changing, any travel between cities]\nDay 4: [Departure day – include checkout time, transport to airport, and flight info]\n\nBest regards,\nOneclick\n\n\nthis is sample mail \n\nDelhi, the vibrant capital of India! I'd be delighted to help you plan your 4-day trip to Delhi with your family.\n\nHere's a suggested itinerary that covers some of the top attractions, cultural experiences, and culinary delights:\n\n**Day 1: Red Fort, Qutub Minar, and Chandni Chowk**\n\n* Morning: Start at the Red Fort (open from 9:30 AM), a majestic Mughal fort with stunning architecture. Explore the fort's imposing walls, gardens, and palaces.\n* Afternoon: Visit Qutub Minar (open from 10:00 AM), the tallest minaret in India, built by Qutb-ud-din Aibak in 1199 AD.\n* Evening: Take a leisurely stroll through Chandni Chowk, one of Delhi's oldest and most vibrant streets, lined with street food stalls, shops, and historic landmarks.\n\n**Day 2: Humayun's Tomb, Lotus Temple, and Indian Museum**\n\n* Morning: Visit Humayun's Tomb (open from 9:30 AM), a beautiful Mughal mausoleum built by Haji Begum in 1573 AD.\n* Afternoon: Explore the Baha'i Temple (Lotus Temple) in Ashok Vihar (open from 10:00 AM), an iconic temple with stunning architecture and peaceful surroundings.\n* Evening: Head to the Indian Museum, a treasure trove of Indian history and culture, located in Central Delhi.\n\n**Day 3: Akshardham Temple, Laxmi Nagar Shopping Mall, and Chilla Village**\n\n* Morning: Visit the Akshardham Temple (open from 9:00 AM), a magnificent temple complex with intricate carvings, stunning architecture, and beautiful gardens.\n* Afternoon: Spend some time shopping at Laxmi Nagar Shopping Mall, one of Delhi's popular shopping destinations.\n* Evening: Head to Chilla Village, a small village located on the outskirts of Delhi, where you can experience rural India and enjoy a peaceful evening.\n\n**Day 4: Gandhi Smriti, India Gate, and Hauz Khas Village**\n\n* Morning: Visit Gandhi Smriti (open from 9:30 AM), the museum dedicated to Mahatma Gandhi's life and legacy.\n* Afternoon: Explore India Gate (open from 10:00 AM), a stunning war memorial built in honor of Indian soldiers who fought in World War I.\n* Evening: Head to Hauz Khas Village, a trendy neighborhood with boutique shops, cafes, and restaurants.\n\n**Additional Tips**\n\n* Be prepared for the crowds and heat during peak summer months (April to June).\n* Wear comfortable shoes, as you'll be doing a lot of walking throughout the day.\n* Try some local street food, like chaat items or kebabs, but ensure they're cooked and served hygienically.\n* Don't forget to bargain when shopping at local markets!\n* Take breaks and stay hydrated throughout the day.\n\n**Getting Around**\n\n* Use an auto-rickshaw, taxi, or ride-hailing apps (like Ola, Uber) to get around Delhi. Be prepared for traffic congestion.\n* The Metro network in Delhi is efficient and convenient, but be aware of peak hours (7:00 AM - 9:00 AM and 4:00 PM - 6:00 PM).\n\n**Budget Breakdown**\n\n* Accommodation: ₹5,000-₹10,000 (approximately $65-$130 USD) for a family of four, depending on the hotel or hostel you choose.\n* Transportation: ₹1,500-₹3,000 (approximately $20-$40 USD) for auto-rickshaws, taxis, and ride-hailing services.\n* Food: ₹2,000-₹4,000 (approximately $25-$50 USD) per day for meals at local restaurants and street food stalls.\n\nThis itinerary provides a good balance of culture, history, and fun activities that are suitable for families. Feel free to adjust it according to your interests and preferences!\n\n**Are there any specific requests or changes you'd like me to make?\n"}]},"promptType":"define"},"typeVersion":1.6},{"id":"e5e3a173-43dd-41e5-b373-97c457c70025","name":"Email Field Setup","type":"n8n-nodes-base.set","position":[100,-120],"parameters":{"options":{},"assignments":{"assignments":[{"id":"7d428c48-4809-45d8-ba1e-c96d68c02c07","name":"from","type":"string","value":"={{ $('Trigger From Mail (IMAP)').first().json.from }}"},{"id":"63b99545-3d2d-4563-b9d7-078cbc20dbcc","name":"subject","type":"string","value":"=Re: {{ $('Trigger From Mail (IMAP)').first().json.subject }}"},{"id":"11d94d3f-2170-4b54-b5f9-b85bb95ad472","name":"text","type":"string","value":"={{ $json.text }} "}]}},"typeVersion":3.4},{"id":"f42413ba-81fb-4995-ad56-21f469f7da82","name":"Sending Email","type":"n8n-nodes-base.emailSend","position":[320,-120],"webhookId":"8ddf4c83-5990-4b1c-ab0d-4cc55932d2c4","parameters":{"text":"={{ $json.text }}","options":{},"subject":"={{ $json.subject }}","toEmail":"={{ $json.from }}","fromEmail":"XYZ@gmail.com","emailFormat":"text"},"credentials":{"smtp":{"id":"3QSx1pWoS0BZcK4c","name":"SMTP account"}},"typeVersion":2.1},{"id":"9a3324e1-3fe5-4b13-924d-dcb05daf4c8d","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1000,-340],"parameters":{"width":420,"height":220,"content":"#### Configure Mail Credentials for Trigger Mail Node\nUnder Credentials, choose or create new IMAP credentials.\nUse settings as per below\n\nIMAP Settings Example:\nHost     - imap.gmail.com\nPort     - 993\nSecure   - true\nUser     - your-email@gmail.com\nPassword - App password (for Gmail, use App Password)"},"typeVersion":1},{"id":"0e562abb-7c3a-41e2-8a98-7d583dfa2c90","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-1000,-100],"parameters":{"width":420,"height":220,"content":"#### Configure SMTP Settings for the Send Mail Node.\nYou need to enter SMTP details:\n\nUser     - your-email@gmail.com\nPassword - App password (for Gmail, use App Password)\nHost     - smtp.gmail.com\nPort     - 465\nSSL/TLS  - True"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"2742d28b-b293-481a-8ef2-ec0972d34fe5","connections":{"Basic LLM":{"main":[[{"node":"Email Field Setup","type":"main","index":0}]]},"Ollama Model":{"ai_languageModel":[[{"node":"Basic LLM","type":"ai_languageModel","index":0}]]},"Email Field Setup":{"main":[[{"node":"Sending Email","type":"main","index":0}]]},"Trigger From Mail (IMAP)":{"main":[[{"node":"Basic LLM","type":"main","index":0}]]}}}


