# templates

name: Automated daily workflow backup to GitHub
author_name: Hugo
author_username: hugop
nodes_used: ["n8n-nodes-base.github"]
categories: []
created_at: 2025-05-15T02:33:44.721Z
updated_at: 2025-05-15T02:33:44.721Z
url: https://n8n.io/workflows/4064
scraped_at: 2025-06-19 22:49:58
description:
  This workflow provides a robust solution for automatically backing up all your n8n workflows to a designated GitHub repository on a daily basis. By leveraging the n8n API and GitHub API, it ensures your workflows are version-controlled and securely stored, safeguarding against data loss and facilitating disaster recovery.

  How it works

  The automation follows these key steps:

  Scheduled trigger: The workflow is initiated automatically every day at a pre-configured time.
  List existing backups: It first connects to your GitHub repository to retrieve a list of already backed-up workflow files. This helps in determining whether a workflow's backup file needs to be created or updated.
  Retrieve n8n workflows: The workflow then fetches all current workflows directly from your n8n instance using the n8n REST API.
  Process and prepare: Each retrieved workflow is individually processed. Its data is converted into JSON format. This JSON content is then encoded to base64, a format suitable for GitHub API file operations.
  Commit to GitHub: For each n8n workflow:
      A standardized filename is generated (e.g., workflow-name-tag.json).
      The workflow checks if a file with this name already exists in the GitHub repository (based on the list fetched in step 2).
      If the file exists: It updates the existing file with the latest version of the workflow.
      If it's a new workflow (file doesn't exist): A new file is created in the repository.
      Each commit is timestamped for clarity.

  This process ensures that you always have an up-to-date version of all your n8n workflows stored securely in your GitHub version control system, providing peace of mind and a reliable backup history.

  Pre-requisites

  Before you can use this template, please ensure you have the following:

  An active n8n instance (self-hosted or cloud).
  A GitHub account.
  A GitHub repository created where you want to store the workflow backups.
  A GitHub Personal Access Token with repo scope (or fine-grained token with read/write access to the specific backup repository). This token will be used for GitHub API authentication.
  n8n API credentials (API key) for your n8n instance.

  Set up steps

  Setting up this workflow should take approximately 10-15 minutes if you have your credentials ready.

  Import the template: Import this workflow into your n8n instance.
  Configure n8n API credentials:
      Locate the "Retrieve workflows" node.
      In the "Credentials" section for "n8n API", create new credentials (or select existing ones).
      Enter your n8n instance URL and your n8n API Key (you can create your n8n api key in the settings of your n8n instance)
  Configure GitHub credentials:
      Locate the "List files from repo" node (and subsequently "Update file" / "Upload file" nodes which will use the same credential).
      In the "Credentials" section for "GitHub API", create new credentials.
      Select OAuth2/Personal Access Token authentication method.
      Enter the GitHub Personal Access Token you generated as per the pre-requisites.
  Specify repository details:
      In the "List files from repo", "Update file", and "Upload file" GitHub nodes:
          Set the Owner: Your GitHub username or organization name.
          Set the Repository: The name of your GitHub repository dedicated to backups.
          Set the Branch (e.g., main or master) where backups should be stored.
          (Optional) Specify a Path within the repository if you want backups in a specific folder (e.g., n8n_backups/). Leave blank to store in the root.
  Adjust schedule (Optional):
      Select the "Schedule Trigger" node.
      Modify the trigger interval (e.g., change the time of day or frequency) as needed. By default, it's set for a daily run.
  Activate the workflow: Save and activate the workflow.

  Explanation of nodes

  Here's a detailed breakdown of each node used in this workflow:

  Schedule trigger**
      Type: n8n-nodes-base.scheduleTrigger
      Purpose: This node automatically starts the workflow based on a defined schedule (e.g., daily at midnight).
  List files from repo**
      Type: n8n-nodes-base.github
      Purpose: Connects to your specified GitHub repository and lists all files, primarily to check for existing workflow backups.
  Aggregate**
      Type: n8n-nodes-base.aggregate
      Purpose: Consolidates the list of file names obtained from the "List files from repo" node into a single item for easier lookup later in the "Check if file exists" node.
  Retrieve workflows**
      Type: n8n-nodes-base.n8n
      Purpose: Uses the n8n API to fetch a list of all workflows currently present in your n8n instance.
  Json file**
      Type: n8n-nodes-base.convertToFile
      Purpose: Takes the data of each workflow (retrieved by the "Retrieve workflows" node) and converts it into a structured JSON file format.
  To base64**
      Type: n8n-nodes-base.extractFromFile
      Purpose: Converts the binary content of the JSON file (from the "Json file" node) into a base64 encoded string. This encoding is required by the GitHub API for file content.
  Commit date & file name**
      Type: n8n-nodes-base.set
      Purpose: Prepares metadata for the GitHub commit. It generates:
          commitDate: The current date and time for the commit message.
          fileName: A standardized file name for the workflow backup (e.g., my-workflow-vps-backups.json), typically using the workflow's name and its first tag.
  Check if file exists**
      Type: n8n-nodes-base.if
      Purpose: A conditional node. It checks if the fileName (generated by "Commit date & file name") is present in the list of files aggregated by the "Aggregate" node. This determines if the workflow backup already exists in GitHub.
  Update file**
      Type: n8n-nodes-base.github
      Purpose: If the "Check if file exists" node determines the file does exist, this node updates that existing file in your GitHub repository with the latest workflow content (base64 encoded) and a commit message.
  Upload file**
      Type: n8n-nodes-base.github
      Purpose: If the "Check if file exists" node determines the file does not exist, this node creates and uploads a new file to your GitHub repository with the workflow content and a commit message.

  Customization

  Here are a few ways you can customize this template to better fit your needs:

  Backup path**: In the GitHub nodes ("List files from repo", "Update file", "Upload file"), you can specify a Path parameter to store backups in a specific folder within your repository (e.g., workflows/ or daily_backups/).
  Filename convention**: Modify the "Commit date & file name" node (specifically the expression for fileName) to change how backup files are named. For example, you might want to include the workflow ID or a different date format.
  Commit messages**: Customize the commit messages in the "Update file" and "Upload file" GitHub nodes to include more specific information if needed.
  Error handling**: Consider adding error handling branches (e.g., using the "Error Trigger" node or checking for node execution failures) to notify you if a backup fails for any reason.
  Filtering workflows**: If you only want to back up specific workflows (e.g., those with a particular tag or name pattern), you can add a "Filter" node after "Retrieve workflows" to include only the desired workflows in the backup process.
  Backup frequency**: Adjust the "Schedule Trigger" node to change how often the backup runs (e.g., hourly, weekly, or on specific days).


  Template was created in n8n v1.92.2

workflow_json:
  {"nodes":[{"id":"2aafc10f-0bb7-419f-a6b3-fa90f5f68653","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[100,-20],"parameters":{"rule":{"interval":[{}]}},"typeVersion":1.2},{"id":"da87b4f8-4507-456b-bfc3-3ae7d9400449","name":"Retrieve workflows","type":"n8n-nodes-base.n8n","position":[580,-20],"parameters":{"filters":{},"requestOptions":{}},"typeVersion":1},{"id":"6cd7d968-6fa0-4ab0-ac58-ceb15c8b7b4a","name":"Aggregate","type":"n8n-nodes-base.aggregate","position":[420,-20],"parameters":{"options":{},"fieldsToAggregate":{"fieldToAggregate":[{"fieldToAggregate":"name"}]}},"typeVersion":1},{"id":"854f6e82-babb-474e-a138-2a6c398fd60e","name":"List files from repo","type":"n8n-nodes-base.github","position":[260,-20],"webhookId":"354d699e-44b0-4444-9d31-af7fd4ff5561","parameters":{"owner":{"__rl":true,"mode":"name","value":""},"filePath":"=","resource":"file","operation":"list","repository":{"__rl":true,"mode":"list","value":""},"authentication":"oAuth2"},"typeVersion":1,"alwaysOutputData":true},{"id":"8abba016-1f34-420a-b10b-3c8e44297725","name":"Update file","type":"n8n-nodes-base.github","position":[1380,-100],"webhookId":"27218087-8df7-474d-a39f-70cfa9c34ec8","parameters":{"owner":{"__rl":true,"mode":"name","value":""},"filePath":"={{ $('Retrieve workflows').item.json.name.replace(/\\s+/g, '-').toLowerCase() }}-{{ $('Retrieve workflows').item.json.tags[0].name }}.json","resource":"file","operation":"edit","repository":{"__rl":true,"mode":"list","value":""},"fileContent":"={{ $('To base64').item.json.data }}","commitMessage":"=backup-{{ $('Commit date & file name').item.json.commitDate }}","authentication":"oAuth2"},"typeVersion":1},{"id":"d55efcc7-5873-4c9a-b374-b7b31814905b","name":"Upload file","type":"n8n-nodes-base.github","position":[1380,60],"webhookId":"ce4b561b-acb9-4cd8-b76f-4928dada9674","parameters":{"owner":{"__rl":true,"mode":"name","value":""},"filePath":"={{ $('Retrieve workflows').item.json.name.replace(/\\s+/g, '-').toLowerCase() }}-{{ $('Retrieve workflows').item.json.tags[0].name }}.json","resource":"file","repository":{"__rl":true,"mode":"list","value":""},"fileContent":"={{ $('To base64').item.json.data }}","commitMessage":"=backup-{{ $node['Commit date & file name'].json.commitDate }}","authentication":"oAuth2"},"typeVersion":1},{"id":"09909c9f-8a68-4670-8396-65fae9be51ff","name":"Check if file exists","type":"n8n-nodes-base.if","position":[1220,-20],"parameters":{"conditions":{"string":[{"value1":"={{ $('Aggregate').item.json.name }}","value2":"={{ $('Retrieve workflows').item.json.name.replace(/\\s+/g, '-').toLowerCase() }}-{{ $('Retrieve workflows').item.json.tags[0].name }}.json","operation":"contains"}]}},"typeVersion":1},{"id":"43990124-eac4-4c57-9da3-39053d9e5850","name":"Json file","type":"n8n-nodes-base.convertToFile","position":[740,-20],"parameters":{"mode":"each","options":{"format":true},"operation":"toJson"},"typeVersion":1.1},{"id":"956de457-4d05-4ea8-be7b-390861a739d4","name":"To base64","type":"n8n-nodes-base.extractFromFile","position":[900,-20],"parameters":{"options":{},"operation":"binaryToPropery"},"typeVersion":1},{"id":"fc258985-2621-42a3-9bc6-01048a92b702","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[240,-160],"parameters":{"color":5,"width":300,"height":380,"content":"### Retrieve previous file names from Github"},"typeVersion":1},{"id":"1bfedd8f-1921-4f33-aa45-7ab612f26059","name":"Commit date & file name","type":"n8n-nodes-base.set","position":[1060,-20],"parameters":{"options":{},"assignments":{"assignments":[{"id":"fe4a36ef-9f04-40e3-99bd-cc517a49b440","name":"commitDate","type":"string","value":"={{ $now.format('dd-MM-yyyy/H:mm') }}"},{"id":"b0fe1bcc-e79c-4a6b-b8b4-44222c8bf4e8","name":"fileName","type":"string","value":"={{ $('Retrieve workflows').item.json.name.replace(/\\s+/g, '-').toLowerCase() }}-{{ $('Retrieve workflows').item.json.tags[0].name }}.json"}]}},"typeVersion":3.4},{"id":"2f36af66-12ca-451a-a1ca-c5a71b94b644","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[560,-160],"parameters":{"color":3,"width":460,"height":380,"content":"### Retrieve and process workflows from n8n"},"typeVersion":1},{"id":"dc914f31-e6b5-43b0-8a4e-f9f46118fa30","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1040,-160],"parameters":{"color":4,"width":460,"height":380,"content":"### Commit + edit/create files if needed"},"typeVersion":1}],"connections":{"Aggregate":{"main":[[{"node":"Retrieve workflows","type":"main","index":0}]]},"Json file":{"main":[[{"node":"To base64","type":"main","index":0}]]},"To base64":{"main":[[{"node":"Commit date & file name","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"List files from repo","type":"main","index":0}]]},"Retrieve workflows":{"main":[[{"node":"Json file","type":"main","index":0}]]},"Check if file exists":{"main":[[{"node":"Update file","type":"main","index":0}],[{"node":"Upload file","type":"main","index":0}]]},"List files from repo":{"main":[[{"node":"Aggregate","type":"main","index":0}]]},"Commit date & file name":{"main":[[{"node":"Check if file exists","type":"main","index":0}]]}}}


name: Automate SEO Blog Creation + Social Media with GPT-4, Perplexity and WordPress
author_name: LukaszB
author_username: lukaszb
categories: []
created_at: 2025-05-15T18:59:00.587Z
updated_at: 2025-05-15T18:59:00.587Z
url: https://n8n.io/workflows/4082
scraped_at: 2025-06-19 22:49:33
description:
  🚀 AI Blog & Social Media Publisher – Fully Automated Workflow

  This workflow is ideal for individuals, marketers, agencies, and brands who want to effortlessly automate the entire blogging and social media process—from idea generation to promotion. Its primary goal is to consistently deliver engaging, SEO-optimized blog posts directly to WordPress, accompanied by professionally crafted social media content ready for Instagram, Facebook, and X (Twitter).

  No writers, editors, designers, or social media managers required. Save countless hours and resources while boosting your brand's online presence.

  🔧 Workflow Capabilities:

  -Automated Blog Topic Generation: Instantly generates unique, high-value blog ideas tailored to your brand.
  -SEO Content Creation: Produces comprehensive, 2000–2500 word articles optimized for search engines.
  -Real-Time Research: Integrates Perplexity AI to ensure factually accurate, authoritative content.
  -Visual Content Generation: Creates custom, AI-generated featured images via GPT-4, with automatic fallback to Pexels.
  -WordPress Publishing: Automatically publishes articles directly to WordPress with complete formatting (HTML), meta descriptions, featured images, and proper categorization.
  -Social Media Automation: Generates and schedules engaging, platform-specific posts for Instagram, Facebook, and X, complete with relevant hashtags, calls-to-action, and links.
  -Detailed Logging & Reporting: Logs every step transparently into Google Sheets and optionally sends publication reports to Gmail.

  ⚙️ How It Works:
  When activated, the workflow checks your content calendar in Google Sheets to avoid duplicate topics. It generates fresh, brand-aligned blog ideas, conducts live research, and creates complete, ready-to-publish articles. It then automatically designs and sources appropriate visuals, publishes content seamlessly to WordPress, and prepares engaging social media posts optimized for each platform.

  🛠️ Easy Setup Steps:
  -Connect your APIs: OpenAI, WordPress, Google Sheets, Gmail, and optionally Pexels.
  -Replace placeholders (WordPress URLs, Google Sheets ID/tab, workflow IDs).
  -Customize AI prompts with your brand’s tone, keywords, and CTAs for personalized content.
  -Configure scheduling to automate daily, weekly, or custom publishing intervals.

  📌 Additional Features:
  -Modular workflow design for easy customization and scalability.
  -Comprehensive Markdown and PDF setup guides included.
  -Bonus: Reference placeholders and quick-edit Sticky Notes for effortless adjustments.

  Launch today. Automate permanently. Amplify your reach effortlessly.

nodes_used:
  ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.wordpress","n8n-nodes-base.facebookGraphApi","n8n-nodes-base.twitter","n8n-nodes-base.gmail","n8n-nodes-base.notion","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.chainLlm","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.memoryBufferWindow","@n8n/n8n-nodes-langchain.outputParserStructured","@n8n/n8n-nodes-langchain.toolWorkflow","@n8n/n8n-nodes-langchain.openAi"]

workflow_json:
  {"id":"To13kL7p4OV8nDaZ","meta":{"instanceId":"740c1df6d3b1b6ea8a9d2223701f6904173f9e3cf7381cd181644b043420ba09","templateCredsSetupCompleted":true},"name":"Automated Blog writer with social media promotion agent","tags":[],"nodes":[{"id":"0b195040-295a-4cff-91d7-6a5121105df9","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-2180,540],"parameters":{"content":""},"typeVersion":1},{"id":"79ed8c8f-9b55-4a57-8309-44180d5d3e43","name":"When clicking ‘Test workflow’","type":"n8n-nodes-base.manualTrigger","position":[-2540,-60],"parameters":{},"typeVersion":1},{"id":"cdbacaac-baad-441d-9f5d-fe5e98d2628f","name":"When Executed by Another Workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[-1300,2260],"parameters":{},"typeVersion":1.1},{"id":"d32d67c4-a62a-4705-b7de-2943d13c32c6","name":"Notion","type":"n8n-nodes-base.notion","position":[-1060,2260],"parameters":{},"typeVersion":2.2},{"id":"3ff83c0a-7a5b-4b52-a1b6-eea59c648d3f","name":"Aggregate","type":"n8n-nodes-base.aggregate","position":[-840,2260],"parameters":{},"typeVersion":1},{"id":"5d0e19f5-0230-4d74-8745-738cc19d7934","name":"Edit Fields","type":"n8n-nodes-base.set","position":[-620,2260],"parameters":{},"typeVersion":3.4},{"id":"e72f8aba-fd75-4d42-9ab8-db91ae89b822","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-1460,2100],"parameters":{"content":""},"typeVersion":1},{"id":"33b0326a-0682-441e-8cb0-6c77493edd25","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-1580,1240],"parameters":{"content":""},"typeVersion":1},{"id":"2d57129b-7472-4cd7-b67b-adbbb744c2de","name":"OpenAI 4.1 mini4","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-1500,1520],"parameters":{},"typeVersion":1.2},{"id":"1646be1c-baae-442f-b567-b5bfe3ca4cd4","name":"Write prompt to create image","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[-1520,1340],"parameters":{},"typeVersion":1.6},{"id":"5b432eb8-0954-49d2-bde7-dcde79120698","name":"OpenAI","type":"@n8n/n8n-nodes-langchain.openAi","onError":"continueErrorOutput","position":[-1080,1340],"parameters":{},"typeVersion":1.8},{"id":"71799dbd-e9dc-4ed2-875d-f2ef2e2bb817","name":"Upload Image to Wordpress2","type":"n8n-nodes-base.httpRequest","onError":"continueRegularOutput","position":[-780,1340],"parameters":{},"retryOnFail":false,"typeVersion":4.2,"alwaysOutputData":false},{"id":"dbf10b1c-4e59-4693-936e-8176fd7022d4","name":"Set Image on Wordpress Post2","type":"n8n-nodes-base.httpRequest","onError":"continueRegularOutput","position":[-580,1340],"parameters":{},"typeVersion":4.2},{"id":"32e44406-845d-404f-89d4-1bd3e3e5c314","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-160,-160],"parameters":{"content":""},"typeVersion":1},{"id":"80cb12c0-b42e-43ca-97ff-bbce1f914509","name":"Wordpress","type":"n8n-nodes-base.wordpress","position":[660,20],"parameters":{},"typeVersion":1},{"id":"16c65a59-d52f-4581-ace2-8e81e6730965","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[540,-60],"parameters":{"content":""},"typeVersion":1},{"id":"6a958569-b7ae-4b08-9c8d-f2d6029c546c","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-700,-160],"parameters":{"content":""},"typeVersion":1},{"id":"83a63492-805e-4cb8-a56a-dd99956c5a9a","name":"Cleanup Links","type":"n8n-nodes-base.set","position":[-400,20],"parameters":{},"typeVersion":3.4},{"id":"11cac099-dee9-4e35-b0fa-d3c0059376b2","name":"Cleanup HTML ","type":"n8n-nodes-base.set","position":[300,20],"parameters":{},"typeVersion":3.4},{"id":"94586cfc-55bf-4b8d-a555-84b146b0b0d3","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[-1800,220],"parameters":{},"typeVersion":1.3},{"id":"da517ec6-05c6-4ecb-bded-a69abf798322","name":"Google Sheets","type":"n8n-nodes-base.googleSheetsTool","position":[-1680,220],"parameters":{},"typeVersion":4.5},{"id":"85aabbbb-1d1e-4300-bcce-c6b63b0cfb77","name":"get brand brief","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[-1560,220],"parameters":{},"typeVersion":2.1},{"id":"f590fc01-77ee-4021-8ea5-b1c079e3c944","name":"Structured Output Parser1","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[-1420,220],"parameters":{},"typeVersion":1.2},{"id":"23168360-e347-4c51-8e0e-cc36bf4a5f2d","name":"Idea creator","type":"@n8n/n8n-nodes-langchain.agent","position":[-1780,20],"parameters":{},"typeVersion":1.8},{"id":"5a646f02-27c6-4c04-bf01-17f88dd26edf","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-2400,-160],"parameters":{"content":""},"typeVersion":1},{"id":"0ab7454b-656a-4a9e-964e-3b59a5ed4003","name":"Perplexity Research1","type":"n8n-nodes-base.httpRequest","position":[-620,20],"parameters":{},"typeVersion":4.2},{"id":"7750794d-8136-4aaa-ae0a-d209fc26ebc8","name":"WordPress excerpt add","type":"n8n-nodes-base.httpRequest","position":[460,880],"parameters":{},"typeVersion":4.2},{"id":"e68ff086-815a-48f9-94f6-6448c72aea59","name":"Excerpt creator","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[60,880],"parameters":{},"typeVersion":1.6},{"id":"89403509-49ab-4873-bd82-51f58e9fa371","name":"Update list of blog post","type":"n8n-nodes-base.googleSheets","onError":"continueRegularOutput","position":[260,1460],"parameters":{},"typeVersion":4.5},{"id":"d60dd82c-6678-4032-b902-5dc044243cc8","name":"Update base post","type":"n8n-nodes-base.googleSheets","position":[460,1460],"parameters":{},"typeVersion":4.5},{"id":"b329dd58-c343-4ade-901a-cbdc1a64de34","name":"Markdown","type":"n8n-nodes-base.markdown","position":[20,1460],"parameters":{},"typeVersion":1},{"id":"e4a89855-7e35-43fe-b57f-788eed6a2a25","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-2560,160],"parameters":{},"typeVersion":1.2},{"id":"bca75a23-9fdf-4109-8698-5323a5153800","name":"Content writer","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[-20,20],"parameters":{},"typeVersion":1.6},{"id":"fe63dd4c-b87b-40a4-96e0-9bb00b6db258","name":"OpenAI 4.1 mini","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-20,240],"parameters":{},"typeVersion":1.2},{"id":"74bc8252-9756-4a39-a991-eb5d78467bf6","name":"OpenAI 4.1 mini2","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[80,1040],"parameters":{},"typeVersion":1.2},{"id":"1de78a9d-d136-46f2-b781-be8c7dad3612","name":"OpenAI 4.1 mini3","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-1940,220],"parameters":{},"typeVersion":1.2},{"id":"bae29b85-a213-408a-8b3b-42a435633f15","name":"Category rewrite","type":"n8n-nodes-base.code","position":[-960,40],"parameters":{},"typeVersion":2},{"id":"85e44c71-f5af-4e09-80c1-569a1980a3c6","name":"Upload Image to Wordpress","type":"n8n-nodes-base.httpRequest","onError":"continueRegularOutput","position":[-660,740],"parameters":{},"retryOnFail":false,"typeVersion":4.2,"alwaysOutputData":false},{"id":"bbaa6459-5eca-4daf-9bc1-793c1b50dca2","name":"Set Image on Wordpress Post","type":"n8n-nodes-base.httpRequest","onError":"continueRegularOutput","position":[-440,740],"parameters":{},"typeVersion":4.2},{"id":"90e0ee6d-8cef-45bc-a163-9fdc49b7a742","name":"Get Image from Pexcel","type":"n8n-nodes-base.httpRequest","position":[-1100,740],"parameters":{},"typeVersion":4.2},{"id":"a457647e-7552-48a5-ab2f-2328036b2995","name":"Download Image","type":"n8n-nodes-base.httpRequest","position":[-880,740],"parameters":{},"typeVersion":4.2,"alwaysOutputData":true},{"id":"5e966ddc-e579-4be3-9696-933f19c57f2f","name":"Write prompt to search image","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[-1500,740],"parameters":{},"typeVersion":1.6},{"id":"7ac845e0-3ec3-43f3-8545-d44f50fa7140","name":"OpenAI 4.1 mini1","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-1500,940],"parameters":{},"typeVersion":1.2},{"id":"4d2917c3-b6a2-4f3d-a694-95c2385a62a1","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1580,600],"parameters":{"content":""},"typeVersion":1},{"id":"a3541b48-3a65-468b-8091-792649a745ef","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-60,540],"parameters":{"content":""},"typeVersion":1},{"id":"f40e6bfe-c6ab-40f0-afe8-848d297181ba","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[-60,1260],"parameters":{"content":""},"typeVersion":1},{"id":"fe9d95f1-49b0-4577-b79b-f3fc82a88de5","name":"Social Media Content","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[2580,420],"parameters":{},"typeVersion":1.2},{"id":"99b24a6f-ee0a-49a7-b2c6-2cf016b242c5","name":"gpt-4.1 mini","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[2280,420],"parameters":{},"typeVersion":1.2},{"id":"c500b909-1949-4862-9a47-021fce4d601a","name":"Social Media Content Creator","type":"@n8n/n8n-nodes-langchain.agent","position":[2320,160],"parameters":{},"retryOnFail":true,"typeVersion":1.7},{"id":"1bfd8b2b-5c4c-4ced-b7bb-d08affd9a439","name":"Upload media to Instagram","type":"n8n-nodes-base.facebookGraphApi","position":[1820,1200],"parameters":{},"typeVersion":1},{"id":"06c54ed2-3abf-4237-936e-6f8d25c4b7be","name":"Publish Post on IG","type":"n8n-nodes-base.facebookGraphApi","position":[1980,1200],"parameters":{},"typeVersion":1},{"id":"73de50b2-f249-4188-9f2e-e55400fb2dad","name":"Facebook Post1","type":"n8n-nodes-base.facebookGraphApi","onError":"continueRegularOutput","position":[1840,1600],"parameters":{},"typeVersion":1,"alwaysOutputData":true},{"id":"a8da9f48-3b83-4fac-905d-209e44311268","name":"Edit Fields1","type":"n8n-nodes-base.set","position":[4620,-60],"parameters":{},"typeVersion":3.4},{"id":"6d3ab439-1af8-4331-982d-b06df191ba9a","name":"Merge3","type":"n8n-nodes-base.merge","position":[4700,140],"parameters":{},"typeVersion":3.1},{"id":"44cf4d27-05df-4512-8958-f0fa66d95afe","name":"Merge4","type":"n8n-nodes-base.merge","position":[4720,520],"parameters":{},"typeVersion":3.1},{"id":"6c3284e9-ed1a-4a1e-a2e7-409cc379eced","name":"Edit Fields2","type":"n8n-nodes-base.set","position":[4560,360],"parameters":{},"typeVersion":3.4},{"id":"06547676-59d7-416e-85ca-e85666a72125","name":"X","type":"n8n-nodes-base.twitter","position":[1840,1980],"parameters":{},"typeVersion":2},{"id":"f00830b5-9035-439c-be46-cc24e0446f72","name":"Sticky Note18","type":"n8n-nodes-base.stickyNote","position":[1580,1840],"parameters":{"content":""},"typeVersion":1},{"id":"eaa1c88a-3629-4d0d-95a6-4fed7cb2c278","name":"Merge","type":"n8n-nodes-base.merge","position":[2660,1440],"parameters":{},"typeVersion":3.1},{"id":"ff7d2733-84a9-4e1a-8068-7f4f5f136ac0","name":"Gmail","type":"n8n-nodes-base.gmail","position":[3740,1540],"webhookId":"916ba034-43a5-46e7-a35c-fd1498db9d12","parameters":{},"typeVersion":2.1},{"id":"60857340-ea45-409c-84bc-5a186b276990","name":"Add too Data Bank","type":"n8n-nodes-base.googleSheets","position":[3220,1440],"parameters":{},"typeVersion":4.5},{"id":"8107eb68-f038-4cb4-bc93-804ac901662e","name":"Sticky Note12","type":"n8n-nodes-base.stickyNote","position":[3580,400],"parameters":{"content":""},"typeVersion":1},{"id":"78edbe8a-b901-4344-b949-b6ec2f214524","name":"Sticky Note13","type":"n8n-nodes-base.stickyNote","position":[3560,20],"parameters":{"content":""},"typeVersion":1},{"id":"05de5f97-fda8-42ed-829d-e844f3fc6a74","name":"Sticky Note14","type":"n8n-nodes-base.stickyNote","position":[1240,1000],"parameters":{"content":""},"typeVersion":1},{"id":"18335555-0037-4d9c-81ea-9d632fdb5d04","name":"Sticky Note15","type":"n8n-nodes-base.stickyNote","position":[2160,-60],"parameters":{"content":""},"typeVersion":1},{"id":"e33d1e93-b242-4383-ae25-01506b2de480","name":"Sticky Note16","type":"n8n-nodes-base.stickyNote","position":[2920,-80],"parameters":{"content":""},"typeVersion":1},{"id":"9ec1629d-50f1-4bf3-850d-241725b6b66d","name":"Sticky Note17","type":"n8n-nodes-base.stickyNote","position":[2480,1140],"parameters":{"content":""},"typeVersion":1},{"id":"24e2edc5-5f05-4ab2-9846-dc1e24e2b52e","name":"Aggregate1","type":"n8n-nodes-base.aggregate","position":[2880,1440],"parameters":{},"typeVersion":1},{"id":"23e18303-51fd-4c8a-9575-b0a2b8606a4d","name":"Sticky Note19","type":"n8n-nodes-base.stickyNote","position":[3560,1140],"parameters":{"content":""},"typeVersion":1},{"id":"dc4fd5e8-e07e-4c42-9ad8-8c9cfbaec989","name":"Sticky Note10","type":"n8n-nodes-base.stickyNote","position":[-2660,-220],"parameters":{"content":""},"typeVersion":1},{"id":"f19e24ac-8fc0-4b86-b87f-d435ff80a71a","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[1160,-220],"parameters":{"content":""},"typeVersion":1},{"id":"b7725230-33b0-4dae-82f8-e2ef31c465da","name":"Edit Fields3","type":"n8n-nodes-base.set","position":[1620,140],"parameters":{},"typeVersion":3.4},{"id":"4b55a423-64b2-4f76-b824-5810653d6977","name":"OpenAI1","type":"@n8n/n8n-nodes-langchain.openAi","position":[3900,120],"parameters":{},"typeVersion":1.8},{"id":"1d0c17cf-52e4-4bde-bb6f-d77b854890a9","name":"OpenAI2","type":"@n8n/n8n-nodes-langchain.openAi","position":[3920,500],"parameters":{},"typeVersion":1.8},{"id":"0bd64785-617b-4ba5-ab5c-bcda09c6f08c","name":"Post image Cloudinary1","type":"n8n-nodes-base.httpRequest","position":[4200,500],"parameters":{},"typeVersion":4.2},{"id":"97c1ee7e-6d3f-4239-97cf-69f3cba626df","name":"Post image Cloudinary","type":"n8n-nodes-base.httpRequest","position":[4180,120],"parameters":{},"typeVersion":4.2},{"id":"1017a22d-4611-4372-8754-d27ae44cf105","name":"Sticky Note20","type":"n8n-nodes-base.stickyNote","position":[5140,-220],"parameters":{"content":""},"typeVersion":1},{"id":"d371b329-85a8-493d-88f7-225f0eef0321","name":"Sticky Note21","type":"n8n-nodes-base.stickyNote","position":[-3420,-220],"parameters":{"content":""},"typeVersion":1},{"id":"29dec5f4-f490-4900-877b-19089e282775","name":"Sticky Note22","type":"n8n-nodes-base.stickyNote","position":[-1240,-160],"parameters":{"content":""},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"2d63b6f6-0a30-41cc-a909-e5bdd02affe9","connections":{"X":{"main":[[{"node":"Merge","type":"main","index":2}]]},"Merge":{"main":[[{"node":"Aggregate1","type":"main","index":0}]]},"Merge3":{"main":[[{"node":"Upload media to Instagram","type":"main","index":0}]]},"Merge4":{"main":[[{"node":"Facebook Post1","type":"main","index":0}]]},"Notion":{"main":[[{"node":"Aggregate","type":"main","index":0}]]},"OpenAI":{"main":[[{"node":"Upload Image to Wordpress2","type":"main","index":0}],[{"node":"Write prompt to search image","type":"main","index":0}]]},"OpenAI1":{"main":[[{"node":"Post image Cloudinary","type":"main","index":0}]]},"OpenAI2":{"main":[[{"node":"Post image Cloudinary1","type":"main","index":0}]]},"Markdown":{"main":[[{"node":"Update list of blog post","type":"main","index":0}]]},"Aggregate":{"main":[[{"node":"Edit Fields","type":"main","index":0}]]},"Wordpress":{"main":[[{"node":"Write prompt to create image","type":"main","index":0}]]},"Aggregate1":{"main":[[{"node":"Add too Data Bank","type":"main","index":0}]]},"Edit Fields1":{"main":[[{"node":"Merge3","type":"main","index":1}]]},"Edit Fields2":{"main":[[{"node":"Merge4","type":"main","index":1}]]},"Edit Fields3":{"main":[[{"node":"Social Media Content Creator","type":"main","index":0}]]},"Idea creator":{"main":[[{"node":"Category rewrite","type":"main","index":0}]]},"gpt-4.1 mini":{"ai_languageModel":[[{"node":"Social Media Content Creator","type":"ai_languageModel","index":0}]]},"Cleanup HTML ":{"main":[[{"node":"Wordpress","type":"main","index":0}]]},"Cleanup Links":{"main":[[{"node":"Content writer","type":"main","index":0}]]},"Google Sheets":{"ai_tool":[[{"node":"Idea creator","type":"ai_tool","index":0}]]},"Simple Memory":{"ai_memory":[[{"node":"Idea creator","type":"ai_memory","index":0}]]},"Content writer":{"main":[[{"node":"Cleanup HTML ","type":"main","index":0}]]},"Download Image":{"main":[[{"node":"Upload Image to Wordpress","type":"main","index":0}]]},"Facebook Post1":{"main":[[{"node":"Merge","type":"main","index":1}]]},"Excerpt creator":{"main":[[{"node":"WordPress excerpt add","type":"main","index":0}]]},"OpenAI 4.1 mini":{"ai_languageModel":[[{"node":"Content writer","type":"ai_languageModel","index":0}]]},"get brand brief":{"ai_tool":[[{"node":"Idea creator","type":"ai_tool","index":0}]]},"Category rewrite":{"main":[[{"node":"Perplexity Research1","type":"main","index":0}]]},"OpenAI 4.1 mini1":{"ai_languageModel":[[{"node":"Write prompt to search image","type":"ai_languageModel","index":0}]]},"OpenAI 4.1 mini2":{"ai_languageModel":[[{"node":"Excerpt creator","type":"ai_languageModel","index":0}]]},"OpenAI 4.1 mini3":{"ai_languageModel":[[{"node":"Idea creator","type":"ai_languageModel","index":0}]]},"OpenAI 4.1 mini4":{"ai_languageModel":[[{"node":"Write prompt to create image","type":"ai_languageModel","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Idea creator","type":"main","index":0}]]},"Update base post":{"main":[[{"node":"Edit Fields3","type":"main","index":0}]]},"Add too Data Bank":{"main":[[{"node":"Gmail","type":"main","index":0}]]},"Publish Post on IG":{"main":[[{"node":"Merge","type":"main","index":0}]]},"Perplexity Research1":{"main":[[{"node":"Cleanup Links","type":"main","index":0}]]},"Social Media Content":{"ai_outputParser":[[{"node":"Social Media Content Creator","type":"ai_outputParser","index":0}]]},"Get Image from Pexcel":{"main":[[{"node":"Download Image","type":"main","index":0}]]},"Post image Cloudinary":{"main":[[{"node":"Merge3","type":"main","index":0}]]},"WordPress excerpt add":{"main":[[{"node":"Markdown","type":"main","index":0}]]},"Post image Cloudinary1":{"main":[[{"node":"Merge4","type":"main","index":0}]]},"Update list of blog post":{"main":[[{"node":"Update base post","type":"main","index":0}]]},"Structured Output Parser1":{"ai_outputParser":[[{"node":"Idea creator","type":"ai_outputParser","index":0}]]},"Upload Image to Wordpress":{"main":[[{"node":"Set Image on Wordpress Post","type":"main","index":0}]]},"Upload media to Instagram":{"main":[[{"node":"Publish Post on IG","type":"main","index":0}]]},"Upload Image to Wordpress2":{"main":[[{"node":"Set Image on Wordpress Post2","type":"main","index":0}]]},"Set Image on Wordpress Post":{"main":[[{"node":"Excerpt creator","type":"main","index":0}]]},"Set Image on Wordpress Post2":{"main":[[{"node":"Excerpt creator","type":"main","index":0}]]},"Social Media Content Creator":{"main":[[{"node":"Edit Fields2","type":"main","index":0},{"node":"Edit Fields1","type":"main","index":0},{"node":"X","type":"main","index":0},{"node":"OpenAI1","type":"main","index":0},{"node":"OpenAI2","type":"main","index":0}]]},"Write prompt to create image":{"main":[[{"node":"OpenAI","type":"main","index":0}]]},"Write prompt to search image":{"main":[[{"node":"Get Image from Pexcel","type":"main","index":0}]]},"When Executed by Another Workflow":{"main":[[{"node":"Notion","type":"main","index":0}]]},"When clicking ‘Test workflow’":{"main":[[{"node":"Idea creator","type":"main","index":0}]]}}}


name: AI Sales Agent: WhatsApp, FB, IG, OpenAI, Airtable, Supabase Auto-Booking
author_name: Sam Yassine
author_username: samyassine
categories: []
created_at: 2025-05-15T19:39:14.260Z
updated_at: 2025-05-15T19:39:14.260Z
url: https://n8n.io/workflows/4083
scraped_at: 2025-06-19 22:49:14
description:
  This workflow automates multi-channel AI-driven sales engagement for lead qualification, service information delivery, and consultation booking. It integrates WhatsApp, Facebook Messenger, Instagram DM, and an n8n chat interface with a backend CRM (Airtable), a knowledge base (Supabase), and conversational AI (OpenAI), all orchestrated by n8n.

  Tools & Services Used

  Messaging Platforms: WhatsApp, Facebook Messenger, Instagram DM, n8n Built-in Chat

  AI Core & Processing: OpenAI (GPT-4o for main agent logic, Whisper for audio transcription)

  CRM & Data Management: Airtable (for initial WhatsApp lead lookup, lead form submissions, and as the backend for the crmAgent sub-workflow operations)

  Knowledge Base: Supabase (Vector Store for technical_and_sales_knowledge tool)

  Chat Memory: PostgreSQL (for the main AI Agent's conversation history)

  Orchestration & Automation: n8n (Self-hosted, utilizing Langchain community nodes)

  Calendar Service: Integrated via the calendarAgent sub-workflow

  CRM Service: Integrated via the crmAgent sub-workflow (interacting with Airtable)

  Workflow Overview

  This automation performs the following steps:

  Trigger: A new interaction is initiated through one of the following channels:

  A new message is received via the WhatsApp Trigger.

  A new message is received via the Facebook Trigger (Webhook).

  A new message is received via the Instagram Trigger (Webhook).

  A new message is received via the n8n Chat Trigger.

  Alternatively, a new lead is submitted via the Airtable Form Submitted Webhook.

  Channel-Specific Ingestion & Pre-processing:

  For WhatsApp:

  The system attempts to find an existing lead in Airtable using the sender's phone number.

  Incoming messages are routed by the Handle Message Types switch:

  Text messages are passed to the Edit Fields - chat1 node to prepare input for the AI Agent, including any found lead information.

  Audio messages are processed: the WhatsApp Business Cloud node gets the media URL, the HTTP Request node downloads the audio, OpenAI transcribes it to text, and Edit Fields - chat2 prepares this transcribed text and lead information for the AI Agent.

  Unsupported message types trigger the Reply To User1 node to send a notification that the message type cannot be processed.

  For Facebook Messenger:

  The system responds to webhook verification (Respond to Webhook - facebook get) and acknowledges new messages (Respond to Webhook - facebook post).

  The If is not echo - facebook node filters out messages sent by the page.

  The Sales Agent Demo - typing_on node sends a typing indicator.

  The Edit Fields - facebook node prepares the message text, sender ID, and Facebook-specific context for the AI Agent.

  For Instagram DM:

  The system responds to webhook verification (Respond to Webhook - instagram get) and acknowledges new messages (Respond to Webhook - instagram post).

  The If is not echo - instagram node filters out messages sent by the business account.

  The Edit Fields - instagram node prepares the message text, sender ID, and Instagram-specific context for the AI Agent.

  For n8n Chat:

  The Edit Fields - chat node prepares the user's input and session information for the AI Agent.

  Input Aggregation for AI Agent:

  Processed data from all active messaging channels (WhatsApp text/audio, Facebook, Instagram, n8n Chat) is funneled through the No Operation, do nothing node to the main AI Agent.

  AI Sales Conversation & Tool Utilization:

  The AI Agent (using OpenAI Chat Model - GPT-4o, and Postgres Chat Memory) engages the user according to its system prompt, aiming to qualify them for Paint Protection Film (PPF), Ceramic Coating, or Window Tint.

  The AI Agent uses the technical_and_sales_knowledge tool (which queries the Demo Supabase vector store via Embeddings OpenAI and OpenAI Chat Model1) to provide service details and answer questions.

  The AI Agent uses the crmAgent tool (a sub-workflow) to log contact details (Name, Email, service interest) and update opportunity statuses in Airtable.

  The AI Agent uses the calendarAgent tool (a sub-workflow) to book consultation appointments once preferred dates/times are provided. This occurs after contact details are logged in the CRM.

  Response Delivery:

  The AI Agent's final textual response is passed to the Switch node.

  The Switch node routes the response to the appropriate node for delivery on the original channel:

  Reply To User for WhatsApp.

  Facebook Graph API - Sales Agent Demo for Facebook Messenger.

  Instagram Graph API - smb.sales.agent.demo for Instagram DM.

  Output - chat for the n8n Chat interface.

  Airtable Form Submission Processing (Separate Branch):

  When the Airtable Form Submitted webhook receives data, the Airtable node fetches the full record.

  The Create Contact node creates a new contact in the Airtable 'Contacts' table.

  The Edit Fields - form node prepares data for a notification.

  The WhatsApp Business Cloud2 node sends a templated WhatsApp message to the lead, confirming their form submission.

nodes_used:
  ["n8n-nodes-base.airtable","n8n-nodes-base.httpRequest","n8n-nodes-base.facebookGraphApi","n8n-nodes-base.whatsApp","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.embeddingsOpenAi","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.toolWorkflow","@n8n/n8n-nodes-langchain.vectorStoreSupabase","@n8n/n8n-nodes-langchain.openAi","@n8n/n8n-nodes-langchain.memoryPostgresChat","@n8n/n8n-nodes-langchain.toolVectorStore"]

workflow_json:
  {"id":"x1h3jkRytSerUGhu","meta":{"instanceId":"5beb610c1ddaf0be11e46fd8edaf0e265560c93f1638f8638d6a8a7adf44f57e"},"name":"Advanced Sales Ai agent","tags":[{"id":"yyl2ODGPNBCXNLhN","name":"Completed","createdAt":"2025-04-28T23:47:07.492Z","updatedAt":"2025-04-28T23:47:07.492Z"}],"nodes":[{"id":"9addca79-498b-44cc-8b7b-da5689c443d4","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[2800,800],"parameters":{},"typeVersion":1.7},{"id":"655b1e6f-88cb-4417-8ed6-41b8e7f39c20","name":"No Operation, do nothing","type":"n8n-nodes-base.noOp","position":[2540,800],"parameters":{},"typeVersion":1},{"id":"3147df28-dcbb-4570-8a0a-5fe72832718d","name":"Switch","type":"n8n-nodes-base.switch","position":[3940,700],"parameters":{},"typeVersion":3.2},{"id":"2514349d-d847-4396-b634-c2ef777588d5","name":"Facebook Trigger","type":"n8n-nodes-base.webhook","position":[1180,840],"webhookId":"b7e461f0-9a0d-4e27-9e86-f74a3e684e3a","parameters":{},"typeVersion":2},{"id":"60321484-988a-4190-9282-ea7dd1b39c26","name":"Edit Fields - facebook","type":"n8n-nodes-base.set","position":[1640,920],"parameters":{},"typeVersion":3.4},{"id":"65a6d0de-14d9-4dd9-9efc-1ad6d7b79cd4","name":"Respond to Webhook - facebook post","type":"n8n-nodes-base.respondToWebhook","position":[1440,720],"parameters":{},"typeVersion":1.1},{"id":"25d0ee32-1dcd-4a6f-9119-d23561c110e8","name":"Respond to Webhook - facebook get","type":"n8n-nodes-base.respondToWebhook","position":[1420,900],"parameters":{},"typeVersion":1.1},{"id":"6fab5fc8-e30e-476b-b45f-f03d7b1a7195","name":"Instagram Trigger","type":"n8n-nodes-base.webhook","position":[1120,1360],"webhookId":"cc6546da-6f16-4546-ada3-e2c83b208997","parameters":{},"typeVersion":2},{"id":"f07daa8f-4392-478c-b56f-ce230241d87d","name":"Respond to Webhook - instagram get","type":"n8n-nodes-base.respondToWebhook","position":[1380,1460],"parameters":{},"typeVersion":1.1},{"id":"dfceb449-89ae-4c58-884d-b77d21c09020","name":"Respond to Webhook - instagram post","type":"n8n-nodes-base.respondToWebhook","position":[1380,1260],"parameters":{},"typeVersion":1.1},{"id":"4c137f1e-1bbc-48f2-900e-24be7096372c","name":"Edit Fields - instagram","type":"n8n-nodes-base.set","position":[1840,1260],"parameters":{},"typeVersion":3.4},{"id":"f6bd4f71-f5f5-4ad1-a3b3-4b0de83767a1","name":"If is not echo - facebook","type":"n8n-nodes-base.if","position":[1640,720],"parameters":{},"typeVersion":2.2},{"id":"40df05f1-eea9-42ad-8ff4-6cfe1d4b8e1a","name":"If is not echo - instagram","type":"n8n-nodes-base.if","position":[1600,1260],"parameters":{},"typeVersion":2.2},{"id":"c6bd22d4-293b-49d8-94a2-da2851a0fbde","name":"Embeddings OpenAI","type":"@n8n/n8n-nodes-langchain.embeddingsOpenAi","position":[2880,1440],"parameters":{},"typeVersion":1},{"id":"e32746ce-7593-4ae5-9fc6-1834bf7116cf","name":"OpenAI Chat Model1","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[3080,1240],"parameters":{},"typeVersion":1},{"id":"068daa60-de05-4106-b408-d904898f44a0","name":"Demo Supabase","type":"@n8n/n8n-nodes-langchain.vectorStoreSupabase","position":[2780,1240],"parameters":{},"typeVersion":1},{"id":"8088cc8d-cb56-43b5-ac20-fddfe6721a0c","name":"Calendar Agent","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[2640,1040],"parameters":{},"typeVersion":2},{"id":"fd7cc952-a433-4c6f-865c-1fe0406daf34","name":"CRM Agent","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[2760,1040],"parameters":{},"typeVersion":2},{"id":"90152733-4a5d-4c39-b274-838b86c7214b","name":"Postgres Chat Memory","type":"@n8n/n8n-nodes-langchain.memoryPostgresChat","position":[2520,1040],"parameters":{},"typeVersion":1.3},{"id":"f82219d3-e81e-4735-8fec-428e24e306cb","name":"sales_technique_knowledge","type":"@n8n/n8n-nodes-langchain.toolVectorStore","position":[2880,1040],"parameters":{},"typeVersion":1},{"id":"31301f2b-8fa4-46f8-be5c-98d2013123cf","name":"Handle Message Types","type":"n8n-nodes-base.switch","position":[1640,360],"parameters":{},"typeVersion":3.2},{"id":"7429d3a0-1da8-45ca-8886-7bf6c335f28b","name":"Reply To User1","type":"n8n-nodes-base.whatsApp","position":[1860,220],"webhookId":"0e86d9ab-6130-44f5-a7f1-4930bfcad48b","parameters":{},"typeVersion":1},{"id":"e3144cd3-dcaa-4fcf-9760-f8f8b12f5351","name":"Edit Fields - chat1","type":"n8n-nodes-base.set","position":[2160,380],"parameters":{},"typeVersion":3.4},{"id":"e51934e6-ba7b-455e-86b9-f2dfbf2283a6","name":"Reply To  User","type":"n8n-nodes-base.whatsApp","position":[4160,360],"webhookId":"3b2ca5bf-7b1d-4012-b68e-ef06653a3c18","parameters":{},"typeVersion":1},{"id":"d64c1897-7e0b-45a0-bdbc-515b7ade019c","name":"WhatsApp","type":"n8n-nodes-base.whatsAppTrigger","position":[1200,360],"webhookId":"aaf6d81e-dbdd-47e2-a2d4-c496ff92933b","parameters":{},"typeVersion":1},{"id":"ae61d0df-d990-48a7-89bf-77bc23dbe0a8","name":"WhatsApp Business Cloud","type":"n8n-nodes-base.whatsApp","position":[1860,360],"webhookId":"5cbf4730-3963-45f9-8457-6f41e648d4fe","parameters":{},"typeVersion":1},{"id":"7d426761-cc8e-40dc-8379-c68c587a5535","name":"HTTP Request","type":"n8n-nodes-base.httpRequest","position":[2160,540],"parameters":{},"typeVersion":4.2},{"id":"2a9389b2-06d0-4c0c-9258-fa00108221fb","name":"OpenAI","type":"@n8n/n8n-nodes-langchain.openAi","position":[2160,760],"parameters":{},"typeVersion":1.8},{"id":"fe272020-8965-4141-8424-bfcd60a2879c","name":"Edit Fields - chat2","type":"n8n-nodes-base.set","position":[2160,980],"parameters":{},"typeVersion":3.4},{"id":"1d11a556-6fef-4aa7-9647-235df6bb0adb","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[2600,1280],"parameters":{},"typeVersion":1.2},{"id":"244019eb-6458-412d-8723-7cf80dda66e0","name":"Airtable","type":"n8n-nodes-base.airtable","position":[1920,1900],"parameters":{},"typeVersion":2.1},{"id":"c3cc2f61-c783-4012-ac86-de0b5509f5bf","name":"Edit Fields - form","type":"n8n-nodes-base.set","position":[2360,1900],"parameters":{},"typeVersion":3.4},{"id":"e8fd649e-196e-43c9-a6b1-380bb0edab28","name":"Airtable Form Submitted","type":"n8n-nodes-base.webhook","position":[1700,1900],"webhookId":"743228b1-915f-4628-a74a-ac277d227051","parameters":{},"typeVersion":2},{"id":"159c829d-5793-46bf-a946-bde7dfcdd573","name":"Sales Agent Demo - typing_on","type":"n8n-nodes-base.facebookGraphApi","position":[1860,720],"parameters":{},"typeVersion":1},{"id":"8cf6f3a6-24e5-4d15-a04f-26a4ea03b863","name":"Facebook Graph API - Sales Agent Demo","type":"n8n-nodes-base.facebookGraphApi","position":[4160,560],"parameters":{},"typeVersion":1},{"id":"289d92fe-2b53-4e15-81ed-73adaaa0df02","name":"Instagram Graph API - smb.sales.agent.demo","type":"n8n-nodes-base.httpRequest","position":[4160,760],"parameters":{},"typeVersion":4.2},{"id":"25076437-3d9b-454c-83a7-bd318710c093","name":"AI Agent1","type":"@n8n/n8n-nodes-langchain.agent","position":[2720,-100],"parameters":{},"typeVersion":1.7},{"id":"d0a454bf-f377-472e-a6b2-63c058d4cebf","name":"Embeddings OpenAI1","type":"@n8n/n8n-nodes-langchain.embeddingsOpenAi","position":[2520,340],"parameters":{},"typeVersion":1},{"id":"158c32ff-3aa8-4878-92f5-3577d02da43f","name":"OpenAI Chat Model2","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[2960,360],"parameters":{},"typeVersion":1},{"id":"8b71ff29-e758-40bf-8bbc-2c72ec8b77f7","name":"Demo Supabase1","type":"@n8n/n8n-nodes-langchain.vectorStoreSupabase","position":[2660,360],"parameters":{},"typeVersion":1},{"id":"d827e73a-7069-4b4b-a97c-8d73481905c4","name":"Postgres Chat Memory1","type":"@n8n/n8n-nodes-langchain.memoryPostgresChat","position":[2640,160],"parameters":{},"typeVersion":1.3},{"id":"c0aaf0c6-a29c-4b5d-a91a-caa24447b68c","name":"sales_technique_knowledge1","type":"@n8n/n8n-nodes-langchain.toolVectorStore","position":[2760,160],"parameters":{},"typeVersion":1},{"id":"6405d310-4cb7-4c55-8484-7f45ca40d45a","name":"OpenAI Chat Model3","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[2520,160],"parameters":{},"typeVersion":1.2},{"id":"cdf2597f-934c-47d3-b843-22d531fe4f61","name":"Calendar Agent1","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[3060,160],"parameters":{},"typeVersion":2},{"id":"f8897f1a-3b3b-412d-81af-2002fc023703","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[1600,1440],"webhookId":"c959ad76-d935-437f-8380-4776b1bcf52a","parameters":{},"typeVersion":1.1},{"id":"7606244f-a59f-48d6-9ca0-8fa2cf7d83bf","name":"Edit Fields - chat","type":"n8n-nodes-base.set","position":[1840,1460],"parameters":{},"typeVersion":3.4},{"id":"fefa88ca-dd9d-4061-a76a-aeb2155dedf0","name":"Output - chat","type":"n8n-nodes-base.set","position":[4160,960],"parameters":{},"typeVersion":3.4},{"id":"1cfdc044-870f-464a-8431-0408f4fe7409","name":"WhatsApp Business Cloud2","type":"n8n-nodes-base.whatsApp","position":[2580,1900],"webhookId":"efdf335a-e120-488f-bfd0-bae49c454b6c","parameters":{},"typeVersion":1},{"id":"f0ab4ccf-c9df-45c1-8d22-647d9c143ba9","name":"Get Lead","type":"n8n-nodes-base.airtable","onError":"continueRegularOutput","position":[1420,360],"parameters":{},"typeVersion":2.1},{"id":"6b942af3-b796-4860-953d-f7d2aef4b201","name":"Create Contact","type":"n8n-nodes-base.airtable","position":[2140,1900],"parameters":{},"typeVersion":2.1},{"id":"a7c9dd71-db24-405a-9193-e9b37d05f915","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[2400,-180],"parameters":{"content":""},"typeVersion":1},{"id":"4a15e4c3-6523-432e-ab43-aecdc396f3cd","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[820,160],"parameters":{"content":""},"typeVersion":1},{"id":"6becd7d1-b79a-4307-8d35-3d18ef6f76c8","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[820,640],"parameters":{"content":""},"typeVersion":1},{"id":"40c195f1-43f5-488d-a4b0-db3fc78b1955","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[820,1160],"parameters":{"content":""},"typeVersion":1},{"id":"8747a173-9ab7-46f5-bd0b-aae2c3ad9358","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[2400,540],"parameters":{"content":""},"typeVersion":1},{"id":"f01553e6-3aca-4d23-8b40-c8114b988fa1","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[1480,1740],"parameters":{"content":""},"typeVersion":1},{"id":"3575bafb-4ea5-4b82-b18a-a01d2f7cbb29","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[3720,100],"parameters":{"content":""},"typeVersion":1},{"id":"1638cf86-cb3f-49c6-a917-37c6b0f9407a","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[2100,220],"parameters":{"content":""},"typeVersion":1}],"active":false,"pinData":{"WhatsApp":[{"json":{"field":"messages","contacts":[{"wa_id":"5511943305954","profile":{"name":"Ben"}}],"messages":[{"id":"wamid.HBgNNTUxMTk0MzMwNTk1NBUCABIYFDNBMzZCMzEzRkE3NEE5QTY4QkY2AA==","from":"5511943305954","type":"audio","audio":{"id":"1035082928515514","voice":true,"sha256":"cvEinUroWyJwJnXdrmNKh58AEenizXyZckc+MR5LDVc=","mime_type":"audio/ogg; codecs=opus"},"timestamp":"1743505155"}],"metadata":{"phone_number_id":"278982118641623","display_phone_number":"5511911957545"},"messaging_product":"whatsapp"}}],"Airtable Form Submitted":[{"json":{"body":{},"query":{"tableId":"tblx4RCYHWg0QDPhk","recordId":"recEOSF2sMmS7Zl3G"},"params":{},"headers":{"host":"n8n.benai.agency","accept":"*/*","x-real-ip":"54.163.57.194","user-agent":"Mozilla/5.0 (compatible; AirtableScripting; +https://airtable.com/developers/scripting;)","accept-encoding":"gzip,deflate","x-forwarded-for":"54.163.57.194","x-forwarded-host":"n8n.benai.agency","x-forwarded-port":"443","x-airtable-source":"appmZHna96JsKNeJL/wflTdWRuMMUw4eaTR","x-forwarded-proto":"https","x-forwarded-server":"4f7a0fd81c9f"},"webhookUrl":"https://n8n.benai.agency/webhook/sales-lead-form","executionMode":"production"}}]},"settings":{"executionOrder":"v1"},"versionId":"bddbe12d-a6dd-497b-846b-8216603ab80e","connections":{"OpenAI":{"main":[[{"node":"Edit Fields - chat2","type":"main","index":0}]]},"Switch":{"main":[[{"node":"Reply To  User","type":"main","index":0}],[{"node":"Facebook Graph API - Sales Agent Demo","type":"main","index":0}],[{"node":"Instagram Graph API - smb.sales.agent.demo","type":"main","index":0}],[{"node":"Output - chat","type":"main","index":0}]]},"AI Agent":{"main":[[{"node":"Switch","type":"main","index":0}]]},"Airtable":{"main":[[{"node":"Create Contact","type":"main","index":0}]]},"Get Lead":{"main":[[{"node":"Handle Message Types","type":"main","index":0}]]},"WhatsApp":{"main":[[{"node":"Get Lead","type":"main","index":0}]]},"CRM Agent":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"HTTP Request":{"main":[[{"node":"OpenAI","type":"main","index":0}]]},"Demo Supabase":{"ai_vectorStore":[[{"node":"sales_technique_knowledge","type":"ai_vectorStore","index":0}]]},"Calendar Agent":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Create Contact":{"main":[[{"node":"Edit Fields - form","type":"main","index":0}]]},"Demo Supabase1":{"ai_vectorStore":[[{"node":"sales_technique_knowledge1","type":"ai_vectorStore","index":0}]]},"Calendar Agent1":{"ai_tool":[[{"node":"AI Agent1","type":"ai_tool","index":0}]]},"Facebook Trigger":{"main":[[{"node":"Respond to Webhook - facebook post","type":"main","index":0}],[{"node":"Respond to Webhook - facebook get","type":"main","index":0}]]},"Embeddings OpenAI":{"ai_embedding":[[{"node":"Demo Supabase","type":"ai_embedding","index":0}]]},"Instagram Trigger":{"main":[[{"node":"Respond to Webhook - instagram post","type":"main","index":0}],[{"node":"Respond to Webhook - instagram get","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Edit Fields - chat":{"main":[[{"node":"No Operation, do nothing","type":"main","index":0}]]},"Edit Fields - form":{"main":[[{"node":"WhatsApp Business Cloud2","type":"main","index":0}]]},"Embeddings OpenAI1":{"ai_embedding":[[{"node":"Demo Supabase1","type":"ai_embedding","index":0}]]},"OpenAI Chat Model1":{"ai_languageModel":[[{"node":"sales_technique_knowledge","type":"ai_languageModel","index":0}]]},"OpenAI Chat Model2":{"ai_languageModel":[[{"node":"sales_technique_knowledge1","type":"ai_languageModel","index":0}]]},"OpenAI Chat Model3":{"ai_languageModel":[[{"node":"AI Agent1","type":"ai_languageModel","index":0}]]},"Edit Fields - chat1":{"main":[[{"node":"No Operation, do nothing","type":"main","index":0}]]},"Edit Fields - chat2":{"main":[[{"node":"No Operation, do nothing","type":"main","index":0}]]},"Handle Message Types":{"main":[[{"node":"Edit Fields - chat1","type":"main","index":0}],[{"node":"WhatsApp Business Cloud","type":"main","index":0}],[{"node":"Reply To User1","type":"main","index":0}]]},"Postgres Chat Memory":{"ai_memory":[[{"node":"AI Agent","type":"ai_memory","index":0}]]},"Postgres Chat Memory1":{"ai_memory":[[{"node":"AI Agent1","type":"ai_memory","index":0}]]},"Edit Fields - facebook":{"main":[[{"node":"No Operation, do nothing","type":"main","index":0}]]},"Airtable Form Submitted":{"main":[[{"node":"Airtable","type":"main","index":0}]]},"Edit Fields - instagram":{"main":[[{"node":"No Operation, do nothing","type":"main","index":0}]]},"WhatsApp Business Cloud":{"main":[[{"node":"HTTP Request","type":"main","index":0}]]},"No Operation, do nothing":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"If is not echo - facebook":{"main":[[{"node":"Edit Fields - facebook","type":"main","index":0},{"node":"Sales Agent Demo - typing_on","type":"main","index":0}]]},"sales_technique_knowledge":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"If is not echo - instagram":{"main":[[{"node":"Edit Fields - instagram","type":"main","index":0}]]},"When chat message received":{"main":[[{"node":"Edit Fields - chat","type":"main","index":0}]]},"sales_technique_knowledge1":{"ai_tool":[[{"node":"AI Agent1","type":"ai_tool","index":0}]]},"Respond to Webhook - facebook post":{"main":[[{"node":"If is not echo - facebook","type":"main","index":0}]]},"Respond to Webhook - instagram post":{"main":[[{"node":"If is not echo - instagram","type":"main","index":0}]]}}}


name: AI Agent To Chat With Files In Supabase Storage and Google Drive
author_name: Mark Shcherbakov
author_username: lowcodingdev
categories: []
created_at: 2025-05-15T20:44:33.064Z
updated_at: 2025-05-15T20:44:33.064Z
url: https://n8n.io/workflows/4086
scraped_at: 2025-06-19 22:49:17
description:
  Video Guide

  I prepared a detailed guide that illustrates the entire process of building an AI agent using Supabase and Google Drive within N8N workflows.



  Youtube Link

  Who is this for?
  This workflow is designed for developers, data scientists, and business users who wish to automate document management and enable AI-powered interactions over their stored files. It's especially beneficial for scenarios where users need to process, analyze, and retrieve information from uploaded documents rapidly.

  What problem does this workflow solve?
  Managing files across multiple platforms often involves tedious manual processes. This workflow facilitates automated file handling, making it easier for users to upload, parse, and interact with documents through an AI agent. It reduces redundancy and enhances the efficiency of data retrieval and management tasks.

  What this workflow does
  This workflow integrates Supabase storage with Google Drive and employs an AI agent to manage files effectively. The agent can:
  Upload files to Supabase storage and activate processes based on file changes in Google Drive.
  Retrieve and parse documents, converting them into a structured format for easy querying.
  Utilize an AI agent to answer user queries based on saved document data.

  Data Collection: The workflow initially gathers files from Supabase storage, ensuring no duplicates are processed in the 'files' table.
  File Handling: It processes files to be parsed based on their type, leveraging LlamaParse for effective data transformation.
  Google Drive Integration: The workflow monitors a designated Google Drive folder to upload files automatically and refresh document records in the database with new data.
  AI Interaction: A webhook is established to enable the AI agent to converse with users, facilitating queries and leveraging stored document knowledge.

  Setup

  Supabase Storage Setup:
     Create a private bucket in Supabase storage, modifying the default name in the URL.
     Upload your files using the provided upload options.

  Database Configuration:
     Establish the 'file' and 'document' tables in Supabase with the necessary fields.
     Execute any required SQL queries for enabling vector matching features.

  N8N Workflow Logic:
     Start with a manual trigger for the initial workflow segment or consider alternative triggers like webhooks.
     Replace all relevant credentials across nodes with your own to ensure seamless operation.

  File Processing and Google Drive Monitoring:
     Set up file processing to take care of downloading and parsing files based on their types.
     Create triggers to monitor the designated Google Drive folder for file uploads and updates.

  Integrate AI Agent:
     Configure the webhook for the AI agent to accept chat inputs while maintaining session context for enhanced user interactions.
     Utilize PostgreSQL to store user interactions and manage conversation states effectively.  

  Testing and Adjustments:
     Once everything is set up, run tests with the AI agent to validate its responses based on the documents in your database.
     Fine-tune the workflow and AI model as needed to achieve desired performance.

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.googleDrive","n8n-nodes-base.supabase","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.embeddingsOpenAi","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.memoryBufferWindow","@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter","@n8n/n8n-nodes-langchain.vectorStoreSupabase","@n8n/n8n-nodes-langchain.documentDefaultDataLoader"]

workflow_json:
  {"meta":{"instanceId":"6a2a7715680b8313f7cb4676321c5baa46680adfb913072f089f2766f42e43bd","templateCredsSetupCompleted":true},"nodes":[{"id":"003915bb-a2e9-42b0-b81f-5bb5bf0c8cb4","name":"Get All files","type":"n8n-nodes-base.httpRequest","position":[1180,1280],"parameters":{"url":"=https://<project_id>.supabase.co/storage/v1/object/list/private","method":"POST","options":{},"jsonBody":"={\n  \"prefix\": \"\",\n  \"limit\": 100,\n  \"offset\": 0,\n  \"sortBy\": {\n    \"column\": \"name\",\n    \"order\": \"asc\"\n  }\n}","sendBody":true,"specifyBody":"json","authentication":"predefinedCredentialType","nodeCredentialType":"supabaseApi"},"credentials":{"supabaseApi":{"id":"t8AQJzvZvrOMDLec","name":"Supabase account info@ Demo"}},"typeVersion":4.2},{"id":"f46e056d-8311-4951-ad38-21759fabdaf7","name":"Default Data Loader","type":"@n8n/n8n-nodes-langchain.documentDefaultDataLoader","position":[3500,1820],"parameters":{"options":{"metadata":{"metadataValues":[{"name":"=file_id","value":"={{ $json.id }}"}]}},"jsonData":"={{ $('Merge Text').item.json.text }}","jsonMode":"expressionData"},"typeVersion":1},{"id":"3cfdcacb-d0ef-422b-9048-a64e5f0dac66","name":"Recursive Character Text Splitter","type":"@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter","position":[3520,1960],"parameters":{"options":{},"chunkSize":500,"chunkOverlap":200},"typeVersion":1},{"id":"3056ea0a-b788-43c7-a070-f40bd1ad3356","name":"Embeddings OpenAI","type":"@n8n/n8n-nodes-langchain.embeddingsOpenAi","position":[3320,1800],"parameters":{"model":"text-embedding-3-small","options":{}},"credentials":{"openAiApi":{"id":"fLfRtaXbR0EVD0pl","name":"OpenAi account"}},"typeVersion":1},{"id":"e6ad8067-0468-440d-a322-2a3de8851431","name":"Create File record2","type":"n8n-nodes-base.supabase","position":[3260,1620],"parameters":{"tableId":"files","fieldsUi":{"fieldValues":[{"fieldId":"name","fieldValue":"={{ $('Loop Over Items').item.json.name }}"},{"fieldId":"storage_id","fieldValue":"={{ $('Loop Over Items').item.json.id }}"}]}},"credentials":{"supabaseApi":{"id":"t8AQJzvZvrOMDLec","name":"Supabase account info@ Demo"}},"typeVersion":1},{"id":"53ac0d69-d935-48a0-8fb8-5cc8f591dbb8","name":"If","type":"n8n-nodes-base.if","position":[1500,1280],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"9b14e306-a04d-40f7-bc5b-b8eda8d8f7f2","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ \n    !$('Aggregate').item.json.data || \n    !Array.isArray($('Aggregate').item.json.data) || \n    !$('Aggregate').item.json.data.some(item => \n        item.storage_id === $('Loop Over Items').item.json.id \n    ) \n}}","rightValue":""},{"id":"c3c0af88-9aea-4539-8948-1b69e601c27c","operator":{"type":"string","operation":"notEquals"},"leftValue":"={{ $json.name }}","rightValue":".emptyFolderPlaceholder"}]}},"typeVersion":2.2},{"id":"f57e857a-094f-470c-ad27-9fc29466ab0e","name":"Get All Files","type":"n8n-nodes-base.supabase","position":[800,1280],"parameters":{"tableId":"files","operation":"getAll"},"credentials":{"supabaseApi":{"id":"t8AQJzvZvrOMDLec","name":"Supabase account info@ Demo"}},"typeVersion":1,"alwaysOutputData":true},{"id":"4484ca47-6879-43b7-8879-261f409014e1","name":"Download","type":"n8n-nodes-base.httpRequest","position":[1660,1280],"parameters":{"url":"=https://<project_id>.supabase.co/storage/v1/object/private/{{ $json.name }}","options":{},"authentication":"predefinedCredentialType","nodeCredentialType":"supabaseApi"},"credentials":{"supabaseApi":{"id":"t8AQJzvZvrOMDLec","name":"Supabase account info@ Demo"}},"typeVersion":4.2},{"id":"f81d2f91-d665-4217-8955-a308ef2b37be","name":"Loop Over Items","type":"n8n-nodes-base.splitInBatches","position":[1340,1280],"parameters":{"options":{},"batchSize":"=1"},"typeVersion":3},{"id":"8857a553-37aa-4ac2-ac4d-e5402849cb2e","name":"When clicking ‘Test workflow’","type":"n8n-nodes-base.manualTrigger","disabled":true,"position":[620,1280],"parameters":{},"typeVersion":1},{"id":"e967af7e-43bd-47cb-8b04-eb431a82c93b","name":"Aggregate","type":"n8n-nodes-base.aggregate","position":[1000,1280],"parameters":{"options":{},"aggregate":"aggregateAllItemData"},"typeVersion":1,"alwaysOutputData":true},{"id":"8abdb8f6-e31d-48cf-8189-831adf7d4889","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[1420,300],"webhookId":"3c40d311-7996-4ed4-b2fa-c73bea5f4cf5","parameters":{"options":{}},"typeVersion":1.1},{"id":"75cf7f9e-d8f6-4a7a-b464-d152fd025188","name":"Insert into Supabase Vectorstore","type":"@n8n/n8n-nodes-langchain.vectorStoreSupabase","position":[3420,1620],"parameters":{"mode":"insert","options":{"queryName":"match_documents"},"tableName":{"__rl":true,"mode":"list","value":"documents","cachedResultName":"documents"}},"credentials":{"supabaseApi":{"id":"t8AQJzvZvrOMDLec","name":"Supabase account info@ Demo"}},"typeVersion":1},{"id":"b3ceb557-53c6-4d19-ac97-c999ba87c7f5","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[1120,1160],"parameters":{"height":89.3775420487804,"content":"### Replace Storage name, database ID and credentials."},"typeVersion":1},{"id":"a81fe332-86ea-46aa-b140-ee5745f0b0e0","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[760,1160],"parameters":{"height":80,"content":"### Replace credentials."},"typeVersion":1},{"id":"44070cd1-0f4d-48ea-8ce0-8d59f94133e7","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[3260,1500],"parameters":{"height":80,"content":"### Replace credentials."},"typeVersion":1},{"id":"3fed931d-69de-4c1b-a951-5e49c683f551","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1620,1160],"parameters":{"height":89.3775420487804,"content":"### Replace Storage name, database ID and credentials."},"typeVersion":1},{"id":"d462978c-7ea3-4b92-a940-64756377c461","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[3220,1940],"parameters":{"height":80,"content":"### Replace credentials."},"typeVersion":1},{"id":"6f0a219d-4258-4982-b912-784a850ef308","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[2080,800],"parameters":{"height":80,"content":"### Replace credentials."},"typeVersion":1},{"id":"469b3caf-c9a8-4f8b-a745-c672e2b1089f","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[560,40],"parameters":{"color":7,"width":636.2128494576581,"height":497.1532689930921,"content":"![5min Logo](https://cflobdhpqwnoisuctsoc.supabase.co/storage/v1/object/public/my_storage/banner.png)\n## AI Agent To Chat With Files In Supabase Storage\n**Made by [Mark Shcherbakov](https://www.linkedin.com/in/marklowcoding/) from community [5minAI](https://www.skool.com/5minai-2861)**\n\nManually retrieving and analyzing specific information from large document repositories is time-consuming and inefficient. This workflow automates the process by vectorizing documents and enabling AI-powered interactions, making it easy to query and retrieve context-based information from uploaded files.\n\nThe workflow integrates Supabase with an AI-powered chatbot to process, store, and query text and PDF files. The steps include:\n- Fetching and comparing files to avoid duplicate processing.\n- Handling file downloads and extracting content based on the file type.\n- Converting documents into vectorized data for contextual information retrieval.\n- Storing and querying vectorized data from a Supabase vector store.\n\n"},"typeVersion":1},{"id":"cb6664f2-0a05-4abb-818d-d72536b57bac","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[1360,40],"parameters":{"color":5,"width":1112,"height":890,"content":"## Scenario 2 - AI agent"},"typeVersion":1},{"id":"a825794d-e7f3-41ba-a113-8503ebaf2be7","name":"Sticky Note10","type":"n8n-nodes-base.stickyNote","position":[540,1000],"parameters":{"color":5,"width":3285,"height":1139,"content":"## Scenario 1 - Flow for adding new files from Supabase storage"},"typeVersion":1},{"id":"1d44ef3b-b1d9-481c-8078-2f0d8d586247","name":"AI Agent1","type":"@n8n/n8n-nodes-langchain.agent","position":[1960,260],"parameters":{"text":"={{ $('Merge').item.json.message }}","options":{"systemMessage":"You are a helpful assistant.\n\nIMPORTANT Always use knowledge base to respond users.","passthroughBinaryImages":false},"promptType":"define"},"typeVersion":1.8},{"id":"d1da58a8-e6c0-4a6d-aa53-88c223a97f0a","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[1880,480],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"SphXAX7rlwRLkiox","name":"Test club key"}},"typeVersion":1.2},{"id":"acb2de9b-a9fa-4934-9759-b84b067dc26a","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[2020,480],"parameters":{"sessionKey":"={{ $('Merge').item.json.session_id }}","sessionIdType":"customKey"},"typeVersion":1.3},{"id":"4d91a4e9-e381-485a-847e-50b5dcc43f6b","name":"Embeddings OpenAI1","type":"@n8n/n8n-nodes-langchain.embeddingsOpenAi","position":[2160,660],"parameters":{"options":{}},"credentials":{"openAiApi":{"id":"SphXAX7rlwRLkiox","name":"Test club key"}},"typeVersion":1.2},{"id":"19b5a9a8-7407-4a1c-822f-3000b67da99b","name":"Supabase Vector Store","type":"@n8n/n8n-nodes-langchain.vectorStoreSupabase","position":[2160,500],"parameters":{"mode":"retrieve-as-tool","options":{},"toolName":"knowledge_base","tableName":{"__rl":true,"mode":"list","value":"documents","cachedResultName":"documents"},"toolDescription":"Gather facts from knowledge base to respond user."},"credentials":{"supabaseApi":{"id":"t8AQJzvZvrOMDLec","name":"Supabase account info@ Demo"}},"typeVersion":1.1},{"id":"0b48a55c-9b47-4913-9aec-264d3932c533","name":"File Created","type":"n8n-nodes-base.googleDriveTrigger","position":[600,2480],"parameters":{"event":"fileCreated","options":{},"pollTimes":{"item":[{"mode":"everyMinute"}]},"triggerOn":"specificFolder","folderToWatch":{"__rl":true,"mode":"list","value":"1rFIHlWMlbt0vAh1CWjcmNOmJYk_8jUIb","cachedResultUrl":"https://drive.google.com/drive/folders/1rFIHlWMlbt0vAh1CWjcmNOmJYk_8jUIb","cachedResultName":"Case - dentist"}},"credentials":{"googleDriveOAuth2Api":{"id":"1Irxryx1yQ3upU2i","name":"Google Drive account"}},"typeVersion":1},{"id":"fd7a9260-7d85-4129-bf2d-f7700781091b","name":"Download File","type":"n8n-nodes-base.googleDrive","position":[1200,2580],"parameters":{"fileId":{"__rl":true,"mode":"id","value":"={{ $('Set File ID').last().json.file_id }}"},"options":{"googleFileConversion":{"conversion":{"docsToFormat":"application/pdf","sheetsToFormat":"application/pdf","slidesToFormat":"application/pdf","drawingsToFormat":"application/pdf"}}},"operation":"download"},"credentials":{"googleDriveOAuth2Api":{"id":"1Irxryx1yQ3upU2i","name":"Google Drive account"}},"executeOnce":true,"typeVersion":3},{"id":"e17a7bc1-6483-439b-acb0-2b13f66466e5","name":"File Updated","type":"n8n-nodes-base.googleDriveTrigger","position":[620,2660],"parameters":{"event":"fileUpdated","options":{},"pollTimes":{"item":[{"mode":"everyMinute"}]},"triggerOn":"specificFolder","folderToWatch":{"__rl":true,"mode":"list","value":"1rFIHlWMlbt0vAh1CWjcmNOmJYk_8jUIb","cachedResultUrl":"https://drive.google.com/drive/folders/1rFIHlWMlbt0vAh1CWjcmNOmJYk_8jUIb","cachedResultName":"Case - dentist"}},"credentials":{"googleDriveOAuth2Api":{"id":"1Irxryx1yQ3upU2i","name":"Google Drive account"}},"typeVersion":1},{"id":"b0e5b639-cf0e-4289-8ce7-96e6fd1e831f","name":"Delete Old Doc Rows","type":"n8n-nodes-base.supabase","position":[1020,2580],"parameters":{"tableId":"documents","operation":"delete","filterType":"string","filterString":"=metadata->>drive_file_id=like.*{{ $json.file_id }}*"},"credentials":{"supabaseApi":{"id":"QBhcokohbJHfQZ9A","name":"Supabase club"}},"typeVersion":1,"alwaysOutputData":true},{"id":"c583b665-b756-4b8c-8150-34f559df9007","name":"Set File ID","type":"n8n-nodes-base.set","position":[860,2580],"parameters":{"options":{},"assignments":{"assignments":[{"id":"10646eae-ae46-4327-a4dc-9987c2d76173","name":"file_id","type":"string","value":"={{ $json.id }}"},{"id":"7d0b3a5e-9dfa-46d3-bf16-f6fc1d44f242","name":"extension","type":"string","value":"={{ $json.fileExtension }}"}]}},"typeVersion":3.4},{"id":"558473fe-cc06-41d8-ab06-cc6c03a8c40e","name":"Create File record1","type":"n8n-nodes-base.supabase","position":[2380,2780],"parameters":{"tableId":"files","fieldsUi":{"fieldValues":[{"fieldId":"name","fieldValue":"={{ $('Download File').item.binary.data.fileName }}"},{"fieldId":"google_drive_id","fieldValue":"={{ $('Set File ID').item.json.file_id }}"}]}},"credentials":{"supabaseApi":{"id":"t8AQJzvZvrOMDLec","name":"Supabase account info@ Demo"}},"typeVersion":1},{"id":"87e490c4-f9cb-4821-a234-a9c9d2c93836","name":"Default Data Loader1","type":"@n8n/n8n-nodes-langchain.documentDefaultDataLoader","position":[2640,2980],"parameters":{"options":{"metadata":{"metadataValues":[{"name":"=file_id","value":"={{ $json.id }}"},{"name":"drive_file_id","value":"={{ $('Set File ID').item.json.file_id }}"}]}},"jsonData":"={{ $('Set Text3').item.json.text }}","jsonMode":"expressionData"},"typeVersion":1},{"id":"373efd3c-f7dd-4efc-a268-ed05d8b2e309","name":"Embeddings OpenAI3","type":"@n8n/n8n-nodes-langchain.embeddingsOpenAi","position":[2480,2960],"parameters":{"model":"text-embedding-3-small","options":{}},"credentials":{"openAiApi":{"id":"fLfRtaXbR0EVD0pl","name":"OpenAi account"}},"typeVersion":1},{"id":"17daf2dd-1d4c-498e-8404-7cc371f81894","name":"Recursive Character Text Splitter1","type":"@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter","position":[2660,3180],"parameters":{"options":{},"chunkSize":500,"chunkOverlap":200},"typeVersion":1},{"id":"afcfc728-9798-4703-998d-edc535eb859e","name":"Insert into Supabase Vectorstore1","type":"@n8n/n8n-nodes-langchain.vectorStoreSupabase","position":[2580,2780],"parameters":{"mode":"insert","options":{"queryName":"match_documents"},"tableName":{"__rl":true,"mode":"list","value":"documents","cachedResultName":"documents"}},"credentials":{"supabaseApi":{"id":"t8AQJzvZvrOMDLec","name":"Supabase account info@ Demo"}},"typeVersion":1},{"id":"78e7d15c-5797-488c-b869-bb887878e930","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[540,2240],"parameters":{"color":5,"width":2465,"height":1139,"content":"## Scenario 3 - Flow for adding new files from Supabase storage"},"typeVersion":1},{"id":"f572511d-6374-4b0b-8907-9f6c82179feb","name":"Edit Fields","type":"n8n-nodes-base.set","position":[1600,300],"parameters":{"options":{},"assignments":{"assignments":[{"id":"ad3055e5-41eb-4e00-9f55-dbcde47a03c7","name":"session_id","type":"string","value":"={{   $('When chat message received').item.json.sessionId }}"},{"id":"56126e31-5fe0-4a9c-b9c9-d62fcb8bd469","name":"message","type":"string","value":"={{   $('When chat message received').item.json.chatInput }}"}]}},"typeVersion":3.4},{"id":"be2de117-410c-49c2-b95c-45b4a0e036d6","name":"Edit Fields1","type":"n8n-nodes-base.set","position":[1600,140],"parameters":{"options":{},"assignments":{"assignments":[{"id":"5e5fbeb0-d866-40fe-8c1b-66b946bd1cec","name":"session_id","type":"string","value":"={{ $('Webhook').item.json.body.session_id }}"},{"id":"28ec27a5-f814-435c-a5bf-df92160eee3e","name":"message","type":"string","value":"={{ $('Webhook').item.json.body.message }}"}]}},"typeVersion":3.4},{"id":"ce8790a1-55a5-4583-8301-03bbde363ee2","name":"Upload File","type":"n8n-nodes-base.httpRequest","position":[2040,1280],"parameters":{"url":"https://api.cloud.llamaindex.ai/api/parsing/upload","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","sendHeaders":true,"authentication":"genericCredentialType","bodyParameters":{"parameters":[{"name":"file","parameterType":"formBinaryData","inputDataFieldName":"data"},{"name":"do_not_cache","value":"=true"}]},"genericAuthType":"httpHeaderAuth","headerParameters":{"parameters":[{"name":"accept","value":"application/json"}]}},"credentials":{"httpHeaderAuth":{"id":"AkhbJSroTy15x6o9","name":"Llama parse bqman"}},"typeVersion":4.2},{"id":"10b8cf52-4301-40a2-a27d-9952f1d3bcda","name":"Get Processing Status","type":"n8n-nodes-base.httpRequest","onError":"continueErrorOutput","position":[2240,1280],"parameters":{"url":"=https://api.cloud.llamaindex.ai/api/parsing/job/{{ $json.id }}","options":{},"sendHeaders":true,"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","headerParameters":{"parameters":[{"name":"accept","value":"application/json"}]}},"credentials":{"httpHeaderAuth":{"id":"AkhbJSroTy15x6o9","name":"Llama parse bqman"}},"typeVersion":4.2},{"id":"c0fc7854-1d04-492d-9541-389356333efd","name":"Wait to stay within service limits","type":"n8n-nodes-base.wait","position":[2660,1040],"webhookId":"17a96ed6-b5ff-47bb-a8a2-39c1eb40185a","parameters":{"amount":7},"typeVersion":1.1},{"id":"971b40d2-a320-4815-9ccc-27de52b58bbd","name":"Is Job Ready?","type":"n8n-nodes-base.switch","position":[2420,1280],"parameters":{"rules":{"values":[{"outputKey":"PENDING","conditions":{"options":{"version":1,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"0fa97d86-432a-409a-917e-5f1a002b1ab9","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"PENDING"}]},"renameOutput":true},{"outputKey":"ERROR","conditions":{"options":{"version":1,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"e6058aa0-a3e2-4ce3-9bed-6ff41a5be052","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"ERROR"}]},"renameOutput":true},{"outputKey":"CANCELED","conditions":{"options":{"version":1,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"ceb6338f-4261-40ac-be11-91f61c7302ba","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"CANCELED"}]},"renameOutput":true},{"outputKey":"SUCCESS","conditions":{"options":{"version":1,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"300fce8c-b19a-4d0c-86e8-f62853c70ce2","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"SUCCESS"}]},"renameOutput":true}]},"options":{"allMatchingOutputs":true}},"typeVersion":3},{"id":"c8f65cc5-e67a-47ae-b43a-fc065fb4900e","name":"Stop and Error","type":"n8n-nodes-base.stopAndError","position":[2660,1300],"parameters":{"errorMessage":"Problem with Llamaparser. Error during parsing."},"typeVersion":1},{"id":"90658f0a-7236-493d-8dd0-fdad64196753","name":"Get Parsed Data","type":"n8n-nodes-base.httpRequest","position":[2660,1480],"parameters":{"url":"=https://api.cloud.llamaindex.ai/api/parsing/job/{{ $json.id }}/result/markdown","options":{"redirect":{"redirect":{}}},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"AkhbJSroTy15x6o9","name":"Llama parse bqman"}},"typeVersion":4.2},{"id":"810aad96-7677-4c27-b3b2-25106b70083a","name":"Sticky Note12","type":"n8n-nodes-base.stickyNote","position":[2060,1460],"parameters":{"width":280,"height":80,"content":"### Add Llamaparse Header auth\nAuthorization: Bearer <api_key>"},"typeVersion":1},{"id":"a0fd62b8-219e-4eb7-b274-1344b0042fac","name":"Merge","type":"n8n-nodes-base.merge","position":[1800,260],"parameters":{},"typeVersion":3.1},{"id":"e5356266-5e4a-41a2-8151-95f994435560","name":"If1","type":"n8n-nodes-base.if","position":[1820,1280],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"f05d708d-f36e-4c6d-8753-81a61ae42546","operator":{"type":"string","operation":"notExists","singleValue":true},"leftValue":"={{ $json.data }}","rightValue":""}]}},"typeVersion":2.2},{"id":"c04fa3f9-74c6-4c7c-ae2a-46a797db0e55","name":"Set Text","type":"n8n-nodes-base.set","position":[2060,1600],"parameters":{"options":{},"assignments":{"assignments":[{"id":"e9bbecd9-3d40-4a6a-9401-94daab15cde0","name":"text","type":"string","value":"={{ $('If1').item.json.data }}"}]}},"typeVersion":3.4},{"id":"2f41ef18-6229-4d3c-9a3c-8b02ec3c60b2","name":"Set Text1","type":"n8n-nodes-base.set","position":[2840,1480],"parameters":{"options":{},"assignments":{"assignments":[{"id":"e9bbecd9-3d40-4a6a-9401-94daab15cde0","name":"text","type":"string","value":"={{ $('Get Parsed Data').item.json.markdown }}"}]}},"typeVersion":3.4},{"id":"9c92b25b-7762-4465-878f-6568073ba521","name":"Merge Text","type":"n8n-nodes-base.merge","position":[3060,1620],"parameters":{},"typeVersion":3.1},{"id":"4a523ad6-d74d-4207-8347-facc7f313fdd","name":"Upload File1","type":"n8n-nodes-base.httpRequest","position":[1380,2580],"parameters":{"url":"https://api.cloud.llamaindex.ai/api/parsing/upload","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","sendHeaders":true,"authentication":"genericCredentialType","bodyParameters":{"parameters":[{"name":"file","parameterType":"formBinaryData","inputDataFieldName":"data"},{"name":"do_not_cache","value":"=true"}]},"genericAuthType":"httpHeaderAuth","headerParameters":{"parameters":[{"name":"accept","value":"application/json"}]}},"credentials":{"httpHeaderAuth":{"id":"AkhbJSroTy15x6o9","name":"Llama parse bqman"}},"typeVersion":4.2},{"id":"c0a43e5e-ec2b-49f5-bbc0-cef914c68c4c","name":"Get Processing Status1","type":"n8n-nodes-base.httpRequest","onError":"continueErrorOutput","position":[1580,2580],"parameters":{"url":"=https://api.cloud.llamaindex.ai/api/parsing/job/{{ $json.id }}","options":{},"sendHeaders":true,"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","headerParameters":{"parameters":[{"name":"accept","value":"application/json"}]}},"credentials":{"httpHeaderAuth":{"id":"AkhbJSroTy15x6o9","name":"Llama parse bqman"}},"typeVersion":4.2},{"id":"68cc70a4-dba0-4ec9-8506-88bb20b37e87","name":"Wait to stay within service limits1","type":"n8n-nodes-base.wait","position":[2000,2340],"webhookId":"17a96ed6-b5ff-47bb-a8a2-39c1eb40185a","parameters":{"amount":7},"typeVersion":1.1},{"id":"aef3b805-166e-47a8-a81c-900f999ae045","name":"Is Job Ready?1","type":"n8n-nodes-base.switch","position":[1760,2580],"parameters":{"rules":{"values":[{"outputKey":"PENDING","conditions":{"options":{"version":1,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"0fa97d86-432a-409a-917e-5f1a002b1ab9","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"PENDING"}]},"renameOutput":true},{"outputKey":"ERROR","conditions":{"options":{"version":1,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"e6058aa0-a3e2-4ce3-9bed-6ff41a5be052","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"ERROR"}]},"renameOutput":true},{"outputKey":"CANCELED","conditions":{"options":{"version":1,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"ceb6338f-4261-40ac-be11-91f61c7302ba","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"CANCELED"}]},"renameOutput":true},{"outputKey":"SUCCESS","conditions":{"options":{"version":1,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"300fce8c-b19a-4d0c-86e8-f62853c70ce2","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"SUCCESS"}]},"renameOutput":true}]},"options":{"allMatchingOutputs":true}},"typeVersion":3},{"id":"5233be31-2ecf-4ddd-96e2-b0fd614f535f","name":"Stop and Error1","type":"n8n-nodes-base.stopAndError","position":[2000,2600],"parameters":{"errorMessage":"Problem with Llamaparser. Error during parsing."},"typeVersion":1},{"id":"09283faa-4ab9-4d59-a610-3491d7f2daf8","name":"Get Parsed Data1","type":"n8n-nodes-base.httpRequest","position":[2000,2780],"parameters":{"url":"=https://api.cloud.llamaindex.ai/api/parsing/job/{{ $json.id }}/result/markdown","options":{"redirect":{"redirect":{}}},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"AkhbJSroTy15x6o9","name":"Llama parse bqman"}},"typeVersion":4.2},{"id":"5ef6959d-1eb4-49cd-9b19-3b0e1aaa0eb7","name":"Sticky Note13","type":"n8n-nodes-base.stickyNote","position":[1400,2760],"parameters":{"width":280,"height":80,"content":"### Add Llamaparse Header auth\nAuthorization: Bearer <api_key>"},"typeVersion":1},{"id":"18fd1d0f-664e-4584-8154-794ca8aad768","name":"Set Text3","type":"n8n-nodes-base.set","position":[2180,2780],"parameters":{"options":{},"assignments":{"assignments":[{"id":"e9bbecd9-3d40-4a6a-9401-94daab15cde0","name":"text","type":"string","value":"={{ $('Get Parsed Data1').item.json.markdown }}"}]}},"typeVersion":3.4},{"id":"337b8593-8f5a-47b2-8b75-f5b3b4195fe8","name":"Webhook","type":"n8n-nodes-base.webhook","position":[1420,140],"webhookId":"05979e87-19bc-4e8b-adbb-7e04808f8b21","parameters":{"path":"05979e87-19bc-4e8b-adbb-7e04808f8b21","options":{},"httpMethod":"POST","responseMode":"lastNode"},"typeVersion":2},{"id":"7911c133-f998-4efd-a9c8-9c52c8e545c4","name":"Sticky Note14","type":"n8n-nodes-base.stickyNote","position":[2380,2660],"parameters":{"width":480,"height":80,"content":"### Replace credentials."},"typeVersion":1}],"pinData":{},"connections":{"If":{"main":[[{"node":"Download","type":"main","index":0}],[{"node":"Loop Over Items","type":"main","index":0}]]},"If1":{"main":[[{"node":"Upload File","type":"main","index":0}],[{"node":"Set Text","type":"main","index":0}]]},"Merge":{"main":[[{"node":"AI Agent1","type":"main","index":0}]]},"Webhook":{"main":[[{"node":"Edit Fields1","type":"main","index":0}]]},"Download":{"main":[[{"node":"If1","type":"main","index":0}]]},"Set Text":{"main":[[{"node":"Merge Text","type":"main","index":1}]]},"Aggregate":{"main":[[{"node":"Get All files","type":"main","index":0}]]},"Set Text1":{"main":[[{"node":"Merge Text","type":"main","index":0}]]},"Set Text3":{"main":[[{"node":"Create File record1","type":"main","index":0}]]},"Merge Text":{"main":[[{"node":"Create File record2","type":"main","index":0}]]},"Edit Fields":{"main":[[{"node":"Merge","type":"main","index":1}]]},"Set File ID":{"main":[[{"node":"Delete Old Doc Rows","type":"main","index":0}]]},"Upload File":{"main":[[{"node":"Get Processing Status","type":"main","index":0}]]},"Edit Fields1":{"main":[[{"node":"Merge","type":"main","index":0}]]},"File Created":{"main":[[{"node":"Set File ID","type":"main","index":0}]]},"File Updated":{"main":[[{"node":"Set File ID","type":"main","index":0}]]},"Upload File1":{"main":[[{"node":"Get Processing Status1","type":"main","index":0}]]},"Download File":{"main":[[{"node":"Upload File1","type":"main","index":0}]]},"Get All Files":{"main":[[{"node":"Aggregate","type":"main","index":0}]]},"Get All files":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Is Job Ready?":{"main":[[{"node":"Wait to stay within service limits","type":"main","index":0}],[{"node":"Stop and Error","type":"main","index":0}],[{"node":"Stop and Error","type":"main","index":0}],[{"node":"Get Parsed Data","type":"main","index":0}]]},"Simple Memory":{"ai_memory":[[{"node":"AI Agent1","type":"ai_memory","index":0}]]},"Is Job Ready?1":{"main":[[{"node":"Wait to stay within service limits1","type":"main","index":0}],[{"node":"Stop and Error1","type":"main","index":0}],[{"node":"Stop and Error1","type":"main","index":0}],[{"node":"Get Parsed Data1","type":"main","index":0}]]},"Get Parsed Data":{"main":[[{"node":"Set Text1","type":"main","index":0}]]},"Loop Over Items":{"main":[[],[{"node":"If","type":"main","index":0}]]},"Get Parsed Data1":{"main":[[{"node":"Set Text3","type":"main","index":0}]]},"Embeddings OpenAI":{"ai_embedding":[[{"node":"Insert into Supabase Vectorstore","type":"ai_embedding","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Agent1","type":"ai_languageModel","index":0}]]},"Embeddings OpenAI1":{"ai_embedding":[[{"node":"Supabase Vector Store","type":"ai_embedding","index":0}]]},"Embeddings OpenAI3":{"ai_embedding":[[{"node":"Insert into Supabase Vectorstore1","type":"ai_embedding","index":0}]]},"Create File record1":{"main":[[{"node":"Insert into Supabase Vectorstore1","type":"main","index":0}]]},"Create File record2":{"main":[[{"node":"Insert into Supabase Vectorstore","type":"main","index":0}]]},"Default Data Loader":{"ai_document":[[{"node":"Insert into Supabase Vectorstore","type":"ai_document","index":0}]]},"Delete Old Doc Rows":{"main":[[{"node":"Download File","type":"main","index":0}]]},"Default Data Loader1":{"ai_document":[[{"node":"Insert into Supabase Vectorstore1","type":"ai_document","index":0}]]},"Get Processing Status":{"main":[[{"node":"Is Job Ready?","type":"main","index":0}],[{"node":"Stop and Error","type":"main","index":0}]]},"Supabase Vector Store":{"ai_tool":[[{"node":"AI Agent1","type":"ai_tool","index":0}]]},"Get Processing Status1":{"main":[[{"node":"Is Job Ready?1","type":"main","index":0}],[{"node":"Stop and Error1","type":"main","index":0}]]},"When chat message received":{"main":[[{"node":"Edit Fields","type":"main","index":0}]]},"Insert into Supabase Vectorstore":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Recursive Character Text Splitter":{"ai_textSplitter":[[{"node":"Default Data Loader","type":"ai_textSplitter","index":0}]]},"When clicking ‘Test workflow’":{"main":[[{"node":"Get All Files","type":"main","index":0}]]},"Recursive Character Text Splitter1":{"ai_textSplitter":[[{"node":"Default Data Loader1","type":"ai_textSplitter","index":0}]]},"Wait to stay within service limits":{"main":[[{"node":"Get Processing Status","type":"main","index":0}]]},"Wait to stay within service limits1":{"main":[[{"node":"Get Processing Status1","type":"main","index":0}]]}}}


name: Extract and Merge Twitter (X) Threads using TwitterAPI.io
author_name: enes cingoz
author_username: ecingoz
nodes_used: ["n8n-nodes-base.httpRequest","n8n-nodes-base.code"]
categories: []
created_at: 2025-05-15T22:37:55.997Z
updated_at: 2025-05-15T22:37:55.997Z
url: https://n8n.io/workflows/4088
scraped_at: 2025-06-19 22:50:16
description:
  Twitter (X) Thread Fetcher: Extract and Merge Tweets from Threads
  What it does

  Thread Detection:** Automatically detects whether the provided Twitter link is a single tweet or a thread.
  Tweet Extraction:** Fetches and returns the content of a single tweet, or gathers all tweets in a thread by retrieving the first tweet and all connected replies.
  Thread Merging:** Merges all tweets in the correct order to reconstruct the complete thread, filtering out any empty results.
  Seamless Integration:** Easily trigger this workflow from other n8n workflows to automate Twitter thread extraction from various sources.

  How it works
  Accepts a Twitter link as input-either a single tweet or a thread.
  If the link is for a single tweet, fetches and returns the tweet content.
  If the link is for a thread, fetches the first tweet, then iteratively retrieves all connected replies that form the thread, ensuring only relevant tweets are included.
  Merges the first tweet and all subsequent thread tweets in order, filters out any empty results, and returns the complete thread.
  Uses twitterapi.io for all Twitter API requests.

  Set up steps
  Setup typically takes just a few minutes. You’ll need to configure your Twitter API credentials for twitterapi.io.
  You can trigger this workflow manually for testing or call it from another workflow to automate thread fetching from sources like Notion, spreadsheets, or other platforms.
  For best results, create a separate workflow to gather Twitter links from your preferred source, then trigger this workflow to fetch and return the full thread.

  &gt; Detailed configuration instructions and node explanations are included as sticky notes within the workflow canvas.

  Benefits

  Light speed:* Fetches a 15-tweet thread in just *3 seconds** for rapid results.
  Cost effective:* Processes a *15-tweet thread* for only *$0.0027*, making it highly affordable. *(Cost may vary depending on the density of replies in the thread.)

workflow_json:
  {"id":"23sZVFonPs0Q3gvm","meta":{"instanceId":"98efd8f034313c65d85cf0927667bbf93252214bae7096a8dd3c1d18b0b96a02","templateCredsSetupCompleted":true},"name":"Twitter Thread Fetcher: Extract and Merge Tweets from Threads","tags":[],"nodes":[{"id":"209216e9-30f6-40d1-98a6-96324e28db47","name":"Merge first tweet and others","type":"n8n-nodes-base.merge","position":[1360,-120],"parameters":{},"typeVersion":3.1},{"id":"3429ac0d-1d24-4d30-aaac-a0ae6adaef93","name":"When clicking ‘Test workflow’","type":"n8n-nodes-base.manualTrigger","position":[-420,120],"parameters":{},"typeVersion":1},{"id":"5df01f81-da74-4a17-8856-682f8bdf580e","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-120,-280],"parameters":{"content":""},"typeVersion":1},{"id":"fe1ba598-8c65-468e-bd58-b8b71d48e0f1","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[340,-280],"parameters":{"content":""},"typeVersion":1},{"id":"95f7ac46-d864-483c-bce3-482142fe3697","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1200,-280],"parameters":{"content":""},"typeVersion":1},{"id":"2a9eabb2-75a4-40a8-9379-0895203c49c9","name":"When Executed by Another Workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[-420,-120],"parameters":{},"typeVersion":1.1},{"id":"ee80999e-4980-4794-ac69-9d2c43a7a9d5","name":"No Operation, do nothing","type":"n8n-nodes-base.noOp","position":[1820,-120],"parameters":{},"typeVersion":1},{"id":"8acccfa4-5bb0-456a-ab7b-7eeef598cf8e","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-120,-440],"parameters":{"content":""},"typeVersion":1},{"id":"82efbaa8-03d6-4d05-81a4-e2bebe26f403","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[340,-440],"parameters":{"content":""},"typeVersion":1},{"id":"5734a4e8-a751-440e-b216-52fe8b257444","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[1200,-440],"parameters":{"content":""},"typeVersion":1},{"id":"36baf07f-abe4-46f1-8e8e-5344ee200f52","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-580,-440],"parameters":{"content":""},"typeVersion":1},{"id":"abd08db1-8742-4d52-b510-b3d6d68453be","name":"Extract Tweet ID and Username","type":"n8n-nodes-base.function","position":[-60,-5],"parameters":{},"typeVersion":1},{"id":"a81d8f05-d7a6-4c97-b90b-2c7e9c7807f1","name":"Get first tweet","type":"n8n-nodes-base.httpRequest","position":[160,-220],"parameters":{},"typeVersion":4.2},{"id":"23a0d0a4-d119-4a25-8771-7b4aca3ffe5b","name":"Extract Conversation and Author ID","type":"n8n-nodes-base.function","position":[380,-120],"parameters":{},"typeVersion":1},{"id":"c48394bc-e96d-455f-92a9-46db485e3aae","name":"Merge all tweet infos","type":"n8n-nodes-base.merge","position":[600,-5],"parameters":{},"typeVersion":3.1},{"id":"1683b177-c050-46fa-8714-c7af785297ca","name":"Get Tweet Replies","type":"n8n-nodes-base.httpRequest","onError":"continueRegularOutput","position":[820,0],"parameters":{},"typeVersion":4.2},{"id":"f85bbf89-c9e9-46f8-8f5a-14ca33c0e220","name":"Fetch tweets which are connected to first tweet","type":"n8n-nodes-base.code","position":[1040,0],"parameters":{},"typeVersion":2},{"id":"0fda4ada-cecd-4730-9ea9-1f385afe1c02","name":"Filter empty ones","type":"n8n-nodes-base.filter","position":[1580,-120],"parameters":{},"typeVersion":2.2}],"active":false,"pinData":{"When clicking ‘Test workflow’":[{"json":{"tweet_url":""}}]},"settings":{"executionOrder":"v1"},"versionId":"805f0bc5-601e-4db7-ba87-7cdc4fef06dc","connections":{"Get first tweet":{"main":[[{"node":"Extract Conversation and Author ID","type":"main","index":0},{"node":"Merge first tweet and others","type":"main","index":0}]]},"Filter empty ones":{"main":[[{"node":"No Operation, do nothing","type":"main","index":0}]]},"Get Tweet Replies":{"main":[[{"node":"Fetch tweets which are connected to first tweet","type":"main","index":0}]]},"Merge all tweet infos":{"main":[[{"node":"Get Tweet Replies","type":"main","index":0}]]},"Merge first tweet and others":{"main":[[{"node":"Filter empty ones","type":"main","index":0}]]},"Extract Tweet ID and Username":{"main":[[{"node":"Get first tweet","type":"main","index":0},{"node":"Merge all tweet infos","type":"main","index":1}]]},"When Executed by Another Workflow":{"main":[[{"node":"Extract Tweet ID and Username","type":"main","index":0}]]},"When clicking ‘Test workflow’":{"main":[[{"node":"Extract Tweet ID and Username","type":"main","index":0}]]},"Extract Conversation and Author ID":{"main":[[{"node":"Merge all tweet infos","type":"main","index":0}]]},"Fetch tweets which are connected to first tweet":{"main":[[{"node":"Merge first tweet and others","type":"main","index":1}]]}}}


name: Tesla Quant Trading AI Agent using Telegram + GPT-4.1 (Main InterFace)
author_name: Don Jayamaha Jr
author_username: don-the-gem-dealer
categories: []
created_at: 2025-05-16T08:44:07.297Z
updated_at: 2025-05-16T08:44:07.297Z
url: https://n8n.io/workflows/4092
scraped_at: 2025-06-19 22:49:47
description:
  📈 Get daily and on-demand Tesla (TSLA) trading signals via Telegram—powered by GPT-4.1 and real-time market data.
  This is the central AI supervisor that orchestrates seven sub-agents for technical analysis, price pattern recognition, and news sentiment. Reports are delivered in structured Telegram-ready HTML, optimized for traders seeking fast, intelligent decision-making signals.

  ⚠️ This master agent requires 7 connected sub-workflows to function. One of them, the News & Sentiment Agent, also requires a DeepSeek Chat API key for language processing.

  🔌 Required Sub-Workflows

  You must download and publish the following workflows:

  Tesla Financial Market Data Analyst Tool
  Tesla News and Sentiment Analyst Tool (Requires DeepSeek Chat API Key)
  Tesla 15min Indicators Tool
  Tesla 1hour Indicators Tool
  Tesla 1day Indicators Tool
  Tesla 1hour & 1day Klines Tool
  Tesla Quant Technical Indicators Webhooks Tool (Requires Alpha Vantage Premium API Key)

  📍 See all tools at:
  🔗 https://n8n.io/creators/don-the-gem-dealer/

  🔍 What This Agent Does

  Listens to your trading query via Telegram
  Calls the Financial Analyst and News & Sentiment Analyst
  These agents aggregate:

     RSI, MACD, BBANDS, SMA, EMA, ADX
     Candlestick pattern + volume divergence analysis
     News summaries and sentiment scoring via DeepSeek Chat
  GPT-4.1 composes the final structured TSLA trade report with:

     Spot and leverage setups
     Signal rationale
     Confidence score
     Sentiment tag
     News summary

  🧠 Output Example

  TSLA Trading Report (Daily Summary)
  Spot Trade
  • Action: Buy
  • Entry: 172.45
  • TP: 182.00
  • SL: 169.80
  • Signal: RSI bounce + Bullish Engulfing
  • Sentiment: Neutral

  Leveraged Position
  • Position: Long
  • Leverage: 3x
  • TP: 186
  • SL: 170
  • Confidence: High (83/100)

  📰 Top News
  • Tesla Model Y delivery surge – Electrek
  • Options market pricing in upside – Bloomberg
  • FSD delayed in Canada – TeslaNorth

  🛠️ Setup Instructions

  1. Import All 8 Workflows

  Ensure all sub-agents above are published in your n8n instance.

  2. Create Your Telegram Bot

  Use @BotFather to generate the token and connect to the trigger/send nodes.

  3. Connect OpenAI GPT-4.1

  Add your OpenAI credentials for GPT-4.1 in the designated node.

  4. Add DeepSeek Chat API Key

  Sign up at https://deepseek.com and insert your DeepSeek Chat credentials in the News Agent.

  5. Add Alpha Vantage Premium API Key

  Sign up at https://www.alphavantage.co/premium/
  Use HTTP Header Auth for webhook-based indicator fetchers.

  6. Replace Telegram ID

  Update the placeholder &lt;&lt;replace your ID here&gt;&gt; with your actual Telegram numeric ID in the auth node.

  📌 Included Sticky Notes

  ✅ Telegram Bot Setup
  ✅ Agent Routing & Memory
  ✅ Financial vs. Sentiment Trigger Flow
  ✅ Report Formatting (HTML)
  ✅ API Requirements (GPT-4.1, DeepSeek, Alpha Vantage)
  ✅ Troubleshooting & Licensing

  🧾 Licensing & Attribution

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

  🔗 For support: LinkedIn – Don Jayamaha

  🚀 Deploy the Tesla Quant Trading AI system with GPT-4.1, DeepSeek Chat, and Alpha Vantage Premium—right into Telegram.
  All 8 workflows are required.

  🎥 Tesla Quant AI Agent – Live Demo

  Experience the power of the Tesla Quant Trading AI Agent in action.
    

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

workflow_json:
  {"id":"YtPhfFCx9D9Eq9zi","meta":{"instanceId":"a5283507e1917a33cc3ae615b2e7d5ad2c1e50955e6f831272ddd5ab816f3fb6","templateCredsSetupCompleted":true},"name":"Tesla Quant Trading AI Agent n8n","tags":[],"nodes":[{"id":"8677aed4-a1bf-4439-8b5e-57c283f81862","name":"Telegram Trigger","type":"n8n-nodes-base.telegramTrigger","position":[-560,-100],"webhookId":"721eba88-462f-40ab-8c53-c6c2f3897e11","parameters":{"updates":["message"],"additionalFields":{}},"credentials":{"telegramApi":{"id":"FH5VC4KOy7sBQBc0","name":"Dad's Tesla AI Agent"}},"typeVersion":1.2},{"id":"fddcfaab-f575-4e72-b3f1-e0965e3c71b5","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[140,260],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"yUizd8t0sD5wMYVG","name":"OpenAi account"}},"typeVersion":1.2},{"id":"f6e5726a-1010-4a55-9d54-f6889eb780e1","name":"Telegram","type":"n8n-nodes-base.telegram","position":[1380,-100],"webhookId":"77b6658d-8dfb-415b-9e67-4f34ef086cdb","parameters":{"text":"={{ $json.message }}","chatId":"={{ $('Telegram Trigger').item.json.message.chat.id }}","additionalFields":{"appendAttribution":false}},"credentials":{"telegramApi":{"id":"FH5VC4KOy7sBQBc0","name":"Dad's Tesla AI Agent"}},"typeVersion":1.2},{"id":"62f3f30c-47e4-4c86-828b-3ab4de28e6c3","name":"User Authentication (Replace Telegram ID)","type":"n8n-nodes-base.code","position":[-300,-100],"parameters":{"jsCode":"if ($input.first().json.message.from.id !== <<replace your ID here>>) { // Replace with your actual ID\n  return {unauthorized: true};\n} else {\n  // Return the original data when authorized\n  return $input.all();\n}"},"typeVersion":2},{"id":"5a79ae5f-583d-41a0-9055-914de6eaf341","name":"Tesla Quant Trading AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[520,-100],"parameters":{"text":"={{ $('Telegram Trigger').item.json.message.text }}","options":{"systemMessage":"You are the **Tesla Quant Trading AI Agent**, responsible for generating structured, professional swing-trading reports for **TSLA** based on both **real-time technical analysis** and **curated sentiment data**.\n\n---\n\n### 🔗 Connected Tools:\n\n1. **Tesla Financial Market Data Analyst Tool**  \n   - Aggregates multi-timeframe indicators + candlestick signals from:\n     • Tesla 15min Indicators Tool  \n     • Tesla 1h Indicators Tool  \n     • Tesla 1d Indicators Tool  \n     • Tesla Klines Tool (1h & 1d pattern/volume)  \n   - Uses Alpha Vantage indicators: **RSI, BBANDS, SMA, EMA, ADX, MACD**  \n   - Each tool returns the **20 most recent points**, cleaned and trimmed  \n   - Pattern logic: detects **Doji, Engulfing**, and **volume divergence**\n\n2. **Tesla News and Sentiment Analyst Tool**  \n   - Scrapes from trusted RSS sources: **Google News, Yahoo Finance, Electrek, CleanTechnica, TeslaNorth**  \n   - Returns:  \n     • **Sentiment score**: Bullish / Bearish / Neutral  \n     • **Summary**: 2–3 sentence narrative  \n     • **Top 3–5 Headlines** (with sources)\n\n---\n\n### 📊 Responsibilities:\n\n1. **Ingest structured inputs** from the tools listed above:\n   - Indicator values and candlestick/volume behavior  \n   - News sentiment summaries and headlines\n\n2. **Perform technical analysis** across timeframes:\n   - **Short-Term**: 15m + 1h  \n   - **Long-Term**: 1d + 1h  \n   - Assess trend, support/resistance, divergence, and reversal signals  \n   - Confirm with lagging indicators and macro sentiment alignment\n\n3. **Generate two trade strategy sections**:\n\n<b>Spot Recommendations</b>  \n• Action: Buy / Sell / Hold  \n• Entry Price  \n• Stop Loss  \n• Take Profit  \n• Rationale:  \n - <b>Primary Signals</b>: e.g. candle pattern, breakout  \n - <b>Lagging Indicators</b>: RSI, BBANDS, etc.  \n - <b>Sentiment & Macro Analysis</b>: use news summary + headlines\n\n<b>Leveraged Recommendations</b>  \n• Position: Long / Short  \n• Leverage: 2x / 3x / 5x  \n• Entry Price  \n• Stop Loss  \n• Take Profit  \n• Rationale:  \n - <b>Primary Price Action Signals</b>  \n - <b>Lagging Indicator Confirmation</b>  \n - <b>Sentiment & Macro Analysis</b>\n\n4. **Score your signal strength**  \n• Confidence score (0–100)  \n• Strength label: Low / Medium / High / Very High\n\n5. **Include sentiment and headlines** at the bottom of the report:  \n• A short <b>News Sentiment Summary</b>  \n• Top 3 Tesla-related headlines with bullet formatting\n\n---\n\n### 🧾 Output Format (Telegram HTML)\n\nStart your message with:\n<b>TSLA Analysis</b>\n\n\nUse:\n• `<b>` for bold headers  \n• `•` for bullet points  \n• Clean line breaks  \n\n---\n\n⚠️ DO NOT:\n• Fabricate or assume any data  \n• Repeat this prompt or system instructions  \n• Include raw JSON or raw API format in your output\n\nOnly use what is provided via structured input. Write like a seasoned quantitative analyst.\n"},"promptType":"define"},"typeVersion":1.8},{"id":"966cf9b6-abd4-48a0-bd32-6c83985a33ac","name":"Tesla Financial Market Data Analyst Tool","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[700,260],"parameters":{"name":"Tesla_Financial_Market_Data_Analyst","workflowId":{"__rl":true,"mode":"list","value":"WmWhVZ3XkJdjTmME","cachedResultName":"Work Drive — Tesla Financial Market Data Analyst"},"workflowInputs":{"value":{"message":"={{ $fromAI(\"message\",\"Populate this with a relevant message to this subagent\")}}","sessionId":"={{ $json.sessionId }}"},"schema":[{"id":"message","type":"string","display":true,"removed":false,"required":false,"displayName":"message","defaultMatch":false,"canBeUsedToMatch":true},{"id":"sessionId","type":"string","display":true,"removed":false,"required":false,"displayName":"sessionId","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false}},"typeVersion":2.1},{"id":"dbf1bef5-044a-4594-af1b-1468d4cdc06a","name":"Tesla News and Sentiment Analyst Tool","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[980,260],"parameters":{"name":"Tesla_News_and_Sentiment_Analyst","workflowId":{"__rl":true,"mode":"list","value":"kOIhNsok4gtt6fD3","cachedResultName":"Work Drive — Tesla News and Sentiment Analyst"},"workflowInputs":{"value":{"message":"={{ $fromAI(\"message\",\"Populate this with a relevant message to this subagent\")}}","sessionId":"={{ $json.sessionId }}"},"schema":[{"id":"message","type":"string","display":true,"removed":false,"required":false,"displayName":"message","defaultMatch":false,"canBeUsedToMatch":true},{"id":"sessionId","type":"string","display":true,"removed":false,"required":false,"displayName":"sessionId","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false}},"typeVersion":2.1},{"id":"2109ef95-4256-4713-aa9d-8a8ecd40eff3","name":"Add SessionId","type":"n8n-nodes-base.set","position":[260,-100],"parameters":{"options":{},"assignments":{"assignments":[{"id":"c9d7a6f2-7e01-46fb-a4ee-f0c3b248bd6b","name":"sessionId","type":"string","value":"={{ $('Telegram Trigger').item.json.message.chat.id }}"},{"id":"d5929b35-1751-4a6a-bbee-d844cbb8e0aa","name":"DateandTime","type":"string","value":"={{ $json.currentDate }}"}]}},"typeVersion":3.4},{"id":"0f45fae9-fef5-4595-97f0-04f974790cd3","name":"Splits message is more than 4000 characters","type":"n8n-nodes-base.code","position":[1020,-100],"parameters":{"jsCode":"// Input: assumes incoming message in `item.json.message`\nconst input = $json.output;\nconst chunkSize = 4000;\n\n// Function to split text\nfunction splitMessage(text, size) {\n  const result = [];\n  for (let i = 0; i < text.length; i += size) {\n    result.push(text.substring(i, i + size));\n  }\n  return result;\n}\n\n// Logic\nif (input.length <= chunkSize) {\n  return [{ json: { message: input } }];\n} else {\n  const chunks = splitMessage(input, chunkSize);\n  return chunks.map(chunk => ({ json: { message: chunk } }));\n}"},"typeVersion":2},{"id":"8e7dcfd4-7f2a-47b4-8e5a-1bc4d77fced7","name":"Date & Time","type":"n8n-nodes-base.dateTime","position":[-20,-100],"parameters":{"options":{}},"typeVersion":2},{"id":"f31dbe9c-25a2-4751-ba34-38ed0ae9e18c","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[420,260],"parameters":{},"typeVersion":1.3},{"id":"97dfa658-3a67-4ed7-9662-b62573e0958b","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-640,-340],"parameters":{"color":4,"height":420,"content":"## Trigger Incoming Telegram Command\n\nThis node **listens for new Telegram messages** to initiate report generation."},"typeVersion":1},{"id":"b7d99e5f-0f36-4963-aa2c-33db04689fc5","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-380,-340],"parameters":{"color":2,"width":260,"height":420,"content":"## Validate User Access\n\nEnsures only **authorized Telegram user IDs** can trigger the agent."},"typeVersion":1},{"id":"9a4d6ba0-2d75-4453-8b05-bc4dedf81be5","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-80,-340],"parameters":{"color":5,"height":420,"content":"## Capture Timestamp\n\nCaptures the **current system date and time** for session tracking and report stamping."},"typeVersion":1},{"id":"157ba065-d228-41f0-a88f-ea8122fb5fa8","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[200,-340],"parameters":{"height":420,"content":"## Generate Session Metadata\n\nAssigns **sessionId based on Telegram chat ID** and stores current **date/time** for context continuity."},"typeVersion":1},{"id":"6fe0bc11-94da-4c82-bf28-5fe6429d6e86","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[480,-340],"parameters":{"color":7,"width":340,"height":420,"content":"## Main AI Agent: Trading Report Generator\n\nUses **GPT model to combine technical and sentiment data** into a structured **TSLA swing-trading report**.\nCalls **Financial Market Analyst + Sentiment Analyst**.\n\n"},"typeVersion":1},{"id":"7a1e3a33-713a-4a72-81c0-001e74af8f73","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[940,-340],"parameters":{"color":5,"width":260,"height":420,"content":"## Handle Telegram Message Limits\n\nChecks **output message length and splits into 4000-character** chunks if needed.\n\n"},"typeVersion":1},{"id":"b5ac3bcb-baa5-4d39-9e44-6be888317089","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[1300,-340],"parameters":{"color":4,"width":260,"height":420,"content":"## Send Final Report to Telegram\n\nSends **formatted HTML report (or split parts)** back to the **original Telegram user**."},"typeVersion":1},{"id":"5df88223-3acc-4b27-b592-58d499a638dd","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[60,220],"parameters":{"color":2,"height":400,"content":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n## GPT Model for Reasoning\nUses **OpenAI GPT (e.g., GPT-4o)** to process signal analysis and produce **final report** text."},"typeVersion":1},{"id":"c7bcc5bc-48b9-464b-9a6b-062535810543","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[340,220],"parameters":{"color":3,"height":400,"content":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Short-Term Memory Module\nMaintains **state during session**. Helps agent **track message history and previous context**.\n\n"},"typeVersion":1},{"id":"b17ec86d-5d91-469f-bc9d-fb5e22ecbfaf","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[620,220],"parameters":{"color":6,"height":400,"content":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Fetch Technical Indicator Insights\nCalls all **15m, 1h, 1d, and Klines sub-agents** via **webhook** to retrieve structured **market analysis**.\n\n"},"typeVersion":1},{"id":"1eda1d9b-2b50-4cd1-8b83-6a7d37517d31","name":"Sticky Note10","type":"n8n-nodes-base.stickyNote","position":[900,220],"parameters":{"color":6,"height":400,"content":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Scrape Tesla News & Generate Sentiment\nPulls latest **Tesla-related headlines from trusted RSS feeds** and **returns structured sentiment** summary.\n\n"},"typeVersion":1},{"id":"8e2ebe09-5488-4fb9-8175-b88ba68fcb9e","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[1900,-1680],"parameters":{"width":1280,"height":2300,"content":"\n# 🧠 Tesla Quant Trading AI Agent – Full System Documentation\n\nA professional-grade AI-driven stock analysis system designed to deliver structured Tesla (TSLA) swing-trading insights based on real-time technical indicators and sentiment signals.\n\n---\n\n## 🧩 Included Workflows\n\n> Download and install **all** of the following workflows for the system to function correctly.\n\n| Workflow Name                               | Function                                                                 |\n| ------------------------------------------- | ------------------------------------------------------------------------ |\n| ✅ Tesla 15min Indicators Tool               | Pulls Alpha Vantage data for short-term signals (15m: RSI, BBANDS, etc.) |\n| ✅ Tesla 1hour Indicators Tool               | Pulls Alpha Vantage data for medium-term signals (1h: RSI, BBANDS, etc.) |\n| ✅ Tesla 1day Indicators Tool                | Pulls Alpha Vantage data for long-term signals (1d: RSI, BBANDS, MACD)   |\n| ✅ Tesla 1hour & 1day Klines Tool            | Analyzes candlestick patterns and volume divergences (OHLCV)             |\n| ✅ Tesla Quant Technical Indicators Webhooks | Webhook handlers that power the above 4 indicator-fetching tools         |\n| ✅ Tesla Financial Market Data Analyst Tool  | Synthesizes multi-timeframe indicator + candle data                      |\n| ✅ Tesla News and Sentiment Analyst Tool     | Scrapes Tesla news RSS + assigns sentiment with headlines                |\n| ✅ Tesla Quant Trading AI Agent              | Final agent that generates Telegram-style trade reports                  |\n\n---\n\n## ⚙️ Installation Instructions\n\n### Step 1: Import Workflows\n\n1. Open your **n8n editor UI**.\n2. Import each workflow JSON file one by one.\n3. Make sure all workflows are **activated** or properly linked via `Execute Workflow` nodes.\n\n### Step 2: Set Up Credentials\n\n1. Go to **Credentials → HTTP Auth → Query Parameter Auth**.\n2. Create a credential named: `Alpha Vantage Premium`\n\n   * Add: `apikey=YOUR_API_KEY`\n3. Add your **OpenAI API** credentials (for GPT-4.1 or equivalent).\n\n### Step 3: Configure Webhooks\n\n1. Deploy the **Tesla Quant Technical Indicators Webhooks Tool**.\n2. Ensure that `/15minData`, `/1hourData`, `/1dayData`, and `/klinesData` routes are properly reachable.\n\n### Step 4: Set Up Execution\n\n1. Trigger the **Tesla Quant Trading AI Agent** manually or via a scheduler.\n2. The agent will:\n\n   * Call all technical + sentiment tools via workflow execution\n   * Format and analyze data\n   * Output full trading report in Telegram-HTML style\n\n---\n\n## 🖥️ System Overview\n\n**Data Flow:**\n\n```\n[Webhook HTTP Trigger] \n→ [Indicator Tool (15m, 1h, 1d)] \n→ [Candlestick Tool (1h, 1d)]\n→ [Financial Market Data Analyst] \n→ [Sentiment Analyst] \n→ [Final Report Generator]\n```\n\n**Output Example:**\n\n* Spot + Leverage trade entries\n* Confidence score (0–100)\n* Reasoning: price action, indicators, and sentiment\n* Summary headlines and sentiment context\n\n---\n\n## 📬 Output Format\n\n* Styled using Telegram HTML (`<b>`, `•`, newlines)\n* Structured trade report with:\n\n  * Action type\n  * Entry/exit prices\n  * Rationale in 3 parts\n  * News sentiment and 3 headlines\n\n---\n\n## 🚀 Support & Licensing\n\n🔗 **Don Jayamaha – LinkedIn**\n[http://linkedin.com/in/donjayamahajr](http://linkedin.com/in/donjayamahajr)\n\n© 2025 Treasurium Capital Limited Company. All rights reserved.\nThis AI workflow architecture, including logic, design, and prompt structures, is the intellectual property of **Treasurium Capital Limited Company**. Unauthorized reproduction, redistribution, or resale is prohibited under **U.S. copyright law**. Licensed use only.\n\n"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"b77078ba-b904-4315-aa13-f80fded7f9a9","connections":{"Telegram":{"main":[[]]},"Date & Time":{"main":[[{"node":"Add SessionId","type":"main","index":0}]]},"Add SessionId":{"main":[[{"node":"Tesla Quant Trading AI Agent","type":"main","index":0}]]},"Simple Memory":{"ai_memory":[[{"node":"Tesla Quant Trading AI Agent","type":"ai_memory","index":0}]]},"Telegram Trigger":{"main":[[{"node":"User Authentication (Replace Telegram ID)","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Tesla Quant Trading AI Agent","type":"ai_languageModel","index":0}]]},"Tesla Quant Trading AI Agent":{"main":[[{"node":"Splits message is more than 4000 characters","type":"main","index":0}]]},"Tesla News and Sentiment Analyst Tool":{"ai_tool":[[{"node":"Tesla Quant Trading AI Agent","type":"ai_tool","index":0}]]},"Tesla Financial Market Data Analyst Tool":{"ai_tool":[[{"node":"Tesla Quant Trading AI Agent","type":"ai_tool","index":0}]]},"User Authentication (Replace Telegram ID)":{"main":[[{"node":"Date & Time","type":"main","index":0}]]},"Splits message is more than 4000 characters":{"main":[[{"node":"Telegram","type":"main","index":0}]]}}}


name: Manage Calendar with Voice & Text using GPT-4, Telegram & Google Calendar
author_name: Marian Tcaciuc
author_username: mariantk
categories: []
created_at: 2025-05-16T11:08:27.232Z
updated_at: 2025-05-16T11:08:27.232Z
url: https://n8n.io/workflows/4102
scraped_at: 2025-06-19 22:49:03
description:
  Manage Calendar with Voice & Text Commands using GPT-4, Telegram & Google Calendar

  This n8n workflow transforms your Telegram bot into a personal AI calendar assistant, capable of understanding both voice and text commands in Romanian, and managing your Google Calendar using the GPT-4 model via LangChain.

  Whether you want to create, update, fetch, or delete events, you can simply speak or write your request to your Telegram bot — and the assistant takes care of the rest.

  🚀 Features

  Voice command support using Telegram voice messages (.ogg)
  Transcription using OpenAI Whisper
  Natural language understanding with GPT-4 via LangChain
  Google Calendar integration:
    ✅ Create Events
    🔁 Update Events
    ❌ Delete Events
    📅 Fetch Events
  Responses sent back via Telegram

  🛠️ Step-by-Step Setup Instructions

  1. Create a Telegram Bot
  Go to @BotFather on Telegram.
  Send /newbot and follow the instructions.
  Save the Bot Token.

  2. Configure Telegram Trigger Node
  Paste the Telegram token into the Telegram Trigger and Telegram nodes.
  Set updates to ["message"].

  3. Set up OpenAI Credentials
  Get an OpenAI API key from https://platform.openai.com
  Create a credential in n8n for OpenAI.
  This is used for both transcription and AI reasoning.

  4. Set up Google Calendar
  In Google Cloud Console:
    Enable Google Calendar API
    Set up OAuth2 credentials
    Add your n8n redirect URI (usually https://yourdomain/rest/oauth2-credential/callback)
  Create a credential in n8n using Google Calendar OAuth2
  Grant access to your calendar (e.g., "Family" calendar).

  ⚙️ Customization Options

  🗣️ Change Language or Locale
  The transcription node uses "en" for English. Change to another locale if needed.

  ✏️ Edit Prompt
  You can modify the prompt in the AI Agent node to include your name, work schedule, or specific behavior expectations.

  📆 Change Calendar Logic
  Adjust time ranges or filters in the Get Events node
  Add custom logic before Create Event (e.g., validation, conflict checks)

  📚 Helpful Tips

  Make sure n8n has HTTPS enabled to receive Telegram updates.
  You can test the flow first using only text, then voice.
  Use AI memory or vector stores (like Supabase) if you want context-aware planning in the future.

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

workflow_json:
  {"id":"X5xgTiDwTjqy8RqW","meta":{"instanceId":"fc43dbbe2855b618f22a32e0af198c70dc1ce7b2c715dfe283e581dd4cc1c13a","templateCredsSetupCompleted":true},"name":"Agent AI Calendar [n8n pro]","tags":[],"nodes":[{"id":"01b29a4c-25cf-4c03-ab87-810f070d4be3","name":"Create Event","type":"n8n-nodes-base.googleCalendarTool","position":[640,340],"parameters":{"end":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('End', `Cand se termina evenimentul`, 'string') }}","start":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start', `Cand incepe evenimentul`, 'string') }}","calendar":{"__rl":true,"mode":"id","value":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Calendar', ``, 'string') }}","__regex":"(^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)"},"additionalFields":{"description":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Description', ``, 'string') }}"},"useDefaultReminders":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Use_Default_Reminders', `Daca vrei sa folosesti reminderul defaul de la calendar sau vrei unul special`, 'boolean') }}"},"credentials":{"googleCalendarOAuth2Api":{"id":"27JiaYgdKeyU1SZC","name":"Google Calendar account"}},"typeVersion":1.3},{"id":"1758e2e3-e25d-4b1b-b57d-c711ec8553ce","name":"Get events","type":"n8n-nodes-base.googleCalendarTool","position":[760,340],"parameters":{"options":{},"timeMax":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Before', ``, 'string') }}","timeMin":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('After', ``, 'string') }}","calendar":{"__rl":true,"mode":"id","value":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Calendar', ``, 'string') }}","__regex":"(^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)"},"operation":"getAll","returnAll":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Return_All', ``, 'boolean') }}"},"credentials":{"googleCalendarOAuth2Api":{"id":"27JiaYgdKeyU1SZC","name":"Google Calendar account"}},"typeVersion":1.3},{"id":"9092f4dd-1982-4bb7-94f9-7f29e4fec6ef","name":"Update Calendar","type":"n8n-nodes-base.googleCalendarTool","position":[880,340],"parameters":{"eventId":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Event_ID', ``, 'string') }}","calendar":{"__rl":true,"mode":"id","value":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Calendar', ``, 'string') }}","__regex":"(^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)"},"operation":"update","updateFields":{},"useDefaultReminders":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Use_Default_Reminders', ``, 'boolean') }}"},"credentials":{"googleCalendarOAuth2Api":{"id":"27JiaYgdKeyU1SZC","name":"Google Calendar account"}},"typeVersion":1.3},{"id":"738a78e0-6256-4827-aac9-9eaf7c6ae91c","name":"Detele Event","type":"n8n-nodes-base.googleCalendarTool","position":[1000,340],"parameters":{"eventId":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Event_ID', ``, 'string') }}","options":{},"calendar":{"__rl":true,"mode":"id","value":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Calendar', ``, 'string') }}","__regex":"(^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)"},"operation":"delete"},"credentials":{"googleCalendarOAuth2Api":{"id":"27JiaYgdKeyU1SZC","name":"Google Calendar account"}},"typeVersion":1.3},{"id":"19674d23-67eb-46a1-a975-d64a64b6188a","name":"Receive User Input (Telegram)\t","type":"n8n-nodes-base.telegramTrigger","position":[-360,0],"webhookId":"19e39057-373f-4ca7-b999-c747d5f71767","parameters":{"updates":["message"],"additionalFields":{}},"credentials":{"telegramApi":{"id":"NYxlz922izZOpLZg","name":"Telegram account"}},"typeVersion":1.2},{"id":"0159ed56-542d-4fa1-867f-cba130466061","name":"Is Voice Message?\t","type":"n8n-nodes-base.if","position":[-80,0],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"c64b00ea-20f1-4d44-aed6-1528d537fc84","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.message.voice.mime_type }}","rightValue":"audio/ogg"}]}},"typeVersion":2.2},{"id":"008051e4-e006-4f18-a204-f64b322a4da6","name":"Download Voice File\t","type":"n8n-nodes-base.telegram","position":[140,-100],"webhookId":"1e904d77-b0a3-41ac-8624-a729103c9a14","parameters":{"fileId":"={{ $('Receive User Input (Telegram)\t').item.json.message.voice.file_id }}","resource":"file"},"credentials":{"telegramApi":{"id":"NYxlz922izZOpLZg","name":"Telegram account"}},"typeVersion":1.2},{"id":"e738c52a-d6b4-4fde-8dd8-2095db8eaf88","name":"Transcribe Voice to Text\t","type":"@n8n/n8n-nodes-langchain.openAi","position":[320,-100],"parameters":{"options":{"language":"en"},"resource":"audio","operation":"transcribe"},"credentials":{"openAiApi":{"id":"XYtY87CqnqwNVBos","name":"OpenAi account"}},"typeVersion":1.8},{"id":"5563f7c4-a87a-4728-a5ae-6e17ba59ff99","name":"Extract Text Message\t","type":"n8n-nodes-base.set","position":[140,100],"parameters":{"options":{},"assignments":{"assignments":[{"id":"41b525e6-a59f-47c7-b6ee-2b88eaa386fe","name":"Text","type":"string","value":"={{ $json.message.text }}"}]}},"typeVersion":3.4},{"id":"7ee11667-7834-464d-92e8-07be97f7f18a","name":"AI Calendar Assistant (LangChain)\t","type":"@n8n/n8n-nodes-langchain.agent","position":[520,100],"parameters":{"text":"=You're my personal digital assistant. Your purpose is to help me manage my personal calendar efficiently, taking into account priorities, work-life balance, and recurring events.\n\nToday is {{ $now }}\n\nInstructions:\n{{ $json.text }}\n{{ $json.Text }}","options":{},"promptType":"define"},"typeVersion":1.9},{"id":"8651b116-a5eb-4e21-b03f-5375efb0d8ed","name":"GPT-4 Language Model\t","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[360,340],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4.1","cachedResultName":"gpt-4.1"},"options":{}},"credentials":{"openAiApi":{"id":"XYtY87CqnqwNVBos","name":"OpenAi account"}},"typeVersion":1.2},{"id":"d014339d-7cb6-4bfe-bfbe-3f319a4fdf2c","name":"Send Response to Telegram\t","type":"n8n-nodes-base.telegram","position":[940,100],"webhookId":"b85c201f-13bd-4990-83e9-62c5e38fa8a4","parameters":{"text":"={{ $json.output }}","chatId":"={{ $('Receive User Input (Telegram)\t').item.json.message.chat.id }}","additionalFields":{"appendAttribution":false}},"credentials":{"telegramApi":{"id":"NYxlz922izZOpLZg","name":"Telegram account"}},"typeVersion":1.2},{"id":"6c74e5a0-56dc-4fbf-8826-fb1b16d96504","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-420,-740],"parameters":{"width":1600,"height":140,"content":"## Global Workflow Description\n  \n**\"AI-Powered Calendar Assistant: Voice & Text Input → GPT-4 → Google Calendar\"**  \n\n*Explains:* Built using Telegram, OpenAI (Whisper + GPT-4), and Google Calendar to help users manage events through natural language input."},"typeVersion":1},{"id":"5728ff55-e8c3-4b3f-9c85-0b111c1e18ec","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-420,-480],"parameters":{"height":320,"content":"## Start / Input\n\n**\"Start: Listen for Telegram input (text or voice message)\"**  \n \n*Explains:* This node triggers the workflow when a user sends a message via Telegram."},"typeVersion":1},{"id":"a2d2cdbf-ad34-4931-a4c9-ba79c89e09ac","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-140,-480],"parameters":{"width":200,"height":320,"content":"## Decision: Voice or Text\n \n**\"Check if the incoming message is a voice note (.ogg)\"**  \n\n*Explains:* If the message is a voice file, the workflow follows the transcription path. Otherwise, it processes the text directly."},"typeVersion":1},{"id":"92b826ed-4189-4d0e-911a-48ae3b44c45e","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[120,-480],"parameters":{"width":300,"height":320,"content":"## Voice Transcription\n \n**\"Download the voice file and transcribe it to text \"**  \n\n\n*Explains:* Uses OpenAI Whisper to convert voice messages to plain text."},"typeVersion":1},{"id":"fbdcd510-14b6-4d50-8fd7-352b421ac8a4","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[80,300],"parameters":{"height":240,"content":"## Text Extraction\n\n**\"Extract plain text from user’s message (if no voice)\"**  \n\n*Explains:* Gets the written message text for further processing."},"typeVersion":1},{"id":"76874498-00dc-499f-9930-8f02e143ad8d","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[440,500],"parameters":{"width":640,"height":360,"content":"## AI Interpretation\n\n**\"Analyze user intent using GPT-4 and decide next calendar action\"**  \n\n*Explains:* AI determines whether the user wants to create, update, fetch, or delete a calendar event.\n\n## Google Calendar Actions\n\n**\"Perform the selected Google Calendar action (Create / Update / Fetch / Delete)\"**  \n\n*Explains:* Executes the action chosen by the AI assistant using dynamic values."},"typeVersion":1},{"id":"7d55eed3-9715-4759-a806-e6d56e38f892","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[820,-220],"parameters":{"width":340,"height":240,"content":"## Send Response\n\n**\"Send a confirmation or result message back to the user\"**  \n\n*Explains:* Closes the loop by replying with the output from the assistant."},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"bca5c9d1-8464-47a8-aa76-0b864ef17a3f","connections":{"Get events":{"ai_tool":[[{"node":"AI Calendar Assistant (LangChain)\t","type":"ai_tool","index":0}]]},"Create Event":{"ai_tool":[[{"node":"AI Calendar Assistant (LangChain)\t","type":"ai_tool","index":0}]]},"Detele Event":{"ai_tool":[[{"node":"AI Calendar Assistant (LangChain)\t","type":"ai_tool","index":0}]]},"Update Calendar":{"ai_tool":[[{"node":"AI Calendar Assistant (LangChain)\t","type":"ai_tool","index":0}]]},"Is Voice Message?\t":{"main":[[{"node":"Download Voice File\t","type":"main","index":0}],[{"node":"Extract Text Message\t","type":"main","index":0}]]},"Download Voice File\t":{"main":[[{"node":"Transcribe Voice to Text\t","type":"main","index":0}]]},"Extract Text Message\t":{"main":[[{"node":"AI Calendar Assistant (LangChain)\t","type":"main","index":0}]]},"GPT-4 Language Model\t":{"ai_languageModel":[[{"node":"AI Calendar Assistant (LangChain)\t","type":"ai_languageModel","index":0}]]},"Transcribe Voice to Text\t":{"main":[[{"node":"AI Calendar Assistant (LangChain)\t","type":"main","index":0}]]},"Send Response to Telegram\t":{"main":[[]]},"Receive User Input (Telegram)\t":{"main":[[{"node":"Is Voice Message?\t","type":"main","index":0}]]},"AI Calendar Assistant (LangChain)\t":{"main":[[{"node":"Send Response to Telegram\t","type":"main","index":0}]]}}}


name: Generate Invoices, Save to Drive and Send Email to Customer with JS + G Sheets
author_name: Joseph
author_username: mjomba
categories: []
created_at: 2025-05-16T11:59:58.245Z
updated_at: 2025-05-16T11:59:58.245Z
url: https://n8n.io/workflows/4105
scraped_at: 2025-06-19 22:49:30
description:
  This workflow automates invoice generation from form submissions, ensuring unique order IDs, creating PDF invoices, storing files, emailing customers, and logging invoice data — all seamlessly integrated.

  🔹 Workflow Overview

  Trigger (Webhook)
     Starts when an order form is submitted, capturing customer and order details.

  Generate Random Order ID
     A Function node creates a unique alphanumeric invoice ID (e.g., INV-X92B7D).

  Check for Duplicate Order ID
     Google Sheets looks up the generated order ID in your invoice log sheet to prevent duplicates.

  Conditional Check (IF Node)

     If the ID already exists → regenerates a new ID (loops back)
     If unique → proceeds to invoice creation

  Prepare Invoice Data
     A Set node formats customer info, date, order items, and the unique order ID to fit your invoice template.

  Convert HTML to PDF
     HTTP Request node sends your invoice HTML to the RapidAPI HTML-to-PDF service and receives the PDF file.

  Upload PDF to Cloud Storage
     Save the PDF in Google Drive or Dropbox with a clear file name like Invoice-INV-X92B7D.pdf.

  Send Invoice Email to Customer
     Email node attaches the PDF and includes the order ID in the email subject/body.

  Log Invoice Details
     Append invoice data (customer info, order ID, total, PDF link) to your Google Sheet for tracking.

  ⚙️ Node Details & Setup

  1. Webhook Trigger

  Configure to receive form submissions (order details like name, email, items, total).

  2. Function: Generate Random Order ID

  Sample JS code generates unique IDs prefixed by INV-.

  3. Google Sheets: Lookup Row

  Set up connection to your invoice log sheet.
  Search for existing order ID to avoid duplicates.

  4. IF Node: Check Order ID Existence

  Condition: If order ID found → loop to regenerate.
  Else → continue workflow.

  5. Set Node: Prepare Invoice HTML

  Define variables like customer name, date, items, and order ID.
  This data populates your HTML invoice template.

  6. HTTP Request: Convert HTML to PDF

  API URL to get your key
  Send invoice HTML in the request body.
  Receive PDF file blob or download URL.

  7. Google Drive (or Dropbox) Upload

  Upload the PDF file.
  Use file name format: Invoice-{{$json["order_id"]}}.pdf

  8. Email Node

  Recipient: customer email from the form data.
  Attach generated PDF.
  Include order ID in email subject or body for reference.

  9. Google Sheets: Append Row

  Log invoice metadata to keep records updated.

  📁 Google Sheets Template

  You can make a copy of the invoice log template here

  This sheet includes columns for order\_id, customer name, email, total, and invoice PDF link. Customize it as needed.

  📌 Additional Notes

  Customize the invoice HTML template inside the Set node to match your branding.
  Ensure API credentials for RapidAPI, Google Drive/Dropbox, and email are properly set up in your n8n credentials.
  You can expand this workflow by adding payment processing or SMS notifications.

  Need help or want a custom workflow?

  Reach out via email at joseph@uppfy.com.

nodes_used:
  ["n8n-nodes-base.emailSend","n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","n8n-nodes-base.googleDrive","n8n-nodes-base.code"]

workflow_json:
  {"id":"K4XpJbwBJYnDiYkF","meta":{"instanceId":"b3c467df4053d13fe31cc98f3c66fa1d16300ba750506bfd019a0913cec71ea3","templateCredsSetupCompleted":true},"name":"Generate Invoices","tags":[],"nodes":[{"id":"e56cbf88-1e0d-4dd7-a269-091ad2ce8420","name":"Webhook Simulator","type":"n8n-nodes-base.webhook","position":[-240,20],"webhookId":"7f884a07-861e-49da-bb0e-1ac6ca40ea00","parameters":{"path":"7f884a07-861e-49da-bb0e-1ac6ca40ea00","options":{}},"typeVersion":2},{"id":"b01307f7-b5cb-421e-833a-0889925bb09c","name":"Generate Invoice ID","type":"n8n-nodes-base.code","position":[-20,20],"parameters":{"jsCode":"function generateOrderID(length = 6) {\n  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n  let result = 'INV-';\n  for (let i = 0; i < length; i++) {\n    result += chars.charAt(Math.floor(Math.random() * chars.length));\n  }\n  return result;\n}\n\nreturn [\n  {\n    json: {\n      order_id: generateOrderID()\n    }\n  }\n];\n"},"typeVersion":2},{"id":"bf50ca10-4021-4e6f-9c08-56fd84ce13ed","name":"Check if ID Already Exists","type":"n8n-nodes-base.googleSheets","position":[200,20],"parameters":{"options":{},"filtersUI":{"values":[{"lookupValue":"={{ $json.order_id }}","lookupColumn":"Invoice ID"}]},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1QW_Lg1aoEBku8GaxwPbZfBY5ITAuSdvoAXRyNdCEujM/edit#gid=0","cachedResultName":"Invoices"},"documentId":{"__rl":true,"mode":"list","value":"1QW_Lg1aoEBku8GaxwPbZfBY5ITAuSdvoAXRyNdCEujM","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1QW_Lg1aoEBku8GaxwPbZfBY5ITAuSdvoAXRyNdCEujM/edit?usp=drivesdk","cachedResultName":"Uppfy Shop Invoices"}},"credentials":{"googleSheetsOAuth2Api":{"id":"d0qeLhShx9sGXalR","name":"Google Sheets"}},"typeVersion":4.5,"alwaysOutputData":true},{"id":"c63871fa-ca0f-4069-ac0d-422d39018a9e","name":"If Does not Exist","type":"n8n-nodes-base.if","position":[420,20],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"loose"},"combinator":"and","conditions":[{"id":"cee7659a-cea3-494a-b4f3-c76d035a3a32","operator":{"type":"string","operation":"empty","singleValue":true},"leftValue":"={{ $json.row_number }}","rightValue":""}]},"looseTypeValidation":true},"typeVersion":2.2},{"id":"feb9ed84-a62c-4cec-bf36-b53a76711bcd","name":"Set Fields","type":"n8n-nodes-base.set","position":[740,-140],"parameters":{"options":{},"assignments":{"assignments":[{"id":"1bd457b4-2c15-433a-96b3-5fabb8566866","name":"order_id","type":"string","value":"={{ $('Generate Invoice ID').item.json.order_id }}"},{"id":"15c51334-b127-485e-9be4-051b086d74b2","name":"customer_name","type":"string","value":"={{ $('Webhook Simulator').item.json.customer_name }}"},{"id":"8c4f2d5c-09c8-4b8c-a77f-ab3c1d752c13","name":"customer_email","type":"string","value":"={{ $('Webhook Simulator').item.json.customer_email }}"},{"id":"ea1bbfe4-c12d-450f-9bee-fff8710eed42","name":"products","type":"array","value":"={{ $('Webhook Simulator').item.json.products }}"},{"id":"025d0783-7eb0-4ac4-b373-39f744692cfd","name":"total","type":"number","value":"={{ $('Webhook Simulator').item.json.total }}"}]}},"typeVersion":3.4},{"id":"0532fa4b-cdd9-4857-8701-6a5baf48fd7c","name":"Create Invoice HTML","type":"n8n-nodes-base.code","position":[740,100],"parameters":{"jsCode":"const { order_id, customer_name, customer_email, products, total } = $json;\n\n// Format products table rows\nconst productRows = products.map((item, index) => {\n  const subtotal = item.quantity * item.price;\n  return `\n    <tr>\n      <td style=\"padding: 8px; border: 1px solid #ccc;\">${index + 1}</td>\n      <td style=\"padding: 8px; border: 1px solid #ccc;\">${item.name}</td>\n      <td style=\"padding: 8px; border: 1px solid #ccc;\">${item.quantity}</td>\n      <td style=\"padding: 8px; border: 1px solid #ccc;\">$${item.price.toFixed(2)}</td>\n      <td style=\"padding: 8px; border: 1px solid #ccc;\">$${subtotal.toFixed(2)}</td>\n    </tr>\n  `;\n}).join('');\n\nconst html = `\n<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Invoice ${order_id}</title>\n</head>\n<body style=\"font-family: Arial, sans-serif; color: #333; max-width: 700px; margin: auto; padding: 20px; border: 1px solid #ddd;\">\n  <h2 style=\"text-align: center;\">Invoice</h2>\n  <p><strong>Order ID:</strong> ${order_id}</p>\n  <p><strong>Customer Name:</strong> ${customer_name}</p>\n  <p><strong>Email:</strong> ${customer_email}</p>\n\n  <table style=\"width: 100%; border-collapse: collapse; margin-top: 20px;\">\n    <thead>\n      <tr>\n        <th style=\"padding: 8px; border: 1px solid #ccc;\">#</th>\n        <th style=\"padding: 8px; border: 1px solid #ccc;\">Product</th>\n        <th style=\"padding: 8px; border: 1px solid #ccc;\">Qty</th>\n        <th style=\"padding: 8px; border: 1px solid #ccc;\">Unit Price</th>\n        <th style=\"padding: 8px; border: 1px solid #ccc;\">Subtotal</th>\n      </tr>\n    </thead>\n    <tbody>\n      ${productRows}\n    </tbody>\n    <tfoot>\n      <tr>\n        <td colspan=\"4\" style=\"text-align: right; padding: 8px; border: 1px solid #ccc;\"><strong>Total:</strong></td>\n        <td style=\"padding: 8px; border: 1px solid #ccc;\"><strong>$${total.toFixed(2)}</strong></td>\n      </tr>\n    </tfoot>\n  </table>\n\n  <p style=\"margin-top: 40px; text-align: center;\">Thank you for your order!</p>\n</body>\n</html>\n`;\n\nreturn [\n  {\n    json: {\n      html\n    }\n  }\n];\n"},"typeVersion":2},{"id":"5a3adb6a-9f64-477e-9622-3d2b9ef2e6de","name":"HTML to PDF","type":"n8n-nodes-base.httpRequest","position":[-20,320],"parameters":{"url":"https://html2pdf2.p.rapidapi.com/html2pdf","method":"POST","options":{},"sendBody":true,"sendHeaders":true,"bodyParameters":{"parameters":[{"name":"html","value":"={{ $json.html }}"}]},"headerParameters":{"parameters":[{"name":"x-rapidapi-host","value":"html2pdf2.p.rapidapi.com"},{"name":"x-rapidapi-key","value":"\"your_rapid_api_key\""}]}},"typeVersion":4.2},{"id":"cebf6d0d-d43f-4e50-abc0-79ff8da1817a","name":"Upload PDF to GDrive","type":"n8n-nodes-base.googleDrive","position":[420,320],"parameters":{"name":"={{ $('Set Fields').item.json.order_id }} - {{ $('Set Fields').item.json.customer_name }}","driveId":{"__rl":true,"mode":"list","value":"My Drive"},"options":{},"folderId":{"__rl":true,"mode":"list","value":"root","cachedResultName":"/ (Root folder)"}},"credentials":{"googleDriveOAuth2Api":{"id":"l8Cc2MEVE7foBfbK","name":"Google Drive account"}},"typeVersion":3},{"id":"b181eddc-e786-4d44-a334-e1b581b3981f","name":"Email Invoice to Customer","type":"n8n-nodes-base.emailSend","position":[640,320],"webhookId":"cdc852fc-03b9-4a89-ba56-879064da5cbb","parameters":{"html":"=Hello  {{ $('Set Fields').item.json.customer_name }},\n\nPlease pay this invoice\n\n\n{{ $('Create Invoice HTML').item.json.html }}\n\n\n<!DOCTYPE html>\n<html>\n<head>\n    <style>\n        .button {\n            display: inline-block;\n            background-color: #4CAF50;\n            border: none;\n            border-radius: 4px;\n            color: white;\n            padding: 15px 32px;\n            text-align: center;\n            text-decoration: none;\n            font-size: 16px;\n            font-weight: bold;\n            margin: 4px 2px;\n            cursor: pointer;\n            font-family: Arial, sans-serif;\n        }\n    </style>\n</head>\n<body>\n    <div style=\"text-align: center;\">\n        <a href=\"YOUR_PAYMENT_LINK_HERE\" class=\"button\">Pay Now</a>\n    </div>\n</body>\n</html>\n\n","options":{"appendAttribution":false},"subject":"={{ $('Set Fields').item.json.order_id }} - New Invoice from Uppfy Shop ","toEmail":"={{ $('Set Fields').item.json.customer_email }}","fromEmail":"Uppfy Shop <your_from_email>"},"credentials":{"smtp":{"id":"xcnAVXwtuOa1IOqE","name":"SMTP account"}},"typeVersion":2.1},{"id":"883e32b6-a812-44c8-b525-97e819af90bd","name":"Append Details to Invoices Sheet","type":"n8n-nodes-base.googleSheets","position":[860,320],"parameters":{"columns":{"value":{"Status":"Unpaid","Invoice ID":"={{ $('Set Fields').item.json.order_id }}","Invoice URL":"={{ $('Upload PDF to GDrive').item.json.webViewLink }}","Invoice Amt.":"=${{ $('Set Fields').item.json.total }}","Customer Name":"={{ $('Set Fields').item.json.customer_name }}","Customer Email":"={{ $('Set Fields').item.json.customer_email }}"},"schema":[{"id":"Invoice ID","type":"string","display":true,"removed":false,"required":false,"displayName":"Invoice ID","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Customer Name","type":"string","display":true,"removed":false,"required":false,"displayName":"Customer Name","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Customer Email","type":"string","display":true,"removed":false,"required":false,"displayName":"Customer Email","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Invoice Amt.","type":"string","display":true,"required":false,"displayName":"Invoice Amt.","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Invoice URL","type":"string","display":true,"required":false,"displayName":"Invoice URL","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Status","type":"string","display":true,"required":false,"displayName":"Status","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["Invoice ID"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"appendOrUpdate","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1QW_Lg1aoEBku8GaxwPbZfBY5ITAuSdvoAXRyNdCEujM/edit#gid=0","cachedResultName":"Invoices"},"documentId":{"__rl":true,"mode":"list","value":"1QW_Lg1aoEBku8GaxwPbZfBY5ITAuSdvoAXRyNdCEujM","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1QW_Lg1aoEBku8GaxwPbZfBY5ITAuSdvoAXRyNdCEujM/edit?usp=drivesdk","cachedResultName":"Uppfy Shop Invoices"}},"credentials":{"googleSheetsOAuth2Api":{"id":"d0qeLhShx9sGXalR","name":"Google Sheets"}},"typeVersion":4.5},{"id":"cd06d6c9-903d-4af8-8327-eb36ba3bc73a","name":"Download PDF from API","type":"n8n-nodes-base.httpRequest","position":[200,320],"parameters":{"url":" https://rhodium-tecnologia-html2pdf.s3.amazonaws.com/public/pdfs/1747392997249.pdf","options":{}},"typeVersion":4.2},{"id":"7d308e22-9b2d-4993-8aad-cc701303d38d","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-280,-160],"parameters":{"width":180,"height":320,"content":"## Pinned Data to Simulate Webhook Query"},"typeVersion":1}],"active":false,"pinData":{"Webhook Simulator":[{"json":{"total":65,"products":[{"name":"T-shirt","price":25,"quantity":2},{"name":"Hat","price":15,"quantity":1}],"customer_name":"Jane Doe","customer_email":"jane@example.com"}}]},"settings":{"executionOrder":"v1"},"versionId":"dec45f2b-cb36-4f86-a8cc-d3c498ae7aa2","connections":{"Set Fields":{"main":[[{"node":"Create Invoice HTML","type":"main","index":0}]]},"HTML to PDF":{"main":[[{"node":"Download PDF from API","type":"main","index":0}]]},"If Does not Exist":{"main":[[{"node":"Set Fields","type":"main","index":0}],[{"node":"Generate Invoice ID","type":"main","index":0}]]},"Webhook Simulator":{"main":[[{"node":"Generate Invoice ID","type":"main","index":0}]]},"Create Invoice HTML":{"main":[[{"node":"HTML to PDF","type":"main","index":0}]]},"Generate Invoice ID":{"main":[[{"node":"Check if ID Already Exists","type":"main","index":0}]]},"Upload PDF to GDrive":{"main":[[{"node":"Email Invoice to Customer","type":"main","index":0}]]},"Download PDF from API":{"main":[[{"node":"Upload PDF to GDrive","type":"main","index":0}]]},"Email Invoice to Customer":{"main":[[{"node":"Append Details to Invoices Sheet","type":"main","index":0}]]},"Check if ID Already Exists":{"main":[[{"node":"If Does not Exist","type":"main","index":0}]]}}}


name: Resume Data Extraction and Storage in Supabase from Email Attachments
author_name: Belgacem Dhiflaoui
author_username: kacemdh
categories: []
created_at: 2025-05-16T13:42:57.033Z
updated_at: 2025-05-16T13:42:57.033Z
url: https://n8n.io/workflows/4106
scraped_at: 2025-06-19 22:50:23
description:
  Description
  What Problem Does This Solve? 🛠️

  This workflow automates the process of extracting key information from resumes received as email attachments and storing that data in a structured format within a Supabase database. It eliminates the manual effort of reviewing each resume, identifying relevant details, and entering them into a database. This streamlines the hiring process, making it faster and more efficient for recruiters and HR professionals.

  Target audience: Recruiters, HR departments, and talent acquisition teams.

  What Does It Do? 🌟
  Monitors a designated email inbox for new messages with resume attachments.
  Extracts key information such as name, contact details, education, work experience, and skills from the attached resumes.
  Cleans and formats the extracted data.
  Stores the processed data securely in a Supabase database.

  Key Features 📋

  Automatic email monitoring for resume attachments.
  Intelligent data extraction from various resume formats (e.g., PDF, DOC, DOCX).
  Customizable data fields to capture specific information.
  Seamless integration with Supabase for data storage.
  Uses OpenRouter to streamline API key management for services such as AI-powered parsing.

  Setup Instructions

  Prerequisites ⚙️

  n8n Instance**: Self-hosted or cloud instance of n8n.
  Email Account**: Gmail account with Gmail API access for receiving resumes.
  Supabase Account**: A Supabase project with a database/table ready to store extracted resume data. You'll need the Supabase URL and API key.
  OpenRouter Account**: For managing AI model API keys centrally when using LLM-based resume parsing.

  Installation Steps 📦
  1. Import the Workflow:

  Copy the exported workflow JSON.
  Import it into your n8n instance via “Import from File” or “Import from URL”.

  2. Configure Credentials:

  In n8n &gt; Credentials, add credentials for:
    Email account (Gmail API): Provide Client ID and Client Secret from the Google Cloud Platform.
    Supabase: Provide the Supabase URL and the anon public API key.
    OpenRouter (Optional): Add your OpenRouter API key for use with any AI-powered resume parsing nodes.

  Assign these credentials to their respective nodes:

    Gmail Trigger → Email credentials.
    Supabase Insert → Supabase credentials.
     AI Parsing Node → OpenRouter credentials.

  3. Set Up Supabase Table:

  Create a table in Supabase with columns such as:
  name, email, phone, education, experience, skills, received_date, etc.

  Make sure the field names align with the structure used in your workflow.

  4. Customize Nodes:

  Parsing Node(s):* Modify the workflow to use an *OpenAI model* directly for field extraction, replacing the *Basic LLM Chain** node that utilizes OpenRouter.

  5. Test the Workflow:

  Send a test email with a resume attachment.
  Check n8n's execution log to confirm the workflow triggered, parsed the data, and inserted it into Supabase.
  Verify data integrity in your Supabase table.

  How It Works
  High-Level Workflow 🔍

  Email Monitoring: Triggered when a new email with an attachment is received (via Gmail API).
  Attachment Check: Verifies the email contains at least one attachment.
  Prepare Data: Extracts the attachment and prepares it for analysis.
  Data Extraction: Uses OpenRouter-powered LLM (if configured) to extract structured information from the resume.
  Data Storage: The structured information is saved into the Supabase database.

  Node Names and Actions (Example)

  Gmail Trigger:** Triggers when a new email is received.
  IF**: Checks whether the received email includes any attachments.
  Get Attachments:** Retrieves attachments from the triggering email.
  Prepare Data:** Prepares the attachment content for processing.
  Basic LLM Chain:** Uses an AI model via OpenRouter to extract relevant resume data and returns it as structured fields.
  Supabase-Insert:** Inserts the structured resume data into your Supabase database.

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.supabase","@n8n/n8n-nodes-langchain.chainLlm","@n8n/n8n-nodes-langchain.outputParserStructured","@n8n/n8n-nodes-langchain.lmChatOpenRouter"]

workflow_json:
  {"id":"GtN4XdkLIPMBIqSU","meta":{"instanceId":"82cad572864ecfae931ea0fa4a2122d5ad401b8f2cb25fb3ff144b553e0d676d"},"name":"Resume-Information-Extractor","tags":[],"nodes":[{"id":"76cdbf85-39be-4617-8215-10d728f281eb","name":"Gmail Trigger","type":"n8n-nodes-base.gmailTrigger","position":[80,80],"parameters":{"simple":false,"filters":{},"options":{"downloadAttachments":true},"pollTimes":{"item":[{"mode":"everyMinute"}]}},"typeVersion":1.2},{"id":"cd0204d2-07b5-4ca7-821a-4a69289f5af1","name":"Extract from File","type":"n8n-nodes-base.extractFromFile","position":[560,80],"parameters":{"options":{},"operation":"pdf","binaryPropertyName":"attachment_0"},"typeVersion":1},{"id":"4814f698-4598-4f07-8493-3ffa5d256847","name":"Edit Fields","type":"n8n-nodes-base.set","position":[780,80],"parameters":{"options":{},"assignments":{"assignments":[{"id":"b5b82b5d-ae4e-43d9-835b-13c9f86555e7","name":"text","type":"string","value":"={{ $json.text }}"}]}},"typeVersion":3.4},{"id":"7e5b3608-b081-4c1a-b349-9ab4fc2d0a1c","name":"Basic LLM Chain","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[1000,80],"parameters":{"text":"=You are an HR expert, you are given a detailed CV text \nextract \nName \nEmail \nTelephone \nExperience \nSkills \nEducation \nThis is the CV text: {{ $json.text }}","promptType":"define","hasOutputParser":true},"typeVersion":1.6},{"id":"04745a86-bf30-46e1-a8e0-b81bd88cf4fe","name":"OpenRouter Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[1000,300],"parameters":{"model":"meta-llama/llama-4-scout:free","options":{}},"typeVersion":1},{"id":"9410f9c8-5df8-4c57-9c50-8f54e14eb14e","name":"Structured Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[1180,300],"parameters":{"jsonSchemaExample":"{ \n\"Name\": \"Firstname Lastname\", \n\"Telephone\": \"01788798797\", \n\"Email\": \"a@b.com\", \n\"Education\": [\"University 1\", \"University 2\"], \n\"Skill\": [\"Skill 1\", \"Skill 2\", \"Skill 3\"], \n\"Experience\": [\"Job 1\", \"job 2\", \"job 3\"] \n}"},"typeVersion":1.2},{"id":"4aeae52b-8d83-4b01-9731-931d49916afa","name":"HTTP Request","type":"n8n-nodes-base.httpRequest","position":[1360,80],"parameters":{"url":"[supabase URL]","method":"POST","options":{},"sendBody":true,"sendHeaders":true,"bodyParameters":{"parameters":[{"name":"name","value":"={{ $json.output.Name }}"},{"name":"telephone","value":"={{ $json.output.Telephone }}"},{"name":"email","value":"={{ $json.output.Email }}"}]},"headerParameters":{"parameters":[{"name":"apikey","value":"[key]"},{"name":"Authorization","value":"Bearer [key]"},{"name":"Prefer","value":"return=representation"}]}},"typeVersion":4.2},{"id":"b0df6998-5b82-44df-8cee-81db46b5cf00","name":"Supabase","type":"n8n-nodes-base.supabase","position":[2000,80],"parameters":{"tableId":"experiences","fieldsUi":{"fieldValues":[{"fieldId":"cv_id","fieldValue":"={{ $('HTTP Request').item.json.id }}"},{"fieldId":"text","fieldValue":"={{ $json.Expr }}"}]}},"typeVersion":1},{"id":"5f08115f-da1c-49e3-b9ee-799a0a051c1d","name":"Edit Fields1","type":"n8n-nodes-base.set","position":[1580,80],"parameters":{"options":{},"assignments":{"assignments":[{"id":"2bd4d4e4-2d0c-4310-b9f9-a7236ac58f74","name":"Expr","type":"array","value":"={{ $('Basic LLM Chain').item.json.output.Experience }}"}]}},"typeVersion":3.4},{"id":"cffc687f-5dbc-45b6-b5b6-328c567eb2d6","name":"Split Out","type":"n8n-nodes-base.splitOut","position":[1800,80],"parameters":{"options":{},"fieldToSplitOut":"Expr"},"typeVersion":1},{"id":"3e676d37-1f0c-4833-8108-62abc882bc1e","name":"Supabase1","type":"n8n-nodes-base.supabase","position":[2000,280],"parameters":{"tableId":"skills","fieldsUi":{"fieldValues":[{"fieldId":"cv_id","fieldValue":"={{ $('HTTP Request').item.json.id }}"},{"fieldId":"text","fieldValue":"={{ $json.skill }}"}]}},"typeVersion":1},{"id":"a6d6b1eb-26b5-4e0d-aee3-1f82c4aeb264","name":"Edit Fields2","type":"n8n-nodes-base.set","position":[1580,280],"parameters":{"options":{},"assignments":{"assignments":[{"id":"2bd4d4e4-2d0c-4310-b9f9-a7236ac58f74","name":"skill","type":"array","value":"={{ $('Basic LLM Chain').item.json.output.Skill }}"}]}},"typeVersion":3.4},{"id":"f93e92e1-5c0e-47dd-9b90-9482df23f4b3","name":"Split Out1","type":"n8n-nodes-base.splitOut","position":[1800,280],"parameters":{"options":{},"fieldToSplitOut":"skill"},"typeVersion":1},{"id":"e5f33b95-0b10-4fbf-96c4-9054d9c2f36f","name":"Supabase2","type":"n8n-nodes-base.supabase","position":[2000,500],"parameters":{"tableId":"education","fieldsUi":{"fieldValues":[{"fieldId":"cv_id","fieldValue":"={{ $('HTTP Request').item.json.id }}"},{"fieldId":"text","fieldValue":"={{ $json.Educ }}"}]}},"typeVersion":1},{"id":"fe182a17-f251-419a-a3e7-6601c1bda065","name":"Edit Fields3","type":"n8n-nodes-base.set","position":[1580,500],"parameters":{"options":{},"assignments":{"assignments":[{"id":"2bd4d4e4-2d0c-4310-b9f9-a7236ac58f74","name":"Educ","type":"array","value":"={{ $('Basic LLM Chain').item.json.output.Education }}"}]}},"typeVersion":3.4},{"id":"e947dd88-027c-4bfc-9c8b-289efe514679","name":"Split Out2","type":"n8n-nodes-base.splitOut","position":[1800,500],"parameters":{"options":{},"fieldToSplitOut":"Educ"},"typeVersion":1},{"id":"d90fd5f8-8b29-4c75-874c-cb2c783a924e","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[0,0],"parameters":{"height":280,"content":"## Email Trigger\n"},"typeVersion":1},{"id":"7465aa08-4604-4d0d-b36c-17aabba2dbe0","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[520,0],"parameters":{"color":4,"width":400,"height":280,"content":"## Prepare Data \n"},"typeVersion":1},{"id":"2a751d1c-1c1f-40dc-93e4-45195dc397dc","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[960,0],"parameters":{"color":3,"width":360,"height":440,"content":"## Extract Information \n"},"typeVersion":1},{"id":"0ff39e87-a016-4bb9-8c00-53178b2ad4bf","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1340,0],"parameters":{"color":6,"width":900,"height":680,"content":"## Save Information\n"},"typeVersion":1},{"id":"6e367ac0-8191-4530-94b7-a6ab7582fbac","name":"If","type":"n8n-nodes-base.if","position":[320,80],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"0047fdcf-2c7b-4286-a54e-7018028dea1c","operator":{"type":"string","operation":"exists","singleValue":true},"leftValue":"attachment_0","rightValue":""}]}},"typeVersion":2.2},{"id":"b7e60ceb-d556-4140-a5fb-6d86a798097f","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[260,0],"parameters":{"color":5,"height":280,"content":"## check if Attachment exists"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"6c3db08e-b96b-4273-8e26-cceec49844a0","connections":{"If":{"main":[[{"node":"Extract from File","type":"main","index":0}]]},"Split Out":{"main":[[{"node":"Supabase","type":"main","index":0}]]},"Split Out1":{"main":[[{"node":"Supabase1","type":"main","index":0}]]},"Split Out2":{"main":[[{"node":"Supabase2","type":"main","index":0}]]},"Edit Fields":{"main":[[{"node":"Basic LLM Chain","type":"main","index":0}]]},"Edit Fields1":{"main":[[{"node":"Split Out","type":"main","index":0}]]},"Edit Fields2":{"main":[[{"node":"Split Out1","type":"main","index":0}]]},"Edit Fields3":{"main":[[{"node":"Split Out2","type":"main","index":0}]]},"HTTP Request":{"main":[[{"node":"Edit Fields1","type":"main","index":0},{"node":"Edit Fields2","type":"main","index":0},{"node":"Edit Fields3","type":"main","index":0}]]},"Gmail Trigger":{"main":[[{"node":"If","type":"main","index":0}]]},"Basic LLM Chain":{"main":[[{"node":"HTTP Request","type":"main","index":0}]]},"Extract from File":{"main":[[{"node":"Edit Fields","type":"main","index":0}]]},"OpenRouter 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: Create AI Videos with OpenAI Scripts, Leonardo Images & HeyGen Avatars
author_name: Adam Crafts
author_username: adamcrafts
categories: []
created_at: 2025-05-16T14:23:39.655Z
updated_at: 2025-05-16T14:23:39.655Z
url: https://n8n.io/workflows/4107
scraped_at: 2025-06-19 22:49:09
description:
  Short Content Automation 🎬 (AI Video System with Bulk Gen, Avatar & Music Customization)

  Overview 🎯

  The "Short Content" automation is a powerful, all-in-one solution designed to streamline the creation of short videos for social media, marketing, or personal projects. Leveraging cutting-edge AI tools and seamless workflows, this automation handles everything from scriptwriting to video assembly—saving time and effort while delivering professional results.


      
        Best Short Content AI System - Watch Video
  Problem 🛠️

  Creating short videos manually is time-consuming and expensive. Businesses and creators struggle with:

  Hiring writers, designers, and editors.  
  Juggling multiple tools for scripts, visuals, and editing.  
  Inconsistent quality and slow turnaround times.  

  This automation solves these challenges with a fully AI-driven, one-click workflow.

  Solution ✅

  A no-code, end-to-end automation that:

  Writes scripts using AI (LLM) or manual input.  
  Generates visuals (Leonardo AI) or acting scenes (RunwayML).  
  Edits and assembles videos (JSON2Video).  
  Generates avatars using HeyGen or Captions.ai.  
  Tracks progress and analytics in Baserow.  

  🔥 Result:  
  High-quality short videos in minutes, not days—with zero manual effort.

  Setup ⚙️ (4–8 minutes)

  Upload Blueprint to N8N  
     Import the provided JSON workflow into your N8N instance.

  Upload Database to Baserow (Free)  
  Follow the setup video step-by-step.

  How It Works 🌟

  Start with a Pre-Built Form  
     Fill in the included Baserow form with your video requirements.

  Generate Videos Instantly  
     Single Video Mode: Run one video at a time for quick results.  
     Bulk Mode: Upload a CSV or use Baserow to queue unlimited videos—perfect for scaling content.

  Workflow Handles the Rest  

  Manage & Iterate  
     Track all videos in Baserow: Edit inputs, retry failed jobs, or adjust styles anytime.

  What’s Included 📦

  ✅ Baserow Template: Pre-configured database.  
  ✅ N8N JSON Blueprint: Ready-to-use workflow.  
  ✅ Step-by-Step Video Guides: Setup & usage instructions.

  Customization 🎨

  🔧 Video Generation Customization

  Script Options**: Auto-generate using AI or write manually.  
  Captions**: Customize type, color, and style.  
  Video Types**: Storytelling, trends, educational, etc.  
  Audio**: Add background music easily.  
  Avatars**:  
    Switch between HeyGen and Captions.ai.  
    Adjust size, position, voice, and appearance.

  ⚙️ System Customization

  N8N Workflow**: Easily customizable for new integrations, prompts, and logic.  
  Baserow Database**: Modify options or add new ones to match your workflow.

  🌐 Explore more workflows

  ❤️ Buy more workflows at: adamcrafts
  🦾 Custom workflows at: adamcrafts@cloudysoftwares.com

  &gt; Build once, customize endlessly, and scale your video content like never before. 🚀

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

workflow_json:
  {"meta":{"instanceId":"2d54f61dfd963457efb86a8690aae457934e92fb9e4b8b6490ca74fc37094458","templateCredsSetupCompleted":true},"nodes":[{"id":"552f4aea-6eba-4ef3-a15a-5803a25ed701","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-4060,260],"parameters":{"content":""},"typeVersion":1},{"id":"e70c19bc-c100-4c4e-bb0c-3480bf43b82e","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-2380,-240],"parameters":{"content":""},"typeVersion":1},{"id":"e51cd6c7-872a-48b8-a6b7-ac47f35a409a","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-1180,1240],"parameters":{"content":""},"typeVersion":1},{"id":"1edeb5fc-2774-46ed-a4f8-c4ac3f3a9ac7","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-700,540],"parameters":{"content":""},"typeVersion":1},{"id":"aa0dff4d-a840-45e0-8de9-fcd170be08d2","name":"Should Process?","type":"n8n-nodes-base.if","position":[-4680,860],"parameters":{},"typeVersion":1},{"id":"1b62d439-f82e-432b-a1bc-5b73abc8b5e6","name":"Switch ScriptType","type":"n8n-nodes-base.switch","position":[-4460,960],"parameters":{},"typeVersion":3.2},{"id":"df9759eb-5511-4323-86b8-7d40bb0e43e9","name":"Basic LLM Chain","type":"@n8n/n8n-nodes-langchain.chainLlm","onError":"continueErrorOutput","position":[-4020,460],"parameters":{},"typeVersion":1.5},{"id":"8ff00af2-cb59-4a48-8504-1e388f00d8c3","name":"If","type":"n8n-nodes-base.if","position":[-4240,1160],"parameters":{},"typeVersion":2.2},{"id":"3ccaa3f8-51b7-44f9-83b2-0ad7fb291596","name":"Body","type":"n8n-nodes-base.set","position":[-4900,860],"parameters":{},"typeVersion":3.4},{"id":"d78562f1-6236-4aa8-81dc-741c82d2b9ea","name":"Structured Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[-3872,1130],"parameters":{},"typeVersion":1.2},{"id":"42276de0-b0f6-490e-9fba-28008e01293b","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-3932,680],"parameters":{},"typeVersion":1.2},{"id":"11c7ba76-0b22-4dfd-b063-dbfc2cf1d582","name":"Leo - Improve Prompt","type":"n8n-nodes-base.httpRequest","onError":"continueErrorOutput","position":[-2984,110],"parameters":{},"typeVersion":4.2},{"id":"8d813e38-4689-4102-9a84-322e57573e72","name":"Leo - Get imageId","type":"n8n-nodes-base.httpRequest","position":[-2324,-90],"parameters":{},"typeVersion":4.2},{"id":"759c964b-560e-476c-9948-041d781d7225","name":"Leo - Generate Image","type":"n8n-nodes-base.httpRequest","onError":"continueErrorOutput","position":[-2764,10],"parameters":{},"notesInFlow":false,"typeVersion":4.2},{"id":"7ba0fa55-3a4a-45ce-bf84-7b0695014e1f","name":"Wait1","type":"n8n-nodes-base.wait","position":[-2544,-90],"webhookId":"ae4c943c-3a67-4532-8fc5-3f0b5c1e9cd3","parameters":{},"typeVersion":1.1},{"id":"8e770b9e-44c3-4d6f-b816-04a141dcea1b","name":"Scenes Mapping","type":"n8n-nodes-base.set","position":[-3644,710],"parameters":{},"typeVersion":3.4},{"id":"eb75b3e1-7945-47cb-99a3-b123d4509840","name":"Split Out","type":"n8n-nodes-base.splitOut","position":[-3424,710],"parameters":{},"typeVersion":1},{"id":"9d1a5b5a-e6f9-4e0b-b0ab-c5d00a42b933","name":"Runway - Create Video","type":"n8n-nodes-base.httpRequest","onError":"continueErrorOutput","position":[-1884,-190],"parameters":{},"typeVersion":4.2},{"id":"e6e34dd1-14b9-457a-94d7-d649df9bf6fa","name":"Runway - Get Video","type":"n8n-nodes-base.httpRequest","onError":"continueErrorOutput","position":[-1444,-290],"parameters":{},"typeVersion":4.2},{"id":"9e5b3314-5ff5-40d5-b25b-650b2b86b673","name":"Wait2","type":"n8n-nodes-base.wait","position":[-1664,-290],"webhookId":"1d9b1044-08ca-446c-a290-e1e28d356402","parameters":{},"typeVersion":1.1},{"id":"9122333a-9cbd-4e05-a071-fa63237abc70","name":"loop_over_scenes","type":"n8n-nodes-base.splitInBatches","position":[-3204,710],"parameters":{},"typeVersion":3},{"id":"12e3944f-bf50-452a-a566-e21e37b8ae8c","name":"Code","type":"n8n-nodes-base.code","position":[-2764,910],"parameters":{},"typeVersion":2},{"id":"87281d2b-c75b-442c-b7b4-069e9b547c3b","name":"Wait","type":"n8n-nodes-base.wait","position":[-1004,835],"webhookId":"5cac0c0c-2373-410d-a4fa-93631e4f7a16","parameters":{},"typeVersion":1.1},{"id":"1d14b153-cf53-4bb8-bc48-500d407f1136","name":"json2video : Video Rendering","type":"n8n-nodes-base.httpRequest","onError":"continueErrorOutput","position":[-1224,835],"parameters":{},"typeVersion":4.2},{"id":"e85203de-a496-4424-92cf-6702be3107fd","name":"json2video : Check Video Rendering","type":"n8n-nodes-base.httpRequest","position":[-784,785],"parameters":{},"typeVersion":4.2},{"id":"1f7e969a-9eb0-4d34-8bee-cc412794757a","name":"Baserow","type":"n8n-nodes-base.baserow","position":[-344,760],"parameters":{},"typeVersion":1},{"id":"8c3c9f77-c674-4082-8417-d218e4c1f146","name":"Baserow Processing","type":"n8n-nodes-base.baserow","position":[-4460,760],"parameters":{},"typeVersion":1},{"id":"f051222a-69de-488b-95ee-8ddba38cfecc","name":"output","type":"n8n-nodes-base.set","position":[-1224,510],"parameters":{},"typeVersion":3.4},{"id":"4ccc7e0b-95a8-4bf8-9328-914796d04e5f","name":"Update Script","type":"n8n-nodes-base.baserow","position":[-3644,510],"parameters":{},"typeVersion":1},{"id":"1ac9cf4f-2ea5-4901-8021-daa1aaebe526","name":"BackgroundType","type":"n8n-nodes-base.if","position":[-2104,-90],"parameters":{},"typeVersion":2.2},{"id":"3f4cfe61-ad21-4306-b510-ff5a6cdc9c6a","name":"output image","type":"n8n-nodes-base.set","position":[-1884,10],"parameters":{},"typeVersion":3.4},{"id":"ae0c2d35-18f4-4360-a61d-d5c40624864e","name":"Execute Workflow2","type":"n8n-nodes-base.executeWorkflow","position":[-1664,-90],"parameters":{},"typeVersion":1.2},{"id":"53ee6f59-3e74-4dbf-9655-4557f2e3dd80","name":"Execute Workflow3","type":"n8n-nodes-base.executeWorkflow","position":[-2544,110],"parameters":{},"typeVersion":1.2},{"id":"3cc71591-718c-48c5-a81f-903bc27703a7","name":"Execute Workflow4","type":"n8n-nodes-base.executeWorkflow","position":[-3600,880],"parameters":{},"typeVersion":1.2},{"id":"ffba25bf-ebfb-437c-88a9-baffa9183ad2","name":"HeyGen","type":"n8n-nodes-base.httpRequest","onError":"continueErrorOutput","position":[-2324,985],"parameters":{},"typeVersion":4.2},{"id":"0f0c91ed-3a81-4add-9219-fb0b2b769592","name":"Wait4","type":"n8n-nodes-base.wait","position":[-2104,885],"webhookId":"d2c37f01-834e-40d3-888e-6e7e4296f474","parameters":{},"typeVersion":1.1},{"id":"e2144fa4-4a79-4203-8690-7fc3654aa2aa","name":"HeyGen : Check Video","type":"n8n-nodes-base.httpRequest","onError":"continueErrorOutput","position":[-1884,810],"parameters":{},"typeVersion":4.2},{"id":"5e3c03f0-2688-48e2-88f9-8c56cb2bcd82","name":"heygen_response","type":"n8n-nodes-base.switch","position":[-1664,885],"parameters":{},"typeVersion":3.2},{"id":"f1fe987d-97f3-4f86-b160-1ec019db8ba9","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-2160,1300],"parameters":{"content":""},"typeVersion":1},{"id":"ecd90ffe-b4f3-4895-858e-f2dbbc758f3f","name":"Wait6","type":"n8n-nodes-base.wait","position":[-2104,285],"webhookId":"1ae300a3-2b49-4ee0-9817-9d29692d7bd8","parameters":{},"typeVersion":1.1},{"id":"7f2db63c-6ccd-427b-976d-788906acaffa","name":"CaptionsAI1","type":"n8n-nodes-base.httpRequest","onError":"continueErrorOutput","position":[-2324,385],"parameters":{},"typeVersion":4.2},{"id":"ef6d1fda-f589-4a80-bef9-6b58a0c7be4c","name":"CaptionsAI : Check Poll1","type":"n8n-nodes-base.httpRequest","position":[-1884,210],"parameters":{},"typeVersion":4.2},{"id":"704dc30e-92d7-4fbf-84f7-fa28c8e3c800","name":"Aggregate","type":"n8n-nodes-base.aggregate","position":[-2544,385],"parameters":{},"typeVersion":1},{"id":"7fa5ee4a-b331-44e3-8eac-bb51a1640f02","name":"j2v_response","type":"n8n-nodes-base.switch","position":[-564,835],"parameters":{},"typeVersion":3.2},{"id":"4bf31cad-30ba-4111-82c6-543c8270ba78","name":"json2video Execute ERROR","type":"n8n-nodes-base.executeWorkflow","position":[-1004,1035],"parameters":{},"typeVersion":1.2},{"id":"2b7f8cf6-e72f-4709-8384-470be9018a58","name":"json2video Execute ERROR1","type":"n8n-nodes-base.executeWorkflow","position":[-344,960],"parameters":{},"typeVersion":1.2},{"id":"000f4384-59f2-45cc-8ac7-947578faf961","name":"CAPTIONS Execute ERROR","type":"n8n-nodes-base.executeWorkflow","position":[-1444,385],"parameters":{},"typeVersion":1.2},{"id":"8c0f1519-7c15-4753-a3a4-e0ea7bdecd91","name":"cap_response","type":"n8n-nodes-base.switch","position":[-1664,285],"parameters":{},"typeVersion":3.2},{"id":"ca2a0e83-1945-44da-88db-fd43f7abdd01","name":"Code Add Sub","type":"n8n-nodes-base.code","position":[-1444,10],"parameters":{},"typeVersion":2},{"id":"32919f30-7192-4fe9-a8c0-5056f23930da","name":"Execute Workflow","type":"n8n-nodes-base.executeWorkflow","position":[-3942,1310],"parameters":{},"typeVersion":1.2},{"id":"0d2c27de-ced5-4717-bd69-120cdca0c404","name":"Code Heygen","type":"n8n-nodes-base.code","position":[-1444,885],"parameters":{},"typeVersion":2},{"id":"49cbb913-b8d8-407b-aba1-772b183fc2cb","name":"Webhook","type":"n8n-nodes-base.webhook","position":[-5120,860],"webhookId":"9dc1daa9-0cc3-4171-bd2c-f334afe7f786","parameters":{},"typeVersion":2},{"id":"ece27b23-6adb-4bde-bd27-16f9c52074b1","name":"If_with_heygen","type":"n8n-nodes-base.if","position":[-2544,910],"parameters":{},"typeVersion":2.2},{"id":"4b574962-192a-4896-9b20-d1a1a6a2dba9","name":"If_with_avatar","type":"n8n-nodes-base.if","position":[-2984,785],"parameters":{},"typeVersion":2.2},{"id":"17443565-19e6-4f87-b3d0-ae760ef2e9c0","name":"heygen Execute ERROR","type":"n8n-nodes-base.executeWorkflow","position":[-2104,1110],"parameters":{},"typeVersion":1.2},{"id":"db4608b4-de96-4fca-8015-9a529c5d7ec2","name":"heygen Execute ERROR2","type":"n8n-nodes-base.executeWorkflow","position":[-1664,1085],"parameters":{},"typeVersion":1.2},{"id":"59b0d81e-47dd-4142-9e4f-2720d3ab4cd2","name":"Execute Workflow5","type":"n8n-nodes-base.executeWorkflow","position":[-2764,235],"parameters":{},"typeVersion":1.2},{"id":"5907b590-cb1a-40f2-973a-c267f4f2a618","name":"CAPTIONS Execute ERROR1","type":"n8n-nodes-base.executeWorkflow","position":[-2104,485],"parameters":{},"typeVersion":1.2},{"id":"5003eb72-ccaf-4397-b222-74520118b710","name":"Execute Workflow6","type":"n8n-nodes-base.executeWorkflow","position":[-1224,-340],"parameters":{},"typeVersion":1.2},{"id":"d7bfd001-f3e7-4615-9cb4-c999f85796b4","name":"Basic LLM Chain Manual","type":"@n8n/n8n-nodes-langchain.chainLlm","onError":"continueErrorOutput","position":[-4020,910],"parameters":{},"typeVersion":1.5},{"id":"7d14ce33-6879-4fbf-8c4d-741dc0199fd8","name":"OpenAI Chat Model1","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-3992,1130],"parameters":{},"typeVersion":1.2},{"id":"0cd3ffe5-17c2-4036-93ff-f26366905418","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-5280,-380],"parameters":{"content":""},"typeVersion":1},{"id":"2dc14abe-5ce2-47dd-95a3-a53e0cc3ba3d","name":"Baserow Error","type":"n8n-nodes-base.baserow","position":[-4900,1280],"parameters":{},"typeVersion":1},{"id":"ec2f48d4-fe85-4395-b6e0-6944a169f405","name":"Stop and Error","type":"n8n-nodes-base.stopAndError","position":[-4680,1280],"parameters":{},"typeVersion":1},{"id":"b57d294a-0872-43b4-9477-84f72990adb4","name":"When Executed by Another Workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[-5120,1280],"parameters":{},"typeVersion":1.1},{"id":"2410ae4a-e42b-41de-b5a6-fcef0726918a","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-5160,1160],"parameters":{"content":""},"typeVersion":1},{"id":"8105cbf3-f289-4de6-b39a-db9ba5a8b85d","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[-4640,-380],"parameters":{"content":""},"typeVersion":1},{"id":"9e42ccf0-a874-4171-bea5-54647a79fb93","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[-1880,520],"parameters":{"content":""},"typeVersion":1}],"pinData":{"Webhook":[{"body":{"items":[{"id":108,"Topic":"5 Mind-Blowing Facts About Space Exploration","order":"17.00000000000000000000","Script":null,"Status":null,"AvatarId":"Conrad_sitting_house_side","Duration":null,"ErrorLog":null,"fontSize":null,"VideoType":{"id":3178320,"color":"light-purple","value":"Story"},"Created on":"2025-05-04T15:04:40.357861Z","ScriptType":{"id":3178323,"color":"green","value":"ai gen"},"AvatarStatus":{"id":3178329,"color":"light-purple","value":"Heygen"},"ScenesNumber":"5","CaptionsStyle":{"id":3178331,"color":"light-green","value":"classic-progressive"},"FinalVideoURL":"","HeygenVoiceId":"2b0587b1089b4544ae41b155e3d21118","Last modified":"2025-05-04T15:04:40.357861Z","BackgroundType":{"id":3178325,"color":"light-cyan","value":"Images"},"BackgroundMusic":"","CaptionsBoxColor":"#000000","CaptionsLineColor":"#FFFFFF","HeygenAvatarWidth":"280","HeygenAvatarHeight":"340","HeygenAvatarPosition":{"id":3178338,"color":"light-green","value":"bottom-right"}}],"event_id":"0c5f0416-4d27-4d2e-a75d-2b5e60c32e6d","table_id":522247,"event_type":"rows.created","webhook_id":6062,"database_id":218184,"workspace_id":96424},"query":{},"params":{},"headers":{"host":"n8n.coolify.cloudysoftwares.tech","accept":"*/*","baggage":"sentry-trace_id=efe94c5a1e454e57aa0b88a0c00d1cb3,sentry-environment=production,sentry-release=38df5eb102dc465ef71bfc85e63012e3d13ad610,sentry-public_key=c030c9f41daa4b3da9cbc0fcdf5027f9, http.route=%5Eapi%2Fdatabase%2Fviews%2Fform%2F%28%3FP%3Cslug%3E%5B-%5Cw%5D%2B%29%2Fsubmit%2F%24,user.id=74171","x-real-ip":"3.77.114.147","user-agent":"python-requests/2.31.0","traceparent":"00-53a1f27d3e9774d4ccb87c740e056a61-b8850e99d79163c6-00","content-type":"application/json","sentry-trace":"efe94c5a1e454e57aa0b88a0c00d1cb3-bc58b7dddbd6c53d","content-length":"1218","accept-encoding":"gzip, deflate, br","x-baserow-event":"rows.created","x-forwarded-for":"3.77.114.147","x-forwarded-host":"n8n.coolify.cloudysoftwares.tech","x-forwarded-port":"443","x-forwarded-proto":"https","x-baserow-delivery":"0c5f0416-4d27-4d2e-a75d-2b5e60c32e6d","x-forwarded-server":"837fcab6fd50"},"webhookUrl":"https://n8n.coolify.cloudysoftwares.tech/webhook/short-gen/v2","executionMode":"production"}]},"connections":{"If":{"main":[[{"node":"Basic LLM Chain Manual","type":"main","index":0}],[{"node":"Execute Workflow","type":"main","index":0}]]},"Body":{"main":[[{"node":"Should Process?","type":"main","index":0}]]},"Code":{"main":[[{"node":"If_with_heygen","type":"main","index":0}]]},"Wait":{"main":[[{"node":"json2video : Check Video Rendering","type":"main","index":0}]]},"Wait1":{"main":[[{"node":"Leo - Get imageId","type":"main","index":0}]]},"Wait2":{"main":[[{"node":"Runway - Get Video","type":"main","index":0}]]},"Wait4":{"main":[[{"node":"HeyGen : Check Video","type":"main","index":0}]]},"Wait6":{"main":[[{"node":"CaptionsAI : Check Poll1","type":"main","index":0}]]},"HeyGen":{"main":[[{"node":"Wait4","type":"main","index":0}],[{"node":"heygen Execute ERROR","type":"main","index":0}]]},"output":{"main":[[{"node":"loop_over_scenes","type":"main","index":0}]]},"Webhook":{"main":[[{"node":"Body","type":"main","index":0}]]},"Aggregate":{"main":[[{"node":"CaptionsAI1","type":"main","index":0}]]},"Split Out":{"main":[[{"node":"loop_over_scenes","type":"main","index":0}]]},"CaptionsAI1":{"main":[[{"node":"Wait6","type":"main","index":0}],[{"node":"CAPTIONS Execute ERROR1","type":"main","index":0}]]},"Code Heygen":{"main":[[{"node":"json2video : Video Rendering","type":"main","index":0}]]},"Code Add Sub":{"main":[[{"node":"json2video : Video Rendering","type":"main","index":0}]]},"cap_response":{"main":[[{"node":"Code Add Sub","type":"main","index":0}],[{"node":"Wait6","type":"main","index":0}],[{"node":"CAPTIONS Execute ERROR","type":"main","index":0}]]},"j2v_response":{"main":[[{"node":"Baserow","type":"main","index":0}],[{"node":"Wait","type":"main","index":0}],[{"node":"json2video Execute ERROR1","type":"main","index":0}]]},"output image":{"main":[[{"node":"loop_over_scenes","type":"main","index":0}]]},"Baserow Error":{"main":[[{"node":"Stop and Error","type":"main","index":0}]]},"BackgroundType":{"main":[[{"node":"Runway - Create Video","type":"main","index":0}],[{"node":"output image","type":"main","index":0}]]},"If_with_avatar":{"main":[[{"node":"Aggregate","type":"main","index":0}],[{"node":"Code","type":"main","index":0}]]},"If_with_heygen":{"main":[[{"node":"HeyGen","type":"main","index":0}],[{"node":"json2video : Video Rendering","type":"main","index":0}]]},"Scenes Mapping":{"main":[[{"node":"Split Out","type":"main","index":0}]]},"Basic LLM Chain":{"main":[[{"node":"Scenes Mapping","type":"main","index":0},{"node":"Update Script","type":"main","index":0}],[{"node":"Execute Workflow4","type":"main","index":0}]]},"Should Process?":{"main":[[{"node":"Switch ScriptType","type":"main","index":0},{"node":"Baserow Processing","type":"main","index":0}]]},"heygen_response":{"main":[[{"node":"Code Heygen","type":"main","index":0}],[{"node":"Wait4","type":"main","index":0}]]},"loop_over_scenes":{"main":[[{"node":"If_with_avatar","type":"main","index":0}],[{"node":"Leo - Improve Prompt","type":"main","index":0}]]},"Leo - Get imageId":{"main":[[{"node":"BackgroundType","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Basic LLM Chain","type":"ai_languageModel","index":0}]]},"Switch ScriptType":{"main":[[{"node":"If","type":"main","index":0}],[{"node":"Basic LLM Chain","type":"main","index":0}]]},"OpenAI Chat Model1":{"ai_languageModel":[[{"node":"Basic LLM Chain Manual","type":"ai_languageModel","index":0}]]},"Runway - Get Video":{"main":[[{"node":"output","type":"main","index":0}],[{"node":"Execute Workflow6","type":"main","index":0}]]},"HeyGen : Check Video":{"main":[[{"node":"heygen_response","type":"main","index":0}],[{"node":"heygen Execute ERROR2","type":"main","index":0}]]},"Leo - Generate Image":{"main":[[{"node":"Wait1","type":"main","index":0}],[{"node":"Execute Workflow3","type":"main","index":0}]]},"Leo - Improve Prompt":{"main":[[{"node":"Leo - Generate Image","type":"main","index":0}],[{"node":"Execute Workflow5","type":"main","index":0}]]},"Runway - Create Video":{"main":[[{"node":"Wait2","type":"main","index":0}],[{"node":"Execute Workflow2","type":"main","index":0}]]},"Basic LLM Chain Manual":{"main":[[{"node":"Update Script","type":"main","index":0},{"node":"Scenes Mapping","type":"main","index":0}],[{"node":"Execute Workflow4","type":"main","index":0}]]},"CaptionsAI : Check Poll1":{"main":[[{"node":"cap_response","type":"main","index":0}]]},"Structured Output Parser":{"ai_outputParser":[[{"node":"Basic LLM Chain","type":"ai_outputParser","index":0},{"node":"Basic LLM Chain Manual","type":"ai_outputParser","index":0}]]},"json2video : Video Rendering":{"main":[[{"node":"Wait","type":"main","index":0}],[{"node":"json2video Execute ERROR","type":"main","index":0}]]},"When Executed by Another Workflow":{"main":[[{"node":"Baserow Error","type":"main","index":0}]]},"json2video : Check Video Rendering":{"main":[[{"node":"j2v_response","type":"main","index":0}]]}}}


name: AI image generator from text built on fal.ai
author_name: n8n Team
author_username: n8n-team
categories: []
created_at: 2025-05-16T14:29:12.278Z
updated_at: 2025-05-16T14:29:12.278Z
url: https://n8n.io/workflows/4108
scraped_at: 2025-06-19 22:49:43
description:
  Who this template is for

  This template is for developers, content creators, or application builders who want to integrate an AI-powered text-to-image generation service into their applications or systems via an API endpoint.

  Use case

  Creating a secure API endpoint that converts text prompts into AI-generated images, with built-in content moderation to prevent inappropriate content generation. This can be used for creative applications, content creation tools, prototyping interfaces, or any system that needs on-demand image generation.

  How this workflow works

  Receives text prompt through a webhook endpoint
  Filters the prompt for inappropriate content using AI moderation
  Submits valid prompts to the Fal.ai Flux image generation service
  Polls for completion status and retrieves the generated image when ready
  Returns the image results in a structured JSON format to the client

  Set up steps

  Create a Fal.ai account and obtain API credentials
  Configure the HTTP Header Auth credentials with your Fal.ai API key
  Set up an OpenAI API key for the content moderation component
  Deploy the workflow and note the webhook URL for your API endpoint
  Test the endpoint by sending a POST request with a JSON body containing a "prompt" field

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

workflow_json:
  {"meta":{"instanceId":"cb484ba7b742928a2048bf8829668bed5b5ad9787579adea888f05980292a4a7"},"nodes":[{"id":"c5b7bac5-6e31-4338-af76-32a34be8ae4d","name":"Webhook","type":"n8n-nodes-base.webhook","position":[-440,280],"webhookId":"5cca11bb-eaea-4c3a-86f7-16d5802b6ac8","parameters":{"path":"ai_text_to_image_generator","options":{},"httpMethod":"POST","responseMode":"responseNode"},"typeVersion":2},{"id":"ba2850cc-3d2b-45d7-9c1d-87bff38d99c3","name":"Fetch Status","type":"n8n-nodes-base.httpRequest","position":[300,280],"parameters":{"url":"=https://queue.fal.run/fal-ai/flux/requests/{{ $json.request_id }}/status","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"0qP44IHCmBfL54Vb","name":"Falai Polina"}},"typeVersion":4.2},{"id":"44e08f96-e6b2-49a8-8077-571e07108d8d","name":"Wait","type":"n8n-nodes-base.wait","position":[680,460],"webhookId":"150069ed-885b-497f-a32a-09e7088136e6","parameters":{"amount":1},"typeVersion":1.1},{"id":"a1455b63-eed2-4c6d-86dc-11bf0937892b","name":"Is Ready?","type":"n8n-nodes-base.if","position":[480,280],"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":"6b4446ef-0c5f-4d8b-839e-e7a9d6ae4773","name":"Submit Request","type":"n8n-nodes-base.httpRequest","position":[100,280],"parameters":{"url":"https://queue.fal.run/fal-ai/flux/schnell","method":"POST","options":{},"jsonBody":"={\"prompt\": \"{{ $json.body.prompt }}\"}","sendBody":true,"sendHeaders":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json"}]}},"credentials":{"httpHeaderAuth":{"id":"0qP44IHCmBfL54Vb","name":"Falai Polina"}},"typeVersion":4.2},{"id":"3f1df77f-8576-4c32-a1c8-7e80f5bf572d","name":"Fetch Result","type":"n8n-nodes-base.httpRequest","position":[680,280],"parameters":{"url":"={{ $json.response_url }}","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"0qP44IHCmBfL54Vb","name":"Falai Polina"}},"typeVersion":4.2},{"id":"744b0b05-d1f7-4972-b16d-70328b7a36c9","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-260,440],"parameters":{"options":{}},"credentials":{"openAiApi":{"id":"QpFZ2EiM3WGl6Zr3","name":"Marketing OpenAI"}},"typeVersion":1.1},{"id":"9ab24ceb-c1c1-42b8-88d9-249c2db60a8d","name":"400 Error","type":"n8n-nodes-base.respondToWebhook","position":[100,640],"parameters":{"options":{"responseCode":400},"respondWith":"json","responseBody":"={{\n{\n  \"error\": \"Prompt is in violation of terms of use. Please try again.\",\n  \"result\": []\n}\n}}"},"typeVersion":1.1},{"id":"c5ef424e-1fb5-44d5-9612-4c76c7d1d232","name":"Success","type":"n8n-nodes-base.respondToWebhook","position":[900,280],"parameters":{"options":{},"respondWith":"json","responseBody":"={{\n{\n  \"error\": null,\n  \"result\": $json.images\n}\n}}"},"typeVersion":1.1},{"id":"eb43cc4a-4d15-47b9-9c81-840ecc9cfafa","name":"NSFW Filter","type":"@n8n/n8n-nodes-langchain.textClassifier","position":[-260,280],"parameters":{"options":{"fallback":"other"},"inputText":"={{ $json.body.prompt }}","categories":{"categories":[{"category":"NSFW","description":"text is NSFW"},{"category":"SFW","description":"text is SFW"}]}},"typeVersion":1},{"id":"db102cc6-b414-4187-b269-8f73158f0fb3","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-480,120],"parameters":{"width":540,"height":460,"content":"## Receives text prompt through a webhook endpoint and filters the prompt for inappropriate content using AI moderation"},"typeVersion":1},{"id":"b2ff86e9-62cc-45d1-9f89-6a5d2010c976","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[80,0],"parameters":{"width":540,"height":580,"content":"## Submits valid prompts to the Fal.ai and polls for completion status and retrieves the generated image when ready\n\nFal.ai is a model inference and finetuning service dedicated to AI image and video. It hosts many popular third party models including Flux by Black Forest Labs.\n\nSign up here - https://fal.ai - for an api key."},"typeVersion":1}],"pinData":{"Webhook":[{"body":{"prompt":"A person sitting under a moonlit sky","styleId":"1"},"query":{},"params":{},"headers":{"host":"[insert your host]","accept":"*/*","origin":"http://localhost:3000","pragma":"no-cache","referer":"http://localhost:3000/","priority":"u=1, i","sec-ch-ua":"\"Chromium\";v=\"134\", \"Not:A-Brand\";v=\"24\", \"Google Chrome\";v=\"134\"","x-real-ip":"10.255.0.2","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36","content-type":"multipart/form-data; boundary=----WebKitFormBoundary6KvXTaJpPc6UJTId","cache-control":"no-cache","content-length":"268","sec-fetch-dest":"empty","sec-fetch-mode":"cors","sec-fetch-site":"cross-site","accept-encoding":"gzip, deflate, br, zstd","accept-language":"pl-PL,pl;q=0.9,en-US;q=0.8,en;q=0.7,fr;q=0.6,la;q=0.5,de;q=0.4,sk;q=0.3,nl;q=0.2,mt;q=0.1","x-forwarded-for":"10.255.0.2","sec-ch-ua-mobile":"?0","x-forwarded-host":"[insert your host]","x-forwarded-port":"443","x-forwarded-proto":"https","sec-ch-ua-platform":"\"macOS\"","x-forwarded-server":"5f641c71d311"},"webhookUrl":"https://[insert your host]/webhook/ai_text_to_image_generator","executionMode":"production"}]},"connections":{"Wait":{"main":[[{"node":"Fetch Status","type":"main","index":0}]]},"Webhook":{"main":[[{"node":"NSFW Filter","type":"main","index":0}]]},"Is Ready?":{"main":[[{"node":"Fetch Result","type":"main","index":0}],[{"node":"Wait","type":"main","index":0}]]},"NSFW Filter":{"main":[[{"node":"400 Error","type":"main","index":0}],[{"node":"Submit Request","type":"main","index":0}],[{"node":"400 Error","type":"main","index":0}]]},"Fetch Result":{"main":[[{"node":"Success","type":"main","index":0}]]},"Fetch Status":{"main":[[{"node":"Is Ready?","type":"main","index":0}]]},"Submit Request":{"main":[[{"node":"Fetch Status","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"NSFW Filter","type":"ai_languageModel","index":0}]]}}}


name: Clone Viral TikToks with AI Avatars & Auto-Post to 9 Platforms using Perplexity & Blotato
author_name: Dr. Firas
author_username: drfiras
categories: []
created_at: 2025-05-16T15:33:36.828Z
updated_at: 2025-05-16T15:33:36.828Z
url: https://n8n.io/workflows/4110
scraped_at: 2025-06-19 22:48:37
description:
  Clone a viral TikTok with AI and auto-post it to 9 platforms using Perplexity & Blotato

  Who is this for?

  This workflow is perfect for:
  Content creators looking to repurpose viral content
  Social media managers who want to scale short-form content across multiple platforms
  Entrepreneurs and marketers aiming to save time and boost visibility with AI-powered automation

  What problem is this workflow solving?

  Reproducing viral video formats with your own branding and pushing them to multiple platforms is time-consuming and hard to scale. This workflow solves that by:
  Cloning a viral TikTok video’s structure
  Generating a new version with your avatar
  Rewriting the script, caption, and overlay text
  Auto-posting it to 9 social media platforms — without manual uploads

  What this workflow does

  From a simple Telegram message with a TikTok link, the workflow:

  Downloads a TikTok video and extracts its thumbnail, audio, and caption
  Transcribes the audio and saves original text into Google Sheets
  Uses Perplexity AI to suggest a new content idea in the same niche
  Rewrites the script, caption, and overlay using GPT-4o
  Generates a new video with your avatar using Captions.ai
  Adds subtitles and overlay text with JSON2Video
  Saves metadata to Google Sheets for tracking
  Sends the final video to Telegram for preview
  Auto-publishes the video to Instagram, YouTube, TikTok, Facebook, LinkedIn, Threads, X (Twitter), Pinterest, and Bluesky via Blotato

  Setup

  Connect your Telegram bot to the trigger node.
  Add your OpenAI, Perplexity, Cloudinary, Captions.ai, and Blotato API keys.
  Make sure your Google Sheet is ready with the appropriate columns.
  Replace the default avatar name in the Captions.ai node with yours.
  Fill in your social media account IDs in the "Assign Platform IDs" node.
  Test by sending a TikTok URL to your Telegram bot.

  How to customize this workflow to your needs

  Change avatar output style**: adjust resolution, voice, or avatar ID.
  Refine script structure**: tweak GPT instructions for different tone/format.
  Swap Perplexity with ChatGPT or Claude** if needed.
  Filter by platform**: disable any Blotato nodes you don’t need.
  Add approval step**: insert a Telegram confirmation node before publishing.
  Adjust subtitle style or overlay text font** in JSON2Video.

  📄 Documentation: Notion Guide

  Need help customizing?
  Contact me for consulting and support : Linkedin / Youtube

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

workflow_json:
  {"id":"21dF4yje1iQpP4jQ","meta":{"instanceId":"a2b23892dd6989fda7c1209b381f5850373a7d2b85609624d7c2b7a092671d44","templateCredsSetupCompleted":true},"name":"💥Clone a viral TikTok and auto-post it to 9 platforms using Perplexity & Blotato vide","tags":[],"nodes":[{"id":"8ad59e84-639c-4a44-afdc-611d15f32d7f","name":"Assign Social Media IDs","type":"n8n-nodes-base.set","position":[-80,920],"parameters":{"mode":"raw","options":{},"jsonOutput":"{\n  \"instagram_id\": \"0000\",\n  \"youtube_id\": \"0000\",\n  \"threads_id\": \"0000\",\n  \"tiktok_id\": \"0000\",\n  \"facebook_id\": \"0000\",\n  \"facebook_page_id\": \"000000000000\",\n  \"twitter_id\": \"0000\",\n  \"linkedin_id\": \"0000\",\n  \"pinterest_id\": \"0000\",\n  \"pinterest_board_id\": \"00000000000000000000\",\n  \"bluesky_id\": \"0000\"\n}\n"},"typeVersion":3.4},{"id":"2e243d6a-81ef-487f-8852-bd48cfaf5ad8","name":"Upload Video to Blotato","type":"n8n-nodes-base.httpRequest","position":[140,920],"parameters":{"url":"https://backend.blotato.com/v2/media","method":"POST","options":{},"sendBody":true,"sendHeaders":true,"bodyParameters":{"parameters":[{"name":"url","value":"={{ $('Update Final Video URL in Sheet').item.json['URL de la vidéo'] }}"}]},"headerParameters":{"parameters":[{"name":"blotato-api-key","value":"YOUR_API_KEY"}]}},"typeVersion":4.2},{"id":"f84ff66b-9270-494f-80e7-29ad2fd51b4d","name":"INSTAGRAM","type":"n8n-nodes-base.httpRequest","position":[420,680],"parameters":{"url":"https://backend.blotato.com/v2/posts","method":"POST","options":{},"jsonBody":"={\n  \"post\": {\n    \"accountId\": \"{{ $('Assign Social Media IDs').item.json.instagram_id }}\",\n    \"target\": {\n      \"targetType\": \"instagram\"\n    },\n    \"content\": {\n      \"text\": \"{{ $('Save Rewritten Video to Google Sheets').item.json.Caption }}\",\n      \"platform\": \"instagram\",\n      \"mediaUrls\": [\n        \"{{ $json.url }}\"\n      ]\n    }\n  }\n}\n\n","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"blotato-api-key","value":"=YOUR_API_KEY"}]}},"typeVersion":4.2},{"id":"3776e592-07be-47e2-89a8-f8d338f0c25e","name":"YOUTUBE","type":"n8n-nodes-base.httpRequest","position":[640,680],"parameters":{"url":"https://backend.blotato.com/v2/posts","method":"POST","options":{},"jsonBody":"={\n  \"post\": {\n    \"accountId\": \"{{ $('Assign Social Media IDs').item.json.youtube_id }}\",\n    \"target\": {\n      \"targetType\": \"youtube\",\n      \"title\": \"{{ $('Save Rewritten Video to Google Sheets').item.json['Texte superposé'] }}\",\n      \"privacyStatus\": \"unlisted\",\n      \"shouldNotifySubscribers\": \"false\"\n    },\n    \"content\": {\n      \"text\": \"{{ $('Save Rewritten Video to Google Sheets').item.json.Caption }}\",\n      \"platform\": \"youtube\",\n      \"mediaUrls\": [\n        \"{{ $json.url }}\"\n      ]\n    }\n  }\n}\n","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"blotato-api-key","value":"YOUR_API_KEY"}]}},"typeVersion":4.2},{"id":"c590765f-deb4-4221-ada7-37c700656ff1","name":"TIKTOK","type":"n8n-nodes-base.httpRequest","position":[840,680],"parameters":{"url":"https://backend.blotato.com/v2/posts","method":"POST","options":{},"jsonBody":"={\n  \"post\": {\n    \"accountId\": \"{{ $('Assign Social Media IDs').item.json.tiktok_id }}\",\n    \"target\": {\n      \"targetType\": \"tiktok\",\n      \"isYourBrand\": \"false\", \n      \"disabledDuet\": \"false\",\n      \"privacyLevel\": \"PUBLIC_TO_EVERYONE\",\n      \"isAiGenerated\": \"true\",\n      \"disabledStitch\": \"false\",\n      \"disabledComments\": \"false\",\n      \"isBrandedContent\": \"false\"\n      \n    },\n    \"content\": {\n      \"text\": \"{{ $('Save Rewritten Video to Google Sheets').item.json.Caption }}\",\n      \"platform\": \"tiktok\",\n      \"mediaUrls\": [\n        \"{{ $json.url }}\"\n      ]\n    }\n  }\n}\n","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"blotato-api-key","value":"YOUR_API_KEY"}]}},"typeVersion":4.2},{"id":"9a9dc42a-20b6-427d-a7d9-08f4ab924e9e","name":"FACEBOOK","type":"n8n-nodes-base.httpRequest","position":[420,920],"parameters":{"url":"https://backend.blotato.com/v2/posts","method":"POST","options":{},"jsonBody":"={\n  \"post\": {\n    \"accountId\": \"{{ $('Assign Social Media IDs').item.json.facebook_id }}\",\n    \"target\": {\n      \"targetType\": \"facebook\",\n      \"pageId\": \"{{ $('Assign Social Media IDs').item.json.facebook_page_id }}\"\n\n      \n    },\n    \"content\": {\n      \"text\": \"{{ $('Save Rewritten Video to Google Sheets').item.json.Caption }}\",\n      \"platform\": \"facebook\",\n      \"mediaUrls\": [\n        \"{{ $json.url }}\"\n      ]\n    }\n  }\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"blotato-api-key","value":"YOUR_API_KEY"}]}},"typeVersion":4.2},{"id":"987a372a-d27e-4a3e-a8b7-b2085463c05a","name":"THREADS","type":"n8n-nodes-base.httpRequest","position":[640,920],"parameters":{"url":"https://backend.blotato.com/v2/posts","method":"POST","options":{},"jsonBody":"={\n  \"post\": {\n    \"accountId\": \"{{ $('Assign Social Media IDs').item.json.threads_id }}\",\n    \"target\": {\n      \"targetType\": \"threads\"\n      \n    },\n    \"content\": {\n      \"text\": \"{{ $('Save Rewritten Video to Google Sheets').item.json.Caption }}\",\n      \"platform\": \"threads\",\n      \"mediaUrls\": [\n        \"{{ $json.url }}\"\n      ]\n    }\n  }\n}\n","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"blotato-api-key","value":"YOUR_API_KEY"}]}},"typeVersion":4.2},{"id":"e9d66412-e27d-47f0-9d17-5ec36fe81859","name":"TWETTER","type":"n8n-nodes-base.httpRequest","position":[840,920],"parameters":{"url":"https://backend.blotato.com/v2/posts","method":"POST","options":{},"jsonBody":"={\n  \"post\": {\n    \"accountId\": \"{{ $('Assign Social Media IDs').item.json.twitter_id }}\",\n    \"target\": {\n      \"targetType\": \"twitter\"\n      \n    },\n    \"content\": {\n      \"text\": \"{{ $('Save Rewritten Video to Google Sheets').item.json.Caption }}\",\n      \"platform\": \"twitter\",\n      \"mediaUrls\": [\n        \"{{ $json.url }}\"\n      ]\n    }\n  }\n}\n","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"blotato-api-key","value":"=YOUR_API_KEY"}]}},"typeVersion":4.2},{"id":"9e7e0fa8-3f0e-4111-9d78-96123ccec1c8","name":"LINKEDIN","type":"n8n-nodes-base.httpRequest","position":[420,1160],"parameters":{"url":"https://backend.blotato.com/v2/posts","method":"POST","options":{},"jsonBody":"={\n  \"post\": {\n    \"accountId\": \"{{ $('Assign Social Media IDs').item.json.linkedin_id }}\",\n    \"target\": {\n      \"targetType\": \"linkedin\"\n      \n    },\n    \"content\": {\n      \"text\": \"{{ $('Save Rewritten Video to Google Sheets').item.json.Caption }}\",\n      \"platform\": \"linkedin\",\n      \"mediaUrls\": [\n        \"{{ $json.url }}\"\n      ]\n    }\n  }\n}\n","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"blotato-api-key","value":"YOUR_API_KEY"}]}},"typeVersion":4.2},{"id":"3368ee92-d40f-482d-8174-53bfd188d2c8","name":"BLUESKY","type":"n8n-nodes-base.httpRequest","position":[640,1160],"parameters":{"url":"https://backend.blotato.com/v2/posts","method":"POST","options":{},"jsonBody":"= {\n  \"post\": {\n    \"accountId\": \"{{ $('Assign Social Media IDs').item.json.bluesky_id }}\",\n    \"target\": {\n      \"targetType\": \"bluesky\"\n      \n    },\n    \"content\": {\n      \"text\": \"{{ $('Save Rewritten Video to Google Sheets').item.json.Caption }}\",\n      \"platform\": \"bluesky\",\n      \"mediaUrls\": [\n        \"https://pbs.twimg.com/media/GE8MgIiWEAAfsK3.jpg\"\n      ]\n    }\n  }\n}\n","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"blotato-api-key","value":"YOUR_API_KEY"}]}},"typeVersion":4.2},{"id":"fea89732-09cc-420d-b2e0-f0f4160d27cb","name":"PINTEREST","type":"n8n-nodes-base.httpRequest","position":[840,1160],"parameters":{"url":"https://backend.blotato.com/v2/posts","method":"POST","options":{},"jsonBody":"={\n  \"post\": {\n    \"accountId\": \"{{ $('Assign Social Media IDs').item.json.pinterest_id }}\",\n    \"target\": {\n      \"targetType\": \"pinterest\",\n      \"boardId\": \"{{ $('Assign Social Media IDs').item.json.pinterest_board_id }}\"      \n    },\n    \"content\": {\n      \"text\": \"{{ $('Save Rewritten Video to Google Sheets').item.json.Caption }}\",\n      \"platform\": \"pinterest\",\n      \"mediaUrls\": [\n        \"https://pbs.twimg.com/media/GE8MgIiWEAAfsK3.jpg\"\n      ]\n    }\n  }\n}\n\n","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"blotato-api-key","value":"YOUR_API_KEY"}]}},"typeVersion":4.2},{"id":"d1400430-0340-4194-b5eb-bd3ae150d577","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-740,-380],"parameters":{"width":2460,"height":300,"content":"# 🟫 STEP 1 — Clone a viral TikTok video"},"typeVersion":1},{"id":"91bf1e19-3e2c-44b3-a7d0-8bea3f80eb04","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-740,-20],"parameters":{"color":4,"width":1920,"height":320,"content":"# 🟦 STEP 2 — Suggest new content idea\n"},"typeVersion":1},{"id":"a831f320-0b5f-4853-8b9c-0ddeaaf84083","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-740,340],"parameters":{"width":1920,"height":300,"content":"# 🟪 STEP 3 — Create the new video with your avatar\n\n"},"typeVersion":1},{"id":"3bb22fc4-b5b4-4323-9039-5b6cf0458084","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-740,660],"parameters":{"color":3,"width":1920,"height":680,"content":"# 🟥 STEP 4 — Publish to 9 platforms\n"},"typeVersion":1},{"id":"6ad81fc8-d79d-44d1-bf17-cdea14e915d1","name":"Trigger: Get TikTok URL via Telegram","type":"n8n-nodes-base.telegramTrigger","position":[-620,-280],"webhookId":"9a749f58-0f17-45ef-80a9-0e8d17bde5b5","parameters":{"updates":["message"],"additionalFields":{}},"credentials":{"telegramApi":{"id":"fO6eyZMLBk66Au44","name":"Telegram account 5"}},"typeVersion":1.1},{"id":"4047a3b1-1fb9-40da-b127-f2e7432a649e","name":"Download TikTok Video (RapidAPI)","type":"n8n-nodes-base.httpRequest","position":[-400,-280],"parameters":{"url":"=https://tiktok-download-video1.p.rapidapi.com/getVideo?url={{ $json.message.text }}","options":{},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"x-rapidapi-host","value":"tiktok-download-video1.p.rapidapi.com"},{"name":"x-rapidapi-key","value":"YOUR_API_KEY"}]}},"typeVersion":4.2},{"id":"6ec78da8-f197-42c0-b631-055bd7bf1eef","name":"Extract Video Thumbnail","type":"n8n-nodes-base.httpRequest","position":[-180,-280],"parameters":{"url":"={{ $json.data.origin_cover }}","options":{}},"typeVersion":4.2},{"id":"f17f39cd-d9f4-4b1b-85de-ade8a5492542","name":"Upload Thumbnail to Cloudinary","type":"n8n-nodes-base.httpRequest","position":[40,-280],"parameters":{"url":"https://api.cloudinary.com/v1_1/YOUR_ID/image/upload","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","authentication":"genericCredentialType","bodyParameters":{"parameters":[{"name":"file","parameterType":"formBinaryData","inputDataFieldName":"data"},{"name":"upload_preset","value":"n8n_clone"}]},"genericAuthType":"httpBasicAuth"},"credentials":{"httpBasicAuth":{"id":"K1UGehJnDI8N25UA","name":"Unnamed credential"}},"typeVersion":4.2},{"id":"160a5960-1312-4c5f-b066-f1ecc30202e6","name":"Analyze Thumbnail (GPT-4o Vision)","type":"@n8n/n8n-nodes-langchain.openAi","position":[260,-280],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4o","cachedResultName":"GPT-4O"},"options":{},"resource":"image","imageUrls":"={{ $json.url }}","operation":"analyze"},"credentials":{"openAiApi":{"id":"6h3DfVhNPw9I25nO","name":"OpenAi account"}},"typeVersion":1.8},{"id":"14a42907-4bc7-4c4a-9ced-a2a23bb88343","name":"Extract Overlay Text (GPT-4o)","type":"@n8n/n8n-nodes-langchain.openAi","position":[480,-280],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4o","cachedResultName":"GPT-4O"},"options":{},"messages":{"values":[{"content":"=Identify the primary text located at the top of the image described above:\n{{ $json.content }}\n\nReturn only that specific top text as the output.\n\nDo not include any quotation marks.\n\nFocus only on the top section's text in the image and disregard any other content."}]}},"credentials":{"openAiApi":{"id":"6h3DfVhNPw9I25nO","name":"OpenAi account"}},"typeVersion":1.8},{"id":"2c183a03-3bb5-45b8-8bc9-5981f0bc30b5","name":"Download TikTok Audio","type":"n8n-nodes-base.httpRequest","position":[840,-280],"parameters":{"url":"={{ $('Download TikTok Video (RapidAPI)').item.json.data.music }}","options":{}},"typeVersion":4.2},{"id":"c6614b8c-6415-4094-a800-302ae8711d14","name":"Transcribe Audio to Script (GPT)","type":"@n8n/n8n-nodes-langchain.openAi","position":[1060,-280],"parameters":{"options":{},"resource":"audio","operation":"transcribe"},"credentials":{"openAiApi":{"id":"6h3DfVhNPw9I25nO","name":"OpenAi account"}},"typeVersion":1.8},{"id":"02ddecfe-5a85-4247-9a33-fc95c42775a0","name":"Generate Unique Template ID","type":"n8n-nodes-base.code","position":[1280,-280],"parameters":{"jsCode":"// Utility to create a random alphanumeric ID\nfunction createUniqueId(length = 12) {\n  const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n  let id = '';\n  for (let i = 0; i < length; i++) {\n    const randomIndex = Math.floor(Math.random() * characters.length);\n    id += characters[randomIndex];\n  }\n  return id;\n}\n\n// Return the ID in the expected output structure\nreturn [\n  {\n    json: {\n      code: createUniqueId()\n    }\n  }\n];"},"typeVersion":2},{"id":"e7e17a73-c75d-413d-842b-aecd0da25eb7","name":"Save Original Video to Google Sheets","type":"n8n-nodes-base.googleSheets","position":[1500,-280],"parameters":{"columns":{"value":{"Caption":"={{ $('Download TikTok Video (RapidAPI)').item.json.data.title }}","ID du modèle":"={{ $json.code }}","Lien de la vidéo":"={{ $('Trigger: Get TikTok URL via Telegram').item.json.message.text }}","Modèle de script vidéo":"={{ $('Transcribe Audio to Script (GPT)').item.json.text }}","Modèle de texte superposé":"={{ $('Download TikTok Audio').item.json.message.content }}"},"schema":[{"id":"ID du modèle","type":"string","display":true,"required":false,"displayName":"ID du modèle","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Lien de la vidéo","type":"string","display":true,"required":false,"displayName":"Lien de la vidéo","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Modèle de texte superposé","type":"string","display":true,"required":false,"displayName":"Modèle de texte superposé","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Modèle de script vidéo","type":"string","display":true,"required":false,"displayName":"Modèle de script vidéo","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Caption","type":"string","display":true,"required":false,"displayName":"Caption","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/1SoYJvZbVNn4L1FNfk9eFqx_vGlCsMxgw8bx0DVFgBLY/edit#gid=0","cachedResultName":"Template"},"documentId":{"__rl":true,"mode":"id","value":"="}},"credentials":{"googleSheetsOAuth2Api":{"id":"51us92xkOlrvArhV","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"e6647507-595e-4f13-9c06-818f90b7759a","name":"Suggest Similar Idea (Perplexity)","type":"n8n-nodes-base.httpRequest","position":[-620,60],"parameters":{"url":"https://api.perplexity.ai/chat/completions","method":"POST","options":{},"jsonBody":"={\n  \"model\": \"sonar-reasoning\",\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"Suggest a content idea different from this video script: \\\"{{ $json['Modèle de script vidéo'] }}\\\". It should be in the same niche and on the exact same topic or content idea but offer fresh value. You must pick one idea from your research that matches the topic idea of the video script exactly but is also different and unique from it so it would stand out on social media. Example: if the video script contains a list of tools, your topic must also be a list of tools in that video script topic but slightly different, maybe different tools etc. If the video's script is about a plan, strategies, or whatever, you must also make your topic about that. So you must maintain the nature of the topic in the video script. You absolutely must be specific as the original video script. You can't just mention generic tools or strategies if the original video script contains specific tools. Etc. That is the level of accuracy and perfect matching of the video script original topic. Make sure it appeals to a broad audience like the example.\"\n    }\n  ]\n}\n","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_API_KEY"},{"name":"Content-Type","value":"application/json"}]}},"typeVersion":4.2},{"id":"a6c047ca-824e-4e33-895f-3be02e509fc6","name":"Clean Perplexity Response","type":"n8n-nodes-base.code","position":[-380,60],"parameters":{"jsCode":"// Step 1: Pull raw input\nlet raw = $input.first().json.choices[0].message.content;\n// Step 2: Forcefully remove anything between <think> and </think>\nlet cleaned = raw.replace(/<think>(.|\\n)*?<\\/think>/gi,\n'').trim();\n// Optional cleanup: remove leading/trailing blank lines\ncleaned = cleaned.replace(/^\\s+|\\s+$/g, '');\n// Done\nreturn [\n{\njson: {\ncleanedResponse: cleaned\n}\n}\n];\n"},"typeVersion":2},{"id":"3b5e242f-b10c-4c8e-be2a-acbc95a92658","name":"Rewrite Script, Caption, Overlay (GPT-4o)","type":"@n8n/n8n-nodes-langchain.openAi","position":[-60,60],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4o","cachedResultName":"GPT-4O"},"options":{},"messages":{"values":[{"content":"=You are rewriting a TikTok video script, caption, and overlay —\nnot inventing a new one. You must follow this format and obey\nthese rules strictly.\n---\n### CONTEXT:\nHere is the content idea to use:\n{{ $json.cleanedResponse }}\n\n---\n### STEP 1: Rewrite the original video script BELOW using the new\ntopic/context above but maintaiin as stubbornly as possible the\noriginal script structure and style:\nOriginal script: {{ $('Save Original Video to Google Sheets').item.json['Modèle de script vidéo'] }}\n\n\n🛑 DO NOT CHANGE the original structure or style but\nThis includes:\n- Numbered list\n- Sentence breaks\n- \"I\" or first-person narration\n- Colloquial/informal tone (like “you're gonna wanna...”)\n✂️ You MUST keep:\n- first person narration of the orignal script at all costs\n- MUST be under 700 characters (yes \"Characters\" not wordcount)\nthis is an absolute MUST, no more than 700 characters!!! But never\nchange the structure or narration style of the original script. It\nmust be an exact imitation.\n✏️ You MAY change:\n- Tool names\n- Use cases\n- Descriptions\n- Niche-specific keywords\n\n#Rule: never use any characers like \"\" in your generated video\nscript as this will yeild syntax errors.\n---\n### STEP 2: Rewrite the caption text using the new topic.\nKeep:\n- Same structure and tone\n- Same use of #hashtags but space between each hashtag\n- Similar sentence count and layout\nCaption:\n{{ $('Save Original Video to Google Sheets').item.json.Caption }}\n\n---\n### STEP 3: Rewrite the text overlay (short version for the\nthumbnail or first screen)\nKeep:\n- EXACT Same length format, case, structure\n- Do NOT invent new words unless absolutely necessary\nOverlay:\n{{ $('Save Original Video to Google Sheets').item.json['Modèle de texte superposé'] }}\n---\n### FINAL OUTPUT FORMAT (no markdown formatting):\nText Overlay: [REWRITTEN TEXT OVERLAY]\nVideo Script: [REWRITTEN SCRIPT]\nCaption Text: [REWRITTEN CAPTION TEXT]\nDO NOT return any explanations. Only return the rewritten\nsections."}]}},"credentials":{"openAiApi":{"id":"6h3DfVhNPw9I25nO","name":"OpenAi account"}},"typeVersion":1.8},{"id":"befec852-bca2-4c54-9c2c-49a8c082e2b4","name":"Split Rewritten Content into Sections","type":"n8n-nodes-base.code","position":[420,60],"parameters":{"jsCode":"// Récupère le contenu du premier item\nconst input = $input.first().json.message.content;\n\n// On tolère les retours à la ligne réels (\\n) ou échappés (\\\\n)\n\n// Text Overlay\nconst textOverlayMatch = input.match(\n  /Text\\s*Overlay:\\s*(.+?)(?:\\r?\\n|\\\\n)/s\n);\n\n// Video Script\nconst videoScriptMatch = input.match(\n  /Video\\s*Script:\\s*(.+?)(?:\\r?\\n|\\\\n)Caption\\s*Text:/s\n);\n\n// Caption Text (jusqu'à la fin)\nconst captionTextMatch = input.match(\n  /Caption\\s*Text:\\s*(.+)/s\n);\n\nreturn [\n  {\n    json: {\n      textOverlay:   textOverlayMatch   ? textOverlayMatch[1].trim()   : null,\n      videoScript:   videoScriptMatch   ? videoScriptMatch[1].trim()   : null,\n      captionText:   captionTextMatch   ? captionTextMatch[1].trim()   : null,\n    }\n  }\n];\n"},"typeVersion":2},{"id":"49828685-cf54-45ac-96d9-03697215f80e","name":"Generate New Video ID","type":"n8n-nodes-base.code","position":[640,60],"parameters":{"jsCode":"// Utility to create a random alphanumeric ID\nfunction createUniqueId(length = 12) {\n  const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n  let id = '';\n  for (let i = 0; i < length; i++) {\n    const randomIndex = Math.floor(Math.random() * characters.length);\n    id += characters[randomIndex];\n  }\n  return id;\n}\n\n// Return the ID in the expected output structure\nreturn [\n  {\n    json: {\n      code: createUniqueId()\n    }\n  }\n];"},"typeVersion":2},{"id":"c9f02616-a944-471b-9c4d-7fa381d684b9","name":"Save Rewritten Video to Google Sheets","type":"n8n-nodes-base.googleSheets","position":[820,60],"parameters":{"columns":{"value":{"Sujet":"={{ $('Clean Perplexity Response').first().json.cleanedResponse }}","Script":"={{ $('Split Rewritten Content into Sections').item.json.videoScript }}","Caption":"={{ $('Split Rewritten Content into Sections').item.json.captionText }}","ID du modèle":"={{ $('Generate Unique Template ID').first().json.code }}","ID de la vidéo":"={{ $json.code }}","Texte superposé":"={{ $('Split Rewritten Content into Sections').item.json.textOverlay }}"},"schema":[{"id":"ID du modèle","type":"string","display":true,"required":false,"displayName":"ID du modèle","defaultMatch":false,"canBeUsedToMatch":true},{"id":"ID de la vidéo","type":"string","display":true,"removed":false,"required":false,"displayName":"ID de la vidéo","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Sujet","type":"string","display":true,"removed":false,"required":false,"displayName":"Sujet","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Texte superposé","type":"string","display":true,"removed":false,"required":false,"displayName":"Texte superposé","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Script","type":"string","display":true,"removed":false,"required":false,"displayName":"Script","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Caption","type":"string","display":true,"required":false,"displayName":"Caption","defaultMatch":false,"canBeUsedToMatch":true},{"id":"URL de la vidéo","type":"string","display":true,"removed":true,"required":false,"displayName":"URL de la vidéo","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Date de publication","type":"string","display":true,"removed":true,"required":false,"displayName":"Date de publication","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Statut","type":"string","display":true,"removed":true,"required":false,"displayName":"Statut","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"id","value":"=52679157"},"documentId":{"__rl":true,"mode":"id","value":"="}},"credentials":{"googleSheetsOAuth2Api":{"id":"51us92xkOlrvArhV","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"dbd21507-ecdf-49c7-b449-e4a6f9fcca86","name":"Fetch Available Avatars","type":"n8n-nodes-base.httpRequest","position":[-620,440],"parameters":{"url":"https://api.captions.ai/api/creator/list","method":"POST","options":{},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json"},{"name":"x-api-key","value":"YOUR_API_KEY"}]}},"typeVersion":4.2},{"id":"988a3283-a57d-4c81-b582-bb59e715208b","name":"Generate Video with Avatar","type":"n8n-nodes-base.httpRequest","position":[-380,440],"parameters":{"url":"https://api.captions.ai/api/creator/submit","method":"POST","options":{},"jsonBody":"={\n\"script\": \"{{ $('Save Rewritten Video to Google Sheets').item.json.Script }}\",\n\"creatorName\": \"{{ $json.supportedCreators[0] }}\",\n\"resolution\": \"fhd\"\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json"},{"name":"x-api-key","value":"YOUR_API_KEY"}]}},"typeVersion":4.2},{"id":"99f95617-c27e-4952-9da6-93bb818d374c","name":"Wait for Avatar Rendering (3 min)","type":"n8n-nodes-base.wait","position":[-180,440],"webhookId":"779e4676-d28f-4be9-9118-c90c688e805a","parameters":{"unit":"minutes","amount":3},"typeVersion":1.1},{"id":"78dd3c62-a184-4ec0-9153-002a0ac3209f","name":"Fetch Avatar Video URL","type":"n8n-nodes-base.httpRequest","position":[20,440],"parameters":{"url":"https://api.captions.ai/api/creator/poll","method":"POST","options":{},"jsonBody":"={\n \"operationId\": \"{{ $json[\"operationId\"] }}\"\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json"},{"name":"x-api-key","value":"YOUR_API_KEY"}]}},"typeVersion":4.2},{"id":"8c6af2a2-c052-40b3-825a-463d7c17b060","name":"Add Overlay Text with JSON2Video","type":"n8n-nodes-base.httpRequest","position":[220,440],"parameters":{"url":"https://api.json2video.com/v2/movies","method":"POST","options":{},"jsonBody":"=\n{\n\"id\": \"qbaasr7s\",\n\"resolution\": \"instagram-story\",\n\"quality\": \"high\",\n\"scenes\": [\n{\n\"id\": \"qyjh9lwj\",\n\"comment\": \"Scene 1\",\n\"elements\": []\n}\n],\n\"elements\": [\n{\n\"id\": \"q6dznzcv\",\n\"type\": \"video\",\n\"src\": \"{{ $json.url }}\",\n\"resize\": \"cover\"\n},\n{\n\"id\": \"top-text\",\n\"type\": \"text\",\n\"text\": \"{{ $('Save Rewritten Video to Google Sheets').item.json['Texte superposé'] }}\",\n\"settings\": {\n\"font-family\": \"Arial\",\n\"font-size\": \"60px\",\n\"color\": \"#000000\",\n\"background-color\": \"#FFFFFF\",\n\"horizontal-position\": \"center\",\n\"vertical-position\": \"top\",\n\"margin-top\": \"100px\",\n\"word-break\": \"break-word\",\n\"overflow-wrap\": \"break-word\",\n\"font-weight\": \"bold\",\n\"text-align\": \"center\",\n\"width\": \"80%\",\n\"padding\": \"0px\",\n\"line-height\": \"1.2\",\n\"margin\": \"50px 0 0 0\",\n\"padding\": \"0 10px 0 10px\",\n\"border-radius\": \"15px\"\n}\n},\n{\n\"id\": \"q41n9kxp\",\n\"type\": \"subtitles\",\n\"settings\": {\n\"style\": \"classic\",\n\"position\": \"bottom\",\n\"font-family\": \"Arial\",\n\"font-size\": \"100px\",\n\"word-color\": \"#ffd700\",\n\"shadow-color\": \"#260B1B\",\n\"line-color\": \"#F1E7F4\",\n\"shadow-offset\": 0,\n\"box-color\": \"#260B1B\",\n\"outline-color\": \"#000000\",\n\"outline-width\": 8\n},\n\"language\": \"en\"\n}\n]\n}","sendBody":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpCustomAuth"},"credentials":{"httpCustomAuth":{"id":"GELGbE2ThQ80HY5A","name":"Custom Auth account"}},"typeVersion":4.2},{"id":"cf55a393-1e63-46f7-b57c-07508141554f","name":"Wait for Caption Rendering","type":"n8n-nodes-base.wait","position":[420,440],"webhookId":"67093c5d-34fa-44e8-9dfd-e25ca5f99ac2","parameters":{"unit":"minutes","amount":2},"typeVersion":1.1},{"id":"4a939455-0c36-49cc-9279-36f2cd8ebcec","name":"Fetch Final Video from JSON2Video","type":"n8n-nodes-base.httpRequest","position":[620,440],"parameters":{"url":"=https://api.json2video.com/v2/movies?id={{ $json.project }}","options":{},"authentication":"genericCredentialType","genericAuthType":"httpCustomAuth"},"credentials":{"httpCustomAuth":{"id":"GELGbE2ThQ80HY5A","name":"Custom Auth account"}},"typeVersion":4.2},{"id":"e64423b9-6e5e-4ab8-b9c1-1bb791fcfa06","name":"Update Final Video URL in Sheet","type":"n8n-nodes-base.googleSheets","position":[820,440],"parameters":{"columns":{"value":{"ID de la vidéo":"={{ $('Save Rewritten Video to Google Sheets').item.json['ID de la vidéo'] }}","URL de la vidéo":"={{ $json.movie.url }}"},"schema":[{"id":"ID du modèle","type":"string","display":true,"removed":true,"required":false,"displayName":"ID du modèle","defaultMatch":false,"canBeUsedToMatch":true},{"id":"ID de la vidéo","type":"string","display":true,"removed":false,"required":false,"displayName":"ID de la vidéo","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Sujet","type":"string","display":true,"removed":true,"required":false,"displayName":"Sujet","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Texte superposé","type":"string","display":true,"removed":true,"required":false,"displayName":"Texte superposé","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Script","type":"string","display":true,"removed":true,"required":false,"displayName":"Script","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Caption","type":"string","display":true,"removed":true,"required":false,"displayName":"Caption","defaultMatch":false,"canBeUsedToMatch":true},{"id":"URL de la vidéo","type":"string","display":true,"removed":false,"required":false,"displayName":"URL de la vidéo","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Date de publication","type":"string","display":true,"removed":true,"required":false,"displayName":"Date de publication","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Statut","type":"string","display":true,"removed":true,"required":false,"displayName":"Statut","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["ID de la vidéo"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"appendOrUpdate","sheetName":{"__rl":true,"mode":"list","value":52679157,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/1SoYJvZbVNn4L1FNfk9eFqx_vGlCsMxgw8bx0DVFgBLY/edit#gid=52679157","cachedResultName":"MA VIDEO"},"documentId":{"__rl":true,"mode":"id","value":"="}},"credentials":{"googleSheetsOAuth2Api":{"id":"51us92xkOlrvArhV","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"d72dc835-b954-4dbd-a210-af7fc6ce058e","name":"Send Video URL via Telegram","type":"n8n-nodes-base.telegram","position":[-600,920],"webhookId":"37975672-4633-4c65-a8d8-4d101bff5f84","parameters":{"text":"=Url VIDEO : {{ $json['URL de la vidéo'] }}","chatId":"={{ $('Trigger: Get TikTok URL via Telegram').item.json.message.chat.id }}","additionalFields":{}},"credentials":{"telegramApi":{"id":"fO6eyZMLBk66Au44","name":"Telegram account 5"}},"typeVersion":1.2},{"id":"33552176-18ab-44ec-9bb6-174e9f9c777d","name":"Send Final Video Preview","type":"n8n-nodes-base.telegram","position":[-400,920],"webhookId":"ee91d7ee-1c35-41fa-b8f0-f153b8776369","parameters":{"file":"={{ $('Update Final Video URL in Sheet').item.json['URL de la vidéo'] }}","chatId":"={{ $json.result.chat.id }}","operation":"sendVideo","additionalFields":{}},"credentials":{"telegramApi":{"id":"fO6eyZMLBk66Au44","name":"Telegram account 5"}},"typeVersion":1.2}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"2bb57143-bfe3-49fd-9492-7396d9611cc7","connections":{"Download TikTok Audio":{"main":[[{"node":"Transcribe Audio to Script (GPT)","type":"main","index":0}]]},"Generate New Video ID":{"main":[[{"node":"Save Rewritten Video to Google Sheets","type":"main","index":0}]]},"Fetch Avatar Video URL":{"main":[[{"node":"Add Overlay Text with JSON2Video","type":"main","index":0}]]},"Assign Social Media IDs":{"main":[[{"node":"Upload Video to Blotato","type":"main","index":0}]]},"Extract Video Thumbnail":{"main":[[{"node":"Upload Thumbnail to Cloudinary","type":"main","index":0}]]},"Fetch Available Avatars":{"main":[[{"node":"Generate Video with Avatar","type":"main","index":0}]]},"Upload Video to Blotato":{"main":[[{"node":"INSTAGRAM","type":"main","index":0},{"node":"YOUTUBE","type":"main","index":0},{"node":"TIKTOK","type":"main","index":0},{"node":"FACEBOOK","type":"main","index":0},{"node":"THREADS","type":"main","index":0},{"node":"TWETTER","type":"main","index":0},{"node":"LINKEDIN","type":"main","index":0},{"node":"BLUESKY","type":"main","index":0},{"node":"PINTEREST","type":"main","index":0}]]},"Send Final Video Preview":{"main":[[{"node":"Assign Social Media IDs","type":"main","index":0}]]},"Clean Perplexity Response":{"main":[[{"node":"Rewrite Script, Caption, Overlay (GPT-4o)","type":"main","index":0}]]},"Generate Video with Avatar":{"main":[[{"node":"Wait for Avatar Rendering (3 min)","type":"main","index":0}]]},"Wait for Caption Rendering":{"main":[[{"node":"Fetch Final Video from JSON2Video","type":"main","index":0}]]},"Generate Unique Template ID":{"main":[[{"node":"Save Original Video to Google Sheets","type":"main","index":0}]]},"Send Video URL via Telegram":{"main":[[{"node":"Send Final Video Preview","type":"main","index":0}]]},"Extract Overlay Text (GPT-4o)":{"main":[[{"node":"Download TikTok Audio","type":"main","index":0}]]},"Upload Thumbnail to Cloudinary":{"main":[[{"node":"Analyze Thumbnail (GPT-4o Vision)","type":"main","index":0}]]},"Update Final Video URL in Sheet":{"main":[[{"node":"Send Video URL via Telegram","type":"main","index":0}]]},"Add Overlay Text with JSON2Video":{"main":[[{"node":"Wait for Caption Rendering","type":"main","index":0}]]},"Download TikTok Video (RapidAPI)":{"main":[[{"node":"Extract Video Thumbnail","type":"main","index":0}]]},"Transcribe Audio to Script (GPT)":{"main":[[{"node":"Generate Unique Template ID","type":"main","index":0}]]},"Analyze Thumbnail (GPT-4o Vision)":{"main":[[{"node":"Extract Overlay Text (GPT-4o)","type":"main","index":0}]]},"Fetch Final Video from JSON2Video":{"main":[[{"node":"Update Final Video URL in Sheet","type":"main","index":0}]]},"Suggest Similar Idea (Perplexity)":{"main":[[{"node":"Clean Perplexity Response","type":"main","index":0}]]},"Wait for Avatar Rendering (3 min)":{"main":[[{"node":"Fetch Avatar Video URL","type":"main","index":0}]]},"Save Original Video to Google Sheets":{"main":[[{"node":"Suggest Similar Idea (Perplexity)","type":"main","index":0}]]},"Trigger: Get TikTok URL via Telegram":{"main":[[{"node":"Download TikTok Video (RapidAPI)","type":"main","index":0}]]},"Save Rewritten Video to Google Sheets":{"main":[[{"node":"Fetch Available Avatars","type":"main","index":0}]]},"Split Rewritten Content into Sections":{"main":[[{"node":"Generate New Video ID","type":"main","index":0}]]},"Rewrite Script, Caption, Overlay (GPT-4o)":{"main":[[{"node":"Split Rewritten Content into Sections","type":"main","index":0}]]}}}


name: Analyze Crypto Market with CoinGecko: Volatility Metrics & Investment Signals
author_name: ist00dent
author_username: ist00dent
nodes_used: ["n8n-nodes-base.httpRequest"]
categories: []
created_at: 2025-05-16T17:00:04.497Z
updated_at: 2025-05-16T17:00:04.497Z
url: https://n8n.io/workflows/4115
scraped_at: 2025-06-19 22:49:12
description:
  This n8n template lets you automatically pull market data for the cryptocurrencies from CoinGecko every hour, calculate custom volatility and market-health metrics, classify each coin’s price action into buy/sell/hold/neutral signals with risk ratings, and expose both individual analyses and a portfolio summary via a webhook. It’s perfect for crypto analysts, DeFi builders, or portfolio managers who want on-demand insights without writing a single line of backend code.

  🔧 How it works
  Schedule Trigger fires every hour (or interval you choose).
  HTTP Request (CoinGecko) fetches the top 10 coins by market cap, including 24 h, 7 d, and 30 d price change percentages.
  Split In Batches ensures each coin is processed sequentially.
  Function (Calculate Market Metrics) computes:
    A weighted volatility score
    Market-cap-to-volume ratio
    Price-to-ATH ratio
    Composite market score

  IF & Switch nodes categorize each coin’s 24 h price action (up &gt;5%, down &gt;5%, high volatility, or stable) and append:
    signal (BUY/SELL/HOLD/NEUTRAL)
    riskRating (High/Medium/Low/Unknown)
    recommendation & investmentStrategy guidance

  NoOp & Merge nodes consolidate each branch back into a single data stream.

  Function (Generate Portfolio Summary) aggregates all analyses into:
    A Markdown portfolioSummary
    Counts of buy/sell/hold/neutral signals
    Risk distribution

  Webhook Response returns the full JSON payload with individual analyses and the summary for downstream consumers.

  👤 Who is it for?
  This workflow is ideal for:

  Crypto researchers and analysts who need scheduled market insights

  DeFi and trading bot developers looking to automate signal generation

  Portfolio managers seeking a no-code overview of top assets

  Automation engineers exploring API integration and data enrichment

  📑 Data Structure
  When you trigger the webhook, you’ll receive a JSON object containing:

  individualAnalyses: Array of { coin, symbol, currentPrice, priceChanges, marketMetrics, signal, riskRating, recommendation }

  portfolioSummary: Markdown report summarizing signals, risk distribution, and top opportunity

  marketSignals: Counts of each signal type

  riskDistribution: Counts of each risk rating

  timestamp: ISO string of analysis time

  ⚙️ Setup Instructions
  Import: In n8n Editor → click “Import from JSON” → paste this workflow JSON.

  Configure Schedule: Double-click the Schedule Trigger → set your desired interval (default: every hour).

  Webhook Path: Open the Webhook node → choose a unique path (e.g., /crypto‐analysis) and “POST”.

  Activate: Save and activate the workflow.

  Test:
    Open the webhook url to other tab or use cURL
  curl -X POST https://&lt;your-n8n-host&gt;/webhook/&lt;path&gt;

  You’ll get back a JSON payload with both portfolioSummary and individualAnalyses.

  📝 Tips
  Rate-Limit Handling: If CoinGecko returns 429, insert a Delay node (e.g., 500 ms) after the HTTP Request.
  Batch Size: Default is 1 coin at a time; you can bump it to parallelize.
  Customization: Tweak volatility weightings or add new metrics directly in the “Calculate Market Metrics” Function node.
  Extension: Swap CoinGecko for another API by updating the HTTP Request URL and field mappings.

workflow_json:
  {"id":"Uw1r9yGqgPRykfUs","meta":{"instanceId":"3fed23de697c60307f3b4f5caeafbeffabaf7bbd62c1b20ae70d5faf5a9806b4"},"name":"day9_getting_updated_in_crypto","tags":[{"id":"4zX1mtizlZxTekJP","name":"training-tasks-n8n","createdAt":"2025-04-29T10:41:14.716Z","updatedAt":"2025-04-29T10:41:14.716Z"},{"id":"F1KjxL3SjfvVqZqo","name":"training-n8n","createdAt":"2025-04-29T10:40:13.332Z","updatedAt":"2025-04-29T10:40:13.332Z"}],"nodes":[{"id":"745e4849-8c61-4b29-9980-24de93821adb","name":"Fetch Crypto Data","type":"n8n-nodes-base.httpRequest","position":[220,385],"parameters":{"url":"https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=10&page=1&sparkline=false&price_change_percentage=24h,7d,30d","options":{}},"typeVersion":3},{"id":"f4e6c40d-ab60-473b-9961-961eb1fa3505","name":"Calculate Market Metrics","type":"n8n-nodes-base.function","position":[660,385],"parameters":{"functionCode":"// Calculate a volatility score based on price changes\nconst item = $input.item.json;\n\n// Extract price change percentages\nconst priceChange24h = item.price_change_percentage_24h || 0;\nconst priceChange7d = item.price_change_percentage_7d_in_currency || 0;\nconst priceChange30d = item.price_change_percentage_30d_in_currency || 0;\n\n// Calculate absolute values to measure volatility regardless of direction\nconst absChange24h = Math.abs(priceChange24h);\nconst absChange7d = Math.abs(priceChange7d);\nconst absChange30d = Math.abs(priceChange30d);\n\n// Calculate a weighted volatility score (more weight to recent changes)\nconst volatilityScore = (absChange24h * 0.5) + (absChange7d * 0.3) + (absChange30d * 0.2);\n\n// Calculate market cap to volume ratio (higher means less liquid/more volatile)\nconst marketCapToVolumeRatio = item.market_cap / (item.total_volume || 1);\n\n// Calculate price to ATH ratio (close to 1 means near all-time high)\nconst priceToAthRatio = item.current_price / (item.ath || item.current_price);\n\n// Calculate a composite market score\nconst marketScore = (\n  (volatilityScore * 0.4) + \n  (Math.min(marketCapToVolumeRatio, 10) * 0.3) + \n  ((1 - priceToAthRatio) * 30) // Invert so coins further from ATH get higher scores\n);\n\n// Add calculated metrics to the item\nitem.volatilityScore = parseFloat(volatilityScore.toFixed(2));\nitem.marketCapToVolumeRatio = parseFloat(marketCapToVolumeRatio.toFixed(2));\nitem.priceToAthRatio = parseFloat(priceToAthRatio.toFixed(4));\nitem.marketScore = parseFloat(marketScore.toFixed(2));\n\n// Add a timestamp for the analysis\nitem.analyzedAt = new Date().toISOString();\n\nreturn {json: item};"},"typeVersion":1},{"id":"5d760f94-ca2f-44cc-aef0-83eb2cf438ee","name":"IF 24h Price Up >5%","type":"n8n-nodes-base.if","position":[880,60],"parameters":{"conditions":{"number":[{"value1":"={{ $json.price_change_percentage_24h }}","value2":5,"operation":"larger"}]}},"typeVersion":1},{"id":"19ca8650-b642-4910-ac7c-50b1ceb41ffc","name":"IF 24h Price Down >5%","type":"n8n-nodes-base.if","position":[1100,260],"parameters":{"conditions":{"number":[{"value1":"={{ $json.price_change_percentage_24h }}","value2":-5}]}},"typeVersion":1},{"id":"c5d69bbb-df7e-4089-b0c8-50653cd936f0","name":"IF High Volatility","type":"n8n-nodes-base.if","position":[1320,560],"parameters":{"conditions":{"number":[{"value1":"={{ $json.volatilityScore }}","value2":10,"operation":"larger"}]}},"typeVersion":1},{"id":"77902b9a-2cf8-4b6f-95e9-590b51278c59","name":"Set Uptrend Data","type":"n8n-nodes-base.set","position":[1540,60],"parameters":{"values":{"string":[{"name":"priceAction","value":"Strong upward momentum in the past 24 hours"},{"name":"signal","value":"BUY"},{"name":"recommendation","value":"Consider buying on continued strength above resistance levels. Set stop loss at recent support."},{"name":"investmentStrategy","value":"Momentum strategy with trailing stop loss. Consider dollar-cost averaging to manage volatility risk."}]},"options":{"dotNotation":true}},"typeVersion":2},{"id":"4706270b-3bdc-4806-a302-830a88c9a982","name":"Set Downtrend Data","type":"n8n-nodes-base.set","position":[1540,260],"parameters":{"values":{"string":[{"name":"priceAction","value":"Rapid price decline in the past 24 hours"},{"name":"signal","value":"SELL"},{"name":"recommendation","value":"Consider reducing exposure or implementing hedging strategies. Watch for oversold conditions."},{"name":"investmentStrategy","value":"Capital preservation is priority. Consider re-evaluation after price stabilization."}]},"options":{"dotNotation":true}},"typeVersion":2},{"id":"608729c4-23a5-4c5b-b9a0-d77f12166aa3","name":"Set Volatility Data","type":"n8n-nodes-base.set","position":[1540,460],"parameters":{"values":{"string":[{"name":"priceAction","value":"High volatility with significant price swings"},{"name":"signal","value":"HOLD"},{"name":"recommendation","value":"High volatility indicates market uncertainty. Consider waiting for clearer signals before making major positions."},{"name":"investmentStrategy","value":"Range-trading strategy may be effective. Set both upper and lower limit orders."}]},"options":{"dotNotation":true}},"typeVersion":2},{"id":"f8134b51-4b41-4684-97a9-008e5f0260df","name":"Set Stable Data","type":"n8n-nodes-base.set","position":[1540,660],"parameters":{"values":{"string":[{"name":"priceAction","value":"Relatively stable price action with minimal volatility"},{"name":"signal","value":"NEUTRAL"},{"name":"recommendation","value":"Market is consolidating. Watch for breakout signals in either direction."},{"name":"investmentStrategy","value":"Consider accumulating small positions or implementing a neutral options strategy."}]},"options":{"dotNotation":true}},"typeVersion":2},{"id":"5f43178c-7bb5-405d-a988-b3b0ae0a0405","name":"Merge Results","type":"n8n-nodes-base.noOp","position":[1760,360],"parameters":{},"typeVersion":1},{"id":"e422a9e1-9016-4db9-912b-58be44604eb2","name":"Set High Risk Rating","type":"n8n-nodes-base.set","position":[2200,-40],"parameters":{"values":{"string":[{"name":"riskRating","value":"High Risk"},{"name":"investmentStrategy","value":"={{ $json.investmentStrategy }} Due to high risk profile, use strict position sizing (max 2-5% of portfolio)."}]},"options":{"dotNotation":true}},"typeVersion":2},{"id":"383a55c7-f42f-4a32-b6ba-742049406f67","name":"Set Medium Risk Rating","type":"n8n-nodes-base.set","position":[2200,160],"parameters":{"values":{"string":[{"name":"riskRating","value":"Medium Risk"},{"name":"investmentStrategy","value":"={{ $json.investmentStrategy }} Moderate risk profile suggests balanced position sizing (5-10% of portfolio)."}]},"options":{"dotNotation":true}},"typeVersion":2},{"id":"2f50e6cd-dd62-4fb2-8ee2-28096c758e23","name":"Set Low Risk Rating","type":"n8n-nodes-base.set","position":[2200,460],"parameters":{"values":{"string":[{"name":"riskRating","value":"Low Risk"},{"name":"investmentStrategy","value":"={{ $json.investmentStrategy }} Lower risk profile allows for larger position sizing (10-15% of portfolio)."}]},"options":{"dotNotation":true}},"typeVersion":2},{"id":"5a820de9-11f8-4aa7-8811-afb6153a7b54","name":"Set Default Risk Rating","type":"n8n-nodes-base.set","position":[2200,660],"parameters":{"values":{"string":[{"name":"riskRating","value":"Unknown Risk"},{"name":"investmentStrategy","value":"={{ $json.investmentStrategy }} Risk profile is unclear - use conservative position sizing until more data is available."}]},"options":{"dotNotation":true}},"typeVersion":2},{"id":"9b39eb90-f0c8-44df-9721-ef1d60a8a0fc","name":"Final Merge","type":"n8n-nodes-base.noOp","position":[2420,360],"parameters":{},"typeVersion":1},{"id":"f84bd02a-92d1-49c7-9ba3-36e860a31636","name":"Format Final Analysis","type":"n8n-nodes-base.function","position":[2640,635],"parameters":{"functionCode":"// Create a formatted summary for each coin\nconst item = $input.item.json;\n\n// Format dollar amounts nicely\nconst formatCurrency = (value) => {\n  return new Intl.NumberFormat('en-US', {\n    style: 'currency',\n    currency: 'USD',\n    minimumFractionDigits: 2,\n    maximumFractionDigits: 2\n  }).format(value);\n};\n\n// Format percentages nicely\nconst formatPercent = (value) => {\n  return `${value > 0 ? '+' : ''}${value.toFixed(2)}%`;\n};\n\n// Create a detailed analysis report\nconst analysisReport = {\n  coin: item.name,\n  symbol: item.symbol.toUpperCase(),\n  currentPrice: formatCurrency(item.current_price),\n  marketCap: formatCurrency(item.market_cap),\n  volume24h: formatCurrency(item.total_volume),\n  priceChanges: {\n    \"24h\": formatPercent(item.price_change_percentage_24h),\n    \"7d\": formatPercent(item.price_change_percentage_7d_in_currency),\n    \"30d\": formatPercent(item.price_change_percentage_30d_in_currency)\n  },\n  marketMetrics: {\n    volatilityScore: item.volatilityScore,\n    marketCapToVolumeRatio: item.marketCapToVolumeRatio,\n    priceToAthRatio: item.priceToAthRatio,\n    marketScore: item.marketScore\n  },\n  analysis: {\n    priceAction: item.priceAction,\n    signal: item.signal,\n    riskRating: item.riskRating,\n    recommendation: item.recommendation,\n    investmentStrategy: item.investmentStrategy\n  },\n  timestamp: item.analyzedAt\n};\n\n// Generate a natural language summary\nconst summary = `\n## ${item.name} (${item.symbol.toUpperCase()}) Analysis\n\nCurrent Price: ${formatCurrency(item.current_price)} (${formatPercent(item.price_change_percentage_24h)} 24h)\\n\\n\n\nMarket Signal: **${item.signal}** - *${item.priceAction}*\nRisk Rating: **${item.riskRating}**\\n\\n\n\n**Recommendation:**\n${item.recommendation}\n\n**Investment Strategy:**\n${item.investmentStrategy}\n\n---\n*Analysis based on volatility score of ${item.volatilityScore} and market score of ${item.marketScore}*\n`;\n\n// Return both structured data and a human-readable summary\nreturn {\n  json: {\n    ...item,\n    analysisReport,\n    summary\n  }\n};"},"typeVersion":1},{"id":"911280f8-82cb-42ee-bd8a-6de15c58f188","name":"Collect All Analyses","type":"n8n-nodes-base.noOp","position":[660,-140],"parameters":{},"typeVersion":1},{"id":"a4de8078-7f49-4b22-a11a-a2efabfa16b1","name":"Generate Portfolio Summary","type":"n8n-nodes-base.function","position":[880,-140],"parameters":{"functionCode":"// Create a portfolio summary based on all coin analyses\nconst allCoins = $input.all();\n\n// Extract all analyzed coins\nconst analyzedCoins = allCoins.map(coin => coin.json);\n\n// Count signals by type\nconst signalCounts = {\n  BUY: 0,\n  SELL: 0,\n  HOLD: 0,\n  NEUTRAL: 0\n};\n\n// Count risk ratings\nconst riskCounts = {\n  \"High Risk\": 0,\n  \"Medium Risk\": 0,\n  \"Low Risk\": 0,\n  \"Unknown Risk\": 0\n};\n\n// Calculate portfolio metrics\nanalyzedCoins.forEach(coin => {\n  // Count signals\n  if (coin.signal) {\n    signalCounts[coin.signal] = (signalCounts[coin.signal] || 0) + 1;\n  }\n\n  // Count risk ratings\n  if (coin.riskRating) {\n    riskCounts[coin.riskRating] = (riskCounts[coin.riskRating] || 0) + 1;\n  }\n});\n\n// Sort coins by market score (highest first)\nconst sortedCoins = [...analyzedCoins].sort((a, b) => b.marketScore - a.marketScore);\n\n// Get top recommendation\nconst topOpportunity = sortedCoins[0];\n\n// Generate portfolio summary markdown\nconst portfolioSummary = `# Cryptocurrency Market Analysis\n\n## Market Overview\n**Analyzed Coins:** ${analyzedCoins.length}  \n**Buy Signals:** ${signalCounts.BUY}  \n**Sell Signals:** ${signalCounts.SELL}  \n**Hold Signals:** ${signalCounts.HOLD}  \n**Neutral Signals:** ${signalCounts.NEUTRAL}  \n\n## Risk Distribution\n**High Risk Assets:** ${riskCounts[\"High Risk\"]}  \n**Medium Risk Assets:** ${riskCounts[\"Medium Risk\"]}  \n**Low Risk Assets:** ${riskCounts[\"Low Risk\"]}  \n\n## Top Opportunity  \n${topOpportunity ? `**${topOpportunity.name} (${topOpportunity.symbol.toUpperCase()})**  \n${topOpportunity.summary}` : \"No opportunities found\"}\n\n## Detailed Coin Analyses  \n${sortedCoins.map(coin => `**${coin.name} (${coin.symbol})**  \n${coin.summary}`).join('\\n\\n')}\n\n*Analysis generated on ${new Date().toLocaleString()}*`;\n\nreturn [\n  {\n    json: {\n      portfolioSummary,\n      individualAnalyses: analyzedCoins.map(coin => coin.analysisReport),\n      marketSignals: signalCounts,\n      riskDistribution: riskCounts,\n      timestamp: new Date().toISOString()\n    }\n  }\n];\n"},"typeVersion":1},{"id":"3277b96e-ab2c-4561-a29c-958998f45686","name":"Loop Over Items","type":"n8n-nodes-base.splitInBatches","position":[440,385],"parameters":{"options":{}},"typeVersion":3},{"id":"8256a60a-ddb8-4d72-b443-8fba819815bb","name":"Switch by Market Score","type":"n8n-nodes-base.switch","position":[1980,339],"parameters":{"rules":{"rules":[{"value2":20,"operation":"larger"},{"value2":10,"operation":"larger"},{"operation":"larger"}]},"value1":"={{ $json.marketScore }}","fallbackOutput":3},"typeVersion":1},{"id":"b8cb4f7d-3818-48df-89ea-9db22797375a","name":"Split Out","type":"n8n-nodes-base.splitOut","position":[1100,-140],"parameters":{"options":{},"fieldToSplitOut":"individualAnalyses"},"typeVersion":1},{"id":"936e9ada-4b6b-4cab-90e1-0bea30eaaa0c","name":"Respond to Webhook","type":"n8n-nodes-base.respondToWebhook","position":[1320,-140],"parameters":{"options":{},"respondWith":"allIncomingItems"},"typeVersion":1.1},{"id":"7791cebf-4733-4cf6-8341-96771733b507","name":"Webhook","type":"n8n-nodes-base.webhook","position":[0,380],"webhookId":"31941fd9-9fd5-4fab-a1b9-9c347e26f5c9","parameters":{"path":"31941fd9-9fd5-4fab-a1b9-9c347e26f5c9","options":{},"responseMode":"responseNode"},"typeVersion":2},{"id":"d25b2427-9fc7-4042-92f2-673de5019206","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[2120,-140],"parameters":{"width":260,"height":960,"content":"## Categorize and set the rating of coin"},"typeVersion":1},{"id":"ac3a6503-5ce7-406d-9efb-122928239337","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[680,40],"parameters":{},"typeVersion":1},{"id":"c4e4e17d-bf13-44a2-9a9e-1d22104f1062","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[140,-20],"parameters":{"content":"## This workflow aims to"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"be12f8a1-3c44-4a1c-8f74-d1df269de92c","connections":{"Webhook":{"main":[[{"node":"Fetch Crypto Data","type":"main","index":0}]]},"Split Out":{"main":[[{"node":"Respond to Webhook","type":"main","index":0}]]},"Final Merge":{"main":[[{"node":"Format Final Analysis","type":"main","index":0}]]},"Merge Results":{"main":[[{"node":"Switch by Market Score","type":"main","index":0}]]},"Loop Over Items":{"main":[[{"node":"Collect All Analyses","type":"main","index":0}],[{"node":"Calculate Market Metrics","type":"main","index":0}]]},"Set Stable Data":{"main":[[{"node":"Merge Results","type":"main","index":0}]]},"Set Uptrend Data":{"main":[[{"node":"Merge Results","type":"main","index":0}]]},"Fetch Crypto Data":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"IF High Volatility":{"main":[[{"node":"Set Volatility Data","type":"main","index":0}],[{"node":"Set Stable Data","type":"main","index":0}]]},"Set Downtrend Data":{"main":[[{"node":"Merge Results","type":"main","index":0}]]},"IF 24h Price Up >5%":{"main":[[{"node":"Set Uptrend Data","type":"main","index":0}],[{"node":"IF 24h Price Down >5%","type":"main","index":0}]]},"Set Low Risk Rating":{"main":[[{"node":"Final Merge","type":"main","index":0}]]},"Set Volatility Data":{"main":[[{"node":"Merge Results","type":"main","index":0}]]},"Collect All Analyses":{"main":[[{"node":"Generate Portfolio Summary","type":"main","index":0}]]},"Set High Risk Rating":{"main":[[{"node":"Final Merge","type":"main","index":0}]]},"Format Final Analysis":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"IF 24h Price Down >5%":{"main":[[{"node":"Set Downtrend Data","type":"main","index":0}],[{"node":"IF High Volatility","type":"main","index":0}]]},"Set Medium Risk Rating":{"main":[[{"node":"Final Merge","type":"main","index":0}]]},"Switch by Market Score":{"main":[[{"node":"Set High Risk Rating","type":"main","index":0}],[{"node":"Set Medium Risk Rating","type":"main","index":0}],[{"node":"Set Low Risk Rating","type":"main","index":0}],[{"node":"Set Default Risk Rating","type":"main","index":0}]]},"Set Default Risk Rating":{"main":[[{"node":"Final Merge","type":"main","index":0}]]},"Calculate Market Metrics":{"main":[[{"node":"IF 24h Price Up >5%","type":"main","index":0},{"node":"IF 24h Price Down >5%","type":"main","index":0},{"node":"IF High Volatility","type":"main","index":0}]]},"Generate Portfolio Summary":{"main":[[{"node":"Split Out","type":"main","index":0}]]}}}


name: WhatsApp Expense Tracker with PostgreSQL Database & AI-Powered Reports
author_name: Roshan Ramani
author_username: rawsun007
categories: []
created_at: 2025-05-17T05:57:32.971Z
updated_at: 2025-05-17T05:57:32.971Z
url: https://n8n.io/workflows/4136
scraped_at: 2025-06-19 22:49:22
description:
  Track Personal Finances with WhatsApp and AI Assistant

  Transform your WhatsApp into a powerful personal finance command center. This AI-powered workflow converts natural language messages into structured financial data, automates record-keeping, and delivers instant insights—all within your favorite messaging app.

  Who is this for?

  This template is perfect for:
  Personal finance enthusiasts** who want effortless expense tracking
  Small business owners** managing personal and business expenses  
  Freelancers** tracking income and expenses across projects
  Anyone** who prefers messaging over complex finance apps
  Users seeking privacy** with self-hosted financial data

  What problem is this workflow solving?

  Traditional expense tracking requires switching between apps, manual data entry, and complex spreadsheets. Most people abandon these systems within weeks. This workflow solves the friction by:
  Eliminating app-switching—everything happens in WhatsApp
  Converting natural language to structured data automatically
  Providing instant confirmations and reports
  Requiring zero learning curve or behavior change

  What this workflow does

  Smart Transaction Processing
  Send natural messages like Spent 300 on groceries at Walmart and the AI automatically extracts:
  Date**: Today's date (or specified date)
  Category**: Groceries  
  Type**: Expense/Income/Debt
  Amount**: 300
  Person/Company**: Walmart

  Intelligent Message Classification
  The workflow automatically routes messages to three processing branches:
  Branch 1**: Reports and analytics (show March expenses)
  Branch 2**: Transaction logging (spent 50 on coffee)  
  Branch 3**: General financial chat (how can I save money?)

  Advanced Reporting
  Generate instant reports by messaging:
  today's report → Daily income/expense summary
  March vs April report → Monthly comparisons with percentages
  show groceries spending → Category-specific analysis
  Automatic daily summaries at your preferred time

  Database Integration
  All transactions are stored in PostgreSQL with proper schema:
  CREATE TABLE financial_transactions (
   date DATE NOT NULL,
   category TEXT NOT NULL, 
   type TEXT NOT NULL,
   amount NUMERIC(12,2) NOT NULL,
   person TEXT
  );

  Setup

  Prerequisites

  n8n instance** (self-hosted or n8n.cloud)
  WhatsApp Business Cloud API** credentials
  PostgreSQL database** (version 12+)
  OpenRouter API key** for AI processing

  Quick Setup Steps

  Import the workflow template into your n8n instance
  Configure credentials:
    WhatsApp Business Cloud API (App Token + Phone Number ID)
    PostgreSQL connection details
    OpenRouter API key for AI processing
  Create database table using the provided SQL schema
  Test the connection by sending a sample message
  Customize the scheduled report timing (default: 8 AM daily)

  Verification Checklist

  [ ] WhatsApp webhook receives messages
  [ ] AI correctly parses transaction messages
  [ ] Database insertions work properly
  [ ] Confirmation messages are sent back
  [ ] Reports generate with accurate data

  How to customize this workflow to your needs

  AI Model Configuration

  Default**: Uses OpenRouter with GPT-3.5-turbo for cost efficiency
  Upgrade**: Switch to GPT-4 or Claude for better accuracy
  Local**: Replace with self-hosted Ollama for complete privacy

  Database Options

  PostgreSQL**: Recommended for production use
  Google Sheets**: Alternative for simpler setups (nodes included)
  MySQL/SQLite**: Easily adaptable with minor SQL modifications

  Message Classification

  Customize the classification system:
  0**: Reports (modify SQL queries for different analytics)
  1**: Transactions (adjust parsing rules for your language/currency)
  2**: Chat (customize AI responses for financial advice)

  Reporting Customization

  Scheduled reports**: Change timing, format, and recipients
  Custom periods**: Add quarterly, yearly, or custom date ranges
  Categories**: Modify auto-categorization rules for your spending patterns
  Currency**: Update formatting for your local currency

  Advanced Features

  Multi-user support**: Add user identification for family/team use
  Receipt photos**: Extend workflow to process image receipts via OCR
  Budgets**: Add budget tracking and overspend alerts
  Integrations**: Connect to banks via Plaid or other financial APIs

  Complete Package Included

  When you download this template, you get everything needed for immediate implementation:

  Ready-to-Use n8n Workflow

  Fully configured nodes** with descriptive names explaining each step
  Color-coded sticky notes** throughout the workflow explaining:
   What each branch does (Reports/Transactions/Chat)
   How the AI classification works
   Database connection requirements
   Error handling and troubleshooting tips

  Comprehensive Documentation Bundle

  Quick Start Guide**: Get running in under 10 minutes
  Detailed Setup Guide**: Complete configuration walkthrough with screenshots
  Branch Explanation Guide**: Deep dive into each processing branch:
   Branch 0: Reports & Analytics - SQL queries and formatting
   Branch 1: Transaction Processing - AI parsing and database insertion
   Branch 2: Financial Chat - AI responses and conversation handling

  Built-in Workflow Documentation

  Sticky notes at every major step** explaining the logic
  Node descriptions** that clarify what each component does
  Visual flow indicators** showing message routing paths
  Dependency callouts** highlighting required credentials and connections

  Technical Implementation Details

  Database schema** with complete SQL commands
  API configuration examples** for all external services
  Troubleshooting checklist** for common setup issues
  Performance optimization** recommendations

  Bonus Resources

  Example message templates** to test each workflow branch
  Sample data** for testing reports and analytics
  Customization recipes** for common modifications
  Integration patterns** for extending functionality

  Example Usage

  Log Expenses:

  Spent 1200 on rent this month
  Paid 45 for gas at Shell
  Coffee 5.50 at Starbucks

  Log Income:

  Received 5000 salary from Company ABC
  Freelance payment 800 from Client XYZ

  Generate Reports:

  today's summary
  show this week's expenses
  compare March vs April spending
  how much on food this month?

  Expected Responses:
  ✅ Logged: expense | Rent | ₹1,200.00 | Landlord
  ✅ Logged: income | salary |₹12,000.00|company

  📊 Today's Summary:
  Income: ₹0.00
  Expenses: ₹1,245.50  
  Savings: -₹1,245.50

  📈 March vs April:
  Expenses: ₹15,000 vs ₹12,500 (-16.7%)
  Top categories: Rent, Food, Transport

nodes_used:
  ["n8n-nodes-base.postgres","n8n-nodes-base.whatsApp","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.outputParserStructured","@n8n/n8n-nodes-langchain.toolCalculator","@n8n/n8n-nodes-langchain.toolCode","@n8n/n8n-nodes-langchain.lmChatOpenRouter"]

workflow_json:
  {"id":"cMhDQYcAoghnCPCK","meta":{"instanceId":"cbc68f6c587084f6fe53914a07ed22d475640cb7a6f4ade193e6f0c6d7a06ce8","templateCredsSetupCompleted":true},"name":"Track___Analyze_Personal_Finances_with_WhatsApp_AI_Assistant_version_2.json","tags":[],"nodes":[{"id":"2d9465b4-58ac-4c00-a782-e8ae4e0767e5","name":"Date and time","type":"@n8n/n8n-nodes-langchain.toolCode","position":[-480,900],"parameters":{},"typeVersion":1.2},{"id":"3ca24176-0bbf-439e-bc09-d4c7c9550db9","name":"Structured Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[-360,900],"parameters":{},"typeVersion":1.2},{"id":"ced1f18b-bdaf-4c29-96f7-b9eb2ed168b2","name":"OpenRouter Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[-2000,920],"parameters":{},"typeVersion":1},{"id":"e28ef82b-c4ca-4956-8714-1ccdf56234bc","name":"OpenRouter Chat Model1","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[-1220,180],"parameters":{},"typeVersion":1},{"id":"bdb2baa4-8595-4526-8526-2249e2546b8c","name":"Calculator","type":"@n8n/n8n-nodes-langchain.toolCalculator","position":[160,180],"parameters":{},"typeVersion":1},{"id":"df26c9be-997b-4c9d-b8bf-4f91851225f8","name":"OpenRouter Chat Model3","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[40,180],"parameters":{},"typeVersion":1},{"id":"d28325fc-2633-469f-8e0b-ed63e1a5cd21","name":"OpenRouter Chat Model4","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[-2180,-700],"parameters":{},"typeVersion":1},{"id":"2af86825-6971-4c04-8807-fdb3fb8f5d2f","name":"Postgres2","type":"n8n-nodes-base.postgresTool","position":[-1540,-800],"parameters":{},"typeVersion":2.6},{"id":"c1b15283-b5ed-47be-88d4-eaa8ec621d18","name":"OpenRouter Chat Model5","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[-1660,-800],"parameters":{},"typeVersion":1},{"id":"68bf1381-c0e1-4f40-a94a-c9128cced0ca","name":"Calculator1","type":"@n8n/n8n-nodes-langchain.toolCalculator","position":[-1080,-700],"parameters":{},"typeVersion":1},{"id":"f0f2a8f1-9571-4097-978e-d403daf2e144","name":"Structured Output Parser2","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[-1420,-800],"parameters":{},"typeVersion":1.2},{"id":"57c96e65-3eaa-4fb4-add1-910cd3a54732","name":"OpenRouter Chat Model6","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[-1200,-700],"parameters":{},"typeVersion":1},{"id":"6da02d5c-d2ff-4531-a1b1-15f26090f5bd","name":"Convert to File","type":"n8n-nodes-base.convertToFile","position":[-180,60],"parameters":{},"typeVersion":1.1},{"id":"1bde35b3-c836-4f2a-bb0f-b8ce24e8b937","name":"Send Financial Response","type":"n8n-nodes-base.whatsApp","position":[1160,700],"webhookId":"f71b40d3-80fc-49d5-85f9-bdac44343b7a","parameters":{},"typeVersion":1},{"id":"f779c955-66b3-43a2-879c-080ab3c1350e","name":"Normal Conversation ","type":"n8n-nodes-base.whatsApp","position":[-760,1480],"webhookId":"f71b40d3-80fc-49d5-85f9-bdac44343b7a","parameters":{},"typeVersion":1},{"id":"21f3f5df-e990-4198-9557-6b91685d953c","name":"Incoming WhatsApp Trigger","type":"n8n-nodes-base.whatsAppTrigger","position":[-2240,700],"webhookId":"c9f59683-0d8a-474e-add3-d07c8fa53c94","parameters":{},"typeVersion":1},{"id":"3b0b47d7-69e9-46de-b1d0-7ccc5b178cda","name":"Message Intent Classifier","type":"@n8n/n8n-nodes-langchain.agent","position":[-2020,700],"parameters":{},"typeVersion":1.9},{"id":"5b78429c-34e6-46d8-87da-3dcf6ca9fdda","name":"Route by Intent","type":"n8n-nodes-base.switch","position":[-1660,700],"parameters":{},"typeVersion":3.2},{"id":"8a41699f-020f-4f8b-af2f-001f81f1d2eb","name":"Parse & Validate Transaction","type":"@n8n/n8n-nodes-langchain.agent","position":[-580,700],"parameters":{},"typeVersion":1.9},{"id":"9fb81ef2-04ca-4fc2-b041-84c13fef05f7","name":"Split Transaction Lines","type":"n8n-nodes-base.splitOut","position":[-160,700],"parameters":{},"typeVersion":1},{"id":"ac5c1e98-c006-4dcc-a547-ac3b47abd40d","name":"Format Transaction JSON","type":"n8n-nodes-base.code","position":[60,700],"parameters":{},"typeVersion":2},{"id":"bd7e2c87-aa9a-4d70-abeb-3500107a9e49","name":"Validate Transaction Fields","type":"n8n-nodes-base.code","position":[280,700],"parameters":{},"typeVersion":2},{"id":"458e9264-0077-4365-9ed9-abcbd2aac464","name":"Insert Transaction into DB","type":"n8n-nodes-base.postgres","position":[500,700],"parameters":{},"typeVersion":2.6},{"id":"2d6dec05-660e-4a2b-ac3b-a4985ba384b2","name":"Build Confirmation Message","type":"@n8n/n8n-nodes-langchain.agent","position":[740,700],"parameters":{},"typeVersion":1.9},{"id":"f545840e-4c0f-49be-a219-9178e2a8deb9","name":"Daily 8AM Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-2480,-920],"parameters":{},"typeVersion":1.2},{"id":"0d2d89ca-3a89-4989-9614-7f610da7e395","name":"Build Daily Report Query","type":"@n8n/n8n-nodes-langchain.agent","position":[-2260,-920],"parameters":{},"typeVersion":1.9},{"id":"fb61c689-a2cd-41af-8fc9-7a9428217338","name":"Execute Daily Report Query","type":"@n8n/n8n-nodes-langchain.agent","position":[-1640,-1020],"parameters":{},"typeVersion":1.9,"alwaysOutputData":false},{"id":"75e06bba-f2e5-4ad9-8c8d-8da69b335a99","name":"Build Daily Financial Summary","type":"@n8n/n8n-nodes-langchain.agent","position":[-1220,-920],"parameters":{},"typeVersion":1.9},{"id":"de60a090-1035-44ac-bb47-57d2313c87c0","name":"Send Daily Report","type":"n8n-nodes-base.whatsApp","position":[-840,-920],"webhookId":"f71b40d3-80fc-49d5-85f9-bdac44343b7a","parameters":{},"typeVersion":1},{"id":"b8adeb56-e85e-4456-9948-138812b37be6","name":"Build Custom Report Query","type":"@n8n/n8n-nodes-langchain.agent","position":[-1220,0],"parameters":{},"typeVersion":1.9},{"id":"65a22ebc-6d8e-4852-870c-86bd1233cb31","name":"Transform Custom Query for Postgres","type":"n8n-nodes-base.code","position":[-840,60],"parameters":{},"typeVersion":2},{"id":"e4df15d9-c259-4402-9f25-f1d272d97b14","name":"Format Custom Query Results","type":"n8n-nodes-base.code","position":[-400,60],"parameters":{},"executeOnce":false,"typeVersion":2},{"id":"e6f8b8f5-814f-4a29-9b5c-401144c382b3","name":"Execute Custom Report Query","type":"n8n-nodes-base.postgres","position":[-620,60],"parameters":{},"typeVersion":2.6},{"id":"fb3a83be-4785-45e3-a527-4a03516db609","name":"Build Custom Financial Summary","type":"@n8n/n8n-nodes-langchain.agent","position":[60,-40],"parameters":{},"executeOnce":true,"typeVersion":1.9},{"id":"64940c1f-41c1-46d9-b183-9f8af3cfb864","name":"Send Custom Report","type":"n8n-nodes-base.whatsApp","position":[480,60],"webhookId":"f71b40d3-80fc-49d5-85f9-bdac44343b7a","parameters":{},"typeVersion":1},{"id":"a22028ea-7164-4e43-9107-2ebbeb875117","name":"simple conversation ","type":"@n8n/n8n-nodes-langchain.agent","position":[-1180,1480],"parameters":{},"typeVersion":1.9},{"id":"e86fe657-0ec0-41de-adac-5d59f304caea","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-2900,-300],"parameters":{"content":""},"typeVersion":1},{"id":"cb66ba94-01aa-4a0c-b2b1-acd6511d55af","name":"Transform Custom Query for Postgres1","type":"n8n-nodes-base.code","position":[-1880,-920],"parameters":{},"typeVersion":2},{"id":"1edd968f-3e50-49eb-a9b7-45a83cb0ba66","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-3080,-1160],"parameters":{"content":""},"typeVersion":1},{"id":"7c7fa6ca-5ca5-44cb-a26e-46a4147821e8","name":"Date and time1","type":"@n8n/n8n-nodes-langchain.toolCode","position":[-1100,180],"parameters":{},"typeVersion":1.2},{"id":"5e3a3c5a-1a6d-4a5c-9f04-0ff8f984fe18","name":"Date and time2","type":"@n8n/n8n-nodes-langchain.toolCode","position":[280,180],"parameters":{},"typeVersion":1.2},{"id":"2cec7aab-a6a0-443e-972f-eeba83f8f75d","name":"Date and time3","type":"@n8n/n8n-nodes-langchain.toolCode","position":[900,920],"parameters":{},"typeVersion":1.2},{"id":"a246fac9-ae73-4192-bdb6-cf7e700b94cc","name":"Date and time4","type":"@n8n/n8n-nodes-langchain.toolCode","position":[-1880,920],"parameters":{},"typeVersion":1.2},{"id":"138de4a3-4c50-4d7b-ae6e-ba02b96d2565","name":"Date and time5","type":"@n8n/n8n-nodes-langchain.toolCode","position":[-1020,1680],"parameters":{},"typeVersion":1.2},{"id":"6e9a0c1e-5302-453f-8d2c-7398172c9055","name":"OpenRouter Chat Model2","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[-620,900],"parameters":{},"typeVersion":1},{"id":"ab6ae6d1-a9b5-4eef-8930-0ee27c5787f0","name":"OpenRouter Chat Model7","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[-1180,1700],"parameters":{},"typeVersion":1},{"id":"a680e6d7-8332-466b-8d3e-8923fb929ab7","name":"OpenRouter Chat Model8","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[780,920],"parameters":{},"typeVersion":1},{"id":"5e75c9ba-ef19-4052-b7a1-9233d469ae4b","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-1880,-100],"parameters":{"content":""},"typeVersion":1},{"id":"444ed176-46c1-4daf-bbfc-9231baccdf19","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-1860,1380],"parameters":{"content":""},"typeVersion":1},{"id":"fcca8840-954e-4ac5-b842-86fe24e35484","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-1240,560],"parameters":{"content":""},"typeVersion":1}],"active":true,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"e4a85103-baa6-4c56-a921-59ea3c322f7a","connections":{"Postgres2":{"ai_tool":[[{"node":"Execute Daily Report Query","type":"ai_tool","index":0}]]},"Calculator":{"ai_tool":[[{"node":"Build Custom Financial Summary","type":"ai_tool","index":0}]]},"Calculator1":{"ai_tool":[[{"node":"Build Daily Financial Summary","type":"ai_tool","index":0}]]},"Date and time":{"ai_tool":[[{"node":"Parse & Validate Transaction","type":"ai_tool","index":0}]]},"Date and time1":{"ai_tool":[[{"node":"Build Custom Report Query","type":"ai_tool","index":0}]]},"Date and time2":{"ai_tool":[[{"node":"Build Custom Financial Summary","type":"ai_tool","index":0}]]},"Date and time3":{"ai_tool":[[{"node":"Build Confirmation Message","type":"ai_tool","index":0}]]},"Date and time4":{"ai_tool":[[{"node":"Message Intent Classifier","type":"ai_tool","index":0}]]},"Date and time5":{"ai_tool":[[{"node":"simple conversation ","type":"ai_tool","index":0}]]},"Convert to File":{"main":[[{"node":"Build Custom Financial Summary","type":"main","index":0}]]},"Route by Intent":{"main":[[{"node":"Build Custom Report Query","type":"main","index":0}],[{"node":"Parse & Validate Transaction","type":"main","index":0}],[{"node":"simple conversation ","type":"main","index":0}]]},"Daily 8AM Trigger":{"main":[[{"node":"Build Daily Report Query","type":"main","index":0}]]},"simple conversation ":{"main":[[{"node":"Normal Conversation ","type":"main","index":0}]]},"OpenRouter Chat Model":{"ai_languageModel":[[{"node":"Message Intent Classifier","type":"ai_languageModel","index":0}]]},"OpenRouter Chat Model1":{"ai_languageModel":[[{"node":"Build Custom Report Query","type":"ai_languageModel","index":0}]]},"OpenRouter Chat Model2":{"ai_languageModel":[[{"node":"Parse & Validate Transaction","type":"ai_languageModel","index":0}]]},"OpenRouter Chat Model3":{"ai_languageModel":[[{"node":"Build Custom Financial Summary","type":"ai_languageModel","index":0}]]},"OpenRouter Chat Model4":{"ai_languageModel":[[{"node":"Build Daily Report Query","type":"ai_languageModel","index":0}]]},"OpenRouter Chat Model5":{"ai_languageModel":[[{"node":"Execute Daily Report Query","type":"ai_languageModel","index":0}]]},"OpenRouter Chat Model6":{"ai_languageModel":[[{"node":"Build Daily Financial Summary","type":"ai_languageModel","index":0}]]},"OpenRouter Chat Model7":{"ai_languageModel":[[{"node":"simple conversation ","type":"ai_languageModel","index":0}]]},"OpenRouter Chat Model8":{"ai_languageModel":[[{"node":"Build Confirmation Message","type":"ai_languageModel","index":0}]]},"Format Transaction JSON":{"main":[[{"node":"Validate Transaction Fields","type":"main","index":0}]]},"Split Transaction Lines":{"main":[[{"node":"Format Transaction JSON","type":"main","index":0}]]},"Build Daily Report Query":{"main":[[{"node":"Transform Custom Query for Postgres1","type":"main","index":0}]]},"Structured Output Parser":{"ai_outputParser":[[{"node":"Parse & Validate Transaction","type":"ai_outputParser","index":0}]]},"Build Custom Report Query":{"main":[[{"node":"Transform Custom Query for Postgres","type":"main","index":0}]]},"Incoming WhatsApp Trigger":{"main":[[{"node":"Message Intent Classifier","type":"main","index":0}]]},"Message Intent Classifier":{"main":[[{"node":"Route by Intent","type":"main","index":0}]]},"Structured Output Parser2":{"ai_outputParser":[[{"node":"Execute Daily Report Query","type":"ai_outputParser","index":0}]]},"Build Confirmation Message":{"main":[[{"node":"Send Financial Response","type":"main","index":0}]]},"Execute Daily Report Query":{"main":[[{"node":"Build Daily Financial Summary","type":"main","index":0}]]},"Insert Transaction into DB":{"main":[[{"node":"Build Confirmation Message","type":"main","index":0}]]},"Execute Custom Report Query":{"main":[[{"node":"Format Custom Query Results","type":"main","index":0}]]},"Format Custom Query Results":{"main":[[{"node":"Convert to File","type":"main","index":0}]]},"Validate Transaction Fields":{"main":[[{"node":"Insert Transaction into DB","type":"main","index":0}]]},"Parse & Validate Transaction":{"main":[[{"node":"Split Transaction Lines","type":"main","index":0}]]},"Build Daily Financial Summary":{"main":[[{"node":"Send Daily Report","type":"main","index":0}]]},"Build Custom Financial Summary":{"main":[[{"node":"Send Custom Report","type":"main","index":0}]]},"Transform Custom Query for Postgres":{"main":[[{"node":"Execute Custom Report Query","type":"main","index":0}]]},"Transform Custom Query for Postgres1":{"main":[[{"node":"Execute Daily Report Query","type":"main","index":0}]]}}}


name: AI SEO Readability Audit: Check Website Friendliness for LLMs
author_name: Leonard
author_username: leonardvanhemert
categories: []
created_at: 2025-05-17T14:15:31.298Z
updated_at: 2025-05-17T14:15:31.298Z
url: https://n8n.io/workflows/4151
scraped_at: 2025-06-19 22:49:27
description:
  Who is this for?
  This workflow is designed for SEO specialists, content creators, marketers, and website developers who want to ensure their web content is easily accessible, understandable, and indexable by Large Language Models (LLMs) like ChatGPT, Perplexity, and Google AI Overviews. If you're looking to optimize your site for the evolving AI-driven search landscape, this template is for you.

  What problem is this workflow solving? / Use case
  Modern AI tools often crawl websites without executing JavaScript. This can lead to them "seeing" a very different version of your page than a human user or traditional search engine bot might. This workflow helps you:
  Identify how much of your content is visible without JavaScript.
  Check for crucial on-page SEO elements that AI relies on (headings, meta descriptions, structured data).
  Detect if your site presents JavaScript-blocking warnings.
  Get an AI-generated readability score and actionable recommendations to improve AI-friendliness.

  What this workflow does
  Receives a URL via a chat interface.
  Sanitizes the input URL to ensure it's correctly formatted.
  Fetches the website's HTML content, simulating a non-JavaScript crawler (like Googlebot).
  Extracts key HTML features: visible text length, presence of H1/H2/H3 tags, meta description, Open Graph data, structured data (JSON-LD), and &lt;noscript&gt; tags. It also checks for common JavaScript-blocking messages.
  Performs an AI SEO Analysis using an LLM (via OpenAI) based on the extracted features.
  Provides a report including an AI Readability Score (0-10), a summary, actionable recommendations, and a reminder to check the robots.txt file for AI bot access.

  Setup
  Estimated setup time:** 2-5 minutes.
  Import this workflow into your n8n instance.
  Ensure you have an OpenAI account and API key.
  Configure the "OpenAI Chat Model" node with your OpenAI API credentials. If you don't have credentials set up yet, create new ones in n8n.
  Activate the workflow.
  Interact with the chat interface provided by the "When chat message received" trigger node (you can access this via its webhook URL).

  How to customize this workflow to your needs
  Change LLM Model:** In the "OpenAI Chat Model" node, you can select a different model that suits your needs or budget.
  Adjust AI Prompt:** Modify the prompt in the "AI SEO Analysis" node (Chain Llm) to change the focus of the analysis or the format of the report. For example, you could ask for more technical details or a different scoring system.
  User-Agent:** The "Get HTML from Website" node uses a Googlebot User-Agent. You can change this to simulate other bots if needed.
  JS Block Indicators:** The "Extract HTML Features" node contains a list of common JavaScript-blocking phrases. You can expand this list with other languages or specific messages relevant to your checks.

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

workflow_json:
  {"id":"qthXGkJCm1YAAQpW","meta":{"instanceId":"c586b172acc6a68496c50087fe4c45ad1d861562820afb3dfa9dc2c12688d8c2","templateCredsSetupCompleted":true},"name":"AI SEO Readability Audit: Check Website Friendliness for LLMs","tags":[{"id":"JkpR8IEIpOrc2x6l","name":"Leonard van Hemert","createdAt":"2025-05-17T14:14:16.649Z","updatedAt":"2025-05-17T14:14:16.649Z"}],"nodes":[{"id":"ea4c49eb-5a9d-4de9-acc7-3eef90b11f29","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[-340,-140],"webhookId":"f41e2ff4-b329-4c64-9147-963726a1eb76","parameters":{"public":true,"options":{"title":"🚀 AI SEO Readability Checker","subtitle":"Test how AI-friendly your website is for search engines like ChatGPT & Perplexity – built by [Leonard van Hemert](https://nl.linkedin.com/in/leonard-van-hemert)","responseMode":"lastNode","inputPlaceholder":"https://example.com"},"initialMessages":"Hi! 👋  \nSend your website link and I’ll check how AI-friendly it is for tools like ChatGPT and Perplexity. Let’s go! 🚀"},"typeVersion":1.1},{"id":"0ede3abb-3cad-4e9a-bc8c-79d8eac06fe6","name":"Get HTML from Website","type":"n8n-nodes-base.httpRequest","position":[100,-140],"parameters":{"url":"={{ $json.url }}","options":{"timeout":10000},"jsonHeaders":"{\n  \"User-Agent\": \"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)\",\n  \"Accept-Language\": \"nl-NL,nl;q=0.9,en-US;q=0.8,en;q=0.7\"\n}","sendHeaders":true,"specifyHeaders":"json"},"retryOnFail":true,"typeVersion":4.2,"alwaysOutputData":true},{"id":"96d8c97a-8d7b-41fb-a109-d56e34d7dff1","name":"Sanitize Website URL","type":"n8n-nodes-base.code","position":[-120,-140],"parameters":{"jsCode":"return [\n  {\n    json: {\n      url: (() => {\n        let input = $json.chatInput.trim().toLowerCase();\n        if (!input.startsWith('http')) input = 'https://' + input;\n        return input;\n      })()\n    }\n  }\n];"},"typeVersion":2},{"id":"2b8a702e-b141-4f71-9e8f-2caa69cfad80","name":"Extract HTML Features","type":"n8n-nodes-base.code","position":[320,-140],"parameters":{"jsCode":"const html = $json.data || '';\n\n// Remove scripts, styles, and extract visible text\nconst cleanedText = html\n  .replace(/<script[\\s\\S]*?<\\/script>/gi, '')\n  .replace(/<style[\\s\\S]*?<\\/style>/gi, '')\n  .replace(/<[^>]*>/g, '') // strip all HTML tags\n  .replace(/\\s+/g, ' ')\n  .trim();\n\n// Preview: first 400 chars of visible content\nconst previewText = cleanedText.slice(0, 400);\n\n// Lowercased text for language-agnostic JS block detection\nconst lowerText = cleanedText.toLowerCase();\n\n// Common JS-related blocking messages (EN + NL + DE)\nconst jsBlockIndicators = [\n  'enable javascript',\n  'javascript is required',\n  'please enable javascript',\n  'javascript moet ingeschakeld zijn',\n  'schakel javascript in',\n  'javascript erforderlich'\n];\n\n// Scan for any of the indicators\nconst jsWarningDetected = jsBlockIndicators.some(phrase => lowerText.includes(phrase));\n\nreturn [\n  {\n    json: {\n      visibleTextLength: cleanedText.length,\n      previewText,\n      hasH1: /<h1[\\s>]/i.test(html),\n      hasH2: /<h2[\\s>]/i.test(html),\n      hasH3: /<h3[\\s>]/i.test(html),\n      hasMetaDescription: /<meta[^>]+name=[\"']description[\"']/i.test(html),\n      hasOpenGraph: /<meta[^>]+property=[\"']og:/i.test(html),\n      hasStructuredData: /<script[^>]*type=[\"']application\\/ld\\+json[\"']/i.test(html),\n      hasNoscript: /<noscript[\\s>]/i.test(html),\n      jsWarning: jsWarningDetected,\n      robotsTxt: $('Sanitize Website URL').first().json.url.replace(/\\/$/, '') + '/robots.txt'\n    }\n  }\n];"},"typeVersion":2},{"id":"58591741-7896-4f0f-a5d6-a16efccdf4a3","name":"AI SEO Analysis","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[540,-140],"parameters":{"text":"=You are an expert in AI SEO analysis and AI search engine accessibility.\n\nYou are evaluating a website’s readability for LLM-based tools like ChatGPT, Perplexity, and Google AI Overviews. The website's raw HTML was fetched *without JavaScript execution*, simulating how LLMs typically see pages.\n\n---\n\n### 🧾 Technical Scan Summary\n\n**Visible content (no JS):**\n- Text length: {{ $json.visibleTextLength }} characters\n- Preview: \"{{ $json.previewText }}\"\n\n**Detected features:**\n- Structured Data (JSON-LD): {{ $json.hasStructuredData }}\n- Meta Description: {{ $json.hasMetaDescription }}\n- Open Graph Metadata: {{ $json.hasOpenGraph }}\n- Headings: H1: {{ $json.hasH1 }}, H2: {{ $json.hasH2 }}, H3: {{ $json.hasH3 }}\n- `<noscript>` fallback present: {{ $json.hasNoscript }}\n- JavaScript-blocking warning found: {{ $json.jsWarning }}\n\n---\n\n### 🎯 Your task:\nEvaluate the AI-readability of this website and return:\n\n1. An **AI Readability Score (0–10)**\n2. A **brief summary** of the current state (2–4 sentences)\n3. Up to **5 actionable recommendations** to improve visibility and accessibility for AI search engines\n\n💡 If the text length is below 300 or the `JavaScript-blocking warning found` is true, clearly state that the site may not be accessible to LLMs due to JavaScript dependency.\n\n⚠️ **Important:**\nYou must also **tell the user** to check their `robots.txt` file manually, and provide this exact clickable link:  \n👉 [{{ $json.robotsTxt }}]({{ $json.robotsTxt }})  \nExplain they must ensure bots like `GPTBot`, `ChatGPT-User`, and `Google-Extended` are **not blocked**.\n\nDo not perform this check yourself — just inform the user to do it.\n\n---\n\n🎁 Format your response like this:\n\n**Score:** x/10  \n**Summary:** ...  \n**Recommendations:**\n- ...\n- Check your robots.txt file at [{{ $json.robotsTxt }}]({{ $json.robotsTxt }}) to ensure AI bots are allowed.","promptType":"define"},"typeVersion":1.6},{"id":"080e40e2-bfb3-42df-8f92-ac1379135aad","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-380,20],"parameters":{"color":4,"width":740,"height":700,"content":"# 🚀 AI SEO Readability Audit Workflow\n\n**Purpose:** This workflow analyzes a website's HTML to assess its readability and accessibility for Large Language Models (LLMs) like ChatGPT and Perplexity, which often crawl without executing JavaScript.\n\n**How it Works:**\n1.  Enter a website URL in the chat.\n2.  The workflow fetches the raw HTML (simulating a no-JS crawler).\n3.  It extracts key SEO features (text content, headings, meta tags, etc.).\n4.  An LLM (via OpenAI) analyzes these features to provide:\n    - An AI Readability Score (0-10)\n    - A summary of the site's AI-friendliness\n    - Actionable recommendations\n    - A reminder to check `robots.txt`\n\n**Setup Required:**\n- An **OpenAI Account & API Key**: Configure your credentials in the \"OpenAI Chat Model\" node.\n- **n8n Instance**: This workflow runs on any n8n instance (cloud or self-hosted).\n\n**To Use:**\n1.  Ensure the \"OpenAI Chat Model\" node is configured with your API key.\n2.  Activate the workflow.\n3.  Open the chat URL provided by the \"When chat message received\" trigger.\n\n**Customization:**\n- **LLM Model:** Change the model in the \"OpenAI Chat Model\" node.\n- **Analysis Prompt:** Modify the prompt in the \"AI SEO Analysis\" node.\n\n🔗 *For more details on setup and customization, see the template description on n8n.io.*"},"typeVersion":1},{"id":"a737c2cb-1d6c-4e69-9d92-c7177c42049a","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[360,260],"parameters":{"width":540,"height":460,"content":"# **🚀 Developed by Leonard van Hemert**  \n\nThank you for using this **AI SEO Readability Audit** workflow! 🎉  \n\nThis workflow was created to help users understand how AI tools \"see\" their websites and to provide actionable insights for improving AI-friendliness.\n\nIf you find this useful, feel free to **connect with me on LinkedIn** and stay updated on my latest AI & automation projects!  \n\n🔗 **Follow me on LinkedIn**: [Leonard van Hemert](https://www.linkedin.com/in/leonard-van-hemert/)  \n\nI truly appreciate the support from the **n8n community**, and I can’t wait to see how you use and improve this workflow! 🚀  \n\nHappy optimizing,  \n**Leonard van Hemert** 💡"},"typeVersion":1},{"id":"7228e3be-1ef7-4f5a-bcb0-2a9299d53cfe","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[628,80],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o","cachedResultName":"gpt-4o"},"options":{"temperature":0.3}},"credentials":{"openAiApi":{"id":"1OV4I35YEqCf9qI5","name":"OpenAI account"}},"typeVersion":1.2}],"active":true,"pinData":{},"settings":{"callerPolicy":"workflowsFromSameOwner","executionOrder":"v1","executionTimeout":300},"versionId":"9e18a350-a243-4368-b3d3-746a55bceb24","connections":{"AI SEO Analysis":{"main":[[]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI SEO Analysis","type":"ai_languageModel","index":0}]]},"Sanitize Website URL":{"main":[[{"node":"Get HTML from Website","type":"main","index":0}]]},"Extract HTML Features":{"main":[[{"node":"AI SEO Analysis","type":"main","index":0}]]},"Get HTML from Website":{"main":[[{"node":"Extract HTML Features","type":"main","index":0}]]},"When chat message received":{"main":[[{"node":"Sanitize Website URL","type":"main","index":0}]]}}}


name: Cold Email Outreach with Gmail and Google Sheets Status Tracking
author_name: Usman Liaqat
author_username: usmanliaqat
nodes_used: ["n8n-nodes-base.googleSheets","n8n-nodes-base.gmail"]
categories: []
created_at: 2025-05-19T06:09:58.904Z
updated_at: 2025-05-19T06:09:58.904Z
url: https://n8n.io/workflows/4214
scraped_at: 2025-06-19 22:49:15
description:
  This workflow automates personalized cold email outreach by pulling lead data from a Google Sheet, sending emails via Gmail, and updating the sheet to track who has been contacted.

  Features
  Automated Scheduling* – Runs daily at a specified hour via the *Schedule Trigger** node.
  Google Sheets Integration** – Fetches leads whose "Is Email Sent" value is empty.
  Batch Processing** – Processes leads in manageable batches.
  Personalized Gmail Outreach** – Sends custom emails using a pre-written template.
  Status Tracking** – Updates each lead’s row after an email is sent to prevent duplicates.

  Requirements

  Google Sheets OAuth2 credentials**
  Gmail account with OAuth2**
  Access to n8n with a deployed instance

  Setup Instructions

  1. Connect Accounts

  Authenticate Google Sheets and Gmail nodes via OAuth2 in your n8n credentials settings.

  2. Prepare Your Google Sheet

  Your Google Sheet must contain the following columns:


  Email
  Name (or WF Full Name (metadata))
  Is Email Sent

  Example:

  | Email               | Name          | Is Email Sent |
  |--------------------|---------------|----------------|
  | test@example.com   | John Doe      |                |
  | jane@company.com   | Jane Smith    | yes            |

  Only rows where "Is Email Sent" is not marked as "yes" will be processed.

  3. Customize the Email Template

  Open the “Send Personalized Email” node and update the message field. You can use variables like:

  {{ $json.Name }}
  {{ $json['WF Full Name (metadata)'] }}

  Example Message:

  Hello {{ $json.Name || $json['WF Full Name (metadata)'] }},

  I’m a software developer and automation expert. I work with businesses and individuals to build websites, mobile apps, and powerful digital solutions that help save time and grow online.

  I offer a range of services including:
  Website & App Development
  SEO & Digital Marketing
  Business Process Automation

  If you’re looking to start a new project or improve your current setup, I’d love to connect and see how I can help.

  Are you interested in discussing any of these services?

  Best regards,  
  Software Developer | Automation Expert

  4. Schedule the Workflow

  Edit the Schedule Trigger node to your preferred time (currently set to 2 PM daily):

  Customization Tips

  Replace the email copy with your branding or offer.
  Add more fields (like company or industry) and update the message for deeper personalization.
  Modify the batch size in the Split In Batches node for rate control.

  Notes & Limitations

  Gmail Quotas:** Gmail has sending limits (e.g., 500 emails/day for free accounts).
  OAuth2 Scope Approval:** Ensure the necessary scopes (e.g., Gmail send and Sheets read/write) are granted.
  Rate Limiting:** If working with large lists, consider time delays or throttle controls.

  Google Sheet Template

  You can make a copy of this sample Google Sheet to get started.

workflow_json:
  {"meta":{"instanceId":"fae057ee2d891478d0c2072cd4fb64f7da69a0dd189c9cf4fd08c30e50dba628","templateCredsSetupCompleted":true},"nodes":[{"id":"07cbdd82-2df1-41eb-80f3-cfe762ce1d5e","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-40,40],"parameters":{"rule":{"interval":[{"triggerAtHour":14}]}},"typeVersion":1.2},{"id":"bbc2f2fe-8f33-4a92-80ab-408655000baa","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-160,-200],"parameters":{"width":1220,"height":480,"content":"## Cold Email Outreach with Gmail and Google Sheets Status Tracking\nThis workflow runs daily at 2 PM, fetches leads from the Google Sheet who haven't received an email yet, sends a personalized outreach message via Gmail, then updates their status in the sheet to \"yes\" for \"Is Email Sent\"."},"typeVersion":1},{"id":"166afe50-aa7b-4e46-8ebc-bd964d670e34","name":"Batch Processing of Leads","type":"n8n-nodes-base.splitInBatches","position":[400,40],"parameters":{"options":{}},"typeVersion":3},{"id":"0284614d-d43e-42a1-85cf-2677e06fc1f4","name":"Send Personalized Email","type":"n8n-nodes-base.gmail","position":[680,-60],"webhookId":"ad8c804e-857d-4a94-b722-65b0776f1d10","parameters":{"sendTo":"={{ $json.Email }}","message":"=Hello {{ $json.Name || $json['WF Full Name (metadata)'] }},\n\nI’m a software developer and automation expert. I work with businesses and individuals to build websites, mobile apps, and powerful digital solutions that help save time and grow online.\n\nI offer a range of services including:\n- Website & App Development\n- SEO & Digital Marketing\n- Business Process Automation\n\nIf you’re looking to start a new project or improve your current setup, I’d love to connect and see how I can help.\n\nAre you interested in discussing any of these services?\n\nBest regards,\nSoftware Developer | Automation Expert","options":{"senderName":"Developer","appendAttribution":false},"subject":"Need Help with Your Website, App, or Online Growth?","emailType":"text"},"credentials":{"gmailOAuth2":{"id":"REDACTED","name":"REDACTED_GMAIL_CREDENTIAL"}},"typeVersion":2.1},{"id":"ae48ba04-d428-4aa3-9212-fb49af92c7ae","name":"Fetch Leads","type":"n8n-nodes-base.googleSheets","position":[180,40],"parameters":{"options":{},"filtersUI":{"values":[{"lookupColumn":"Is Email Sent"}]},"sheetName":{"__rl":true,"mode":"list","value":"REDACTED_SHEET_ID"},"documentId":{"__rl":true,"mode":"list","value":"REDACTED_DOCUMENT_ID"}},"credentials":{"googleSheetsOAuth2Api":{"id":"REDACTED","name":"REDACTED_SHEETS_CREDENTIAL"}},"typeVersion":4.5},{"id":"62e831c3-c67c-4b0c-a0bd-5e4a8fcb23f6","name":"Update Lead Status","type":"n8n-nodes-base.googleSheets","position":[880,40],"parameters":{"columns":{"value":{"Email":"={{ $('Batch Processing of Leads').item.json.Email }}","Is Email Sent":"yes"},"schema":[{"id":"Email","type":"string","display":true},{"id":"Is Email Sent","type":"string","display":true}],"mappingMode":"defineBelow","matchingColumns":["Email"]},"options":{},"operation":"update","sheetName":{"__rl":true,"mode":"list","value":"REDACTED_SHEET_ID"},"documentId":{"__rl":true,"mode":"list","value":"REDACTED_DOCUMENT_ID"}},"credentials":{"googleSheetsOAuth2Api":{"id":"REDACTED","name":"REDACTED_SHEETS_CREDENTIAL"}},"typeVersion":4.5}],"pinData":{},"connections":{"Fetch Leads":{"main":[[{"node":"Batch Processing of Leads","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Fetch Leads","type":"main","index":0}]]},"Update Lead Status":{"main":[[{"node":"Batch Processing of Leads","type":"main","index":0}]]},"Send Personalized Email":{"main":[[{"node":"Update Lead Status","type":"main","index":0}]]},"Batch Processing of Leads":{"main":[[],[{"node":"Send Personalized Email","type":"main","index":0}]]}}}


name: Context-Aware Google Calendar Management with MCP Protocol
author_name: Simeon
author_username: simealdana
nodes_used: ["n8n-nodes-base.googleCalendar","@n8n/n8n-nodes-langchain.toolWorkflow"]
categories: []
created_at: 2025-05-19T19:53:44.325Z
updated_at: 2025-05-19T19:53:44.325Z
url: https://n8n.io/workflows/4231
scraped_at: 2025-06-19 22:48:57
description:
  Google Calendar MCP – Context-Aware Calendar Operations

  This n8n template implements an MCP (Model Context Protocol)-compliant module for managing Google Calendar events in a context-aware, conflict-free manner.

  🧠 What It Does

  This MCP enables structured interaction with Google Calendar based on context and intent, ensuring reliable, reusable operations with awareness of existing data and state.

  ✅ Core Capabilities

  Context-aware event creation**  
    Prevents overlapping by validating time availability before creating new events.

  Gap validation**  
    Checks if a time range is busy or free, enabling smarter scheduling decisions.

  Conditional updates**  
    Only updates events after confirming their existence and current state.

  Safe deletion**  
    Removes events using MCP principles of validation and traceability.

  🚀 How to Use

  To use this MCP in your context-aware systems:

  Deploy the template in your n8n instance.
  Locate the Server node in the workflow — it exposes a Server-Sent Events (SSE) URL.
  Copy that SSE URL.
  Use that URL as the entry point for your MCP client or orchestrator.

  This URL acts as the communication bridge, allowing you to interact with the MCP-compliant Google Calendar logic using standard MCP semantics.

workflow_json:
  {"id":"aiKrExd0rAxJO6xi","meta":{"instanceId":"f8eaf8bef1c6467fb3687216a5c1296ee5e886fb01cb197574b7f8e91332a8d8","templateCredsSetupCompleted":true},"name":"MCP_google_calendar","tags":[],"nodes":[{"id":"17ccfdbf-d121-4ff0-95d4-bb38644d2bb1","name":"MCP Server Trigger","type":"@n8n/n8n-nodes-langchain.mcpTrigger","position":[80,-40],"webhookId":"c734cf98-3d5a-4cbd-af97-8ad2da760944","parameters":{"path":"c734cf98-3d5a-4cbd-af97-8ad2da760944"},"typeVersion":1},{"id":"174a13be-04f1-417c-8510-26798dae3447","name":"When Executed by Another Workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[1060,220],"parameters":{"workflowInputs":{"values":[{"name":"operation"},{"name":"startDate"},{"name":"endDate"},{"name":"eventId"},{"name":"timeZone"}]}},"typeVersion":1.1},{"id":"f74799f0-67b4-4247-905c-46adb1be4739","name":"Operation","type":"n8n-nodes-base.switch","position":[1460,180],"parameters":{"rules":{"values":[{"outputKey":"getEvent","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"81b134bc-d671-4493-b3ad-8df9be3f49a6","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.operation }}","rightValue":"getEvent"}]},"renameOutput":true},{"outputKey":"deleteEvent","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"8d57914f-6587-4fb3-88e0-aa1de6ba56c1","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.operation }}","rightValue":"deleteEvent"}]},"renameOutput":true},{"outputKey":"createEvent","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"7c38f238-213a-46ec-aefe-22e0bcb8dffc","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.operation }}","rightValue":"createEvent"}]},"renameOutput":true},{"outputKey":"updateEvent","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"ee9b6783-a0f2-4848-9166-aba6645c1ebc","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.operation }}","rightValue":"updateEvent"}]},"renameOutput":true},{"outputKey":"getEventData","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"9ea6980d-a7be-4dec-8ddf-d2fcffb00af1","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"getEventData","rightValue":"getEventData"}]},"renameOutput":true}]},"options":{}},"typeVersion":3.2},{"id":"b8007362-0d41-4875-872b-877f33b74bf8","name":"validate_busy_time","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[-80,240],"parameters":{"name":"validate_busy_time","workflowId":{"__rl":true,"mode":"list","value":"aiKrExd0rAxJO6xi","cachedResultName":"MCP_google_calendar"},"description":"Call this tool to validate if the gap of time is already busy. it is useful to validate before creating a new event","workflowInputs":{"value":{"endDate":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('endDate', ``, 'string') }}","eventId":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('eventId', ``, 'string') }}","timeZone":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('timeZone', ``, 'string') }}","operation":"=getEvent","startDate":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('startDate', ``, 'string') }}"},"schema":[{"id":"operation","type":"string","display":true,"removed":false,"required":false,"displayName":"operation","defaultMatch":false,"canBeUsedToMatch":true},{"id":"startDate","type":"string","display":true,"removed":false,"required":false,"displayName":"startDate","defaultMatch":false,"canBeUsedToMatch":true},{"id":"endDate","type":"string","display":true,"removed":false,"required":false,"displayName":"endDate","defaultMatch":false,"canBeUsedToMatch":true},{"id":"eventId","type":"string","display":true,"removed":false,"required":false,"displayName":"eventId","defaultMatch":false,"canBeUsedToMatch":true},{"id":"timeZone","type":"string","display":true,"removed":false,"required":false,"displayName":"timeZone","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false}},"typeVersion":2.1},{"id":"51f39673-4657-401b-b1bf-34e816318acf","name":"create_new_event","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[80,240],"parameters":{"name":"create_new_event","workflowId":{"__rl":true,"mode":"list","value":"aiKrExd0rAxJO6xi","cachedResultName":"MCP_google_calendar"},"description":"Use this tool to create a new event; always validate if the gap of time is available before creating a new event ","workflowInputs":{"value":{"endDate":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('endDate', ``, 'string') }}","eventId":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('eventId', ``, 'string') }}","timeZone":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('timeZone', ``, 'string') }}","operation":"createEvent","startDate":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('startDate', ``, 'string') }}"},"schema":[{"id":"operation","type":"string","display":true,"removed":false,"required":false,"displayName":"operation","defaultMatch":false,"canBeUsedToMatch":true},{"id":"startDate","type":"string","display":true,"removed":false,"required":false,"displayName":"startDate","defaultMatch":false,"canBeUsedToMatch":true},{"id":"endDate","type":"string","display":true,"removed":false,"required":false,"displayName":"endDate","defaultMatch":false,"canBeUsedToMatch":true},{"id":"eventId","type":"string","display":true,"removed":false,"required":false,"displayName":"eventId","defaultMatch":false,"canBeUsedToMatch":true},{"id":"timeZone","type":"string","display":true,"removed":false,"required":false,"displayName":"timeZone","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false}},"typeVersion":2.1},{"id":"3587c022-2f57-4bf6-8066-c292bcab5399","name":"delete_event","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[360,240],"parameters":{"name":"delete_event","workflowId":{"__rl":true,"mode":"list","value":"aiKrExd0rAxJO6xi","cachedResultName":"MCP_google_calendar"},"description":"Call this tool to delete a event, to delete a event you need the even id. it is required","workflowInputs":{"value":{"endDate":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('endDate', ``, 'string') }}","eventId":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('eventId', ``, 'string') }}","timeZone":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('timeZone', ``, 'string') }}","operation":"deleteEvent","startDate":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('startDate', ``, 'string') }}"},"schema":[{"id":"operation","type":"string","display":true,"removed":false,"required":false,"displayName":"operation","defaultMatch":false,"canBeUsedToMatch":true},{"id":"startDate","type":"string","display":true,"removed":false,"required":false,"displayName":"startDate","defaultMatch":false,"canBeUsedToMatch":true},{"id":"endDate","type":"string","display":true,"removed":false,"required":false,"displayName":"endDate","defaultMatch":false,"canBeUsedToMatch":true},{"id":"eventId","type":"string","display":true,"removed":false,"required":false,"displayName":"eventId","defaultMatch":false,"canBeUsedToMatch":true},{"id":"timeZone","type":"string","display":true,"removed":false,"required":false,"displayName":"timeZone","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false}},"typeVersion":2.1},{"id":"1da9a808-b478-47cd-b129-2a11d83d8735","name":"update_event","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[220,240],"parameters":{"name":"update_event","workflowId":{"__rl":true,"mode":"list","value":"aiKrExd0rAxJO6xi","cachedResultName":"MCP_google_calendar"},"description":"Call this tool to update the event name, startDate or endDate. Validate with validate_busy_time before any action","workflowInputs":{"value":{"endDate":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('endDate', ``, 'string') }}","eventId":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('eventId', ``, 'string') }}","timeZone":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('timeZone', ``, 'string') }}","operation":"updateEvent","startDate":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('startDate', ``, 'string') }}"},"schema":[{"id":"operation","type":"string","display":true,"removed":false,"required":false,"displayName":"operation","defaultMatch":false,"canBeUsedToMatch":true},{"id":"startDate","type":"string","display":true,"removed":false,"required":false,"displayName":"startDate","defaultMatch":false,"canBeUsedToMatch":true},{"id":"endDate","type":"string","display":true,"removed":false,"required":false,"displayName":"endDate","defaultMatch":false,"canBeUsedToMatch":true},{"id":"eventId","type":"string","display":true,"removed":false,"required":false,"displayName":"eventId","defaultMatch":false,"canBeUsedToMatch":true},{"id":"timeZone","type":"string","display":true,"removed":false,"required":false,"displayName":"timeZone","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false}},"typeVersion":2.1},{"id":"f3105e5b-0dec-44d0-ba5c-5bd91b0887d1","name":"validate_availability_event","type":"n8n-nodes-base.googleCalendar","position":[2100,-220],"parameters":{"options":{},"timeMax":"={{ $json.endDate }}","timeMin":"={{ $json.startDate }}","calendar":{"__rl":true,"mode":"list","value":"your-calendar@gmail.com","cachedResultName":"your-calendar@gmail.com"},"resource":"calendar"},"credentials":{"googleCalendarOAuth2Api":{"id":"google-api-id","name":"Google Calendar account"}},"typeVersion":1.3},{"id":"43f2125b-85ea-455d-92ed-b84d0eb4a566","name":"check_availability_to_create","type":"n8n-nodes-base.googleCalendar","position":[1780,220],"parameters":{"options":{},"timeMax":"={{ $('map_data').item.json.endDate }}","timeMin":"={{ $('map_data').item.json.startDate }}","calendar":{"__rl":true,"mode":"list","value":"your-calendar@gmail.com","cachedResultName":"your-calendar@gmail.com"},"resource":"calendar"},"credentials":{"googleCalendarOAuth2Api":{"id":"google-api-id","name":"Google Calendar account"}},"typeVersion":1.3},{"id":"7f2e1fef-79cb-4728-aa63-1afe038598ab","name":"If","type":"n8n-nodes-base.if","position":[2000,220],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"4ee8a84d-c48a-416f-aa31-0633ee59124b","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.available }}","rightValue":""}]}},"typeVersion":2.2},{"id":"b2523fe9-526b-4617-b404-59a0b0e6d0e0","name":"Stop and Error","type":"n8n-nodes-base.stopAndError","position":[2220,320],"parameters":{"errorMessage":"The time you are trying to create the event is busy"},"typeVersion":1},{"id":"c72026c4-820d-4be0-9bbd-37b9ec6d2bf1","name":"create_event","type":"n8n-nodes-base.googleCalendar","position":[2220,160],"parameters":{"end":"={{ $('map_data').item.json.endDate }}","start":"={{ $('map_data').item.json.startDate }}","calendar":{"__rl":true,"mode":"list","value":"your-calendar@gmail.com","cachedResultName":"your-calendar@gmail.com"},"additionalFields":{}},"credentials":{"googleCalendarOAuth2Api":{"id":"google-api-id","name":"Google Calendar account"}},"typeVersion":1.3},{"id":"61f84fdb-768e-4b5f-9df9-21316dfa7678","name":"delete_event1","type":"n8n-nodes-base.googleCalendar","position":[2120,-20],"parameters":{"eventId":"={{ $('map_data').item.json.eventId }}","options":{},"calendar":{"__rl":true,"mode":"list","value":"your-calendar@gmail.com","cachedResultName":"your-calendar@gmail.com"},"operation":"delete"},"credentials":{"googleCalendarOAuth2Api":{"id":"google-api-id","name":"Google Calendar account"}},"typeVersion":1.3},{"id":"2544e1e6-e620-4794-b1d4-898b2e9722ad","name":"Edit Fields","type":"n8n-nodes-base.set","position":[2320,-220],"parameters":{"options":{},"assignments":{"assignments":[{"id":"973dfb96-eeda-45be-bc93-668c9118677f","name":"available","type":"boolean","value":"={{ $json.available }}"}]}},"typeVersion":3.4},{"id":"966dc7bb-b2c8-40b1-95d9-ad10b232d1b2","name":"get_event_in_time_gap","type":"n8n-nodes-base.googleCalendar","position":[1860,700],"parameters":{"options":{},"timeMax":"={{ $('map_data').item.json.endDate }}","timeMin":"={{ $('map_data').item.json.startDate }}","calendar":{"__rl":true,"mode":"list","value":"your-calendar@gmail.com","cachedResultName":"your-calendar@gmail.com"},"operation":"getAll"},"credentials":{"googleCalendarOAuth2Api":{"id":"google-api-id","name":"Google Calendar account"}},"typeVersion":1.3,"alwaysOutputData":true},{"id":"7010b476-f500-4891-a795-30c75f0f077c","name":"update_calendar","type":"n8n-nodes-base.googleCalendar","position":[1860,480],"parameters":{"eventId":"={{ $json.eventId }}","calendar":{"__rl":true,"mode":"list","value":"your-calendar@gmail.com","cachedResultName":"your-calendar@gmail.com"},"operation":"update","updateFields":{"end":"={{ $json.endDate }}","start":"={{ $json.startDate }}"}},"credentials":{"googleCalendarOAuth2Api":{"id":"google-api-id","name":"Google Calendar account"}},"typeVersion":1.3},{"id":"933163a6-5597-48da-95de-7067dd55ad84","name":"get_events_in_gap_time","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[520,240],"parameters":{"name":"get_events_in_gap_time","workflowId":{"__rl":true,"mode":"list","value":"aiKrExd0rAxJO6xi","cachedResultName":"MCP_google_calendar"},"description":"Use this tool to get event data in a gap of time. but if you have just validate the availibity of the time use \"validate_busy_time\" tool this is tool is to get data","workflowInputs":{"value":{"endDate":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('endDate', ``, 'string') }}","eventId":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('eventId', ``, 'string') }}","timeZone":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('timeZone', ``, 'string') }}","operation":"getEventData","startDate":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('startDate', ``, 'string') }}"},"schema":[{"id":"operation","type":"string","display":true,"required":false,"displayName":"operation","defaultMatch":false,"canBeUsedToMatch":true},{"id":"startDate","type":"string","display":true,"required":false,"displayName":"startDate","defaultMatch":false,"canBeUsedToMatch":true},{"id":"endDate","type":"string","display":true,"required":false,"displayName":"endDate","defaultMatch":false,"canBeUsedToMatch":true},{"id":"eventId","type":"string","display":true,"required":false,"displayName":"eventId","defaultMatch":false,"canBeUsedToMatch":true},{"id":"timeZone","type":"string","display":true,"removed":false,"required":false,"displayName":"timeZone","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false}},"typeVersion":2.1},{"id":"01c9435e-0258-4048-a3ad-cf84424fad6c","name":"map_data","type":"n8n-nodes-base.set","position":[1240,220],"parameters":{"mode":"raw","options":{},"jsonOutput":"={\n  \"operation\": \"{{ $json.operation }}\",\n  \"startDate\": \"{{ DateTime.fromISO($json.startDate).setZone($json.timeZone).toISO() }}\",\n  \"endDate\": \"{{ DateTime.fromISO($json.endDate).setZone($json.timeZone).toISO() }}\",\n  \"eventId\": \"{{ $json.eventId }}\",\n  \"timeZone\": \"{{ $json.timeZone }}\"\n}\n"},"typeVersion":3.4},{"id":"0e3a8817-7485-499c-9692-7b920bb34b3f","name":"response_data_get_data","type":"n8n-nodes-base.set","position":[2080,700],"parameters":{"mode":"raw","options":{},"jsonOutput":"={\n  \"isAvailableTime\":{{$json.values().length === 0}},\n\"eventData\":{\nid:\"{{ $json.id }}\"\n}\n}\n"},"typeVersion":3.4}],"active":true,"pinData":{"When Executed by Another Workflow":[{"json":{"endDate":"2025-05-17T20:00:00Z","eventId":null,"timeZone":"America/Argentina/Buenos_Aires","operation":"getEventData","startDate":"2025-05-17T19:00:00Z"}}]},"settings":{"executionOrder":"v1"},"versionId":"fbb67adf-7d52-4b42-8b61-a3c01470a1f9","connections":{"If":{"main":[[{"node":"create_event","type":"main","index":0}],[{"node":"Stop and Error","type":"main","index":0}]]},"map_data":{"main":[[{"node":"Operation","type":"main","index":0}]]},"Operation":{"main":[[{"node":"validate_availability_event","type":"main","index":0}],[{"node":"delete_event1","type":"main","index":0}],[{"node":"check_availability_to_create","type":"main","index":0}],[{"node":"update_calendar","type":"main","index":0}],[{"node":"get_event_in_time_gap","type":"main","index":0}]]},"delete_event":{"ai_tool":[[{"node":"MCP Server Trigger","type":"ai_tool","index":0}]]},"update_event":{"ai_tool":[[{"node":"MCP Server Trigger","type":"ai_tool","index":0}]]},"create_new_event":{"ai_tool":[[{"node":"MCP Server Trigger","type":"ai_tool","index":0}]]},"validate_busy_time":{"ai_tool":[[{"node":"MCP Server Trigger","type":"ai_tool","index":0}]]},"get_event_in_time_gap":{"main":[[{"node":"response_data_get_data","type":"main","index":0}]]},"get_events_in_gap_time":{"ai_tool":[[{"node":"MCP Server Trigger","type":"ai_tool","index":0}]]},"validate_availability_event":{"main":[[{"node":"Edit Fields","type":"main","index":0}]]},"check_availability_to_create":{"main":[[{"node":"If","type":"main","index":0}]]},"When Executed by Another Workflow":{"main":[[{"node":"map_data","type":"main","index":0}]]}}}


name: Translate & Repost Twitter Threads in Multiple Languages with OpenAI
author_name: enes cingoz
author_username: ecingoz
categories: []
created_at: 2025-05-19T21:51:46.647Z
updated_at: 2025-05-19T21:51:46.647Z
url: https://n8n.io/workflows/4233
scraped_at: 2025-06-19 22:49:20
description:
  Twitter Thread (Flood) Translator & Poster

  What it does

  Thread Extraction:** Automatically detects and extracts all tweets from a provided Twitter thread (flood) link.
  Translation:** Translates each extracted tweet into your target language using OpenAI.
  Rewriting:** Rewrites each translated tweet to maintain the original meaning while improving clarity or style.
  Automated Posting:** Posts the rewritten tweets as a new thread on Twitter using twitterapi.io, preserving the original thread structure.

  How it works

  Accepts a Twitter thread (flood) link as input.
  Extracts all tweets from the thread in their original order.
  Each tweet is sent to OpenAI for translation into your desired language.
  The translated tweets are then rewritten for clarity and natural flow, while keeping the original meaning intact.
  The processed tweets are automatically posted as a new thread on your Twitter account via twitterapi.io.

  Setup Steps

  Create a Notion Database:  
     Set up a database page in Notion to store and manage your Twitter links and workflow data.
  Configure Notion Integration:  
     Add the created database page ID to the Notion nodes in your workflow.
  Set Twitter API Credentials:  
     Add your twitterapi.io API key to the relevant nodes.
  Add Twitter Account Details:  
     Enter your Twitter account username/email and password for authentication.
  Set Up OpenAI Credentials:  
     Provide your OpenAI API credentials to enable translation and rewriting.
  Subworkflow Integration:  
     Create a separate workflow for subworkflow logic and call it using the Execute Workflow node for modular automation.
  Set Desired Language & Thread Link:  
     Change the target language and Twitter thread (flood) link directly in the Manual Trigger node to customize each run.

  Benefits

  Ultra Low Cost:* *Total cost for a 15-tweet thread (flood) is just $0.016 USD* ($0.015 for twitterapi.io + $0.001 for OpenAI API). *(Actual cost may vary depending on the density of tweets in the thread.)
  End-to-End Automation:** Go from thread extraction to translation, rewriting, and reposting-all in one workflow.
  Multilingual Support:** Effortlessly translate and republish Twitter threads in any supported language.



  &gt; Note: Detailed configuration instructions and node explanations are included as sticky notes within the workflow canvas.

  Ideal for:  
  Content creators looking to reach new audiences by translating and republishing Twitter threads  
  Social media managers automating multilingual content workflows  
  Anyone wanting to streamline the process of thread extraction, translation, and posting

  Notes

  This workflow is not able to post images or videos to Twitter-it handles text-only threads.

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

workflow_json:
  {"id":"IBfjTnWypBRXCPvj","meta":{"instanceId":"98efd8f034313c65d85cf0927667bbf93252214bae7096a8dd3c1d18b0b96a02"},"name":"Twitter Thread (Flood) Translator & Poster","tags":[],"nodes":[{"id":"72df7ac0-9e65-41f2-bdf4-180f3ed6f1e9","name":"When clicking ‘Test workflow’","type":"n8n-nodes-base.manualTrigger","position":[920,-20],"parameters":{},"typeVersion":1},{"id":"5716837e-9709-4ec8-b41d-1f17c4fe1f4b","name":"Execute Workflow","type":"n8n-nodes-base.executeWorkflow","position":[1440,-20],"parameters":{},"typeVersion":1.2},{"id":"aa0f1d55-f9fc-4932-8109-fdbc3aaf36ea","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[1360,-180],"parameters":{"content":""},"typeVersion":1},{"id":"a54bc9c6-3120-49eb-b779-e3af80f5813a","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[1060,-180],"parameters":{"content":""},"typeVersion":1},{"id":"5fdb1ec4-315f-4361-a069-5e9e25dc3934","name":"config","type":"n8n-nodes-base.code","position":[1140,-20],"parameters":{},"typeVersion":2},{"id":"174bc61b-1fb1-4772-bcf6-d0b223f0a57b","name":"Translator_openai","type":"@n8n/n8n-nodes-langchain.agent","position":[2140,160],"parameters":{},"typeVersion":1.7},{"id":"083b6c06-1944-49a9-bdc2-750810c2861d","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[2220,400],"parameters":{},"typeVersion":1.2},{"id":"88a7b3be-1128-4e46-a6fa-b0872b5970db","name":"Rewriter","type":"@n8n/n8n-nodes-langchain.agent","position":[2520,160],"parameters":{},"typeVersion":1.8},{"id":"59ca4c7a-2c45-4abc-b118-43303f830c8f","name":"Sticky Note10","type":"n8n-nodes-base.stickyNote","position":[2480,100],"parameters":{"content":""},"typeVersion":1},{"id":"ec8bcd97-54a5-45aa-ac2c-3306f428e0f1","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[2080,100],"parameters":{"content":""},"typeVersion":1},{"id":"4e9f7da0-bd52-4de4-aad1-3f917d3dfda5","name":"Login Twitter","type":"n8n-nodes-base.httpRequest","position":[3560,640],"parameters":{},"typeVersion":4.2},{"id":"3ee576d3-e73e-4c1f-9fa9-446e6dc1da53","name":"Wait for 2fa code","type":"n8n-nodes-base.wait","position":[4060,640],"webhookId":"edf03471-76bd-4d9a-8c3e-7c18b0e4f039","parameters":{},"typeVersion":1.1},{"id":"d26e7f0f-8763-4c0d-ab0e-2e83816d0025","name":"Login Twitter with 2fa","type":"n8n-nodes-base.httpRequest","position":[4300,640],"parameters":{},"typeVersion":4.2},{"id":"7e92ad78-4d8f-45e4-942b-8613bc93d101","name":"Check login","type":"n8n-nodes-base.if","position":[4520,640],"parameters":{},"typeVersion":2.2},{"id":"335637cf-cea6-4bb2-a2c8-16cf11a1525d","name":"Check session data","type":"n8n-nodes-base.if","position":[3160,540],"parameters":{},"typeVersion":2.2},{"id":"48c94aa1-8077-4c08-ad42-4fa70bca37d0","name":"Set first tweet id and session","type":"n8n-nodes-base.set","position":[5180,620],"parameters":{},"typeVersion":3.4},{"id":"3a768947-083a-493e-a080-b5daa7f7c2b9","name":"Post first tweet","type":"n8n-nodes-base.httpRequest","position":[5440,620],"parameters":{},"typeVersion":4.2},{"id":"54f189cc-0dcb-4c9f-8324-0c671db903ca","name":"Check posting","type":"n8n-nodes-base.if","position":[5660,620],"parameters":{},"typeVersion":2.2},{"id":"c5e56b2b-0250-4fb2-9662-1398d139b83e","name":"Authorization Error","type":"n8n-nodes-base.if","position":[5880,760],"parameters":{},"typeVersion":2.2},{"id":"96149e63-37be-4148-8b66-d84ebc74715f","name":"Update twitter session","type":"n8n-nodes-base.notion","position":[4800,600],"parameters":{},"typeVersion":2.2},{"id":"c8ff5ba5-a9a3-46f6-847b-0d6521c6fd1f","name":"Get twitter session","type":"n8n-nodes-base.notion","position":[2940,540],"parameters":{},"typeVersion":2.2},{"id":"c30a3783-46f4-4aea-bf3b-6bae0feaea03","name":"login_2fa error","type":"n8n-nodes-base.if","position":[3880,920],"parameters":{},"typeVersion":2.2},{"id":"d34a6dbb-1a42-489f-8778-06f1493c329a","name":"Check login status","type":"n8n-nodes-base.if","position":[3720,640],"parameters":{},"typeVersion":2.2},{"id":"9cab075a-55f0-4754-9015-3c22b65caee0","name":"First tweet or thread","type":"n8n-nodes-base.if","position":[4840,200],"parameters":{},"typeVersion":2.2},{"id":"8234f0ee-7184-4aea-ba3a-0197dca248e2","name":"Set tweet infos","type":"n8n-nodes-base.set","position":[5160,-240],"parameters":{},"typeVersion":3.4},{"id":"64257a36-2fd5-48fa-ad94-3e3bee2fdbbc","name":"Check posting1","type":"n8n-nodes-base.if","position":[5680,-240],"parameters":{},"typeVersion":2.2},{"id":"d5788735-40be-46cc-8aa9-eba78cce3bb9","name":"Authorization Error1","type":"n8n-nodes-base.if","position":[5820,-80],"parameters":{},"typeVersion":2.2},{"id":"8c0a7f58-51af-44fe-acb9-a3d5048b226b","name":"Post reply tweet","type":"n8n-nodes-base.httpRequest","position":[5420,-240],"parameters":{},"typeVersion":4.2},{"id":"e6b16945-b9d2-43cb-a6a2-d82a892fb185","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[2880,480],"parameters":{"content":""},"typeVersion":1},{"id":"d9712b4b-c340-4e8c-a447-7aefe0315490","name":"set_iteration_outputs","type":"n8n-nodes-base.code","position":[6220,200],"parameters":{},"typeVersion":2},{"id":"e90d235e-ca52-44f7-ae11-80ebf8871f32","name":"MAIN_LOOP","type":"n8n-nodes-base.splitInBatches","position":[1900,-20],"parameters":{},"typeVersion":3},{"id":"952d5f9d-9db9-42ff-a00c-166bc2023c3a","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[5100,540],"parameters":{"content":""},"typeVersion":1},{"id":"44e8e0ea-d063-4a58-9c64-4f38c9af3efe","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[5100,-320],"parameters":{"content":""},"typeVersion":1},{"id":"c299b7bf-ebff-4908-8020-3d3707406bcc","name":"Extract tweets list","type":"n8n-nodes-base.code","position":[1660,-20],"parameters":{},"typeVersion":2},{"id":"aec16371-e942-4be9-9b00-809ca0d54e84","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[1060,-360],"parameters":{"content":""},"typeVersion":1},{"id":"4f42b137-0150-44d1-b628-b5f945d8a259","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[1360,-360],"parameters":{"content":""},"typeVersion":1},{"id":"9b936b1c-f594-453e-9a43-be8e655debd1","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[2080,-100],"parameters":{"content":""},"typeVersion":1},{"id":"2cac2fc1-d3ff-42c2-ba1a-f65daf439ea5","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[2480,-100],"parameters":{"content":""},"typeVersion":1},{"id":"dd6dc5c9-5950-4e8e-8810-941ee1e3fa4c","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[2880,1080],"parameters":{"content":""},"typeVersion":1},{"id":"1837647c-8619-41b3-8635-18ba646d6bd6","name":"Send error message","type":"n8n-nodes-base.noOp","position":[4760,920],"parameters":{},"typeVersion":1},{"id":"3828dc13-6ed4-4ca8-a1fc-1e26700a71fb","name":"Sticky Note12","type":"n8n-nodes-base.stickyNote","position":[5100,1020],"parameters":{"content":""},"typeVersion":1},{"id":"9637b6f0-5792-42ff-adf1-96f96a8ed389","name":"Sticky Note13","type":"n8n-nodes-base.stickyNote","position":[5100,-560],"parameters":{"content":""},"typeVersion":1},{"id":"9aa336df-7dec-4eb9-a3f7-5f1844497147","name":"DONE","type":"n8n-nodes-base.noOp","position":[2100,-280],"parameters":{},"typeVersion":1},{"id":"99d86957-c9f7-4f5c-a7c9-8d8cb4bfd78f","name":"Merge first tweet and others","type":"n8n-nodes-base.merge","position":[2940,2120],"parameters":{},"typeVersion":3.1},{"id":"69946d5e-1730-4b33-98f0-474507c7740b","name":"When Executed by Another Workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[1160,2120],"parameters":{},"typeVersion":1.1},{"id":"2c8025d2-fade-45bf-b5bf-184766b1ec79","name":"No Operation, do nothing","type":"n8n-nodes-base.noOp","position":[3400,2120],"parameters":{},"typeVersion":1},{"id":"15e79dd7-cce8-4c22-a6e7-b0326218147b","name":"Extract Tweet ID and Username","type":"n8n-nodes-base.function","position":[1520,2240],"parameters":{},"typeVersion":1},{"id":"5d476c98-feb5-4c4e-97f5-64e23798432c","name":"Get first tweet","type":"n8n-nodes-base.httpRequest","position":[1740,2020],"parameters":{},"typeVersion":4.2},{"id":"81a08de6-85d6-4f57-9602-7484d696b431","name":"Extract Conversation and Author ID","type":"n8n-nodes-base.function","position":[1960,2120],"parameters":{},"typeVersion":1},{"id":"efe5470a-618b-4c19-8da3-a49cfeb4aea0","name":"Merge all tweet infos","type":"n8n-nodes-base.merge","position":[2180,2240],"parameters":{},"typeVersion":3.1},{"id":"2b02d409-d36d-4c13-9380-0e7e24f35e37","name":"Get Tweet Replies","type":"n8n-nodes-base.httpRequest","onError":"continueRegularOutput","position":[2400,2240],"parameters":{},"typeVersion":4.2},{"id":"833c0d80-fa81-4db9-a720-cf4626445c46","name":"Fetch tweets which are connected to first tweet","type":"n8n-nodes-base.code","position":[2620,2240],"parameters":{},"typeVersion":2},{"id":"90b985e7-8e14-4801-a315-e52e52d57cac","name":"Filter empty ones","type":"n8n-nodes-base.filter","position":[3160,2120],"parameters":{},"typeVersion":2.2},{"id":"da5309da-bc63-4157-b790-102728307f4e","name":"Sticky Note14","type":"n8n-nodes-base.stickyNote","position":[1460,1960],"parameters":{"content":""},"typeVersion":1},{"id":"b6a229b1-a4db-4d32-a46c-5dda58885597","name":"Sticky Note15","type":"n8n-nodes-base.stickyNote","position":[1920,1960],"parameters":{"content":""},"typeVersion":1},{"id":"e0919f2e-6771-4df3-9d72-88333ef2a717","name":"Sticky Note16","type":"n8n-nodes-base.stickyNote","position":[2780,1960],"parameters":{"content":""},"typeVersion":1},{"id":"c8a1b8e9-23b6-4561-aa55-6471e47f9703","name":"Sticky Note17","type":"n8n-nodes-base.stickyNote","position":[1460,1800],"parameters":{"content":""},"typeVersion":1},{"id":"fe98b5de-7600-47fc-8b6f-4487646d7c35","name":"Sticky Note18","type":"n8n-nodes-base.stickyNote","position":[1920,1800],"parameters":{"content":""},"typeVersion":1},{"id":"c468ca50-25c1-4467-9065-46a1a69dd253","name":"Sticky Note19","type":"n8n-nodes-base.stickyNote","position":[2780,1800],"parameters":{"content":""},"typeVersion":1},{"id":"22d1bd3b-ce0b-455f-b750-321f322be192","name":"Sticky Note20","type":"n8n-nodes-base.stickyNote","position":[1000,1800],"parameters":{"content":""},"typeVersion":1},{"id":"2bd70d81-4345-4f4b-99df-a030269a6168","name":"Sticky Note21","type":"n8n-nodes-base.stickyNote","position":[1000,1660],"parameters":{"content":""},"typeVersion":1},{"id":"bf8de65a-d7b2-42ea-89e9-d89c3bae92a3","name":"REMOVE THIS NODE","type":"n8n-nodes-base.twitter","position":[2320,-280],"parameters":{},"typeVersion":2}],"active":false,"pinData":{"When clicking ‘Test workflow’":[{"json":{"language":"German","tweet_url":""}}]},"settings":{"timezone":"Europe/London","callerPolicy":"workflowsFromSameOwner","executionOrder":"v1"},"versionId":"156bf779-c9ab-4cae-b275-cdf7dd5b57e3","connections":{"DONE":{"main":[[{"node":"REMOVE THIS NODE","type":"main","index":0}]]},"config":{"main":[[{"node":"Execute Workflow","type":"main","index":0}]]},"Rewriter":{"main":[[{"node":"Get twitter session","type":"main","index":0}]]},"MAIN_LOOP":{"main":[[{"node":"DONE","type":"main","index":0}],[{"node":"Translator_openai","type":"main","index":0}]]},"Check login":{"main":[[{"node":"Update twitter session","type":"main","index":0}],[{"node":"Send error message","type":"main","index":0}]]},"Check posting":{"main":[[{"node":"set_iteration_outputs","type":"main","index":0}],[{"node":"Authorization Error","type":"main","index":0}]]},"Login Twitter":{"main":[[{"node":"Check login status","type":"main","index":0}]]},"Check posting1":{"main":[[{"node":"set_iteration_outputs","type":"main","index":0}],[{"node":"Authorization Error1","type":"main","index":0}]]},"Get first tweet":{"main":[[{"node":"Extract Conversation and Author ID","type":"main","index":0},{"node":"Merge first tweet and others","type":"main","index":0}]]},"Set tweet infos":{"main":[[{"node":"Post reply tweet","type":"main","index":0}]]},"login_2fa error":{"main":[[{"node":"Login Twitter with 2fa","type":"main","index":0}],[{"node":"Wait for 2fa code","type":"main","index":0}]]},"Execute Workflow":{"main":[[{"node":"Extract tweets list","type":"main","index":0}]]},"Post first tweet":{"main":[[{"node":"Check posting","type":"main","index":0}]]},"Post reply tweet":{"main":[[{"node":"Check posting1","type":"main","index":0}]]},"Filter empty ones":{"main":[[{"node":"No Operation, do nothing","type":"main","index":0}]]},"Get Tweet Replies":{"main":[[{"node":"Fetch tweets which are connected to first tweet","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Translator_openai","type":"ai_languageModel","index":0},{"node":"Rewriter","type":"ai_languageModel","index":0}]]},"Translator_openai":{"main":[[{"node":"Rewriter","type":"main","index":0}]]},"Wait for 2fa code":{"main":[[{"node":"Login Twitter with 2fa","type":"main","index":0}]]},"Check login status":{"main":[[{"node":"Get twitter session","type":"main","index":0}],[{"node":"login_2fa error","type":"main","index":0}]]},"Check session data":{"main":[[{"node":"First tweet or thread","type":"main","index":0}],[{"node":"Login Twitter","type":"main","index":0}]]},"Authorization Error":{"main":[[{"node":"Login Twitter","type":"main","index":0}]]},"Extract tweets list":{"main":[[{"node":"MAIN_LOOP","type":"main","index":0}]]},"Get twitter session":{"main":[[{"node":"Check session data","type":"main","index":0}]]},"Authorization Error1":{"main":[[],[{"node":"Get twitter session","type":"main","index":0}]]},"First tweet or thread":{"main":[[{"node":"Set tweet infos","type":"main","index":0}],[{"node":"Set first tweet id and session","type":"main","index":0}]]},"Merge all tweet infos":{"main":[[{"node":"Get Tweet Replies","type":"main","index":0}]]},"set_iteration_outputs":{"main":[[{"node":"MAIN_LOOP","type":"main","index":0}]]},"Login Twitter with 2fa":{"main":[[{"node":"Check login","type":"main","index":0}]]},"Update twitter session":{"main":[[{"node":"Get twitter session","type":"main","index":0}]]},"Merge first tweet and others":{"main":[[{"node":"Filter empty ones","type":"main","index":0}]]},"Extract Tweet ID and Username":{"main":[[{"node":"Get first tweet","type":"main","index":0},{"node":"Merge all tweet infos","type":"main","index":1}]]},"Set first tweet id and session":{"main":[[{"node":"Post first tweet","type":"main","index":0}]]},"When Executed by Another Workflow":{"main":[[{"node":"Extract Tweet ID and Username","type":"main","index":0}]]},"When clicking ‘Test workflow’":{"main":[[{"node":"config","type":"main","index":0}]]},"Extract Conversation and Author ID":{"main":[[{"node":"Merge all tweet infos","type":"main","index":0}]]},"Fetch tweets which are connected to first tweet":{"main":[[{"node":"Merge first tweet and others","type":"main","index":1}]]}}}


name: Monitor and Track brand Sentiment on Facebook Groups with Bright data
author_name: Imperol
author_username: imperolq
categories: []
created_at: 2025-05-20T05:59:11.051Z
updated_at: 2025-05-20T05:59:11.051Z
url: https://n8n.io/workflows/4235
scraped_at: 2025-06-19 22:49:58
description:
  Workflow documentation updated on  21 May 2025
   
  This workflow keeps track of your brand mentions across different Facebook groups and provides an analysis of  the posts as positive, negative or neutral and updates this to Googe sheets for further analysis

  This is useful and relevants for brands looking to keep track of what people are saying about their brands and guage the customer satisfaction or disatisfaction based on what they are talking about

  Who is this template for?
  This workflow is for you if You

  Need to keep track of your brand sentiments across different niche facebook groups 
  Own a saas and want to monitor it across different local facebook Groups  
  Are looking to do some competitor research to understand what others dont like about their products
  Are testing the market on different market offerings and products to get best results
  Are looking for sources other that review sites for product, software or service reviews
  Need to keep track of your brand sentiments across different niche facebook groups
  Are starting on market research and would like to get insights from differnt facebook groups on app usage, strngths weaknesses, features etc

  How it works
  You will set the desired schedule by which to monitor the groups
  This gets the brand names and facebook Groups to monitor.

  Setup Steps
  Before you begin
  You will need access to a Bright Data API to run this workflows
  Make a copy of the sheet below and add the urls for the facebook groups to scrap and the brand names you wish to monitor.


  Import the workflow json to your canvas
  Make a copy of this Google sheet to get started easily
  Set your APi key in the Map out the Google sheet to your tables
  You can use/update the current AI models to differnt models eg Gemini or anthropic
  Run the workflow

  Setup B
  Bright Data provides an option to receive the results on an external webhook via a POST call. This can be collected via the 

nodes_used:
  ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest","@n8n/n8n-nodes-langchain.sentimentAnalysis","@n8n/n8n-nodes-langchain.informationExtractor","@n8n/n8n-nodes-langchain.lmChatOpenRouter"]

workflow_json:
  {"meta":{"instanceId":"","templateCredsSetupCompleted":true},"nodes":[{"id":"fe514019-3f38-47ae-9a3f-64eb77f2f3ca","name":"facebook groups","type":"n8n-nodes-base.httpRequest","position":[680,-60],"parameters":{"url":"https://api.brightdata.com/datasets/v3/trigger","method":"POST","options":{},"jsonBody":"={{ \n  $json.url.map(u => ({\n    url: u,\n    start_date: $now.format('yyyy-MM-dd'),\n    end_date: \"\"\n  }))\n}}","sendBody":true,"sendQuery":true,"sendHeaders":true,"specifyBody":"json","queryParameters":{"parameters":[{"name":"dataset_id","value":"gd_lz11l67o2cb3r0lkj3"},{"name":"endpoint","value":"={{ $('Set up KEYS').first().json.endpoint }}"},{"name":"format","value":"json"},{"name":"uncompressed_webhook","value":"true"},{"name":"include_errors","value":"true"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"=Bearer {{ $('Set up KEYS').first().json.API }}"}]}},"typeVersion":4.2},{"id":"5beb7eb8-c835-4a8e-a997-5bdae466e3ee","name":"get progress","type":"n8n-nodes-base.httpRequest","position":[860,-60],"parameters":{"url":"=https://api.brightdata.com/datasets/v3/progress/{{ $json.snapshot_id }}","options":{},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"Authorization","value":"=Bearer {{ $('Set up KEYS').first().json.API }}"}]}},"typeVersion":4.2},{"id":"72e4d325-19fb-45e1-a2f0-c125de4886b3","name":"Switch","type":"n8n-nodes-base.switch","position":[1000,-60],"parameters":{"rules":{"values":[{"outputKey":"ready","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"66155e3c-e3de-4f3f-9401-1e477bcc19d8","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"ready"}]},"renameOutput":true},{"outputKey":"running","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"ac86d07d-dfa3-495d-bc5e-cf10dcbe3e82","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"running"}]},"renameOutput":true}]},"options":{}},"typeVersion":3.2},{"id":"4708eb72-1432-4519-97d8-fce6d85a4553","name":"Wait","type":"n8n-nodes-base.wait","position":[1180,140],"webhookId":"b4565427-d217-4157-92da-f38b9c7834b4","parameters":{},"typeVersion":1.1},{"id":"8d10b6fd-80b8-4038-ae96-7bc895241b4b","name":"Get data","type":"n8n-nodes-base.httpRequest","position":[1180,-80],"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 {{ $('Set up KEYS').first().json.API }}"}]}},"typeVersion":4.2},{"id":"589c7d42-15b0-4065-afdf-546e0740da01","name":"Limit","type":"n8n-nodes-base.limit","position":[1340,-80],"parameters":{"maxItems":20},"typeVersion":1},{"id":"94d1760a-197d-4fcb-912f-1f2218649859","name":"Sentiment Analysis","type":"@n8n/n8n-nodes-langchain.sentimentAnalysis","position":[1640,-80],"parameters":{"options":{"categories":"Positive, Negative, Neutral","enableAutoFixing":true,"systemPromptTemplate":"You are highly intelligent and accurate sentiment analyzer. Analyze the sentiment of the provided text. Categorize it into one of the following: {categories}. Use the provided formatting instructions. Only output the JSON.","includeDetailedResults":true},"inputText":"={{ $json.content }}"},"typeVersion":1},{"id":"c66139b0-7113-43aa-9549-724f45bd6cc3","name":"Filter brand name","type":"n8n-nodes-base.filter","position":[1480,-80],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"or","conditions":[{"id":"ddc26838-8e02-4aeb-8bd6-02e854cb0455","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ \n  $('Aggregate brand names').first().json['Brand names'].some(\n    b => $json.content.toLowerCase().includes(b.toLowerCase())\n  )\n}}","rightValue":"={{ $('Aggregate brand names').first().json['Brand names'] }}"}]}},"typeVersion":2.2},{"id":"a57b4efe-75ff-48b4-a57f-58908bce7096","name":"OpenRouter Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[1660,180],"parameters":{"options":{}},"credentials":{"openRouterApi":{"id":"DjsDsrPkJRSfqINF","name":"OpenRouter account"}},"typeVersion":1},{"id":"eb2a9998-6b7e-4240-82bb-5672c6204142","name":"Merge","type":"n8n-nodes-base.merge","position":[1960,-80],"parameters":{"numberInputs":3},"typeVersion":3.1},{"id":"1f234f27-e474-4e46-b09d-48b279568ba3","name":"Set up KEYS","type":"n8n-nodes-base.set","position":[-160,-60],"parameters":{"options":{},"assignments":{"assignments":[{"id":"7ba2241b-3a1f-42d7-9770-2ed7a3f13a67","name":"endpoint","type":"string","value":"={your POST webhook url}"},{"id":"7b78e955-2f02-47f0-9903-fa0f27c3e43e","name":"API","type":"string","value":"={brightdata api}"}]}},"typeVersion":3.4},{"id":"3b405223-0e8b-45fd-a3de-c7f1956c1a1e","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-340,-60],"parameters":{"rule":{"interval":[{"triggerAtHour":9}]}},"typeVersion":1.2},{"id":"b5158aa4-112d-4443-9b3f-c4a82d62788e","name":"Split Out","type":"n8n-nodes-base.splitOut","position":[1320,-260],"parameters":{"options":{},"fieldToSplitOut":"url"},"typeVersion":1},{"id":"f13b255c-5d25-4eac-bc7e-e8948d0490d6","name":"set urls","type":"n8n-nodes-base.set","position":[1160,-260],"parameters":{"options":{},"assignments":{"assignments":[{"id":"17d32287-0140-4cec-9132-1d3bec34de32","name":"url","type":"array","value":"={{ $('Aggregate group links').first().json.url }}"}]}},"typeVersion":3.4},{"id":"cfc4f837-f4dc-471e-9958-f47375eebfeb","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[500,-500],"parameters":{"width":380,"height":280,"content":"## Social Media Sentiment Analysis Pipeline\n\nThis workflow keeps track of our brand mentions across different groups and provides an analysis of  the posts as positive, negative or neutral \n\nMake a copy of this [Google sheet](https://docs.google.com/spreadsheets/d/1TXF_xLPF7XJJakoWB5Ix-tTduvX3GRxocJcp6DA-U_A/edit?usp=sharing) to get started easily"},"typeVersion":1},{"id":"08fa5532-7c45-4449-a5c6-99abe0daef25","name":"Information Extractor","type":"@n8n/n8n-nodes-langchain.informationExtractor","position":[2140,-80],"parameters":{"text":"={{ $json.content }}","options":{"systemPromptTemplate":"=Summarize the post and understand what they are asking about our brand name {{ $('Set up KEYS').first().json['brand name'] }}\n\nYour task is to\n\n- Provide insights on what the user is asking\nIdentify the segment\n- Suggest a posible category for the post eg Technical Support, Bug, Missing features, Goog review, etc to align with what the users are talking about"},"schemaType":"fromJson","jsonSchemaExample":"{\n\t\"Insight\": \"\",\n    \"Sentiment\": \"\",\n    \"Category\": \"\"\n}"},"typeVersion":1},{"id":"7de252d0-d8cb-4b4e-adb7-619e783c8534","name":"OpenRouter Chat Model1","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[2180,120],"parameters":{"options":{}},"credentials":{"openRouterApi":{"id":"DjsDsrPkJRSfqINF","name":"OpenRouter account"}},"typeVersion":1},{"id":"4f37699e-806f-4a84-8780-c8792992960f","name":"pull group results","type":"n8n-nodes-base.set","position":[2460,-80],"parameters":{"mode":"raw","options":{},"jsonOutput":"={{ $('Filter brand name').item.json}}"},"typeVersion":3.4},{"id":"3bc5d96e-0dc1-4e44-9229-a25dd43ae12c","name":"insights and sentiments","type":"n8n-nodes-base.set","position":[2640,-80],"parameters":{"options":{},"assignments":{"assignments":[{"id":"d0716947-0432-47f6-a389-a10fe832f9a1","name":"url","type":"string","value":"={{ $json.url }}"},{"id":"c7002730-73ef-44b7-b5c6-635f09baafab","name":"post_id","type":"string","value":"={{ $json.post_id }}"},{"id":"fe133603-776c-4c8f-bab4-4d184051d26c","name":"user_url","type":"string","value":"={{ $json.user_url }}"},{"id":"fc375461-c19f-406f-9cb1-a2928835643c","name":"user_username_raw","type":"string","value":"={{ $json.user_username_raw }}"},{"id":"0361d704-a24e-4337-94b6-5d5af8715d6f","name":"content","type":"string","value":"={{ $json.content }}"},{"id":"b8e1e54e-b15f-4d79-af56-5514127cc4cb","name":"date_posted","type":"string","value":"={{ $json.date_posted }}"},{"id":"877d3101-d16b-40c8-bb74-f46e86a87b85","name":"hashtags","type":"array","value":"={{ $json.hashtags }}"},{"id":"f1db3944-e03e-4273-98a5-078f597a6da1","name":"num_comments","type":"number","value":"={{ $json.num_comments }}"},{"id":"bf02b664-37bf-41a6-9492-b2399ebed1f1","name":"num_shares","type":"number","value":"={{ $json.num_shares }}"},{"id":"892177fe-da75-42b3-bbeb-4df2d0aac35d","name":"group_name","type":"string","value":"={{ $json.group_name }}"},{"id":"58f57e5e-7a1f-4598-895a-123506fb08af","name":"group_id","type":"string","value":"={{ $json.group_id }}"},{"id":"6255a67f-e4e4-44e0-b4f1-0db5298d45fa","name":"group_url","type":"string","value":"={{ $json.group_url }}"},{"id":"9c754a19-d051-4884-831d-45b9763c43fe","name":"group_members","type":"number","value":"={{ $json.group_members }}"},{"id":"f0a352c9-6dbe-480e-aaf5-eeac342a8774","name":"post_image","type":"string","value":"={{ $json.post_image }}"},{"id":"0995058f-fa2f-4111-b8c7-e7d8bbcd3a8a","name":"confidence","type":"number","value":"={{ $('Merge').item.json.confidence }}"},{"id":"8aa35ee1-e957-4270-a939-63504564e78c","name":"sentimentAnalysis","type":"string","value":"={{ $('Merge').item.json.sentimentAnalysis }}"},{"id":"527c9c2e-f346-4666-878c-235ed6b7570c","name":"Insight","type":"string","value":"={{ $('Information Extractor').item.json.output.Insight }}"},{"id":"f5b9639f-257d-4209-9066-17095093ebe7","name":"Sentiment","type":"string","value":"={{ $('Information Extractor').item.json.output.Sentiment }}"},{"id":"03dea790-0998-49ec-8710-c2acf7848b23","name":"Category","type":"string","value":"={{ $('Information Extractor').item.json.output.Category }}"}]}},"typeVersion":3.4},{"id":"5fa75597-8ad5-4804-a9f8-9c519afcb70a","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[300,-120],"parameters":{"color":6,"width":300,"height":240,"content":"- 2.Get the links for the facebook groups we want to monitor"},"typeVersion":1},{"id":"47b7dd9f-6734-4701-a4ad-66b9dfc7be1a","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[620,-120],"parameters":{"color":4,"width":360,"height":240,"content":"- 3.Scrap with Bright Data API to get posts from the group and get progress"},"typeVersion":1},{"id":"fe891d81-95c6-4937-b4df-0bb73fc370d6","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1140,100],"parameters":{"color":3,"width":220,"content":"4.Wait for a few seconds if still running"},"typeVersion":1},{"id":"af2b3124-e27e-4e2f-ab11-39e2b94d8b0e","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[1140,-340],"parameters":{"color":5,"width":460,"height":420,"content":"5.Get results from the GROUPS and update the urls scraped\n\n6.Next we filter our our brand name from all these posts"},"typeVersion":1},{"id":"cc98cd10-a402-4e0a-a717-69629304bfef","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[1620,-140],"parameters":{"width":480,"height":200,"content":"7.We do a sentiment analysis to understand the posts and how our users are feeling"},"typeVersion":1},{"id":"609ed303-5049-487b-b746-0fd16475ab2a","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[2120,-120],"parameters":{"color":2,"width":300,"height":200,"content":"8.Extract the information from The post ie the summary, Category and Insights"},"typeVersion":1},{"id":"19c2a27c-ee58-4dc6-8378-cb6f700f92e0","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[-200,-140],"parameters":{"color":7,"width":170,"height":260,"content":"1. Set your bright data API and webhook endpoint to receive the results"},"typeVersion":1},{"id":"08746958-4785-41ef-9c16-fab76ef9c06f","name":"Get Brand names","type":"n8n-nodes-base.googleSheets","position":[0,-60],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"list","value":2091976134,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/1TXF_xLPF7XJJakoWB5Ix-tTduvX3GRxocJcp6DA-U_A/edit#gid=2091976134","cachedResultName":"Brand Name"},"documentId":{"__rl":true,"mode":"list","value":"1TXF_xLPF7XJJakoWB5Ix-tTduvX3GRxocJcp6DA-U_A","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1TXF_xLPF7XJJakoWB5Ix-tTduvX3GRxocJcp6DA-U_A/edit?usp=drivesdk","cachedResultName":"Facebook Groups research"}},"credentials":{"googleSheetsOAuth2Api":{"id":"ZAI2a6Qt80kX5a9s","name":"Google Sheets account✅ "}},"retryOnFail":true,"typeVersion":4.5},{"id":"b2d8f50e-f0a4-44b0-9003-3a698c5ee47e","name":"Aggregate brand names","type":"n8n-nodes-base.aggregate","position":[160,-60],"parameters":{"options":{},"fieldsToAggregate":{"fieldToAggregate":[{"fieldToAggregate":"Brand names"}]}},"typeVersion":1},{"id":"0e07b599-a8c1-4403-ab52-3c0797ed18fb","name":"Aggregate group links","type":"n8n-nodes-base.aggregate","position":[480,-60],"parameters":{"options":{},"fieldsToAggregate":{"fieldToAggregate":[{"fieldToAggregate":"url"}]}},"typeVersion":1},{"id":"9e34b53c-d2a5-4bf6-a61b-4002c0415e17","name":"Get links","type":"n8n-nodes-base.googleSheets","position":[320,-60],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"list","value":1190188291,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/1TXF_xLPF7XJJakoWB5Ix-tTduvX3GRxocJcp6DA-U_A/edit#gid=1190188291","cachedResultName":"Facebook group Links"},"documentId":{"__rl":true,"mode":"list","value":"1TXF_xLPF7XJJakoWB5Ix-tTduvX3GRxocJcp6DA-U_A","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1TXF_xLPF7XJJakoWB5Ix-tTduvX3GRxocJcp6DA-U_A/edit?usp=drivesdk","cachedResultName":"Facebook Groups research"}},"credentials":{"googleSheetsOAuth2Api":{"id":"ZAI2a6Qt80kX5a9s","name":"Google Sheets account✅ "}},"typeVersion":4.5},{"id":"11539ebf-7743-4d28-a437-e5bf48aea99d","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[2440,-120],"parameters":{"color":4,"width":560,"height":200,"content":"9.Format and update your results to Google Sheets for further analysis"},"typeVersion":1},{"id":"aa27a538-446e-49b9-8da6-58bd7aaa77f7","name":"Receive results","type":"n8n-nodes-base.webhook","position":[-300,-400],"webhookId":"ca835c61-fa01-4cd5-8919-2d3b0e62ac5a","parameters":{"path":"ca835c61-fa01-4cd5-8919-2d3b0e62ac5a","options":{},"httpMethod":"POST"},"typeVersion":2},{"id":"470b19a5-4df3-4566-81f0-49f819659a1b","name":"update last Scrap","type":"n8n-nodes-base.googleSheets","position":[1480,-260],"parameters":{"columns":{"value":{"url":"={{ $json.url }}","last Scraped":"={{ $now.format('yyyy-MM-dd t') }}"},"schema":[{"id":"url","type":"string","display":true,"removed":false,"required":false,"displayName":"url","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Group Neme","type":"string","display":true,"removed":true,"required":false,"displayName":"Group Neme","defaultMatch":false,"canBeUsedToMatch":true},{"id":"last Scraped","type":"string","display":true,"required":false,"displayName":"last Scraped","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":["url"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"update","sheetName":{"__rl":true,"mode":"list","value":1190188291,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/1TXF_xLPF7XJJakoWB5Ix-tTduvX3GRxocJcp6DA-U_A/edit#gid=1190188291","cachedResultName":"Facebook group Links"},"documentId":{"__rl":true,"mode":"list","value":"1TXF_xLPF7XJJakoWB5Ix-tTduvX3GRxocJcp6DA-U_A","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1TXF_xLPF7XJJakoWB5Ix-tTduvX3GRxocJcp6DA-U_A/edit?usp=drivesdk","cachedResultName":"Facebook Groups research"}},"credentials":{"googleSheetsOAuth2Api":{"id":"ZAI2a6Qt80kX5a9s","name":"Google Sheets account✅ "}},"typeVersion":4.5},{"id":"089fcff0-f34b-48e1-aebf-9b44344e3e7a","name":"Update sentiments","type":"n8n-nodes-base.googleSheets","onError":"continueRegularOutput","position":[2820,-80],"parameters":{"columns":{"value":{},"schema":[{"id":"url","type":"string","display":true,"removed":false,"required":false,"displayName":"url","defaultMatch":false,"canBeUsedToMatch":true},{"id":"post_id","type":"string","display":true,"removed":false,"required":false,"displayName":"post_id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"user_url","type":"string","display":true,"removed":false,"required":false,"displayName":"user_url","defaultMatch":false,"canBeUsedToMatch":true},{"id":"user_username_raw","type":"string","display":true,"removed":false,"required":false,"displayName":"user_username_raw","defaultMatch":false,"canBeUsedToMatch":true},{"id":"content","type":"string","display":true,"removed":false,"required":false,"displayName":"content","defaultMatch":false,"canBeUsedToMatch":true},{"id":"date_posted","type":"string","display":true,"removed":false,"required":false,"displayName":"date_posted","defaultMatch":false,"canBeUsedToMatch":true},{"id":"hashtags","type":"string","display":true,"removed":false,"required":false,"displayName":"hashtags","defaultMatch":false,"canBeUsedToMatch":true},{"id":"num_comments","type":"string","display":true,"removed":false,"required":false,"displayName":"num_comments","defaultMatch":false,"canBeUsedToMatch":true},{"id":"num_shares","type":"string","display":true,"removed":false,"required":false,"displayName":"num_shares","defaultMatch":false,"canBeUsedToMatch":true},{"id":"group_name","type":"string","display":true,"removed":false,"required":false,"displayName":"group_name","defaultMatch":false,"canBeUsedToMatch":true},{"id":"group_id","type":"string","display":true,"removed":false,"required":false,"displayName":"group_id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"group_url","type":"string","display":true,"removed":false,"required":false,"displayName":"group_url","defaultMatch":false,"canBeUsedToMatch":true},{"id":"group_members","type":"string","display":true,"removed":false,"required":false,"displayName":"group_members","defaultMatch":false,"canBeUsedToMatch":true},{"id":"post_image","type":"string","display":true,"removed":false,"required":false,"displayName":"post_image","defaultMatch":false,"canBeUsedToMatch":true},{"id":"sentimentAnalysis","type":"string","display":true,"removed":false,"required":false,"displayName":"sentimentAnalysis","defaultMatch":false,"canBeUsedToMatch":true},{"id":"confidence","type":"string","display":true,"removed":false,"required":false,"displayName":"confidence","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Insight","type":"string","display":true,"removed":false,"required":false,"displayName":"Insight","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Sentiment","type":"string","display":true,"removed":false,"required":false,"displayName":"Sentiment","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Category","type":"string","display":true,"removed":false,"required":false,"displayName":"Category","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"autoMapInputData","matchingColumns":["post_id"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"appendOrUpdate","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1TXF_xLPF7XJJakoWB5Ix-tTduvX3GRxocJcp6DA-U_A/edit#gid=0","cachedResultName":"Groups"},"documentId":{"__rl":true,"mode":"list","value":"1TXF_xLPF7XJJakoWB5Ix-tTduvX3GRxocJcp6DA-U_A","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1TXF_xLPF7XJJakoWB5Ix-tTduvX3GRxocJcp6DA-U_A/edit?usp=drivesdk","cachedResultName":"Facebook Groups research"}},"credentials":{"googleSheetsOAuth2Api":{"id":"ZAI2a6Qt80kX5a9s","name":"Google Sheets account✅ "}},"typeVersion":4.5},{"id":"5c8153b5-a24f-4897-ba0e-78b75f110ca0","name":"Split Out1","type":"n8n-nodes-base.splitOut","position":[-140,-400],"parameters":{"options":{},"fieldToSplitOut":"body"},"typeVersion":1},{"id":"126a57ac-5754-4732-8254-ba6b40f532b9","name":"Get Brand names1","type":"n8n-nodes-base.googleSheets","position":[40,-400],"parameters":{"columns":{"value":{},"schema":[],"mappingMode":"autoMapInputData","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"list","value":2110363951,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/1TXF_xLPF7XJJakoWB5Ix-tTduvX3GRxocJcp6DA-U_A/edit#gid=2110363951","cachedResultName":"All POSTS"},"documentId":{"__rl":true,"mode":"list","value":"1TXF_xLPF7XJJakoWB5Ix-tTduvX3GRxocJcp6DA-U_A","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1TXF_xLPF7XJJakoWB5Ix-tTduvX3GRxocJcp6DA-U_A/edit?usp=drivesdk","cachedResultName":"Facebook Groups research"}},"credentials":{"googleSheetsOAuth2Api":{"id":"ZAI2a6Qt80kX5a9s","name":"Google Sheets account✅ "}},"retryOnFail":true,"typeVersion":4.5},{"id":"8c8ce74c-ac51-4b31-a746-b3e346d8038a","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-360,-440],"parameters":{"width":660,"height":200,"content":"Receives the results from the Facebook group scrap and stores all the results to Google sheets"},"typeVersion":1}],"pinData":{},"connections":{"Wait":{"main":[[{"node":"get progress","type":"main","index":0}]]},"Limit":{"main":[[{"node":"Filter brand name","type":"main","index":0}]]},"Merge":{"main":[[{"node":"Information Extractor","type":"main","index":0}]]},"Switch":{"main":[[{"node":"Get data","type":"main","index":0},{"node":"set urls","type":"main","index":0}],[{"node":"Wait","type":"main","index":0}]]},"Get data":{"main":[[{"node":"Limit","type":"main","index":0}]]},"set urls":{"main":[[{"node":"Split Out","type":"main","index":0}]]},"Get links":{"main":[[{"node":"Aggregate group links","type":"main","index":0}]]},"Split Out":{"main":[[{"node":"update last Scrap","type":"main","index":0}]]},"Split Out1":{"main":[[{"node":"store posts","type":"main","index":0}]]},"Set up KEYS":{"main":[[{"node":"Get Brand names","type":"main","index":0}]]},"get progress":{"main":[[{"node":"Switch","type":"main","index":0}]]},"Get Brand names":{"main":[[{"node":"Aggregate brand names","type":"main","index":0}]]},"Receive results":{"main":[[{"node":"Split Out1","type":"main","index":0}]]},"facebook groups":{"main":[[{"node":"get progress","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Set up KEYS","type":"main","index":0}]]},"Filter brand name":{"main":[[{"node":"Sentiment Analysis","type":"main","index":0}]]},"Sentiment Analysis":{"main":[[{"node":"Merge","type":"main","index":0}],[{"node":"Merge","type":"main","index":1}],[{"node":"Merge","type":"main","index":2}]]},"pull group results":{"main":[[{"node":"insights and sentiments","type":"main","index":0}]]},"Aggregate brand names":{"main":[[{"node":"Get links","type":"main","index":0}]]},"Aggregate group links":{"main":[[{"node":"facebook groups","type":"main","index":0}]]},"Information Extractor":{"main":[[{"node":"pull group results","type":"main","index":0}]]},"OpenRouter Chat Model":{"ai_languageModel":[[{"node":"Sentiment Analysis","type":"ai_languageModel","index":0}]]},"OpenRouter Chat Model1":{"ai_languageModel":[[{"node":"Information Extractor","type":"ai_languageModel","index":0}]]},"insights and sentiments":{"main":[[{"node":"Update sentiments","type":"main","index":0}]]}}}


name: Dynamic AI Model Router for Query Optimization with OpenRouter
author_name: Davide
author_username: n3witalia
categories: []
created_at: 2025-05-20T07:40:19.495Z
updated_at: 2025-05-20T07:40:19.495Z
url: https://n8n.io/workflows/4237
scraped_at: 2025-06-19 22:49:19
description:
  The Agent Decisioner is a dynamic, AI-powered routing system that automatically selects the most appropriate large language model (LLM) to respond to a user's query based on the query’s content and purpose.

  This workflow ensures dynamic, optimized AI responses by intelligently routing queries to the best-suited model.

  Advantages

  🔁 Automatic Model Routing:**
    Automatically selects the best model for the job, improving efficiency and relevance of responses.

  🎯 Optimized Use of Resources:**
    Avoids overuse of expensive models like GPT-4 by routing simpler queries to lightweight models.

  📚 Model-Aware Reasoning:**
    Uses detailed metadata about model capabilities (e.g., reasoning, coding, web search) for intelligent selection.

  📥 Modular and Extendable:**
    Easy to integrate with other tools or expand by adding more models or custom decision logic.

  👨‍💻 Ideal for RAG and Multi-Agent Systems:**
    Can serve as the brain behind more complex agent frameworks or Retrieval-Augmented Generation pipelines.

  How It Works  

  Chat Trigger: The workflow starts when a user sends a message, triggering the Routing Agent.  
  Model Selection: The AI Agent analyzes the query and selects the best-suited model from the available options (e.g., Claude 3.7 Sonnet for coding, Perplexity/Sonar for web searches, GPT-4o Mini for reasoning).  
  Structured Output: The agent returns a JSON response with the user’s prompt and the chosen model.  
  Execution: The selected model processes the query and generates a response, ensuring optimal performance for the task.  

  Set Up Steps  

  Configure Nodes:  
     Chat Trigger: Set up the webhook to receive user messages.  
     Routing Agent (AI Agent): Define the system message with model strengths and JSON output rules.  
     OpenRouter Chat Model: Connect to OpenRouter for model access.  
     Structured Output Parser: Ensure it validates the JSON response format (prompt + model).  
     Execution Agent (AI Agent1): Configure it to forward the prompt to the selected model.  

  Connect Nodes:  
     Link the Chat Trigger to the Routing Agent.  
     Connect the OpenRouter Chat Model and Output Parser to the Routing Agent.  
     Route the parsed JSON to the Execution Agent, which uses the chosen model via OpenRouter Chat Model1.  

  Credentials:  
     Ensure OpenRouter API credentials are correctly set for both chat model nodes.  

  Test & Deploy:  
     Activate the workflow and test with sample queries to verify model selection logic.  
     Adjust the routing rules if needed for better accuracy.  

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

nodes_used:
  ["@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.outputParserAutofixing","@n8n/n8n-nodes-langchain.outputParserStructured","@n8n/n8n-nodes-langchain.lmChatOpenRouter"]

workflow_json:
  {"id":"uNLWQ7BSozpoehpU","meta":{"instanceId":"a4bfc93e975ca233ac45ed7c9227d84cf5a2329310525917adaf3312e10d5462","templateCredsSetupCompleted":true},"name":"Automated AI Routing with OpenRouter","tags":[],"nodes":[{"id":"25903a04-24d2-41f9-bf34-5d6234e642e5","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[-180,-180],"webhookId":"a0032740-26d8-491b-93f9-2250906d0e17","parameters":{"options":{}},"typeVersion":1.1},{"id":"fabffdee-3c1e-47db-a4e9-f6473a6e9257","name":"OpenRouter Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[0,40],"parameters":{"options":{}},"credentials":{"openRouterApi":{"id":"pb06rfB4xmxzVe3Q","name":"OpenRouter"}},"typeVersion":1},{"id":"c53fe672-92cb-4d88-b4f6-f413fb00ad6a","name":"Structured Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[340,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\t\"model\": {\n\t\t\t\"type\": \"string\"\n\t\t}\n\t}\n}"},"typeVersion":1.2},{"id":"d60a9d61-c611-4813-bf85-e8f8faaa21b6","name":"OpenRouter Chat Model1","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[420,40],"parameters":{"model":"={{ $json.output.model }}","options":{}},"credentials":{"openRouterApi":{"id":"pb06rfB4xmxzVe3Q","name":"OpenRouter"}},"typeVersion":1},{"id":"ef9ceacb-55e4-4795-aa18-976997ec3717","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-180,-420],"parameters":{"width":840,"height":180,"content":"## Dynamic Model Selector for Optimal AI Responses\n\nThe **Agent Decisioner** is a dynamic, AI-powered routing system that automatically selects the most appropriate large language model (LLM) to respond to a user's query based on the query’s content and purpose.\n\nThis workflow ensures **dynamic, optimized AI responses** by intelligently routing queries to the best-suited model."},"typeVersion":1},{"id":"4d688ad7-b463-4e72-9b79-4b9142f022d2","name":"Routing Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[40,-180],"parameters":{"options":{"systemMessage":"=You are a **Routing Agent**.\n\nYour task is to analyze user queries and determine the most appropriate model to handle each specific use case.\n\n## Available Models\n\nYou have access to the following models:\n\n1. **perplexity/sonar**\n2. **openai/gpt-4o-mini**\n3. **anthropic/claude-3.7-sonnet**\n4. **meta-llama/llama-3-70b-instruct**\n5. **google/gemini-2.5-pro-preview**\n6. **qwen/qwen-qwq-32b**\n7. **openai/codex-mini**\n8. **openai/o1-pro**\n\n## Model Strengths\n\n### 1. perplexity/sonar\n- Built-in web search capability\n- Provides citations and customizable sources\n- Ideal for retrieving live, up-to-date information from the web\n\n### 2. openai/gpt-4o-mini\n- Cost-efficient language model optimized for advanced reasoning tasks\n- Excels in science and mathematics\n- Best suited for problems requiring careful, well-thought-out responses involving multiple variables or connections\n\n### 3. anthropic/claude-3.7-sonnet\n- High proficiency in coding tasks, scoring ~94% on SWE-Bench Verified\n- Enhances data science expertise by navigating unstructured data and utilizing multiple tools for insights\n- Handles very long documents and maintains coherence over extended conversations or analyses\n- Performs well in creative writing tasks such as storytelling, dialogue generation, and summarization\n- Tends to produce responses that are more aligned with safety and ethical guidelines\n\n### 4. meta-llama/llama-3-70b-instruct\n- Strong performance in coding and reasoning tasks\n- Suitable for complex programming and technical problem-solving\n- Supports long context windows, making it ideal for extended analyses\n\n### 5. google/gemini-2.5-pro-preview\n- Advanced multimodal capabilities, handling both text and images\n- Excels in tasks requiring integration of visual and textual information\n- Ideal for complex problem-solving involving diverse data types\n\n### 6. qwen/qwen-qwq-32b\n- Specialized in reasoning and problem-solving tasks\n- Effective in handling logical puzzles and complex analytical queries\n\n### 7. openai/codex-mini\n- Optimized for code generation and completion tasks\n- Suitable for lightweight coding tasks and quick code snippets\n\n### 8. openai/o1-pro\n- Designed for complex reasoning with enhanced computational resources\n- Performs well in STEM-related tasks, including physics, chemistry, and biology\n- Capable of handling large context windows, making it suitable for in-depth analyses\n\n## Output Format\n\nYour output must always be a valid JSON object in the following format:\n\n```json\n{\n  \"prompt\": \"user query goes here\",\n  \"model\": \"selected-model-name\"\n}\n```\n\n- The **\"prompt\"** field should contain the exact query to be sent to the selected model.\n- The **\"model\"** field should contain the model name (one of: perplexity/sonar, openai/gpt-4o-mini, anthropic/claude-3.7-sonnet, meta-llama/llama-3-70b-instruct, google/gemini-2.5-pro-preview, qwen/qwen-qwq-32b, openai/codex-mini, openai/o1-pro).\n\n**Important:** Only return the JSON object. Do not include any explanations or additional text."},"hasOutputParser":true},"typeVersion":1.9},{"id":"94c49c22-9697-4230-ba35-5159041cfdc7","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[400,-180],"parameters":{"text":"={{ $json.output.prompt }}","options":{},"promptType":"define"},"typeVersion":1.9},{"id":"54c4278e-c185-4ab4-b21e-d8e837b14818","name":"Auto-fixing Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserAutofixing","position":[140,60],"parameters":{"options":{"prompt":"Instructions:\n--------------\n{instructions}\n--------------\nCompletion:\n--------------\n{completion}\n--------------\n\nAbove, the Completion did not satisfy the constraints given in the Instructions.\nError:\n--------------\n{error}\n--------------\n\nPlease try again. Please only respond with an answer that satisfies the constraints laid out in the Instructions:"}},"typeVersion":1},{"id":"2813da6b-423b-41d6-8eb4-664f616ca8d5","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[140,220],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"TefveNaDaMERl1hY","name":"OpenAi account (Eure)"}},"typeVersion":1.2}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"bb8e8d46-ce32-49e0-a843-496c6e026902","connections":{"Routing Agent":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Auto-fixing Output Parser","type":"ai_languageModel","index":0}]]},"OpenRouter Chat Model":{"ai_languageModel":[[{"node":"Routing Agent","type":"ai_languageModel","index":0}]]},"OpenRouter Chat Model1":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Structured Output Parser":{"ai_outputParser":[[{"node":"Auto-fixing Output Parser","type":"ai_outputParser","index":0}]]},"Auto-fixing Output Parser":{"ai_outputParser":[[{"node":"Routing Agent","type":"ai_outputParser","index":0}]]},"When chat message received":{"main":[[{"node":"Routing Agent","type":"main","index":0}]]}}}


name: Invoice Processor & Validator with OCR, AI & Google Sheets
author_name: Dhrumil Patel
author_username: itechdp
categories: []
created_at: 2025-05-20T19:58:32.680Z
updated_at: 2025-05-20T19:58:32.680Z
url: https://n8n.io/workflows/4247
scraped_at: 2025-06-19 22:48:47
description:
  📝 Say goodbye to manual invoice checking! 
  This smart workflow automates your entire invoice processing pipeline using AI, OCR, and Google Sheets.

  ⚙️ What This Workflow Does:

  📥 1. Reads an invoice PDF
  — Select a local PDF invoice from your machine.

  🔍 2. Extracts raw text using OCR
  — Converts scanned or digital PDFs into readable text.

  🧠 3. AI Agent processes the text
  — Transforms messy raw text into clean JSON using natural language understanding.

  🧱 4. Structures and refines the JSON
  — Converts AI output into a structured, usable format.

  🔄 5. Splits item-wise data
  — Extracts individual invoice line items with all details.

  🆔 6. Generates unique keys
  — Creates a unique identifier for each item for tracking.

  📊 7. Updates Google Sheet
  — Adds extracted items to your designated sheet automatically.

  📂 8. Fetches master item data
  — Loads your internal product master to validate against.

  ✅ 9. Validates item name & cost
  — Compares extracted items with your official records to verify accuracy.

  📌 10. Updates results per item
  — Marks each item as Valid or Invalid in the sheet based on matching.

  💼 Use Case:

  Perfect for businesses, freelancers, or operations teams who receive invoices and want to automate validation, detect billing errors, and log everything seamlessly in Google Sheets — all using the power of AI + n8n.

  &gt; 🔁 Fast. Accurate. Zero manual work.

  #OCR #AI #Invoices #Automation.

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

workflow_json:
  {"meta":{"instanceId":"761a3dddae2bb21eb8973ffca0ba97d5b4f499405873760164a536f547546882","templateCredsSetupCompleted":true},"nodes":[{"id":"0d426dc6-d9ff-44cd-82f0-9d87bda8821a","name":"When clicking ‘Test workflow’","type":"n8n-nodes-base.manualTrigger","position":[-200,405],"parameters":{},"typeVersion":1},{"id":"2722d720-22e9-488b-9b39-4273fe88257c","name":"OpenRouter Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[548,625],"parameters":{"model":"deepseek/deepseek-chat-v3-0324","options":{}},"credentials":{"openRouterApi":{"id":"ykjF5geNxohYAYJ9","name":"OpenRouter account - sentiimenta.ai"}},"typeVersion":1},{"id":"6992dfda-d65e-4694-8261-2328a7d0bc09","name":"Split Out","type":"n8n-nodes-base.splitOut","position":[1276,280],"parameters":{"options":{},"fieldToSplitOut":"line_items"},"typeVersion":1},{"id":"06e91f54-fbc3-4161-949c-779ecd7924b9","name":"Post-Processing","type":"n8n-nodes-base.code","position":[880,380],"parameters":{"jsCode":"const output = $input.first().json.output;\nlet raw = output.result || output.completion || output.text || JSON.stringify(output);\n\n// Step 1: Remove backticks if present\nraw = raw.trim();\nif (raw.startsWith(\"```json\")) {\n  raw = raw.replace(/^```json\\s*/, '').replace(/```$/, '').trim();\n} else if (raw.startsWith(\"```\")) {\n  raw = raw.replace(/^```\\s*/, '').replace(/```$/, '').trim();\n}\n\n// Step 2: Find full JSON block from first { to last }\nconst start = raw.indexOf('{');\nconst end = raw.lastIndexOf('}');\nif (start === -1 || end === -1 || end <= start) {\n  return [{\n    json: {\n      error: \"No valid JSON block found\",\n      raw_output: raw\n    }\n  }];\n}\n\nlet jsonCandidate = raw.substring(start, end + 1).trim();\n\n// Step 3: Unescape characters\njsonCandidate = jsonCandidate\n  .replace(/\\\\n/g, '')\n  .replace(/\\\\t/g, '')\n  .replace(/\\\\\"/g, '\"')\n  .replace(/\\\\'/g, \"'\")\n  .replace(/\\\\\\\\/g, '\\\\');\n\n// Step 4: Parse JSON safely\ntry {\n  let parsed = JSON.parse(jsonCandidate);\n\n  // Only double-parse if it looks like stringified JSON\n  if (typeof parsed === \"string\" && parsed.trim().startsWith('{') && parsed.trim().endsWith('}')) {\n    parsed = JSON.parse(parsed);\n  }\n\n  return [{ json: parsed }];\n} catch (e) {\n  return [{\n    json: {\n      error: \"JSON parsing failed\",\n      raw_output: raw,\n      attempted_extraction: jsonCandidate,\n      message: e.message\n    }\n  }];\n}\n"},"typeVersion":2},{"id":"34f5988b-9c83-4828-a13d-1ff33615e509","name":"Text Extractor","type":"@n8n/n8n-nodes-langchain.agent","position":[460,420],"parameters":{"text":"=- You must respond ONLY with valid raw rendered JSON.\n- Do NOT include the word \"json\".\n- Do NOT include the word \"```json\".\n- Do NOT use triple backticks or markdown formatting.\n- Do NOT wrap the response in any key like \"output\".\n- Do NOT write anything starting at output directly start with valid root-level JSON.\n- Only respond with a valid, root-level JSON object.\n- Do NOT skip any line item. Continue extracting all line items until the sum of all line_total values exactly equals the total sale amount extracted from the invoice. This verification ensures that all items are fully extracted and no entries are missed. If the totals do not match, keep parsing and extracting additional line items until they do. Only then stop.\n\nText to convert: {{ $json.text }}","options":{"systemMessage":"=You are a document parsing assistant designed to extract structured data from invoice PDFs for automated uploading and validation in a financial system.\n\nExtract the following fields from the invoice text:\n\ninvoice_number: Extract from the 'Invoice No' field.\n\nvendor_name: Company name issuing the invoice.\n\ninvoice_date: Format as DD/MM/YYYY.\n\npo_number: Extract the PO number or return null if not found.\n\npo_date: Extract the PO date in DD/MM/YYYY format or return null if not found.\n\ntotal_amount: Extract the invoice total as a float.\n\ntax_details: Include total CGST, total SGST.\n\nline_items: List of all items in the invoice. For each item, extract:\n\n  Serial No.: Item Serial No. In invoice.\n\n  code: The TWW word and its postfix only (e.g., TWW, TWW-Cover, TWW-HPCN). Do not include HSN code or numbers. This field must always be present.\n\n  description: Item description, never include HSN code of product in product description.\n\n  last character: This is a single word/character string found just after or around the line item, typically at the end of the price line or just on the next line. It will never be a number, HSN code, GST %, or unit (like PCS). Examples: G, C, S, 5C, .C If nothing is present (only digits or blank), return \"\". Check the next 1–2 lines after each item if it's not found on the same line.\n\n  quantity: Quantity value.\n\n  unit_price: Price per unit.\n\n  line_total: Total price for the line.\n\n  hsn_code: HSN code of the item.\n\n  cgst: Only extract the CGST percentage (e.g., 9%, 6%) as written in the invoice. Do not calculate based on line total.\n\n  sgst: Only extract the SGST percentage (e.g., 9%, 6%) as written in the invoice. Do not calculate based on line total.\n\nImportant: Double-check that all line items are extracted without omission.\n\nDo NOT skip any line item. Continue extracting all line items until the sum of all line_total values exactly equals the total_amount extracted from the invoice. This verification ensures that all items are fully extracted and no entries are missed. If the totals do not match, keep parsing and extracting additional line items until they do. Only then stop."},"promptType":"define"},"typeVersion":1.8},{"id":"3446d02e-2c94-4575-9062-455dbd71ecd8","name":"Read/Write Files from Disk","type":"n8n-nodes-base.readWriteFile","position":[20,405],"parameters":{"options":{},"fileSelector":"=E:/SentIImenta AI/SentIImenta AI Website/White Willow/Invoice Validator/May Invoices/Jumax TWW Daily PO Invoices 05_05_2025/661.pdf"},"typeVersion":1},{"id":"95e99fb0-a12f-40e6-9126-d84cf2b0c493","name":"Extract from File","type":"n8n-nodes-base.extractFromFile","position":[240,405],"parameters":{"options":{},"operation":"pdf"},"typeVersion":1},{"id":"ce0a9035-c99f-4cc3-9ec3-b2be2158623e","name":"If","type":"n8n-nodes-base.if","position":[1100,340],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"e73c23b4-39e9-4719-8a72-53808eefe607","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.error }}","rightValue":"JSON parsing failed"},{"id":"b3b7d3d4-c709-40fe-8782-ffd34180ba8b","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.error }}","rightValue":"No valid JSON block found"}]}},"typeVersion":2.2},{"id":"6675d752-7230-4335-9c68-387396728e7f","name":"Send Raw Text Again","type":"n8n-nodes-base.set","position":[1340,520],"parameters":{"options":{},"assignments":{"assignments":[{"id":"18f61f00-03e8-4fd4-b305-f3742bb32d17","name":"text","type":"string","value":"={{ $('Extract from File').item.json.text }}"}]}},"typeVersion":3.4},{"id":"7706b71b-25dc-4f61-b975-51322d7b9d32","name":"Validation","type":"n8n-nodes-base.code","position":[2156,280],"parameters":{"jsCode":"// --- Helper: Levenshtein Distance ---\nfunction levenshtein(a, b) {\n  const matrix = Array.from({ length: b.length + 1 }, (_, i) => [i]);\n  for (let j = 0; j <= a.length; j++) matrix[0][j] = j;\n\n  for (let i = 1; i <= b.length; i++) {\n    for (let j = 1; j <= a.length; j++) {\n      const cost = a[j - 1] === b[i - 1] ? 0 : 1;\n      matrix[i][j] = Math.min(\n        matrix[i - 1][j] + 1,\n        matrix[i][j - 1] + 1,\n        matrix[i - 1][j - 1] + cost\n      );\n    }\n  }\n  return matrix[b.length][a.length];\n}\n\n// --- Helper: Clean String ---\nfunction cleanString(str) {\n  if (str && typeof str === 'string') {\n    return str\n      .replace(/(^\"|\"$|\\[|\\])/g, '') // remove unwanted chars\n      .replace(/\\s{2,}/g, ' ')       // replace multiple spaces with one\n      .toLowerCase()\n      .trim();\n  }\n  return '';\n}\n\n// --- 1. Get all SKUs from \"Split Out\" and corresponding Unique Keys ---\nconst splitOutItems = $items('Split Out');\nconst uniqueKeyItems = $items('Generate Unique Key');\n\nconst inputSKUs = splitOutItems.map((item, index) => {\n  const uniqueKeyItem = uniqueKeyItems[index];\n\n  const code = cleanString(item.json.code);\n  const description = cleanString(item.json.description);\n  // handle both possible keys for last character\n  const lastCharacter = cleanString(item.json['last_character'] ?? item.json['last character'] ?? '');\n\n  let sku = `${code} ${description}`;\n\n  if (lastCharacter) {\n    if (/^[a-z0-9]+$/i.test(lastCharacter)) {\n      // Append directly without space if alphanumeric postfix\n      sku += lastCharacter;\n    } else {\n      // Otherwise, add a space\n      sku += ` ${lastCharacter}`;\n    }\n  }\n  \n  sku = sku.trim().replace(/\\s{2,}/g, ' ');\n\n  return {\n    Unique_Key: uniqueKeyItem ? uniqueKeyItem.json['Unique Key'] || uniqueKeyItem.json.Unique_Key || '' : '',\n    serial_no: item.json['Serial No.'] ?? item.json['Serial_No.'] ?? '',\n    sku,\n    quantity: item.json.quantity,\n    unit_price: item.json.unit_price,\n    line_total: item.json.line_total,\n    hsn_code: item.json.hsn_code,\n    cgst: item.json.cgst,\n    sgst: item.json.sgst\n  };\n});\n\n// --- 2. Get all rows from \"Google Sheets\" ---\nconst sheetRows = $items('Fetch Master Data').map(i => i.json);\n\n// --- 3. Set Levenshtein match threshold ---\nconst threshold = 5;\nconst results = [];\n\nfor (const inputSKU of inputSKUs) {\n  let bestMatch = null;\n  let lowestDistance = Infinity;\n\n  for (const row of sheetRows) {\n    const descriptionRaw = row['Jumax PDF Description'] || '';\n    const description = cleanString(descriptionRaw);\n    if (!description) continue;\n\n    const distance = levenshtein(inputSKU.sku, description);\n\n    if (distance < lowestDistance) {\n      lowestDistance = distance;\n      bestMatch = row;\n    }\n  }\n\n  if (bestMatch && lowestDistance <= threshold) {\n    const jumaxASIN = cleanString(bestMatch['ASIN']);\n    const tASIN = cleanString(bestMatch['TWW ASIN']);\n    const cost = Number(bestMatch['Cost '] || bestMatch['Cost'] || bestMatch['Rate']);\n    const unitPrice = Number(inputSKU.unit_price);\n\n    const asinMatch = jumaxASIN === tASIN;\n    const costMatch = cost === unitPrice;\n    const allConditionsMet = asinMatch && costMatch;\n\n    results.push({\n      json: {\n        Unique_Key: inputSKU.Unique_Key,\n        serial_no: inputSKU.serial_no,\n        matchedSKU: inputSKU.sku,\n        matchedRow: bestMatch,\n        distance: lowestDistance,\n        Jumax_ASIN: jumaxASIN,\n        T_ASIN: tASIN,\n        asinMatch,\n        costMatch,\n        quantity: inputSKU.quantity,\n        unit_price: inputSKU.unit_price,\n        costFromSheet: cost,\n        line_total: inputSKU.line_total,\n        hsn_code: inputSKU.hsn_code,\n        cgst: inputSKU.cgst,\n        sgst: inputSKU.sgst,\n        message: allConditionsMet\n          ? '✅ Match found, ASINs match, and Cost matches Unit Price'\n          : asinMatch\n            ? '⚠️ ASINs match but Cost does not match Unit Price'\n            : '❌ Match found but ASINs do not match',\n        All_Conditions_Met: allConditionsMet\n      }\n    });\n  } else {\n    results.push({\n      json: {\n        Unique_Key: inputSKU.Unique_Key,\n        serial_no: inputSKU.serial_no,\n        matchedSKU: inputSKU.sku,\n        matchedRow: null,\n        message: `❌ No match found for SKU: ${inputSKU.sku}`,\n        closestDistance: lowestDistance,\n        quantity: inputSKU.quantity,\n        unit_price: inputSKU.unit_price,\n        line_total: inputSKU.line_total,\n        hsn_code: inputSKU.hsn_code,\n        cgst: inputSKU.cgst,\n        sgst: inputSKU.sgst,\n        All_Conditions_Met: false\n      }\n    });\n  }\n}\n\n// --- 4. Return final results ---\nreturn results;\n"},"typeVersion":2},{"id":"34e482d2-9658-496b-ad2f-fc376f3490ff","name":"Send Invoice Data","type":"n8n-nodes-base.googleSheets","position":[1716,280],"parameters":{"columns":{"value":{"HSN":"={{ $('Split Out').item.json.hsn_code }}","Qty":"={{ $('Split Out').item.json.quantity }}","CGST%":"={{ $('Split Out').item.json.cgst }}","SGST%":"={{ $('Split Out').item.json.sgst }}","SR No.":"={{ $('Split Out').item.json['serial_no'] }}","PO Date":"={{ $('Post-Processing').item.json.po_date }}","PO Number":"={{ $('Post-Processing').item.json.po_number }}","Unique Key":"={{ $json['Unique Key'] }}","Invoice No.":"={{ $('Post-Processing').item.json.invoice_number }}","Sale Amount":"={{ $('Split Out').item.json.line_total }}","Invoice Date":"={{ $('Post-Processing').item.json.invoice_date }}","Rate (Vendor)":"={{ $('Split Out').item.json.unit_price }}","TWW Description":"={{ \n  $node[\"Split Out\"].json[\"code\"] + \" \" + \n  $node[\"Split Out\"].json[\"description\"] + \" \" + \n  ($node[\"Split Out\"].json[\"last character\"] ?? $node[\"Split Out\"].json[\"last_character\"] ?? \"\") \n}}"},"schema":[{"id":"SR No.","type":"string","display":true,"removed":false,"required":false,"displayName":"SR No.","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Invoice No.","type":"string","display":true,"required":false,"displayName":"Invoice No.","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Unique Key","type":"string","display":true,"removed":false,"required":false,"displayName":"Unique Key","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Invoice Date","type":"string","display":true,"required":false,"displayName":"Invoice Date","defaultMatch":false,"canBeUsedToMatch":true},{"id":"PO Number","type":"string","display":true,"required":false,"displayName":"PO Number","defaultMatch":false,"canBeUsedToMatch":true},{"id":"PO Date","type":"string","display":true,"required":false,"displayName":"PO Date","defaultMatch":false,"canBeUsedToMatch":true},{"id":"TWW Description","type":"string","display":true,"required":false,"displayName":"TWW Description","defaultMatch":false,"canBeUsedToMatch":true},{"id":"HSN","type":"string","display":true,"required":false,"displayName":"HSN","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Qty","type":"string","display":true,"required":false,"displayName":"Qty","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Rate (Vendor)","type":"string","display":true,"required":false,"displayName":"Rate (Vendor)","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Sale Amount","type":"string","display":true,"required":false,"displayName":"Sale Amount","defaultMatch":false,"canBeUsedToMatch":true},{"id":"CGST%","type":"string","display":true,"required":false,"displayName":"CGST%","defaultMatch":false,"canBeUsedToMatch":true},{"id":"SGST%","type":"string","display":true,"required":false,"displayName":"SGST%","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Matched Cost (Actual Price)","type":"string","display":true,"removed":true,"required":false,"displayName":"Matched Cost (Actual Price)","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Matched Unit Price (Vendor Price)","type":"string","display":true,"removed":true,"required":false,"displayName":"Matched Unit Price (Vendor Price)","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Price Difference (₹)","type":"string","display":true,"removed":true,"required":false,"displayName":"Price Difference (₹)","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Total Loss/Gain (₹)","type":"string","display":true,"removed":true,"required":false,"displayName":"Total Loss/Gain (₹)","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Mismatch Note","type":"string","display":true,"removed":true,"required":false,"displayName":"Mismatch Note","defaultMatch":false,"canBeUsedToMatch":true},{"id":"SKU Matched","type":"string","display":true,"removed":false,"required":false,"displayName":"SKU Matched","defaultMatch":false,"canBeUsedToMatch":true},{"id":"ASIN","type":"string","display":true,"removed":false,"required":false,"displayName":"ASIN","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Taxable Amount","type":"string","display":true,"removed":false,"required":false,"displayName":"Taxable Amount","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Invoice Amount","type":"string","display":true,"removed":false,"required":false,"displayName":"Invoice Amount","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Total Quantity","type":"string","display":true,"removed":false,"required":false,"displayName":"Total Quantity","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/1L2DN1aGp1uhLhNm7TrI54tC0Yuk4ER9y2DU-jbHrSrk/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1L2DN1aGp1uhLhNm7TrI54tC0Yuk4ER9y2DU-jbHrSrk","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1L2DN1aGp1uhLhNm7TrI54tC0Yuk4ER9y2DU-jbHrSrk/edit?usp=drivesdk","cachedResultName":"Invoice Validation"}},"credentials":{"googleSheetsOAuth2Api":{"id":"vRHrArbX33qgxWfK","name":"Google Sheets account 3"}},"typeVersion":4.5},{"id":"3e30f4f1-15e1-41d9-a7f3-bf49d6273c02","name":"Fetch Master Data","type":"n8n-nodes-base.googleSheets","position":[1980,280],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"list","value":305288444,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/1ZBODB_mwa17Amtxnme5l8MxyEcWHYy9SSjQ6atPJXhc/edit#gid=305288444","cachedResultName":"Cost-Priority sheet-GPT"},"documentId":{"__rl":true,"mode":"list","value":"1ZBODB_mwa17Amtxnme5l8MxyEcWHYy9SSjQ6atPJXhc","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1ZBODB_mwa17Amtxnme5l8MxyEcWHYy9SSjQ6atPJXhc/edit?usp=drivesdk","cachedResultName":"Mapping Sheet Final"}},"credentials":{"googleSheetsOAuth2Api":{"id":"vRHrArbX33qgxWfK","name":"Google Sheets account 3"}},"executeOnce":true,"typeVersion":4.5},{"id":"7a46cfd3-3e2f-4818-80cd-e2776d0303a5","name":"Update Results","type":"n8n-nodes-base.googleSheets","position":[2460,280],"parameters":{"columns":{"value":{"Unique Key":"={{ $json.Unique_Key }}","Mismatch Note":"={{ $('Validation').item.json.message }}","Total Loss/Gain (₹)":"={{ ($json.unit_price - $json.costFromSheet) * $json.quantity}}","Price Difference (₹)":"={{ $json.unit_price - $json.costFromSheet }}","Matched Cost (Actual Price)":"={{ $json.costFromSheet }}","Matched Unit Price (Vendor Price)":"={{ $('Validation').item.json.unit_price }}"},"schema":[{"id":"SR No.","type":"string","display":true,"removed":true,"required":false,"displayName":"SR No.","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Invoice No.","type":"string","display":true,"removed":true,"required":false,"displayName":"Invoice No.","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Unique Key","type":"string","display":true,"removed":false,"required":false,"displayName":"Unique Key","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Invoice Date","type":"string","display":true,"removed":true,"required":false,"displayName":"Invoice Date","defaultMatch":false,"canBeUsedToMatch":true},{"id":"PO Number","type":"string","display":true,"removed":true,"required":false,"displayName":"PO Number","defaultMatch":false,"canBeUsedToMatch":true},{"id":"PO Date","type":"string","display":true,"removed":true,"required":false,"displayName":"PO Date","defaultMatch":false,"canBeUsedToMatch":true},{"id":"TWW Description","type":"string","display":true,"removed":true,"required":false,"displayName":"TWW Description","defaultMatch":false,"canBeUsedToMatch":true},{"id":"HSN","type":"string","display":true,"removed":true,"required":false,"displayName":"HSN","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Qty","type":"string","display":true,"removed":true,"required":false,"displayName":"Qty","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Rate (Vendor)","type":"string","display":true,"removed":true,"required":false,"displayName":"Rate (Vendor)","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Sale Amount","type":"string","display":true,"removed":true,"required":false,"displayName":"Sale Amount","defaultMatch":false,"canBeUsedToMatch":true},{"id":"CGST%","type":"string","display":true,"removed":true,"required":false,"displayName":"CGST%","defaultMatch":false,"canBeUsedToMatch":true},{"id":"SGST%","type":"string","display":true,"removed":true,"required":false,"displayName":"SGST%","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Matched Cost (Actual Price)","type":"string","display":true,"removed":false,"required":false,"displayName":"Matched Cost (Actual Price)","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Matched Unit Price (Vendor Price)","type":"string","display":true,"required":false,"displayName":"Matched Unit Price (Vendor Price)","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Price Difference (₹)","type":"string","display":true,"required":false,"displayName":"Price Difference (₹)","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Total Loss/Gain (₹)","type":"string","display":true,"required":false,"displayName":"Total Loss/Gain (₹)","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Mismatch Note","type":"string","display":true,"required":false,"displayName":"Mismatch Note","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":["Unique Key"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"update","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1L2DN1aGp1uhLhNm7TrI54tC0Yuk4ER9y2DU-jbHrSrk/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1L2DN1aGp1uhLhNm7TrI54tC0Yuk4ER9y2DU-jbHrSrk","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1L2DN1aGp1uhLhNm7TrI54tC0Yuk4ER9y2DU-jbHrSrk/edit?usp=drivesdk","cachedResultName":"Invoice Validation"}},"credentials":{"googleSheetsOAuth2Api":{"id":"vRHrArbX33qgxWfK","name":"Google Sheets account 3"}},"typeVersion":4.5},{"id":"d9752205-2712-46d0-9058-86857f28e470","name":"Generate Unique Key","type":"n8n-nodes-base.set","position":[1496,280],"parameters":{"options":{},"assignments":{"assignments":[{"id":"1907451f-cc09-45d7-a04f-113f8f94d918","name":"Unique Key","type":"string","value":"={{ $('If').item.json.invoice_number + \"-\" + $itemIndex }}"}]}},"typeVersion":3.4},{"id":"52a2b54a-69e8-4a83-9861-5931a51a7162","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-240,320],"parameters":{"color":7,"width":620,"height":280,"content":"## Reading Invoice's PDF File Locally"},"typeVersion":1},{"id":"67d04fa9-3ad7-4613-89f0-511f9ee32f1d","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[400,320],"parameters":{"color":7,"width":380,"height":280,"content":"## Extracting Details From Invoice PDF"},"typeVersion":1},{"id":"4465dff2-ea51-4392-8aa7-8a780a73c33e","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[800,320],"parameters":{"color":7,"height":220,"content":"## Processing Output"},"typeVersion":1},{"id":"c4ed886e-3e16-451b-b554-badb5f130623","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1280,460],"parameters":{"color":7,"width":220,"height":220,"content":"## Fallback On Error"},"typeVersion":1},{"id":"159dd4d1-f052-4401-a426-0621af19d300","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[1240,220],"parameters":{"color":7,"width":400,"height":220,"content":"## Extracting Line Items"},"typeVersion":1},{"id":"b90a3aba-a18a-4846-a22d-cbd72aac8e6d","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[1660,200],"parameters":{"color":7,"width":220,"height":240,"content":"## Sending Data To G-Sheet"},"typeVersion":1},{"id":"69e4f146-394f-4dc2-ab70-22337a3031e9","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[1900,200],"parameters":{"color":7,"width":440,"height":240,"content":"## Fetch Master Data & Validating Invoice Extracted Data"},"typeVersion":1},{"id":"23c130e3-1727-48a2-b050-a4fdc07749f1","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[2360,200],"parameters":{"color":7,"width":300,"height":240,"content":"## Update Validation Result"},"typeVersion":1}],"pinData":{},"connections":{"If":{"main":[[{"node":"Send Raw Text Again","type":"main","index":0}],[{"node":"Split Out","type":"main","index":0}]]},"Split Out":{"main":[[{"node":"Generate Unique Key","type":"main","index":0}]]},"Validation":{"main":[[{"node":"Update Results","type":"main","index":0}]]},"Text Extractor":{"main":[[{"node":"Post-Processing","type":"main","index":0}]]},"Post-Processing":{"main":[[{"node":"If","type":"main","index":0}]]},"Extract from File":{"main":[[{"node":"Text Extractor","type":"main","index":0}]]},"Fetch Master Data":{"main":[[{"node":"Validation","type":"main","index":0}]]},"Send Invoice Data":{"main":[[{"node":"Fetch Master Data","type":"main","index":0}]]},"Generate Unique Key":{"main":[[{"node":"Send Invoice Data","type":"main","index":0}]]},"Send Raw Text Again":{"main":[[{"node":"Text Extractor","type":"main","index":0}]]},"OpenRouter Chat Model":{"ai_languageModel":[[{"node":"Text Extractor","type":"ai_languageModel","index":0}]]},"Read/Write Files from Disk":{"main":[[{"node":"Extract from File","type":"main","index":0}]]},"When clicking ‘Test workflow’":{"main":[[{"node":"Read/Write Files from Disk","type":"main","index":0}]]}}}


name: Web Site Scraper for LLMs with Airtop
author_name: Airtop
author_username: cesar-at-airtop
categories: []
created_at: 2025-05-21T00:17:56.473Z
updated_at: 2025-05-21T00:17:56.473Z
url: https://n8n.io/workflows/4252
scraped_at: 2025-06-19 22:49:22
description:
  Recursive Web Scraping 

  Use Case  
  Automating web scraping with recursive depth is ideal for collecting content across multiple linked pages—perfect for content aggregation, lead generation, or research projects.

  What This Automation Does  
  This automation reads a list of URLs from a Google Sheet, scrapes each page, stores the content in a document, and adds newly discovered links back to the sheet. It continues this process for a specified number of iterations based on the defined scraping depth.

  Input Parameters:
  Seed URL: The starting URL to begin the scraping process.  
    Example: https://example.com/
  Links must contain: Restricts the links to those that contain this specified string.  
    Example: https://example.com/
  Depth: The number of iterations (layers of links) to scrape beyond the initial set.  
    Example: 3

  How It Works  
  Starts by reading the Seed URL from the Google Sheet.
  Scrapes each page and saves its content to the specified document.
  Extracts new links from each page that match the Links must contain string, appends them to the Google Sheet.
  Repeats steps 2–3 for the number of times specified by Depth - 1.

  Setup Requirements  
  Airtop API Key — free to generate.  
  Credentials set up for Google Docs (requires creating a project on Google Console). Read how to.  
  Credentials set up for Google Spreadsheet.

  Next Steps  
  Add Filtering Rules**: Filter which links to follow based on domain, path, or content type.  
  Combine with Scheduler**: Run this automation on a schedule to continuously explore newly discovered pages.  
  Export Structured Data**: Extend the process to store extracted data in a CSV or database for analysis.

  Read more about website scraping for LLMS

nodes_used:
  ["n8n-nodes-base.googleSheets","n8n-nodes-base.googleDocs","n8n-nodes-base.code","n8n-nodes-base.airtop"]

workflow_json:
  {"id":"3SNBO1RAF0ZIyido","meta":{"instanceId":"28a947b92b197fc2524eaba16e57560338657b2b0b5796300b2f1cedc1d0d355","templateCredsSetupCompleted":true},"name":"Website scraper","tags":[],"nodes":[{"id":"aaa5bf43-bf76-4433-93c7-7e168f2e140c","name":"On form submission","type":"n8n-nodes-base.formTrigger","position":[-400,-200],"webhookId":"6c508326-84d3-4155-9f2e-fe7ddb50f14a","parameters":{"options":{},"formTitle":"Website scraper","formFields":{"values":[{"fieldLabel":"Seed url","requiredField":true},{"fieldLabel":"Links must contain","requiredField":true},{"fieldType":"number","fieldLabel":"Depth","requiredField":true}]}},"typeVersion":2.2},{"id":"5f862a6f-8079-4d24-a2ae-7442c45c8f04","name":"Info to upload into spreadsheet","type":"n8n-nodes-base.set","position":[260,-100],"parameters":{"options":{},"assignments":{"assignments":[{"id":"5970bab1-0bfb-4212-a8f2-df6b2e003800","name":"URL","type":"string","value":"={{ $('Unify params').item.json[\"Seed url\"] }}"},{"id":"5c941ad3-70bf-4fba-8cf3-1f79c1b20d3a","name":"Scraped","type":"string","value":""}]}},"typeVersion":3.4},{"id":"556e5da4-4454-46cd-b17d-bd8695515670","name":"Load info to spreadsheet","type":"n8n-nodes-base.googleSheets","position":[480,-100],"parameters":{"columns":{"value":{},"schema":[{"id":"URL","type":"string","display":true,"removed":false,"required":false,"displayName":"URL","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"autoMapInputData","matchingColumns":["URL"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"name","value":"={{ $('Create Spreadsheet').item.json.sheets[0].properties.title }}"},"documentId":{"__rl":true,"mode":"id","value":"={{ $('Create Spreadsheet').item.json.spreadsheetId }}"}},"credentials":{"googleSheetsOAuth2Api":{"id":"DdxyhUJLGcclD2YO","name":"Google sheets Andres"}},"typeVersion":4.5},{"id":"4592ada8-8f21-4117-a0ee-8906922f5685","name":"Scrape webpage","type":"n8n-nodes-base.airtop","position":[700,-100],"parameters":{"url":"={{ $json.URL }}","resource":"extraction","operation":"scrape","profileName":"=","sessionMode":"new"},"credentials":{"airtopApi":{"id":"Yi4YPNnovLVUjFn5","name":"Airtop Official Org"}},"typeVersion":1},{"id":"74a1399d-a335-455c-a3dd-167624b4a5f2","name":"Create Google Docs","type":"n8n-nodes-base.googleDocs","position":[920,-100],"parameters":{"title":"=Site to File - {{ $('Unify params').item.json[\"Seed url\"] }}","folderId":"default"},"credentials":{"googleDocsOAuth2Api":{"id":"pDMGILToKi9P4taJ","name":"Andres Google Docs"}},"typeVersion":2},{"id":"1e69e40f-0465-430b-85ec-c6a71e1cb4a4","name":"Write scraped content","type":"n8n-nodes-base.googleDocs","position":[1140,-100],"parameters":{"actionsUi":{"actionFields":[{"text":"=The entire content from {{ $('Info to upload into spreadsheet').item.json.URL }} up to {{ $('Unify params').item.json.Depth }} levels deep.\n---------------------------------------------  \n{{ $('Scrape webpage').item.json.data.modelResponse.scrapedContent.text }}\n---------------------------------------------","action":"insert"}]},"operation":"update","documentURL":"={{ $json.id }}"},"credentials":{"googleDocsOAuth2Api":{"id":"pDMGILToKi9P4taJ","name":"Andres Google Docs"}},"typeVersion":2},{"id":"49e9b38c-c2d4-49f3-bf3f-531b10257db4","name":"Should scrape more?","type":"n8n-nodes-base.if","position":[1380,-100],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"707d2bae-e834-478b-a4f6-9e6bbfa47530","operator":{"type":"number","operation":"lt"},"leftValue":"={{ $runIndex }}","rightValue":"={{ $('Unify params').first().json.Depth - 1 }}"},{"id":"cc763610-f775-4dcb-ae29-a3235b011b75","operator":{"type":"number","operation":"gt"},"leftValue":"={{ Number($('Unify params').first().json.Depth) }}","rightValue":1}]}},"typeVersion":2.2},{"id":"239b2a02-bd66-4805-8ad3-b4ef6daa5e60","name":"Read scraped webpages","type":"n8n-nodes-base.googleSheets","position":[1580,-175],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"name","value":"={{ $('Create Spreadsheet').first().json.sheets[0].properties.title }}"},"documentId":{"__rl":true,"mode":"id","value":"={{ $('Create Spreadsheet').first().json.spreadsheetId }}"}},"credentials":{"googleSheetsOAuth2Api":{"id":"DdxyhUJLGcclD2YO","name":"Google sheets Andres"}},"typeVersion":4.5},{"id":"029d7de1-9043-424e-9c22-aed436436e6a","name":"Retrieve links to scrape","type":"n8n-nodes-base.airtop","position":[1800,-175],"parameters":{"url":"={{ $json.URL }}","prompt":"Extract the list of links that lead to other pages in the same domain","resource":"extraction","operation":"query","sessionMode":"new","additionalFields":{"outputSchema":"{\n  \"type\": \"object\",\n  \"properties\": {\n    \"internal_links\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"string\",\n        \"description\": \"A URL that leads to another page within the airtop.ai domain\"\n      },\n      \"description\": \"A list of URLs that lead to other pages within the airtop.ai domain\"\n    }\n  },\n  \"required\": [\n    \"internal_links\"\n  ],\n  \"additionalProperties\": false,\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\"\n}"}},"credentials":{"airtopApi":{"id":"Yi4YPNnovLVUjFn5","name":"Airtop Official Org"}},"typeVersion":1},{"id":"57f2a3ee-40c9-4e72-99f4-739fff04667a","name":"Filter links to insert to Sheets","type":"n8n-nodes-base.code","position":[2020,-180],"parameters":{"jsCode":"const modelResponse = $('Retrieve links to scrape').first().json.data.modelResponse;\nconst containsString = $('Unify params').first().json[\"Links must contain\"];\nconst parsed = JSON.parse(modelResponse);\nconst links = [...new Set(parsed.internal_links)]; \nconst sheetsLinks = $input.all().map(item => item.json.URL)\nlet response; \n\nif(containsString === \"\"){\n  response = links\n    .map(item =>(\n        { json: { link: item.split('?')[0] } }\n    ))\n} else {\n  response = links\n    .map(item =>\n      item.includes(containsString)\n        ? { json: { link: item.split('?')[0] } }\n        : null\n    )\n    .filter(item => item !== null);\n}\nconst dedupeBetweenSheetsAndModel = response.filter(item => !sheetsLinks.includes(item.json.link));\nconst deduped = [...new Map(dedupeBetweenSheetsAndModel.map(item => [item.json.link, item])).values()]\nreturn deduped\n"},"typeVersion":2},{"id":"6a0f20e8-df45-4799-8162-21d427e19e49","name":"Insert new links","type":"n8n-nodes-base.googleSheets","position":[2240,-175],"parameters":{"columns":{"value":{"URL":"={{ $json.link }}"},"schema":[{"id":"URL","type":"string","display":true,"removed":false,"required":false,"displayName":"URL","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Scraped","type":"string","display":true,"removed":false,"required":false,"displayName":"Scraped","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"name","value":"={{ $('Create Spreadsheet').first().json.sheets[0].properties.title }}"},"documentId":{"__rl":true,"mode":"id","value":"={{ $('Create Spreadsheet').first().json.spreadsheetId }}"}},"credentials":{"googleSheetsOAuth2Api":{"id":"DdxyhUJLGcclD2YO","name":"Google sheets Andres"}},"typeVersion":4.5},{"id":"9433ab9e-b562-4aa3-a311-ae2a355ce774","name":"Scrape webpage1","type":"n8n-nodes-base.airtop","position":[2460,-175],"parameters":{"url":"={{ $json.URL }}","resource":"extraction","operation":"scrape","sessionMode":"new"},"credentials":{"airtopApi":{"id":"Yi4YPNnovLVUjFn5","name":"Airtop Official Org"}},"typeVersion":1},{"id":"704c25cf-b690-492d-a759-7b24a870edf4","name":"Update with new scraped content","type":"n8n-nodes-base.googleDocs","position":[2680,-175],"parameters":{"actionsUi":{"actionFields":[{"text":"=-------------------------  \n{{ $json.data.modelResponse.scrapedContent.text }}\n-------------------------","action":"insert"}]},"operation":"update","documentURL":"={{ $('Create Google Docs').first().json.id }}"},"credentials":{"googleDocsOAuth2Api":{"id":"pDMGILToKi9P4taJ","name":"Andres Google Docs"}},"typeVersion":2},{"id":"14f1465d-3d7d-4b7a-87d2-2552b9514e37","name":"Flag scraped link","type":"n8n-nodes-base.set","position":[2900,-175],"parameters":{"options":{},"assignments":{"assignments":[{"id":"72c9cd92-fd01-4339-b9fe-52477b691df3","name":"URL","type":"string","value":"={{ $('Insert new links').item.json.URL }}"},{"id":"a817116e-6ae5-4e0a-b210-4fd27f5a455a","name":"Scraped","type":"string","value":"={{ $runIndex }}"}]}},"typeVersion":3.4},{"id":"364513e7-39c0-47af-83bd-475ffb0ae2a0","name":"Insert flag","type":"n8n-nodes-base.googleSheets","position":[3120,-100],"parameters":{"columns":{"value":{"URL":"={{ $('Insert new links').item.json.URL }}"},"schema":[{"id":"URL","type":"string","display":true,"removed":false,"required":false,"displayName":"URL","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Scraped","type":"string","display":true,"removed":false,"required":false,"displayName":"Scraped","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":"autoMapInputData","matchingColumns":["URL"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"update","sheetName":{"__rl":true,"mode":"name","value":"={{ $('Create Spreadsheet').first().json.sheets[0].properties.title }}"},"documentId":{"__rl":true,"mode":"id","value":"={{ $('Create Spreadsheet').first().json.spreadsheetId }}"}},"credentials":{"googleSheetsOAuth2Api":{"id":"DdxyhUJLGcclD2YO","name":"Google sheets Andres"}},"typeVersion":4.5},{"id":"bd799398-e6c6-4cd4-a8a9-d189acabb194","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-20,-220],"parameters":{"width":660,"height":280,"content":"## Create Spreadsheet\nCreate a spreadsheet to track all the links found on the webpage."},"typeVersion":1},{"id":"7a5aeddd-9c0f-4ea2-8452-35dd14e6963a","name":"Create Spreadsheet","type":"n8n-nodes-base.googleSheets","position":[40,-100],"parameters":{"title":"=Site map -  {{ $json[\"Seed url\"] }} (Depth - {{ $json.Depth }})","options":{},"resource":"spreadsheet"},"credentials":{"googleSheetsOAuth2Api":{"id":"DdxyhUJLGcclD2YO","name":"Google sheets Andres"}},"typeVersion":4.5},{"id":"19a6c42b-8be5-4599-bc60-99f0b09e3623","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[660,-220],"parameters":{"color":4,"width":180,"height":280,"content":"## Scrape webpage"},"typeVersion":1},{"id":"5de141f9-9e1e-4159-8611-06d23ee7b476","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[860,-220],"parameters":{"width":440,"height":280,"content":"## Create Doc\nCreate a document to store all the information scraped from the webpage."},"typeVersion":1},{"id":"a9108190-01d9-4c9a-a7b0-9ea582026acb","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1320,-280],"parameters":{"width":1980,"height":380,"content":"## Recursive Scraping Process\nReads a list of URLs from a Google Sheet, scrapes each page, saves the content to a doc, and adds new links back to the sheet. Repeats the process for each depth level, up to the defined scraping depth minus one."},"typeVersion":1},{"id":"bec8b412-51e1-45df-95b5-ae4e4aeb1fc2","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-1160,-540],"parameters":{"color":7,"width":660,"height":940,"content":"README\n# Recursive Web Scraping \n\n## Use Case  \nAutomating web scraping with recursive depth is ideal for collecting content across multiple linked pages—perfect for content aggregation, lead generation, or research projects.\n\n## What This Automation Does  \nThis automation reads a list of URLs from a Google Sheet, scrapes each page, stores the content in a document, and adds newly discovered links back to the sheet. It continues this process for a specified number of iterations based on the defined scraping depth.\n\n### Input Parameters:\n- `Seed URL`: The starting URL to begin the scraping process.  \n  Example: `https://example.com/`\n- `Links must contain`: Restricts the links to those that contain this specified string.  \n  Example: `https://example.com/`\n- `Depth`: The number of iterations (layers of links) to scrape beyond the initial set.  \n  Example: `3`\n\n## How It Works  \n1. Starts by reading the `Seed URL` from the Google Sheet.\n2. Scrapes each page and saves its content to the specified document.\n3. Extracts new links from each page that match the `Links must contain` string, appends them to the Google Sheet.\n4. Repeats steps 2–3 for the number of times specified by `Depth - 1`.\n\n## Setup Requirements  \n1. [Airtop API Key](https://portal.airtop.ai/api-keys) — free to generate.  \n2. Credentials set up for Google Docs (requires creating a project on Google Console). Read [how to](https://docs.n8n.io/integrations/builtin/credentials/google/).  \n3. Credentials set up for Google Spreadsheet.\n\n## Next Steps  \n- **Add Filtering Rules**: Filter which links to follow based on domain, path, or content type.  \n- **Combine with Scheduler**: Run this automation on a schedule to continuously explore newly discovered pages.  \n- **Export Structured Data**: Extend the process to store extracted data in a CSV or database for analysis.\n"},"typeVersion":1},{"id":"ef3cfdbf-bd61-4452-bad0-d0154bbd893b","name":"When Executed by Another Workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[-400,0],"parameters":{"workflowInputs":{"values":[{"name":"Seed url"},{"name":"Links must contain"},{"name":"Depth","type":"number"}]}},"typeVersion":1.1},{"id":"16d54958-18b6-497f-af9e-5953a39ae0bb","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-440,-300],"parameters":{"width":400,"height":460,"content":"## Input Parameters\nRun this workflow using a form or from another workflow"},"typeVersion":1},{"id":"99cc34ec-37eb-423a-9cc5-7c1b7736d352","name":"Unify params","type":"n8n-nodes-base.set","position":[-180,-100],"parameters":{"options":{},"assignments":{"assignments":[{"id":"18e3200c-ab2a-44da-b401-eace47a3ccc0","name":"Seed url","type":"string","value":"={{ $json[\"Seed url\"] }}"},{"id":"cb21aa86-bf75-427f-bf07-70d4f2d83894","name":"Links must contain","type":"string","value":"={{ $json[\"Links must contain\"] }}"},{"id":"80bb934f-816d-43f0-9432-170047fa02a3","name":"Depth","type":"number","value":"={{ $json.Depth }}"}]}},"typeVersion":3.4}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"dffadb4b-7c72-42ec-802c-26d4f96b5ec7","connections":{"Insert flag":{"main":[[{"node":"Should scrape more?","type":"main","index":0}]]},"Unify params":{"main":[[{"node":"Create Spreadsheet","type":"main","index":0}]]},"Scrape webpage":{"main":[[{"node":"Create Google Docs","type":"main","index":0}]]},"Scrape webpage1":{"main":[[{"node":"Update with new scraped content","type":"main","index":0}]]},"Insert new links":{"main":[[{"node":"Scrape webpage1","type":"main","index":0}]]},"Flag scraped link":{"main":[[{"node":"Insert flag","type":"main","index":0}]]},"Create Google Docs":{"main":[[{"node":"Write scraped content","type":"main","index":0}]]},"Create Spreadsheet":{"main":[[{"node":"Info to upload into spreadsheet","type":"main","index":0}]]},"On form submission":{"main":[[{"node":"Unify params","type":"main","index":0}]]},"Should scrape more?":{"main":[[{"node":"Read scraped webpages","type":"main","index":0}],[]]},"Read scraped webpages":{"main":[[{"node":"Retrieve links to scrape","type":"main","index":0}]]},"Write scraped content":{"main":[[{"node":"Should scrape more?","type":"main","index":0}]]},"Load info to spreadsheet":{"main":[[{"node":"Scrape webpage","type":"main","index":0}]]},"Retrieve links to scrape":{"main":[[{"node":"Filter links to insert to Sheets","type":"main","index":0}]]},"Info to upload into spreadsheet":{"main":[[{"node":"Load info to spreadsheet","type":"main","index":0}]]},"Update with new scraped content":{"main":[[{"node":"Flag scraped link","type":"main","index":0}]]},"Filter links to insert to Sheets":{"main":[[{"node":"Insert new links","type":"main","index":0}]]},"When Executed by Another Workflow":{"main":[[{"node":"Unify params","type":"main","index":0}]]}}}


