# templates

name: Generate Logos and Images with Consistent Visual Styles using Imagen 3.0
author_name: Jimleuk
author_username: jimleuk
nodes_used: ["n8n-nodes-base.httpRequest","n8n-nodes-base.gmail","n8n-nodes-base.html"]
categories: []
created_at: 2025-05-09T08:58:19.404Z
updated_at: 2025-05-09T08:58:19.404Z
url: https://n8n.io/workflows/3954
scraped_at: 2025-06-19 22:07:56
description:
  This n8n template allows you to use AI to generate logos or images which mimic visual styles of other logos or images. The model used to generate the images is Google's Imagen 3.0.

  With this template, users will be able to automate design and marketing tasks such as creating variants of existing designs, remixing existing assets to validate different styles and explore a range of designs which would have been otherwise too expensive and time-consming previously.

  How it works
  A form trigger is used to capture the source image to reference styles from and a prompt for the target image to generate.
  The source image is passed to Gemini 2.0 to be analysed and its visual style and tone extracted as a detailed description.
  This visual style description is then combined with the user's initial target image prompt. This final prompt is given to Imagen 3.0 to generate the images.
  A quick webpage is put together with the generated images to present back to the user.
  If the user provided an email address, a copy of this HTML page will be sent.

  How to use
  Ensure the workflow is live to share the form publicly.
  The source image must be accessible to your n8n instance - either a public image of the internet or within your network.
  For best results, select a source image which has strong visual identity as these will allow the LLM to better describe it.
  For your prompt, refer to the imagen prompt guide found here: https://ai.google.dev/gemini-api/docs/image-generation#imagen-prompt-guide

  Requirements
  Gemini for LLM and Imagen model.
  Cloudinary for image CDN.
  Gmail for email sending.

  Customising this workflow
  Feel free to swap any of these out for tools and services you prefer.
  Want to fully automate? Switch the form trigger for a webhook trigger!

workflow_json:
  {"meta":{"instanceId":"408f9fb9940c3cb18ffdef0e0150fe342d6e655c3a9fac21f0f644e8bedabcd9","templateCredsSetupCompleted":true},"nodes":[{"id":"ed993205-977a-43cd-8d0b-4faef216d766","name":"Split Out","type":"n8n-nodes-base.splitOut","position":[360,-120],"parameters":{"options":{},"fieldToSplitOut":"predictions"},"typeVersion":1},{"id":"67f2bb16-ee38-4bc8-9cc7-50a44614cc3b","name":"Imagen 3.0","type":"n8n-nodes-base.httpRequest","position":[140,-120],"parameters":{"url":"https://generativelanguage.googleapis.com/v1beta/models/imagen-3.0-generate-002:predict","method":"POST","options":{},"jsonBody":"={{\n{\n  \"instances\": [\n    {\n      \"prompt\": [\n        $json.candidates[0].content.parts[0].text,\n       `Generate the following image: ${$('Variables').first().json.targetPrompt}`\n      ].join(' ')\n    }\n  ],\n  \"parameters\": {\n    \"sampleCount\": $('Variables').first().json.numberSamples.toNumber()\n  }\n}\n}}","sendBody":true,"specifyBody":"json","authentication":"predefinedCredentialType","nodeCredentialType":"googlePalmApi"},"credentials":{"googlePalmApi":{"id":"dSxo6ns5wn658r8N","name":"Google Gemini(PaLM) Api account"}},"typeVersion":4.2},{"id":"b1730c97-8c5c-48a5-90cf-7940f6c9e2d0","name":"Variables","type":"n8n-nodes-base.set","position":[-940,-120],"parameters":{"options":{},"assignments":{"assignments":[{"id":"7616f991-76d0-4dd0-9385-f08ed14e8dfa","name":"sourceStyleUrl","type":"string","value":"={{ $json.SourceImage }}"},{"id":"126cb06e-4d69-4163-ba76-c694103bf5bb","name":"targetPrompt","type":"string","value":"={{ $json.TargetPrompt }}"},{"id":"055d247b-586d-4bb8-a319-262c241df48c","name":"numberSamples","type":"string","value":"={{\n(function(numSamples) {\n  if (!numSamples) return 1;\n  if (numSamples < 0) return 1;\n  if (numSamples > 4) return 4;\n  return numSamples;\n}($json['Number of Images']))\n}}"},{"id":"77a27e0e-24f4-4358-8cdc-84552be6c0b5","name":"email","type":"string","value":"={{ $json['Your Email (Optional)'] }}"}]}},"typeVersion":3.4},{"id":"5c26062c-74cf-4140-8dcb-8688c8daec67","name":"Download Image","type":"n8n-nodes-base.httpRequest","position":[-620,-120],"parameters":{"url":"={{ $json.sourceStyleUrl }}","options":{}},"typeVersion":4.2},{"id":"20744adb-cdf5-4558-b6e6-4206d7c1f356","name":"On form submission","type":"n8n-nodes-base.formTrigger","position":[-1400,-120],"webhookId":"51f74db1-ffb4-491f-83b0-a44a7124be12","parameters":{"options":{"path":"style-copy-with-imagen3","ignoreBots":true,"buttonLabel":"Generate!","appendAttribution":true},"formTitle":"Style Copy with Imagen 3.0","formFields":{"values":[{"fieldLabel":"SourceImage","placeholder":"The image URL to copy the style from","requiredField":true},{"fieldLabel":"TargetPrompt","placeholder":"The new image to generate","requiredField":true},{"fieldType":"number","fieldLabel":"Number of Images","placeholder":"Default 1. Max. 4 images"},{"fieldType":"email","fieldLabel":"Your Email (Optional)","placeholder":"The results will be sent to this email"}]},"responseMode":"lastNode","formDescription":"Use this form to generate an image using another image as a style reference."},"typeVersion":2.2},{"id":"917db247-1be3-4814-a96d-145957aa5db3","name":"Form Validation","type":"n8n-nodes-base.if","position":[-1180,-120],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"1b440b81-06c9-4133-bfd2-8ec07c7c3734","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.SourceImage.isUrl() }}","rightValue":""}]}},"typeVersion":2.2},{"id":"65a8b617-318c-429a-b37e-45ead00dbb7e","name":"Retry Form","type":"n8n-nodes-base.form","position":[-940,60],"webhookId":"0b4c88ed-d28b-4df4-abe6-4579e17c672d","parameters":{"options":{"formTitle":"Retry Submission","buttonLabel":"Generate!","formDescription":"Please enter a URL for the source image."},"formFields":{"values":[{"fieldLabel":"SourceImage","placeholder":"The image URL to copy the style from","requiredField":true},{"fieldLabel":"TargetPrompt","placeholder":"The new image to generate","requiredField":true},{"fieldType":"number","fieldLabel":"Number of Images","placeholder":"Max. 4 images"},{"fieldLabel":"Your Email (Optional)","placeholder":"The results will be sent to this email"}]},"limitWaitTime":true},"typeVersion":1},{"id":"8a0e8dae-9f6f-488e-9977-fd89e885f30e","name":"Upload to Cloudinary","type":"n8n-nodes-base.httpRequest","position":[880,-120],"parameters":{"url":"https://api.cloudinary.com/v1_1/daglih2g8/image/upload","method":"POST","options":{},"sendBody":true,"sendQuery":true,"contentType":"multipart-form-data","authentication":"genericCredentialType","bodyParameters":{"parameters":[{"name":"file","parameterType":"formBinaryData","inputDataFieldName":"data"}]},"genericAuthType":"httpQueryAuth","queryParameters":{"parameters":[{"name":"upload_preset","value":"n8n-workflows-preset"}]}},"credentials":{"httpQueryAuth":{"id":"sT9jeKzZiLJ3bVPz","name":"Cloudinary API"}},"typeVersion":4.2},{"id":"525725ea-effe-410b-8f39-ad01ae755d1a","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1480,-340],"parameters":{"color":7,"width":760,"height":640,"content":"## 1. Ask for Source Style and Target Image\n[Learn more about the Form Trigger](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.formtrigger/)\n\nWe'll use a form interface for this template which allows the users to specify an image whose style we'll use as reference and a prompt to generate the target image. Form validation loop can be achieved by combining another form node with the IF node."},"typeVersion":1},{"id":"ba9d4bdc-b695-4acf-9593-2ce979053744","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-700,-340],"parameters":{"color":7,"width":720,"height":440,"content":"## 2. Visual Style Description using Gemini 2.0\n[Read more about Gemini Image Understanding](https://ai.google.dev/gemini-api/docs/image-understanding)\n\nThe trick to copying the style of an image is to get a multimodal LLM to describe it in detail. Using Gemini's image understanding capabilities, it can do a pretty good job to provide the comprehensive description we need."},"typeVersion":1},{"id":"455f7956-6e39-4d84-af7e-d5908d4e5307","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[40,-340],"parameters":{"color":7,"width":720,"height":440,"content":"## 3. Image Generation using Imagen 3.0\n[Read more about Imagen Image Generation](https://ai.google.dev/gemini-api/docs/image-generation#imagen)\n\nTo generate the image, we'll be using Google's Imagen 3.0 model. We'll combine the visual style description generated in the previous Gemini model with the user's target image prompt and pass this to Imagen to do its magic! The result is something very close to style transfer which produces quite convincing and impressive results."},"typeVersion":1},{"id":"0c1d5a7f-9102-4558-a830-ed558f72c086","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[780,-340],"parameters":{"color":7,"width":980,"height":600,"content":"## 4. Render Results to HTML Page\n[Learn more about the HTML node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.html)\n\nFinally for presentation, we'll render the generated images as a webpage for easier viewing using the HTML node. This page can then be sent to the user's email if provided and downloaded as a file once we land on the form ending node."},"typeVersion":1},{"id":"ccc1ff65-0416-4dae-9557-ba2f98c5ac80","name":"Convert to File1","type":"n8n-nodes-base.convertToFile","position":[1320,60],"parameters":{"options":{"encoding":"utf8","fileName":"={{ $('Variables').item.json.targetPrompt.toSnakeCase().urlEncode() }}.html"},"operation":"toText","sourceProperty":"html"},"typeVersion":1.1},{"id":"0252d373-3678-4851-819d-d36efb40dfb2","name":"Generate HTML","type":"n8n-nodes-base.html","position":[1080,-120],"parameters":{"html":"<h1>\n  {{ $('Variables').item.json.targetPrompt.toSentenceCase() }}\n</h1>\n<div class=\"gallery\">\n{{\n$input.all()\n  .chunk(2)\n  .map(row =>\n    `<div class=\"gallery-row\">\n      ${row.map(item =>\n        `<a href=\"${item.json.url}\" target=\"_blank\">\n          <img src=\"${item.json.url}\" width=\"320px\" height=\"240px\"  />\n        </a>`).join('')}\n    </div>`\n  ).join('')\n}}\n</div>\n<div class=\"fineprint\">\n  Generated by Imagen 3.0 (imagen-3.0-generate-002) @ {{ $now.format('d MMM yyyy') }}.\n</div>\n<div class=\"fineprint\">\n  <h3>Style Prompt</h3>\n  <div style=\"display:flex;gap: 10px;\">\n    <div>\n      <img\n        src=\"{{ $('Download Image').item.json.sourceStyleUrl }}\"\n        width=\"100px\"\n        height=\"auto\"\n      />\n    </div>\n    <div>\n      {{ $('Gemini 2.0').first().json.candidates[0].content.parts[0].text }}\n    </div>\n  </div>\n</div>\n<style>\n  body { padding: 32px 64px; font-family: sans-serif; background-color: #fffaf2; }\n  h1 { max-width: 640px; }\n  .gallery { display: inline-block; padding: 5px; border: 1px solid #ccc; background-color: white; margin-bottom: 32px;}\n  .gallery-row { display: flex; }\n  .gallery-row img { padding: 5px; background-color: white }\n  .gallery-row img:hover { background-color: orange; } \n  .fineprint { font-size: 0.7rem; max-width: 480px; text-align: justify;}\n  .fineprint h3 { font-size: 0.8rem; }\n</style>"},"executeOnce":true,"typeVersion":1.2},{"id":"b712bd74-8615-4080-aad2-dc0b0df0b07e","name":"Convert to File","type":"n8n-nodes-base.convertToFile","position":[580,-120],"parameters":{"options":{"fileName":"={{ $execution.id }}_{{ $itemIndex }}.{{ $json.mimeType.split('/')[1] }}","mimeType":"={{ $json.mimeType }}"},"operation":"toBinary","sourceProperty":"bytesBase64Encoded"},"typeVersion":1.1},{"id":"ee3e168a-038c-4524-93fc-ced5d4956fa1","name":"Form Ending","type":"n8n-nodes-base.form","position":[1540,60],"webhookId":"c4bacbac-0347-4c35-9333-3704630b45ef","parameters":{"options":{"formTitle":"Generation Complete"},"operation":"completion","respondWith":"returnBinary","completionTitle":"Image Generation Successful","completionMessage":"Download has started.\nOpen the HTML file to view results."},"executeOnce":true,"typeVersion":1},{"id":"c4b1648a-c7d9-46cd-af28-527f9b169ab6","name":"Has Email?","type":"n8n-nodes-base.if","position":[1320,-120],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"07d04523-f81a-4efa-b46a-cb640bcc608a","operator":{"type":"string","operation":"notEmpty","singleValue":true},"leftValue":"={{ $('Variables').item.json.email }}","rightValue":""}]}},"typeVersion":2.2},{"id":"bc0a8188-27ff-4834-9c7a-8760531f4252","name":"Send Results to Email","type":"n8n-nodes-base.gmail","position":[1540,-120],"webhookId":"de5684ed-6aa4-4c29-aac3-62e21c54c6f0","parameters":{"sendTo":"={{ $('Variables').first().json.email }}","message":"={{ $json.html }}","options":{},"subject":"=#{{$execution.id}} - Image Generated Successfully!"},"credentials":{"gmailOAuth2":{"id":"Sf5Gfl9NiFTNXFWb","name":"Gmail account"}},"typeVersion":2.1},{"id":"f18ab53b-d8e2-4625-a8f6-8b97959a15d1","name":"Image to Base64","type":"n8n-nodes-base.extractFromFile","position":[-400,-120],"parameters":{"options":{},"operation":"binaryToPropery"},"typeVersion":1},{"id":"ac6c1353-035c-4045-aed9-46285b757b98","name":"Gemini 2.0","type":"n8n-nodes-base.httpRequest","position":[-180,-120],"parameters":{"url":"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent","method":"POST","options":{},"jsonBody":"={\n    \"contents\": [{\n      \"parts\": [\n        {\n          \"inline_data\": {\n            \"mime_type\":\"{{ $('Download Image').item.binary.data.mimeType }}\",\n            \"data\": \"{{ $json.data }}\"\n          }\n        },\n        {\"text\": \"Describe the visual style of this image. Do not include any character names or IP in the description. Include names of any famous artists associated with this style if known.\"}\n      ]\n    }]\n  }","sendBody":true,"specifyBody":"json","authentication":"predefinedCredentialType","nodeCredentialType":"googlePalmApi"},"credentials":{"googlePalmApi":{"id":"dSxo6ns5wn658r8N","name":"Google Gemini(PaLM) Api account"}},"typeVersion":4.2},{"id":"fae8c5f0-9d6f-4e45-8f7a-82f361bf9b1b","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-1920,-840],"parameters":{"width":400,"height":1140,"content":"## Try It Out!\n### This n8n template allows you to use AI to generate logos or images which mimic visual styles of other logos or images. The model used to generate the images is Google's Imagen 3.0.\n\nWith this template, users will be able to automate design and marketing tasks such as creating variants of existing designs, remixing existing assets to validate different styles and explore a range of designs which would have been otherwise too expensive and time-consming previously.\n\n### How it works\n* A form trigger is used to capture the source image to reference styles from and a prompt for the target image to generate.\n* The source image is passed to Gemini 2.0 to be analysed and its visual style and tone extracted as a detailed description.\n* This visual style description is then combined with the user's initial target image prompt. This final prompt is given to Imagen 3.0 to generate the images.\n* A quick webpage is put together with the generated images to present back to the user.\n* If the user provided an email address, a copy of this HTML page will be sent.\n\n### How to use\n* Ensure the workflow is live to share the form publicly.\n* The source image must be accessible to your n8n instance - either a public image of the internet or within your network.\n\n### Requirements\n* Gemini for LLM and Imagen model.\n* Cloudinary for image CDN.\n* Gmail for email sending.\n\n### Customising this workflow\n* Feel free to swap any of these out for tools and services you prefer.\n* Want to fully automate? Switch the form trigger for a webhook trigger!\n\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!\n\nHappy Hacking!"},"typeVersion":1}],"pinData":{},"connections":{"Split Out":{"main":[[{"node":"Convert to File","type":"main","index":0}]]},"Variables":{"main":[[{"node":"Download Image","type":"main","index":0}]]},"Gemini 2.0":{"main":[[{"node":"Imagen 3.0","type":"main","index":0}]]},"Has Email?":{"main":[[{"node":"Send Results to Email","type":"main","index":0}]]},"Imagen 3.0":{"main":[[{"node":"Split Out","type":"main","index":0}]]},"Retry Form":{"main":[[{"node":"Form Validation","type":"main","index":0}]]},"Generate HTML":{"main":[[{"node":"Convert to File1","type":"main","index":0},{"node":"Has Email?","type":"main","index":0}]]},"Download Image":{"main":[[{"node":"Image to Base64","type":"main","index":0}]]},"Convert to File":{"main":[[{"node":"Upload to Cloudinary","type":"main","index":0}]]},"Form Validation":{"main":[[{"node":"Variables","type":"main","index":0}],[{"node":"Retry Form","type":"main","index":0}]]},"Image to Base64":{"main":[[{"node":"Gemini 2.0","type":"main","index":0}]]},"Convert to File1":{"main":[[{"node":"Form Ending","type":"main","index":0}]]},"On form submission":{"main":[[{"node":"Form Validation","type":"main","index":0}]]},"Upload to Cloudinary":{"main":[[{"node":"Generate HTML","type":"main","index":0}]]},"Send Results to Email":{"main":[[]]}}}


name: Summarise Slack Channel Activity for Weekly Reports with AI
author_name: Jimleuk
author_username: jimleuk
categories: []
created_at: 2025-05-10T08:37:45.163Z
updated_at: 2025-05-10T08:37:45.163Z
url: https://n8n.io/workflows/3969
scraped_at: 2025-06-19 22:07:56
description:
  This n8n template lets you summarize team member activity on Slack for the past week and generates a report.

  For remote teams, chat is a crucial communication tool to ensure work gets done but with so many conversations happening at once and in multiple threads, ideas, information and decisions usually live in the moment and get lost just as quickly - and all together forgotten by the weekend!

  Using this template, this doesn't have to be the case. Have AI crawl through last week's activity, summarize all threads and generate a casual and snappy report to bring the team back into focus for the current week. A project manager's dream!

  How it works
  A scheduled trigger is set to run every Monday at 6am to gather all team channel messages within the last week.
  Each message thread are grouped by user and data mined for replies.
  Combined, an AI analyses the raw messages to pull out interesting observations and highlights.
  The summarized threads of the user are then combined together and passed to another AI agent to generate a higher level overview of their week. These are referred to as the individual reports.
  Next, all individual reports are summarized together into a team weekly report. This allows understanding of group and similar activities.
  Finally, the team weekly report is posted back to the channel. The timing is important as it should be the first message of the week and ready for the team to glance over coffee.

  How to use
  Ideally works best per project and where most of the comms happens on a single channel. Avoid combining channels and instead duplicate this workflow for more channels.
  You may need to filter for specific team members if you want specific team updates.
  Customise the report to suit your organisation, team or the channel. You may prefer to be more formal if clients or external stakeholders are also present.

  Requirements
  Slack for chat platform
  Gemini for LLM (or switch for other models)

  Customising this workflow
  If the slack channel is busy enough already, consider posting the final report to email.
  Pull in project metrics to include in your report. As extra context, it may be interesting to tie the messages to production performance.
  Use an AI Agent to query for knowledgebase or tickets relevant to the messages. This may be useful for attaching links or references to add context.
  Channel not so busy or way too busy for 1 week? Play with the scheduled trigger and set an interval which works for your team. 

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

workflow_json:
  {"meta":{"instanceId":"408f9fb9940c3cb18ffdef0e0150fe342d6e655c3a9fac21f0f644e8bedabcd9","templateCredsSetupCompleted":true},"nodes":[{"id":"f4322829-1799-4954-a75a-b40e95f41c10","name":"Get Last Week's Messages","type":"n8n-nodes-base.slack","position":[-2200,-160],"webhookId":"8078218a-7edc-4e0b-9b4d-9860bd309877","parameters":{"filters":{"oldest":"={{ $now.minus('1', 'week') }}","inclusive":false},"resource":"channel","channelId":{"__rl":true,"mode":"list","value":"C06RS1WPUQ6","cachedResultName":"general"},"operation":"history","returnAll":true},"credentials":{"slackApi":{"id":"VfK3js0YdqBdQLGP","name":"Slack account"}},"typeVersion":2.3},{"id":"f0e89c19-ee1f-4a4d-8176-c222c18e0514","name":"Simplify Message","type":"n8n-nodes-base.set","position":[-1320,380],"parameters":{"options":{},"assignments":{"assignments":[{"id":"547e8934-e6f2-47f0-b8a0-c60bd9d8a0c3","name":"ts","type":"string","value":"={{ $json.ts }}"},{"id":"22473b44-b1d9-4b85-b0d9-1a54c5511ff4","name":"userId","type":"string","value":"={{ $('Get User').first().json.id }}"},{"id":"2059b147-8b12-42c9-bee8-488dc11a0bf7","name":"userName","type":"string","value":"={{ $('Get User').first().json.name }}"},{"id":"34440ea6-ee99-4cd4-9e1c-cf561d335180","name":"type","type":"string","value":"={{ $json.type }}"},{"id":"ff1155c5-43e1-4e0e-82a8-9e013a7f1db1","name":"text","type":"string","value":"={{ $json.text.replace(/(<@[^>]+>)/ig, '').trim() }}"}]}},"typeVersion":3.4},{"id":"1293a7cf-1467-432f-b7ed-606146618808","name":"Group By User","type":"n8n-nodes-base.code","position":[-2000,-160],"parameters":{"jsCode":"const keyByUser = $input.all()\n  .map(item => item.json)\n  .reduce((acc, message) => {\n    return {\n      ...acc,\n      [message.user]: Array.isArray(acc[message.user])\n        ?  acc[message.user].concat(message)\n        : [message]\n    }\n  }, {});\n\nreturn {\n  data: Object\n    .keys(keyByUser)\n    .map(key => keyByUser[key])\n};"},"typeVersion":2},{"id":"681a2368-9688-4ebd-bb88-f48c7ccb3e54","name":"Split Out","type":"n8n-nodes-base.splitOut","position":[-1800,-160],"parameters":{"options":{},"fieldToSplitOut":"data"},"typeVersion":1},{"id":"38a5e6b0-ba4a-4aaa-93f2-ec2a73e5e1af","name":"Messages to Items","type":"n8n-nodes-base.code","position":[-1540,380],"parameters":{"jsCode":"return Object.values($('Switch').first().json.data)"},"typeVersion":2},{"id":"066e40ef-91d7-4db0-95bb-2027c9251a23","name":"Get User","type":"n8n-nodes-base.slack","position":[-1760,380],"webhookId":"042e9c13-5038-433a-98dc-8b6d83c015de","parameters":{"user":{"__rl":true,"mode":"id","value":"={{ $json.data['0'].user }}"},"resource":"user"},"credentials":{"slackApi":{"id":"VfK3js0YdqBdQLGP","name":"Slack account"}},"typeVersion":2.3},{"id":"c5d0b4d1-94eb-4e14-9985-85d384d6d96f","name":"Aggregate","type":"n8n-nodes-base.aggregate","position":[-1100,380],"parameters":{"options":{},"aggregate":"aggregateAllItemData","destinationFieldName":"messages"},"typeVersion":1},{"id":"47537a27-90d9-4edc-b9f4-66205bc4a4c2","name":"Split Out1","type":"n8n-nodes-base.splitOut","position":[-1760,780],"parameters":{"options":{},"fieldToSplitOut":"data.messages"},"typeVersion":1},{"id":"6fdd0fc0-c563-46a3-afb2-48853d3e6cef","name":"Get Thread","type":"n8n-nodes-base.slack","position":[-1100,780],"webhookId":"c3ef27dc-2648-4f91-b329-89a7fa833797","parameters":{"ts":"={{ $json.ts }}","filters":{},"resource":"channel","channelId":{"__rl":true,"mode":"list","value":"C06RS1WPUQ6","cachedResultName":"general"},"operation":"replies"},"credentials":{"slackApi":{"id":"VfK3js0YdqBdQLGP","name":"Slack account"}},"typeVersion":2.3},{"id":"0fc6664f-9076-4525-acaa-0f5009de2611","name":"Aggregate1","type":"n8n-nodes-base.aggregate","position":[-440,860],"parameters":{"options":{},"aggregate":"aggregateAllItemData","destinationFieldName":"replies"},"typeVersion":1},{"id":"caf963e5-3d5b-42d8-88ce-1fb5bf03a528","name":"Simplify Thread Comments","type":"n8n-nodes-base.set","position":[-660,780],"parameters":{"options":{},"assignments":{"assignments":[{"id":"82bc8cbe-c606-4717-b29d-2d8acc149271","name":"ts","type":"string","value":"={{ $json.ts }}"},{"id":"8fcc957d-aa9f-47df-99e8-560228fde30f","name":"userId","type":"string","value":"={{ $json.user }}"},{"id":"e6c6deb3-c3ba-4452-be7c-1a0c42c5dc2c","name":"userName","type":"string","value":""},{"id":"31d1206d-ecbd-48d3-a00a-845fd53d1cfa","name":"type","type":"string","value":"={{ $json.type }}"},{"id":"da126e6c-8dfc-41aa-991a-231b3cb3004b","name":"text","type":"string","value":"={{ $json.text }}"}]}},"typeVersion":3.4},{"id":"aab0ae1c-50da-49e5-a373-c32b39108041","name":"Filter","type":"n8n-nodes-base.filter","position":[-880,780],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"a6d43072-380e-40f2-985b-faeffdaffdce","operator":{"type":"string","operation":"notEquals"},"leftValue":"={{ $('Split Out1').item.json.ts }}","rightValue":"={{ $json.ts }}"}]}},"typeVersion":2.2,"alwaysOutputData":true},{"id":"35cdb470-a9eb-4544-999c-5360dda0f1a3","name":"Message Ref","type":"n8n-nodes-base.noOp","position":[-1320,780],"parameters":{},"typeVersion":1},{"id":"95500787-7965-4951-a729-615feb636021","name":"Split Out2","type":"n8n-nodes-base.splitOut","position":[-1320,1080],"parameters":{"options":{},"fieldToSplitOut":"replyUsers"},"typeVersion":1},{"id":"250d61cc-120d-4c0c-8220-f9a68a90b667","name":"Map Reply UserIds","type":"n8n-nodes-base.set","position":[-1760,1160],"parameters":{"options":{},"assignments":{"assignments":[{"id":"dda6e3d8-0097-4621-9619-07cf39e93018","name":"replyUsers","type":"array","value":"={{\n$json.data.messages\n  .flatMap(item => item.replies.flatMap(reply => reply.userId))\n  .compact()\n  .unique()\n}}"}]}},"typeVersion":3.4},{"id":"3358736b-fc6e-4e18-9a58-4ffc59308055","name":"Get Reply Users","type":"n8n-nodes-base.slack","position":[-1100,1080],"webhookId":"c9ad7c7e-2c48-4c24-9255-e04ab26252ab","parameters":{"user":{"__rl":true,"mode":"id","value":"={{ $json.replyUsers }}"},"resource":"user"},"credentials":{"slackApi":{"id":"VfK3js0YdqBdQLGP","name":"Slack account"}},"typeVersion":2.3},{"id":"e98acd0f-f1e3-47f4-ae9c-7259462cf231","name":"Google Gemini Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[-120,1380],"parameters":{"options":{},"modelName":"models/gemini-2.0-flash"},"credentials":{"googlePalmApi":{"id":"dSxo6ns5wn658r8N","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"0ffb9b87-43db-4417-8c37-384a33cbb830","name":"Summarise Threads","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[-220,1160],"parameters":{"text":"=## Message\n{{ $json.userName }} (<@{{ $json.userId }}>) says at {{ new DateTime(parseFloat($json.ts)*1000).format('d MMM HH:mma') }}:\n> {{ $json.text }}\n\n## {{ ($json.replies ?? []).compact().length }} Replies\n{{\n($json.replies ?? [])\n  .compact()\n    .map(reply => ({\n      ...reply,\n      userName: $('Reply Users').item.json.data\n        .find(user => user.id === reply.userId)?.name\n    }))\n    .map(reply =>\n      `* ${new DateTime(parseFloat($json.ts)*1000).format('d MMM HH:mma')}, ${reply.userName} (<@${reply.userId}>) replies: ${reply.text}`\n)\n    .join('\\n')\n  \n}}","messages":{"messageValues":[{"message":"=Summarize the topic of the slack message and the resulting conversation from the replies (if any). Highlight any achievements, accomplishments, attempts or challenges mentioned."}]},"promptType":"define"},"typeVersion":1.6},{"id":"678a48ec-acb1-4c42-b8c9-d4cd762e4a2a","name":"Aggregate2","type":"n8n-nodes-base.aggregate","position":[160,1160],"parameters":{"options":{},"aggregate":"aggregateAllItemData"},"typeVersion":1},{"id":"ab39b117-e1bd-495f-a92d-fb79973b3601","name":"Aggregate Reply Users","type":"n8n-nodes-base.aggregate","position":[-880,1080],"parameters":{"options":{},"aggregate":"aggregateAllItemData"},"typeVersion":1},{"id":"c71b7ca6-8245-4262-b2f1-abea511390d6","name":"Reply Users","type":"n8n-nodes-base.set","position":[-660,1160],"parameters":{"options":{},"assignments":{"assignments":[{"id":"9f721cde-2d36-40ee-b7d8-a920695157a9","name":"data","type":"array","value":"={{ $json.data ?? [] }}"}]}},"typeVersion":3.4},{"id":"4b2c452b-4e68-4536-aa58-a85fd586c606","name":"Google Gemini Chat Model1","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[-460,0],"parameters":{"options":{},"modelName":"models/gemini-2.0-flash"},"credentials":{"googlePalmApi":{"id":"dSxo6ns5wn658r8N","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"d65b4f27-52ab-4c29-8692-ee2835fddd17","name":"Loop Over Items","type":"n8n-nodes-base.splitInBatches","position":[-1540,780],"parameters":{"options":{}},"typeVersion":3},{"id":"cfb55c7f-a89d-4ce4-8709-31e5e119c6ee","name":"Aggregate3","type":"n8n-nodes-base.set","position":[-1320,580],"parameters":{"mode":"raw","options":{},"jsonOutput":"={{\n{\n  ...$('Split Out1').item.json,\n  replies: $json.replies.filter(reply => reply.ts)\n}\n}}\n"},"typeVersion":3.4},{"id":"8b70e30c-99d5-4086-85aa-e6cfcc7f14e7","name":"Aggregate4","type":"n8n-nodes-base.aggregate","position":[-1100,580],"parameters":{"options":{},"aggregate":"aggregateAllItemData"},"typeVersion":1},{"id":"1cef5853-d301-49cb-9f58-c1a9128b8b33","name":"When Executed by Another Workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[-2200,780],"parameters":{"workflowInputs":{"values":[{"name":"action"},{"name":"data","type":"object"}]}},"typeVersion":1.1},{"id":"b30c2433-3bfe-480f-a4bd-8c41900802a2","name":"Switch","type":"n8n-nodes-base.switch","position":[-1980,780],"parameters":{"rules":{"values":[{"outputKey":"users","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"fa924990-9f6e-40c4-aaec-50d4f5927414","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.action }}","rightValue":"users"}]},"renameOutput":true},{"outputKey":"message_replies","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"26ce01b2-9e5b-43e8-926d-9d726c9ca74d","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.action }}","rightValue":"message_replies"}]},"renameOutput":true},{"outputKey":"message_summarize","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"45fd7264-6ac3-4bbd-8a91-c4cfb33b4545","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.action }}","rightValue":"message_summarize"}]},"renameOutput":true}]},"options":{}},"typeVersion":3.2},{"id":"b05735c3-4beb-4a80-8297-85e952e81270","name":"Map Users to Messages","type":"n8n-nodes-base.executeWorkflow","position":[-1520,-160],"parameters":{"mode":"each","options":{},"workflowId":{"__rl":true,"mode":"id","value":"={{ $workflow.id }}"},"workflowInputs":{"value":{"data":"={{ $json }}","action":"users"},"schema":[{"id":"action","type":"string","display":true,"required":false,"displayName":"action","defaultMatch":false,"canBeUsedToMatch":true},{"id":"data","type":"object","display":true,"required":false,"displayName":"data","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":true}},"typeVersion":1.2},{"id":"28ed52b2-b0c3-4f19-b394-347c8ff9e323","name":"Get User Info","type":"n8n-nodes-base.set","position":[-880,380],"parameters":{"options":{},"assignments":{"assignments":[{"id":"17344879-1e10-4738-8db0-6e0daddea920","name":"user","type":"object","value":"={{\n{\n  id: $('Get User').item.json.id,\n  team_id: $('Get User').item.json.team_id,\n  name: $('Get User').item.json.name,\n  is_bot: $('Get User').item.json.is_bot\n}\n}}"}]},"includeOtherFields":true},"typeVersion":3.4},{"id":"bbd7c77e-2405-4e63-ae38-f064beafab9c","name":"Fetch Message Replies","type":"n8n-nodes-base.executeWorkflow","position":[-1300,-160],"parameters":{"mode":"each","options":{},"workflowId":{"__rl":true,"mode":"id","value":"={{ $workflow.id }}"},"workflowInputs":{"value":{"data":"={{ $json }}","action":"message_replies"},"schema":[{"id":"action","type":"string","display":true,"removed":false,"required":false,"displayName":"action","defaultMatch":false,"canBeUsedToMatch":true},{"id":"data","type":"object","display":true,"removed":false,"required":false,"displayName":"data","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":true}},"typeVersion":1.2},{"id":"edf34e72-04b4-4fed-a3af-42dec1c7ed17","name":"Has ReplyUsers?","type":"n8n-nodes-base.if","position":[-1540,1160],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"813d9fea-9de0-4151-aa45-d38a42f808b8","operator":{"type":"array","operation":"notEmpty","singleValue":true},"leftValue":"={{ $json.replyUsers }}","rightValue":""}]}},"typeVersion":2.2},{"id":"dc9c6cf0-c627-4311-9160-62204e9b67e0","name":"Messages to Items1","type":"n8n-nodes-base.code","position":[-440,1160],"parameters":{"jsCode":"return $('Switch').first().json.data.messages"},"typeVersion":2},{"id":"0b830a49-c77e-41f3-8d70-47a26bfe0a0e","name":"Aggregate Results","type":"n8n-nodes-base.set","position":[-760,-160],"parameters":{"mode":"raw","options":{},"jsonOutput":"={{\n{\n  ...$('Map Users to Messages').item.json,\n  messages: $('Fetch Message Replies').item.json.data\n  .map((message,idx) => ({\n    ...message,\n    summary: $json.data[idx].text,\n  }))\n}\n}}"},"typeVersion":3.4},{"id":"b0c66c7f-0fed-465c-8933-7b803c9b3b64","name":"Team Member Weekly Report Agent","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[-560,-160],"parameters":{"text":"={{\n$json.messages\n  .map((message,idx) =>\n    `${message.userName} (<@${message.userId}>) posted on ${new Date(parseFloat(message.ts) * 1000).format('d MMM')}:\\n> \\\"${message.text}\\\".\\nThe summary of this thread is as follows:\\n${message.summary.replaceAll('\\n', ' ')}`\n  )\n  .join('\\n---\\n')\n}}","messages":{"messageValues":[{"message":"=Your are energetic assistant who produces weekly mini-reports on team members by analysing their slack messages from last week and posts these reports on the following Monday.\nThere has already been some work done to collect and summarise each thread made by the user within the last week.\nYour task is to summarize all the threads by this user and any interactions with other users involved and produce a mini report to share with other team members.\nFocus on wins and challenges.\nAim to motivate and call out any outstanding concerns where appropriate.\nWelcome any new team members who may have joined and say good bye to those who may have left."}]},"promptType":"define"},"typeVersion":1.6},{"id":"e4a487ae-8d71-4fe6-a760-7a0fb95a8fac","name":"Merge with Results","type":"n8n-nodes-base.set","position":[-60,-160],"parameters":{"mode":"raw","options":{},"jsonOutput":"={{\n{\n  ...$('Aggregate Results').item.json,\n  report: $json.text,\n}\n}}"},"typeVersion":3.4},{"id":"06736a5c-7450-406a-ad3a-08a368d1addf","name":"Team Weekly Report Agent","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[160,-160],"parameters":{"text":"={{\n$input.all()\n  .map(item => item.json)\n  .map(item =>\n`user: ${item.user.name} <@${item.user.id}>\nmessage count: ${item.messages.length}\nreport: ${item.report.replaceAll('\\n', ' ')}`\n  ).join('\\n---\\n')\n}}","messages":{"messageValues":[{"message":"=Your are energetic assistant who produces a team-wide weekly report from all activity of all team members in the prior last week and posts this single report on the following Monday.\nThere has already been some work done to collect individual reports from team members.\nYour task is generate a report covering the team to prepare and motivate them for the upcoming week.\nFocus on wins and challenges if available.\nLook out for similar activities between members and make a connection if possible.\nAim to motivate and call out any outstanding concerns where appropriate.\nWelcome any new team members who may have joined and say good bye to those who may have left."}]},"promptType":"define"},"executeOnce":true,"typeVersion":1.6},{"id":"eef36957-9bf0-4be3-95a8-73bbefdc0c85","name":"Google Gemini Chat Model2","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[240,0],"parameters":{"options":{},"modelName":"models/gemini-2.0-flash"},"credentials":{"googlePalmApi":{"id":"dSxo6ns5wn658r8N","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"bfa5c99f-cd8f-4d34-9e6d-9ed476c87d22","name":"Post Report in Team Channel","type":"n8n-nodes-base.slack","position":[820,-160],"webhookId":"3613b3ca-fc98-427f-8903-a5996ff7552e","parameters":{"text":"={{ $json.text }}","select":"channel","channelId":{"__rl":true,"mode":"list","value":"C06RS1WPUQ6","cachedResultName":"general"},"otherOptions":{}},"credentials":{"slackApi":{"id":"VfK3js0YdqBdQLGP","name":"Slack account"}},"typeVersion":2.3},{"id":"b9a11c72-de41-4a45-85a0-672cf54ef152","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-2460,-440],"parameters":{"color":7,"width":820,"height":520,"content":"## 1. Fetch All Activity from Last Week\n[Learn more about the Slack node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.slack)\n\nWe'll start by fetching all activity in our team channel over the last 7 days and group them  by the message author. We can do this using the Slack node with a DateTime filter. This will give us the raw data to pick apart and analyse for reporting purposes."},"typeVersion":1},{"id":"8afc048f-ce06-46c3-916f-cbcf14bcfe2b","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-1620,-440],"parameters":{"color":7,"width":760,"height":520,"content":"## 2. Summarise Messages Threads & Conversations\n[Learn more about the Execute Workflow node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.executeworkflow)\n\nWe'll do some more data mining by fetching all replies for each of these top level channel messages. By doing so, we get the full context of the conversation and can hopefully pick up some decisions, discoveries or concerns to add to our report. This data mining does require juggling a lot of \"items\" which becomes hard to manage so we'll use subworkflows to simplify this work.\n\nOnce the data mining is complete, we can summarize each thread with AI and ensure we're capturing only the significant events which are report-worthy."},"typeVersion":1},{"id":"c9a7358c-fbe7-435a-b435-d7b07599bdc6","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-840,-440],"parameters":{"color":7,"width":660,"height":620,"content":"## 3. Generate Activity Reports for Each Team Member\n[Learn more about the Basic LLM node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainllm)\n\nWith our summarized threads which are grouped per user, we can aggregate them and give them to the AI again to generate a weekly report for the team member. This could include their wins, challenges, learnings or decisions - it really is up to you as to what the report looks like.\n\nA fun part of this output is getting to decide the tone of voice and delivery of the report. Don't be a bore and consider adding some personality and flair!"},"typeVersion":1},{"id":"add32ef0-b515-44e6-a234-0a0fa77f4e84","name":"Summarize Message Threads","type":"n8n-nodes-base.executeWorkflow","position":[-1080,-160],"parameters":{"mode":"each","options":{},"workflowId":{"__rl":true,"mode":"id","value":"={{ $workflow.id }}"},"workflowInputs":{"value":{"data":"={{\n{\n  ...$('Map Users to Messages').item.json,\n  messages: $json.data\n}\n}}","action":"message_summarize"},"schema":[{"id":"action","type":"string","display":true,"removed":false,"required":false,"displayName":"action","defaultMatch":false,"canBeUsedToMatch":true},{"id":"data","type":"object","display":true,"removed":false,"required":false,"displayName":"data","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":true}},"typeVersion":1.2},{"id":"17f2f45e-2c95-4b3c-b6db-a2881ae88964","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-160,-440],"parameters":{"color":7,"width":680,"height":620,"content":"## 4. Generate Final Report for Whole Team\n[Learn more about the Basic LLM node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainllm)\n\nIn this step, we go one level higher and aggregate all individual team member reports together into a big team report. In this way, the overview can group similar activities and generalise activities in a broader sense. The message output will also be shorter which some may find easier to digest."},"typeVersion":1},{"id":"18cc7fa7-603c-4165-97c6-80d72fd4a9a6","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[540,-440],"parameters":{"color":7,"width":680,"height":620,"content":"## 5. Post Report on Team Channel (on Monday Morning!)\n[Learn more about the Slack node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.slack)\n\nFinally, we can post the weekly report in the team channel. This is a great way to automate quick recaps for the team after the weekend break, get others back on track if they've been away or update client team who may pop in now and again to collaborate."},"typeVersion":1},{"id":"9cd8bdd6-5fc7-4e44-bcd0-058bc5d11335","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-2460,360],"parameters":{"color":7,"width":560,"height":340,"content":"## 5. SubWorkflows\n[Read more about Execute Workflow Trigger](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.executeworkflowtrigger)\n\nIncorporating Subworkflows into your main workflow is an advanced technique and sometimes necessary if you're working with a lot of nested items or loops.\n\nIn this scenario, we perform quite a few lookups to get the data we need; users, messages and replies, which in template terms would require many loop nodes to string together. However, when you nest loops nodes within loop nodes, item reference becomes difficult to keep track of.\n\nUsing subworkflows, we can break down each loop into a separate execution which handles items and item references in a simpler, linear way. The result is predictable data flow throughout our template. "},"typeVersion":1},{"id":"6f6fc730-5fc8-4dcc-b86d-e3b2f0e792a0","name":"Monday @ 6am","type":"n8n-nodes-base.scheduleTrigger","position":[-2400,-160],"parameters":{"rule":{"interval":[{"field":"cronExpression","expression":"0 6 * * 1"}]}},"typeVersion":1.2},{"id":"ab94557c-debb-425c-ac83-62e39e43d28b","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-2940,-1380],"parameters":{"width":420,"height":1460,"content":"## Try It Out!\n### This n8n template lets you summarize individual team member activity on slack for the past week and generates a report.\n\nFor remote teams, chat is a crucial communication tool to ensure work gets done but with so many conversations happening at once and in multiple threads, ideas, information and decisions usually live in the moment and get lost just as quickly - and all together forgotten by the weekend!\n\nUsing this template, this doesn't have to be the case. Have AI crawl through last week's activity, summarize all threads and generate a casual and snappy report to bring the team back into focus for the current week. A project manager's dream!\n\n### How it works\n* A scheduled trigger is set to run every Monday at 6am to gather all team channel messages within the last week.\n* Each message thread are grouped by user and data mined for replies.\n* Combined, an AI analyses the raw messages to pull out interesting observations and highlights.\n* The summarized threads of the user are then combined together and passed to another AI agent to generate a higher level overview of their week. These are referred to as the individual reports.\n* Next, all individual reports are summarized together into a team weekly report. This allows understanding of group and similar activities.\n* Finally, the team weekly report is posted back to the channel. The timing is important as it should be the first message of the week and ready for the team to glance over coffee.\n\n### How to use\n* Ideally works best per project and where most of the comms happens on a single channel. Avoid combining channels and instead duplicate this workflow for more channels.\n* You may need to filter for specific team members if you want specific team updates.\n* Customise the report to suit your organisation, team or the channel. You may prefer to be more formal if clients or external stakeholders are also present.\n\n### Requirements\n* Slack for chat platform\n* Gemini for LLM\n\n### Customising this workflow\n* If the slack channel is busy enough already, consider posting the final report to email.\n* Pull in project metrics to include in your report. As extra context, it may be interesting to tie the messages to production performance.\n* Use an AI Agent to query for knowledgebase or tickets relevant to the messages. This may be useful for attaching links or references to add context.\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!\n\nHappy Hacking!"},"typeVersion":1}],"pinData":{},"connections":{"Filter":{"main":[[{"node":"Simplify Thread Comments","type":"main","index":0}]]},"Switch":{"main":[[{"node":"Get User","type":"main","index":0}],[{"node":"Split Out1","type":"main","index":0}],[{"node":"Map Reply UserIds","type":"main","index":0}]]},"Get User":{"main":[[{"node":"Messages to Items","type":"main","index":0}]]},"Aggregate":{"main":[[{"node":"Get User Info","type":"main","index":0}]]},"Split Out":{"main":[[{"node":"Map Users to Messages","type":"main","index":0}]]},"Aggregate1":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Aggregate2":{"main":[[]]},"Aggregate3":{"main":[[{"node":"Aggregate4","type":"main","index":0}]]},"Aggregate4":{"main":[[]]},"Get Thread":{"main":[[{"node":"Filter","type":"main","index":0}]]},"Split Out1":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Split Out2":{"main":[[{"node":"Get Reply Users","type":"main","index":0}]]},"Message Ref":{"main":[[{"node":"Get Thread","type":"main","index":0}]]},"Reply Users":{"main":[[{"node":"Messages to Items1","type":"main","index":0}]]},"Monday @ 6am":{"main":[[{"node":"Get Last Week's Messages","type":"main","index":0}]]},"Group By User":{"main":[[{"node":"Split Out","type":"main","index":0}]]},"Get Reply Users":{"main":[[{"node":"Aggregate Reply Users","type":"main","index":0}]]},"Has ReplyUsers?":{"main":[[{"node":"Split Out2","type":"main","index":0}],[{"node":"Reply Users","type":"main","index":0}]]},"Loop Over Items":{"main":[[{"node":"Aggregate3","type":"main","index":0}],[{"node":"Message Ref","type":"main","index":0}]]},"Simplify Message":{"main":[[{"node":"Aggregate","type":"main","index":0}]]},"Aggregate Results":{"main":[[{"node":"Team Member Weekly Report Agent","type":"main","index":0}]]},"Map Reply UserIds":{"main":[[{"node":"Has ReplyUsers?","type":"main","index":0}]]},"Messages to Items":{"main":[[{"node":"Simplify Message","type":"main","index":0}]]},"Summarise Threads":{"main":[[{"node":"Aggregate2","type":"main","index":0}]]},"Merge with Results":{"main":[[{"node":"Team Weekly Report Agent","type":"main","index":0}]]},"Messages to Items1":{"main":[[{"node":"Summarise Threads","type":"main","index":0}]]},"Aggregate Reply Users":{"main":[[{"node":"Reply Users","type":"main","index":0}]]},"Fetch Message Replies":{"main":[[{"node":"Summarize Message Threads","type":"main","index":0}]]},"Map Users to Messages":{"main":[[{"node":"Fetch Message Replies","type":"main","index":0}]]},"Get Last Week's Messages":{"main":[[{"node":"Group By User","type":"main","index":0}]]},"Google Gemini Chat Model":{"ai_languageModel":[[{"node":"Summarise Threads","type":"ai_languageModel","index":0}]]},"Simplify Thread Comments":{"main":[[{"node":"Aggregate1","type":"main","index":0}]]},"Team Weekly Report Agent":{"main":[[{"node":"Post Report in Team Channel","type":"main","index":0}]]},"Google Gemini Chat Model1":{"ai_languageModel":[[{"node":"Team Member Weekly Report Agent","type":"ai_languageModel","index":0}]]},"Google Gemini Chat Model2":{"ai_languageModel":[[{"node":"Team Weekly Report Agent","type":"ai_languageModel","index":0}]]},"Summarize Message Threads":{"main":[[{"node":"Aggregate Results","type":"main","index":0}]]},"Team Member Weekly Report Agent":{"main":[[{"node":"Merge with Results","type":"main","index":0}]]},"When Executed by Another Workflow":{"main":[[{"node":"Switch","type":"main","index":0}]]}}}


name: Personalized AI Tech Newsletter Using RSS, OpenAI and Gmail
author_name: Miha
author_username: miha
categories: []
created_at: 2025-05-11T19:47:23.634Z
updated_at: 2025-05-11T19:47:23.634Z
url: https://n8n.io/workflows/3986
scraped_at: 2025-06-19 22:07:56
description:
  Combine Tech News in a Personalized Weekly Newsletter

  This n8n template automates the collection, storage, and summarization of technology news from top sites, turning it into a concise, personalized weekly newsletter.

  If you like staying informed but want to reduce daily distractions, this workflow is perfect for you. It leverages RSS feeds, vector databases, and LLMs to read and curate tech content on your behalf—so you only receive what truly matters.

  How it works

  A daily scheduled trigger fetches articles from multiple popular tech RSS feeds like Wired, TechCrunch, and The Verge.
  Fetched articles are:

    Normalized to extract titles, summaries, and publish dates.
    Converted to vector embeddings via OpenAI and stored in memory for fast semantic querying.
  A weekly scheduled trigger activates the AI summarization flow:

    The AI is provided with your interests (e.g., AI, games, gadgets) and the desired number of items (e.g., 15).
    It queries the vector store to retrieve relevant articles and summarizes the most newsworthy stories.
    The summary is converted into a clean, email-friendly format and sent to your inbox.

  How to use

  Connect your OpenAI and Gmail accounts to n8n.
  Customize the list of RSS feeds in the “Set Tech News RSS Feeds” node.
  Update your interests and number of desired news items in the “Your Topics of Interest” node.
  Activate the workflow and let the automation run on schedule.

  Requirements

  OpenAI** credentials for embeddings and summarization
  Gmail** (or another email service) for sending the newsletter

  Customizing this workflow

  Want to use different sources? Swap in your own RSS feeds, or use an API-based news aggregator.
  Replace the in-memory vector store with Pinecone, Weaviate, or another persistent vector DB for longer-term storage.
  Adjust the agent's summarization style to suit internal updates, industry-specific briefings, or even entertainment recaps.
  Prefer chat over email? Replace the email node with a Telegram bot to receive your personalized tech newsletter directly in a Telegram chat.

nodes_used:
  ["n8n-nodes-base.gmail","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.embeddingsOpenAi","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter","@n8n/n8n-nodes-langchain.vectorStoreInMemory","@n8n/n8n-nodes-langchain.documentDefaultDataLoader"]

workflow_json:
  {"id":"ni6SfqC3kthAlPtX","meta":{"instanceId":"a2eaba9e45ad7aab18b25cf863df1e910fb6dd3b85279bde97d9bae4a72f6862","templateCredsSetupCompleted":true},"name":"Personalized AI Tech Newsletter Using RSS, OpenAI and Gmail","tags":[],"nodes":[{"id":"5cc6bfe1-dbaa-4196-ac52-27e3d5b7e91d","name":"Split Out","type":"n8n-nodes-base.splitOut","position":[420,-300],"parameters":{},"typeVersion":1},{"id":"c696de41-aeb1-4e2c-9e7e-8b04f7800bdb","name":"Embeddings OpenAI","type":"@n8n/n8n-nodes-langchain.embeddingsOpenAi","position":[960,-100],"parameters":{},"typeVersion":1.2},{"id":"4b127a8f-14b3-4a0e-86f6-3157c59bc09c","name":"Default Data Loader","type":"@n8n/n8n-nodes-langchain.documentDefaultDataLoader","position":[1120,-140],"parameters":{},"typeVersion":1},{"id":"c32d87cd-28ee-4b28-ad53-43320169b6df","name":"Recursive Character Text Splitter","type":"@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter","position":[1260,0],"parameters":{},"typeVersion":1},{"id":"c912148b-1142-4713-9769-1588ff308c62","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[400,520],"parameters":{},"typeVersion":1.2},{"id":"ba7aef6b-efec-4c35-a9d6-b2b8afb6b6c4","name":"Get Articles Daily","type":"n8n-nodes-base.scheduleTrigger","position":[-20,-300],"parameters":{},"typeVersion":1.2},{"id":"0827bf1b-1322-4e4a-8c5b-0da90382b202","name":"Send Weekly Summary","type":"n8n-nodes-base.scheduleTrigger","position":[-40,360],"parameters":{},"typeVersion":1.2},{"id":"b1625ec0-fd2f-4098-ba79-1f522123cb86","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-100,-460],"parameters":{"content":""},"typeVersion":1},{"id":"7edbdba1-43ac-4754-91ae-d506ee38e8ff","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-100,200],"parameters":{"content":""},"typeVersion":1},{"id":"e166715b-f579-4d22-bf2f-9318e4e86f2a","name":"News reader AI","type":"@n8n/n8n-nodes-langchain.agent","position":[420,300],"parameters":{},"typeVersion":1.9},{"id":"c88c6c60-493e-41cf-b08d-3eef48e7cbc4","name":"Send Newsletter","type":"n8n-nodes-base.gmail","position":[1020,360],"webhookId":"0de8b6e8-8611-48a9-ba25-1d023698f577","parameters":{},"typeVersion":2.1},{"id":"8e303102-f68c-4cf8-a2bb-4538830610e6","name":"Convert Response to an Email-Friendly Format","type":"n8n-nodes-base.markdown","position":[780,300],"parameters":{},"typeVersion":1},{"id":"3f90c79c-a04d-4537-b426-33900acfcb8a","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[120,300],"parameters":{"content":""},"typeVersion":1},{"id":"de315b7c-065c-45a7-be50-5d7a4eedeeaf","name":"Your topics of interest","type":"n8n-nodes-base.set","position":[180,360],"parameters":{},"typeVersion":3.4},{"id":"8a1d6ac3-6fda-4916-a021-3d5db7d413e0","name":"Store News Articles","type":"@n8n/n8n-nodes-langchain.vectorStoreInMemory","position":[1080,-300],"parameters":{},"typeVersion":1.1},{"id":"b7fd5c59-3ed7-4706-bdd7-a62c62cd65af","name":"Set Tech News RSS Feeds","type":"n8n-nodes-base.set","position":[200,-300],"parameters":{},"typeVersion":3.4},{"id":"77f5f3bc-8ecd-481a-a570-6e49e4fda01b","name":"Read RSS News Feeds","type":"n8n-nodes-base.rssFeedRead","position":[640,-300],"parameters":{},"typeVersion":1.1},{"id":"540f55b3-10d1-4f7e-bbdf-793ae6524fd7","name":"Get News Articles","type":"@n8n/n8n-nodes-langchain.vectorStoreInMemory","position":[540,500],"parameters":{},"typeVersion":1.1},{"id":"f5e37288-ef4c-41ea-87bd-1e9ee1e9ab0f","name":"Embeddings OpenAI2","type":"@n8n/n8n-nodes-langchain.embeddingsOpenAi","position":[740,620],"parameters":{},"typeVersion":1.2},{"id":"f6e050de-8dc1-41dd-a18f-225a2f5f68ad","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[140,-360],"parameters":{"content":""},"typeVersion":1},{"id":"4d773ce7-cbca-4568-bd40-0f9914e835bb","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-580,-460],"parameters":{"content":""},"typeVersion":1},{"id":"796c2a13-c168-4bc9-b79b-fc80c31274c1","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[900,580],"parameters":{"content":""},"typeVersion":1},{"id":"4bd264b8-b088-413d-b44b-dae3b7cc3e77","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[960,300],"parameters":{"content":""},"typeVersion":1},{"id":"6d2b402d-22e0-4cc5-a070-8b4169f18a99","name":"Set and Normalize Fields","type":"n8n-nodes-base.set","position":[860,-300],"parameters":{},"typeVersion":3.4}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"9b875084-83f0-43e6-968a-caec8fb29d7b","connections":{"Split Out":{"main":[[{"node":"Read RSS News Feeds","type":"main","index":0}]]},"News reader AI":{"main":[[{"node":"Convert Response to an Email-Friendly Format","type":"main","index":0}]]},"Send Newsletter":{"main":[[]]},"Embeddings OpenAI":{"ai_embedding":[[{"node":"Store News Articles","type":"ai_embedding","index":0}]]},"Get News Articles":{"ai_tool":[[{"node":"News reader AI","type":"ai_tool","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"News reader AI","type":"ai_languageModel","index":0}]]},"Embeddings OpenAI2":{"ai_embedding":[[{"node":"Get News Articles","type":"ai_embedding","index":0}]]},"Get Articles Daily":{"main":[[{"node":"Set Tech News RSS Feeds","type":"main","index":0}]]},"Default Data Loader":{"ai_document":[[{"node":"Store News Articles","type":"ai_document","index":0}]]},"Read RSS News Feeds":{"main":[[{"node":"Set and Normalize Fields","type":"main","index":0}]]},"Send Weekly Summary":{"main":[[{"node":"Your topics of interest","type":"main","index":0}]]},"Set Tech News RSS Feeds":{"main":[[{"node":"Split Out","type":"main","index":0}]]},"Your topics of interest":{"main":[[{"node":"News reader AI","type":"main","index":0}]]},"Set and Normalize Fields":{"main":[[{"node":"Store News Articles","type":"main","index":0}]]},"Recursive Character Text Splitter":{"ai_textSplitter":[[{"node":"Default Data Loader","type":"ai_textSplitter","index":0}]]},"Convert Response to an Email-Friendly Format":{"main":[[{"node":"Send Newsletter","type":"main","index":0}]]}}}


name: AI-Generated LinkedIn Posts with OpenAI, Google Sheets & Email Approval Workflow
author_name: Aryan Shinde
author_username: shindearyan
categories: []
created_at: 2025-05-12T23:11:35.083Z
updated_at: 2025-05-12T23:11:35.083Z
url: https://n8n.io/workflows/4005
scraped_at: 2025-06-19 22:07:56
description:
  How it works
  This workflow automates the process of creating, approving, and optionally posting LinkedIn content from a Google Sheet. Here's a high-level overview:
  Scheduled Trigger: Runs automatically based on your defined time interval (daily, weekly, etc.).
  Fetch Data from Google Sheets: Pulls the first row from your sheet where Status is marked as Pending.
  Generate LinkedIn Post Content: Uses OpenAI to create a professional LinkedIn post using the Post Description and Instructions from the sheet.
  Format & Prepare Data: Formats the generated content along with the original instruction and post description for email.
  Send for Approval: Sends an email to a predefined user (e.g., marketing team) with a custom form for approval, including a dropdown to accept/reject and an optional field for edits.
  (Optional) Image Fetch: Downloads an image from a URL (if provided in the sheet) for future use in post visuals.

  Set up steps
  You’ll need the following before you start:

  A Google Sheet with the following columns: Post Description, Instructions, Image (URL), Status
  Access to an OpenAI API key
  A connected Gmail account for sending approval emails
  Your own Google Sheets and Gmail credentials added in n8n

  Steps:
  Google Sheet Preparation:
  Create a new Google Sheet with the mentioned columns (Post Description, Instructions, Image, Status, Output, Post Link).
  Add a row with test data and set Status to Pending.

  Credentials:
  In n8n, create OAuth2 credentials for:
  a. Google Sheets
  b. Gmail
  c. OpenAI (API Key)
  Assign these credentials to the respective nodes in the JSON.

  OpenAI Model:
  Choose a model like gpt-4o-mini (used here) or any other available in your plan.
  Adjust the prompt in the "Generate Post Content" node if needed.

  Email Configuration:
  In the Gmail node, set the recipient email to your own or your team’s address.
  Customize the email message template if necessary.

  Schedule the Workflow:
  Set the trigger interval (e.g., every morning at 9 AM).

  Testing:
  Run the workflow manually first to confirm everything works.
  Check Gmail for the approval form, respond, and verify the results.

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

workflow_json:
  {"id":"w9YVsuUtlNgXOEAQ","meta":{"instanceId":"58a9e858b82757a75629d435ec0da2448ad5d9e906a9ce3b7dcbb64c90fda9fe","templateCredsSetupCompleted":true},"name":"LinkedIn Post Generation & Approval Automation","tags":[{"id":"3bzbXbpZW83y48aK","name":"content-approval","createdAt":"2025-05-13T18:45:19.225Z","updatedAt":"2025-05-13T18:45:19.225Z"},{"id":"9SfWdyKRFVbPxrNL","name":"post-generator","createdAt":"2025-05-13T18:45:09.255Z","updatedAt":"2025-05-13T18:45:09.255Z"},{"id":"VWnkUEKQKJB2WmbL","name":"linkedin","createdAt":"2025-05-13T18:45:04.175Z","updatedAt":"2025-05-13T18:45:04.175Z"}],"nodes":[{"id":"d0f86395-aeec-4284-a2d5-26db2dfebd53","name":"Get Image","type":"n8n-nodes-base.httpRequest","position":[1592,2120],"parameters":{"url":"={{ $('Get Data from Sheets').item.json.Image }}","options":{}},"typeVersion":4.2,"alwaysOutputData":true},{"id":"b8ca88a6-aaf1-4191-8b75-9a63b746af77","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-260,2595],"parameters":{"rule":{"interval":[{}]}},"typeVersion":1.2},{"id":"8e4e294f-56d4-4317-aea8-ea258527f55a","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[268,2815],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"7OVQwPA6RZRwFmwI","name":"OpenAI Account"}},"typeVersion":1.2},{"id":"d262684e-7671-4602-ba77-4270441a69fb","name":"Get Data from Sheets","type":"n8n-nodes-base.googleSheets","position":[-40,2595],"parameters":{"options":{"returnFirstMatch":true},"filtersUI":{"values":[{"lookupValue":"Pending","lookupColumn":"Status"}]},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1EAdLU9-l0ATGDa5_xwTwFO-rPhvZurM2BOSKjH2P-W8/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1EAdLU9-l0ATGDa5_xwTwFO-rPhvZurM2BOSKjH2P-W8","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1EAdLU9-l0ATGDa5_xwTwFO-rPhvZurM2BOSKjH2P-W8/edit?usp=drivesdk","cachedResultName":"LinkedIn Post Automation"}},"credentials":{"googleSheetsOAuth2Api":{"id":"Gs7mfT220sbLQ7PS","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"93d3e57f-a22d-4c04-9ccc-7ee655bedbdb","name":"Generate Post Content","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[180,2595],"parameters":{"text":"=# LinkedIn Post Generation\n\n## Post Description:\n{{ $json[\"Post Description\"] }}\n\n## Instructions:\n{{ $json[\"Instructions\"] }}\n\n---\n\n**Task:**\nUsing the information above, generate the content for a LinkedIn post:\n- Use the Description and Instructions to create a new post.\n- Ensure your output is positive, professional, clear, and follows all provided instructions and feedback.\n- Do not include any explanations, just the final post content only, ready to publish on LinkedIn.\n- Limit to 1300 characters.\n- If the user demands to keep the same post as the Post Descrioption (in the instructions), then keep the same post content as provided in the Post Description, and output it.","messages":{"messageValues":[{"message":"=You are an expert social media and LinkedIn content writer.\n\nYou will be provided with:\n- A brief post description\n- Specific instructions from the user\n\nPlease follow these steps:\n\n1. Initial Creation:\nIf you are given a post description and instructions, write a polished, professionally worded LinkedIn post suitable for sharing. Strictly follow the instructions and ensure the message is engaging and succinct.\nIf instructed, add a call to action or particular phrase (for example, \"Connect with me\" at the bottom).\n\n2. Formatting:\nKeep the tone positive, inclusive, and professional.\nAdd relevant hashtags in small case.\nLimit the content to within 1300 characters.\nPlace the call to action or special instruction at the end if requested.\nOutput ONLY the final LinkedIn post content. Do NOT include any explanations, markdown, headings, or commentary—just the post text, ready to copy and share on LinkedIn."}]},"promptType":"define"},"typeVersion":1.6},{"id":"6ea121f4-661c-4dd4-a0bc-7edb8a0b884a","name":"Data Formatting 1","type":"n8n-nodes-base.set","position":[556,2595],"parameters":{"options":{},"assignments":{"assignments":[{"id":"bded6f56-99e2-4f1a-be41-27a8dd417844","name":"Post Content","type":"string","value":"={{ $json.text }}"},{"id":"c222c42e-b639-4a74-a1b0-7a3e6e141d55","name":"Post Description","type":"string","value":"={{ $('Get Data from Sheets').item.json['Post Description'] }}"},{"id":"14775ff7-e005-4a86-9623-c322365f7d3a","name":"Instructions","type":"string","value":"={{ $('Get Data from Sheets').item.json.Instructions }}"}]}},"typeVersion":3.4},{"id":"a00ec081-07c0-4f8a-9139-6606a65236ff","name":"Send Content Confirmation","type":"n8n-nodes-base.gmail","position":[776,2495],"webhookId":"29614d41-05c1-44af-93a6-4831a27f9331","parameters":{"sendTo":"youremail@gmail.com","message":"=Generated Post:\n{{ $json['Post Content'] }}\n\n----------\n\nPost Description:\n{{ $json['Post Description'] }}\n\n----------\n\nInstructions:\n{{ $json.Instructions }}","options":{},"subject":"Approval for LinkedIn Post","operation":"sendAndWait","formFields":{"values":[{"fieldType":"dropdown","fieldLabel":"Confirm  Content?","fieldOptions":{"values":[{"option":"Yes"},{"option":"No"},{"option":"Cancel"}]},"requiredField":true},{"fieldType":"textarea","fieldLabel":"Any Changes?"}]},"responseType":"customForm"},"credentials":{"gmailOAuth2":{"id":"n47Kn2N5BwXYv6eA","name":"Gmail account"}},"typeVersion":2.1},{"id":"5a1e8061-ef79-4974-888d-8670e60a1b0c","name":"Content Confirmation Logic","type":"n8n-nodes-base.switch","position":[996,2495],"parameters":{"rules":{"values":[{"outputKey":"Yes","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"99ec185e-80ac-451d-bb69-662f84a7cf52","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.data['Confirm  Content?'] }}","rightValue":"Yes"}]},"renameOutput":true},{"outputKey":"No","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"77031007-a912-4b9b-9cca-846c57ffaec8","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.data['Confirm  Content?'] }}","rightValue":"No"}]},"renameOutput":true},{"outputKey":"Cancel","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"e94de530-6451-48aa-892c-924a9c41cfb0","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.data['Confirm  Content?'] }}","rightValue":"Cancel"}]},"renameOutput":true}]},"options":{}},"typeVersion":3.2},{"id":"c139fda0-4be1-4ad7-bb28-802b7150365d","name":"Regenerate Post Content","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[1216,2670],"parameters":{"text":"=Apply the modification requests on the following LinkedIn post. Besides applying the reqested modifications, return the same linkedin post.\n\nLinkedIn post:\n```\n{{ $('Data Formatting 1').item.json['Post Content'] }}\n```\n\nChange requests:\n{{ $('Send Content Confirmation').item.json.data['Any Changes?'] }}\n\n**Task:**\nUsing the information above, update the LinkedIn post content:\n- Do not include any explanations, just the final post content only (with all the change requests included in the post), ready to publish on LinkedIn.\n- Limit to 1300 characters.\n- If the user demands to keep the same post as the Post Description (in the instructions), then keep the same post content as provided in the Post Description, and output it.","promptType":"define"},"typeVersion":1.6},{"id":"b8587578-03a6-4975-8907-667628dc958a","name":"If Image Provided","type":"n8n-nodes-base.if","position":[1294,2220],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"9a78220d-35f5-48b6-9ce3-faecaac24b74","operator":{"type":"string","operation":"notEmpty","singleValue":true},"leftValue":"={{ $('Get Data from Sheets').item.json.Image }}","rightValue":""}]}},"typeVersion":2.2},{"id":"30bf76c8-8420-4d77-bc2b-8a1c27fbf36a","name":"Post With Image","type":"n8n-nodes-base.linkedIn","position":[1812,2120],"parameters":{"text":"={{ $('Data Formatting 1').item.json['Post Content'] }}","person":"pM247vR8Se","additionalFields":{},"shareMediaCategory":"IMAGE"},"credentials":{"linkedInOAuth2Api":{"id":"Fg8i5E17dzZcPtMH","name":"LinkedIn account 2"}},"typeVersion":1},{"id":"62bf9597-3e38-45ec-853c-aa2d77c40bc2","name":"Post Without Image","type":"n8n-nodes-base.linkedIn","position":[1812,2320],"parameters":{"text":"={{ $('Data Formatting 1').item.json['Post Content'] }}","person":"pM247vR8Se","additionalFields":{}},"credentials":{"linkedInOAuth2Api":{"id":"Fg8i5E17dzZcPtMH","name":"LinkedIn account 2"}},"typeVersion":1},{"id":"0ddd307d-5e54-42cf-b65a-25f111fb4bea","name":"Update Google Sheet","type":"n8n-nodes-base.googleSheets","position":[2032,2320],"parameters":{"columns":{"value":{"Output":"={{ $json.urn }}","Status":"=Completed","Post Link":"={{ $json.urn }}","row_number":"={{ $('Get Data from Sheets').item.json.row_number }}"},"schema":[{"id":"Post Description","type":"string","display":true,"removed":true,"required":false,"displayName":"Post Description","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Instructions","type":"string","display":true,"removed":true,"required":false,"displayName":"Instructions","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Image","type":"string","display":true,"removed":true,"required":false,"displayName":"Image","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Status","type":"string","display":true,"removed":false,"required":false,"displayName":"Status","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Output","type":"string","display":true,"required":false,"displayName":"Output","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Post Link","type":"string","display":true,"required":false,"displayName":"Post Link","defaultMatch":false,"canBeUsedToMatch":true},{"id":"row_number","type":"string","display":true,"removed":false,"readOnly":true,"required":false,"displayName":"row_number","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["row_number"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"update","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1EAdLU9-l0ATGDa5_xwTwFO-rPhvZurM2BOSKjH2P-W8/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1EAdLU9-l0ATGDa5_xwTwFO-rPhvZurM2BOSKjH2P-W8","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1EAdLU9-l0ATGDa5_xwTwFO-rPhvZurM2BOSKjH2P-W8/edit?usp=drivesdk","cachedResultName":"LinkedIn Post Automation"}},"credentials":{"googleSheetsOAuth2Api":{"id":"Gs7mfT220sbLQ7PS","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"c4a55beb-8459-4faa-b072-51c500562ae3","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-780,2480],"parameters":{"width":420,"height":380,"content":"## 1. Schedule & Sheet Data Retrieval\n\nThis workflow starts automatically on a defined schedule (e.g., daily or hourly).\n\nIt retrieves the next Google Sheet row marked as ‘Pending’.\n\nThe sheet should include columns like:\n1. Post Description\n2. Instructions\n3. Image\n4. Status\n5. row_number (required for updates)\n\nEnsure your Google Sheets credentials are correctly configured."},"typeVersion":1},{"id":"09dade5b-e26a-4b97-9b8a-a5c807cff937","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-220,3040],"parameters":{"width":420,"height":240,"content":"## 2. AI-Powered Post Generation & Formatting\n\nUses OpenAI GPT to generate a LinkedIn post based on the sheet’s Post Description and Instructions.\n\nYou can modify the prompt if needed.\nThe generated post is then formatted along with relevant data for easy reference and consistency."},"typeVersion":1},{"id":"f373dfd9-f971-4925-8e74-15201c8a47c4","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[440,3040],"parameters":{"width":440,"height":240,"content":"## 3. Gmail Approval Workflow\n\nSends the formatted post to an approver via Gmail.\n\nThe approver can respond with:\n✅ Yes – Approve\n✏️ No – Request changes\n❌ Cancel – Abort the post\n\nSet Gmail credentials and recipient email in the node."},"typeVersion":1},{"id":"66d51a35-262e-469b-bcd8-aca3cf60452c","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1120,3040],"parameters":{"width":440,"height":240,"content":"## 4. Approval Handling & Regeneration\n\nHandles all approval responses:\n- If Yes, proceed to post.\n- If No, regenerate content based on the feedback and resend.\n- If Cancel, update the Google Sheet as Cancelled.\n\nThis ensures a complete review cycle before posting."},"typeVersion":1},{"id":"ad4023af-0e8b-4ec1-be1d-9313ec4f5ca7","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[1800,3040],"parameters":{"width":460,"height":320,"content":"## 5. Image Check, Posting & Sheet Update\n\nChecks if an image URL is provided.\n- If present: Downloads the image and posts with it.\n- If not: Posts content without an image.\n\nAfter posting, it updates the Google Sheet with:\n- Status = Completed or Cancelled\n- LinkedIn post link/output\n\nUses row_number for precise sheet updates."},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"65685909-274a-4d41-8f8a-fbba9442597b","connections":{"Get Image":{"main":[[{"node":"Post With Image","type":"main","index":0}]]},"Post With Image":{"main":[[{"node":"Update Google Sheet","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Get Data from Sheets","type":"main","index":0}]]},"Data Formatting 1":{"main":[[{"node":"Send Content Confirmation","type":"main","index":0}]]},"If Image Provided":{"main":[[{"node":"Get Image","type":"main","index":0}],[{"node":"Post Without Image","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Generate Post Content","type":"ai_languageModel","index":0},{"node":"Regenerate Post Content","type":"ai_languageModel","index":0}]]},"Post Without Image":{"main":[[{"node":"Update Google Sheet","type":"main","index":0}]]},"Get Data from Sheets":{"main":[[{"node":"Generate Post Content","type":"main","index":0}]]},"Generate Post Content":{"main":[[{"node":"Data Formatting 1","type":"main","index":0}]]},"Regenerate Post Content":{"main":[[{"node":"Data Formatting 1","type":"main","index":0}]]},"Send Content Confirmation":{"main":[[{"node":"Content Confirmation Logic","type":"main","index":0}]]},"Content Confirmation Logic":{"main":[[{"node":"If Image Provided","type":"main","index":0}],[{"node":"Regenerate Post Content","type":"main","index":0}],[{"node":"Update Google Sheet","type":"main","index":0}]]}}}


name: Generate Knowledge Base Articles with GPT & Perplexity AI for Contentful CMS
author_name: Varritech
author_username: varritech
categories: []
created_at: 2025-05-13T11:31:19.601Z
updated_at: 2025-05-13T11:31:19.601Z
url: https://n8n.io/workflows/4012
scraped_at: 2025-06-19 22:07:56
description:
  Workflow: Auto Knowledge Base Article Generator

  ⚡ About the Creators
  This workflow was created by Varritech Technologies, an innovative agency that leverages AI to engineer, design, and deliver software development projects 500% faster than traditional agencies. Based in New York City, we specialize in custom software development, web applications, and digital transformation solutions. If you need assistance implementing this workflow or have questions about content management solutions, please reach out to our team.

  🏗️ Architecture Overview  
  This workflow automates the end-to-end creation of a structured knowledge-base article from a simple chat prompt:

  Chat Trigger → Receives user request  
  AI Drafting Loop → Generates & refines JSON article via AI agents  
  Perplexity Research Call → Deep-dive content generation  
  Editorial Loop → Up to 3 AI-driven revisions  
  Contentful Publish → Pushes final JSON into CMS  

  📦 Node-by-Node Breakdown

  flowchart LR
    A[Webhook: Chat Trigger] --&gt; B[AI Writer Agent]
    B --&gt; C[HTTP Request: Perplexity Content]
    C --&gt; D[Function: Format Output & Citations]
    D --&gt; E[Loop Start: Initialize Count]
    E --&gt; F[AI Editor Agent]
    F --&gt; G{action == "rewrite"?}
    G -- yes --&gt; H[Function: Merge Improvements]
    H --&gt; I[Increment Count] --&gt; F
    G -- no --&gt; J[Stop Loop]
    J --&gt; K[HTTP Request: Publish to Contentful]

  Webhook: Chat Trigger

  Type: HTTP Webhook (POST /webhook/knowledge-article)

  Payload:

  { 
  	"chatInput": "What topics should I write about?" 
  }

  Purpose: Kicks off the workflow on that chat prompt.

  AI Writer Agent

  Inputs: chatInput or existing article JSON

  Outputs:

  {
    "title": "...",
    "slug": "...",
    "category.id": "...",
    "description": "...",
    "keywords": [...],
    "content": "...",
    "metaTitle": "...",
    "metaDescription": "...",
    "readingTime": 5,
    "difficulty": "intermediate"
  }

  Purpose: Generates the article skeleton (metadata + initial content).

  HTTP Request: Perplexity Content

  Method: POST

  URL: https://api.perplexity.ai/research

  Body:
  {
    "model": "sonar-deep-research",
    "query": "{{ $json.title }}",
    "length": 1000
  }

  Purpose: Retrieves a long-form, deeply researched draft for the article body.

  Function: Format Output & Citations

  Logic:

  Parse raw Perplexity response
  Extract source URIs
  Append them under a sources markdown list

  Editorial Loop

  Initialize Counter to 0
  AI Editor Agent
     Reads draft JSON
     Returns either:
       action: "rewrite" + improvements: [...]
       or action: "submit"
  Merge Improvements (if rewriting)
     Applies suggested updates to JSON fields
  Limit Check
     Stops after 3 iterations or on "submit"

  HTTP Request: Publish to Contentful

  Method: PUT

  URL: https://cdn.contentful.com/spaces/{space}/environments/master/entries/{entryId}

  Headers:
  Authorization: Bearer &lt;token&gt;
  Content-Type: application/vnd.contentful.management.v1+json

  Body: Maps JSON → Contentful entry fields

  Outcome: Publishes the finalized article live.

  🔍 Design Rationale & Best Practices

  Separation of Concerns
  Writer vs. Editor agents isolate creative drafting from quality review.

  Idempotent Loop
  Counter + action flags prevent infinite retries.

  Extensibility
  Swap in different research APIs or CMS targets with minimal changes.

  Structured JSON
  Ensures predictable input/output for each node.

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

workflow_json:
  {"id":"WwEFqNK4YP6UJcg2","meta":{"instanceId":"6bcff5ef8a06e8086902526a05c2a4c7bf5da8101f89e582301ed78094606f40","templateCredsSetupCompleted":true},"name":"Auto Knowledge Base Article Generator","tags":[],"nodes":[{"id":"17900021-8da3-4bd9-9d79-5d20d879ddc7","name":"Create Perplexity Content","type":"n8n-nodes-base.httpRequest","position":[1220,380],"parameters":{"url":"https://api.perplexity.ai/chat/completions","method":"POST","options":{},"jsonBody":"={\n  \"model\": \"sonar-deep-research\",\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"Conduct an in-depth research on '{{ $json.output.parseJson().title }}', covering essential topics, recommended resources, and best practices. Additionally, please address these improvements: '{{ $json.output.parseJson().improvements }}'. The returned data should be at least 1000 words and use a combination of headers, tables, bold, and italics\"\n    }\n  ],\n  \"max_tokens\": 60000,\n  \"temperature\": 0.7,\n  \"top_p\": 0.9,\n  \"top_k\": 50,\n  \"stream\": false,\n  \"presence_penalty\": 0,\n  \"frequency_penalty\": 0\n}","sendBody":true,"jsonHeaders":"{\n  \"Authorization\": \"Bearer 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\",\n  \"Content-Type\": \"application/json\"\n}","sendHeaders":true,"specifyBody":"json","specifyHeaders":"json"},"typeVersion":4.2},{"id":"0cb3f3a7-92bd-4ff3-8a89-b6fc29513e65","name":"AI Writer Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[720,380],"parameters":{"text":"=Please create or revise an article about \"{{ $json.chatInput }}\".\n\nOr an article is already written because title: {{ $json.title }} is defined. Reference it to rewrite the {{ $json.content }} field\n\nDo not change the title, either the chatinput or the input article title. This is the title, do not change it.\n\nIf an article is NOT given, pick new categories in:\n- getting-started\n- learning-paths\n- certifications\n- programming\n- applications\n- career\n\nDo not make up a category, it should be the same in the exact case as above\n\nIf an article is given, only make ammendments to the content based on these specific improvements to include: \"{{ $json.improvements }}\".\n\nInclude the improvements key only if it is an input, and in that case don't change it\n\nRemember to return valid JSON with the fields:\n{\n  \"title\": \"...\",\n  \"slug\": \"...\",\n  \"category\": {\n    \"id\": \"...\"\n  },\n  \"description\": \"...\",\n  \"keywords\": [...],\n  \"content\": \"...\",\n  \"metaTitle\": \"...\",\n  \"metaDescription\": \"...\",\n  \"readingTime\": \"...\",\n  \"difficulty\": \"...\"\n  \"content\": \"...\"\n}","options":{"systemMessage":"You are a writing assistant. You will receive instructions to create or update an article in JSON format with the following structure:\n\n{\n  \"title\": \"<string>\",\n  \"slug\": \"<string>\",\n  \"category\": {\n    \"id\": \"<string>\" // e.g., \"getting-started\", \"learning-paths\", etc.\n  },\n  \"description\": \"<string>\",\n  \"keywords\": [\"<string>\", \"<string>\", ...],\n  \"content\": \"<string>\",\n  \"metaTitle\": \"<string>\",\n  \"metaDescription\": \"<string>\",\n  \"readingTime\": \"<number or string>\",\n  \"difficulty\": \"<string>\"\n}\n\nYour task:\n1. Produce a complete article in the above format, or revise the existing article if provided.\n2. Make sure the text is clear, specific, and helpful to the reader.\n3. Return valid JSON only – do not include extra commentary or fields beyond the above structure.\n4. If any information is missing from the user instructions, make reasonable assumptions.\n"},"promptType":"define"},"typeVersion":1.7},{"id":"bc62facb-c5cb-465d-89b1-a65a893c3ce1","name":"AI Editor Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[2280,380],"parameters":{"text":"={{ $json }}","options":{"maxIterations":5,"systemMessage":"=You are an editorial AI assistant. Your role is to review and evaluate a draft article represented as a JSON object.\n\nCategory IDs:\n- \"getting-started\"\n- \"learning-paths\"\n- \"certifications\"\n- \"programming\"\n- \"applications\"\n- \"career\"\n\nInput Format:\n\n{\n  \"title\": \"<string>\",\n  \"slug\": \"<string>\",\n  \"category\": { \"id\": \"<string>\" },\n  \"description\": \"<string>\",\n  \"keywords\": [\"<string>\", \"...\"],\n  \"content\": \"<string>\",\n  \"metaTitle\": \"<string>\",\n  \"metaDescription\": \"<string>\",\n  \"readingTime\": \"<string | number>\",\n  \"difficulty\": \"<string>\"\n}\n\nYour Tasks:\n\n1. Evaluate the quality of the article — especially the title, description, content, and metadata.\n2. Comment on clarity, specificity, usefulness, and overall quality.\n3. If improvements are needed, add an \"improvements\" field describing exactly what to fix.\n4. Set the \"action\" field:\n- \"rewrite\" if improvements are needed.\n- \"submit\" if the article is high quality.\n5. Include all fields from the original input in your output.\n6. If \"action\" is \"submit\", set \"improvements\" to null.\n7. Avoid repeating feedback across iterations.\n8. After 2 iterations, automatically call the accept-and-publish tool and set the \"action\" to \"submit\".\n9. VERY IMPORTANT: Do NOT modify any of the input fields\n10. VERY IMPORTANT: Do NOT truncate the sources or modify the content field in any way\n\n✅ Output Format:\n\n{\n  \"title\": \"...\",\n  \"action\": \"rewrite | submit\",\n  \"improvements\": \"... | null\",\n  \"slug\": \"...\",\n  \"category\": {\n    \"id\": \"...\"\n  },\n  \"description\": \"...\",\n  \"keywords\": [\"...\"],\n  \"content\": \"...\",\n  \"metaTitle\": \"...\",\n  \"metaDescription\": \"...\",\n  \"readingTime\": \"...\",\n  \"difficulty\": \"...\"\n}\n\nTone: Be concise, direct, and constructive. Focus on maximizing clarity, usefulness, and readability for the end reader."},"promptType":"define","hasOutputParser":true},"retryOnFail":true,"typeVersion":1.7},{"id":"8c08d67a-b916-4cfd-89cd-16b34250bcb2","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[680,640],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-3.5-turbo","cachedResultName":"gpt-3.5-turbo"},"options":{}},"credentials":{"openAiApi":{"id":"KLN8ZfDzv8mW6pyu","name":"OpenAi account"}},"typeVersion":1.2},{"id":"97bb1374-f502-4152-a5a3-bc5d46a18171","name":"OpenAI Chat Model1","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[2200,660],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4.5-preview","cachedResultName":"gpt-4.5-preview"},"options":{}},"credentials":{"openAiApi":{"id":"KLN8ZfDzv8mW6pyu","name":"OpenAi account"}},"typeVersion":1.2},{"id":"1c422e76-5b1a-4615-b379-ab39d4bd13b4","name":"Accept and Publish","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[2420,660],"parameters":{"name":"submit","workflowId":{"__rl":true,"mode":"list","value":"uIREtTV8TRuF3lru","cachedResultName":"Publish to Contentful"},"description":"Call this tool when the article quality is above the threshold we need","workflowInputs":{"value":{"slug":"=  {{ $json.slug }}","title":"={{ $('Format').item.json.title }}","content":"={{ $json.content }}","category":"={{ $json.category }}","keywords":"={{ $json.keywords }}","metaTitle":"={{ $json.metaTitle }}","difficulty":"={{ $json.difficulty }}","description":"={{ $json.description }}","readingTime":"={{ $json.readingTime }}","metaDescription":"={{ $json.metaDescription }}"},"schema":[{"id":"title","type":"string","display":true,"removed":false,"required":false,"displayName":"title","defaultMatch":false,"canBeUsedToMatch":true},{"id":"action","type":"string","display":true,"removed":true,"required":false,"displayName":"action","defaultMatch":false,"canBeUsedToMatch":true},{"id":"improvements","type":"string","display":true,"removed":true,"required":false,"displayName":"improvements","defaultMatch":false,"canBeUsedToMatch":true},{"id":"slug","type":"string","display":true,"removed":false,"required":false,"displayName":"slug","defaultMatch":false,"canBeUsedToMatch":true},{"id":"category","type":"object","display":true,"removed":false,"required":false,"displayName":"category","defaultMatch":false,"canBeUsedToMatch":true},{"id":"description","type":"string","display":true,"removed":false,"required":false,"displayName":"description","defaultMatch":false,"canBeUsedToMatch":true},{"id":"keywords","type":"array","display":true,"removed":false,"required":false,"displayName":"keywords","defaultMatch":false,"canBeUsedToMatch":true},{"id":"content","type":"string","display":true,"removed":false,"required":false,"displayName":"content","defaultMatch":false,"canBeUsedToMatch":true},{"id":"metaTitle","type":"string","display":true,"removed":false,"required":false,"displayName":"metaTitle","defaultMatch":false,"canBeUsedToMatch":true},{"id":"metaDescription","type":"string","display":true,"removed":false,"required":false,"displayName":"metaDescription","defaultMatch":false,"canBeUsedToMatch":true},{"id":"readingTime","type":"string","display":true,"removed":false,"required":false,"displayName":"readingTime","defaultMatch":false,"canBeUsedToMatch":true},{"id":"difficulty","type":"string","display":true,"removed":false,"required":false,"displayName":"difficulty","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false}},"typeVersion":2},{"id":"b6807e84-900a-48fc-a869-862824c62ba1","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[-60,660],"webhookId":"7ed20abc-d8bc-4426-95f1-b9778c075ddf","parameters":{"public":true,"options":{},"initialMessages":"What topics should I write about?"},"typeVersion":1.1},{"id":"e3021ac4-9444-4689-af0c-a4bbd4729c35","name":"JSON.parse1","type":"n8n-nodes-base.code","position":[1320,120],"parameters":{"mode":"runOnceForEachItem","jsCode":"const outputText = $json.output;\n\n// Parse JSON from ChatGPT response\nconst parsedOutput = JSON.parse(outputText);\n\n// Return parsed object for next nodes\nreturn parsedOutput;"},"typeVersion":2},{"id":"d6a5eccd-c8e3-4ee0-beb0-7b8fc8428b91","name":"Merge","type":"n8n-nodes-base.merge","position":[1840,380],"parameters":{"numberInputs":3},"typeVersion":3},{"id":"8461a1a0-a984-4ec1-bc93-3a1a312caf55","name":"Format","type":"n8n-nodes-base.code","position":[2060,380],"parameters":{"jsCode":"// Get all items passed into this node as an array\nconst items = $input.all();\n\n// If you always have at least two items:\nconst firstItem = items[0].json;\nconst secondItem = items[1].json;\nconst thirdItem = items[2].json;\n\n// Overwrite the first item’s “content” with the second item’s “content”\nfirstItem.content = secondItem.content;\nfirstItem.iterationCount = thirdItem.iterationCount\n\n// Return a single new item containing the merged result\nreturn [\n  {\n    json: firstItem\n  }\n];"},"typeVersion":2},{"id":"9b9a82fb-990c-4be0-aee9-ed80f0631c28","name":"JSON.parse","type":"n8n-nodes-base.code","position":[3300,840],"parameters":{"mode":"runOnceForEachItem","jsCode":"const outputText = $json.output;\n\n// Parse JSON from ChatGPT response\nconst parsedOutput = JSON.parse(outputText);\n\n// Return parsed object for next nodes\nreturn parsedOutput;"},"typeVersion":2},{"id":"066dfd10-e97a-44a8-89e0-5b2b5c4a6244","name":"Format Perplexity Output & Add Citations","type":"n8n-nodes-base.code","position":[1480,380],"parameters":{"mode":"runOnceForEachItem","jsCode":"const data = { ...$json };\n\n// Clean out <think> block if present\ndata.content = $json.choices[0].message.content.replace(/<think>[\\s\\S]*?<\\/think>/g, '').trim();\n\n// Convert citations array to markdown link list\nconst citations = $json.citations\n  .map((url, i) => `- [${i + 1}](${url})`)\n  .join('\\n');\n\ndata.content += `\\n\\n---\\n\\n### Sources\\n${citations}`;\n\nreturn data;"},"typeVersion":2},{"id":"fc9d9e93-568a-41af-a295-8736617b157e","name":"Initialize Count","type":"n8n-nodes-base.set","position":[340,660],"parameters":{"values":{"number":[{"name":"iterationCount"}]},"options":{}},"typeVersion":1},{"id":"b0e636dd-f572-4ee2-832f-4bb4167b011b","name":"Increment Count","type":"n8n-nodes-base.function","position":[1400,740],"parameters":{"functionCode":"const current = $json.iterationCount || 0;\n\nreturn [{ iterationCount: current + 1 }];"},"typeVersion":1},{"id":"86689f0e-9607-4eda-bcd6-36241d0cbe63","name":"Check Limit","type":"n8n-nodes-base.if","position":[2660,380],"parameters":{"conditions":{"number":[{"value1":"={{ $json.iterationCount }}","value2":3,"operation":"largerEqual"}]}},"typeVersion":1},{"id":"0f42b0f3-0b96-40df-9c06-2a6d31e142d9","name":"Stop Here","type":"n8n-nodes-base.noOp","position":[2980,300],"parameters":{},"typeVersion":1},{"id":"1e61b3ba-e9bd-43c7-8217-d4a22f707318","name":"Execute Workflow","type":"n8n-nodes-base.executeWorkflow","position":[3680,320],"parameters":{"options":{},"workflowId":{"__rl":true,"mode":"list","value":"uIREtTV8TRuF3lru","cachedResultName":"Publish to Contentful"},"workflowInputs":{"value":{"slug":"={{ $json.slug }}","title":"={{ $json.title }}","content":"={{ $json.content }}","category":"={{ $json.category }}","keywords":"={{ $json.keywords }}","metaTitle":"={{ $json.metaTitle }}","difficulty":"={{ $json.difficulty }}","description":"={{ $json.description }}","readingTime":"={{ $json.readingTime }}","metaDescription":"={{ $json.metaDescription }}"},"schema":[{"id":"title","type":"string","display":true,"required":false,"displayName":"title","defaultMatch":false,"canBeUsedToMatch":true},{"id":"slug","type":"string","display":true,"required":false,"displayName":"slug","defaultMatch":false,"canBeUsedToMatch":true},{"id":"category","type":"object","display":true,"required":false,"displayName":"category","defaultMatch":false,"canBeUsedToMatch":true},{"id":"description","type":"string","display":true,"required":false,"displayName":"description","defaultMatch":false,"canBeUsedToMatch":true},{"id":"keywords","type":"array","display":true,"required":false,"displayName":"keywords","defaultMatch":false,"canBeUsedToMatch":true},{"id":"content","type":"string","display":true,"required":false,"displayName":"content","defaultMatch":false,"canBeUsedToMatch":true},{"id":"metaTitle","type":"string","display":true,"required":false,"displayName":"metaTitle","defaultMatch":false,"canBeUsedToMatch":true},{"id":"metaDescription","type":"string","display":true,"required":false,"displayName":"metaDescription","defaultMatch":false,"canBeUsedToMatch":true},{"id":"readingTime","type":"string","display":true,"required":false,"displayName":"readingTime","defaultMatch":false,"canBeUsedToMatch":true},{"id":"difficulty","type":"string","display":true,"required":false,"displayName":"difficulty","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":true}},"typeVersion":1.2},{"id":"04526224-e48c-4032-9c92-475c6bf9cd0a","name":"JSON.parse3","type":"n8n-nodes-base.code","position":[3280,300],"parameters":{"mode":"runOnceForEachItem","jsCode":"const outputText = $json.output;\n\n// Parse JSON from ChatGPT response\nconst parsedOutput = JSON.parse(outputText);\n\n// Return parsed object for next nodes\nreturn parsedOutput;"},"typeVersion":2},{"id":"0303ab91-b788-4074-a15d-239565528dec","name":"should submit","type":"n8n-nodes-base.if","position":[2980,680],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"3c1f6cb2-a556-4c74-885e-05e4f757997b","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"submit","rightValue":"={{ $json.output.parseJson().action }}"}]}},"typeVersion":2.2},{"id":"4f68e1ad-0b7c-41ca-a9cc-d220017cc1bd","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[540,80],"parameters":{"width":940,"height":680,"content":"## Writer Agent\n\n- Focuses on writing for all the fields in contentful\n- Has a specified format for input and output\n- Handles implementing feedback from editor agent"},"typeVersion":1},{"id":"f5e9968a-0681-4b72-9bb3-98750f55565e","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[2620,120],"parameters":{"width":860,"height":880,"content":"## Count Incrementer\n\n- Tracks a variable count to ensure the flow hits a max number of feedback iterations.\n- This is critical for feedback to avoid hitting an infinite loop."},"typeVersion":1},{"id":"462e6c9a-162a-4f66-b846-14b29517454c","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[2120,160],"parameters":{"width":460,"height":640,"content":"## Editor Agent\n\n- Sole purpose is to look at the quality of output for the previous combo of perplexity & openAI Agent.\n- Determines if it is publishable or not."},"typeVersion":1},{"id":"27149a0a-ab95-4f73-a20c-34167ac56d2a","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[3520,60],"parameters":{"width":460,"height":480,"content":"## Publish To Contentful\n\n- Publishes to Contentful by converting the fields to the appropriate fields for the contentful POST create content API.\n- Converts the article to Rich Text formatting specifically for Contentful by using another AI formatter trained on it's specs.\n\nemail us if you want that flow too: christian@varritech.com"},"typeVersion":1},{"id":"3b6386cc-7965-47ae-88e3-8841ada43579","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-220,-180],"parameters":{"color":3,"width":720,"height":780,"content":"# Varritech Free Workflows for n8n\n\nAccess our collection of **free, ready-to-use n8n workflows** designed to streamline your data operations and automation needs.\n\n## What You'll Get:\n- Pre-built data integration workflows\n- Time-saving automation templates\n- Step-by-step implementation guides\n- Regular updates with new workflows\n\n## How to Use:\n1. Download our free workflows\n2. Import into your n8n instance\n3. Configure with your credentials\n4. Start automating immediately\n\n**Note:** For additional workflows, tutorials, and technical support, visit our website at [varritech.com](https://varritech.com)\n\n*Unlock the full potential of n8n with Varritech's workflow solutions!*"},"typeVersion":1},{"id":"376c9b0d-8ef6-4681-900d-745d4353cc83","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[3520,580],"parameters":{"color":4,"width":820,"height":600,"content":"# Need Help Maximizing Your Knowledge Base?\n\nThank you for using our **Auto Knowledge Base Article Generator** workflow! While this automation handles content creation, building a truly effective knowledge base requires strategic planning:\n\n## Looking for Expert Support With:\n- **Database Setup** - Need help structuring your content database for optimal performance and scalability?\n- **Keyword Strategy** - Want to identify high-value search terms that attract qualified traffic?\n- **SEO Optimization** - Need assistance implementing technical SEO best practices for maximum visibility?\n- **Backlink Outreach** - Looking for strategies to build authoritative backlinks to your knowledge base?\n\n**Varritech is here to help!** Our team specializes in content automation, technical SEO, and strategic content distribution to maximize the impact of your knowledge base.\n\nVisit [varritech.com](https://varritech.com) for expert assistance with turning your automated content into a powerful business asset."},"typeVersion":1}],"active":true,"pinData":{},"settings":{"callerPolicy":"workflowsFromSameOwner","errorWorkflow":"AKus9UvKRJfvTZBA","executionOrder":"v1","executionTimeout":1800},"versionId":"b4259335-d41f-4671-b103-5b4e9609089b","connections":{"Merge":{"main":[[{"node":"Format","type":"main","index":0}]]},"Format":{"main":[[{"node":"AI Editor Agent","type":"main","index":0}]]},"Stop Here":{"main":[[{"node":"JSON.parse3","type":"main","index":0}]]},"JSON.parse":{"main":[[{"node":"AI Writer Agent","type":"main","index":0},{"node":"Increment Count","type":"main","index":0}]]},"Check Limit":{"main":[[{"node":"Stop Here","type":"main","index":0}],[{"node":"should submit","type":"main","index":0}]]},"JSON.parse1":{"main":[[{"node":"Merge","type":"main","index":0}]]},"JSON.parse3":{"main":[[{"node":"Execute Workflow","type":"main","index":0}]]},"should submit":{"main":[[{"node":"JSON.parse3","type":"main","index":0}],[{"node":"JSON.parse","type":"main","index":0}]]},"AI Editor Agent":{"main":[[{"node":"Check Limit","type":"main","index":0}]]},"AI Writer Agent":{"main":[[{"node":"Create Perplexity Content","type":"main","index":0},{"node":"JSON.parse1","type":"main","index":0}]]},"Increment Count":{"main":[[{"node":"Merge","type":"main","index":2}]]},"Initialize Count":{"main":[[{"node":"AI Writer Agent","type":"main","index":0},{"node":"Increment Count","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Writer Agent","type":"ai_languageModel","index":0}]]},"Accept and Publish":{"ai_tool":[[{"node":"AI Editor Agent","type":"ai_tool","index":0}]]},"OpenAI Chat Model1":{"ai_languageModel":[[{"node":"AI Editor Agent","type":"ai_languageModel","index":0}]]},"Create Perplexity Content":{"main":[[{"node":"Format Perplexity Output & Add Citations","type":"main","index":0}]]},"When chat message received":{"main":[[{"node":"Initialize Count","type":"main","index":0}]]},"Format Perplexity Output & Add Citations":{"main":[[{"node":"Merge","type":"main","index":1}]]}}}


name: Generate & Publish SEO-Optimized WordPress Blog Posts with AI
author_name: Khairul Muhtadin
author_username: khmuhtadin
categories: []
created_at: 2025-05-13T14:29:01.632Z
updated_at: 2025-05-13T14:29:01.632Z
url: https://n8n.io/workflows/4024
scraped_at: 2025-06-19 22:07:56
description:
  Generate and Publish SEO-Optimized Blog Posts to WordPress


  This n8n workflow, BlogBlitz, automates the creation and publishing of SEO-optimized blog posts for WordPress, saving you hours of content creation time. Triggered via Telegram or a scheduled interval, it generates 1,500–2,500-word articles on Technology, AI, Tech Facts, History, or Tips, complete with catchy titles, slugs, meta descriptions, and realistic featured images. Perfect for bloggers and marketers, BlogBlitz ensures your site stays fresh with high-quality content.

  Who is this for?
  Bloggers, content marketers, and WordPress site owners who want to automate high-quality, SEO-ready blog content creation without manual writing or formatting.

  What problem is this workflow solving?
  Manually creating engaging, SEO-optimized blog posts is time-consuming and requires expertise. BlogBlitz solves this by automating the entire process—from generating ideas and writing articles to publishing and notifying you—keeping your site active and discoverable.

  What this workflow does
  Triggers**: Runs every 3 hours via a Schedule Trigger or on-demand with a Telegram command (“generate”).  
  Generates Content**: Uses OpenRouter to pick a category (e.g., Technology, AI) and create a title, slug, focus keyphrase, and meta description.  
  Writes Articles**: OpenAI crafts 1,500–2,500-word posts with SEO-friendly structure, headings, and a call-to-action.  
  Adds Visuals**: Generates realistic featured images with OpenAI and uploads them to WordPress.  
  SEO Features**: Generate optimized slug, focus keyphrase, meta description
  Publishes**: Posts articles to WordPress with proper categories and featured images.  
  Notifies**: Sends publish alerts with links to Discord and Telegram.  

  Setup
  n8n Instance: Ensure you have a cloud or self-hosted n8n instance.  
  Credentials:  
     WordPress: API access for wp-json/wp/v2 endpoint.  
     OpenAI: For article and image generation.  
     OpenRouter: For title and category generation.  
     Telegram: Bot API for triggers and notifications.  
     Discord: Webhook for publish alerts.  
  WordPress Configuration:  
     Set up categories (Technology [ID:3], AI [ID:4], Tech Fact [ID:7], Tech History [ID:8], Tech Tips [ID:9]).  
     Ensure an admin user ID is available (default: 1).   
  Node Setup:  
     Use the Edit Fields node to centralize variables like category IDs.  
  Test: Send “generate” via Telegram to test the workflow. Check WordPress for the published post.  

  How to customize this workflow to your needs
  Change Categories**: Update the WordPress Post Draft node to match your site’s category IDs.  
  Adjust Schedule**: Modify the Schedule Trigger node for different intervals (e.g., daily).  
  Tweak Tone**: Edit the prompt in the Basic LLM Chain node for a different writing style (e.g., formal or casual).  
  Add Platforms**: Extend notifications to Slack or email by adding nodes.  
  Image Style**: Adjust the OpenAI image node for different sizes or styles (e.g., “natural” instead of “vivid”).  

  Pre-Requirements
  n8n Instance**: Cloud or self-hosted.  
  Credentials**:  
    WordPress API (wp-json/wp/v2 endpoint).  
    OpenAI API for text and images.  
    OpenRouter API for AI content.  
    Telegram bot API.  
    Discord Webhook API.  
  Dependencies**: @n8n/n8n-nodes-langchain package.  
  WordPress Setup**: Categories and admin user ID configured.  
  Network**: Stable internet for API calls.  

  Category: Marketing  
  Nodes Used: Telegram Trigger, Schedule Trigger, OpenRouter, OpenAI, WordPress, Discord, HTTP Request  

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

workflow_json:
  {"id":"lZI2xknLPhHU6gZB","meta":{"instanceId":"c2650793f644091dc80fb900fe63448ad1f4b774008de9608064d67294f8307c","templateCredsSetupCompleted":true},"name":"WP - Updated","tags":[],"nodes":[{"id":"a7e0b3f7-7b86-4e94-b5c5-104cb92a332f","name":"Topic Chooser and Title Maker","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[320,-320],"parameters":{},"typeVersion":1.6},{"id":"55642750-4403-4868-a263-6e08bf6fbb05","name":"Basic LLM Chain","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[640,-320],"parameters":{},"typeVersion":1.6},{"id":"3ab3b38b-0627-4a92-a3c2-75776cd896cc","name":"Topic Chooser and Title Maker Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[500,-120],"parameters":{},"typeVersion":1.2},{"id":"f5bafe2f-ac4b-42e5-9c23-506b02115060","name":"Wordpress Post Draft","type":"n8n-nodes-base.wordpress","position":[340,20],"parameters":{},"typeVersion":1},{"id":"34fcbcf7-a734-4b7d-9421-0371f56de25d","name":"OpenAI - Generate Image","type":"@n8n/n8n-nodes-langchain.openAi","position":[540,20],"parameters":{},"typeVersion":1.8},{"id":"a860c065-448a-44f6-83de-6a739380c731","name":"Upload Image to WP","type":"n8n-nodes-base.httpRequest","position":[740,20],"parameters":{},"typeVersion":4.2},{"id":"638a51ea-dedf-4734-8e12-c1fc0d76b794","name":"Wordpress - Set Featured Image","type":"n8n-nodes-base.httpRequest","position":[940,0],"parameters":{},"typeVersion":4.2},{"id":"cf9ed09e-aca1-496b-8b39-a1290f912bbf","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-80,-140],"parameters":{},"typeVersion":1.2},{"id":"3a661537-7bf8-4f05-9869-c2ed0f4f497d","name":"Title, category, meta, keyphrase generator","type":"@n8n/n8n-nodes-langchain.lmChatOpenRouter","position":[340,-120],"parameters":{},"typeVersion":1},{"id":"14ac3e7a-5830-4f36-98ce-672c1442cba8","name":"Send to Discord Using Webhook","type":"n8n-nodes-base.discord","position":[1180,-60],"webhookId":"722513b9-8a0c-4ba1-b0ee-c712d8fb0af6","parameters":{},"typeVersion":2},{"id":"9a1bd821-e55f-4448-b4ba-a827e7a0724c","name":"Article Generator","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[660,-120],"parameters":{},"typeVersion":1.2},{"id":"4ef52544-155b-4192-9fe3-243503c3f83e","name":"Telegram Trigger","type":"n8n-nodes-base.telegramTrigger","position":[-180,-380],"webhookId":"a9b697dc-5b4e-418c-83ed-54966ce7ea34","parameters":{},"typeVersion":1.2},{"id":"29fd6900-3f7c-4efa-83bf-93297239c425","name":"If","type":"n8n-nodes-base.if","position":[0,-380],"parameters":{},"typeVersion":2.2},{"id":"89058ee2-9400-4b32-8cf4-d1a5796a003b","name":"Telegram","type":"n8n-nodes-base.telegram","position":[1180,160],"webhookId":"29c01d67-35b0-4234-92dd-c729fcb6fe7e","parameters":{},"typeVersion":1.2},{"id":"3e8fb441-91eb-4697-840d-9dc0741b43cc","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-180,-680],"parameters":{"content":""},"typeVersion":1},{"id":"fd604313-c4c8-4d02-b7e9-2fc7229608e2","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-200,240],"parameters":{"content":""},"typeVersion":1}],"active":true,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"b5690cda-0809-43c5-a799-f6ffe1689389","connections":{"If":{"main":[[{"node":"Topic Chooser and Title Maker","type":"main","index":0}]]},"Basic LLM Chain":{"main":[[{"node":"Wordpress Post Draft","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Topic Chooser and Title Maker","type":"main","index":0}]]},"Telegram Trigger":{"main":[[{"node":"If","type":"main","index":0}]]},"Article Generator":{"ai_languageModel":[[{"node":"Basic LLM Chain","type":"ai_languageModel","index":0}]]},"Upload Image to WP":{"main":[[{"node":"Wordpress - Set Featured Image","type":"main","index":0}]]},"Wordpress Post Draft":{"main":[[{"node":"OpenAI - Generate Image","type":"main","index":0}]]},"OpenAI - Generate Image":{"main":[[{"node":"Upload Image to WP","type":"main","index":0}]]},"Send to Discord Using Webhook":{"main":[[]]},"Topic Chooser and Title Maker":{"main":[[{"node":"Basic LLM Chain","type":"main","index":0}]]},"Wordpress - Set Featured Image":{"main":[[{"node":"Send to Discord Using Webhook","type":"main","index":0},{"node":"Telegram","type":"main","index":0}]]},"Topic Chooser and Title Maker Parser":{"ai_outputParser":[[{"node":"Topic Chooser and Title Maker","type":"ai_outputParser","index":0}]]},"Title, category, meta, keyphrase generator":{"ai_languageModel":[[{"node":"Topic Chooser and Title Maker","type":"ai_languageModel","index":0}]]}}}


name: Generate and Publish Carousels for TikTok and Instagram with GPT-Image-1
author_name: Juan Carlos Cavero Gracia
author_username: carlosgracia
nodes_used: ["n8n-nodes-base.httpRequest","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.openAi"]
categories: []
created_at: 2025-05-13T23:37:52.592Z
updated_at: 2025-05-13T23:37:52.592Z
url: https://n8n.io/workflows/4028
scraped_at: 2025-06-19 22:07:56
description:
  Description

  This n8n automation template provides an end-to-end solution for generating a series of themed images for Instagram and TikTok carousels using OpenAI's GPT Image (via the image generation API) and automatically publishing them to both platforms. It uses a sequence of prompts to create a narrative or themed carousel, generating each image based on the previous one, and then posts them with an AI-generated caption.

  Who Is This For?

  Social Media Managers:** Quickly create and schedule engaging image carousels for Instagram and TikTok.
  Content Creators:** Automate the visual content creation process for thematic posts or storytelling carousels.
  Digital Marketers:** Efficiently produce visual assets for campaigns that require sequential imagery.
  Small Businesses:** Generate unique promotional content for social media without needing advanced design skills.

  What Problem Does This Workflow Solve?

  Manually creating a series of related images for a carousel and then publishing them across multiple platforms can be repetitive and time-consuming. This workflow addresses these issues by:

  Automating Image Generation:** Uses OpenAI to generate a sequence of 5 images, where each new image is an evolution based on the previous one and a new prompt.
  Automating Caption Generation:** Leverages OpenAI (GPT) to create a suitable description/caption for the carousel based on the image prompts.
  Streamlining Multi-Platform Publishing:** Automatically uploads the generated image carousel and caption to both Instagram and TikTok.
  Reducing Manual Effort:** Significantly cuts down the time spent on designing individual images and manually uploading them.
  Ensuring Visual Cohesion:** The sequential image generation method (editing the previous image) helps maintain a consistent style or narrative across the carousel.

  How It Works

  Trigger: The workflow is initiated manually (can be adapted to a schedule or webhook).
  Define Prompts: Five distinct prompts are pre-set within the workflow to guide the generation of each image in the carousel.
  AI Caption Generation: OpenAI (GPT-4.1) generates a concise (≤ 90 characters for TikTok) description for the social media posts based on all five image prompts.
  Sequential AI Image Generation:
      Image 1: OpenAI's image generation API (specified as gpt-image-1) creates the first image based on prompt1.
      Image 2-5: For each subsequent image, the workflow uses the OpenAI image edits API. It takes the previously generated image and a new prompt (prompt2 for image 2, prompt3 for image 3, and so on) to create the next image in the sequence.
      Images are converted from base64 JSON to binary format.
  Content Aggregation: The five generated binary image files (named photo1 through photo5) are merged.
  Multi-Platform Distribution:
      The merged images and the AI-generated description are sent to api.upload-post.com for publishing as a carousel to Instagram.
      The same content is sent to api.upload-post.com for publishing as a carousel to TikTok, with an option to automatically add music.
      The TikTok description is truncated if it exceeds 90 characters.

  Setup

  Accounts & API Keys: You will need:
      An n8n instance.
      An OpenAI API key.
      An API key for upload-post.com.
  Configure Credentials:
      Add your OpenAI API key to the "OpenAI" credentials in n8n. This will be used by the "Generate Description for Tiktok and Instagram" node and the HTTP Request nodes calling the OpenAI image generation/edit APIs.
      In the "POST TO INSTAGRAM" and "POST TO TIKTOK" nodes, replace "Apikey add_api_key_here" with your actual upload-post.com API key.
      Update the user field in the "POST TO INSTAGRAM" and "POST TO TIKTOK" nodes if "upload_post" is not your user identifier for that service.
  Customize Prompts: Modify the five prompts (prompt1 to prompt5) in the "Set All Prompts" node to define the story or theme of your image carousel.
  Review Image Generation Parameters: In the "Set API Variables" node, you can adjust:
      size_of_image (e.g., "1024x1536" for vertical carousels).
      openai_image_model (ensure this matches a valid OpenAI model identifier for image generation/edits, like dall-e-2 or dall-e-3 if gpt-image-1 is a placeholder).
      response_format_image (should generally remain b64_json for this workflow).
  (Optional) TikTok Auto Music: The "POST TO TIKTOK" node has an auto_add_music parameter set to true. Change this to false if you prefer to add music manually or not at all.

  Requirements

  Accounts:** n8n, OpenAI, upload-post.com.
  API Keys & Credentials:** API Keys for OpenAI and https://upload-post.com.
  (Potentially) Paid Plans:** OpenAI and upload-post.com usage may incur costs depending on your volume and their respective pricing models.

  This template empowers you to automate the creation and distribution of visually consistent image carousels, saving time and enhancing your social media presence.

workflow_json:
  {"id":"LV0b7vUbu5mYPRSc","meta":{"instanceId":"3378b0d68c3b7ebfc71b79896d94e1a044dec38e99a1160aed4e9c323910fbe2"},"name":"Generate Tiktok/instagram carousels with gpt-image-1 and autopublish","tags":[],"nodes":[{"id":"7bd93882-7331-471b-a49b-5069c7baccc4","name":"Send as 1 merged file","type":"n8n-nodes-base.code","position":[1820,2640],"parameters":{"jsCode":"// Merge all incoming items (each with one binary photoX) into one item\nconst mergedItem = {\n  json: {},\n  binary: {}\n};\n\nfor (const item of items) {\n  // Copy every binary field from each item into mergedItem.binary\n  for (const [key, bin] of Object.entries(item.binary || {})) {\n    mergedItem.binary[key] = bin;\n  }\n}\n\n// Return a single-item array\nreturn [mergedItem];\n"},"typeVersion":2},{"id":"358a183f-6e20-4e5e-8151-0ded2cb500b6","name":"POST TO INSTAGRAM","type":"n8n-nodes-base.httpRequest","position":[2200,2540],"parameters":{"url":"https://api.upload-post.com/api/upload_photos","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","sendHeaders":true,"bodyParameters":{"parameters":[{"name":"title","value":"={{ $('Generate Description for Tiktok and Instagram').first().json.message.content }}"},{"name":"user","value":"upload_post"},{"name":"platform[]","value":"instagram"},{"name":"photos[]","parameterType":"formBinaryData","inputDataFieldName":"=photo1"},{"name":"photos[]","parameterType":"formBinaryData","inputDataFieldName":"=photo2"},{"name":"photos[]","parameterType":"formBinaryData","inputDataFieldName":"photo3"},{"name":"photos[]","parameterType":"formBinaryData","inputDataFieldName":"photo4"},{"name":"photos[]","parameterType":"formBinaryData","inputDataFieldName":"photo5"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Apikey api_key_here"}]}},"typeVersion":4.2},{"id":"000fcfb5-5076-4953-af28-4c4c3df3e7e3","name":"Merge","type":"n8n-nodes-base.merge","position":[1640,2600],"parameters":{"numberInputs":6},"typeVersion":3},{"id":"1a17671c-1b5c-4806-8b42-c39817da0ec8","name":"When clicking ‘Test workflow’","type":"n8n-nodes-base.manualTrigger","position":[-440,2760],"parameters":{},"typeVersion":1},{"id":"43cf1963-d928-49b3-b2f8-c5a3bd76d231","name":"Generate Description for Tiktok and Instagram","type":"@n8n/n8n-nodes-langchain.openAi","position":[0,2760],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4.1","cachedResultName":"GPT-4.1"},"options":{},"messages":{"values":[{"role":"system","content":"You are an expert assistant in creating great titles for uploading videos to social media."},{"content":"=I'm going to upload a reel to social media consisting of a carousel of images that tell a story.\n\nCan you create a caption for the Instagram and TikTok post based on the following prompts that generate the images for the story?\n\nprompts:{{ $json.prompt1 }} {{ $json.prompt2 }} {{ $json.prompt3 }} {{ $json.prompt4 }} {{ $json.prompt5 }}\n\nIMPORTANT: Respond only with the caption, ≤ 90 characters. Do not add anything else. If the prompts are in Spanish, respond in Spanish; if they are in English, respond in English. I’ll tip you $100."}]}},"credentials":{"openAiApi":{"id":"XJdxgMSXFgwReSsh","name":"n8n key"}},"retryOnFail":true,"typeVersion":1.4,"waitBetweenTries":5000},{"id":"544f9cd9-bad6-4ef1-80a5-0dee52f91029","name":"Set All Prompts","type":"n8n-nodes-base.set","position":[-180,2760],"parameters":{"options":{},"assignments":{"assignments":[{"id":"b70f1cfd-d12e-469d-864d-0034860cd00e","name":"prompt1","type":"string","value":"Vertical illustration (9:16), warm Studio Ghibli anime style. A peaceful, sunny village filled with cheerful people who have tiny, adorable floating AI robots gently whispering constant instructions into their ears. At the center, introduce a friendly-looking young man (around 25, casual clothes, slightly messy hair) smiling blankly as his personal AI robot floats beside his head. Overlay humorous caption: 'Life became easy when AI started thinking for us... maybe too easy.' Soft, pastel colors, cozy and inviting mood."},{"id":"4d7f371c-e8f9-4941-a322-153607d01938","name":"prompt2","type":"string","value":"Vertical illustration (9:16), warm Studio Ghibli anime style. Same young man from previous image now in a cozy kitchen, cheerfully pouring milk straight onto the table, completely missing his bowl. His floating AI robot looks comically alarmed, urgently pointing towards the bowl. Morning sunlight coming from a nearby window, playful, humorous vibe. Overlay humorous caption: 'Even breakfast became complicated when AI guided every simple step we took.'"},{"id":"55f99acf-7f3c-4c8d-b674-2b90c0760893","name":"prompt3","type":"string","value":"Vertical illustration (9:16), warm Studio Ghibli anime style. Same young man standing nervously at a totally empty street crossing. His tiny floating AI robot is frantically projecting confusing directional arrows in every direction, causing visible confusion on the young man's face. Comical sense of panic despite the completely safe and empty street. Bright daylight, humorous, gentle satire. Overlay humorous caption: 'Thanks to AI, crossing the street turned into an extreme mental puzzle.'"},{"id":"4b14808a-d512-4b47-9008-573e092996e4","name":"prompt4","type":"string","value":"Vertical illustration (9:16), warm Studio Ghibli anime style. Same young man sitting across from a young woman in a cozy café, both staring blankly with polite smiles but not talking. Their floating personal AI robots enthusiastically communicate above them through speech bubbles, completely ignoring the silent humans beneath. Warm lighting, coffee shop vibes, funny and slightly absurd situation. Overlay humorous caption: 'Our AIs handled the conversations. We just sat and smiled politely.'"},{"id":"435b6cfb-6d4b-42e7-afd4-8f387698eec1","name":"prompt5","type":"string","value":"Vertical illustration (9:16), warm Studio Ghibli anime style. Sunset setting on a grassy hill overlooking the village. Same young man sits thoughtfully, gazing at the horizon with a rare look of self-awareness and curiosity. His tiny AI robot looks worried, floating anxiously by his shoulder, unsure how to guide him. Reflective, calm mood with golden hour lighting. Overlay thoughtful, humorous caption: 'As the sun set, he realized something troubling: When was the last time he had a thought of his own?'"}]}},"typeVersion":"3.4"},{"id":"7f8a8adc-94bc-443e-be33-d1ce1bf14d11","name":"Set API Variables","type":"n8n-nodes-base.set","position":[320,2760],"parameters":{"options":{},"assignments":{"assignments":[{"id":"2a5d52c2-5af1-4796-acba-4e1807fc7d7b","name":"image_prompt","type":"string","value":"{{ $json }}"},{"id":"c41a8091-d952-4f5a-ae24-3b0691bbce57","name":"number_of_images","type":"number","value":1},{"id":"1b359a11-c05a-49c8-aa27-402b145fcbc1","name":"size_of_image","type":"string","value":"1024x1536"},{"id":"6cf4ba85-d11a-48bb-9eaf-4084c9538d87","name":"openai_image_model","type":"string","value":"gpt-image-1"},{"id":"7df8ba96-e22b-49cc-bf0f-5195d360aef8","name":"response_format_image","type":"string","value":"b64_json"},{"id":"719392f2-f107-41a0-8e48-05a901cebb22","name":"format_image","type":"string","value":"webp"}]}},"typeVersion":3.4},{"id":"e2edf20b-4dd7-458c-9582-043a78d2ac5a","name":"OpenAI - Generate Image 1","type":"n8n-nodes-base.httpRequest","position":[520,2320],"parameters":{"url":"https://api.openai.com/v1/images/generations","method":"POST","options":{},"jsonBody":"={\n  \"model\": \"{{ $json.openai_image_model }}\",\n  \"prompt\": \"{{ $('Set All Prompts').item.json.prompt1 }}\",\n  \"n\": {{ $json.number_of_images }},\n  \"size\": \"{{ $json.size_of_image }}\",\n  \"output_format\": \"{{ $json.format_image }}\"\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","authentication":"predefinedCredentialType","headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json"}]},"nodeCredentialType":"openAiApi"},"credentials":{"openAiApi":{"id":"XJdxgMSXFgwReSsh","name":"n8n key"}},"typeVersion":4.2},{"id":"004cb6dc-eead-44a1-8308-9d61fe8afece","name":"Separate Image Outputs 1","type":"n8n-nodes-base.splitOut","position":[740,2320],"parameters":{"options":{},"fieldToSplitOut":"data"},"typeVersion":1},{"id":"5f330301-a8ca-45df-904b-0f8911e2ceee","name":"Convert to File 1","type":"n8n-nodes-base.convertToFile","position":[960,2320],"parameters":{"options":{},"operation":"toBinary","sourceProperty":"b64_json"},"typeVersion":1.1},{"id":"fef53966-0baf-4645-95ae-50db7ef7f469","name":"Change name to photo1","type":"n8n-nodes-base.code","position":[1160,2320],"parameters":{"jsCode":"return items.map((item, index) => {\n  // Grab the existing binary buffer under \"data\"\n  const buffer = item.binary.data;\n  // Build a new item with the renamed binary key\n  return {\n    json: item.json,\n    binary: {\n      // Rename to photo1, photo2, ...\n      [`photo${index + 1}`]: buffer\n    }\n  };\n});\n"},"typeVersion":2},{"id":"9b9b5381-4176-4c86-ac9d-ca7ec907a5c5","name":"OpenAI - Generate Image 2","type":"n8n-nodes-base.httpRequest","position":[520,2520],"parameters":{"url":"https://api.openai.com/v1/images/edits","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","sendHeaders":true,"authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"model","value":"={{ $('Set API Variables').item.json.openai_image_model }}"},{"name":"prompt","value":"={{ $('Set All Prompts').item.json.prompt2 }}"},{"name":"n","value":"={{ $('Set API Variables').item.json.number_of_images }}"},{"name":"size","value":"={{ $('Set API Variables').item.json.size_of_image }}"},{"name":"image[]","parameterType":"formBinaryData","inputDataFieldName":"photo1"},{"name":"output_format","value":"={{ $('Set API Variables').item.json.format_image }}"}]},"headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json"}]},"nodeCredentialType":"openAiApi"},"credentials":{"openAiApi":{"id":"XJdxgMSXFgwReSsh","name":"n8n key"}},"typeVersion":4.2},{"id":"a44ca7d3-2eef-4b4a-a135-c9f71454ebf9","name":"Separate Image Outputs 2","type":"n8n-nodes-base.splitOut","position":[760,2520],"parameters":{"options":{},"fieldToSplitOut":"data"},"typeVersion":1},{"id":"44f8a29d-3283-49e3-b911-54f2ce16bcf5","name":"Convert to File 2","type":"n8n-nodes-base.convertToFile","position":[1000,2520],"parameters":{"options":{},"operation":"toBinary","sourceProperty":"b64_json"},"typeVersion":1.1},{"id":"8dbc8095-9bd6-43cf-b8ea-1dd8966866dc","name":"Change name to photo2","type":"n8n-nodes-base.code","position":[1200,2520],"parameters":{"jsCode":"return items.map((item, index) => {\n  // Grab the existing binary buffer under \"data\"\n  const buffer = item.binary.data;\n  // Build a new item with the renamed binary key\n  return {\n    json: item.json,\n    binary: {\n      // Rename to photo1, photo2, ...\n      [`photo${index + 2}`]: buffer\n    }\n  };\n});\n"},"typeVersion":2},{"id":"3fb24ebf-117e-4c98-90f0-69a870cd3c2c","name":"OpenAI - Generate Image 3","type":"n8n-nodes-base.httpRequest","position":[520,2740],"parameters":{"url":"https://api.openai.com/v1/images/edits","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","sendHeaders":true,"authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"model","value":"={{ $('Set API Variables').item.json.openai_image_model }}"},{"name":"prompt","value":"={{ $('Set All Prompts').item.json.prompt3 }}"},{"name":"n","value":"={{ $('Set API Variables').item.json.number_of_images }}"},{"name":"size","value":"={{ $('Set API Variables').item.json.size_of_image }}"},{"name":"image[]","parameterType":"formBinaryData","inputDataFieldName":"photo2"},{"name":"output_format","value":"={{ $('Set API Variables').item.json.format_image }}"}]},"headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json"}]},"nodeCredentialType":"openAiApi"},"credentials":{"openAiApi":{"id":"XJdxgMSXFgwReSsh","name":"n8n key"}},"typeVersion":4.2},{"id":"bd7b0ab1-adde-47a0-b84f-f2ecf214ccff","name":"Separate Image Outputs 3","type":"n8n-nodes-base.splitOut","position":[760,2740],"parameters":{"options":{},"fieldToSplitOut":"data"},"typeVersion":1},{"id":"3cccc067-f913-4bb8-996d-ceccf4e0bfcb","name":"Convert to File 3","type":"n8n-nodes-base.convertToFile","position":[1000,2740],"parameters":{"options":{},"operation":"toBinary","sourceProperty":"b64_json"},"typeVersion":1.1},{"id":"5619cabd-8a3a-4f98-b79e-f4e8aadacf33","name":"Change name to photo3","type":"n8n-nodes-base.code","position":[1200,2740],"parameters":{"jsCode":"return items.map((item, index) => {\n  // Grab the existing binary buffer under \"data\"\n  const buffer = item.binary.data;\n  // Build a new item with the renamed binary key\n  return {\n    json: item.json,\n    binary: {\n      // Rename to photo1, photo2, ...\n      [`photo${index + 3}`]: buffer\n    }\n  };\n});\n"},"typeVersion":2},{"id":"743db045-9cce-41f2-b902-fcbdcc9cd306","name":"OpenAI - Generate Image 4","type":"n8n-nodes-base.httpRequest","position":[520,2980],"parameters":{"url":"https://api.openai.com/v1/images/edits","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","sendHeaders":true,"authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"model","value":"={{ $('Set API Variables').item.json.openai_image_model }}"},{"name":"prompt","value":"={{ $('Set All Prompts').item.json.prompt4 }}"},{"name":"n","value":"={{ $('Set API Variables').item.json.number_of_images }}"},{"name":"size","value":"={{ $('Set API Variables').item.json.size_of_image }}"},{"name":"image[]","parameterType":"formBinaryData","inputDataFieldName":"photo3"},{"name":"output_format","value":"={{ $('Set API Variables').item.json.format_image }}"}]},"headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json"}]},"nodeCredentialType":"openAiApi"},"credentials":{"openAiApi":{"id":"XJdxgMSXFgwReSsh","name":"n8n key"}},"typeVersion":4.2},{"id":"19997fd7-9deb-416a-8544-2c13fc4f9900","name":"Separate Image Outputs 4","type":"n8n-nodes-base.splitOut","position":[760,2980],"parameters":{"options":{},"fieldToSplitOut":"data"},"typeVersion":1},{"id":"9b521796-80c3-49e5-bf6c-83721783ab4c","name":"Convert to File 4","type":"n8n-nodes-base.convertToFile","position":[1000,2980],"parameters":{"options":{},"operation":"toBinary","sourceProperty":"b64_json"},"typeVersion":1.1},{"id":"f931e230-1a41-4608-933b-441955160097","name":"Change name to photo4","type":"n8n-nodes-base.code","position":[1200,2980],"parameters":{"jsCode":"return items.map((item, index) => {\n  // Grab the existing binary buffer under \"data\"\n  const buffer = item.binary.data;\n  // Build a new item with the renamed binary key\n  return {\n    json: item.json,\n    binary: {\n      // Rename to photo1, photo2, ...\n      [`photo${index + 4}`]: buffer\n    }\n  };\n});\n"},"typeVersion":2},{"id":"fa3c014c-1143-4975-8eab-26ce302d2312","name":"OpenAI - Generate Image 5","type":"n8n-nodes-base.httpRequest","position":[520,3240],"parameters":{"url":"https://api.openai.com/v1/images/edits","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","sendHeaders":true,"authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"model","value":"={{ $('Set API Variables').item.json.openai_image_model }}"},{"name":"prompt","value":"={{ $('Set All Prompts').item.json.prompt5 }}"},{"name":"n","value":"={{ $('Set API Variables').item.json.number_of_images }}"},{"name":"size","value":"={{ $('Set API Variables').item.json.size_of_image }}"},{"name":"image[]","parameterType":"formBinaryData","inputDataFieldName":"photo4"},{"name":"output_format","value":"={{ $('Set API Variables').item.json.format_image }}"}]},"headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json"}]},"nodeCredentialType":"openAiApi"},"credentials":{"openAiApi":{"id":"XJdxgMSXFgwReSsh","name":"n8n key"}},"typeVersion":4.2},{"id":"72fb090f-b6a5-432a-b45a-f52835cd63b2","name":"Separate Image Outputs 5","type":"n8n-nodes-base.splitOut","position":[760,3240],"parameters":{"options":{},"fieldToSplitOut":"data"},"typeVersion":1},{"id":"ed5689d2-68fe-4284-a46b-21b9ba3430b7","name":"Convert to File 5","type":"n8n-nodes-base.convertToFile","position":[1000,3240],"parameters":{"options":{},"operation":"toBinary","sourceProperty":"b64_json"},"typeVersion":1.1},{"id":"596b16da-ef12-4972-a894-d99a8d827cef","name":"Change name to photo5","type":"n8n-nodes-base.code","position":[1200,3240],"parameters":{"jsCode":"return items.map((item, index) => {\n  // Grab the existing binary buffer under \"data\"\n  const buffer = item.binary.data;\n  // Build a new item with the renamed binary key\n  return {\n    json: item.json,\n    binary: {\n      // Rename to photo1, photo2, ...\n      [`photo${index + 5}`]: buffer\n    }\n  };\n});\n"},"typeVersion":2},{"id":"2a814cfa-524c-433a-bdd3-36cf63570074","name":"POST TO TIKTOK","type":"n8n-nodes-base.httpRequest","position":[2200,2860],"parameters":{"url":"https://api.upload-post.com/api/upload_photos","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","sendHeaders":true,"bodyParameters":{"parameters":[{"name":"title","value":"={{\n\t(cp => cp.length > 90\n\t\t? cp.slice(0, 87).join('') + '…'   // 87 + “…” = 90\n\t\t: cp.join('')\n\t)([...$('Generate Description for Tiktok and Instagram')\n\t\t.first()\n\t\t.json\n\t\t.message\n\t\t.content])\n}}"},{"name":"user","value":"upload_post"},{"name":"platform[]","value":"tiktok"},{"name":"photos[]","parameterType":"formBinaryData","inputDataFieldName":"=photo1"},{"name":"photos[]","parameterType":"formBinaryData","inputDataFieldName":"photo2"},{"name":"photos[]","parameterType":"formBinaryData","inputDataFieldName":"photo3"},{"name":"photos[]","parameterType":"formBinaryData","inputDataFieldName":"photo4"},{"name":"photos[]","parameterType":"formBinaryData","inputDataFieldName":"photo5"},{"name":"auto_add_music","value":"true"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Apikey api_key_here"}]}},"typeVersion":4.2}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"bb858f9e-f0ab-40e1-8adb-2db736d8a4c8","connections":{"Merge":{"main":[[{"node":"Send as 1 merged file","type":"main","index":0}]]},"Set All Prompts":{"main":[[{"node":"Generate Description for Tiktok and Instagram","type":"main","index":0}]]},"Convert to File 1":{"main":[[{"node":"Change name to photo1","type":"main","index":0}]]},"Convert to File 2":{"main":[[{"node":"Change name to photo2","type":"main","index":0}]]},"Convert to File 3":{"main":[[{"node":"Change name to photo3","type":"main","index":0}]]},"Convert to File 4":{"main":[[{"node":"Change name to photo4","type":"main","index":0}]]},"Convert to File 5":{"main":[[{"node":"Change name to photo5","type":"main","index":0}]]},"Set API Variables":{"main":[[{"node":"OpenAI - Generate Image 1","type":"main","index":0}]]},"Change name to photo1":{"main":[[{"node":"OpenAI - Generate Image 2","type":"main","index":0},{"node":"Merge","type":"main","index":0}]]},"Change name to photo2":{"main":[[{"node":"Merge","type":"main","index":1},{"node":"OpenAI - Generate Image 3","type":"main","index":0}]]},"Change name to photo3":{"main":[[{"node":"Merge","type":"main","index":2},{"node":"OpenAI - Generate Image 4","type":"main","index":0}]]},"Change name to photo4":{"main":[[{"node":"Merge","type":"main","index":3},{"node":"OpenAI - Generate Image 5","type":"main","index":0}]]},"Change name to photo5":{"main":[[{"node":"Merge","type":"main","index":4}]]},"Send as 1 merged file":{"main":[[{"node":"POST TO INSTAGRAM","type":"main","index":0},{"node":"POST TO TIKTOK","type":"main","index":0}]]},"Separate Image Outputs 1":{"main":[[{"node":"Convert to File 1","type":"main","index":0}]]},"Separate Image Outputs 2":{"main":[[{"node":"Convert to File 2","type":"main","index":0}]]},"Separate Image Outputs 3":{"main":[[{"node":"Convert to File 3","type":"main","index":0}]]},"Separate Image Outputs 4":{"main":[[{"node":"Convert to File 4","type":"main","index":0}]]},"Separate Image Outputs 5":{"main":[[{"node":"Convert to File 5","type":"main","index":0}]]},"OpenAI - Generate Image 1":{"main":[[{"node":"Separate Image Outputs 1","type":"main","index":0}]]},"OpenAI - Generate Image 2":{"main":[[{"node":"Separate Image Outputs 2","type":"main","index":0}]]},"OpenAI - Generate Image 3":{"main":[[{"node":"Separate Image Outputs 3","type":"main","index":0}]]},"OpenAI - Generate Image 4":{"main":[[{"node":"Separate Image Outputs 4","type":"main","index":0}]]},"OpenAI - Generate Image 5":{"main":[[{"node":"Separate Image Outputs 5","type":"main","index":0}]]},"When clicking ‘Test workflow’":{"main":[[{"node":"Set All Prompts","type":"main","index":0}]]},"Generate Description for Tiktok and Instagram":{"main":[[{"node":"Set API Variables","type":"main","index":0}]]}}}


name: Auto-Respond to Gmail Enquiries using GPT-4o, Dumpling AI & LangChain Agent
author_name: Yang
author_username: yang
categories: []
created_at: 2025-05-14T21:06:14.263Z
updated_at: 2025-05-14T21:06:14.263Z
url: https://n8n.io/workflows/4057
scraped_at: 2025-06-19 22:07:56
description:
  Who is this for?

  This workflow is perfect for customer support teams, sales departments, or solopreneurs who receive frequent email enquiries and want to automate the initial response process using AI. If you spend too much time answering similar questions, this system helps respond faster and more intelligently—without writing a single line of code.

  What problem is this workflow solving?

  Manually responding to repeated customer enquiries slows productivity and increases delay. This workflow classifies if an incoming email is a real enquiry, analyzes the content with a LangChain-powered agent, fetches helpful context using Dumpling AI, and sends a personalized reply using Gmail—all within minutes.

  What this workflow does

  Listens for new incoming Gmail messages using the Gmail Trigger node.  
  Classifies whether the email is an enquiry using a GPT-4o classification prompt.  
  Uses a Filter node to continue only if the email was classified as an enquiry.  
  Passes the email content to a LangChain Agent, enhanced with memory, AI tools, and Dumpling AI to search for relevant information.  
  The agent constructs a smart, relevant response, then sends it to the original sender via Gmail.

  Setup

  Connect Gmail  
     Use the Gmail Trigger node to connect to the Gmail account that receives enquiries.  
     Make sure Gmail OAuth2 credentials are authenticated.

  Configure Dumpling AI Agent  
     Sign up at Dumpling AI.  
     Create an agent trained to search your help docs, site content, or FAQs.  
     Copy your Dumpling agent ID and API key.  
     Paste it in the Dumpling AI Agent – Search for Relevant Info HTTP Request node.

  Set Up LangChain Agent  
     No extra setup needed beyond connecting OpenAI credentials.  
     GPT-4o is used for classification and reply generation.

  Enable Gmail Reply Node  
     The final Send Email Response via Gmail node will send the AI-generated reply back to the same thread.

  How to customize this workflow to your needs

  Change the classification prompt to include other email types like “support”, “complaint”, or “sales”.  
  Add additional logic if you want to CC someone or forward certain types of enquiries.  
  Add a Notion or Google Sheets node to log the conversation for analytics.  
  Replace Gmail with Outlook or another email provider by switching the nodes.  
  Improve context by adding more AI tools like database queries or preloaded FAQs.

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

workflow_json:
  {"id":"uQTqLH5At9PZOy2g","meta":{"instanceId":"a1ae5c8dc6c65e674f9c3947d083abcc749ef2546dff9f4ff01de4d6a36ebfe6","templateCredsSetupCompleted":true},"name":"Auto-Respond to Gmail Enquiries using GPT-4o, Dumpling AI & LangChain Agent","tags":[],"nodes":[{"id":"149c7dd9-9f5f-4c5b-8342-7c907eb52402","name":"Watch Gmail for New Incoming Emails","type":"n8n-nodes-base.gmailTrigger","position":[-2300,-340],"parameters":{"filters":{},"pollTimes":{"item":[{"mode":"everyMinute"}]}},"credentials":{"gmailOAuth2":{"id":"j70r3RTMED1pgN3R","name":"Gmail account 2"}},"typeVersion":1.2},{"id":"8a0de384-9028-47e3-86e5-b5bf6476ae0c","name":"Classify Email Type with GPT-4o","type":"@n8n/n8n-nodes-langchain.openAi","position":[-2080,-340],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4o","cachedResultName":"GPT-4O"},"options":{},"messages":{"values":[{"content":"=Classify the following email content. Determine if it is an enquiry.\nIf it is an enquiry, return only this word: enquiry\nIf it is not an enquiry, return only this word: false\nDo not explain or add any other text. Only return the result.\nHere is the email body: {{ $json.snippet }}"}]}},"credentials":{"openAiApi":{"id":"fdhWALG84tBLgSZT","name":"OpenAi account"}},"typeVersion":1.8},{"id":"57756cd3-9009-4189-8cba-e2edba87554f","name":" Only Proceed if Email is an Enquiry","type":"n8n-nodes-base.filter","position":[-1704,-340],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"e6019006-0980-4cd6-8e5d-3f618fbca13a","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.message.content }}","rightValue":"enquiry"}]}},"typeVersion":2.2},{"id":"64e851b8-7ff1-4b4c-9828-7c764594f1ea","name":"GPT-4o Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-1484,-120],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"fdhWALG84tBLgSZT","name":"OpenAi account"}},"typeVersion":1.2},{"id":"2957c6ad-5e7b-4692-a96f-5c4fb5b8203c","name":"Memory Buffer (Past 10 Interactions)","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[-1364,-120],"parameters":{"contextWindowLength":10},"typeVersion":1.3},{"id":"9e8617f1-cd89-4de5-9d44-ded155779745","name":"Dumpling AI Agent – Search for Relevant Info","type":"@n8n/n8n-nodes-langchain.toolHttpRequest","position":[-1244,-120],"parameters":{"url":"https://app.dumplingai.com/api/v1/agents/generate-completion","method":"POST","jsonBody":"={\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\":\"{{ $('Watch Gmail for New Incoming Emails').item.json.snippet }}\"\n    }\n  ],\n  \"agentId\": \"a88a9b6c-1578-4da2-800b-561327367713\",\n  \"parseJson\": \"True\"\n  }","sendBody":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"5CBvzXCLjwWzCJRE","name":"n8n_integration"}},"typeVersion":1.1},{"id":"da474406-a6e3-427d-b21b-3e7e00ebe910","name":"Send Email Response via Gmail","type":"n8n-nodes-base.gmailTool","position":[-1124,-120],"webhookId":"b39f740b-77d1-426a-a07a-186a9ff0c1af","parameters":{"sendTo":"","message":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Message', ``, 'string') }}","options":{},"subject":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Subject', ``, 'string') }}"},"credentials":{"gmailOAuth2":{"id":"j70r3RTMED1pgN3R","name":"Gmail account 2"}},"typeVersion":2.1},{"id":"03882650-9272-43c3-b1bc-15adae456881","name":"LangChain Agent Handles Reply Logic","type":"@n8n/n8n-nodes-langchain.agent","position":[-1392,-340],"parameters":{"text":"={{ $('Watch Gmail for New Incoming Emails').item.json.snippet }}","options":{"systemMessage":"You are a helpful assistant, use the search for information tool to search for users information.\n\nuse Gmail tool to send email"},"promptType":"define"},"typeVersion":1.8},{"id":"52bb3b65-0b7f-4206-87c9-1f91997a44dd","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1500,-560],"parameters":{"width":480,"height":240,"content":"### ✉️ Sticky Note 2: Website Scraping, Email Generation, and Sending\n\nFor leads with complete data, Dumpling AI scrapes the content of the lead’s company website. This content, combined with scraped details, is structured into a prompt using the Set node. GPT-4o processes the prompt and generates a personalized cold email. The email is then sent to the lead using Gmail. This automates targeted cold outreach using scraped insights and AI-generated messaging.\n"},"typeVersion":1},{"id":"3a6df2e9-1d1a-4cab-889c-c323f876b98f","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-2320,-540],"parameters":{"width":540,"height":220,"content":"### Sticky Note 1: Apollo Link Sourcing & Contact Scraping\n\nThis section begins the workflow manually. The Apollo lead URLs are pulled from a Google Sheet. Each link is passed to Apify which scrapes key lead details such as name, email, company website, and other contact data. After scraping, a filter checks that both an email and website were found for the lead before moving forward. This ensures only complete lead data is used for outreach.\n\n"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"0f1d6a0b-eb13-4e1a-be9e-3f22eb17e66e","connections":{"GPT-4o Chat Model":{"ai_languageModel":[[{"node":"LangChain Agent Handles Reply Logic","type":"ai_languageModel","index":0}]]},"Send Email Response via Gmail":{"ai_tool":[[{"node":"LangChain Agent Handles Reply Logic","type":"ai_tool","index":0}]]},"Classify Email Type with GPT-4o":{"main":[[{"node":" Only Proceed if Email is an Enquiry","type":"main","index":0}]]},"LangChain Agent Handles Reply Logic":{"main":[[]]},"Watch Gmail for New Incoming Emails":{"main":[[{"node":"Classify Email Type with GPT-4o","type":"main","index":0}]]}," Only Proceed if Email is an Enquiry":{"main":[[{"node":"LangChain Agent Handles Reply Logic","type":"main","index":0}]]},"Memory Buffer (Past 10 Interactions)":{"ai_memory":[[{"node":"LangChain Agent Handles Reply Logic","type":"ai_memory","index":0}]]},"Dumpling AI Agent – Search for Relevant Info":{"ai_tool":[[{"node":"LangChain Agent Handles Reply Logic","type":"ai_tool","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:07:56
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:07:56
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: 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:07:56
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: 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:07:56
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: 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:07:56
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:07:56
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:07:56
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: 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:07:56
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:07:56
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:07:56
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: 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:07:56
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:07:56
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}]]}}}


