# templates

name: AI-Powered Vendor Policy & RSS Feed Analysis with Integrated Risk Scoring
author_name: Kamalraj
author_username: kamalraj
categories: []
created_at: 2025-06-21T13:38:35.772Z
updated_at: 2025-06-21T13:38:35.772Z
url: https://n8n.io/workflows/5103
scraped_at: 2025-07-06 21:16:30
description:
  🧠 Overview

  A dual-engine, AI-driven n8n workflow that automates the monitoring of both vendor policy webpages and compliance-related RSS feeds. It intelligently detects recent updates, evaluates their potential risk, and delivers a structured HTML digest categorized by severity — right to your inbox.

  ⚙️ How It Works

  1️⃣ Scheduled Execution  
  ⏰ Runs daily at 3 AM to ensure timely and consistent monitoring.

  2️⃣ Dual Data Streams  
  📰 RSS Feed Monitoring: Ingests articles from selected feeds focused on security, privacy, and compliance.  
  🌐 Vendor Webpage Monitoring: Fetches specified policy URLs and checks for updates using Last-Modified headers and in-page content analysis.

  3️⃣ Content Filtering  
  🧹 Applies logic to filter out stale or irrelevant data, focusing only on updates within the past 24 hours.

  4️⃣ AI-Powered Risk Categorization  
  🤖 Two dedicated AI agents (one per stream) analyze content to:  
  📝 Generate a 2-line compliance/risk-focused summary  
  🚦 Assign a risk score: High, Medium, Low, or Informational

  5️⃣ Digest Generation  
  🖼️ Summaries are grouped by risk level and formatted into a visually polished HTML report, using category-specific styles and color coding.

  6️⃣ Email Delivery  
  📧 Automatically sends out two separate email reports via Gmail:  
  🗂️ One for vendor webpage updates  
  📰 One for RSS feed-based vendor news

  ✨ Key Features

  🔁 Automates daily monitoring across feeds and policy pages  
  🤖 AI-driven summarization and structured risk scoring  
  🧾 Clean, HTML-formatted digests grouped by risk category  
  🧩 Fully customizable: feed sources, vendor URLs, AI prompts, and email styling  
  🛡️ Designed for compliance, security, and risk teams needing proactive intelligence

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

workflow_json:
  {"id":"DHLbKyEoYyzkhEBA","meta":{"instanceId":"818946a823ca34034ea73f38168c80e4b7ae5021e8280b7645e14b95574ba259"},"name":"AI-Powered Vendor Policy & Feed Analysis with Integrated Risk Scoring","tags":[],"nodes":[{"id":"477ac26f-b2f9-48a9-ba04-8acff89225ff","name":"HTTP Request","type":"n8n-nodes-base.httpRequest","notes":"🌐 Requests vendor policy pages for content inspection.","position":[-700,260],"parameters":{"url":"={{ $json.feedUrl }}","options":{"response":{"response":{"fullResponse":true}}}},"notesInFlow":true,"typeVersion":4.2,"alwaysOutputData":false},{"id":"209ac43c-361b-4cdf-b8f1-5cfadf3bace0","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","notes":"🤖 Analyzes grouped RSS feeds and categorizes risks using structured JSON.","position":[200,-420],"parameters":{"text":"={{ $json.entries }}","options":{"systemMessage":"=Vendor Risk & Compliance Digest Prompt\n\nAI Agent Role: You are a Senior Compliance & Risk Intelligence Analyst embedded in an automation workflow. Your job is to analyze compliance-related content from vendor feeds and produce structured, actionable summaries for use by compliance, security, and executive teams. Dont Halucinate, Dont add any new news, only act on the provided data\n\n🧾 Input Format\n\nYou will receive a single JSON object containing an array of items. Each item is structured as:\n\n{\n  \"Title\": \"...\",\n  \"Vendor Name\": \"...\",\n  \"link\": \"https://…\",\n  \"content\": \"Snippet or article content here\"\n}\n\n🧠 Instructions\n\nDeduplicate entries by the link field.\n\nFor each unique item:\n\nAssign a Risk Rating:\n\nHigh\n\nMedium\n\nLow\n\nInformational\n\nWrite a 2-sentence summary from a compliance, risk, or security standpoint.\n\nGroup the output by the risk level in a single JSON object.\n\nOmit any empty groups (i.e., risk levels with no entries).\n\nDo not include extra prose, HTML, Markdown, or escape characters.\n\n✅ Output Format\n\nRespond with only this structure:\n\n{\n  \"High\": [\n    { \"summary\": \"...\", \"link\": \"https://...\", \"Title\": \"...\",\"Vendor Name\": \"...\" }\n  ],\n  \"Medium\": [ ... ],\n  \"Low\": [ ... ],\n  \"Informational\": [ ... ]\n}\n\nThis output will be used by downstream code to generate an HTML email digest.","passthroughBinaryImages":false},"promptType":"define"},"notesInFlow":true,"typeVersion":2,"alwaysOutputData":false},{"id":"371b32e3-46de-41a7-9358-34761fb1a796","name":"RSS Feed List","type":"n8n-nodes-base.code","notes":"📰 Provide a list of RSS feeds (Security, Privacy, Compliance). Customize URLs as needed.","position":[-1120,-320],"parameters":{"jsCode":"const feeds = [\n  { name: 'TechCrunch',    feedUrl: 'https://techcrunch.com/feed/' },\n  { name: 'The Verge',     feedUrl: 'https://www.theverge.com/rss/index.xml' },\n  { name: 'SmashingMag',    feedUrl: 'https://www.smashingmagazine.com/feed/' },\n];\n\n// 2) Transform into n8n-compatible output\nreturn feeds.map(feed => ({\n  json: {\n    name:    feed.name,\n    feedUrl: feed.feedUrl,\n  }\n}));"},"executeOnce":true,"notesInFlow":true,"typeVersion":2},{"id":"2f441c7f-6acf-49a8-bfdc-7daca7d444d1","name":"Splitting the Feeds","type":"n8n-nodes-base.splitOut","notes":"🔀 Split RSS list so each feed can be fetched individually.","position":[-900,-320],"parameters":{"options":{},"fieldToSplitOut":"feedUrl"},"notesInFlow":true,"typeVersion":1},{"id":"745a6e0b-418a-4f1f-ace6-2b91ac5e0a8a","name":"Vendor RSS Feed Read","type":"n8n-nodes-base.rssFeedRead","notes":"📥 Reads RSS feed content per URL.","position":[-680,-320],"parameters":{"url":"={{ $json.feedUrl }}","options":{}},"notesInFlow":true,"typeVersion":1.1},{"id":"ec6e38d4-dcc4-4b16-8894-d4161a244291","name":"Vendor URLs","type":"n8n-nodes-base.code","notes":"🌐 Provide a list of direct vendor policy webpage URLs to monitor updates.","position":[-1140,260],"parameters":{"jsCode":"const feeds = [\n    \n  {\n  name: 'test', feedUrl:'https://www.ted.com/about/our-organization/our-policies-terms/privacy-policy'},\n  {name: 'test2', feedUrl: 'https://www.teamviewer.com/en-in/global/support/knowledge-base/teamviewer-remote/devices/policies/'},\n];\n\n// 2) Transform into n8n-compatible output\nreturn feeds.map(feed => ({\n  json: {\n    name:    feed.name,\n    feedUrl: feed.feedUrl,\n  }\n}));"},"notesInFlow":true,"typeVersion":2},{"id":"7c705e85-bff5-4d71-9a82-5985b1f230c1","name":"AI Agent1","type":"@n8n/n8n-nodes-langchain.agent","notes":"🧠 Summarizes individual webpage content into short risk summaries.","position":[560,260],"parameters":{"text":"={{ $json.content }} & {{ $json.url }}","options":{"systemMessage":"You are a Senior Risk and Compliance Analyst.\n\nYour job is to:\n- Read the content and generate a short 2-line summary\n- Categorize the risk as one of: High, Medium, Low, Informational\n\nReturn a clean JSON like:\n{\n  \"summary\": \"...\",\n  \"risk\": \"Medium\",\n  \"title\": \"...\",\n  \"Vendor Name\": \"....\",\n  \"url\": \"...\"\n}\n\nInput:\nTitle: {{$json[\"title\"]}}\nLink: {{$json[\"link\"]}}\nContent: {{$json[\"content\"]}}\n","passthroughBinaryImages":false},"promptType":"define"},"notesInFlow":true,"typeVersion":2,"alwaysOutputData":false},{"id":"225e4108-f4e1-428c-a62a-870fdf2e0eb4","name":"Google Gemini Chat Model1","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[580,480],"parameters":{"options":{},"modelName":"models/gemini-2.0-flash-001"},"credentials":{"googlePalmApi":{"id":"3Ekb1D8LUyg2zvwJ","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"92968717-e76c-4fd4-acad-7cae37e6ca07","name":"Gmail","type":"n8n-nodes-base.gmail","notes":"📨 Sends summary email for webpage policy updates.","position":[1160,260],"webhookId":"d33f7afd-47c3-4616-9a37-6319d93c0e92","parameters":{"sendTo":"Email id here","message":"={{ $json.html }}","options":{},"subject":"=Vendor Webpage Change  {{$now}}"},"credentials":{"gmailOAuth2":{"id":"DCglvd9VagxSYbJx","name":"Gmail account"}},"notesInFlow":true,"typeVersion":2.1},{"id":"d7e6e8bd-6f10-4107-b31f-c65650b40ce4","name":"Gmail1","type":"n8n-nodes-base.gmail","notes":"📧 Sends HTML newsletter summary email for RSS feeds.","position":[960,-320],"webhookId":"66d44179-c4aa-4acd-b61e-d91a1f888d9d","parameters":{"sendTo":"Email id here","message":"={{ $json.html }}","options":{},"subject":"=Vendor RSS Feed Monitoring as on {{ $now }}"},"credentials":{"gmailOAuth2":{"id":"DCglvd9VagxSYbJx","name":"Gmail account"}},"notesInFlow":true,"typeVersion":2.1},{"id":"dbe4724d-1914-40f3-b79b-48927a7dd62b","name":"Google Gemini Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[200,-200],"parameters":{"options":{},"modelName":"models/gemini-2.0-flash-001"},"credentials":{"googlePalmApi":{"id":"3Ekb1D8LUyg2zvwJ","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"df8b19b8-a079-4776-9165-4272f65d1833","name":"Filtering last 24hrs feed","type":"n8n-nodes-base.filter","notes":"⏳ Filters RSS articles published in the last 24 hours.","position":[-460,-320],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"or","conditions":[{"id":"09fe1774-6a5a-4cf5-97c8-0afb7d44431e","operator":{"type":"number","operation":"gte"},"leftValue":"={{ new Date($json.isoDate).getTime() }}","rightValue":"={{Date.now() - 24 * 60 * 60 * 1000 }}"},{"id":"93e97b32-40d7-4514-bc70-a7f51729b681","operator":{"type":"number","operation":"gte"},"leftValue":"={{ new Date($json.pubDate).getTime()}}","rightValue":"={{ Date.now() - 24 * 60 * 60 * 1000 }}"}]}},"notesInFlow":true,"typeVersion":2.2},{"id":"2a4925f3-69cd-4162-9e65-dfd69f47e8c8","name":"Formatting the Content for Mail","type":"n8n-nodes-base.code","notes":"💌 Formats AI response as styled HTML grouped by risk category.","position":[660,-320],"parameters":{"jsCode":"const allItems = $input.all();\nlet combined = [];\n\nfor (const item of allItems) {\n  let rawOutput = item.json.output || '';\n\n  let cleaned = rawOutput\n    .replace(/^```json\\s*/, '')\n    .replace(/```$/, '')\n    .trim()\n    .replace(/,\\s*(\\]|\\})/g, '$1');\n\n  try {\n    const parsed = JSON.parse(cleaned);\n    for (const [riskLevel, entries] of Object.entries(parsed)) {\n      if (Array.isArray(entries)) {\n        entries.forEach(entry => {\n          combined.push({\n            risk: riskLevel,\n            summary: entry.summary,\n            link: entry.link,\n            title: entry.title || '',\n            vendor: entry['Vendor Name'] || ''\n          });\n        });\n      }\n    }\n  } catch (err) {\n    throw new Error(\"Invalid JSON in input item: \" + err.message);\n  }\n}\n\nconst riskData = { High: [], Medium: [], Low: [], Informational: [] };\ncombined.forEach(entry => {\n  const risk = entry.risk || 'Informational';\n  riskData[risk]?.push(entry);\n});\n\nconst categoryStyles = {\n  High: { color: '#f28b82', emoji: '🔴' },\n  Medium: { color: '#fbbc04', emoji: '🟠' },\n  Low: { color: '#81c995', emoji: '🟢' },\n  Informational: { color: '#a7c7e7', emoji: '🔵' }\n};\n\nlet html = `\n<!DOCTYPE html>\n<html>\n<head>\n  <style>\n    @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');\n    body {\n      font-family: 'Inter', sans-serif;\n      background: #fff;\n      padding: 32px;\n      margin: 0;\n      color: #333;\n    }\n    .risk-YOUR_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE {\n      font-size: 22px;\n      font-weight: 700;\n      margin: 30px 0 20px;\n      padding: 16px 24px;\n      border-radius: 16px;\n      color: #fff;\n      display: inline-block;\n      box-shadow: 0 2px 8px rgba(0,0,0,0.08);\n    }\n    .card {\n      background: #fff;\n      border-left: 6px solid;\n      border-radius: 12px;\n      padding: 24px;\n      margin: 20px 0;\n      box-shadow: 0 1px 6px rgba(0,0,0,0.06);\n      max-width: 800px;\n    }\n    .vendor {\n      font-size: 18px;\n      font-weight: 700;\n      color: #111;\n      margin-bottom: 6px;\n    }\n    .title {\n      font-size: 15px;\n      font-weight: 600;\n      color: #444;\n      margin-bottom: 14px;\n    }\n    .summary {\n      font-size: 15px;\n      line-height: 1.6;\n      margin-bottom: 12px;\n    }\n    .read-more a {\n      font-size: 14px;\n      color: #1a73e8;\n      text-decoration: none;\n      font-weight: 500;\n    }\n    .read-more a:hover {\n      text-decoration: underline;\n    }\n  </style>\n</head>\n<body>\n`;\n\nfor (const [category, entries] of Object.entries(riskData)) {\n  if (entries.length === 0) continue;\n  const { color, emoji } = categoryStyles[category];\n  html += `<div class=\"risk-YOUR_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE\" style=\"background-color: ${color};\">${emoji} ${category} Risk</div>`;\n  entries.forEach(item => {\n    html += `\n      <div class=\"card\" style=\"border-left-color: ${color};\">\n        <div class=\"vendor\">${item.vendor || '—'}</div>\n        <div class=\"title\">${item.title || '—'}</div>\n        <div class=\"summary\">${item.summary}</div>\n        <div class=\"read-more\"><a href=\"${item.link}\" target=\"_blank\" rel=\"noopener noreferrer\">Read more</a></div>\n      </div>\n    `;\n  });\n}\n\nhtml += `</body></html>`;\n\nreturn [{ json: { html } }];\n"},"notesInFlow":true,"typeVersion":2},{"id":"1e2a44d6-bc8b-42e8-abe9-c08e9dfde4a5","name":"Sort the feeds","type":"n8n-nodes-base.sort","notes":"🔃 Sort the RSS entries by pubDate for consistent order.","position":[-240,-320],"parameters":{"options":{},"sortFieldsUi":{"sortField":[{"fieldName":"pubDate"}]}},"notesInFlow":true,"typeVersion":1},{"id":"4a7bb247-bc86-4228-b4a4-9a94e5bfcfb4","name":"Merge the content for AI","type":"n8n-nodes-base.code","notes":"🧩 Merges cleaned RSS entries into one payload for the AI agent.","position":[-20,-320],"parameters":{"jsCode":"// Build an array of { link, content } pairs\nconst entries = items.map(item => ({\n  link:    item.json.link,\n  content: item.json.contentSnippet || item.json.content || \"\"\n}));\n\n// Return one item with a single field “entries”\nreturn [\n  {\n    json: {\n      entries\n    }\n  }\n];\n"},"notesInFlow":true,"typeVersion":2},{"id":"1a4ca2a0-1379-4140-b9a0-f0a7efd5e774","name":"Merge","type":"n8n-nodes-base.merge","notes":"🔀 Merge both page meta and body-based content analysis.","position":[-40,260],"parameters":{},"notesInFlow":true,"typeVersion":3.2},{"id":"d8a76c14-7aad-47f8-9b62-8254bb1e2d01","name":"Format the Summary for Email","type":"n8n-nodes-base.code","notes":"🧾 Formats webpage summary output into email-ready HTML.","position":[940,260],"parameters":{"jsCode":"const allItems = $input.all();\nlet combined = [];\n\nfor (const item of allItems) {\n  let rawOutput = item.json.output || '';\n\n  let cleaned = rawOutput\n    .replace(/^```json\\s*/, '')\n    .replace(/```$/, '')\n    .trim()\n    .replace(/,\\s*(\\]|\\})/g, '$1');\n\n  try {\n    const parsed = JSON.parse(cleaned);\n    if (Array.isArray(parsed)) {\n      combined.push(...parsed);\n    } else if (parsed && parsed.risk && parsed.summary) {\n      combined.push(parsed);\n    }\n  } catch (err) {\n    throw new Error(\"Invalid JSON in input item: \" + err.message);\n  }\n}\n\n// Group by risk\nlet riskData = {\n  High: [],\n  Medium: [],\n  Low: [],\n  Informational: []\n};\n\ncombined.forEach(entry => {\n  const risk = entry.risk || 'Informational';\n  riskData[risk]?.push(entry);\n});\n\nconst categoryStyles = {\n  High: { color: '#f28b82', emoji: '🔴' },\n  Medium: { color: '#fbbc04', emoji: '🟠' },\n  Low: { color: '#81c995', emoji: '🟢' },\n  Informational: { color: '#a7c7e7', emoji: '🔵' },\n};\n\nlet html = `\n<!DOCTYPE html>\n<html>\n<head>\n  <style>\n    @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');\n    body {\n      font-family: 'Inter', sans-serif;\n      background: #fff;\n      padding: 32px;\n      margin: 0;\n      color: #333;\n    }\n    .risk-YOUR_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE {\n      font-size: 22px;\n      font-weight: 700;\n      margin: 30px 0 20px;\n      padding: 16px 24px;\n      border-radius: 16px;\n      color: #fff;\n      display: inline-block;\n      box-shadow: 0 2px 8px rgba(0,0,0,0.08);\n    }\n    .card {\n      background: #fff;\n      border-left: 6px solid;\n      border-radius: 12px;\n      padding: 24px;\n      margin: 20px 0;\n      box-shadow: 0 1px 6px rgba(0,0,0,0.06);\n      max-width: 800px;\n    }\n    .vendor {\n      font-size: 18px;\n      font-weight: 700;\n      color: #111;\n      margin-bottom: 6px;\n    }\n    .title {\n      font-size: 15px;\n      font-weight: 600;\n      color: #444;\n      margin-bottom: 14px;\n    }\n    .summary {\n      font-size: 15px;\n      line-height: 1.6;\n      margin-bottom: 12px;\n    }\n    .read-more a {\n      font-size: 14px;\n      color: #1a73e8;\n      text-decoration: none;\n      font-weight: 500;\n    }\n    .read-more a:hover {\n      text-decoration: underline;\n    }\n  </style>\n</head>\n<body>\n`;\n\nfor (const [category, entries] of Object.entries(riskData)) {\n  if (entries.length === 0) continue;\n  const { color, emoji } = categoryStyles[category];\n  html += `<div class=\"risk-YOUR_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE\" style=\"background-color: ${color};\">${emoji} ${category} Risk</div>`;\n  entries.forEach(item => {\n    html += `\n      <div class=\"card\" style=\"border-left-color: ${color};\">\n        <div class=\"vendor\">${item['Vendor Name'] || 'Vendor Unknown'}</div>\n        <div class=\"title\">${item.title || 'Untitled Update'}</div>\n        <div class=\"summary\">${item.summary}</div>\n        <div class=\"read-more\"><a href=\"${item.url || item.link}\" target=\"_blank\" rel=\"noopener noreferrer\">Read more</a></div>\n      </div>\n    `;\n  });\n}\n\nhtml += `</body></html>`;\n\nreturn [{ json: { html } }];\n"},"notesInFlow":true,"typeVersion":2},{"id":"eb66887a-7de8-4151-8368-9e394084bdce","name":"Scrapping inside the Webpage content","type":"n8n-nodes-base.code","notes":"🔍 Inspects webpage HTML body to find 'update/modified' dates.","position":[-240,380],"parameters":{"jsCode":"const now = new Date();\nconst results = [];\n\nconst datePatterns = [\n  /\\b(\\d{4}-\\d{2}-\\d{2}(?:[ T]\\d{2}:\\d{2}:\\d{2}(?:Z|[+\\-]\\d{2}:\\d{2})?)?)\\b/g,  // ISO + timezone\n  /\\b(\\d{4}\\/\\d{2}\\/\\d{2}(?:[ T]\\d{2}:\\d{2}:\\d{2})?)\\b/g,\n  /\\b(\\d{2}\\/\\d{2}\\/\\d{4}(?: \\d{2}:\\d{2}:\\d{2})?)\\b/g,\n  /\\b(\\d{2}\\.\\d{2}\\.\\d{4})\\b/g,\n  /\\b([A-Z][a-z]{2,8} \\d{1,2},? \\d{4})\\b/g,\n  /\\b(\\d{1,2} [A-Z][a-z]{2,8} \\d{4})\\b/g,\n  /\\b([A-Z][a-z]{2},? \\d{1,2} [A-Z][a-z]{2} \\d{4})\\b/g  // e.g., Fri, 20 Jun 2025\n];\n\nconst keywordRegex = /(updated|modified|published)/i;\nconst relativeRegex = /(updated|modified|published)[^\\d]{0,30}(today|yesterday)/i;\nconst keywordDateRegex = new RegExp(\n  `(updated|modified|published)[^\\\\dA-Z]{0,30}[:\\\\-\\\\s]*?(\\\\d{4}-\\\\d{2}-\\\\d{2}(?:[ T]\\\\d{2}:\\\\d{2}:\\\\d{2})?|\\\\d{2}\\\\/\\\\d{2}\\\\/\\\\d{4}|\\\\d{2}\\\\.\\\\d{2}\\\\.\\\\d{4}|[A-Z][a-z]{2,8} \\\\d{1,2},? \\\\d{4})`,\n  'i'\n);\n\nfor (const item of items) {\n  const content = item.json.data || \"\";\n  let found = false;\n  let matchedDate = null;\n  let matchedType = null;\n  let matchedKeyword = null;\n  let note = \"\";\n  let published = null;\n\n  // --- 1. Direct keyword-date detection (e.g. Updated: 2025-06-20)\n  const directMatch = content.match(keywordDateRegex);\n  if (directMatch) {\n    matchedKeyword = directMatch[1];\n    const dateStr = directMatch[2];\n    const parsedDate = new Date(dateStr);\n\n    if (!isNaN(parsedDate)) {\n      const isRecent = (() => {\n        const diffMs = now - parsedDate;\n        if (/\\d{2}:\\d{2}:\\d{2}/.test(dateStr)) {\n          return diffMs >= 0 && diffMs <= 24 * 60 * 60 * 1000;\n        } else {\n          const test = new Date(parsedDate); test.setHours(0,0,0,0);\n          const nowTrimmed = new Date(now); nowTrimmed.setHours(0,0,0,0);\n          const diffDays = (nowTrimmed - test) / (24 * 60 * 60 * 1000);\n          return diffDays === 0 || diffDays === 1;\n        }\n      })();\n\n      if (isRecent) {\n        found = true;\n        matchedDate = dateStr;\n        matchedType = /\\d{2}:\\d{2}:\\d{2}/.test(dateStr) ? \"datetime\" : \"date-only\";\n        note = `Found '${matchedKeyword}' with ${matchedType} \"${dateStr}\" (recent).`;\n      }\n    }\n  }\n\n  // --- 2. Relative phrases like \"Updated yesterday\"\n  if (!found) {\n    const relMatch = content.match(relativeRegex);\n    if (relMatch) {\n      matchedKeyword = relMatch[1];\n      const rel = relMatch[2].toLowerCase();\n      if (rel === \"today\" || rel === \"yesterday\") {\n        const refDate = new Date(now);\n        if (rel === \"yesterday\") refDate.setDate(refDate.getDate() - 1);\n        const isoDate = refDate.toISOString().split(\"T\")[0];\n        found = true;\n        matchedDate = isoDate;\n        matchedType = \"relative\";\n        note = `Found '${matchedKeyword}' with relative date \"${rel}\".`;\n      }\n    }\n  }\n\n  // --- 3. Fallback: Any keyword in proximity of any valid date\n  if (!found && keywordRegex.test(content)) {\n    for (const pat of datePatterns) {\n      pat.lastIndex = 0;\n      let dateMatch;\n      while ((dateMatch = pat.exec(content)) !== null) {\n        const dateStr = dateMatch[1];\n        const parsedDate = new Date(dateStr);\n        if (!isNaN(parsedDate)) {\n          const isTime = /\\d{2}:\\d{2}:\\d{2}/.test(dateStr);\n          const diff = isTime ? now - parsedDate : (() => {\n            const pd = new Date(parsedDate); pd.setHours(0,0,0,0);\n            const nd = new Date(now); nd.setHours(0,0,0,0);\n            return (nd - pd);\n          })();\n          const withinLimit = isTime ? diff >= 0 && diff <= 86400000 : (diff === 0 || diff === 86400000);\n          if (withinLimit) {\n            found = true;\n            matchedKeyword = \"generic-fallback\";\n            matchedDate = dateStr;\n            matchedType = isTime ? \"datetime\" : \"date-only\";\n            note = `Fallback: keyword present and found nearby date \"${dateStr}\" (recent).`;\n            break;\n          }\n        }\n      }\n      if (found) break;\n    }\n  }\n\n  // --- Extract published (non-filtering fallback)\n  if (!published) {\n    for (const pat of datePatterns) {\n      const match = pat.exec(content);\n      if (match && Date.parse(match[1])) {\n        published = match[1];\n        break;\n      }\n    }\n  }\n\n  // --- Return only matched results\n  if (!found) continue;\n\n  results.push({\n    json: {\n      keywordDetected: true,\n      matchedKeyword,\n      matchedDate,\n      matchedType,\n      published: published || \"Not available\",\n      note,\n      data: content\n    }\n  });\n}\n\nreturn results;\n"},"notesInFlow":true,"typeVersion":2},{"id":"dd0073e0-dbe8-4a46-953f-cc3759160817","name":"Cleaning up the code","type":"n8n-nodes-base.code","notes":"🧹 Cleans and strips raw HTML into readable content for AI processing.","position":[260,260],"parameters":{"jsCode":"const items = [];\n\nfor (const item of $input.all()) {\n  const rawHtml = item.json.body || item.json.data || \"\";\n  let urlFromRequest = item.json.url || item.json.requestUrl || item.json.headers?.['x-final-url'] || '';\n\n  let html = rawHtml.toString();\n\n  // Try to extract canonical URL or og:url from HTML head\n  let extractedUrl = '';\n\n  const canonicalMatch = html.match(/<link[^>]+rel=[\"']canonical[\"'][^>]*href=[\"']([^\"']+)[\"']/i);\n  if (canonicalMatch) {\n    extractedUrl = canonicalMatch[1];\n  } else {\n    const ogUrlMatch = html.match(/<meta[^>]+property=[\"']og:url[\"'][^>]*content=[\"']([^\"']+)[\"']/i);\n    if (ogUrlMatch) {\n      extractedUrl = ogUrlMatch[1];\n    }\n  }\n\n  const finalUrl = extractedUrl || urlFromRequest;\n\n  // Strip scripts/styles/noscript/iframe/svg/etc.\n  html = html.replace(/<script[\\s\\S]*?>[\\s\\S]*?<\\/script>/gi, '');\n  html = html.replace(/<style[\\s\\S]*?>[\\s\\S]*?<\\/style>/gi, '');\n  html = html.replace(/<noscript[\\s\\S]*?>[\\s\\S]*?<\\/noscript>/gi, '');\n  html = html.replace(/<iframe[\\s\\S]*?>[\\s\\S]*?<\\/iframe>/gi, '');\n  html = html.replace(/<svg[\\s\\S]*?>[\\s\\S]*?<\\/svg>/gi, '');\n  html = html.replace(/<!--[\\s\\S]*?-->/g, '');\n  html = html.replace(/<\\/?[^>]+(>|$)/g, '');\n\n  // Decode HTML entities\n  html = html\n    .replace(/&nbsp;/g, ' ')\n    .replace(/&amp;/g, '&')\n    .replace(/&quot;/g, '\"')\n    .replace(/&lt;/g, '<')\n    .replace(/&gt;/g, '>');\n\n  // Clean whitespace\n  let content = html.replace(/\\s{2,}/g, ' ').trim();\n\n  // Limit size (safe for AI)\n  const maxLength = 30000;\n  if (content.length > maxLength) content = content.slice(0, maxLength) + '... [truncated]';\n\n  items.push({\n    json: {\n      url: finalUrl,\n      content\n    }\n  });\n}\n\nreturn items;\n"},"notesInFlow":true,"typeVersion":2},{"id":"c37f2b54-bdd5-4177-b70d-b48226692b7b","name":"Daily Trigger","type":"n8n-nodes-base.scheduleTrigger","notes":"⏰ Triggers the workflow every day at 3 AM to initiate all newsletter jobs.","position":[-1740,20],"parameters":{"rule":{"interval":[{"triggerAtHour":3}]}},"notesInFlow":true,"typeVersion":1.2},{"id":"7062eea3-a57a-4eb3-89f1-60209f9ed518","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-1200,-460],"parameters":{"color":6,"width":2540,"height":460,"content":"## ✳️  RSS Feed-Based Monitoring\n"},"typeVersion":1},{"id":"03543938-705f-4ac9-9324-3316e1fa75f1","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1200,160],"parameters":{"color":4,"width":2560,"height":460,"content":"## 🔎 Direct Webpage Monitoring"},"typeVersion":1},{"id":"13f31425-21fd-4485-b40b-1bccbb18db6b","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-1140,440],"parameters":{"width":170,"height":140,"content":"## ⬆️  Provide your vendor URLs here"},"typeVersion":1},{"id":"1f0d93fa-8ba9-4389-abca-5ea4f75ecbec","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-1140,-160],"parameters":{"width":170,"height":140,"content":"## ⬆️  Provide your vendor URLs here"},"typeVersion":1},{"id":"e210deb2-b084-4bd9-8355-6c1b1bb85fd9","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[980,-160],"parameters":{"width":150,"height":80,"content":"## 📧 Add your email"},"typeVersion":1},{"id":"3ce9e429-f52e-49e1-aaa4-d9c4e59a4469","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[1160,440],"parameters":{"width":150,"height":80,"content":"## 📧 Add your email"},"typeVersion":1},{"id":"e6c24c42-8c67-4d2d-93e2-e7f7a7bfce4f","name":"Splitting the Urls","type":"n8n-nodes-base.splitOut","notes":"🔀 Split array of vendor URLs to process them individually.","position":[-920,260],"parameters":{"options":{},"fieldToSplitOut":"feedUrl"},"notesInFlow":true,"typeVersion":1},{"id":"0d873aa3-baa9-4632-b489-bf439ed7d897","name":"Check the headers","type":"n8n-nodes-base.if","notes":"🕵️‍♂️ Checks vendor page headers for signs of recent updates (last modified).","position":[-480,260],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"3cc0b4e8-e015-44fc-8118-ec7ec79dc2de","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{    Object.entries($json.headers).some(([key, val]) =>     /update|modified/i.test(key) &&     !isNaN(Date.parse(val)) &&     Date.parse(val) >= Date.now() - 24*60*60*1000   ) }}","rightValue":""}]}},"notesInFlow":true,"typeVersion":2.2},{"id":"059afda6-dc5f-457f-bdec-f6acd7feb161","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-2700,-880],"parameters":{"width":800,"height":1840,"content":"## 🛡️ AI-Powered Vendor Policy & RSS Feed Analysis with Integrated Risk Scoring\n\nThis workflow automates monitoring, analyzing, and scoring vendor-related updates using RSS feeds and direct web scraping. It leverages AI agents to produce actionable, risk-YOUR_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE_OPENAI_KEY_HERE summaries delivered via email in a clean, styled HTML format.\n\n### 🚀 Features\n- 📥 **Pulls updates** from RSS feeds and vendor policy pages  \n- 🤖 **Uses AI agents** to analyze and assign risk ratings (High, Medium, Low, Informational)  \n- 🧹 **Extracts and cleans** web content for LLM processing  \n- 🕵️ **Filters changes** within last 24 hours using headers, body text, and AI-based date detection  \n- 💌 **Sends separate HTML email digests** for RSS and webpage-based insights  \n\n### 🧱 Workflow Modules\n\n#### 📡 RSS Feed Monitoring\n- 🔗 Reads vendor feed URLs  \n- ⏳ Filters posts from the last 24 hours  \n- 🧠 Sends entries to AI agent for risk assessment and summarization  \n\n#### 🌐 Webpage Monitoring\n- 🔍 Scrapes vendor policy URLs  \n- 📅 Extracts update dates using:\n  - 🧾 *Last-Modified headers*\n  - 🧠 *HTML body scan* for keywords like “updated” or “modified”\n- ✍️ Uses AI to extract, summarize, and categorize risk content  \n\n#### 🧾 Output\n- 🗂️ Formats summaries by risk level  \n- 📧 Sends HTML digest emails to designated recipients  \n\n---\n\n### 🧪 Use Case Scenarios\n\n#### ✅ Use Case 1: RSS Feed-Based Risk Categorization\n\n**Scenario:**  \nYour organization subscribes to cybersecurity and compliance blogs like TechCrunch or Smashing Magazine. You want to identify which new updates might indicate High or Medium vendor risk.\n\n**Workflow Behavior:**\n- 🗞️ Filters feed articles from the last 24 hours  \n- 🧠 AI assigns risk level and summarizes content  \n- 📬 Email shows grouped insights (🔴 High, 🟠 Medium, etc.)\n\n**Example Output:**\n\n🔴 **High Risk**  \n**Vendor:** Vendor name  \n**Title:** “Zero-Day Vulnerability in XYZ”  \n**Summary:** A critical zero-day was reported affecting vendor systems. Immediate patching is required.  \n👉 *Read more*\n\n---\n\n#### ✅ Use Case 2: Vendor Policy Page Monitoring\n\n**Scenario:**  \nYou need to track privacy or terms-of-service pages for subtle but important changes.\n\n**Workflow Behavior:**\n- 🌐 Scrapes specified vendor URLs (e.g., Privacy Policy)  \n- 📅 Extracts “Last Modified” date or infers updates via HTML content  \n- 🤖 AI summarizes the change and assesses risk  \n\n**Example Output:**\n\n🟠 **Medium Risk**  \n**Vendor:** Vendor name  \n**Title:** “Privacy Policy Updated”  \n**Summary:** The vendor added new clauses around third-party data sharing. Legal review recommended.  \n👉 *Read more*\n"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"d815af19-e2bb-4f3a-b954-c10b47d98347","connections":{"Merge":{"main":[[{"node":"Cleaning up the code","type":"main","index":0}]]},"AI Agent":{"main":[[{"node":"Formatting the Content for Mail","type":"main","index":0}]]},"AI Agent1":{"main":[[{"node":"Format the Summary for Email","type":"main","index":0}]]},"Vendor URLs":{"main":[[{"node":"Splitting the Urls","type":"main","index":0}]]},"HTTP Request":{"main":[[{"node":"Check the headers","type":"main","index":0}]]},"Daily Trigger":{"main":[[{"node":"Vendor URLs","type":"main","index":0},{"node":"RSS Feed List","type":"main","index":0}]]},"RSS Feed List":{"main":[[{"node":"Splitting the Feeds","type":"main","index":0}]]},"Sort the feeds":{"main":[[{"node":"Merge the content for AI","type":"main","index":0}]]},"Check the headers":{"main":[[{"node":"Merge","type":"main","index":0}],[{"node":"Scrapping inside the Webpage content","type":"main","index":0}]]},"Splitting the Urls":{"main":[[{"node":"HTTP Request","type":"main","index":0}]]},"Splitting the Feeds":{"main":[[{"node":"Vendor RSS Feed Read","type":"main","index":0}]]},"Cleaning up the code":{"main":[[{"node":"AI Agent1","type":"main","index":0}]]},"Vendor RSS Feed Read":{"main":[[{"node":"Filtering last 24hrs feed","type":"main","index":0}]]},"Google Gemini Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Merge the content for AI":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Filtering last 24hrs feed":{"main":[[{"node":"Sort the feeds","type":"main","index":0}]]},"Google Gemini Chat Model1":{"ai_languageModel":[[{"node":"AI Agent1","type":"ai_languageModel","index":0}]]},"Format the Summary for Email":{"main":[[{"node":"Gmail","type":"main","index":0}]]},"Formatting the Content for Mail":{"main":[[{"node":"Gmail1","type":"main","index":0}]]},"Scrapping inside the Webpage content":{"main":[[{"node":"Merge","type":"main","index":1}]]}}}


name: Automatically Post Latest Reddit Content to Discord with Image Extraction
author_name: ikbendion
author_username: ikbendion
nodes_used: ["n8n-nodes-base.discord","n8n-nodes-base.reddit","n8n-nodes-base.code"]
categories: []
created_at: 2025-06-21T14:59:26.292Z
updated_at: 2025-06-21T14:59:26.292Z
url: https://n8n.io/workflows/5105
scraped_at: 2025-07-06 21:16:30
description:
  Reddit Poster to Discord
  This workflow checks Reddit every 15 minutes for new posts and sends selected posts to a Discord channel via webhook.

  Flow Overview:
  Schedule Trigger
  Runs every 15 minutes.

  Fetch Latest Posts
  Retrieves up to 3 new posts from any subreddit.

  Filter Posts
  Skips moderator or announcement posts based on author ID.

  Fetch Full Post Data
  Gets full details for the remaining post.

  Extract Image URL
  Parses the post to extract a direct image link.

  Send to Discord
  Sends the post title, image, and link to a Discord webhook.

  Setup Notes:
  Create a Reddit app and connect credentials in n8n.

  Add your subreddit name to both Reddit nodes.

  Connect a Discord webhook for posting.

workflow_json:
  {"id":"pQsIsuD3FqbyPYgJ","meta":{"instanceId":"f5447aacc75878ec23c68728277d69b42b8a47397d6598c62610dabdfff5c5f1","templateCredsSetupCompleted":true},"name":"Reddit Poster to Discord","tags":[],"nodes":[{"id":"93d15b82-9ce5-4189-8913-1f29bea05a23","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[-140,-40],"parameters":{"rule":{"interval":[{"field":"minutes","minutesInterval":15}]}},"typeVersion":1.2},{"id":"4bd7becf-e6cc-4975-a098-441accc2d24b","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[120,-200],"parameters":{"width":600,"height":440,"content":"## Fetch and filter reddit posts\n- Fetches latest post from a subreddit, filters out aome postIDs from mod posts.\n- Add another one if nessecary"},"typeVersion":1},{"id":"2602f8be-c1c3-4403-9b61-714bbfe517e7","name":"Fetch latest reddit posts","type":"n8n-nodes-base.reddit","position":[220,-40],"parameters":{"limit":3,"filters":{},"operation":"getAll","subreddit":"news"},"credentials":{"redditOAuth2Api":{"id":"sdadadsaddasd","name":"Stream8"}},"typeVersion":1},{"id":"1c24ec32-b231-4139-967d-677dad046ac6","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[740,-200],"parameters":{"color":7,"width":560,"height":440,"content":"## Post fetching and URL extraction\n- Fetches per post data, extracts direct URL for image."},"typeVersion":1},{"id":"fc5bca77-baaa-4e68-ae8c-4c246aea43bc","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1320,-200],"parameters":{"color":3,"width":280,"height":440,"content":"## Post To platforms\n- Send Direct image + context to social media platforms"},"typeVersion":1},{"id":"38f3aa18-95db-4814-9383-801d22b66cee","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-220,-200],"parameters":{"color":5,"width":320,"height":440,"content":"## Scheduling\n- Set up the frequency of time to check for new posts\n"},"typeVersion":1},{"id":"2331d25e-9468-4787-871f-8692ff0b8546","name":"Filter out announcement posts","type":"n8n-nodes-base.if","position":[440,-40],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"7e7d515c-16f4-4fe7-9636-8282f53ac104","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.author_fullname }}","rightValue":"t2_6l4z3"}]}},"typeVersion":2.2},{"id":"a8126cca-1674-478a-878a-a69d1d002959","name":"Fetch Reddit Post","type":"n8n-nodes-base.reddit","position":[800,-40],"parameters":{"postId":"={{ $('Filter out announcement posts').item.json.id }}","operation":"get","subreddit":"news"},"credentials":{"redditOAuth2Api":{"id":"oz2vVkjLl9rNadasdadNB","name":"Stream8"}},"typeVersion":1},{"id":"85e63030-ed64-4f82-a2a5-c4aeecbb4679","name":"Extract Image URL","type":"n8n-nodes-base.code","position":[1100,-40],"parameters":{"jsCode":"return items.map(item => {\n  const mediaMetadata = item.json.media_metadata;\n  if (!mediaMetadata) return { directUrl: null };\n  \n  const mediaKey = Object.keys(mediaMetadata)[0];\n  const media = mediaMetadata[mediaKey];\n  if (!media || !media.s || !media.s.u) return { directUrl: null };\n\n  let url = media.s.u.replace(/&amp;/g, '&');\n  \n  const match = url.match(/([a-z0-9]+)\\.(jpg|png|gif)/i);\n  if (!match) return { directUrl: null };\n  \n  const imageName = match[1];\n  const extension = match[2];\n  \n  const directUrl = `https://i.redd.it/${imageName}.${extension}`;\n  \n  return { directUrl };\n});\n"},"typeVersion":2},{"id":"c11ecaf3-9f82-47cd-bc86-0a17b1c869db","name":"Send to discord","type":"n8n-nodes-base.discord","position":[1420,-40],"webhookId":"0b28872f-2769-4474-a1bc-0a95228cd934","parameters":{"content":"=New post on reddit:\n{{ $('Fetch Reddit Post').item.json.title }}\n{{ $json.directUrl }}\n{{ $('Filter out announcement posts').item.json.url_overridden_by_dest }}","options":{},"authentication":"webhook"},"credentials":{"discordWebhookApi":{"id":"sdadsadadadada","name":"Debug"}},"typeVersion":2},{"id":"63672e8c-1ebc-44ca-845c-2a17ad0acc40","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-220,-380],"parameters":{"color":6,"width":940,"content":"## SETUP\n- Set up a reddit account including reddit app, copy client/id secret.\n- Configure redirect URL as n8n base url.\n- Configure subreddit in both reddit nodes.\n- Add a webhook to discord."},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"1909d356-13e9-4045-8aed-8c640c93fe39","connections":{"Schedule Trigger":{"main":[[{"node":"Fetch latest reddit posts","type":"main","index":0}]]},"Extract Image URL":{"main":[[{"node":"Send to discord","type":"main","index":0}]]},"Fetch Reddit Post":{"main":[[{"node":"Extract Image URL","type":"main","index":0}]]},"Fetch latest reddit posts":{"main":[[{"node":"Filter out announcement posts","type":"main","index":0}]]},"Filter out announcement posts":{"main":[[],[{"node":"Fetch Reddit Post","type":"main","index":0}]]}}}


name: SEO On-site Audit
author_name: Jacob
author_username: jacobgad
categories: []
created_at: 2025-06-21T16:39:34.273Z
updated_at: 2025-06-21T16:39:34.273Z
url: https://n8n.io/workflows/5106
scraped_at: 2025-07-06 21:16:30
description:
  Automated SEO Audit in n8n – Your All-in-One Website Optimization Tool!

  Looking for a powerful, fully automated solution to analyze your website’s SEO? Our custom n8n workflow is designed just for you!

  What does this workflow do?
  Our advanced SEO audit collects all the essential data that impact your site’s search engine rankings, including:

  Analysis of meta tags (title, description) with actionable optimization recommendations

  Verification of H1 and H2 headings, presented in clear, organized tables

  Checking internal, external, and broken links for full link health insights

  Detection of key technical files: robots.txt and sitemap.xml

  Identification of Google Analytics and social media links implementation

  Evaluation of URL friendliness and mobile responsiveness

  SSL certificate and noindex meta tag presence checks

  Integration with Google PageSpeed API for website speed and performance metrics

  DeepSeek API support for in-depth content and keyword analysis

  Generation of clean, user-friendly HTML reports ready to share with clients or teams

  Why choose this workflow?
  Easy integration – just connect your Google PageSpeed and DeepSeek API keys, and the workflow automatically gathers and analyzes all data.

  Fully automated – run the workflow and get a comprehensive SEO report with zero manual work.

  Scalable – audit single pages or entire website portfolios effortlessly.

  Customizable – pre-built functions and templates ready for extension or integration with your systems.

  Professional HTML report – visually appealing and packed with actionable insights for your team or clients.

  How to get started?
  Set up your Google PageSpeed and DeepSeek API keys.

  Connect them within n8n – no extra steps needed!

  Run the workflow and receive a detailed SEO audit report that will help you improve rankings and boost traffic.

  Automate your SEO audits with n8n – faster, easier, and more effective than ever before!

  If you want, I can also prepare a shorter marketing snippet or social media posts. Just let me know: jacobmarketingservice@gmail.com

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

workflow_json:
  {"id":"5hGK8AtGnDY7uwZK","meta":{"instanceId":"cd438fd1eca1b4215129611b59e2a783bbecd4a7fc04e24e9ac21de3d46ce6cc","templateCredsSetupCompleted":true},"name":"SEO Audit","tags":[],"nodes":[{"id":"f8927c6f-dfe9-4f07-a3cf-8096a25c9b31","name":"Webhook","type":"n8n-nodes-base.webhook","position":[-200,320],"webhookId":"a04dff47-cef4-4e69-8f8b-d832ee33e26b","parameters":{},"typeVersion":1},{"id":"65c73183-c68e-4b17-85d3-db2339069154","name":"HTTP Request - Get Page","type":"n8n-nodes-base.httpRequest","position":[380,320],"parameters":{},"typeVersion":1},{"id":"a55e0a44-cdd7-4295-8229-6e6b968e700b","name":"HTML Extract","type":"n8n-nodes-base.htmlExtract","position":[540,320],"parameters":{},"typeVersion":1,"alwaysOutputData":false},{"id":"35d30004-9859-4d9e-8a88-a9c3de88ac58","name":"PageSpeed API","type":"n8n-nodes-base.httpRequest","position":[760,1100],"parameters":{},"typeVersion":1},{"id":"6c9a1496-80f2-484c-a735-36fde73cb695","name":"Send Email","type":"n8n-nodes-base.emailSend","position":[2340,320],"parameters":{},"typeVersion":1},{"id":"f5416c60-7053-4d76-8ad4-ebb9d6768196","name":"Generate HTML REPORT","type":"n8n-nodes-base.html","position":[2100,320],"parameters":{},"typeVersion":1.2},{"id":"7a6f39cc-1478-41c9-934a-f667f2a05c72","name":"FUnctions to report","type":"n8n-nodes-base.code","position":[1860,320],"parameters":{},"typeVersion":2},{"id":"5ee2b5c8-6b5c-4888-9483-51638c64b808","name":"Check Image","type":"n8n-nodes-base.code","position":[760,420],"parameters":{},"typeVersion":2},{"id":"fac001d4-75b6-4973-b323-79804ce39775","name":"Links","type":"n8n-nodes-base.code","position":[760,100],"parameters":{},"retryOnFail":false,"typeVersion":2,"alwaysOutputData":false},{"id":"a289e805-e403-4dae-a4bc-5e9732f6f5ed","name":"DeepSeek Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatDeepSeek","position":[880,500],"parameters":{},"typeVersion":1},{"id":"80463d6f-b336-4501-a668-59d716c381b4","name":"Title Analysis","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[980,-220],"parameters":{},"typeVersion":1.7},{"id":"7bfac124-951a-465b-9500-e70e54e7f5f3","name":"Description Analysis","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[980,-60],"parameters":{},"typeVersion":1.7},{"id":"87220a68-c5a2-44b5-ae57-df8e82f29411","name":"Title","type":"n8n-nodes-base.code","position":[760,-220],"parameters":{},"typeVersion":2},{"id":"85506ef5-16fb-4534-884d-66607fcb3ad9","name":"Description","type":"n8n-nodes-base.code","position":[760,-60],"parameters":{},"typeVersion":2,"alwaysOutputData":false},{"id":"eea293a2-ed3c-404d-97bd-74a06fb7b031","name":"Alts Analysis","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[980,420],"parameters":{},"typeVersion":1.7},{"id":"24100f61-7e8b-4cc7-a03e-d29d9583e6a6","name":"Density Analysis","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[980,260],"parameters":{},"typeVersion":1.7},{"id":"f774850c-ef86-4755-9bfb-9971ba188893","name":"Keyword Density","type":"n8n-nodes-base.code","position":[760,260],"parameters":{},"typeVersion":2},{"id":"c5118540-2d6e-4c89-a40e-84dd3dc7dbb2","name":"Content Analysis","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[980,100],"parameters":{},"typeVersion":1.7},{"id":"9d707223-f77a-4c9f-9bc8-1acce061004a","name":"Domain","type":"n8n-nodes-base.code","position":[420,760],"parameters":{},"typeVersion":2},{"id":"103435c7-2d14-4363-bfb8-5a73c6d46d0e","name":"Robots.txt","type":"n8n-nodes-base.httpRequest","position":[580,760],"parameters":{},"typeVersion":4.2},{"id":"a28dc3af-7b67-428e-b274-1034b615c07f","name":"Code Analysis","type":"n8n-nodes-base.code","position":[760,600],"parameters":{},"typeVersion":2},{"id":"98d22fce-2280-4e94-b6f6-0731ab040034","name":"Sitemap","type":"n8n-nodes-base.httpRequest","position":[580,940],"parameters":{},"typeVersion":4.2},{"id":"e5e4e812-40d2-4931-a798-2bfcfd3fa14f","name":"Robots Analysis","type":"n8n-nodes-base.code","position":[760,760],"parameters":{},"typeVersion":2},{"id":"567a8e4a-ae16-49c5-9be5-21c63fb845f3","name":"Code","type":"n8n-nodes-base.code","position":[760,940],"parameters":{},"typeVersion":2},{"id":"b4820ce3-c72b-4237-9ec1-f0d46540484b","name":"Merge","type":"n8n-nodes-base.merge","position":[1560,160],"parameters":{},"typeVersion":3.2}],"active":true,"settings":{"executionOrder":"v1"},"versionId":"5d502a59-2716-4174-807d-835f2d034b01","connections":{"Code":{"main":[[{"node":"Merge","type":"main","index":8}]]},"Links":{"main":[[{"node":"Merge","type":"main","index":0}]]},"Merge":{"main":[[{"node":"FUnctions to report","type":"main","index":0}]]},"Title":{"main":[[{"node":"Title Analysis","type":"main","index":0}]]},"Domain":{"main":[[{"node":"Robots.txt","type":"main","index":0},{"node":"Sitemap","type":"main","index":0}]]},"Sitemap":{"main":[[{"node":"Code","type":"main","index":0}]]},"Webhook":{"main":[[{"node":"HTTP Request - Get Page","type":"main","index":0},{"node":"Domain","type":"main","index":0},{"node":"PageSpeed API","type":"main","index":0}]]},"Robots.txt":{"main":[[{"node":"Robots Analysis","type":"main","index":0}]]},"Send Email":{"main":[[]]},"Check Image":{"main":[[{"node":"Alts Analysis","type":"main","index":0}]]},"Description":{"main":[[{"node":"Description Analysis","type":"main","index":0}]]},"HTML Extract":{"main":[[{"node":"Keyword Density","type":"main","index":0},{"node":"Links","type":"main","index":0},{"node":"Check Image","type":"main","index":0},{"node":"Title","type":"main","index":0},{"node":"Description","type":"main","index":0},{"node":"Content Analysis","type":"main","index":0}]]},"Alts Analysis":{"main":[[{"node":"Merge","type":"main","index":5}]]},"Code Analysis":{"main":[[{"node":"Merge","type":"main","index":6}]]},"PageSpeed API":{"main":[[{"node":"Merge","type":"main","index":9}]]},"Title Analysis":{"main":[[{"node":"Merge","type":"main","index":1}]]},"Keyword Density":{"main":[[{"node":"Density Analysis","type":"main","index":0}]]},"Robots Analysis":{"main":[[{"node":"Merge","type":"main","index":7}]]},"Content Analysis":{"main":[[{"node":"Merge","type":"main","index":3}]]},"Density Analysis":{"main":[[{"node":"Merge","type":"main","index":4}]]},"DeepSeek Chat Model":{"ai_languageModel":[[{"node":"Title Analysis","type":"ai_languageModel","index":0},{"node":"Description Analysis","type":"ai_languageModel","index":0},{"node":"Density Analysis","type":"ai_languageModel","index":0},{"node":"Alts Analysis","type":"ai_languageModel","index":0},{"node":"Content Analysis","type":"ai_languageModel","index":0}]]},"FUnctions to report":{"main":[[{"node":"Generate HTML REPORT","type":"main","index":0}]]},"Description Analysis":{"main":[[{"node":"Merge","type":"main","index":2}]]},"Generate HTML REPORT":{"main":[[{"node":"Send Email","type":"main","index":0}]]},"HTTP Request - Get Page":{"main":[[{"node":"HTML Extract","type":"main","index":0},{"node":"Code Analysis","type":"main","index":0}]]}}}


name: Auto-Generate Problem-Focused Blog Posts for Shopify Products with AI
author_name: Khairul Muhtadin
author_username: khmuhtadin
categories: []
created_at: 2025-06-21T16:51:32.577Z
updated_at: 2025-06-21T16:51:32.577Z
url: https://n8n.io/workflows/5107
scraped_at: 2025-07-06 21:16:30
description:
  This workflow contains community nodes that are only compatible with the self-hosted version of n8n. 

  AI Blog Automation for Shopify is a n8n workflow that automatically transforms your Shopify products into engaging, problem-focused blog posts.

  Say goodbye to spending 5+ hours per article – this workflow generates SEO-optimized content that addresses customer pain points, not just product features.



  🎯 Who is this for?
  E-commerce store owners** wanting consistent content marketing without the time investment.
  Dropshipping entrepreneurs** with frequent product launches needing automated blog content.
  Shopify merchants** who know blogging drives traffic but lack writing resources.
  Content marketers** seeking scalable, cost-effective blog automation.

  🚨 Problem Solved
  Creating quality blog content is time-consuming and expensive. Most store owners either skip blogging entirely or burn out after a few posts. This workflow solves it by:
  Automatically generating problem-first content (not salesy product descriptions).
  Creating stunning AI-generated hero images for each post.
  Publishing directly to your Shopify blog with proper SEO formatting.
  Costing only $0.05-0.15 per post vs. $200+ for professional writers.

  ⚙️ What This Workflow Does

  | Feature | Description |
  |---------|-------------|
  | Triggers | - Manual execution for existing products- Automatic trigger when new products are created |
  | Analyzes Products | Uses LangChain + OpenAI to:- Identify core problems the product solves- Analyze customer pain points- Generate problem-focused angles |
  | Creates Content | GPT-4o-mini generates 1000-1500 word articles:- Problem-first approach (not product-first)- SEO-optimized structure- Natural product integration- Soft call-to-actions |
  | Generates Images | DALL-E 3 creates blog hero images:- Matches blog theme (not just product)- Brand-consistent styling- Mobile-optimized dimensions |
  | Hosts Images | Uploads to ImgBB (free CDN):- No expiration- Fast global delivery- Direct URL integration |
  | Publishes | Posts directly to Shopify blog:- Proper HTML formatting- SEO meta descriptions- Relevant tags- Mobile-responsive images |

  🚀 Setup Instructions

  🔐 Credentials Needed
  Shopify Access Token API** (with read_products, write_content, read_content scopes)
  OpenAI API** (for content + image generation)
  ImgBB API** (free image hosting)

  🔧 Shopify Configuration
  Create private app in Shopify admin
  Enable required API scopes:
    read_products - Read product data
    write_content - Create blog posts  
    read_content - Access blog configuration
  Copy access token (starts with shpat_)

  🧩 Node Setup
  Manual Trigger** — For on-demand execution
  Shopify Trigger** — Auto-runs on product creation
  Shopify Node** — Fetches product data
  LangChain + OpenAI** — Generates problem-focused content
  Structured Output Parser** — Formats AI response
  HTTP Request** — Retrieves blog configuration
  DALL-E Node** — Creates hero images
  ImgBB Upload** — Hosts images on free CDN
  GraphQL Mutation** — Publishes to Shopify blog

  🛠️ Customization Tips

  | Feature | How to Customize |
  |---------|------------------|
  | Content Length | Adjust word count in AI Content Generator prompt |
  | Image Style | Modify DALL-E prompt for brand colors/aesthetics |
  | Author Name | Change author field in Publish Blog Article node |
  | Blog Selection | Update blog ID to target specific Shopify blog |
  | Publishing | Set isPublished: false to save as drafts |
  | Brand Voice | Customize tone and style in content prompts |

  📦 Pre-Requirements
  n8n Instance** (Cloud/Self-hosted)
  Install: @n8n/n8n-nodes-langchain
  Shopify private app** with proper scopes
  OpenAI account** with billing enabled
  ImgBB account** (free)

  🔧 Nodes Used
  Manual Trigger
  Shopify Trigger
  Shopify
  LangChain LLM
  OpenAI Chat Model
  Structured Output Parser
  HTTP Request
  OpenAI (DALL-E)
  Wait

  ✅ Test the Workflow
  Import workflow and configure all credentials.
  Update store URLs and API tokens.
  Run manually or add a new product to trigger automatically.
  Check your Shopify blog for the new problem-focused post!

  💰 Expected Results
  Time Saved**: 5+ hours per blog post
  Cost**: $0.10-0.20 per post (vs. $200+ for writers)
  Traffic**: 40-60% increase within 3 months (typical)
  Content Quality**: Problem-focused, not salesy
  Made by: Khaisa Studio
  Tags: shopify, blog, automation, ai, content-marketing, seo
  Category: E-commerce Automation, Content Marketing
  Need customization? contact me on LinkedIn or web

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

workflow_json:
  {"id":"rVCbug44PE4NbGEu","meta":{"instanceId":"c2650793f644091dc80fb900fe63448ad1f4b774008de9608064d67294f8307c","templateCredsSetupCompleted":true},"name":"n8n (AI-Powered Shopify Blog Automation)","tags":[],"nodes":[{"id":"a4c17ff5-ef96-48e8-9198-d578fd0aead6","name":"Start","type":"n8n-nodes-base.manualTrigger","position":[-460,-560],"parameters":{},"typeVersion":1},{"id":"039a3952-342f-48d9-b5c5-6cc167bfc7ee","name":"Publish Blog Article","type":"n8n-nodes-base.httpRequest","position":[1300,-360],"parameters":{},"typeVersion":4.2},{"id":"36a57759-3595-42d2-9ae4-c00195a065e9","name":"Processing Delay","type":"n8n-nodes-base.wait","position":[1060,-360],"webhookId":"6a6836c7-143a-4a43-a9a6-a3298864970d","parameters":{},"typeVersion":1.1},{"id":"fea56c6a-2efb-4d62-8448-234092bab590","name":"Retrieve Blog Configuration","type":"n8n-nodes-base.httpRequest","position":[400,-360],"parameters":{},"typeVersion":4.2},{"id":"e1934dbb-ad5b-43c9-b9b2-8305fbbad9d1","name":"Upload to Image Host","type":"n8n-nodes-base.httpRequest","position":[820,-360],"parameters":{},"typeVersion":4.2},{"id":"a8fed918-a3b7-4dc1-bfb4-481ec2588282","name":"AI Content Generator","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[20,-360],"parameters":{},"typeVersion":1.7},{"id":"f26fb1c2-4f62-4769-aee0-aca2f33afbcf","name":"Fetch Product Data","type":"n8n-nodes-base.shopify","position":[-160,-360],"parameters":{},"typeVersion":1},{"id":"864cffa4-cc18-4659-844b-2e6e8afd7cb1","name":"OpenAI","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[20,-200],"parameters":{},"typeVersion":1.2},{"id":"585798c8-2ae7-4c79-b915-e4e0fb72c1e4","name":"Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[180,-200],"parameters":{},"typeVersion":1.3},{"id":"1801538d-2175-443f-8d90-2903ca3d6554","name":"On Product Created","type":"n8n-nodes-base.shopifyTrigger","position":[-460,-360],"webhookId":"7d1e4f1e-73e4-4138-a460-de4d0f01a94c","parameters":{},"typeVersion":1},{"id":"db48c417-2c01-4f1f-b84f-46023d3853b9","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1320,-700],"parameters":{"content":""},"typeVersion":1},{"id":"9cfa48a3-2a44-422c-a6a3-fb625a2b5446","name":"AI Image Generator","type":"@n8n/n8n-nodes-langchain.openAi","position":[600,-360],"parameters":{},"typeVersion":1.8},{"id":"e6d82c54-5ff6-47b6-b0dc-2d47ae56979f","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-740,20],"parameters":{"content":""},"typeVersion":1},{"id":"3da060cb-64b3-47e7-87ff-1e2d1597890e","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-260,20],"parameters":{"content":""},"typeVersion":1},{"id":"9c03d91c-8bca-4c4a-815c-4c5fd795c66c","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[220,20],"parameters":{"content":""},"typeVersion":1},{"id":"17049232-4a30-482b-9d0c-2529f1d0e82e","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[700,20],"parameters":{"content":""},"typeVersion":1},{"id":"17425395-954f-43d6-ae9a-cef1e7d22f1d","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[1200,20],"parameters":{"content":""},"typeVersion":1},{"id":"206ea900-2d8e-44eb-8e37-e9277fc39f08","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[1880,-700],"parameters":{"content":""},"typeVersion":1},{"id":"56eeeb01-0401-4710-9770-6e43c1aa0353","name":"Notify: Published","type":"n8n-nodes-base.slack","disabled":true,"position":[1520,-360],"webhookId":"0dbe71e3-d113-4e62-bcd7-506fc149f6a2","parameters":{},"typeVersion":2.3},{"id":"917a43dc-b6e6-489c-9d30-7b4c1d6fc4f0","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[-740,-700],"parameters":{"content":""},"typeVersion":1},{"id":"d796b874-c2bf-4f40-89a9-45df036c6b93","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[140,180],"parameters":{"content":""},"typeVersion":1},{"id":"c175d406-3413-4845-b6c1-fbbd7c4bca35","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[120,-520],"parameters":{"content":""},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"48016090-d565-4327-ac34-8e27233acb7d","connections":{"Start":{"main":[[{"node":"Fetch Product Data","type":"main","index":0}]]},"OpenAI":{"ai_languageModel":[[{"node":"AI Content Generator","type":"ai_languageModel","index":0}]]},"Output Parser":{"ai_outputParser":[[{"node":"AI Content Generator","type":"ai_outputParser","index":0}]]},"Processing Delay":{"main":[[{"node":"Publish Blog Article","type":"main","index":0}]]},"AI Image Generator":{"main":[[{"node":"Upload to Image Host","type":"main","index":0}]]},"Fetch Product Data":{"main":[[{"node":"AI Content Generator","type":"main","index":0}]]},"On Product Created":{"main":[[{"node":"Fetch Product Data","type":"main","index":0}]]},"AI Content Generator":{"main":[[{"node":"Retrieve Blog Configuration","type":"main","index":0}]]},"Publish Blog Article":{"main":[[{"node":"Notify: Published","type":"main","index":0}]]},"Upload to Image Host":{"main":[[{"node":"Processing Delay","type":"main","index":0}]]},"Retrieve Blog Configuration":{"main":[[{"node":"AI Image Generator","type":"main","index":0}]]}}}


name: Forex, Crypto, Mergers and Financial Markets AI Analyst Updates to Telegram
author_name: Malik Hashir
author_username: malikx
nodes_used: ["n8n-nodes-base.httpRequest","n8n-nodes-base.telegram","n8n-nodes-base.code"]
categories: []
created_at: 2025-06-21T20:31:17.703Z
updated_at: 2025-06-21T20:31:17.703Z
url: https://n8n.io/workflows/5109
scraped_at: 2025-07-06 21:16:30
description:
  Purpose & Audience:
  This workflow is designed for active traders, financial analysts, and market enthusiasts who want to stay informed about high-impact market news without information overload. It targets users interested in Forex, Crypto, Mergers, and general market-moving geopolitical news delivered directly to their Telegram channels or personal chats.

  What It Does:
  The workflow fetches the latest market news from Finnhub’s API filtered by categories like forex, crypto, mergers, and general financial news. It then formats the news into clear, concise Telegram messages and sends updates on a schedule you choose — every hour, every 4 hours, or daily. This keeps traders focused on relevant, actionable news and avoids clutter from irrelevant updates.

  How to Set Up:
  Sign up for a free account at Finnhub.io and obtain your API key.
  Create a Telegram bot (using @botfather and get api key) and get your chat ID for the group or personal chat where you want to receive updates.
  Import this workflow into your n8n instance.
  Enter your Finnhub API key (copy from finhubb) and connect Telegram (using telegram bot api key) in their respective  nodes. Step by step guide is included in the sticky notes.
  Configure the schedule trigger node to run at your preferred interval (hourly, 4-hourly, or daily).
  Activate the workflow and start receiving curated market news updates on Telegram.

  Why Use This Workflow:
  Simple and quick to set up (under 2 minutes).
  Filters out noise, delivering only high-impact market news.
  Keeps traders informed without distraction.
  Fully customizable schedule to fit your trading routine.
  Leverages reliable Finnhub data and Telegram’s instant messaging.

workflow_json:
  {"meta":{"instanceId":"d04643ba872bb0fb252ed2c8197858d58cc47dd3c15ff6d08b19addd679e927b","templateCredsSetupCompleted":true},"nodes":[{"id":"fd6a2a46-e854-492a-8f09-79cced64e271","name":"Set API Key for Finhubb","type":"n8n-nodes-base.set","position":[-180,-220],"parameters":{},"typeVersion":3.4},{"id":"c4e1d782-fa58-4a52-b5ee-88391bf2de5b","name":"Get Latest News","type":"n8n-nodes-base.httpRequest","position":[320,-160],"parameters":{},"typeVersion":4.2},{"id":"38f9545e-6e18-4abd-a9cc-be356e1d799d","name":"Code","type":"n8n-nodes-base.code","position":[900,-200],"parameters":{},"typeVersion":2},{"id":"6991e8e2-a34e-4d79-b644-8cb973fa24a9","name":"Schedule Trigger - Every 4 Hours","type":"n8n-nodes-base.scheduleTrigger","position":[-680,-220],"parameters":{},"typeVersion":1.2},{"id":"8bfb9458-7980-4529-8951-9dc4d90e5b9f","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-840,-480],"parameters":{"content":""},"typeVersion":1},{"id":"74f5d37e-7561-41fb-ba2c-db7b0f70f019","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-340,-440],"parameters":{"content":""},"typeVersion":1},{"id":"bf289fe8-f141-46ed-b319-ccc814e7710d","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[180,-500],"parameters":{"content":""},"typeVersion":1},{"id":"45a6d72c-365c-40ba-a8ef-853097ff753a","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1080,-580],"parameters":{"content":""},"typeVersion":1},{"id":"a09b3f82-7ffd-4b27-9a7b-2ba1cb6187d4","name":"Download Image (optional)","type":"n8n-nodes-base.httpRequest","position":[680,-200],"parameters":{},"typeVersion":4.2},{"id":"97db9cda-6959-4a0f-b3d6-8b5f96bb00be","name":"Send Text Updates via Telegram","type":"n8n-nodes-base.telegram","position":[1120,-220],"webhookId":"be330673-ed11-430d-a276-a10846645163","parameters":{},"typeVersion":1.2},{"id":"229a64f2-a8c8-4e23-98d0-09078e8f99a6","name":"Send Image (with text update) - Optional","type":"n8n-nodes-base.telegram","position":[1340,-220],"webhookId":"05d07797-6597-4967-995b-014b6f5e16d3","parameters":{},"typeVersion":1.2},{"id":"b9b3bf08-17a6-4f14-92ef-d176e8e454ab","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[1560,-580],"parameters":{"content":""},"typeVersion":1}],"connections":{"Code":{"main":[[{"node":"Send Text Updates via Telegram","type":"main","index":0}]]},"Get Latest News":{"main":[[{"node":"Download Image (optional)","type":"main","index":0}]]},"Set API Key for Finhubb":{"main":[[{"node":"Get Latest News","type":"main","index":0}]]},"Download Image (optional)":{"main":[[{"node":"Code","type":"main","index":0}]]},"Send Text Updates via Telegram":{"main":[[{"node":"Send Image (with text update) - Optional","type":"main","index":0}]]},"Schedule Trigger - Every 4 Hours":{"main":[[{"node":"Set API Key for Finhubb","type":"main","index":0}]]}}}


name: Create & Upload AI-Generated ASMR YouTube Shorts with Seedance, Fal AI, and GPT-4
author_name: Bilel Aroua
author_username: bilsimaging
categories: []
created_at: 2025-06-21T22:27:33.109Z
updated_at: 2025-06-21T22:27:33.109Z
url: https://n8n.io/workflows/5110
scraped_at: 2025-07-06 21:16:30
description:
  //ASMR AI Workflow 
  Who is this for?

  Content Creators, YouTube Automation Enthusiasts, and AI Hobbyists looking to autonomously generate and publish unique, satisfying ASMR-style YouTube Shorts without manual effort.

  What problem does this solve?

  This workflow solves the creative bottleneck and time-consuming nature of daily content creation. It fully automates the entire production pipeline, from brainstorming trendy ideas to publishing a finished video, turning your n8n instance into a 24/7 content factory.

  What this workflow does

  1. Two-Stage AI Ideation & Planning:
  Uses an initial AI agent to brainstorm a short, viral ASMR concept based on current trends.
  A second "Planning" AI agent then takes this concept and expands it into a detailed, structured production plan, complete with a viral-optimized caption, hashtags, and descriptions for the environment and sound.

  2. Multi-Modal Asset Generation:
  Video:* Feeds detailed scene prompts to the *ByteDance Seedance** text-to-video model (via Wavespeed AI) to generate high-quality video clips.
  Audio:* Simultaneously calls the *Fal AI** text-to-audio model to create custom, soothing ASMR sound effects that match the video's theme.
  Assembly:** Automatically sequences the video clips and sound into a single, cohesive final video file using an FFMPEG API call.

  3. Closed-Loop Publishing & Logging:
  Logging:** Initially logs the new idea to a Google Sheet with a status of "In Progress".
  Publishing:** Automatically uploads the final, assembled video directly to your YouTube channel, setting the title and description from the AI's plan.
  Updating:** Finds the original row in the Google Sheet and updates its status to "Done", adding a direct link to the newly published YouTube video.
  Notifications:** Sends real-time alerts to Telegram and/or Gmail with the video title and link, confirming the successful publication.

  Setup

  Credentials:
  You will need to create credentials in your n8n instance for the following services:
  OpenAI API
  Wavespeed AI API (for Seedance)
  Fal AI API
  Google OAuth Credential (enable YouTube Data API v3 and Google Sheets API in your Google Cloud Project)
  Telegram Bot Credential
  (Optional) Gmail OAuth Credential

  Configuration:
  This is an advanced workflow. The initial setup should take approximately 15-20 minutes.
  Google Sheet:* Create a Google Sheet with these columns: idea, caption, production_status, youtube_url. Add the *Sheet ID** to the Google Sheets nodes in the workflow.
  Node Configuration:** In the Telegram Notification node, enter your own Chat ID. In the Gmail Notification node, update the recipient email address.
  Activate:** Once configured, save and set the workflow to "Active" to let it run on its schedule.

  How to customize

  Creative Direction:* To change the style or theme of the videos (e.g., from kinetic sand to soap cutting), simply edit the systemMessage in the *"2. Enrich Idea into Plan"* and *"Prompts AI Agent"** nodes.

  Initial Ideas:* To influence the AI's starting concepts, modify the prompt in the *"1. Generate Trendy Idea"** node.
  Video & Sound:* To change the video duration or sound style, adjust the parameters in the *"Create Clips"* and *"Create Sounds"** nodes.
  Notifications:* Add or remove notification channels (like Slack or Discord) after the *"Upload to YouTube"** node.

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

workflow_json:
  {"id":"LPUpZtHK7gGRA5wa","meta":{"instanceId":"1d871c7857f6a0f6093c24e2cd2fa1fa755b3826859fe85548d66cefd9f0e0ed"},"name":"Automated AI YouTube Shorts Factory for ASMR (Seedance)","tags":[{"id":"1","name":"AI"},{"id":"2","name":"YouTube"},{"id":"3","name":"Content Creation"}],"nodes":[{"id":"25a59939-f6b6-4fae-8ed0-7808e008331c","name":"Unbundle Prompts","type":"n8n-nodes-base.code","position":[3060,220],"parameters":{"jsCode":"function findSceneEntries(obj) {\n  const scenes = [];\n\n  for (const [key, value] of Object.entries(obj)) {\n    if (key.toLowerCase().startsWith(\"scene\") && typeof value === \"string\") {\n      scenes.push(value);\n    } else if (typeof value === \"object\" && value !== null) {\n      scenes.push(...findSceneEntries(value));\n    }\n  }\n\n  return scenes;\n}\n\nlet output = [];\n\ntry {\n  const inputData = items[0].json;\n  const scenes = findSceneEntries(inputData);\n\n  if (scenes.length === 0) {\n    throw new Error(\"No scene keys found at any level.\");\n  }\n\n  output = scenes.map(scene => ({ description: scene }));\n} catch (e) {\n  throw new Error(\"Could not extract scenes properly. Details: \" + e.message);\n}\n\nreturn output;\n"},"typeVersion":2},{"id":"c15a3956-bf4f-446e-b14b-1304d5b37f3d","name":"Create Sounds","type":"n8n-nodes-base.httpRequest","position":[3260,440],"parameters":{"url":"https://queue.fal.run/fal-ai/mmaudio-v2 ","body":"= {\n        \"prompt\": \"ASMR Soothing sound effects. {{ $('Prompts AI Agent').item.json.output.Sound }}\",\n        \"duration\": 10,\n        \"video_url\": \"{{ $json.data.outputs[0] }}\"\n  }\n","method":"POST","options":{"batching":{"batch":{"batchSize":1,"batchInterval":2000}}},"sendBody":true,"contentType":"raw","authentication":"genericCredentialType","rawContentType":"application/json","genericAuthType":"httpHeaderAuth"},"credentials":{},"typeVersion":4.2},{"id":"d277a432-e3b3-4069-837c-6e68def03672","name":"Get Sounds","type":"n8n-nodes-base.httpRequest","position":[3780,440],"parameters":{"url":"=https://queue.fal.run/fal-ai/mmaudio-v2/requests/{{ $json.request_id }}","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{},"typeVersion":4.2},{"id":"2734cc8e-416a-41fd-a20b-40c079889907","name":"Wait for Sounds","type":"n8n-nodes-base.wait","position":[3480,440],"parameters":{"amount":60},"typeVersion":1.1},{"id":"70f2ebeb-1ef1-439c-88b5-3c6094dca6a3","name":"List Elements","type":"n8n-nodes-base.code","position":[3060,640],"parameters":{"jsCode":"return [\n  {\n    video_urls: items.map(item => item.json.video.url)\n  }\n];"},"typeVersion":2},{"id":"8892adcd-e2da-476c-998d-b814b12184e0","name":"Sequence Video","type":"n8n-nodes-base.httpRequest","position":[3260,640],"parameters":{"url":"https://queue.fal.run/fal-ai/ffmpeg-api/compose","body":"={\n  \"tracks\": [\n    {\n      \"id\": \"1\",\n      \"type\": \"video\",\n      \"keyframes\": [\n        { \"url\": \"{{ $json.video_urls[0] }}\", \"timestamp\": 0, \"duration\": 10 },\n        { \"url\": \"{{ $json.video_urls[1] }}\", \"timestamp\": 10, \"duration\": 10 },\n        { \"url\": \"{{ $json.video_urls[2] }}\", \"timestamp\": 20, \"duration\": 10 }\n      ]\n    }\n  ]\n}","method":"POST","options":{"batching":{"batch":{"batchSize":1,"batchInterval":2000}}},"sendBody":true,"contentType":"raw","authentication":"genericCredentialType","rawContentType":"application/json","genericAuthType":"httpHeaderAuth"},"credentials":{},"typeVersion":4.2},{"id":"9063eb02-8cd4-4b75-87f2-fdd59f56f26c","name":"Get Final Video","type":"n8n-nodes-base.httpRequest","position":[3780,640],"parameters":{"url":"=https://queue.fal.run/fal-ai/ffmpeg-api/requests/{{ $json.request_id }}","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{},"typeVersion":4.2},{"id":"b3c4c19c-2caa-454c-ae56-a6c00117a6d4","name":"Wait for Final Video","type":"n8n-nodes-base.wait","position":[3480,640],"parameters":{"amount":60},"typeVersion":1.1},{"id":"7edea676-00ad-4c17-8fd9-54e55e06dbc5","name":"Think","type":"@n8n/n8n-nodes-langchain.toolThink","position":[2580,520],"parameters":{},"typeVersion":1},{"id":"9d61496d-66a5-454f-b60a-6d997a4d75e8","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[2220,440],"parameters":{"model":{"__rl":true,"value":"gpt-4.1"}},"credentials":{"openAiApi":{}},"typeVersion":1.2},{"id":"da01687e-ad98-42c0-bab5-057882d6709b","name":"Prompts AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[2720,220],"parameters":{"text":"=Give me 3 video prompts based on the previous \n\nUse the Think tool to review your output","options":{"systemMessage":"=Role: You are a prompt-generation AI specializing in satisfying, ASMR-style video prompts for kinetic sand. Your task is to generate a multi-scene video sequence that vividly shows a tool (like a knife, scoop, or press) interacting with kinetic sand in a clean, high-detail setting.\n\nYour writing must follow this style:\n\nSatisfying, tactile realism.\nMacro-level detail with a tight focus on the tool interacting with the sand's unique texture.\nThe tool must always be in motion — slicing, scooping, pressing, or crumbling the sand. Never idle or static.\nCamera terms are allowed (e.g. macro view, top-down shot, slow-motion).\n\nEach scene must contain all of the following, expressed through detailed visual language:\n\n✅ The kinetic sand (from the Idea)\n✅ The environment or surface (from the Environment)\n✅ The texture, structure, and behavior of the sand as it's being manipulated\n✅ A visible tool (knife, scoop, mold) actively interacting with the sand\n\nDescriptions should show:\n\nThe physical makeup of the sand — is it layered with different colors, sparkly, smooth, or matte? Emphasize its granular, yet cohesive structure.\nHow the sand responds to the tool — clean slicing, soft crumbling, perfect imprints, satisfying deformation, or a cascading collapse.\nThe interaction between the tool and the sand — sand grains momentarily sticking to the tool, the smooth surface left behind, the crisp edges of a cut.\nAny ASMR-relevant sensory cues like the satisfying crunch, the soft hiss of falling grains, or the shimmer of glitter, but always shown visually — not narrated.\n\nTone:\n\nSatisfying, mesmerizing, tactile.\nNo poetic metaphors, emotion, or storytelling.\nAvoid fantasy or surreal imagery.\nAll description must feel physically grounded and visually appealing.\n\nLength:\n\nEach scene must be between 1,000 and 2,000 characters.\nNo shallow or repetitive scenes — each must be immersive, descriptive, and specific.\nEach scene should explore a distinct phase of the action, a different camera perspective, or a new behavior of the sand.\n\nInputs:\n\nIdea: \"{{ $json.idea }}\"\nEnvironment: \"{{ $json.environment_prompt }}\"\nSound: \"{{ $json.sound_prompt }}\"\n\nFormat:\n\nIdea: \"...\"\nEnvironment: \"...\"\nSound: \"...\"\n\nScene 1: \"...\"\nScene 2: \"...\"\nScene 3: \"...\"\n(and so on)"},"promptType":"define","hasOutputParser":true},"typeVersion":1.9},{"id":"64abf568-4e09-4e5c-bd12-7475e721a54c","name":"Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[2380,440],"parameters":{"jsonSchemaExample":"[\n  {\n    \"Caption\": \"Diver Removes Nets Off Whale 🐋 #whalerescue #marinelife #oceanrescue #seahelpers #love #nature #instagood #explore #viral #savenature #oceanguardians #cleanoceans\",\n    \"Idea\": \"Diver carefully cuts tangled net from distressed whale in open sea\",\n    \"Environment\": \"Open ocean, sunlight beams through water, diver and whale, cinematic realism\",\n    \"Sound\": \"Primary sound description under 15 words\",\n    \"Status\": \"for production\"\n  }\n]\n"},"typeVersion":1.2},{"id":"d8c29c02-f396-4150-aa2c-550d7b123f9e","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[1500,220],"parameters":{"rule":{"interval":[{"field":"minutes","minutesInterval":30}]}},"typeVersion":1.2},{"id":"f2e85826-3416-4a1e-8f26-5a8538087174","name":"Parser2","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[2900,440],"parameters":{"jsonSchemaExample":"{\n  \"Idea\": \"An obsidian rock being sliced with a shimmering knife\",\n  \"Environment\": \"Clean studio table, subtle light reflections\",\n  \"Sound\": \"Crisp slicing, deep grinding, and delicate crumbling\",\n  \"Scene 1\": \"Extreme macro shot: a razor-sharp, polished knife blade presses into the dark, granular surface of an obsidian rock, just beginning to indent.\",\n  \"Scene 2\": \"Close-up: fine, iridescent dust particles erupt from the point of contact as the blade cuts deeper into the obsidian, catching the studio light.\",\n  \"Scene 3\": \"Mid-shot: the knife, held perfectly steady, has formed a shallow, clean groove across the obsidian's shimmering surface, revealing a new, smooth texture.\"\n}"},"typeVersion":1.2},{"id":"790aee60-38b8-4939-834c-bd468b0f240b","name":"Create Clips","type":"n8n-nodes-base.httpRequest","position":[3260,220],"parameters":{"url":"https://api.wavespeed.ai/api/v3/bytedance/seedance-v1-lite-t2v-480p","body":"={\n  \"aspect_ratio\": \"9:16\",\n  \"duration\": 10,\n  \"prompt\": \"VIDEO THEME: {{ $('Prompts AI Agent').item.json.output.Idea }} | WHAT HAPPENS IN THE VIDEO: {{ $json.description }} | WHERE THE VIDEO IS SHOT: {{ $('Prompts AI Agent').item.json.output.Environment }}\"\n}\n","method":"POST","options":{"batching":{"batch":{"batchSize":1,"batchInterval":3000}}},"sendBody":true,"contentType":"raw","authentication":"genericCredentialType","rawContentType":"application/json","genericAuthType":"httpHeaderAuth"},"credentials":{},"typeVersion":4.2},{"id":"ba98805d-7d8b-476e-86b3-94017f79454b","name":"Wait for Clips","type":"n8n-nodes-base.wait","position":[3480,220],"parameters":{"amount":120},"typeVersion":1.1},{"id":"7fc24bd4-8740-4633-b15a-868ff3cdacf5","name":"Get Clips","type":"n8n-nodes-base.httpRequest","position":[3780,220],"parameters":{"url":"=https://api.wavespeed.ai/api/v3/predictions/{{ $json.data.id }}/result","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{},"typeVersion":4.2},{"id":"614d8a4b-1319-4c0a-9b52-de284c232a6d","name":"Download Final Video","type":"n8n-nodes-base.httpRequest","position":[4120,820],"parameters":{"url":"={{ $('Get Final Video').item.json.video_url }}","options":{"response":{"response":"file"}}},"typeVersion":4.2},{"id":"f916f4e9-9634-4863-bdb9-b56e3401165e","name":"Upload to YouTube","type":"n8n-nodes-base.youTube","position":[4320,820],"parameters":{"title":"=AI ASMR : {{ $('Update Final Video to Sheet').item.json.idea }}","options":{"tags":"=asmr, viral, asmrai, n8n, automation","description":"=AI-Generated Video Idea: {{ $('Update Final Video to Sheet').item.json.idea }}\n\nThis video was created automatically using our automated workflow #asmrai #asmr #n8n","privacyStatus":"public","notifySubscribers":true},"resource":"video","operation":"upload"},"credentials":{"youTubeOAuth2Api":{}},"typeVersion":1},{"id":"f9c33085-e6e4-41c9-a463-62cb52c6e71c","name":"Telegram Notification","type":"n8n-nodes-base.telegram","position":[4600,820],"parameters":{"text":"=✅ Your new video is ready!  **Title:** {{ $('Update Final Video to Sheet').item.json.idea }}  \nWatch it here: \nhttps://www.youtube.com/watch?v={{ $('Upload to YouTube').item.json.id }}","chatId":"YOUR_CHAT_ID","additionalFields":{"parse_mode":"HTML"}},"credentials":{"telegramApi":{}},"typeVersion":1.2},{"id":"acbdb550-278a-4f0a-a3c2-b3f1e9183dec","name":"OpenAI Chat Model1","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[1800,420],"parameters":{"model":{"__rl":true,"value":"gpt-4.1"}},"credentials":{"openAiApi":{}},"typeVersion":1.2},{"id":"708c4602-2d5c-49f1-84a8-3117a83ce2cc","name":"Gmail Notification","type":"n8n-nodes-base.gmail","position":[4600,1000],"parameters":{"sendTo":"your-email@gmail.com","message":"=✅ Your new video is ready!  **Title:** {{ $('Update Final Video to Sheet').item.json.idea }}  Watch it here: https://www.youtube.com/watch?v={{ $('Upload to YouTube').item.json.id }}","options":{"senderName":"Bilsimaging -n8n Automation"},"subject":"✅ Your new video is ready!"},"credentials":{"gmailOAuth2":{}},"typeVersion":2.1},{"id":"86188a74-2ca4-4e15-a151-f5a2ae927763","name":"1. Generate Trendy Idea","type":"@n8n/n8n-nodes-langchain.agent","position":[1800,220],"parameters":{"text":"Generate one short, trendy, and viral ASMR video idea. Describe the core concept in less than 10 words. Do not explain it, just state the idea.","options":{"systemMessage":"You are an AI that specializes in identifying viral trends on platforms like TikTok and YouTube Shorts. Your job is to brainstorm a single, simple, and satisfying ASMR video concept. You must only return the idea as a single line of plain text. Do not add any extra words, formatting, or explanation."},"promptType":"define","hasOutputParser":true},"typeVersion":1.9},{"id":"2d8da7d8-c7a0-48b6-b999-59832b543e91","name":"Note: AI Ideation","type":"n8n-nodes-base.stickyNote","position":[1520,0],"parameters":{"color":3,"width":940,"height":180,"content":"### Step 1: AI Brainstorms an Idea\nThis workflow starts with a Schedule Trigger. The first AI agent generates a simple, trendy ASMR concept. The second agent expands this into a full production plan (caption, environment, etc.)."},"typeVersion":1},{"id":"692c4c92-7d16-482f-8bca-cc951ab772e4","name":"Note: Asset Generation","type":"n8n-nodes-base.stickyNote","position":[2560,0],"parameters":{"color":3,"width":600,"height":180,"content":"### Step 2: Scene Generation & Video Creation\nThe plan is used to generate detailed scene descriptions. Then, we call the Wavespeed AI (Seedance) and Fal AI APIs to create the video clips and sound effects in parallel."},"typeVersion":1},{"id":"211c2810-58c9-4246-ba27-561c3e57a74c","name":"Note: Final Assembly","type":"n8n-nodes-base.stickyNote","position":[3260,0],"parameters":{"color":3,"width":660,"height":180,"content":"### Step 3: Final Assembly\nThe video clips are stitched together."},"typeVersion":1},{"id":"c76e5236-b71b-4705-b30c-89d5ae5dd0f5","name":"Note: Distribution","type":"n8n-nodes-base.stickyNote","position":[4040,0],"parameters":{"color":3,"width":960,"height":180,"content":"### Step 4: Distribution & Logging\nThe final video is uploaded to YouTube, the Google Sheet is updated, and notifications are sent."},"typeVersion":1},{"id":"57e8010f-7184-4d88-84fd-d2b85782a09b","name":"SUBMISSION GUIDE","type":"n8n-nodes-base.stickyNote","position":[0,0],"parameters":{"width":1320,"height":1240,"content":"//ASMR AI Workflow By Bilsimaging.com\n### How It Works\n\nThis workflow is a fully autonomous content factory that creates and publishes satisfying ASMR-style YouTube Shorts without any human intervention. It's a powerful example of chaining multiple AI services together to generate unique media.\n\nThe process runs in four main stages:\n\n1.  **AI Ideation:** A schedule trigger kicks off the workflow. The first AI agent brainstorms a simple, trendy ASMR concept. A second agent then enriches this concept into a detailed JSON production plan, including a viral-style caption, environment description, and sound profile.\n\n2.  **Asset Generation:** The workflow generates detailed scene-by-scene prompts. It then calls the ByteDance Seedance API (via Wavespeed) to create the video clips and the Fal AI API to generate corresponding sound effects.\n\n3.  **Final Assembly:** The clips are sequenced into a final video. \n\n4.  **Distribution & Logging:** The final video is downloaded, uploaded to a designated YouTube channel, the original row in a Google Sheet is updated with the new YouTube link and a \"Done\" status, and notifications are sent via Telegram and Gmail.\n\n### Set Up Steps\n\nThis is an advanced workflow that requires several credentials. \n\nYou will need to create credentials for the following services:\n\n*   **OpenAI:** For the AI agents.\n*   **Wavespeed AI:** For the Seedance video model.\n*   **Fal AI:** For sound generation and video sequencing.\n*   **Google OAuth:** For both the Google Sheets and YouTube nodes. You will need to enable the Google Sheets API and YouTube Data API v3 in your Google Cloud project.\n*   **Telegram Bot:** For the final notification.\n*   **Gmail (Optional):** If you want email notifications.\n\nYou will also need to create a **Google Sheet** to log the ideas and final outputs. A template can be easily created with columns for `id`, `idea`, `caption`, `production_status`, `environment_prompt`, `sound_prompt`, `final_output`, and `youtube_url`.\n\n### Features\n\n*   **Fully Autonomous Content Creation:** Runs on a schedule to generate and publish content without any manual input.\n*   **Two-Stage AI Ideation:** Uses a \"creative\" AI and a \"planning\" AI to produce more dynamic and well-structured ideas.\n*   **Multi-Modal AI:** Chains together text-to-text, text-to-video, and text-to-audio models in a single, cohesive flow.\n*   **Closed-Loop System:** Logs the initial idea to a Google Sheet and updates the *same row* with the final links and status, creating a perfect production log.\n*   **Spreadsheet as a CMS:** Manage your entire content pipeline from a simple Google Sheet.\n*   **Real-time Notifications:** Get immediate alerts on Telegram or Gmail as soon as a new video is live.\n\n### Pro-Tips & How to Handle APIs\n\n*   **API Rate Limits:** If you run the workflow very frequently, some APIs might temporarily block you. To avoid this, you can adjust the **Schedule Trigger** to run less often (e.g., every 30 minutes instead of every 10). For more advanced control, you can add a `batchInterval` in the settings of the HTTP Request nodes.\n\n\n*   **Cost Management:** Remember that AI API calls cost money. It is highly recommended to set up **budget alerts** in your OpenAI, Fal AI, and Wavespeed AI account dashboards to avoid any surprise bills.\n\n*   **Customization:** The creative core of this workflow is in the **Prompts AI Agent** and **Enrich Idea into Plan** nodes. To change the style, tone, or type of videos created, simply edit the `systemMessage` in the options of these nodes.\n\nFor any help or tips on handling the APIs, don't hesitate to contact me at **bilsimaging@gmail.com**."},"typeVersion":1},{"id":"62e10519-d31e-4012-8dcf-7e2e82ab35cd","name":"2. Enrich Idea into Plan","type":"@n8n/n8n-nodes-langchain.agent","position":[2200,220],"parameters":{"text":"=Take the following trendy ASMR idea and expand it into a full production plan using your required JSON format. Use the examples below for inspiration on how to format the \"Idea\" field.\n\nThe short ASMR idea is:\n[[\n{{ $json.output }}\n]]\n\nHave your final expanded \"Idea\" field be in this format: \"(color/style) (object) being (action)\". \nExamples for your inspiration: layered rainbow kinetic sand being sliced, sparkly purple soap being scooped, neon green slime being pressed.\n\nUse the Think tool to review your output.","options":{"systemMessage":"=**Role**: You are an AI designed to generate 1 immersive, satisfying idea based on a user-provided topic. Your output must be formatted as a JSON array (single line) and follow all the rules below exactly.\n\n***\nRULES:\n\nOnly return 1 idea at a time.\n\nThe user will provide a key topic (e.g. \"kinetic sand slicing,\" \"satisfying sand scooping,\" \"ASMR sand sounds\").\n\nThe Idea must:\n\nBe under 13 words.\n\nDescribe an interesting and viral-worthy moment, action, or event related to the provided topic.\n\nThe Caption must be:\n\nShort, punchy, and viral-friendly.\n\nInclude one relevant emoji.\n\nInclude exactly 12 hashtags in this order:\n** 4 topic-relevant hashtags\n** 4 all-time most popular hashtags\n** 4 currently trending hashtags\n\nAll hashtags must be lowercase.\n\nSet Status to \"for production\" (always).\n\nThe Environment must:\n\nBe under 20 words.\n\nMatch the action in the Idea exactly.\n\nClearly describe:\n\nWhere the event is happening (e.g. minimalist white surface, clean studio table)\nKey visuals or background details (e.g. bright lighting, subtle glitter)\nStyle of scene (e.g. macro close-up, cinematic slow-motion)\n\nThe Sound must:\n\nBe under 15 words.\n\nDescribe the primary sound that makes sense to happen in the video. This will be fed to a sound model later on.\n\n\n***\nOUTPUT FORMAT (single-line JSON array):\n\n[\n  {\n    \"Caption\": \"That crunch! 🤤 #kineticsand #satisfyingvideos #asmrsand #sand #oddlysatisfying #viral #fyp #explore #trending #tiktok #diy #crafts\",\n    \"Idea\": \"Slicing through a block of layered rainbow kinetic sand\",\n    \"Environment\": \"Macro close-up on a clean, bright white surface, cinematic slow-motion\",\n    \"Sound\": \"Crisp, crunchy slicing sounds with a soft, gentle hiss\",\n    \"Status\": \"for production\"\n  }\n]"},"promptType":"define","hasOutputParser":true},"typeVersion":1.9},{"id":"06ccc97f-aa87-4c64-860b-0da4739d3de5","name":"3. Log New Idea to Sheet","type":"n8n-nodes-base.googleSheets","position":[2560,220],"parameters":{"columns":{"value":{"idea":"={{ $json.output[0].Idea }}","caption":"={{ $json.output[0].Caption }}","production":"In Progress","sound_prompt":"={{ $json.output[0].Sound }}","environment_prompt":"={{ $json.output[0].Environment }}"},"mappingMode":"defineBelow"},"options":{},"operation":"append","sheetName":{"__rl":true,"value":"YOUR_SHEET_NAME"},"documentId":{"__rl":true,"value":"YOUR_GOOGLE_SHEET_ID"}},"credentials":{"googleSheetsOAuth2Api":{}},"typeVersion":4.5},{"id":"58b1f682-2752-4995-b05e-7598353d7a61","name":"Update Final Video to Sheet","type":"n8n-nodes-base.googleSheets","position":[4120,640],"parameters":{"key":"idea","value":"={{ $('Update Final Video to Sheet').item.json.idea }}","columns":{"value":{"production":"Done","youtube_url":"=","final_output":"={{ $json.video_url }}"},"mappingMode":"defineBelow"},"operation":"update","sheetName":{"__rl":true,"value":"YOUR_SHEET_NAME"},"documentId":{"__rl":true,"value":"YOUR_GOOGLE_SHEET_ID"}},"credentials":{"googleSheetsOAuth2Api":{}},"typeVersion":4.5},{"id":"fbf64920-6e9c-4dfa-b75a-bbf022ea597b","name":"Update Sheet with Youtube Link","type":"n8n-nodes-base.googleSheets","position":[4600,640],"parameters":{"key":"idea","value":"={{ $('Update Final Video to Sheet').item.json.idea }}","columns":{"value":{"youtube_url":"=https://www.youtube.com/watch?v={{ $('Upload to YouTube').item.json.id }}"},"mappingMode":"defineBelow"},"operation":"update","sheetName":{"__rl":true,"value":"YOUR_SHEET_NAME"},"documentId":{"__rl":true,"value":"YOUR_GOOGLE_SHEET_ID"}},"credentials":{"googleSheetsOAuth2Api":{}},"typeVersion":4.5}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"final_submission_v1","connections":{"Think":{"ai_tool":[[{"node":"2. Enrich Idea into Plan","type":"ai_tool","index":0},{"node":"Prompts AI Agent","type":"ai_tool","index":0}]]},"Parser":{"ai_outputParser":[[{"node":"2. Enrich Idea into Plan","type":"ai_outputParser","index":0}]]},"Parser2":{"ai_outputParser":[[{"node":"Prompts AI Agent","type":"ai_outputParser","index":0}]]},"Get Clips":{"main":[[{"node":"Create Sounds","type":"main","index":0}]]},"Get Sounds":{"main":[[{"node":"List Elements","type":"main","index":0}]]},"Create Clips":{"main":[[{"node":"Wait for Clips","type":"main","index":0}]]},"Create Sounds":{"main":[[{"node":"Wait for Sounds","type":"main","index":0}]]},"List Elements":{"main":[[{"node":"Sequence Video","type":"main","index":0}]]},"Sequence Video":{"main":[[{"node":"Wait for Final Video","type":"main","index":0}]]},"Wait for Clips":{"main":[[{"node":"Get Clips","type":"main","index":0}]]},"Get Final Video":{"main":[[{"node":"Update Final Video to Sheet","type":"main","index":0}]]},"Wait for Sounds":{"main":[[{"node":"Get Sounds","type":"main","index":0}]]},"Prompts AI Agent":{"main":[[{"node":"Unbundle Prompts","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"1. Generate Trendy Idea","type":"main","index":0}]]},"Unbundle Prompts":{"main":[[{"node":"Create Clips","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"2. Enrich Idea into Plan","type":"ai_languageModel","index":0},{"node":"Prompts AI Agent","type":"ai_languageModel","index":0}]]},"Upload to YouTube":{"main":[[{"node":"Gmail Notification","type":"main","index":0},{"node":"Telegram Notification","type":"main","index":0},{"node":"Update Sheet with Youtube Link","type":"main","index":0}]]},"OpenAI Chat Model1":{"ai_languageModel":[[{"node":"1. Generate Trendy Idea","type":"ai_languageModel","index":0}]]},"Download Final Video":{"main":[[{"node":"Upload to YouTube","type":"main","index":0}]]},"Wait for Final Video":{"main":[[{"node":"Get Final Video","type":"main","index":0}]]},"1. Generate Trendy Idea":{"main":[[{"node":"2. Enrich Idea into Plan","type":"main","index":0}]]},"2. Enrich Idea into Plan":{"main":[[{"node":"3. Log New Idea to Sheet","type":"main","index":0}]]},"3. Log New Idea to Sheet":{"main":[[{"node":"Prompts AI Agent","type":"main","index":0}]]},"Update Final Video to Sheet":{"main":[[{"node":"Download Final Video","type":"main","index":0}]]}}}


name: Create Adaptive RAG Chat Agent with Google Gemini and Qdrant
author_name: Brandon Crenshaw
author_username: brandononchain
categories: []
created_at: 2025-06-22T04:11:54.325Z
updated_at: 2025-06-22T04:11:54.325Z
url: https://n8n.io/workflows/5111
scraped_at: 2025-07-06 21:16:30
description:
  Unlock adaptive, context-aware AI chat in your automations—no coding required!

  This template is a plug-and-play n8n workflow that transforms how your chatbots, support agents, and knowledge systems respond to users. Powered by Google Gemini and a Qdrant vector database, it automatically classifies every incoming query and applies a tailor-made strategy for Factual, Analytical, Opinion, or Contextual requests—delivering the right answer, every time.

  🛠️ Key Features
  Automatic Query Classification:
  Seamlessly detects whether the user wants facts, a deep analysis, opinions, or context—then routes each input to the best answering strategy.

  Four Dynamic Retrieval Modes:
  1) Factual: Delivers precise, accurate information
  2) Analytical: Breaks down complex topics for deep dives
  3) Opinion: Surfaces diverse viewpoints and perspectives
  4) Contextual: Connects the dots using implied or user-specific context

  End-to-End RAG Pipeline:
  Uses Gemini to classify and answer, while Qdrant powers fast, smart knowledge retrieval.

  No-Code Visual Editing:
  Import into n8n, connect your LLM and vector database credentials, and you’re live—customize, extend, and scale with zero backend code.

  Reusable in Any Project:
  Perfect for customer support, research, onboarding bots, internal knowledgebases, or any adaptive AI chat interface.

  🚀 How it Works
  1) User submits a query (via chat or API)
  2) Query is auto-classified as Factual, Analytical, Opinion, or Contextual
  3) Adaptive retrieval strategy is triggered
  (each with its own prompt logic and memory buffer)
  4) Smart knowledge search is performed using Gemini and Qdrant
  5) Response is generated and sent back to the user—tailored to the query type!

  🧩 What’s Included
  Full n8n workflow (.json)
  Step-by-step setup instructions
  Sample prompts and system messages for each strategy
  Lifetime updates (as the workflow evolves)

  💡 Use Cases
  Chatbots that adapt to every user’s intent
  Internal/external FAQ and helpdesk automations
  AI research and summarization agents
  Product support and onboarding flows

  Any scenario where smarter, more relevant answers = better user experience

  Ready to build smarter automations? Import this template, connect your Gemini & Qdrant accounts, and let your AI agent adapt to every conversation.

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

workflow_json:
  {"id":"bU9BBKV0yadVVd30","meta":{"instanceId":"315ec16104c52c82cc21fd9b6adb469e4bd7c2899d0990cb255788b78628ebf4"},"name":"Adaptive & Conditional AI Chat Agent - www.quantralabs.com","tags":[],"nodes":[{"id":"6cccf7c5-9d8b-4f11-a7e1-c1bcf48bb9fe","name":"Query Classification","type":"@n8n/n8n-nodes-langchain.agent","notes":"Classify a query into one of four categories: Factual, Analytical, Opinion, or Contextual.\n        \nReturns:\nstr: Query category","position":[-660,880],"parameters":{"text":"=Classify this query: {{ $('Combined Fields').item.json.user_query }}","options":{"systemMessage":"You are an expert at classifying questions. \n\nClassify the given query into exactly one of these categories:\n- Factual: Queries seeking specific, verifiable information.\n- Analytical: Queries requiring comprehensive analysis or explanation.\n- Opinion: Queries about subjective matters or seeking diverse viewpoints.\n- Contextual: Queries that depend on user-specific context.\n\nReturn ONLY the category name, without any explanation or additional text."},"promptType":"define"},"typeVersion":1.8},{"id":"937104bc-5756-4adb-af0b-3e8741536e44","name":"Switch","type":"n8n-nodes-base.switch","position":[-300,860],"parameters":{"rules":{"values":[{"outputKey":"Factual","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"87f3b50c-9f32-4260-ac76-19c05b28d0b4","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.output.trim() }}","rightValue":"Factual"}]},"renameOutput":true},{"outputKey":"Analytical","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"f8651b36-79fa-4be4-91fb-0e6d7deea18f","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.output.trim() }}","rightValue":"Analytical"}]},"renameOutput":true},{"outputKey":"Opinion","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"5dde06bc-5fe1-4dca-b6e2-6857c5e96d49","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.output.trim() }}","rightValue":"Opinion"}]},"renameOutput":true},{"outputKey":"Contextual","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"bf97926d-7a0b-4e2f-aac0-a820f73344d8","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.output.trim() }}","rightValue":"Contextual"}]},"renameOutput":true}]},"options":{"fallbackOutput":0}},"typeVersion":3.2},{"id":"7346bf45-3f9b-4717-8cb5-52d829f0826c","name":"Factual Strategy - Focus on Precision","type":"@n8n/n8n-nodes-langchain.agent","notes":"Retrieval strategy for factual queries focusing on precision.","position":[100,120],"parameters":{"text":"=Enhance this factual query: {{ $('Combined Fields').item.json.user_query }}","options":{"systemMessage":"=You are an expert at enhancing search queries.\n\nYour task is to reformulate the given factual query to make it more precise and specific for information retrieval. Focus on key entities and their relationships.\n\nProvide ONLY the enhanced query without any explanation."},"promptType":"define"},"typeVersion":1.7},{"id":"ac1df57d-524c-4393-a81c-fb720f19b05e","name":"Analytical Strategy - Comprehensive Coverage","type":"@n8n/n8n-nodes-langchain.agent","notes":"Retrieval strategy for analytical queries focusing on comprehensive coverage.","position":[100,660],"parameters":{"text":"=Generate sub-questions for this analytical query: {{ $('Combined Fields').item.json.user_query }}","options":{"systemMessage":"=You are an expert at breaking down complex questions.\n\nGenerate sub-questions that explore different aspects of the main analytical query.\nThese sub-questions should cover the breadth of the topic and help retrieve comprehensive information.\n\nReturn a list of exactly 3 sub-questions, one per line."},"promptType":"define"},"typeVersion":1.7},{"id":"7df8350e-4f18-47fb-bd9a-c0238d218603","name":"Opinion Strategy - Diverse Perspectives","type":"@n8n/n8n-nodes-langchain.agent","notes":"Retrieval strategy for opinion queries focusing on diverse perspectives.","position":[100,1200],"parameters":{"text":"=Identify different perspectives on: {{ $('Combined Fields').item.json.user_query }}","options":{"systemMessage":"=You are an expert at identifying different perspectives on a topic.\n\nFor the given query about opinions or viewpoints, identify different perspectives that people might have on this topic.\n\nReturn a list of exactly 3 different viewpoint angles, one per line."},"promptType":"define"},"typeVersion":1.7},{"id":"0f9ef12d-7df4-4255-b5e2-27eb4e7ce982","name":"Contextual Strategy - User Context Integration","type":"@n8n/n8n-nodes-langchain.agent","notes":"Retrieval strategy for contextual queries integrating user context.","position":[100,1740],"parameters":{"text":"=Infer the implied context in this query: {{ $('Combined Fields').item.json.user_query }}","options":{"systemMessage":"=You are an expert at understanding implied context in questions.\n\nFor the given query, infer what contextual information might be relevant or implied but not explicitly stated. Focus on what background would help answering this query.\n\nReturn a brief description of the implied context."},"promptType":"define"},"typeVersion":1.7},{"id":"3c04f8e8-1304-436d-86eb-d905aa1cc261","name":"Chat","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[-1320,1020],"webhookId":"56f626b5-339e-48af-857f-1d4198fc8a4d","parameters":{"options":{}},"typeVersion":1.1},{"id":"e1daa9fc-62d2-4664-a9f3-dcdecf9071e6","name":"Factual Prompt and Output","type":"n8n-nodes-base.set","position":[500,120],"parameters":{"options":{},"assignments":{"assignments":[{"id":"a4a28ac2-4a56-46f6-8b86-f5d1a34b2ced","name":"output","type":"string","value":"={{ $json.output }}"},{"id":"7aa6ce13-afbf-4871-b81c-6e9c722a53dc","name":"prompt","type":"string","value":"You are a helpful assistant providing factual information. Answer the question based on the provided context. Focus on accuracy and precision. If the context doesn't contain the information needed, acknowledge the limitations."}]}},"typeVersion":3.4},{"id":"1429dfd5-709d-4065-9134-05820fad871b","name":"Contextual Prompt and Output","type":"n8n-nodes-base.set","position":[500,1740],"parameters":{"options":{},"assignments":{"assignments":[{"id":"a4a28ac2-4a56-46f6-8b86-f5d1a34b2ced","name":"output","type":"string","value":"={{ $json.output }}"},{"id":"7aa6ce13-afbf-4871-b81c-6e9c722a53dc","name":"prompt","type":"string","value":"You are a helpful assistant providing contextually relevant information. Answer the question considering both the query and its context. Make connections between the query context and the information in the provided documents. If the context doesn't fully address the specific situation, acknowledge the limitations."}]}},"typeVersion":3.4},{"id":"01c57856-4378-4085-bb67-2edf9b1164f9","name":"Opinion Prompt and Output","type":"n8n-nodes-base.set","position":[500,1200],"parameters":{"options":{},"assignments":{"assignments":[{"id":"a4a28ac2-4a56-46f6-8b86-f5d1a34b2ced","name":"output","type":"string","value":"={{ $json.output }}"},{"id":"7aa6ce13-afbf-4871-b81c-6e9c722a53dc","name":"prompt","type":"string","value":"You are a helpful assistant discussing topics with multiple viewpoints. Based on the provided context, present different perspectives on the topic. Ensure fair representation of diverse opinions without showing bias. Acknowledge where the context presents limited viewpoints."}]}},"typeVersion":3.4},{"id":"3cb3f5e1-c85c-4481-a147-8b3c419526ee","name":"Analytical Prompt and Output","type":"n8n-nodes-base.set","position":[500,660],"parameters":{"options":{},"assignments":{"assignments":[{"id":"a4a28ac2-4a56-46f6-8b86-f5d1a34b2ced","name":"output","type":"string","value":"={{ $json.output }}"},{"id":"7aa6ce13-afbf-4871-b81c-6e9c722a53dc","name":"prompt","type":"string","value":"You are a helpful assistant providing analytical insights. Based on the provided context, offer a comprehensive analysis of the topic. Cover different aspects and perspectives in your explanation. If the context has gaps, acknowledge them while providing the best analysis possible."}]}},"typeVersion":3.4},{"id":"34577e85-b067-49dd-90a6-048805de5118","name":"Gemini Classification","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[-680,1080],"parameters":{"options":{},"modelName":"models/gemini-2.0-flash-lite"},"typeVersion":1},{"id":"7257c1dd-56bb-4f50-b206-2edd55fdd7cf","name":"Gemini Factual","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[80,340],"parameters":{"options":{},"modelName":"models/gemini-2.0-flash"},"typeVersion":1},{"id":"47465499-74e8-4425-913a-2efd5c5e3441","name":"Gemini Analytical","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[80,880],"parameters":{"options":{},"modelName":"models/gemini-2.0-flash"},"typeVersion":1},{"id":"a7273940-82c8-44a9-8890-b00c1a741015","name":"Chat Buffer Memory Analytical","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[240,880],"parameters":{"sessionKey":"={{ $('Combined Fields').item.json.chat_memory_key }}","sessionIdType":"customKey","contextWindowLength":10},"typeVersion":1.3},{"id":"6b573a7d-a6f0-4290-b3f1-3e36785bbee1","name":"Chat Buffer Memory Factual","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[240,340],"parameters":{"sessionKey":"={{ $('Combined Fields').item.json.chat_memory_key }}","sessionIdType":"customKey","contextWindowLength":10},"typeVersion":1.3},{"id":"9b20e2d9-9c67-45a0-9dfe-03bafb62f67f","name":"Gemini Opinion","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[80,1420],"parameters":{"options":{},"modelName":"models/gemini-2.0-flash"},"typeVersion":1},{"id":"70489752-18b8-4676-a700-539c7b0fecb3","name":"Chat Buffer Memory Opinion","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[240,1420],"parameters":{"sessionKey":"={{ $('Combined Fields').item.json.chat_memory_key }}","sessionIdType":"customKey","contextWindowLength":10},"typeVersion":1.3},{"id":"e32a0ce3-2f72-43ca-b12a-03e3cf1b7818","name":"Gemini Contextual","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[80,1960],"parameters":{"options":{},"modelName":"models/gemini-2.0-flash"},"typeVersion":1},{"id":"75c4f677-4c78-4a22-b0b4-44f3882c1a4e","name":"Chat Buffer Memory Contextual","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[240,1960],"parameters":{"sessionKey":"={{ $('Combined Fields').item.json.chat_memory_key }}","sessionIdType":"customKey","contextWindowLength":10},"typeVersion":1.3},{"id":"31d68f85-3cfc-4c93-81f7-c27070bf7307","name":"Embeddings","type":"@n8n/n8n-nodes-langchain.embeddingsGoogleGemini","position":[1020,1100],"parameters":{"modelName":"models/text-embedding-004"},"typeVersion":1},{"id":"53910aea-7326-4d59-8585-693cb05afc3e","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[0,0],"parameters":{"color":7,"width":700,"height":520,"content":"## Factual Strategy\n**Retrieve precise facts and figures.**"},"typeVersion":1},{"id":"87015bf7-0bf1-490f-90b4-96346cc51b7c","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[0,540],"parameters":{"color":7,"width":700,"height":520,"content":"## Analytical Strategy\n**Provide comprehensive coverage of a topics and exploring different aspects.**"},"typeVersion":1},{"id":"b14886e0-e513-405d-92d5-d4a417280546","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[0,1080],"parameters":{"color":7,"width":700,"height":520,"content":"## Opinion Strategy\n**Gather diverse viewpoints on a subjective issue.**"},"typeVersion":1},{"id":"77cd1373-d547-462b-85cb-6799e7fbae84","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[0,1620],"parameters":{"color":7,"width":700,"height":520,"content":"## Contextual Strategy\n**Incorporate user-specific context to fine-tune the retrieval.**"},"typeVersion":1},{"id":"edfe1620-b040-466c-a8b2-a6f2aae565c5","name":"Concatenate Context","type":"n8n-nodes-base.summarize","position":[1400,880],"parameters":{"options":{},"fieldsToSummarize":{"values":[{"field":"document.pageContent","separateBy":"other","aggregation":"concatenate","customSeparator":"={{ \"\\n\\n---\\n\\n\" }}"}]}},"typeVersion":1.1},{"id":"059f5b2e-52db-49f6-bee8-9dfcd5fd1ea4","name":"Retrieve Documents from Vector Store","type":"@n8n/n8n-nodes-langchain.vectorStoreQdrant","position":[1040,880],"parameters":{"mode":"load","topK":10,"prompt":"={{ $json.prompt }}\n\nUser query: \n{{ $json.output }}","options":{},"qdrantCollection":{"__rl":true,"mode":"id","value":"={{ $('Combined Fields').item.json.vector_store_id }}"}},"typeVersion":1.1},{"id":"d1a2de81-c92b-459a-a2b6-bb6d171ba712","name":"Set Prompt and Output","type":"n8n-nodes-base.set","position":[840,880],"parameters":{"options":{},"assignments":{"assignments":[{"id":"1d782243-0571-4845-b8fe-4c6c4b55379e","name":"output","type":"string","value":"={{ $json.output }}"},{"id":"547091fb-367c-44d4-ac39-24d073da70e0","name":"prompt","type":"string","value":"={{ $json.prompt }}"}]}},"typeVersion":3.4},{"id":"aa7dede0-8241-4428-84db-7a403935a052","name":"Gemini Answer","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[1680,1100],"parameters":{"options":{},"modelName":"models/gemini-2.0-flash"},"typeVersion":1},{"id":"5a33f53d-2297-46a1-9508-54c1e4f168be","name":"Answer","type":"@n8n/n8n-nodes-langchain.agent","position":[1720,880],"parameters":{"text":"=User query: {{ $('Combined Fields').item.json.user_query }}","options":{"systemMessage":"={{ $('Set Prompt and Output').item.json.prompt }}\n\nUse the following context (delimited by <ctx></ctx>) and the chat history to answer the user query.\n<ctx>\n{{ $json.concatenated_document_pageContent }}\n</ctx>"},"promptType":"define"},"typeVersion":1.8},{"id":"888d1b5e-151f-4fb7-a201-fa8706af6ae8","name":"Chat Buffer Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[1860,1100],"parameters":{"sessionKey":"={{ $('Combined Fields').item.json.chat_memory_key }}","sessionIdType":"customKey","contextWindowLength":10},"typeVersion":1.3},{"id":"573efafe-0dca-46d9-98a9-2684277d411d","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[760,680],"parameters":{"color":7,"width":820,"height":580,"content":"## Perform adaptive retrieval\n**Find document considering both query and context.**"},"typeVersion":1},{"id":"f4219ef7-16ce-4cc6-8b03-a9480b2daf55","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[1600,680],"parameters":{"color":7,"width":740,"height":580,"content":"## Reply to the user integrating retrieval context"},"typeVersion":1},{"id":"4fe79c8d-9670-4b2a-a7c7-5a2239906a14","name":"Respond to Webhook","type":"n8n-nodes-base.respondToWebhook","position":[2080,880],"parameters":{"options":{}},"typeVersion":1.1},{"id":"ff99bc5a-bbbe-457d-b979-2ca1e04bd980","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-760,680],"parameters":{"color":7,"width":700,"height":580,"content":"## User query classification\n**Classify the query into one of four categories: Factual, Analytical, Opinion, or Contextual.**"},"typeVersion":1},{"id":"c632a735-5a96-4a70-bf4c-6126e2e193f1","name":"When Executed by Another Workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[-1320,760],"parameters":{"workflowInputs":{"values":[{"name":"user_query"},{"name":"chat_memory_key"},{"name":"vector_store_id"}]}},"typeVersion":1.1},{"id":"332b925d-0581-4b92-a7ce-83cbc8f66254","name":"Combined Fields","type":"n8n-nodes-base.set","position":[-1000,880],"parameters":{"options":{},"assignments":{"assignments":[{"id":"90ab73a2-fe01-451a-b9df-bffe950b1599","name":"user_query","type":"string","value":"={{ $json.user_query || $json.chatInput }}"},{"id":"36686ff5-09fc-40a4-8335-a5dd1576e941","name":"chat_memory_key","type":"string","value":"={{ $json.chat_memory_key || $('Chat').item.json.sessionId }}"},{"id":"4230c8f3-644c-4985-b710-a4099ccee77c","name":"vector_store_id","type":"string","value":"={{ $json.vector_store_id || \"<ID HERE>\" }}"}]}},"typeVersion":3.4},{"id":"eab0d609-5d9b-4794-adb5-fd8a784f34b0","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[-1340,1300],"parameters":{"width":1280,"height":1300,"content":"# Adaptive RAG Workflow\n\nThis n8n workflow implements a version of the Adaptive Retrieval-Augmented Generation (RAG) approach. It classifies user queries and applies different retrieval and generation strategies based on the query type (Factual, Analytical, Opinion, or Contextual) to provide more relevant and tailored answers from a knowledge base stored in a Qdrant vector store.\n\n## How it Works\n\n1.  **Input Trigger:**\n    * The workflow can be initiated via the built-in Chat interface or triggered by another n8n workflow.\n    * It expects inputs: `user_query`, `chat_memory_key` (for conversation history), and `vector_store_id` (specifying the Qdrant collection).\n    * A `Set` node (`Combined Fields`) standardizes these inputs.\n\n2.  **Query Classification:**\n    * A Google Gemini agent (`Query Classification`) analyzes the `user_query`.\n    * It classifies the query into one of four categories:\n        * **Factual:** Seeking specific, verifiable information.\n        * **Analytical:** Requiring comprehensive analysis or explanation.\n        * **Opinion:** Asking about subjective matters or seeking diverse viewpoints.\n        * **Contextual:** Depending on user-specific or implied context.\n\n3.  **Adaptive Strategy Routing:**\n    * A `Switch` node routes the workflow based on the classification result from the previous step.\n\n4.  **Strategy Implementation (Query Adaptation):**\n    * Depending on the route, a specific Google Gemini agent adapts the query or approach:\n        * **Factual Strategy:** Rewrites the query for better precision, focusing on key entities (`Factual Strategy - Focus on Precision`).\n        * **Analytical Strategy:** Breaks down the main query into multiple sub-questions to ensure comprehensive coverage (`Analytical Strategy - Comprehensive Coverage`).\n        * **Opinion Strategy:** Identifies different potential perspectives or angles related to the query (`Opinion Strategy - Diverse Perspectives`).\n        * **Contextual Strategy:** Infers implied context needed to answer the query effectively (`Contextual Strategy - User Context Integration`).\n    * Each strategy path uses its own chat memory buffer for the adaptation step.\n\n5.  **Retrieval Prompt & Output Setup:**\n    * Based on the *original* query classification, a `Set` node (`Factual/Analytical/Opinion/Contextual Prompt and Output`, combined via connections to `Set Prompt and Output`) prepares:\n        * The output from the strategy step (e.g., rewritten query, sub-questions, perspectives).\n        * A tailored system prompt for the final answer generation agent, instructing it how to behave based on the query type (e.g., focus on precision for Factual, present diverse views for Opinion).\n\n6.  **Document Retrieval (RAG):**\n    * The `Retrieve Documents from Vector Store` node uses the adapted query/output from the strategy step to search the specified Qdrant collection (`vector_store_id`).\n    * It retrieves the top relevant document chunks using Google Gemini embeddings.\n\n7.  **Context Preparation:**\n    * The content from the retrieved document chunks is concatenated (`Concatenate Context`) to form a single context block for the final answer generation.\n\n8.  **Answer Generation:**\n    * The final `Answer` agent (powered by Google Gemini) generates the response.\n    * It uses:\n        * The tailored system prompt set in step 5.\n        * The concatenated context from retrieved documents (step 7).\n        * The original `user_query`.\n        * The shared chat history (`Chat Buffer Memory` using `chat_memory_key`).\n\n9.  **Response:**\n    * The generated answer is sent back to the user via the `Respond to Webhook` node."},"typeVersion":1},{"id":"1580b44f-bd48-43f8-b9ef-dbfd58042e68","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[-1100,680],"parameters":{"color":7,"width":320,"height":580,"content":"## ⚠️  If using in Chat mode\n\nUpdate the `vector_store_id` variable to the corresponding Qdrant ID needed to perform the documents retrieval."},"typeVersion":1},{"id":"df475a3d-cec6-4a29-8d33-cfe8a1ae3d6c","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-1720,1300],"parameters":{"color":5,"width":360,"height":200,"content":"## Quantra Labs \nFollow Us\nhttps://www.x.com/quantralabs\n\nConnect with Us\nhttps://www.linkedin.com/company/quantra-labs\n\nwww.quantralabs.com"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"c562673d-bddb-4abd-adef-59c2fb61e716","connections":{"Chat":{"main":[[{"node":"Combined Fields","type":"main","index":0}]]},"Answer":{"main":[[{"node":"Respond to Webhook","type":"main","index":0}]]},"Switch":{"main":[[{"node":"Factual Strategy - Focus on Precision","type":"main","index":0}],[{"node":"Analytical Strategy - Comprehensive Coverage","type":"main","index":0}],[{"node":"Opinion Strategy - Diverse Perspectives","type":"main","index":0}],[{"node":"Contextual Strategy - User Context Integration","type":"main","index":0}]]},"Embeddings":{"ai_embedding":[[{"node":"Retrieve Documents from Vector Store","type":"ai_embedding","index":0}]]},"Gemini Answer":{"ai_languageModel":[[{"node":"Answer","type":"ai_languageModel","index":0}]]},"Gemini Factual":{"ai_languageModel":[[{"node":"Factual Strategy - Focus on Precision","type":"ai_languageModel","index":0}]]},"Gemini Opinion":{"ai_languageModel":[[{"node":"Opinion Strategy - Diverse Perspectives","type":"ai_languageModel","index":0}]]},"Combined Fields":{"main":[[{"node":"Query Classification","type":"main","index":0}]]},"Gemini Analytical":{"ai_languageModel":[[{"node":"Analytical Strategy - Comprehensive Coverage","type":"ai_languageModel","index":0}]]},"Gemini Contextual":{"ai_languageModel":[[{"node":"Contextual Strategy - User Context Integration","type":"ai_languageModel","index":0}]]},"Chat Buffer Memory":{"ai_memory":[[{"node":"Answer","type":"ai_memory","index":0}]]},"Concatenate Context":{"main":[[{"node":"Answer","type":"main","index":0}]]},"Query Classification":{"main":[[{"node":"Switch","type":"main","index":0}]]},"Gemini Classification":{"ai_languageModel":[[{"node":"Query Classification","type":"ai_languageModel","index":0}]]},"Set Prompt and Output":{"main":[[{"node":"Retrieve Documents from Vector Store","type":"main","index":0}]]},"Factual Prompt and Output":{"main":[[{"node":"Set Prompt and Output","type":"main","index":0}]]},"Opinion Prompt and Output":{"main":[[{"node":"Set Prompt and Output","type":"main","index":0}]]},"Chat Buffer Memory Factual":{"ai_memory":[[{"node":"Factual Strategy - Focus on Precision","type":"ai_memory","index":0}]]},"Chat Buffer Memory Opinion":{"ai_memory":[[{"node":"Opinion Strategy - Diverse Perspectives","type":"ai_memory","index":0}]]},"Analytical Prompt and Output":{"main":[[{"node":"Set Prompt and Output","type":"main","index":0}]]},"Contextual Prompt and Output":{"main":[[{"node":"Set Prompt and Output","type":"main","index":0}]]},"Chat Buffer Memory Analytical":{"ai_memory":[[{"node":"Analytical Strategy - Comprehensive Coverage","type":"ai_memory","index":0}]]},"Chat Buffer Memory Contextual":{"ai_memory":[[{"node":"Contextual Strategy - User Context Integration","type":"ai_memory","index":0}]]},"When Executed by Another Workflow":{"main":[[{"node":"Combined Fields","type":"main","index":0}]]},"Retrieve Documents from Vector Store":{"main":[[{"node":"Concatenate Context","type":"main","index":0}]]},"Factual Strategy - Focus on Precision":{"main":[[{"node":"Factual Prompt and Output","type":"main","index":0}]]},"Opinion Strategy - Diverse Perspectives":{"main":[[{"node":"Opinion Prompt and Output","type":"main","index":0}]]},"Analytical Strategy - Comprehensive Coverage":{"main":[[{"node":"Analytical Prompt and Output","type":"main","index":0}]]},"Contextual Strategy - User Context Integration":{"main":[[{"node":"Contextual Prompt and Output","type":"main","index":0}]]}}}


name: Automated AWS IAM Key Compromise Response with Slack & Claude AI
author_name: Niranjan G
author_username: niranjan
categories: []
created_at: 2025-06-22T07:43:25.214Z
updated_at: 2025-06-22T07:43:25.214Z
url: https://n8n.io/workflows/5123
scraped_at: 2025-07-06 21:16:30
description:
  🛡️ Automated AWS Key Compromise Remediation

  Description

  This n8n workflow provides a secure, enterprise-grade response system for AWS IAM access key compromises with built-in form submission and human approval mechanisms. When an AWS access key is suspected to be compromised, this workflow enables rapid containment through a secure web form interface with basic authentication, human approval via Slack, and automated damage prevention through immediate key deactivation, credential invalidation, and comprehensive security reporting.

  How This Workflow is Useful

  Secure Form-Based Response
  Authenticated Form Submission**: Secure web form with basic authentication for capturing compromise details
  Human Approval Workflow**: Slack-based approval system for sensitive security operations
  Rapid Key Deactivation**: Instantly disables compromised access keys after approval
  Credential Invalidation**: Creates and applies security policies to invalidate existing temporary credentials
  Policy Analysis**: Automatically scans and analyzes both inline and attached IAM policies for the affected user
  AI-Powered Reporting**: Generates detailed security reports with intelligent analysis and team notifications

  Business Value
  Reduces Mean Time to Response (MTTR)**: Automates manual security procedures that typically take hours
  Minimizes Security Exposure**: Immediate containment prevents potential data breaches and unauthorized resource access
  Ensures Compliance**: Provides audit trails and documentation required for security compliance frameworks
  Cost Prevention**: Prevents potential financial damage from compromised credentials being used maliciously
  Rapid Response Capability**: Streamlines security response procedures when incidents are detected

  Technical Benefits
  AWS Best Practices**: Implements official AWS security recommendations for key compromise response
  Scalable Architecture**: Handles multiple access keys and complex IAM policy structures
  Error Handling**: Robust error handling ensures workflow continues even if individual steps fail
  Audit Trail**: Complete logging of all actions taken during the incident response
  Integration Ready**: Easily integrates with existing security tools and notification systems

  Use Cases

  1. Incident Response Automation
  Automated response to security alerts from AWS CloudTrail
  Integration with SIEM systems for immediate key compromise response
  24/7 security monitoring and automated containment

  2. Compliance and Audit
  Meeting regulatory requirements for incident response documentation
  Providing audit trails for security compliance frameworks (SOC 2, ISO 27001, PCI DSS)
  Demonstrating due diligence in security incident handling

  3. Multi-Account Management
  Centralized security response across multiple AWS accounts
  Consistent incident response procedures across different environments
  Standardized security automation for enterprise AWS deployments

  4. Security Training and Testing
  Security team training on AWS incident response procedures
  Tabletop exercises and security drills
  Testing and validation of security response capabilities

  Key Features

  Core Functionality
  ✅ Secure Form Interface: Web form with basic authentication for secure data submission
  ✅ Human Approval Gate: Slack-based approval workflow for sensitive operations
  ✅ Authenticated Data Processing: Secure handling of form submissions with validation
  ✅ Immediate Key Deactivation: Instant disabling of compromised credentials after approval
  ✅ Security Policy Generation: Automatic creation and attachment of credential invalidation policies
  ✅ Policy Analysis: Deep analysis of user permissions and attached policies
  ✅ AI Security Analysis: Intelligent security report generation with risk assessment
  ✅ Team Notifications: Real-time Slack notifications to security teams
  ✅ Comprehensive Logging: Complete audit trail of all response actions

  Technical Specifications
  Secure Form Interface**: Web form with basic authentication for secure data capture
  Human Approval System**: Slack-based approval workflow for sensitive operations
  AWS API Integration**: Direct integration with AWS IAM APIs
  Authentication Layer**: Basic auth protection for form submissions
  Error Handling**: Robust error handling with continuation on non-critical failures
  Scalable Processing**: Handles multiple policies and complex IAM structures
  Security Best Practices**: No hardcoded credentials, uses AWS credential management
  Modular Design**: Easy to customize and extend for specific organizational needs

  Prerequisites

  Required Credentials
  AWS Credentials** with IAM permissions for:
    ListAccessKeys, UpdateAccessKey
    ListUserPolicies, ListAttachedUserPolicies
    CreatePolicy, AttachUserPolicy
    GetPolicy, GetPolicyVersion, GetUserPolicy

  Required Integrations
  Slack Workspace** for approval workflow and team notifications
  Basic Authentication Setup** for secure form access

  Optional Integrations
  AI Language Model** (Claude/OpenAI) for intelligent security analysis and report generation

  Installation and Setup

  Import the workflow into your n8n instance
  Configure AWS credentials in n8n credential manager
  Set up basic authentication for the secure form interface
  Configure Slack integration for approval notifications and team alerts
  Set up AI model (optional) for enhanced security analysis and reporting
  Configure approval workflow in Slack for human oversight
  Test in development environment before production use

  Workflow Inputs

  Secure Form Submission
  This workflow uses a secure web form with basic authentication to capture compromise details:
  Username**: The AWS IAM username of the compromised account
  Access Key ID**: The specific access key ID that has been compromised

  Authentication & Approval Process
  Form Authentication: Basic authentication protects the submission form
  Data Processing: Secure handling and validation of submitted credentials
  Human Approval: Slack notification sent to security team for approval
  Automated Execution: Upon approval, the workflow executes the security response

  This multi-layered approach ensures that sensitive security operations require both authentication and human oversight before execution.

  🚀 Automate with Slack Integration

  Want to fully automate and simplify this workflow? Connect it with Slack for seamless team collaboration and instant response capabilities!

  Interactive Slack Automation
  Combine this AWS Key Compromise Response workflow with our Interactive Slack Approval & Data Submission System to create a fully automated incident response pipeline:

  Instant Slack Alerts**: Receive immediate notifications when key compromises are detected
  One-Click Response**: Trigger the AWS response workflow directly from Slack with interactive buttons
  Team Collaboration**: Enable security teams to respond collectively through Slack channels
  Approval Workflows**: Add human approval gates before executing critical security actions
  Real-time Updates**: Get live status updates and completion notifications in Slack

  How the Complete Solution Works
  Detection: External security monitoring tools (CloudTrail, SIEM, etc.) detect potential key compromise
  Secure Form Access: Security team accesses the authenticated web form to submit compromise details
  Form Submission: Credentials are securely submitted through the basic auth-protected form
  Human Approval: Slack notification sent to security team for review and approval
  Approved Execution: Upon approval, the AWS security response executes automatically
  Real-time Updates: Progress and completion notifications sent back to Slack
  Security Analysis: AI-powered analysis and comprehensive reporting delivered to the team

  Get Started with Full Automation
  To enable automatic notifications and complete the automation pipeline, use the Interactive Slack Approval & Data Submission System with Webhooks workflow: https://n8n.io/workflows/5049-interactive-slack-approval-and-data-submission-system-with-webhooks/

  This integration transforms manual security responses into streamlined, team-collaborative automation that reduces response time from hours to minutes.

  Security Considerations

  Form Authentication**: Basic authentication protects the submission interface
  Human Approval Gate**: Slack-based approval prevents unauthorized execution
  AWS Credential Management**: Uses AWS credential management best practices
  No Sensitive Data Storage**: No sensitive data stored in workflow configuration
  Least-Privilege Access**: Implements least-privilege access principles
  Complete Audit Trails**: Provides complete audit trails for compliance
  Secure Data Processing**: Encrypted handling of form submissions and approvals
  Immediate Damage Prevention**: Designed for rapid containment after approval

  ⚠️ Important Disclaimer

  Use with Caution: Disabling access keys without proper understanding can significantly impact your personal or business operations. This workflow immediately deactivates AWS access keys, which may disrupt running applications, automated processes, or services that depend on these credentials.

  AWS Best Practices Recommendation: 
  Use IAM Roles instead of Access Keys** whenever possible for enhanced security
  IAM roles provide temporary credentials and eliminate the need for long-term access keys
  Follow the principle of least privilege when assigning permissions
  Regularly rotate and audit your AWS credentials
  Implement proper monitoring and alerting for credential usage

  Before Using This Workflow:
  Ensure you understand which services and applications use the target access key
  Have a rollback plan in case of accidental disruption
  Test in a non-production environment first
  Coordinate with your team before executing in production

  For comprehensive AWS security best practices, refer to the AWS Security Best Practices Guide.

  For more workflows and automation solutions, visit: https://n8n.io/creators/niranjan/

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

workflow_json:
  {"meta":{"instanceId":"c62c01f3e843893075a10f252ec7d6d69e5ab593af019f50055d506cb3081b99","templateCredsSetupCompleted":true},"nodes":[{"id":"d5fa0dbd-41d5-402c-1234-1234567890","name":"🔑 Fetch User Access Keys","type":"n8n-nodes-base.httpRequest","position":[-1480,380],"parameters":{"url":"https://iam.amazonaws.com","method":"POST","options":{},"sendBody":true,"contentType":"form-urlencoded","authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"Action","value":"ListAccessKeys"},{"name":"Version","value":"2010-05-08"},{"name":"UserName","value":"={{ $json.UserName }}"}]},"nodeCredentialType":"aws"},"credentials":{"aws":{"id":"ABC123456789","name":"AWS account"}},"typeVersion":4.1},{"id":"02461671-e2a2-4424-bfe8-fd74afc460c5","name":"📊 Parse Access Key Response","type":"n8n-nodes-base.code","position":[-1260,380],"parameters":{"jsCode":"const result = {};\nlet counter = 1;\n\nfor (const item of items) {\n  try {\n    const response = item.json.body || item.json;\n    const metadata = response?.ListAccessKeysResponse?.ListAccessKeysResult?.AccessKeyMetadata || [];\n\n    for (const key of metadata) {\n      const keyLabel = `AccessKey${counter}`;\n      result[keyLabel] = {\n        [`AccessKeyId${counter}`]: key.AccessKeyId,\n        [`UserName${counter}`]: key.UserName,\n        Status: key.Status,\n        [`CreateDate${counter}`]: new Date(key.CreateDate * 1000).toISOString()\n      };\n      counter++;\n    }\n  } catch (error) {\n    console.error('Error processing access keys:', error);\n  }\n}\n\nreturn [{ json: result }];\n"},"typeVersion":2},{"id":"83640bea-3b16-4173-a486-bcbfe9cffddd","name":"🚫 Deactivate Compromised Key","type":"n8n-nodes-base.httpRequest","onError":"continueRegularOutput","position":[-180,900],"parameters":{"url":"https://iam.amazonaws.com","method":"POST","options":{},"sendBody":true,"contentType":"form-urlencoded","authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"Action","value":"UpdateAccessKey"},{"name":"Version","value":"2010-05-08"},{"name":"UserName","value":"={{ $json.UserName }}"},{"name":"AccessKeyId","value":"={{ $json.AccessKeyId }}"},{"name":"Status","value":"Inactive"}]},"nodeCredentialType":"aws"},"credentials":{"aws":{"id":"ABC123456789","name":"AWS account"}},"typeVersion":4.1},{"id":"d671f4f7-759f-4bd6-abc1-abc1234567","name":"📜 Audit Inline Policies","type":"n8n-nodes-base.httpRequest","onError":"continueRegularOutput","position":[-160,1320],"parameters":{"url":"https://iam.amazonaws.com","method":"POST","options":{},"sendBody":true,"contentType":"form-urlencoded","authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"Action","value":"ListUserPolicies"},{"name":"Version","value":"2010-05-08"},{"name":"UserName","value":"={{ $json.UserName }}"}]},"nodeCredentialType":"aws"},"credentials":{"aws":{"id":"ABC123456789","name":"AWS account"}},"typeVersion":4.2},{"id":"6e6a912f-d043-44c0-abc1-abc123456789","name":"🔍 Audit Attached Policies","type":"n8n-nodes-base.httpRequest","position":[-160,1680],"parameters":{"url":"https://iam.amazonaws.com","method":"POST","options":{},"sendBody":true,"contentType":"form-urlencoded","authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"Action","value":"ListAttachedUserPolicies"},{"name":"Version","value":"2010-05-08"},{"name":"UserName","value":"={{ $json.UserName }}"}]},"nodeCredentialType":"aws"},"credentials":{"aws":{"id":"ABC123456789","name":"AWS account"}},"typeVersion":4.2},{"id":"9fc7c861-a714-4b24-b19d-7d163c8e6a4d","name":"🛡️ Generate Invalidation Policy","type":"n8n-nodes-base.httpRequest","onError":"continueRegularOutput","position":[-200,480],"parameters":{"url":"https://iam.amazonaws.com","method":"POST","options":{},"sendBody":true,"contentType":"form-urlencoded","authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"Action","value":"CreatePolicy"},{"name":"PolicyDocument","value":"={\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [{\n    \"Sid\": \"DenyExpiredSessions\",\n    \"Effect\": \"Deny\",\n    \"Action\": \"*\",\n    \"Resource\": \"*\",\n    \"Condition\": {\n      \"DateLessThan\": {\n        \"aws:TokenIssueTime\": \"{{ $now.minus({ days: 3 }).toISO() }}\"\n      }\n    }\n  }]\n}\n"},{"name":"PolicyName","value":"=Invalidating-Temporary-Security-Credentials-{{ $now.toFormat('yyyy-MM-dd') + '-' + Math.random().toString(36).substring(2, 8).toUpperCase() }}"},{"name":"Version","value":"2010-05-08"}]},"nodeCredentialType":"aws"},"credentials":{"aws":{"id":"ABC123456789","name":"AWS account"}},"typeVersion":4.2},{"id":"df0f64b3-95cf-48ef-b2a9-fe035d3e14ad","name":"🔗 Apply Security Policy","type":"n8n-nodes-base.httpRequest","onError":"continueRegularOutput","position":[340,60],"parameters":{"url":"https://iam.amazonaws.com","method":"POST","options":{},"sendBody":true,"contentType":"form-urlencoded","authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"Action","value":"AttachUserPolicy"},{"name":"PolicyArn","value":"={{ $json.CreatePolicyResponse.CreatePolicyResult.Policy.Arn }}"},{"name":"Version","value":"2010-05-08"},{"name":"UserName","value":"={{ $('✅ Approved Compromise Data').item.json.UserName }}"}]},"nodeCredentialType":"aws"},"credentials":{"aws":{"id":"ABC123456789","name":"AWS account"}},"typeVersion":4.2},{"id":"c4ec2ef4-7db8-4189-877b-abc1234567890","name":"📤 Extract Inline Policy Names","type":"n8n-nodes-base.splitOut","onError":"continueRegularOutput","position":[60,1320],"parameters":{"options":{},"fieldToSplitOut":"ListUserPoliciesResponse.ListUserPoliciesResult.PolicyNames"},"typeVersion":1},{"id":"07ab67a9-146d-4576-8afa-a128cf62974f","name":"🔄 Batch Process Inline Policies","type":"n8n-nodes-base.splitInBatches","position":[280,1320],"parameters":{"options":{}},"typeVersion":3},{"id":"ff91b356-3771-463f-8593-82a0396c6514","name":"🔄 Batch Process Attached Policies","type":"n8n-nodes-base.splitInBatches","position":[280,1700],"parameters":{"options":{}},"typeVersion":3},{"id":"e1344921-481a-467b-9240-72b80e8f8ef9","name":"📤 Extract Attached Policy List","type":"n8n-nodes-base.splitOut","position":[60,1680],"parameters":{"options":{},"fieldToSplitOut":"ListAttachedUserPoliciesResponse.ListAttachedUserPoliciesResult.AttachedPolicies"},"typeVersion":1},{"id":"c884daa9-f96f-40c7-8fd0-3a00612bf431","name":"🤖 AI Security Analysis","type":"@n8n/n8n-nodes-langchain.agent","onError":"continueRegularOutput","position":[2400,980],"parameters":{"text":"={{ JSON.stringify($json.data, null, 2) }}","options":{"systemMessage":"# AWS Key Compromise Response Summary Prompt\n\nYou are an AWS security analyst. Your task is to analyze the key compromise response actions and provide a simple, clear summary of what happened and the current security status.\n\n## Instructions\n\nFollow these instructions precisely:\n\n### 1. Analysis Output Format\n\nOutput your analysis wrapped exactly between these tags, inside a fenced code block:\n```\n...your simple analysis here...\n```\n\n### 2. Keep It Simple - Focus Only On:\n\n#### Key Compromise Response Summary\n- **What happened**: Brief description of the compromise\n- **Actions taken**: Key deactivation, policy creation, and attachment status\n- **Current status**: Whether the response was successful\n- **Risk level**: Simple HIGH/MEDIUM/LOW assessment\n\n#### Essential Details Only\n- **User affected**: Username and access key ID\n- **Response actions**: What automated actions were completed\n- **Security status**: Current protection level after response\n- **Next steps**: 1-2 simple recommendations if needed\n\n### 3. Policy Analysis Guidelines\n\n**Ignore all policy version metadata** fields — if you see `versionId`, `isDefault`, `createDate`, or the `\"Version\"` field inside `decodedPolicy`, do **not** mention or interpret these as security findings; focus **only** on the actual policy statements and actions.\n\n### 4. Slack-Compatible Report\n\nAfter the fenced code block, output a Slack-compatible report using **ONLY** the following supported Slack Markdown formats:\n\n#### Supported Slack Markdown Elements:\n- **Bold text:** `*bold text*` (asterisks)\n- **Italic text:** `_italic text_` (underscores)\n- **Strikethrough:** `~strikethrough~` (tildes)\n- **Inline code:** `code` (single backticks)\n- **Code blocks:** ``` (three backticks)\n- **Block quotes:** `> quoted text` (greater than symbol)\n- **Bulleted lists:** `* item` or `• item` (asterisk or bullet)\n- **Ordered lists:** `1. item` (number and period)\n- **Links:** `<https://example.com|Link Text>` (angle brackets with pipe)\n\n#### Slack Report Format:\n\n🚨 *AWS Key Compromise Response Summary*\n\n👤 *Affected User*\n• User: username\n• Access Key: AKIA...\n\n✅ *Response Actions Completed*\n• 🚫 Access key deactivated\n• 🛡️ Security policy applied\n• ⏰ Temporary credentials invalidated\n\n📊 *Current Status*\n• Response: Successful/Failed\n• Risk Level: HIGH/MEDIUM/LOW\n• Account Secured: Yes/No\n\n💡 *Next Steps*\n• [1-2 simple recommendations or \"No further action needed\"]\n\n📅 *Incident Date*\n• YYYY-MM-DD\n\n_Automated security response completed_\n\n### 5. Simple Guidelines\n\n**Keep it simple:**\n• Use clear, non-technical language\n• Focus on what happened and current status\n• Avoid complex security jargon\n• Provide actionable next steps only if needed\n• Keep the summary under 200 words\n\n### 6. What to Look For in the Data\n\n- **User information**: Username and access key ID\n- **Key deactivation**: Whether the access key was successfully disabled\n- **Policy creation**: Whether security policies were created and attached\n- **Response status**: Overall success or failure of the automated response\n\nThis prompt is designed to provide simple, clear summaries of AWS key compromise response actions for business stakeholders."},"promptType":"define"},"typeVersion":2},{"id":"3eae5e83-a978-44eb-814e-ca97d32bcde0","name":"🔀 Merge Response Data","type":"n8n-nodes-base.merge","position":[1940,920],"parameters":{"numberInputs":6},"typeVersion":3.2},{"id":"45f1ed8f-e1cd-45ff-a70b-96e4ffa5dbb4","name":"📦 Aggregate Final Results","type":"n8n-nodes-base.aggregate","position":[2180,980],"parameters":{"options":{},"aggregate":"aggregateAllItemData"},"typeVersion":1},{"id":"9880aa6e-5475-467f-9281-64c42b3d7898","name":"📋 Fetch Policy Metadata","type":"n8n-nodes-base.httpRequest","position":[500,1760],"parameters":{"url":"https://iam.amazonaws.com","method":"POST","options":{},"sendBody":true,"contentType":"form-urlencoded","authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"Action","value":"GetPolicy"},{"name":"Version","value":"=2010-05-08"},{"name":"PolicyArn","value":"={{ $json.PolicyArn }}"}]},"nodeCredentialType":"aws"},"credentials":{"aws":{"id":"ABC123456789","name":"AWS account"}},"typeVersion":4.2},{"id":"fa82af49-be87-4579-a6fc-68b14e16b1aa","name":"📄 Retrieve Policy Document","type":"n8n-nodes-base.httpRequest","position":[720,1760],"parameters":{"url":"https://iam.amazonaws.com","method":"POST","options":{},"sendBody":true,"contentType":"form-urlencoded","authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"Action","value":"GetPolicyVersion"},{"name":"Version","value":"2010-05-08"},{"name":"=PolicyArn","value":"={{ $json.GetPolicyResponse.GetPolicyResult.Policy.Arn }}"},{"name":"=VersionId","value":"={{ $json.GetPolicyResponse.GetPolicyResult.Policy.DefaultVersionId }}"}]},"nodeCredentialType":"aws"},"credentials":{"aws":{"id":"ABC123456789","name":"AWS account"}},"typeVersion":4.2},{"id":"b1abafca-5443-4dc5-992e-7210296b27ca","name":"📜 Retrieve Inline Policy Details","type":"n8n-nodes-base.httpRequest","position":[520,1360],"parameters":{"url":"https://iam.amazonaws.com","method":"POST","options":{},"sendBody":true,"contentType":"form-urlencoded","authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"Action","value":"GetUserPolicy"},{"name":"Version","value":"2010-05-08"},{"name":"UserName","value":"={{ $('📝 Secure Form: Key Compromise Input').item.json.Username }}"},{"name":"=PolicyName","value":"={{ $json[\"ListUserPoliciesResponse.ListUserPoliciesResult.PolicyNames\"] }}"}]},"nodeCredentialType":"aws"},"credentials":{"aws":{"id":"ABC123456789","name":"AWS account"}},"typeVersion":4.2},{"id":"68ad6474-1a28-4c1d-9708-911e3475da7d","name":"🔓 Parse Inline Policy JSON","type":"n8n-nodes-base.code","position":[720,1360],"parameters":{"jsCode":"// Sample input (you'll usually get this from n8n's input)\nconst inputItems = $input.all();\n\nconst decodedPolicies = inputItems.map(item => {\n  const encoded = item.json?.GetUserPolicyResponse?.GetUserPolicyResult?.PolicyDocument;\n  let decoded = null;\n  let parsed = null;\n\n  try {\n    decoded = decodeURIComponent(encoded);\n    parsed = JSON.parse(decoded);\n  } catch (e) {\n    // Fallback if decoding or parsing fails\n    parsed = { error: 'Invalid or undecodable policy document' };\n  }\n\n  return {\n    json: {\n      user: item.json?.GetUserPolicyResponse?.GetUserPolicyResult?.UserName || 'unknown',\n      policyName: item.json?.GetUserPolicyResponse?.GetUserPolicyResult?.PolicyName || 'unknown',\n      decodedPolicy: parsed\n    }\n  };\n});\n\nreturn decodedPolicies;\n"},"typeVersion":2},{"id":"d3cf69d7-15ba-4ec9-b463-6223ed3959eb","name":"🔓 Parse Attached Policy JSON","type":"n8n-nodes-base.code","position":[900,1760],"parameters":{"jsCode":"const inputItems = $input.all();\n\nconst decodedPolicies = inputItems.map(item => {\n  const encoded = item.json?.GetPolicyVersionResponse?.GetPolicyVersionResult?.PolicyVersion?.Document;\n  let decoded = null;\n  let parsed = null;\n\n  try {\n    decoded = decodeURIComponent(encoded);\n    parsed = JSON.parse(decoded);\n  } catch (e) {\n    parsed = { error: 'Invalid or undecodable policy document' };\n  }\n\n  return {\n    json: {\n      versionId: item.json?.GetPolicyVersionResponse?.GetPolicyVersionResult?.PolicyVersion?.VersionId || 'unknown',\n      isDefault: item.json?.GetPolicyVersionResponse?.GetPolicyVersionResult?.PolicyVersion?.IsDefaultVersion || false,\n      createDate: item.json?.GetPolicyVersionResponse?.GetPolicyVersionResult?.PolicyVersion?.CreateDate || null,\n      decodedPolicy: parsed\n    }\n  };\n});\n\nreturn decodedPolicies;\n"},"typeVersion":2},{"id":"9b3a898c-70be-4fb1-905d-e29a92e89772","name":"⚡ Inline Policy Router","type":"n8n-nodes-base.noOp","position":[920,1360],"parameters":{},"typeVersion":1},{"id":"9402330b-7f94-4fbc-ba49-38e668e59abe","name":"⚡ Attached Policy Router","type":"n8n-nodes-base.noOp","position":[1100,1760],"parameters":{},"typeVersion":1},{"id":"0d40fba1-568e-41db-8d58-170df5f0a927","name":"💬 Notify Security Team","type":"n8n-nodes-base.slack","position":[2760,980],"webhookId":"981a72f0-c86f-46ba-ba1c-96e05fd35b2e","parameters":{"text":"=🚫 AWS Key Compromise Summary\n\n {{ $json.output }}","select":"channel","channelId":{"__rl":true,"mode":"id","value":"ABC1234567890"},"otherOptions":{}},"credentials":{"slackApi":{"id":"ABC123456789","name":"Slack account"}},"typeVersion":2.3},{"id":"89b5bf1b-081c-46e9-b634-eb4e95a6e2a9","name":"🧠 Claude AI Engine","type":"@n8n/n8n-nodes-langchain.lmChatAnthropic","position":[2420,1200],"parameters":{"model":{"__rl":true,"mode":"list","value":"claude-3-7-sonnet-20250219","cachedResultName":"Claude Sonnet 3.7"},"options":{}},"credentials":{"anthropicApi":{"id":"ABC123456789","name":"Anthropic account"}},"typeVersion":1.3},{"id":"bec15d6b-2869-4784-b55d-c1cb8a1644d9","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-420,1600],"parameters":{"width":1840,"height":400,"content":"## 🔄 Process Each Attached Policy"},"typeVersion":1},{"id":"06904eef-ed07-4b84-a4b9-c5f9defb384d","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-420,1180],"parameters":{"width":1840,"height":400,"content":"## 🔄 Process Each Inline Policy"},"typeVersion":1},{"id":"ca8a044a-211a-4548-86e6-f2ae758b97f1","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-420,760],"parameters":{"width":1840,"height":400,"content":"## 🚫 Disable Compromised Key"},"typeVersion":1},{"id":"22145ce8-1fcb-4e7d-977a-5e3758a4b635","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-420,340],"parameters":{"width":1840,"height":400,"content":"## 🛠 Create Security Policy [Invalidating-Temporary-Security-Credentials]"},"typeVersion":1},{"id":"f4100d07-40db-41da-a60c-3770fc8dbba3","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-420,-80],"parameters":{"width":1840,"height":400,"content":"## 🔗 Attach Security Policy [Invalidating-Temporary-Security-Credentials]]"},"typeVersion":1},{"id":"b0bac576-f2ab-4d58-b1f6-1fb70a620649","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[1700,700],"parameters":{"color":5,"width":1320,"height":740,"content":"## 🤖 Generate Security Report"},"typeVersion":1},{"id":"489444dd-c8ab-444e-ac11-aef48061650b","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-2260,780],"parameters":{"color":3,"width":720,"height":400,"content":"# ✏️ Manual Entry: UserName & AccessKeyId"},"typeVersion":1},{"id":"3f524117-9a16-4e3c-9c9b-b365af4d51c7","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[-2080,240],"parameters":{"width":1360,"height":400,"content":"## 🔍 Retrieve IAM Key Info"},"typeVersion":1},{"id":"e3bf53dd-84dd-48aa-af4a-0352e30ea4ba","name":"🔍 AWS IAM Service","type":"n8n-nodes-base.awsIam","position":[-1700,380],"parameters":{"returnAll":true,"requestOptions":{},"additionalFields":{}},"credentials":{"aws":{"id":"ABC123456789","name":"AWS account"}},"typeVersion":1},{"id":"4be7829d-c736-4125-aaa6-f75118e98c17","name":"🔔 Request Human Approval","type":"n8n-nodes-base.slack","position":[-1320,940],"webhookId":"93b4ba77-b68e-4393-b4a8-4fac3f7f00ae","parameters":{"user":{"__rl":true,"mode":"id","value":"ABC1234567890"},"message":"=🛡️ Approval Request: AWS IAM Key Compromise Response\n\nUser: {{ $json.UserName }}\nAccess Key ID: {{ $json.AccessKeyId }}\nDate: {{ $json.Date }}\n\nPlease review and approve the remediation action.","options":{},"operation":"sendAndWait"},"credentials":{"slackApi":{"id":"ABC123456789","name":"Slack account"}},"typeVersion":2.3,"alwaysOutputData":true},{"id":"1db4a332-df13-494b-87e6-1226f8d89b3f","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[-1480,780],"parameters":{"color":4,"width":420,"height":400,"content":"# ✏️ Human in the loop\n## Wait for approval or human input before continuing"},"typeVersion":1},{"id":"296666c1-c6dd-451e-b9d6-a799634ac9ae","name":"✅ Approved Compromise Data","type":"n8n-nodes-base.set","position":[-880,940],"parameters":{"options":{},"assignments":{"assignments":[{"id":"ad40b317-c48b-4814-b06b-6aced6ab5174","name":"UserName","type":"string","value":"={{ $('📝 Secure Form: Key Compromise Input').item.json.Username }}"},{"id":"a5b68025-b2cc-42d6-aae8-527bd46dad41","name":"AccessKeyId","type":"string","value":"={{ $('📝 Secure Form: Key Compromise Input').item.json.AccessKeyID }}"},{"id":"23551fee-041c-4822-9957-da228b721bc1","name":"Date","type":"string","value":"={{ new Date().toISOString().split(\"T\")[0] }}"}]}},"typeVersion":3.4},{"id":"95eb48d4-ef3f-410b-b2d8-815e9083e5e4","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-1020,780],"parameters":{"color":4,"width":420,"height":400,"content":"# ✏️ Selected UserName & AccessKeyId"},"typeVersion":1},{"id":"2b792970-ebae-4e60-86b3-1780c45948e5","name":"🔧 Process Form Submission","type":"n8n-nodes-base.set","position":[-1820,940],"parameters":{"options":{},"assignments":{"assignments":[{"id":"ad40b317-c48b-4814-b06b-6aced6ab5174","name":"UserName","type":"string","value":"={{ $json.Username }}"},{"id":"a5b68025-b2cc-42d6-aae8-527bd46dad41","name":"AccessKeyId","type":"string","value":"={{ $json.AccessKeyID }}"},{"id":"23551fee-041c-4822-9957-da228b721bc1","name":"Date","type":"string","value":"={{ new Date().toISOString().split(\"T\")[0] }}"}]}},"typeVersion":3.4},{"id":"987b3736-c325-4fe5-8d70-f14b9f5955d8","name":"🔍 Manual Key Lookup Trigger","type":"n8n-nodes-base.manualTrigger","position":[-1920,380],"parameters":{},"typeVersion":1},{"id":"97bb3007-1143-4a13-9adf-811e1268db4f","name":"📝 Secure Form: Key Compromise Input","type":"n8n-nodes-base.formTrigger","position":[-2100,940],"webhookId":"f3d8ce11-9e3f-46c3-ba17-221674b9dd6e","parameters":{"options":{},"formTitle":"🚨 Automated AWS IAM Key Compromise Response Input","formFields":{"values":[{"fieldLabel":"Username","requiredField":true},{"fieldLabel":"AccessKeyID","requiredField":true}]},"authentication":"basicAuth"},"credentials":{"httpBasicAuth":{"id":"pmJaCcMGEkPDYowB","name":"Basic Auth Webhook credential"}},"typeVersion":2.2},{"id":"33cd00aa-6027-4b3b-b373-c802ac6bf17d","name":"⚡ No Operation, do nothing","type":"n8n-nodes-base.noOp","position":[-1040,380],"parameters":{},"typeVersion":1}],"connections":{"🔍 AWS IAM Service":{"main":[[{"node":"🔑 Fetch User Access Keys","type":"main","index":0}]]},"🧠 Claude AI Engine":{"ai_languageModel":[[{"node":"🤖 AI Security Analysis","type":"ai_languageModel","index":0}]]},"⚡ Inline Policy Router":{"main":[[{"node":"🔄 Batch Process Inline Policies","type":"main","index":0}]]},"🔀 Merge Response Data":{"main":[[{"node":"📦 Aggregate Final Results","type":"main","index":0}]]},"🤖 AI Security Analysis":{"main":[[{"node":"💬 Notify Security Team","type":"main","index":0}]]},"⚡ Attached Policy Router":{"main":[[{"node":"🔄 Batch Process Attached Policies","type":"main","index":0}]]},"📋 Fetch Policy Metadata":{"main":[[{"node":"📄 Retrieve Policy Document","type":"main","index":0}]]},"📜 Audit Inline Policies":{"main":[[{"node":"📤 Extract Inline Policy Names","type":"main","index":0}]]},"🔗 Apply Security Policy":{"main":[[{"node":"🔀 Merge Response Data","type":"main","index":0}]]},"🔑 Fetch User Access Keys":{"main":[[{"node":"📊 Parse Access Key Response","type":"main","index":0}]]},"🔔 Request Human Approval":{"main":[[{"node":"✅ Approved Compromise Data","type":"main","index":0}]]},"✅ Approved Compromise Data":{"main":[[{"node":"🛡️ Generate Invalidation Policy","type":"main","index":0},{"node":"🚫 Deactivate Compromised Key","type":"main","index":0},{"node":"🔀 Merge Response Data","type":"main","index":3},{"node":"📜 Audit Inline Policies","type":"main","index":0},{"node":"🔍 Audit Attached Policies","type":"main","index":0}]]},"📦 Aggregate Final Results":{"main":[[{"node":"🤖 AI Security Analysis","type":"main","index":0}]]},"🔍 Audit Attached Policies":{"main":[[{"node":"📤 Extract Attached Policy List","type":"main","index":0}]]},"🔧 Process Form Submission":{"main":[[{"node":"🔔 Request Human Approval","type":"main","index":0}]]},"📄 Retrieve Policy Document":{"main":[[{"node":"🔓 Parse Attached Policy JSON","type":"main","index":0}]]},"🔓 Parse Inline Policy JSON":{"main":[[{"node":"⚡ Inline Policy Router","type":"main","index":0}]]},"📊 Parse Access Key Response":{"main":[[{"node":"⚡ No Operation, do nothing","type":"main","index":0}]]},"🔍 Manual Key Lookup Trigger":{"main":[[{"node":"🔍 AWS IAM Service","type":"main","index":0}]]},"🔓 Parse Attached Policy JSON":{"main":[[{"node":"⚡ Attached Policy Router","type":"main","index":0}]]},"🚫 Deactivate Compromised Key":{"main":[[{"node":"🔀 Merge Response Data","type":"main","index":2}]]},"📤 Extract Inline Policy Names":{"main":[[{"node":"🔄 Batch Process Inline Policies","type":"main","index":0}]]},"📤 Extract Attached Policy List":{"main":[[{"node":"🔄 Batch Process Attached Policies","type":"main","index":0}]]},"🔄 Batch Process Inline Policies":{"main":[[{"node":"🔀 Merge Response Data","type":"main","index":4}],[{"node":"📜 Retrieve Inline Policy Details","type":"main","index":0}]]},"📜 Retrieve Inline Policy Details":{"main":[[{"node":"🔓 Parse Inline Policy JSON","type":"main","index":0}]]},"🔄 Batch Process Attached Policies":{"main":[[{"node":"🔀 Merge Response Data","type":"main","index":5}],[{"node":"📋 Fetch Policy Metadata","type":"main","index":0}]]},"🛡️ Generate Invalidation Policy":{"main":[[{"node":"🔗 Apply Security Policy","type":"main","index":0},{"node":"🔀 Merge Response Data","type":"main","index":1}]]},"📝 Secure Form: Key Compromise Input":{"main":[[{"node":"🔧 Process Form Submission","type":"main","index":0}]]}}}


name: AI-Powered Accounting Reports from Sabre EDI with GPT-4 and Pinecone RAG
author_name: Mohan Gopal
author_username: mohan
categories: []
created_at: 2025-06-22T16:45:54.084Z
updated_at: 2025-06-22T16:45:54.084Z
url: https://n8n.io/workflows/5130
scraped_at: 2025-07-06 21:16:30
description:
  This workflow automates the process of reading EDI files generated by Sabre, parsing them using an AI Agent, and producing structured accounting reports like:

  📌 Accounts Receivable (AR) Summary
  📌 Tax and Surcharges Report

  It also uses Retrieval-Augmented Generation (RAG) to vectorize the Sabre Interface User Record (IUR)—a 154-page technical document—so that the AI agent can reference it when clarification is required while generating reports.

  ⚙️ Tools & Integrations Used
  Component:Tool/Service:Purpose:Workflow Engine:n8n:Automation & orchestration
  LLM Model:OpenAI GPT-4 / Chat Model:Natural language understanding and parsing
  Embeddings Model:OpenAI Embeddings:Convert text into semantic vector format
  Vector Database:Pinecone:Store and retrieve document chunks semantically
  Storage:Google Drive:Source of raw EDI text files and PDF documentation
  DataLoader + Splitter:n8n Node + Recursive Splitter:Loads and prepares documents for embedding
  AI Agents:n8n AI Agent Node:Runs context-aware prompts and parses reports

  🧱 Workflow Breakdown
  🧠 1. Vectorizing the Sabre IUR Document (RAG Setup)
  📘 Objective: Enable the AI Agent to refer to the IUR document (154 pages) for detailed explanations of EDI terms, formats, and rules.

  Flow Steps:

  Google Drive Search + Download – Find and pull the IUR PDF file.

  Default Data Loader – Load the file and preprocess it for semantic splitting.

  Recursive Character Splitter – Break down large pages into meaningful chunks.

  OpenAI Embeddings – Vectorize each chunk.

  Pinecone Vector Store – Save into a Pinecone namespace for future retrieval.

  ✅ Result: The IUR is now searchable via semantic queries from the AI Agent.

  📁 2. Reading and Extracting Data from EDI Files
  📘 Objective: Parse raw EDI files for financial records and summaries.

  Flow Steps:

  Trigger – Manual or scheduled execution of the workflow.

  Google Drive Search – Finds all new .edi or .txt files.

  Download File Contents – Loads content of each file into memory.

  Extract from File – Raw text extraction.

  📊 3. Report Generation Using AI Agents
  📘 Objective: AI Agents parse the extracted data to generate structured accounting reports.

  a. Accounts Receivable Report Agent
  The extracted text is passed to an AI Agent.

  Model is connected to:

  OpenAI Chat Model (LLM)

  Pinecone Vector DB (IUR reference)

  Outputs a structured AR Summary Report.

  b. Tax and Surcharges Report Agent
  Same steps as above.

  Prompts adjusted to extract tax, fees, surcharges, and amounts.

  ✅ Output Format: Can be mapped to columns and inserted into a Google Sheet or exported as a CSV/JSON.

  📑 Sample Reports You Can Build
  Already implemented:

  ✅ Accounts Receivable (AR) Summary Report

  ✅ Tax and Surcharges Report

  Can be extended to:
  Accounts Payable (AP)
  Passenger Revenue
  Daily Sales
  Commission Report
  Net Profit Margin (if supplier cost + commission is available)

  💡 Key Advantages
  ✅ No-code automation with n8n

  ✅ Semantic reasoning using AI + Vector DB (RAG)

  ✅ Can work with various Sabre outputs without manual parsing

  ✅ Modular: Easy to add new report types

  ✅ Cloud-integrated (Drive, Pinecone, OpenAI)

  🧪 Potential Improvements
  Area	Suggestions
  Testing	Add a “Preview” step to validate extracted data before writing
  Scalability	Batch mode + Google Sheet batching for multiple reports
  Audit Trail	Log every file name, timestamp, report type in a Google Sheet
  Notification	Send Slack/Email when a new report is generated
  Multi-model support	Add Claude/Gemini fallback if OpenAI usage limit is hit

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

workflow_json:
  {"id":"HWsEhnkLn4XfhWIc","meta":{"instanceId":"92e36925b2d06addd7a010605535ce53ac105737436355f7e52e2980c726ed3d"},"name":"05 EDI File Processing - Completed","tags":[{"id":"oKGIn6U0wpeHShTN","name":"working flow","createdAt":"2025-06-02T06:27:44.762Z","updatedAt":"2025-06-02T06:27:44.762Z"}],"nodes":[{"id":"ac1d38b5-6177-4b36-9a23-c26889e94a78","name":"When clicking ‘Test workflow’","type":"n8n-nodes-base.manualTrigger","position":[-280,1060],"parameters":{},"typeVersion":1},{"id":"2daa8cbd-acc8-4365-938b-b3caf49ad9ea","name":"Pinecone Vector Store1","type":"@n8n/n8n-nodes-langchain.vectorStorePinecone","position":[540,100],"parameters":{"mode":"insert","options":{},"pineconeIndex":{"__rl":true,"mode":"list","value":"package1536","cachedResultName":"package1536"}},"credentials":{"pineconeApi":{"id":"HqCFDvnsq0D6wXpJ","name":"PineconeApi account 2"}},"typeVersion":1.1},{"id":"52f425bf-9269-43fc-a685-482ea5cf3e0c","name":"Embeddings OpenAI1","type":"@n8n/n8n-nodes-langchain.embeddingsOpenAi","position":[440,360],"parameters":{"options":{}},"credentials":{"openAiApi":{"id":"SCKN5KUziIpM8NB7","name":"OpenAi account 5"}},"typeVersion":1.2},{"id":"7ed2dc8d-60ef-4c65-935c-fca4e7502c06","name":"Default Data Loader1","type":"@n8n/n8n-nodes-langchain.documentDefaultDataLoader","position":[600,360],"parameters":{"options":{},"dataType":"binary"},"typeVersion":1},{"id":"44ad4300-31f9-4e14-904a-de23f9a5b81c","name":"Recursive Character Text Splitter1","type":"@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter","position":[680,540],"parameters":{"options":{},"chunkOverlap":50},"typeVersion":1},{"id":"f9512cb3-5b71-4a65-91eb-19f01130c459","name":"Google Drive","type":"n8n-nodes-base.googleDrive","position":[120,100],"parameters":{"filter":{"folderId":{"__rl":true,"mode":"list","value":"1fuSiN8yukGRr27nigbt4oUsffIpzg_L7","cachedResultUrl":"https://drive.google.com/drive/folders/1fuSiN8yukGRr27nigbt4oUsffIpzg_L7","cachedResultName":"SabreEDIFileGuide"}},"options":{},"resource":"fileFolder","returnAll":true},"credentials":{"googleDriveOAuth2Api":{"id":"RFbg76pQ49AUClT1","name":"mohan.gopal001@gmail.com"}},"typeVersion":3},{"id":"cc3a857b-9053-4fbf-aec0-91604a3cc608","name":"Google Drive1","type":"n8n-nodes-base.googleDrive","position":[300,100],"parameters":{"fileId":{"__rl":true,"mode":"id","value":"={{ $json.id }}"},"options":{},"operation":"download"},"credentials":{"googleDriveOAuth2Api":{"id":"RFbg76pQ49AUClT1","name":"mohan.gopal001@gmail.com"}},"typeVersion":3},{"id":"cbdd35c6-8c8b-4eb4-910b-ef77cd440916","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-320,-60],"parameters":{"width":1740,"height":740,"content":"## Vectorizing Sabre Interface User Record (IUR) \n**The Sabre Interface User Record (IUR) supports travel agency back-office functions for Ticketing, Invoicing and Itinerary type entries. The IUR is used to store and transmit information gathered from the Passenger Name Record (PNR) in Sabre to the back-office system via an asynchronous communications device utilizing a standard EIA-RS2312C signal transmission.**"},"typeVersion":1},{"id":"c25c8091-66ab-4ba9-88be-cc5870a88b98","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[500,1280],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"SCKN5KUziIpM8NB7","name":"OpenAi account 5"}},"typeVersion":1.2},{"id":"de06cb47-a14a-4c4a-8398-679bd4ed6e4f","name":"Pinecone Vector Store","type":"@n8n/n8n-nodes-langchain.vectorStorePinecone","position":[660,1280],"parameters":{"mode":"retrieve-as-tool","options":{"pineconeNamespace":""},"toolName":"PackageDetails","pineconeIndex":{"__rl":true,"mode":"list","value":"package1536","cachedResultName":"package1536"},"toolDescription":"Return the Accounts Payable details reading the information from the input file. "},"credentials":{"pineconeApi":{"id":"HqCFDvnsq0D6wXpJ","name":"PineconeApi account 2"}},"typeVersion":1.1},{"id":"c06ce64d-e52d-4901-8d9b-78276315a43c","name":"Embeddings OpenAI","type":"@n8n/n8n-nodes-langchain.embeddingsOpenAi","position":[680,1440],"parameters":{"options":{}},"credentials":{"openAiApi":{"id":"SCKN5KUziIpM8NB7","name":"OpenAi account 5"}},"typeVersion":1.2},{"id":"17f220b8-51c3-4819-b14d-44acb827e9d1","name":"Extract from File","type":"n8n-nodes-base.extractFromFile","position":[320,1060],"parameters":{"options":{},"operation":"text"},"typeVersion":1},{"id":"1a62d317-36fa-4cbf-991e-ae9fefc43da4","name":"Account Receivable Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[540,1060],"parameters":{"text":"=\nUse the incoming EDI files and generate Account Receivable Report by going throug each file, listing the account receivables for each PNR and the passenger data. \n {{ $json.data }}","options":{"systemMessage":"##Role##\nYou are an Accounting and Finance Reporting Expert and you understand the incoming EDI file from which you extract data and compile Accounts Receivable (AR) Summary Report\n\nInstruction:\nRead the incoming EDI file and identify the accounting info and generate accounting receivable report. \nIf there are data that you don't understand, query the pinecone vector database where the complete guidelines is stored for the undersatnding. \nOutput just the table with the data. No need to give a dscription in the begining. \n\nGenerate report in the below tabular format that is extractable in JSON format: \n\n{\n  [\n    {\"passenger\": \"Sergei\", \"fare\": 414, \"tax\": 34.88, \"total\": 448.88}\n  ]\n}\nNote:\nNever ever create your own AR report if in doubt or missing data.\n"},"promptType":"define","hasOutputParser":true},"typeVersion":1.9},{"id":"f3d494ce-439e-4b74-96c7-b4aeea412b6b","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-320,720],"parameters":{"width":1740,"height":860,"content":"## Reports from EDI file\n1. Accounts Receivable (AR) Summary Report\n2. Accounts Payable (AP) Report\n3. Tax and Surcharges Report\n4. Passenger Revenue Report\n5. Daily Sales Report\n6. Uncollected Revenue / Payment Status Report\n7. Commission Report (if applicable)\n8. Audit & Compliance Report\n9. Ticketing Report\n10. Profit Margin Report (if commission & supplier cost known)\n"},"typeVersion":1},{"id":"12e76ce9-9bf6-42ea-9059-252a1e39d50d","name":"Google Drive: extract files","type":"n8n-nodes-base.googleDrive","position":[-80,1060],"parameters":{"filter":{"folderId":{"__rl":true,"mode":"list","value":"172VdwV-JNLv0H7i7OXRMjYqIshg6ow1O","cachedResultUrl":"https://drive.google.com/drive/folders/172VdwV-JNLv0H7i7OXRMjYqIshg6ow1O","cachedResultName":"EDIFileForProcessing"}},"options":{},"resource":"fileFolder","returnAll":true},"credentials":{"googleDriveOAuth2Api":{"id":"RFbg76pQ49AUClT1","name":"mohan.gopal001@gmail.com"}},"typeVersion":3},{"id":"a7f51cdc-614e-460a-8327-9cc20c61741a","name":"Google Drive: download file contents","type":"n8n-nodes-base.googleDrive","position":[120,1060],"parameters":{"fileId":{"__rl":true,"mode":"id","value":"={{ $json.id }}"},"options":{},"operation":"download"},"credentials":{"googleDriveOAuth2Api":{"id":"RFbg76pQ49AUClT1","name":"mohan.gopal001@gmail.com"}},"typeVersion":3},{"id":"296bbaf6-a5fb-4be4-8e83-cb8d6a696b12","name":"OpenAI Chat Model1","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[960,1280],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"SCKN5KUziIpM8NB7","name":"OpenAi account 5"}},"typeVersion":1.2},{"id":"74f71aa2-dde2-4bb8-8142-dfe5bb0ca896","name":"Pinecone Vector Store2","type":"@n8n/n8n-nodes-langchain.vectorStorePinecone","position":[1120,1280],"parameters":{"mode":"retrieve-as-tool","options":{"pineconeNamespace":""},"toolName":"PackageDetails","pineconeIndex":{"__rl":true,"mode":"list","value":"package1536","cachedResultName":"package1536"},"toolDescription":"Return the Tax Summary aligning to the input file"},"credentials":{"pineconeApi":{"id":"HqCFDvnsq0D6wXpJ","name":"PineconeApi account 2"}},"typeVersion":1.1},{"id":"5206c19e-bd8b-4e24-bf6d-225af26fdd48","name":"Embeddings OpenAI2","type":"@n8n/n8n-nodes-langchain.embeddingsOpenAi","position":[1140,1440],"parameters":{"options":{}},"credentials":{"openAiApi":{"id":"SCKN5KUziIpM8NB7","name":"OpenAi account 5"}},"typeVersion":1.2},{"id":"a1b109f9-3259-48d7-a426-c876d3aaf97e","name":"Tax and Surcharges Report","type":"@n8n/n8n-nodes-langchain.agent","position":[1000,1060],"parameters":{"text":"=\nUse the incoming EDI files and generate Tax and Surcharges Report by going through each file, listing the tax surcharge report for each PNR and the passenger data. \n {{ $json.data }}","options":{"systemMessage":"##Role##\nYou are an Accounting and Finance Reporting Expert and you understand the incoming EDI file from which you extract data and compile Tax and Surcharges Report\n\nInstruction:\nRead the incoming EDI file and identify the accounting info and generate accounting receivable report. \nIf there are data that you don't understand, query the pinecone vector database where the complete guidelines is stored for the undersatnding. \nOutput just the table with the data. No need to give a dscription in the begining. \n\nGenerate report in the below tabular format that is extractable in JSON format: \n\n [\n    {\"taxType\": \"JD\", \"amount\": 23.84}\n  ]\n\nNote:\nNever ever create your own Tax report if in doubt or missing data.\n"},"promptType":"define","hasOutputParser":true},"typeVersion":1.9}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"c9cacda3-eb77-4755-a95b-fd7f97615d4d","connections":{"Google Drive":{"main":[[{"node":"Google Drive1","type":"main","index":0}]]},"Google Drive1":{"main":[[{"node":"Pinecone Vector Store1","type":"main","index":0}]]},"Embeddings OpenAI":{"ai_embedding":[[{"node":"Pinecone Vector Store","type":"ai_embedding","index":0}]]},"Extract from File":{"main":[[{"node":"Account Receivable Agent","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Account Receivable Agent","type":"ai_languageModel","index":0}]]},"Embeddings OpenAI1":{"ai_embedding":[[{"node":"Pinecone Vector Store1","type":"ai_embedding","index":0}]]},"Embeddings OpenAI2":{"ai_embedding":[[{"node":"Pinecone Vector Store2","type":"ai_embedding","index":0}]]},"OpenAI Chat Model1":{"ai_languageModel":[[{"node":"Tax and Surcharges Report","type":"ai_languageModel","index":0}]]},"Default Data Loader1":{"ai_document":[[{"node":"Pinecone Vector Store1","type":"ai_document","index":0}]]},"Pinecone Vector Store":{"ai_tool":[[{"node":"Account Receivable Agent","type":"ai_tool","index":0}]]},"Pinecone Vector Store1":{"main":[[]]},"Pinecone Vector Store2":{"ai_tool":[[{"node":"Tax and Surcharges Report","type":"ai_tool","index":0}]]},"Account Receivable Agent":{"main":[[]]},"Google Drive: extract files":{"main":[[{"node":"Google Drive: download file contents","type":"main","index":0}]]},"When clicking ‘Test workflow’":{"main":[[{"node":"Google Drive: extract files","type":"main","index":0}]]},"Recursive Character Text Splitter1":{"ai_textSplitter":[[{"node":"Default Data Loader1","type":"ai_textSplitter","index":0}]]},"Google Drive: download file contents":{"main":[[{"node":"Extract from File","type":"main","index":0}]]}}}


name: Manage GoHighLevel CRM with Conversational AI Assistant and GPT-4o
author_name: Adam Crafts
author_username: adamcrafts
categories: []
created_at: 2025-06-22T19:08:36.160Z
updated_at: 2025-06-22T19:08:36.160Z
url: https://n8n.io/workflows/5131
scraped_at: 2025-07-06 21:16:30
description:
  🌟 Your Conversational GoHighLevel CRM Assistant: Instantly manage contacts, deals, and tasks in GoHighLevel using simple chat commands.

  🚀 Overview

  This automation sets up an intelligent AI assistant directly connected to your GoHighLevel CRM. Instead of clicking through menus and forms, you can now manage your entire sales pipeline through a simple chat conversation. It's like having a dedicated, 24/7 sales operations expert on your team, ready to act on your commands instantly.

  😩 The Problem

  Managing a powerful CRM like GoHighLevel is essential, but it can be incredibly time-consuming. You're constantly jumping between screens to add a new contact after a call, update a deal's status, create a follow-up task, or check calendar availability. Each small action requires navigating different menus, filling out multiple fields, and saving your work. This constant context-switching kills productivity, creates opportunities for human error, and slows down your entire sales cycle.

  ✨ The Solution

  This workflow acts as your personal "automated employee," transforming your GoHighLevel experience by giving you an AI-powered conversational assistant. Now, you can simply tell the AI what you need in plain English, and it gets done.

  When you send a message like, "Create a new contact for John Doe at john@email.com" the automation instantly captures the information and creates the contact. Ask it to "Find all open deals for ABC Corp" and it will search your pipeline. Need to schedule a follow-up? Just say "Create a task to call John Doe next Tuesday." 📅 This assistant handles everything from contact creation and opportunity management to task setting and appointment booking, turning tedious CRM admin into a fast and simple conversation.

  ⚙️ Simple Setup

  This workflow is a pre-built blueprint, designed to be up and running in minutes!

  Upload:** Simply upload the provided JSON file into your n8n instance.
  Connect:** Connect your app credentials (e.g., your GoHighLevel and OpenAI accounts). The workflow will show you exactly where.
  Activate:** Turn the workflow on, and it's ready to go! Let your new automated employee get to work.

  🌐 Explore more workflows
  ❤️ Buy more workflows at: adamcrafts
  🦾 Custom workflows at: adamcrafts@cloudysoftwares.com
  adamaicrafts@gmail.com


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

nodes_used:
[cell repeats an earlier one in this file: 120 characters]

workflow_json:
  {"meta":{"instanceId":"2d54f61dfd963457efb86a8690aae457934e92fb9e4b8b6490ca74fc37094458","templateCredsSetupCompleted":true},"nodes":[{"id":"5b13ce35-0fb0-4966-8e97-23b8d7099a39","name":"Conversation Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[180,-920],"parameters":{},"typeVersion":1},{"id":"eed9e953-f1c8-41a5-aa3e-701ca91a63c3","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[100,-760],"parameters":{"content":""},"typeVersion":1},{"id":"0a3694c5-cc83-4825-b2b7-2e60a6ea4a18","name":"Get Contact Tool","type":"n8n-nodes-base.highLevelTool","position":[200,-160],"parameters":{},"typeVersion":2},{"id":"0757b6fa-cd02-40b6-93ad-7f53e5f16719","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[780,-300],"parameters":{"content":""},"typeVersion":1},{"id":"80760105-2936-4bfd-9c26-231a01294fad","name":"Update Opportunity Tool","type":"n8n-nodes-base.highLevelTool","position":[820,-480],"parameters":{},"typeVersion":2},{"id":"d34c42d6-38d8-43dc-bcf8-4ba342fcc177","name":"Get Opportunities Tool","type":"n8n-nodes-base.highLevelTool","position":[980,-480],"parameters":{},"typeVersion":2},{"id":"9db24d83-a0da-47f4-8127-4eb4b0ee130f","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1820,-1000],"parameters":{"content":""},"typeVersion":1},{"id":"21a2f55a-53d8-4532-bc16-d6af07791060","name":"Get Opportunitiy Tool","type":"n8n-nodes-base.highLevelTool","position":[1120,-480],"parameters":{},"typeVersion":2},{"id":"42ac7d13-d554-4ecd-9b26-442321c8ce9e","name":"Update Contact Tool","type":"n8n-nodes-base.highLevelTool","position":[200,-480],"parameters":{},"typeVersion":2},{"id":"44acc2eb-f0b3-4aba-806a-1436522a0795","name":"Create Contact Tool","type":"n8n-nodes-base.highLevelTool","position":[200,-640],"parameters":{},"typeVersion":2,"alwaysOutputData":false},{"id":"079aaf13-f159-4bea-8272-f557f42b1539","name":"Get Contacts Tool","type":"n8n-nodes-base.highLevelTool","position":[200,-320],"parameters":{},"typeVersion":2},{"id":"d40fcf37-72db-479e-962b-a0f55304957c","name":"Create Opportunity Tool","type":"n8n-nodes-base.highLevelTool","position":[660,-480],"parameters":{},"typeVersion":2},{"id":"47470e9c-3b6a-4bcf-b3c1-8c4d886fa1ca","name":"Get Task Tool","type":"n8n-nodes-base.highLevelTool","position":[1920,-380],"parameters":{},"typeVersion":2},{"id":"6bec14e0-125d-495f-adfa-3b69a7106a80","name":"Get Tasks Tool","type":"n8n-nodes-base.highLevelTool","position":[1920,-560],"parameters":{},"typeVersion":2},{"id":"ae15dbc2-ece8-4b87-8485-ae20082adfc3","name":"Update Task Tool","type":"n8n-nodes-base.highLevelTool","position":[1920,-720],"parameters":{},"typeVersion":2},{"id":"f3256cbe-02e2-4905-86ed-e9f2df4cf764","name":"Create Task Tool","type":"n8n-nodes-base.highLevelTool","position":[1920,-880],"parameters":{},"typeVersion":2},{"id":"228093a7-1bd8-4ec8-a1b6-98163ba09c1a","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[1320,-240],"parameters":{"content":""},"typeVersion":1},{"id":"7eb4f106-d117-40ad-86be-dfeec480fba9","name":"Book appointment Calendar Tool","type":"n8n-nodes-base.highLevelTool","position":[1360,-400],"parameters":{},"typeVersion":2},{"id":"0e84e5cc-7c68-4701-b063-bee71f031505","name":"Get Free Slots Calendar Tool","type":"n8n-nodes-base.highLevelTool","position":[1520,-400],"parameters":{},"typeVersion":2},{"id":"58337958-45be-4894-9e7a-667a488fe368","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[-120,-1100],"webhookId":"137c5e36-fef8-4487-85b2-2e15d351172a","parameters":{},"typeVersion":1.1},{"id":"b049019f-15cb-416f-815a-e96f914aebb6","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[340,-1100],"parameters":{},"typeVersion":2},{"id":"373e322d-ad2b-4072-9e1b-7ec47950ddc4","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[40,-920],"parameters":{},"typeVersion":1.2},{"id":"201697f8-f358-4843-8503-34bf12cab5ee","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[-700,-1120],"parameters":{"content":""},"typeVersion":1}],"connections":{"Get Task Tool":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Get Tasks Tool":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Create Task Tool":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Get Contact Tool":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Update Task Tool":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Get Contacts Tool":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Conversation Memory":{"ai_memory":[[{"node":"AI Agent","type":"ai_memory","index":0}]]},"Create Contact Tool":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Update Contact Tool":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Get Opportunitiy Tool":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Get Opportunities Tool":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Create Opportunity Tool":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Update Opportunity Tool":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"When chat message received":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Get Free Slots Calendar Tool":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Book appointment Calendar Tool":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]}}}


name: Smart Lead Outreach with Explorium MCP Using Google Sheets and Telegram
author_name: David Olusola
author_username: dae221
categories: []
created_at: 2025-06-22T21:30:08.367Z
updated_at: 2025-06-22T21:30:08.367Z
url: https://n8n.io/workflows/5133
scraped_at: 2025-07-06 21:16:30
description:
  🚀 Smart Outreach: Auto-Personalized Lead Sequences

  🧠 What It Does

  This n8n workflow turns your Telegram bot into an AI-powered B2B lead enrichment and outreach engine.

  It uses Explorium MCP's premium business data, combined with GPT-4 intelligence, to deliver:

  Enriched lead profiles (person or company)
  AI-personalized 4-step cold email sequences
  Real-time interaction via Telegram
  Google Sheets logging for CRM or follow-up
  🖥️ Demo: https://www.loom.com/share/4c2ae62154d74b66b4a59a6926282fab
  🔄 How It Works

  Telegram Input
  Users message a company or person’s name to your Telegram bot.

  GPT-4 AI Agent Analyzes the Request
  Determines if input is a person or company
  Starts the enrichment process
  Explorium MCP Client Fetches B2B Data
  Pulls from enterprise-grade business databases
  Finds company size, revenue, funding, contact names, tech stack, and more
  Augments with Tavily search where needed
  Smart Data Processor
  Structures the info
  Classifies it
  Adds enrichment and processing timestamps
  GPT-4 Generates Email Sequence
  4-email cold outreach campaign
  Personalized based on enriched profile
  Professional tone with soft CTA and clear value
  Google Sheets Logging
  People Sheet: name, role, LinkedIn, experience, education, skills
  Companies Sheet: size, HQ, tech stack, funding, lead score, outreach emails
  Telegram Responds in Real-Time
  Sends back structured summary
  Clean JSON or readable text
  🧰 Requirements

  To run this workflow, you’ll need:

  ✅ Telegram Bot (via BotFather)
  ✅ OpenAI API Key (GPT-4 or GPT-4o)
  ✅ Explorium MCP credentials (for B2B enrichment)
  ✅ Tavily API key (for supplemental web results)
  ✅ Google Sheets account (OAuth2 connected to n8n)

  ⚙️ Setup Instructions

  Import the Template into n8n
  Use the JSON file to create a new workflow.
  Configure Telegram Trigger
  Set up your bot via BotFather
  Connect your Telegram API credentials in n8n
  Connect External APIs
  Set up Explorium MCP credentials (via header auth)
  Add Tavily and OpenAI credentials in their respective nodes
  Replace Google Sheets Links
  Update documentId and sheetName to point to your target Sheets
  Customize (Optional)
  Tweak prompt logic, email tone, or data mapping
  Add Slack alerts or CRM pushes
  Test the Flow
  DM a name or company to your Telegram bot
  Wait a few seconds for a full enriched reply + email sequence
  📥 Output Includes:

  Full structured profile in JSON format
  4 cold outreach emails tailored to the lead
  Stored copy in Google Sheets for sales or follow-up
  💼 Who This Is For:

  SDRs & Sales Teams
  AI/Marketing Agencies
  Growth Hackers
  Founders doing outbound manually

nodes_used:
  ["n8n-nodes-base.googleSheets","n8n-nodes-base.telegram","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.lmChatGoogleGemini","@n8n/n8n-nodes-langchain.memoryPostgresChat","@n8n/n8n-nodes-langchain.mcpClientTool"]

workflow_json:
  {"id":"QJxM3oTiPoFiRO9Y","meta":{"instanceId":"2000c64071c20843606b95c63795bb0797c41036047055a6586498e855b96efc"},"name":"Smart Lead Outreach with Explorium MCP Using Google Sheets and Telegram1","tags":[],"nodes":[{"id":"8220566c-d068-4da5-af75-1b3f946a2e97","name":"Telegram Trigger","type":"n8n-nodes-base.telegramTrigger","position":[1580,200],"webhookId":"19045114-ade9-4c43-9beb-64a226b7d297","parameters":{},"typeVersion":1.2},{"id":"2a50c70c-6537-498f-ad4c-6a232cd5225e","name":"Enhanced AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[1880,200],"parameters":{},"typeVersion":2},{"id":"0e31696b-7236-4809-a8b6-0939690520dc","name":"OpenAI GPT-4","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[2380,560],"parameters":{},"typeVersion":1.2},{"id":"1f232c08-9eef-458e-a45d-48d16ba1766a","name":"Postgres Memory","type":"@n8n/n8n-nodes-langchain.memoryPostgresChat","position":[2320,660],"parameters":{},"typeVersion":1.3},{"id":"38c484f5-8ad7-4ee9-a89e-b6499ea16498","name":"Explorium MCP Client","type":"@n8n/n8n-nodes-langchain.mcpClientTool","position":[1560,700],"parameters":{},"typeVersion":1},{"id":"a76e0f45-8501-4594-ab40-fd84a13adda2","name":"Enhanced Tavily Search","type":"n8n-nodes-base.httpRequestTool","position":[1760,680],"parameters":{},"typeVersion":4.2},{"id":"988248fa-cb4b-4228-be8a-35c2a2b2d6fc","name":"Smart Data Processor","type":"n8n-nodes-base.code","position":[2360,200],"parameters":{},"typeVersion":2},{"id":"4498b8d4-d348-4789-af18-d096831eda8b","name":"Telegram Response","type":"n8n-nodes-base.telegram","position":[2820,140],"webhookId":"b673900a-8b35-4e7c-a662-c5ebef2c6ca5","parameters":{},"typeVersion":1.2},{"id":"d928e6f9-3bc0-497a-9f30-47690aaeb0d9","name":"Lead Data Filter","type":"n8n-nodes-base.if","position":[2560,1180],"parameters":{},"typeVersion":2},{"id":"0d79f485-6c48-45d7-8be3-a6571f8cd12c","name":"Person/Company Split","type":"n8n-nodes-base.if","position":[2800,1160],"parameters":{},"typeVersion":2},{"id":"e3977ba4-974d-45aa-9551-3bb3540145e0","name":"Save Person Data","type":"n8n-nodes-base.googleSheets","position":[4040,1160],"parameters":{},"typeVersion":4.6},{"id":"0038c8cd-a10c-462c-8ede-aacf5a7c9e1b","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[200,-120],"parameters":{"content":""},"typeVersion":1},{"id":"776b4d30-33ec-4772-972b-0a279aaafa09","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[2220,-40],"parameters":{"content":""},"typeVersion":1},{"id":"128889b1-899d-40c3-a35f-52b669591db9","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[1440,-40],"parameters":{"content":""},"typeVersion":1},{"id":"4393728c-7a77-4a6e-856c-3f5a2db7698d","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1800,-40],"parameters":{"content":""},"typeVersion":1},{"id":"55d249fe-e7bf-487c-8956-7f7d0e73598b","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[1480,380],"parameters":{"content":""},"typeVersion":1},{"id":"905b4aa3-eb93-4860-99af-d8f6ac8ad4b0","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[2520,360],"parameters":{"content":""},"typeVersion":1},{"id":"6ec63191-bc63-4e4e-b38b-3741ddd96d2d","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[3000,1140],"parameters":{},"typeVersion":2},{"id":"abb2ccfe-e0d9-4672-ae3c-fff00892c8b9","name":"Google Gemini Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[2900,1340],"parameters":{},"typeVersion":1},{"id":"da26b1fe-a135-4729-a195-25ab8de7ecbd","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[2680,-20],"parameters":{"content":""},"typeVersion":1},{"id":"499121cf-5d7e-429e-a8b2-797f371e68bd","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[2040,460],"parameters":{"content":""},"typeVersion":1},{"id":"e24d339f-70e6-4f4e-be6c-c85b3d975808","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[3600,1120],"parameters":{"content":""},"typeVersion":1},{"id":"b9ed567b-6057-4377-b197-d3d60a6fb338","name":"Code","type":"n8n-nodes-base.code","position":[3360,1140],"parameters":{},"typeVersion":2}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"e3732194-a037-4234-9baa-021aa2d8f202","connections":{"Code":{"main":[[{"node":"Save Person Data","type":"main","index":0}]]},"AI Agent":{"main":[[{"node":"Code","type":"main","index":0}]]},"OpenAI GPT-4":{"ai_languageModel":[[{"node":"Enhanced AI Agent","type":"ai_languageModel","index":0}]]},"Postgres Memory":{"ai_memory":[[{"node":"Enhanced AI Agent","type":"ai_memory","index":0}]]},"Lead Data Filter":{"main":[[{"node":"Person/Company Split","type":"main","index":0}]]},"Telegram Trigger":{"main":[[{"node":"Enhanced AI Agent","type":"main","index":0}]]},"Enhanced AI Agent":{"main":[[{"node":"Smart Data Processor","type":"main","index":0}]]},"Explorium MCP Client":{"ai_tool":[[{"node":"Enhanced AI Agent","type":"ai_tool","index":0}]]},"Person/Company Split":{"main":[[{"node":"AI Agent","type":"main","index":0}],[{"node":"AI Agent","type":"main","index":0}]]},"Smart Data Processor":{"main":[[{"node":"Telegram Response","type":"main","index":0},{"node":"Lead Data Filter","type":"main","index":0}]]},"Enhanced Tavily Search":{"ai_tool":[[{"node":"Enhanced AI Agent","type":"ai_tool","index":0}]]},"Google Gemini Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]}}}


name: Multi-Channel Customer Support Automation Suite
author_name: Elie Kattar
author_username: solutionflows
nodes_used: ["n8n-nodes-base.emailSend","n8n-nodes-base.httpRequest","n8n-nodes-base.slack"]
categories: []
created_at: 2025-06-22T22:08:29.964Z
updated_at: 2025-06-22T22:08:29.964Z
url: https://n8n.io/workflows/5135
scraped_at: 2025-07-06 21:16:30
description:
  Multi-Channel Customer Support Automation Suite

  Transform your customer support operations with this enterprise-grade automation workflow that unifies, categorizes, and intelligently routes support tickets from multiple channels.

  🎯 Overview

  This comprehensive n8n workflow automates your entire customer support pipeline, reducing response times by up to 80% while ensuring no customer inquiry goes unnoticed. It seamlessly integrates email, web forms, and webhooks into a single, intelligent support system that works 24/7.

  💡 Key Benefits

  Unified Inbox**: Consolidate support requests from email, web forms, chat, and social media into one streamlined workflow
  Instant Response**: Automatically acknowledge tickets with intelligent, category-specific responses within seconds
  Smart Routing**: Use AI-powered categorization to route tickets to the right team instantly
  Priority Detection**: Automatically identify and escalate urgent issues and VIP customers
  Team Collaboration**: Real-time Slack notifications with color-coded priority alerts
  Zero Setup Hassle**: Pre-configured with industry best practices and ready to deploy

  🚀 Core Features

  Intelligent Ticket Processing
  Automatic categorization into billing, technical, account, feature requests, and complaints
  Sentiment analysis to detect frustrated customers
  Priority assignment based on keywords, customer status, and urgency indicators
  Custom tagging for easy tracking and reporting

  Multi-Channel Integration
  IMAP email monitoring for support inboxes
  Webhook endpoints for web forms and chat widgets
  Expandable architecture for social media channels
  Unified message format regardless of source

  Automated Response System
  Category-specific email templates
  Personalized responses with ticket IDs
  Smart logic to skip auto-responses for urgent/negative cases
  Customizable templates for your brand voice

  Team Notifications & Escalation
  Real-time Slack alerts with full ticket context
  Color-coded priorities (red/urgent, orange/high, green/normal)
  One-click actions to view or claim tickets
  Automatic escalation rules for time-sensitive issues

  CRM & Analytics Ready
  Pre-configured for major CRM systems (Zendesk, HubSpot, Salesforce)
  Comprehensive logging for performance metrics
  Error handling with admin notifications
  Built-in success/failure tracking

  📊 Use Cases

  SaaS Companies: Handle subscription issues, technical bugs, and feature requests with specialized routing to product, engineering, and billing teams.

  E-commerce: Manage order inquiries, shipping issues, and returns while maintaining high customer satisfaction scores.

  Agencies: Provide white-label support services with customizable branding and client-specific routing rules.

  Startups: Scale support operations without hiring additional staff by automating 70% of routine inquiries.

  🛠️ Technical Specifications

  Channels Supported**: Email (IMAP), Web Forms, Webhooks, expandable to social media
  Response Time**: &lt; 2 seconds for auto-responses
  Categorization Accuracy**: 85%+ with keyword matching, 95%+ with AI enhancement
  Scalability**: Handles 1,000+ tickets/day on standard n8n infrastructure
  Integration Ready**: Slack, all major CRMs, SMTP, custom APIs

  💰 ROI & Impact

  Typical results from implementing this workflow:
  80% reduction** in first response time
  60% decrease** in ticket handling time
  40% of tickets** resolved automatically
  95% customer satisfaction** for auto-responded tickets
  Save 20+ hours/week** of manual ticket sorting

  🎁 What's Included

  Complete n8n workflow JSON (ready to import)
  5 pre-configured auto-response templates
  Intelligent categorization rules for common support scenarios
  Priority detection algorithms
  Slack notification formatting
  Error handling and recovery logic
  Setup documentation and customization guide

  🔧 Requirements

  n8n instance (self-hosted or cloud)
  Email account with IMAP/SMTP access
  Slack workspace (for notifications)
  CRM system (optional but recommended)

  🚦 Quick Setup

  Import the workflow JSON
  Configure email and Slack credentials
  Customize auto-response templates
  Connect your CRM
  Go live in under 30 minutes

  Perfect for businesses handling 50-5,000 support tickets monthly who want to deliver exceptional customer service while reducing operational costs.

workflow_json:
  {"id":"OUvCtjVgtro3MT2J","meta":{"instanceId":"0d1aac533628b88b03392640352a107d7fb2b1999c77dfa29323f9815e9d2e71"},"name":"My workflow 3","tags":[],"nodes":[{"id":"2b5c3f5d-bf7d-41be-bae2-c5785add0f07","name":"Email Trigger","type":"n8n-nodes-base.emailReadImap","position":[220,240],"parameters":{"options":{"customEmailConfig":"=[\"UNSEEN\"]"},"postProcessAction":"nothing"},"typeVersion":2},{"id":"fcccc1d7-e4d6-4f40-87bf-3eebd058a62d","name":"Web Form Webhook","type":"n8n-nodes-base.webhook","position":[220,440],"webhookId":"support-form-webhook","parameters":{"path":"support-ticket","options":{},"httpMethod":"POST","responseMode":"responseNode"},"typeVersion":1},{"id":"526cdbed-260d-46e5-b47d-497a4ea1c8d8","name":"Normalize Messages","type":"n8n-nodes-base.function","position":[600,340],"parameters":{"functionCode":"// Normalize incoming messages from different channels\nconst items = [];\n\nfor (const item of $input.all()) {\n  const source = item.json;\n  \n  let normalizedTicket = {\n    id: 'TKT-' + Date.now() + '-' + Math.random().toString(36).substr(2, 5),\n    timestamp: new Date().toISOString(),\n    channel: '',\n    customer: {\n      name: '',\n      email: '',\n      id: ''\n    },\n    message: {\n      subject: '',\n      body: '',\n      attachments: []\n    },\n    metadata: {},\n    sourceData: source\n  };\n\n  // Check if this is from Email Trigger\n  if (source.from && source.subject) {\n    normalizedTicket.channel = 'email';\n    normalizedTicket.customer.email = source.from.value?.[0]?.address || source.from;\n    normalizedTicket.customer.name = source.from.value?.[0]?.name || 'Email Customer';\n    normalizedTicket.message.subject = source.subject;\n    normalizedTicket.message.body = source.text || source.html || '';\n    if (source.attachments) {\n      normalizedTicket.message.attachments = source.attachments.map(att => ({\n        filename: att.filename,\n        size: att.size\n      }));\n    }\n  }\n  // Check if this is from Web Form\n  else if (source.body && (source.body.email || source.body.name)) {\n    normalizedTicket.channel = 'webform';\n    normalizedTicket.customer.name = source.body.name || 'Web Form User';\n    normalizedTicket.customer.email = source.body.email || '';\n    normalizedTicket.message.subject = source.body.subject || 'Web Form Submission';\n    normalizedTicket.message.body = source.body.message || source.body.description || '';\n  }\n  // Generic webhook data\n  else {\n    normalizedTicket.channel = 'webhook';\n    normalizedTicket.customer.name = source.name || source.customerName || 'Unknown';\n    normalizedTicket.customer.email = source.email || source.customerEmail || '';\n    normalizedTicket.message.subject = source.subject || 'Support Request';\n    normalizedTicket.message.body = source.message || source.body || JSON.stringify(source);\n  }\n\n  items.push({\n    json: normalizedTicket\n  });\n}\n\nreturn items;"},"typeVersion":1},{"id":"0aef988c-3364-4a9a-bbef-e2156febe585","name":"Categorize & Prioritize","type":"n8n-nodes-base.function","position":[800,340],"parameters":{"functionCode":"// Categorize and prioritize tickets based on content\nconst items = [];\n\nfor (const item of $input.all()) {\n  const ticket = item.json;\n  const message = (ticket.message.body + ' ' + ticket.message.subject).toLowerCase();\n  \n  let category = 'general';\n  let priority = 'medium';\n  let tags = [];\n  let sentiment = 'neutral';\n  \n  // Category detection rules\n  const categoryRules = {\n    'billing': ['invoice', 'payment', 'charge', 'refund', 'subscription', 'cancel', 'upgrade', 'downgrade', 'pricing', 'cost', 'bill'],\n    'technical': ['bug', 'error', 'broken', 'not working', 'crash', 'slow', 'issue', 'problem', 'fix', '500', '404', 'loading'],\n    'account': ['password', 'login', 'access', 'account', 'email', 'username', '2fa', 'locked', 'forgot', 'reset', 'sign in'],\n    'feature': ['feature', 'request', 'suggestion', 'improvement', 'add', 'would be nice', 'enhancement', 'idea'],\n    'complaint': ['terrible', 'awful', 'worst', 'hate', 'angry', 'frustrated', 'disappointed', 'unacceptable', 'ridiculous']\n  };\n  \n  // Check categories\n  for (const [cat, keywords] of Object.entries(categoryRules)) {\n    if (keywords.some(keyword => message.includes(keyword))) {\n      category = cat;\n      tags.push(cat);\n      break;\n    }\n  }\n  \n  // Sentiment analysis (simplified)\n  const negativeWords = ['not working', 'broken', 'error', 'angry', 'frustrated', 'terrible', 'awful', 'worst', 'hate', 'disappointed', 'unacceptable'];\n  const positiveWords = ['thank', 'great', 'excellent', 'love', 'amazing', 'fantastic', 'wonderful', 'perfect'];\n  const urgentWords = ['urgent', 'asap', 'emergency', 'critical', 'immediately', 'now', 'quickly'];\n  \n  const negativeCount = negativeWords.filter(word => message.includes(word)).length;\n  const positiveCount = positiveWords.filter(word => message.includes(word)).length;\n  \n  if (negativeCount > positiveCount + 1) {\n    sentiment = 'negative';\n    tags.push('negative_sentiment');\n  } else if (positiveCount > negativeCount + 1) {\n    sentiment = 'positive';\n    tags.push('positive_sentiment');\n  }\n  \n  // Priority rules\n  if (urgentWords.some(word => message.includes(word))) {\n    priority = 'urgent';\n    tags.push('urgent');\n  } else if (category === 'complaint' || sentiment === 'negative') {\n    priority = 'high';\n  } else if (category === 'billing' || category === 'account') {\n    priority = 'high';\n  }\n  \n  // Check for VIP customers (you can add your VIP domains here)\n  const vipDomains = ['enterprise.com', 'vip.com', 'premium.com'];\n  if (ticket.customer.email && vipDomains.some(domain => ticket.customer.email.includes(domain))) {\n    priority = priority === 'medium' ? 'high' : priority;\n    tags.push('vip_customer');\n  }\n  \n  items.push({\n    json: {\n      ...ticket,\n      category,\n      priority,\n      tags,\n      sentiment,\n      requiresHumanReview: priority === 'urgent' || sentiment === 'negative',\n      autoResponseEligible: priority !== 'urgent' && sentiment !== 'negative' && category !== 'complaint'\n    }\n  });\n}\n\nreturn items;"},"typeVersion":1},{"id":"d0186a2f-34b0-4c68-921f-3050f270dd1a","name":"Check Auto-Response","type":"n8n-nodes-base.if","position":[1000,340],"parameters":{"conditions":{"boolean":[{"value1":"={{$json[\"autoResponseEligible\"]}}","value2":true}]}},"typeVersion":1},{"id":"fa5ecd58-23e9-4194-9bb5-954e6b1b7e05","name":"Generate Auto-Response","type":"n8n-nodes-base.function","position":[1200,240],"parameters":{"functionCode":"// Generate auto-response based on category\nconst items = [];\n\nfor (const item of $input.all()) {\n  const ticket = item.json;\n  \n  const templates = {\n    'billing': {\n      subject: `Re: Your billing inquiry - ${ticket.id}`,\n      body: `Hello ${ticket.customer.name || 'Valued Customer'},\n\nThank you for contacting us about your billing concern. We understand how important this is.\n\nYour ticket (${ticket.id}) has been received and forwarded to our billing department. You can expect a response within 2-4 business hours.\n\nIn the meantime, you might find these resources helpful:\n- Billing FAQ: https://support.yourcompany.com/billing\n- View invoices: https://app.yourcompany.com/billing\n\nBest regards,\nCustomer Support Team`\n    },\n    'technical': {\n      subject: `Re: Technical support request - ${ticket.id}`,\n      body: `Hello ${ticket.customer.name || 'Valued Customer'},\n\nWe've received your technical support request (${ticket.id}).\n\nOur technical team is reviewing your issue. To help us resolve this faster, please ensure you've provided:\n- Description of the issue\n- Steps to reproduce\n- Any error messages\n\nExpected response time: Within 4-6 hours\n\nBest regards,\nTechnical Support Team`\n    },\n    'account': {\n      subject: `Re: Account assistance - ${ticket.id}`,\n      body: `Hello ${ticket.customer.name || 'Valued Customer'},\n\nWe've received your account-related request (${ticket.id}).\n\nFor security reasons, our account specialists will handle this personally. You'll hear from us within 1-2 business hours.\n\nBest regards,\nAccount Security Team`\n    },\n    'feature': {\n      subject: `Re: Feature request received - ${ticket.id}`,\n      body: `Hello ${ticket.customer.name || 'Valued Customer'},\n\nThank you for your feature suggestion! We love hearing from our users.\n\nYour request (${ticket.id}) has been logged and will be reviewed by our product team. We consider all feedback when planning future updates.\n\nBest regards,\nProduct Team`\n    },\n    'general': {\n      subject: `Re: ${ticket.message.subject} - ${ticket.id}`,\n      body: `Hello ${ticket.customer.name || 'Valued Customer'},\n\nThank you for contacting support. We've received your request (${ticket.id}) and our team is reviewing it.\n\nWe'll get back to you within 24 business hours.\n\nBest regards,\nCustomer Support Team`\n    }\n  };\n  \n  const template = templates[ticket.category] || templates['general'];\n  \n  items.push({\n    json: {\n      ...ticket,\n      autoResponse: {\n        to: ticket.customer.email,\n        subject: template.subject,\n        body: template.body,\n        shouldSend: !!ticket.customer.email && ticket.autoResponseEligible\n      }\n    }\n  });\n}\n\nreturn items;"},"typeVersion":1},{"id":"67eeb519-d0d6-44f4-aef6-3897159621fb","name":"Send Auto-Response","type":"n8n-nodes-base.emailSend","position":[1400,240],"webhookId":"69b9ec96-0edd-4747-ab7d-d9e0006b5175","parameters":{"text":"={{$json[\"autoResponse\"][\"body\"]}}","options":{},"subject":"={{$json[\"autoResponse\"][\"subject\"]}}","toEmail":"={{$json[\"autoResponse\"][\"to\"]}}","fromEmail":"support@yourcompany.com"},"typeVersion":2,"continueOnFail":true},{"id":"352f497d-9b66-40c5-8a0a-cfac715db269","name":"Notify Slack","type":"n8n-nodes-base.slack","onError":"continueErrorOutput","position":[1200,440],"webhookId":"d2b03044-781c-477d-bff7-92065a35efd3","parameters":{"text":"=🎫 New {{$json[\"priority\"]}} Priority Ticket","otherOptions":{},"authentication":"oAuth2"},"credentials":{"slackOAuth2Api":{"id":"28iMYDLTDQPtb6Ew","name":"O2 Personal Account"}},"typeVersion":2},{"id":"b6eb4722-5a89-41b0-a865-f2a2ea8851c7","name":"Store in CRM","type":"n8n-nodes-base.function","position":[1400,440],"parameters":{"functionCode":"// Store ticket in database or CRM\n// This is a placeholder - replace with your actual CRM node (Zendesk, HubSpot, etc.)\n\nconst items = [];\n\nfor (const item of $input.all()) {\n  const ticket = item.json;\n  \n  // Example structure for CRM integration\n  const crmTicket = {\n    external_id: ticket.id,\n    subject: ticket.message.subject || `Support Request from ${ticket.channel}`,\n    description: ticket.message.body,\n    priority: ticket.priority,\n    status: 'new',\n    channel: ticket.channel,\n    tags: ticket.tags,\n    custom_fields: {\n      sentiment: ticket.sentiment,\n      category: ticket.category,\n      auto_response_sent: ticket.autoResponseEligible\n    },\n    requester: {\n      name: ticket.customer.name,\n      email: ticket.customer.email\n    },\n    created_at: ticket.timestamp\n  };\n  \n  // In production, you would send this to your CRM API\n  console.log('Would create ticket in CRM:', crmTicket);\n  \n  items.push({\n    json: {\n      ...ticket,\n      crmTicket,\n      stored: true\n    }\n  });\n}\n\nreturn items;"},"typeVersion":1},{"id":"92de134e-ac68-4f99-87a4-d7fcbada6a1f","name":"Log Success","type":"n8n-nodes-base.function","position":[1600,340],"parameters":{"functionCode":"// Log success metrics\nconst items = [];\n\nfor (const item of $input.all()) {\n  const ticket = item.json;\n  \n  const metrics = {\n    timestamp: new Date().toISOString(),\n    ticketId: ticket.id,\n    channel: ticket.channel,\n    category: ticket.category,\n    priority: ticket.priority,\n    sentiment: ticket.sentiment,\n    autoResponseSent: ticket.autoResponseEligible,\n    processingTime: Date.now() - new Date(ticket.timestamp).getTime(),\n    success: true\n  };\n  \n  // Log to console (in production, send to analytics platform)\n  console.log('Ticket processed successfully:', metrics);\n  \n  items.push({ json: metrics });\n}\n\nreturn items;"},"typeVersion":1},{"id":"aec8fd1f-6a51-4f8b-b001-541646619b8a","name":"Error Handler","type":"n8n-nodes-base.function","position":[1400,640],"parameters":{"functionCode":"// Handle errors and log them\nconst error = $json[\"error\"];\nconst originalData = $json[\"originalData\"] || {};\n\nconst errorLog = {\n  timestamp: new Date().toISOString(),\n  workflow: 'customer-support-automation',\n  error: {\n    message: error?.message || 'Unknown error',\n    code: error?.code,\n    node: error?.node\n  },\n  ticketId: originalData.id || 'unknown',\n  channel: originalData.channel || 'unknown',\n  recovery: 'manual_intervention_required'\n};\n\n// In production, send to error tracking service (Sentry, etc.)\nconsole.error('Workflow error:', errorLog);\n\n// Could also send critical errors to Slack\nreturn [{ json: errorLog }];"},"typeVersion":1},{"id":"043ceb80-fe46-4f59-8a31-dffd67144364","name":"Merge","type":"n8n-nodes-base.merge","position":[400,340],"parameters":{},"typeVersion":2},{"id":"fade1855-3973-493d-8d17-841cf1ad1097","name":"Notify Error to Slack","type":"n8n-nodes-base.httpRequest","position":[1600,640],"parameters":{"url":"=https://hooks.slack.com/services/YOUR/WEBHOOK/URL","method":"POST","options":{},"sendBody":true,"bodyParameters":{"parameters":[{"name":"text","value":"=⚠️ Error in support automation: {{$json[\"error\"][\"message\"]}}"}]}},"typeVersion":3,"continueOnFail":true},{"id":"67fa2e0e-c3b8-47ba-807e-46af2720408e","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-300,140],"parameters":{"width":389,"height":464,"content":"## Multi-Channel Customer Support Automation\n\nThis workflow automates customer support across multiple channels.\n\n### Features:\n- 📧 Email support via IMAP\n- 🌐 Web form submissions\n- 🏷️ Automatic categorization\n- 🎯 Smart prioritization\n- 💬 Auto-responses\n- 🔔 Slack notifications\n- 📊 CRM integration ready\n\n### Setup Required:\n1. Configure IMAP credentials\n2. Configure SMTP credentials\n3. Configure Slack credentials\n4. Update webhook URL in error handler\n5. Replace CRM placeholder with your system\n\n### Categories:\n- Billing\n- Technical\n- Account\n- Feature requests\n- General\n\n### Priority Levels:\n- Urgent (immediate attention)\n- High (4 hours)\n- Medium (24 hours)\n- Low (72 hours)"},"typeVersion":1},{"id":"1eb04a7a-6519-4336-9588-f74b6528a6a7","name":"Webhook Response","type":"n8n-nodes-base.respondToWebhook","position":[1800,340],"parameters":{"options":{}},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"d53058f5-8312-4553-913b-45de35c35900","connections":{"Merge":{"main":[[{"node":"Normalize Messages","type":"main","index":0}]]},"Log Success":{"main":[[{"node":"Webhook Response","type":"main","index":0}]]},"Notify Slack":{"main":[[{"node":"Store in CRM","type":"main","index":0}],[{"node":"Error Handler","type":"main","index":0}]]},"Store in CRM":{"main":[[{"node":"Log Success","type":"main","index":0}]]},"Email Trigger":{"main":[[{"node":"Merge","type":"main","index":0}]]},"Error Handler":{"main":[[{"node":"Notify Error to Slack","type":"main","index":0}]]},"Web Form Webhook":{"main":[[{"node":"Merge","type":"main","index":1}]]},"Normalize Messages":{"main":[[{"node":"Categorize & Prioritize","type":"main","index":0}]]},"Send Auto-Response":{"main":[[{"node":"Notify Slack","type":"main","index":0}]]},"Check Auto-Response":{"main":[[{"node":"Generate Auto-Response","type":"main","index":0}],[{"node":"Notify Slack","type":"main","index":0}]]},"Generate Auto-Response":{"main":[[{"node":"Send Auto-Response","type":"main","index":0}]]},"Categorize & Prioritize":{"main":[[{"node":"Check Auto-Response","type":"main","index":0}]]}}}


name: Facebook/Meta Conversion API for eCommerce Leads/Orders
author_name: Omar Akoudad
author_username: mediaplusma
nodes_used: ["n8n-nodes-base.facebookGraphApi","n8n-nodes-base.code"]
categories: []
created_at: 2025-06-23T00:59:02.029Z
updated_at: 2025-06-23T00:59:02.029Z
url: https://n8n.io/workflows/5136
scraped_at: 2025-07-06 21:16:30
description:
  This n8n workflow helps eCommerce businesses (especially in the Cash on Delivery space) send real-time order events to the Meta (Facebook) Conversions API, ensuring accurate event tracking and better ad attribution.

  Features
  Webhook Listener**: Accepts incoming order data (name, phone, IP, user-agent, etc.) via HTTP POST/GET.

  Data Normalization**: Cleans and formats first_name, last_name, phone, and event_time according to Facebook's strict specs.

  Data Hashing**: Securely hashes sensitive user data (SHA256), as required by Meta.

  Full Custom Data Suppor**t: Pass order value, currency, and more.

  Ideal For:
  Shopify, WooCommerce, custom stores (Laravel, Node, etc.)

  Businesses using Meta Ads and needing high-quality server-side tracking

  Teams without access to full dev resources, but using n8n for automation

  How It Works:

  Receive Order from your store via Webhook or API.

  Format & Normalize fields to match Facebook’s expected structure.

  Encrypt Sensitive Fields using SHA256 (name, phone, email).

  Send to Facebook via the Conversions API endpoint.

  Requirements:
  A Meta Business Manager account with Conversions API access

  Your Access Token and Pixel ID set up in n8n credentials

workflow_json:
  {"meta":{"instanceId":"66ce8bb89c7868f862e0d2e755cd17c6a5aea7904e5504a5b2e292e317980443"},"nodes":[{"id":"7fd5ddfd-a858-4a0a-84b8-f8f4ec034d63","name":"Normalize data","type":"n8n-nodes-base.set","position":[-60,0],"parameters":{"include":"except","options":{},"assignments":{"assignments":[{"id":"65d1994d-f4b8-478a-8cf1-490990e6639d","name":"user_data.phone","type":"string","value":"={{$json.user_data.phone.replace(/\\D/g, '').replace(/^0+/, '')}}"},{"id":"5650546d-f0ad-4c69-829c-3e4283e16ac7","name":"event_time","type":"number","value":"={{Math.floor(new Date($json.event_time).getTime() / 1000)}}"},{"id":"9475d631-348f-4d53-9e75-0d568654aeef","name":"user_data.first_name","type":"string","value":"={{$json.user_data.first_name}}"},{"id":"77a8f321-abf9-4618-8fb2-ef5d567a9cd1","name":"user_data.last_name","type":"string","value":"={{$json.user_data.last_name}}"}]},"excludeFields":"user_data.name","includeOtherFields":true},"typeVersion":3.4},{"id":"978d3854-44f6-4773-928e-4536a97a48b1","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-180,-60],"parameters":{"color":7,"width":343,"height":252,"content":"## Data normalization"},"typeVersion":1},{"id":"feb4a686-278f-41d4-ab13-ba4fbc159ef6","name":"Encrypt data","type":"n8n-nodes-base.set","position":[300,0],"parameters":{"options":{},"assignments":{"assignments":[{"id":"097ed7ff-c076-454e-930c-1f4820ac6e2e","name":"user_data.first_name","type":"string","value":"={{ $json.user_data.first_name.hash(\"sha256\") }}"},{"id":"e285fa12-d272-48a0-a583-5e90b394fd74","name":"user_data.last_name","type":"string","value":"={{ $json.user_data.last_name.hash(\"sha256\") }}"},{"id":"1e87a997-5b78-48d8-9616-edfb1b910743","name":"user_data.phone","type":"string","value":"={{ $json.user_data.phone.hash(\"sha256\") }}"}]},"includeOtherFields":true},"typeVersion":3.4},{"id":"1beb8a7c-0bce-489a-aea4-c2acb937601f","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[180,-60],"parameters":{"color":7,"width":343,"height":252,"content":"## Data encryption\n"},"typeVersion":1},{"id":"9f867c8b-fdc1-4294-b56e-12340c604111","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[680,-220],"parameters":{"color":7,"width":375,"height":414,"content":"## Send event\nYou can use a test code from Facebook Events Manager to verify your integration.\n\nAdd your test code to the test_code parameter inside the JSON payload.\n\nOnce everything is confirmed to be working, remove the test_event_code so that events are officially logged.\n\n[**Read more**](https://business.facebook.com/business/help/2040882565969969)"},"typeVersion":1},{"id":"c00c1fac-7550-4fa9-8fc9-e9f250519e6a","name":"Send event to Meta","type":"n8n-nodes-base.facebookGraphApi","position":[820,20],"parameters":{"edge":"events","node":"={{$('Format data').item.json.pixel_id}}","options":{"queryParametersJson":"={\n  \"data\": [\n    {\n      \"event_name\": \"{{ $('Encrypt data').item.json.event_name }}\",\n      \"event_time\": {{ $('Encrypt data').item.json.event_time }},\n      \"event_source_url\": \"{{ $('Encrypt data').item.json.event_source_url }}\",\n      \"action_source\": \"{{ $('Encrypt data').item.json.action_source }}\",\n      \"user_data\": {\n        \"em\": \"{{ $('Encrypt data').item.json.user_data.email }}\",\n        \"ph\": \"{{ $('Encrypt data').item.json.user_data.phone }}\",\n        \"fn\": \"{{ $('Encrypt data').item.json.user_data.first_name }}\",\n        \"ln\": \"{{ $('Encrypt data').item.json.user_data.last_name }}\",\n        \"fbc\": \"{{ $('Encrypt data').item.json.user_data.fbp }}\",\n        \"fbp\": \"{{ $('Encrypt data').item.json.user_data.fbc }}\",\n        \"ip\": \"{{ $('Encrypt data').item.json.user_data.ip }}\",\n        \"user_agent\": \"{{ $('Encrypt data').item.json.user_data.user_agent }}\"\n      },\n      \"custom_data\": {\n        \"value\": {{ $('Encrypt data').item.json.custom_data.value }},\n        \"currency\": \"{{ $('Encrypt data').item.json.custom_data.currency }}\"\n      }\n    }\n  ],\n  \"test_event_code\": \"TEST1337\"\n}\n"},"graphApiVersion":"=v20.0","httpRequestMethod":"POST"},"credentials":{"facebookGraphApi":{"id":"ThsFZDy4veCJfHRP","name":"Meta conversion api (WIJDANPROMO)"}},"typeVersion":1},{"id":"5b486767-1ec1-4829-a556-ddc4f0c13f95","name":"Webhook","type":"n8n-nodes-base.webhook","position":[-1260,-240],"webhookId":"b408defb-315d-4676-b4c4-1dcebe81ffc0","parameters":{"path":"b408defb-315d-4676-b4c4-1dcebe81ffc0","options":{},"httpMethod":["POST","GET"],"multipleMethods":true},"typeVersion":2},{"id":"8a8ee5fb-edf4-410c-b86c-a1b805a66319","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1160,100],"parameters":{"height":220,"content":"## Test data \nYou can chenge test data here"},"typeVersion":1},{"id":"40240bfc-8e7b-4c5b-84e0-b8ccd52b097e","name":"Test data","type":"n8n-nodes-base.code","position":[-1100,180],"parameters":{"jsCode":"return {\n  \"body\": {\n    'first_name': \"Alex\",\n    'last_name': \"Forbic\",\n    'phone': \"+116435562\",\n    'ip': \"16.115.243.190\",\n    'user_agent': \"Mozilla/5.0 (Linux; Android 14; SM-A065F Build/UP1A.231005.007; )\",\n    'fbp': \"fb.1.1750638230973.IwZXh0bgNhZW0BMABhZGlkAasgzcY0SboBHlIpXRPFXRua8Udfs9qnBwf4GN3xGWPk9HvipTCJeUYt8jaENcQyAm_TYaYITPrWtzJcJ8e38-CMQ\",\n    'fbc': \"fb.1.1750612363841.918837434857767253\",\n    'created_at': \"2025-06-18T15:24:06.000000Z\",\n    'amount': 120,\n    'currency': \"EUR\"\n  }\n};"},"notesInFlow":true,"typeVersion":2},{"id":"dbb5d646-4500-4ed9-89b6-607ebfc216d9","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-1620,80],"parameters":{"height":240,"content":"## Test Workflow\nClick this button to test the workflow with fake data \n"},"typeVersion":1},{"id":"8473264d-fbad-4213-a0bf-84e7f841053e","name":"Execute workflow","type":"n8n-nodes-base.manualTrigger","position":[-1540,180],"parameters":{},"typeVersion":1},{"id":"ad465243-cb30-492d-b77c-1066fec33c1b","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-640,-220],"parameters":{"color":7,"width":340,"height":80,"content":"## Change here\n"},"typeVersion":1},{"id":"1b1c1cd5-ecfe-40d2-af82-1b0cc2b65e7c","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-640,-120],"parameters":{"color":7,"width":343,"height":312,"content":"## Collect data\nIn this node you link between your webhook data with this node parameters, also you can add more data."},"typeVersion":1},{"id":"63208dd1-6258-4630-9c3b-c8913cf04085","name":"Format data","type":"n8n-nodes-base.code","position":[-520,0],"parameters":{"jsCode":"return [\n  {\n    json: {\n      event_name: \"Purchase\",\n      pixel_id:'1714041194725552', // you pixel ID\n      user_data: {\n        first_name: $input.first().json.body.first_name, // your customer first_name\n        last_name: $input.first().json.body.last_name, // your customer last_name\n        phone: $input.first().json.body.phone, // your customer phone\n        ip: $input.first().json.body.ip, // your customer IP\n        user_agent: $input.first().json.body.user_agent, // your customer User agent\n        fbp: $input.first().json.body.fbp, // your customer fbp\n        fbc: $input.first().json.body.fbc // your customer fbc\n      },\n      event_time: $input.first().json.body.created_at, // order Date like 2025-06-18T15:24:06.000000Z\n      custom_data: {\n        value: $input.first().json.body.amount, // pricing\n        currency: $input.first().json.body.currency\n      },\n      action_source: \"website\",\n      event_source_url: \"https://example.com/thanks\"\n    }\n  }\n];"},"typeVersion":2},{"id":"81bb1144-9e20-41d2-a611-c5f2422cba09","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[-640,360],"parameters":{"color":4,"width":1700,"height":100,"content":"## Do you need more help or have any suggestions?\nContact me at mediaplus.ma@gmail.com"},"typeVersion":1},{"id":"a959b199-3d42-4a97-9c59-17cfa0b48124","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[-1620,340],"parameters":{"width":700,"height":80,"content":"## Just to test"},"typeVersion":1},{"id":"541e0afe-1fd4-4c5e-a8e9-d7aa6f0e5832","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-1300,-320],"parameters":{"color":4,"width":200,"height":240,"content":"## Production"},"typeVersion":1}],"connections":{"Webhook":{"main":[[{"node":"Format data","type":"main","index":0}]]},"Test data":{"main":[[{"node":"Format data","type":"main","index":0}]]},"Format data":{"main":[[{"node":"Normalize data","type":"main","index":0}]]},"Encrypt data":{"main":[[{"node":"Send event to Meta","type":"main","index":0}]]},"Normalize data":{"main":[[{"node":"Encrypt data","type":"main","index":0}]]},"Execute workflow":{"main":[[{"node":"Test data","type":"main","index":0}]]}}}


name: Extract Facebook Group Posts with Airtop
author_name: Airtop
author_username: cesar-at-airtop
nodes_used: ["n8n-nodes-base.airtop"]
categories: []
created_at: 2025-06-23T05:35:12.640Z
updated_at: 2025-06-23T05:35:12.640Z
url: https://n8n.io/workflows/5138
scraped_at: 2025-07-06 21:16:30
description:
  Extract Facebook Group Posts with Airtop

  Use Case

  Extracting content from Facebook Groups allows community managers, marketers, and researchers to gather insights, monitor discussions, and collect engagement metrics efficiently. This automation streamlines the process of retrieving non-sponsored post data from group feeds.

  What This Automation Does

  This automation extracts key post details from a Facebook Group feed using the following input parameters:

  Facebook Group URL**: The URL of the Facebook Group feed you want to scrape.
  Airtop Profile**: The name of your Airtop Profile authenticated to Facebook.

  It returns up to 5 non-sponsored posts with the following attributes for each:

  Post text
  Post URL
  Page/profile URL
  Timestamp
  Number of likes
  Number of shares
  Number of comments
  Page or profile details
  Post thumbnail

  How It Works

  Form Trigger: Collects the Facebook Group URL and Airtop Profile via a form.
  Browser Automation:

     Initiates a new browser session using Airtop.
     Navigates to the provided Facebook Group feed.
     Uses an AI prompt to extract post data, including interaction metrics and profile information.
  Structured Output: The results are returned in a defined JSON schema, ready for downstream use.

  Setup Requirements

  Airtop API Key — Free to generate.
  An Airtop Profile logged into Facebook.

  Next Steps

  Integrate With Analytics Tools**: Feed the output into dashboards or analytics platforms to monitor community engagement.
  Automate Alerts**: Trigger notifications for posts matching certain criteria (e.g., high engagement, keywords).
  Combine With Comment Automation**: Extend this to reply to posts or engage with users using other Airtop automations.

  Let me know if you’d like this saved as a .md file or included in your Airtop automation library.

  Read more about how to extract posts from Facebook groups

workflow_json:
  {"id":"1LBhz8JFWZgT5cui","meta":{"instanceId":"28a947b92b197fc2524eaba16e57560338657b2b0b5796300b2f1cedc1d0d355","templateCredsSetupCompleted":true},"name":"Facebook Group Scraper","tags":[],"nodes":[{"id":"22789f80-781f-42c4-89c4-ebbf32745a05","name":"On form submission","type":"n8n-nodes-base.formTrigger","position":[0,0],"webhookId":"bf8d7e5f-f886-4586-affa-03c839ce3d70","parameters":{"options":{},"formTitle":"Facebook Group Scraper","formFields":{"values":[{"fieldLabel":"Facebook Group URL","placeholder":"The URL of the Facebook Group feed you want to scrape","requiredField":true},{"fieldLabel":"Airtop Profile","placeholder":"Airtop Profile authenticated to Facebook","requiredField":true}]},"formDescription":"This automation will extract information from a Facebook group"},"typeVersion":2.2},{"id":"31c32d54-5fe3-4125-9e29-029a1c955822","name":"Airtop","type":"n8n-nodes-base.airtop","position":[220,0],"parameters":{"url":"={{ $json['Facebook Group URL'] }}","prompt":"This is a Facebook group feed. \nExtract up to 5 non-sponsored posts, for each post extract:\n - Post text\n- Post URL\n- Page/profile URL\n- Timestamp\t\n- Number of likes \n- Number if shares\n- Number of comments\n- Page or profile details\t\n- Post thumbnail","resource":"extraction","profileName":"={{ $json['Airtop Profile'] }}","sessionMode":"new","additionalFields":{"outputSchema":"{\n  \"type\": \"object\",\n  \"properties\": {\n    \"posts\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"post_text\": {\n            \"type\": \"string\",\n            \"description\": \"The text content of the post.\"\n          },\n          \"post_url\": {\n            \"type\": \"string\",\n            \"description\": \"The URL of the post.\"\n          },\n          \"page_profile_url\": {\n            \"type\": \"string\",\n            \"description\": \"The URL of the page or profile that made the post.\"\n          },\n          \"timestamp\": {\n            \"type\": \"string\",\n            \"description\": \"The timestamp of when the post was made.\"\n          },\n          \"number_of_likes\": {\n            \"type\": \"integer\",\n            \"description\": \"The number of likes the post has received.\"\n          },\n          \"number_of_shares\": {\n            \"type\": \"integer\",\n            \"description\": \"The number of times the post has been shared.\"\n          },\n          \"number_of_comments\": {\n            \"type\": \"integer\",\n            \"description\": \"The number of comments on the post.\"\n          },\n          \"page_profile_details\": {\n            \"type\": \"string\",\n            \"description\": \"Details about the page or profile that made the post.\"\n          },\n          \"post_thumbnail\": {\n            \"type\": \"string\",\n            \"description\": \"The URL of the post's thumbnail image.\"\n          }\n        },\n        \"required\": [\n          \"post_text\",\n          \"post_url\",\n          \"page_profile_url\",\n          \"timestamp\",\n          \"number_of_likes\",\n          \"number_of_shares\",\n          \"number_of_comments\",\n          \"page_profile_details\",\n          \"post_thumbnail\"\n        ],\n        \"additionalProperties\": false\n      }\n    }\n  },\n  \"required\": [\n    \"posts\"\n  ],\n  \"additionalProperties\": false,\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\"\n}","paginationMode":"infinite-scroll","parseJsonOutput":true}},"credentials":{"airtopApi":{"id":"Yi4YPNnovLVUjFn5","name":"Airtop Official Org"}},"typeVersion":1},{"id":"8ada5770-7a77-4e75-8342-f0cad8146e4d","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-980,-680],"parameters":{"color":5,"width":820,"height":1380,"content":"README\n\n# Facebook Group Scraper\n\n## Use Case\n\nExtracting content from Facebook Groups allows community managers, marketers, and researchers to gather insights, monitor discussions, and collect engagement metrics efficiently. This automation streamlines the process of retrieving non-sponsored post data from group feeds.\n\n## What This Automation Does\n\nThis automation extracts key post details from a Facebook Group feed using the following input parameters:\n\n* **Facebook Group URL**: The URL of the Facebook Group feed you want to scrape.\n* **Airtop Profile**: The name of your [Airtop Profile](https://portal.airtop.ai/browser-profiles) authenticated to Facebook.\n\nIt returns up to 5 non-sponsored posts with the following attributes for each:\n\n* Post text\n* Post URL\n* Page/profile URL\n* Timestamp\n* Number of likes\n* Number of shares\n* Number of comments\n* Page or profile details\n* Post thumbnail\n\n## How It Works\n\n1. **Form Trigger**: Collects the Facebook Group URL and Airtop Profile via a form.\n2. **Browser Automation**:\n\n   * Initiates a new browser session using Airtop.\n   * Navigates to the provided Facebook Group feed.\n   * Uses an AI prompt to extract post data, including interaction metrics and profile information.\n3. **Structured Output**: The results are returned in a defined JSON schema, ready for downstream use.\n\n## Setup Requirements\n\n1. [Airtop API Key](https://portal.airtop.ai/api-keys) — Free to generate.\n2. An [Airtop Profile](https://portal.airtop.ai/browser-profiles) logged into Facebook.\n3. An [n8n instance](https://n8n.io/) with the Airtop integration enabled.\n\n## Next Steps\n\n* **Integrate With Analytics Tools**: Feed the output into dashboards or analytics platforms to monitor community engagement.\n* **Automate Alerts**: Trigger notifications for posts matching certain criteria (e.g., high engagement, keywords).\n* **Combine With Comment Automation**: Extend this to reply to posts or engage with users using other Airtop automations.\n\nLet me know if you’d like this saved as a `.md` file or included in your Airtop automation library.\n"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"33402a6d-082e-4fb9-8ad0-90275049a366","connections":{"On form submission":{"main":[[{"node":"Airtop","type":"main","index":0}]]}}}


name: Instagram Reels Automation: Streamlined Content Creation & Publishing
author_name: Iniyavan JC
author_username: netwithjc
categories: []
created_at: 2025-06-23T05:42:27.177Z
updated_at: 2025-06-23T05:42:27.177Z
url: https://n8n.io/workflows/5139
scraped_at: 2025-07-06 21:16:30
description:
  This workflow automates the process of creating and posting Instagram Reels using a combination of Google Drive, AI, Airtable, and the Facebook Graph API. It offers two distinct paths for content creation:

  Scheduled Random Video Selection & Posting
  Randomly Selects from Source Folder: This part of the workflow is triggered based on a schedule. It pulls a random video file from a designated "Random video mover" folder within Google Drive.
  Moves Video to Processing Folder: The selected video is then moved to a dedicated processing folder.
  Manual Upload Trigger & Posting
  File Upload Detection: This part of the workflow watches a specific Google Drive folder ("n8n reels automation on instagram"). When a new video file is uploaded, it triggers the workflow.
  Core Functionality (Applied to Both Paths):
  Downloads Video: Downloads the video file from Google Drive.
  AI-Powered Caption Generation: Leverages an AI model (Google Gemini) to generate an engaging Instagram caption based on the video's file name. The prompt is designed to create concise, attention-grabbing captions with relevant hashtags and a call-to-action.
  Airtable Integration: Stores the generated caption and video details (name, URL) in an Airtable base for tracking and organization.
  Instagram Reels Posting: Uses the Facebook Graph API to create a media container with the video and generated caption. It then waits for a specified duration before publishing the Reel to Instagram.
  Cleanup: Deletes the downloaded video file from your n8n server after successful posting.
  Benefits:
  Saves Time: Automates the repetitive tasks of caption writing and scheduling posts.
  Enhances Engagement: Uses AI to create compelling captions.
  Organized Content: Keeps track of your Reels and captions in Airtable.
  Flexible Trigger Options: Supports both scheduled and manual uploads.
  How to Use:
  Set up Google Drive: Create two folders: one for storing videos intended for random selection ("Random video mover") and one for manual uploads ("n8n reels automation on instagram").
  Configure Airtable: Create an Airtable base with a table containing columns for the video's name, caption, and URL.
  Connect Credentials: Add your Google Drive, Facebook Graph API, Google Gemini API, and Airtable credentials to the appropriate nodes.
  Customize Prompts: Adjust the AI prompt in the "AI Agent" node to better suit your brand voice and target audience.
  Adjust Timings: Modify the "Wait" node durations to control the delay between video processing, caption generation, and publishing.
  Enable Workflow: Activate the workflow to start automating your Instagram Reels creation!

nodes_used:
  ["n8n-nodes-base.airtable","n8n-nodes-base.httpRequest","n8n-nodes-base.googleDrive","n8n-nodes-base.facebookGraphApi","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatGoogleGemini"]

workflow_json:
  {"meta":{"instanceId":"67849de66331aaa2dca6a4f3cbf793b274f923d94e4d9cdaae2e5d9aebaff626","templateCredsSetupCompleted":true},"nodes":[{"id":"e56fcbb9-2ede-4fa0-91b1-565b41e45ec9","name":"Post File Upload in Google Drive Folder  Trigger","type":"n8n-nodes-base.googleDriveTrigger","position":[-860,-640],"parameters":{"event":"fileCreated","options":{},"pollTimes":{"item":[{"mode":"everyX","unit":"minutes","value":1}]},"triggerOn":"specificFolder","folderToWatch":{"__rl":true,"mode":"list","value":"YOUR_FOLDER_ID","cachedResultUrl":"https://drive.google.com/drive/folders/YOUR_FOLDER_ID","cachedResultName":"n8n reels automation on instagram"}},"credentials":{"googleDriveOAuth2Api":{"id":"YOUR_GOOGLE_DRIVE_CREDENTIAL_ID","name":"Google Drive account"}},"typeVersion":1},{"id":"14f7c794-938e-4c19-ba7d-9df7c8db2713","name":"Post File Download in N8N (Google Drive Node)","type":"n8n-nodes-base.googleDrive","position":[-500,-280],"parameters":{"fileId":{"__rl":true,"mode":"id","value":"={{ $json.id }}"},"options":{},"operation":"download"},"credentials":{"googleDriveOAuth2Api":{"id":"YOUR_GOOGLE_DRIVE_CREDENTIAL_ID","name":"Google Drive account"}},"typeVersion":3},{"id":"8edf7ec7-06c5-47f5-8f35-e294af1256df","name":"Google Gemini Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[-420,180],"parameters":{"options":{},"modelName":"models/gemini-2.0-flash-001"},"credentials":{"googlePalmApi":{"id":"YOUR_GOOGLE_GEMINI_CREDENTIAL_ID","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"1f09b5fc-331b-4914-9b2f-598f5a492722","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[-140,-680],"parameters":{"text":"=Generate an engaging Instagram caption for a video titled \"{{ $json.processedFileName }}\".\n\nHere's what to include:\n- 2-3 engaging sentences with appropriate emojis.\n- 3-5 relevant hashtags based on the video title.\n- A clear call-to-action encouraging comments.\n\nPlease keep the total caption under 150 characters.\n\nYou are skilled at writing clear, engaging, and detailed captions based on just a file name. Help viewers understand and appreciate the post. The tone should be relatable and suitable for an Instagram audience. Avoid using too many whimsical words or excessive adjectives. Focus on encouraging people to connect with the post and respond in the comments.","options":{},"promptType":"define"},"typeVersion":2},{"id":"4289ddbe-71f0-49bb-98e8-fbe0899f4ad4","name":"Airtable","type":"n8n-nodes-base.airtable","position":[260,-660],"parameters":{"base":{"__rl":true,"mode":"list","value":"YOUR_AIRTABLE_BASE_ID","cachedResultUrl":"https://airtable.com/YOUR_AIRTABLE_BASE_ID","cachedResultName":"IG reels"},"table":{"__rl":true,"mode":"list","value":"YOUR_AIRTABLE_TABLE_ID","cachedResultUrl":"https://airtable.com/YOUR_AIRTABLE_BASE_ID/YOUR_AIRTABLE_TABLE_ID","cachedResultName":"Table 1"},"columns":{"value":{"URL":"={{ $('Code').item.json.processedWebContentLink }}","Name":"={{ $('Code').item.json.processedFileName }}","Caption":"={{ $json.output }}"},"schema":[{"id":"Name","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Name","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Caption","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Caption","defaultMatch":false,"canBeUsedToMatch":true},{"id":"URL","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"URL","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"create"},"credentials":{"airtableTokenApi":{"id":"YOUR_AIRTABLE_CREDENTIAL_ID","name":"Airtable Personal Access Token account"}},"typeVersion":2.1},{"id":"b7c45adb-ae7e-4497-b261-e37b0437a70c","name":"container","type":"n8n-nodes-base.facebookGraphApi","position":[540,-560],"parameters":{"edge":"media","node":"YOUR_FACEBOOK_PAGE_ID","options":{"queryParameters":{"parameter":[{"name":"video_url","value":"={{ $json.fields.URL }}"},{"name":"media_type","value":"REELS"},{"name":"caption","value":"={{ $('AI Agent').item.json.output }}"}]}},"graphApiVersion":"v22.0","httpRequestMethod":"POST"},"credentials":{"facebookGraphApi":{"id":"YOUR_FACEBOOK_GRAPH_CREDENTIAL_ID","name":"Facebook Graph account"}},"typeVersion":1},{"id":"80ba05f1-127d-4a79-9be7-d05f13287568","name":"Post to IG","type":"n8n-nodes-base.facebookGraphApi","position":[1060,-380],"parameters":{"edge":"media_publish","node":"YOUR_FACEBOOK_PAGE_ID","options":{"queryParameters":{"parameter":[{"name":"creation_id","value":"={{ $json.id }}"}]}},"graphApiVersion":"v22.0","httpRequestMethod":"POST"},"credentials":{"facebookGraphApi":{"id":"YOUR_FACEBOOK_GRAPH_CREDENTIAL_ID","name":"Facebook Graph account"}},"typeVersion":1},{"id":"cdcef117-9334-4683-90a1-cdd6a3608bc8","name":"Google Drive1","type":"n8n-nodes-base.googleDrive","position":[40,120],"parameters":{"fileId":{"__rl":true,"mode":"url","value":"={{ $('Post File Download in N8N (Google Drive Node)').item.json.webViewLink }}"},"options":{},"operation":"deleteFile"},"credentials":{"googleDriveOAuth2Api":{"id":"YOUR_GOOGLE_DRIVE_CREDENTIAL_ID","name":"Google Drive account"}},"typeVersion":3},{"id":"795dcd70-54d4-4e99-9336-0575b2e4fe41","name":"Wait","type":"n8n-nodes-base.wait","position":[780,-460],"webhookId":"YOUR_WEBHOOK_ID","parameters":{"amount":90},"typeVersion":1.1},{"id":"fa82e952-e230-4d3a-9cd2-97bf59747a3d","name":"Wait1","type":"n8n-nodes-base.wait","position":[120,-140],"webhookId":"YOUR_WEBHOOK_ID","parameters":{"amount":20},"typeVersion":1.1},{"id":"57e21bda-91ec-4061-bc9a-1cbb47d4ce74","name":"Code","type":"n8n-nodes-base.code","position":[-320,-380],"parameters":{"jsCode":"// Code (Function) Node Script - Focused on Input Debugging\nconst inputItem = items[0]; // Get the whole item, not just .json yet\n\n// Log the entire incoming item to see its structure, including binary properties if any\nconsole.log(\"Full Input Item to Code Node:\", JSON.stringify(inputItem, null, 2));\n\nconst itemJson = inputItem.json; // Now get the JSON part\n\nlet fileId;\nlet fileName;\nlet webContentLink;\n\nif (typeof itemJson !== 'object' || itemJson === null) {\n    console.error(\"Input item.json is not an object or is null. Input was:\", JSON.stringify(inputItem, null, 2));\n    fileName = \"Unknown Video (Input not an object)\";\n} else {\n    // Try to access properties directly, assuming Google Drive File Resource structure\n    fileId = itemJson.id;\n    fileName = itemJson.name;\n    webContentLink = itemJson.webContentLink || itemJson.webViewLink; // Fallback to webViewLink\n\n    console.log(`Attempting to extract: id='${fileId}', name='${fileName}', webContentLink='${webContentLink}'`);\n\n    if (typeof fileName !== 'string' || fileName.trim() === \"\") {\n        console.warn(\"fileName is missing or invalid in Code Node input. Actual item.json.name was:\", itemJson.name, \". Setting to 'Unknown Video'.\");\n        fileName = \"Unknown Video\";\n    } else {\n        console.log(\"Successfully extracted fileName:\", fileName);\n    }\n\n    if (typeof fileId !== 'string' || fileId.trim() === \"\") {\n        console.warn(\"fileId is missing or invalid.\");\n        // fileId remains as extracted or undefined\n    }\n\n    if (typeof webContentLink !== 'string' || webContentLink.trim() === \"\") {\n        console.warn(\"webContentLink (and webViewLink) is missing or invalid.\");\n        // webContentLink remains as extracted or undefined\n    }\n}\n\nconst outputData = {\n  processedFileId: fileId,\n  processedFileName: fileName,\n  processedWebContentLink: webContentLink\n};\n\nconsole.log(\"Output from Code Node:\", JSON.stringify(outputData, null, 2));\n\n// Return structure expected by n8n\nreturn [{ json: outputData }];"},"typeVersion":2},{"id":"d5a8af48-f6da-46d6-aa9a-9307c426f9c9","name":"HTTP Request","type":"n8n-nodes-base.httpRequest","position":[-1240,-380],"parameters":{"url":"https://www.googleapis.com/drive/v3/files","options":{"response":{"response":{"responseFormat":"json"}}},"sendQuery":true,"authentication":"predefinedCredentialType","queryParameters":{"parameters":[{"name":"q","value":"'YOUR_RANDOM_VIDEO_SOURCE_FOLDER_ID' in parents and mimeType='video/mp4' and trashed=false"},{"name":"fields","value":"files(id, name, mimeType, parents)"},{"name":"supportsAllDrives","value":"true"},{"name":"includeItemsFromAllDrives","value":"true"}]},"nodeCredentialType":"googleOAuth2Api"},"credentials":{"googleOAuth2Api":{"id":"YOUR_GOOGLE_DRIVE_CREDENTIAL_ID","name":"Google account 2"}},"typeVersion":4.2},{"id":"b6b7630c-cf14-4318-9bb8-fc67750805db","name":"HTTP Request1","type":"n8n-nodes-base.httpRequest","position":[-1240,100],"parameters":{"url":"=https://www.googleapis.com/drive/v3/files/{{ $json.id }}","method":"PATCH","options":{"response":{"response":{"responseFormat":"json"}}},"sendQuery":true,"authentication":"predefinedCredentialType","queryParameters":{"parameters":[{"name":"addParents","value":"YOUR_FOLDER_ID"},{"name":"removeParents","value":"YOUR_RANDOM_VIDEO_SOURCE_FOLDER_ID"},{"name":"fields","value":"id,name,parents,webContentLink,webViewLink,mimeType"}]},"nodeCredentialType":"googleOAuth2Api"},"credentials":{"googleOAuth2Api":{"id":"YOUR_GOOGLE_DRIVE_CREDENTIAL_ID","name":"Google account 2"}},"typeVersion":4.2},{"id":"db8fd564-37e0-47f8-81ab-8bac592df96c","name":"Schedule Trigger1","type":"n8n-nodes-base.scheduleTrigger","position":[-1260,-620],"parameters":{"rule":{"interval":[{"field":"hours","hoursInterval":6}]}},"typeVersion":1.2},{"id":"4c78b24d-f9be-4db9-ab8a-8ca064865911","name":"Code1","type":"n8n-nodes-base.code","position":[-1240,-160],"parameters":{"jsCode":"const responseData = items[0].json;\n\nif (!responseData || !responseData.files || responseData.files.length === 0) {\n  console.warn(\"No files found in the source Google Drive folder via API or API response was unexpected.\");\n  return [];\n}\n\nconst filesArray = responseData.files;\nconst randomIndex = Math.floor(Math.random() * filesArray.length);\nconst randomFile = filesArray[randomIndex];\n\nreturn [{ json: randomFile }];"},"typeVersion":2},{"id":"a4d882e1-93bc-4647-8222-0a1a9519e1f0","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-980,-380],"parameters":{"color":5,"width":400,"height":720,"content":"## wait 20 seconds then trigger the insta posting workflow"},"typeVersion":1},{"id":"a75eab91-cb94-42b2-b8aa-491bcaadc2bf","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-1400,-800],"parameters":{"width":420,"height":1140,"content":"## Random file mover\n**For every 100 minutes this path of workflow will select and move a single video file from the G-drive fil named: Random video mover**"},"typeVersion":1},{"id":"ea0150fd-e301-4d4a-aaa7-69124b1aa624","name":"Wait2","type":"n8n-nodes-base.wait","position":[-840,-60],"webhookId":"YOUR_WEBHOOK_ID","parameters":{"amount":20},"typeVersion":1.1},{"id":"50f581c6-f8f1-4967-91a4-2a636eaffb1c","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-980,-800],"parameters":{"color":3,"width":400,"height":420,"content":"## manual upload trigger\n\n**it will trigger the workflow whenever the video file as upload manually on the folder"},"typeVersion":1},{"id":"f312023b-cb76-415c-945b-732b534a6b6e","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-580,-800],"parameters":{"color":4,"width":1880,"height":1140,"content":"## insta uploader"},"typeVersion":1},{"id":"e37c99b4-1393-4978-91e5-84e999f40e2e","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-1520,-880],"parameters":{"color":6,"width":2920,"height":1320,"content":"## Instagram automation workflow....."},"typeVersion":1}],"connections":{"Code":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Wait":{"main":[[{"node":"Post to IG","type":"main","index":0}]]},"Code1":{"main":[[{"node":"HTTP Request1","type":"main","index":0}]]},"Wait1":{"main":[[{"node":"Google Drive1","type":"main","index":0}]]},"Wait2":{"main":[[{"node":"Post File Download in N8N (Google Drive Node)","type":"main","index":0}]]},"AI Agent":{"main":[[{"node":"Airtable","type":"main","index":0}]]},"Airtable":{"main":[[{"node":"container","type":"main","index":0}]]},"container":{"main":[[{"node":"Wait","type":"main","index":0}]]},"Post to IG":{"main":[[{"node":"Wait1","type":"main","index":0}]]},"HTTP Request":{"main":[[{"node":"Code1","type":"main","index":0}]]},"HTTP Request1":{"main":[[{"node":"Wait2","type":"main","index":0}]]},"Schedule Trigger1":{"main":[[{"node":"HTTP Request","type":"main","index":0}]]},"Google Gemini Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Post File Download in N8N (Google Drive Node)":{"main":[[{"node":"Code","type":"main","index":0}]]},"Post File Upload in Google Drive Folder  Trigger":{"main":[[{"node":"Post File Download in N8N (Google Drive Node)","type":"main","index":0}]]}}}


name: Build and Update RAG System with Google Drive, Qdrant, and Gemini Chat
author_name: Davide
author_username: n3witalia
categories: []
created_at: 2025-06-23T08:09:25.952Z
updated_at: 2025-06-23T08:09:25.952Z
url: https://n8n.io/workflows/5140
scraped_at: 2025-07-06 21:16:30
description:
  This workflow automates the creation and management of a Retrieval-Augmented Generation (RAG) system using Qdrant as a vector store and Google Drive as the document source. It enables full or incremental updates to documents in the Qdrant vector database and integrates with a chatbot using Google Gemini for question answering.

  Here is a clear and professional description in English of the n8n workflow “Create a RAG with Qdrant and update single files”, including its benefits:

  Benefits

  Efficient RAG Setup**
    Seamlessly integrates OpenAI, Qdrant, and Google Drive to create a scalable RAG pipeline.

  Single File Update**
    You can replace the vector representation of a single file without reprocessing the entire collection—ideal for maintaining document freshness.

  Flexible File Source**
    Works with Google Drive, allowing document management and updates from a familiar interface.
  How It Works  
  This workflow is designed to create a Retrieval-Augmented Generation (RAG) system using Qdrant as a vector store and Google Drive as a document source. It consists of four main phases:  

  Collection Setup**:  
    Creates or clears a Qdrant collection to store vectorized documents.  
    Configures the collection with cosine distance metrics and other parameters.  

  Document Processing**:  
    Retrieves files from a specified Google Drive folder.  
    Downloads and processes each file (text extraction, chunking, and embedding using OpenAI).  
    Stores the embeddings in Qdrant for vector search.  

  Single-File Update**:  
    Allows updating or deleting a specific file in the Qdrant collection by referencing its Google Drive ID.  
    Re-embeds the file and updates the vector store.  

  RAG Querying**:  
    Uses a chat trigger to receive user questions.  
    Retrieves relevant documents from Qdrant using vector similarity.  
    Generates answers using Google Gemini as the language model.  

  Set Up Steps  

  Configure Qdrant:  
     Replace QDRANTURL and COLLECTION in the "Create collection" and "Clear collection" HTTP nodes.  
     Ensure Qdrant API credentials are correctly set in the credentials section.  

  Google Drive Integration:  
     Specify the Google Drive folder ID in the "Get files" node.  
     Ensure Google Drive OAuth credentials are configured.  

  OpenAI and Gemini Keys:  
     Add OpenAI API credentials for embeddings (used in "Embeddings OpenAI" nodes).  
     Configure Google Gemini credentials for the chat model.  

  Single-File Update:  
     Set the file_id in the "Edit Fields3" node to target a specific Google Drive file for updates.  

  Testing:  
     Trigger the workflow manually to populate the Qdrant collection.  
     Use the chat interface to test RAG responses.  
  Need help customizing?  
  Contact me for consulting and support or add me on Linkedin. 

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.googleDrive","@n8n/n8n-nodes-langchain.chainRetrievalQa","@n8n/n8n-nodes-langchain.embeddingsOpenAi","@n8n/n8n-nodes-langchain.retrieverVectorStore","@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter","@n8n/n8n-nodes-langchain.documentDefaultDataLoader","@n8n/n8n-nodes-langchain.vectorStoreQdrant","@n8n/n8n-nodes-langchain.lmChatGoogleGemini"]

workflow_json:
  {"id":"cN4nA1LigjoreUYv","meta":{"instanceId":"a4bfc93e975ca233ac45ed7c9227d84cf5a2329310525917adaf3312e10d5462","templateCredsSetupCompleted":true},"name":"Enables updates to documents in RAG","tags":[{"id":"oFVn9SpkmyjWZwco","name":"Qdrant","createdAt":"2024-12-04T16:52:58.409Z","updatedAt":"2024-12-04T16:52:58.409Z"}],"nodes":[{"id":"23afa2cc-7085-474f-aa9e-b110ef17208c","name":"When clicking ‘Test workflow’","type":"n8n-nodes-base.manualTrigger","position":[-400,220],"parameters":{},"typeVersion":1},{"id":"71115f33-f461-4942-9df1-e554e6432054","name":"Embeddings OpenAI1","type":"@n8n/n8n-nodes-langchain.embeddingsOpenAi","position":[940,480],"parameters":{"options":{}},"credentials":{"openAiApi":{"id":"4zwP0MSr8zkNvvV9","name":"OpenAi account"}},"typeVersion":1.1},{"id":"81d855d2-a883-4e74-ae2a-1a4e722af4d7","name":"Default Data Loader1","type":"@n8n/n8n-nodes-langchain.documentDefaultDataLoader","position":[1080,480],"parameters":{"options":{"metadata":{"metadataValues":[{"name":"file_id","value":"={{ $('Download files').item.json.id }}"},{"name":"file_name","value":"={{ $('Download files').item.json.name }}"}]}},"dataType":"binary","binaryMode":"specificField"},"typeVersion":1},{"id":"4e5539a5-0f3a-4de9-ba69-0eb7d9c00804","name":"Qdrant Vector Store","type":"@n8n/n8n-nodes-langchain.vectorStoreQdrant","position":[1000,240],"parameters":{"mode":"insert","options":{},"qdrantCollection":{"__rl":true,"mode":"list","value":"negozio-emporio-verde","cachedResultName":"negozio-emporio-verde"}},"credentials":{"qdrantApi":{"id":"iyQ6MQiVaF3VMBmt","name":"QdrantApi account (Hetzner)"}},"typeVersion":1},{"id":"8f944f0e-51a0-470e-9735-1ed539522acb","name":"Create collection","type":"n8n-nodes-base.httpRequest","position":[-140,-200],"parameters":{"url":"http://QDRANTURL/collections/COLLECTION","method":"PUT","options":{},"jsonBody":"{\n  \"vectors\": {\n    \"size\": 1536,\n    \"distance\": \"Cosine\"  \n  },\n  \"shard_number\": 1,  \n  \"replication_factor\": 1,  \n  \"write_consistency_factor\": 1 \n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json"}]}},"credentials":{"httpHeaderAuth":{"id":"qhny6r5ql9wwotpn","name":"Qdrant API (Hetzner)"}},"typeVersion":4.2},{"id":"25c035aa-7a07-47cf-8878-44ac2eab0c3d","name":"Recursive Character Text Splitter","type":"@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter","position":[1060,680],"parameters":{"options":{},"chunkSize":500,"chunkOverlap":50},"typeVersion":1},{"id":"2ade51da-1711-4f71-8bd9-ebd3b6494b0b","name":"Loop Over Items","type":"n8n-nodes-base.splitInBatches","position":[420,220],"parameters":{"options":{}},"typeVersion":3},{"id":"74a224b0-8755-41ef-bb55-22e83b7d762d","name":"Wait","type":"n8n-nodes-base.wait","position":[1380,240],"webhookId":"3d477cc3-8182-43e9-ae61-23e8ce308887","parameters":{},"typeVersion":1.1},{"id":"1c0d5b8c-e53e-47d3-aaac-ddccae80f280","name":"Embeddings OpenAI2","type":"@n8n/n8n-nodes-langchain.embeddingsOpenAi","position":[620,1220],"parameters":{"options":{}},"credentials":{"openAiApi":{"id":"4zwP0MSr8zkNvvV9","name":"OpenAi account"}},"typeVersion":1.1},{"id":"f838f548-52dd-4aaf-aa97-9a8029018a1a","name":"Default Data Loader","type":"@n8n/n8n-nodes-langchain.documentDefaultDataLoader","position":[820,1260],"parameters":{"options":{"metadata":{"metadataValues":[{"name":"file_id","value":"={{ $('Download file').item.json.file_id }}"},{"name":"file_name","value":"={{ $binary.data.fileName}}"}]}},"dataType":"binary","binaryMode":"specificField"},"typeVersion":1},{"id":"07bb3ae1-145f-4784-8409-d3bc73d5522c","name":"Recursive Character Text Splitter1","type":"@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter","position":[860,1460],"parameters":{"options":{},"chunkSize":500,"chunkOverlap":50},"typeVersion":1},{"id":"dfa7b994-13b7-490f-82b7-5ae4ea1e2e7f","name":"Delete single file","type":"n8n-nodes-base.httpRequest","position":[360,720],"parameters":{"url":"http://QDRANTURL/collections/COLLECTION/points/delete","method":"POST","options":{},"jsonBody":"={\n  \"filter\": {\n    \"must\": [\n      {\n          \"key\": \"metadata.file_id\",\n          \"match\": { \"value\": \"{{$json.file_id}}\" }\n        }\n    ]\n  }\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json"}]}},"credentials":{"httpHeaderAuth":{"id":"qhny6r5ql9wwotpn","name":"Qdrant API (Hetzner)"}},"typeVersion":4.2},{"id":"44bf5e40-3947-4288-a7ba-7797ea6ad266","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[140,-280],"parameters":{"color":6,"width":880,"height":220,"content":"# STEP 1\n\n## Create Qdrant Collection\nChange:\n- QDRANTURL\n- COLLECTION"},"typeVersion":1},{"id":"56e6534e-e191-4756-8bcf-d9ff8fc88b5f","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-160,700],"parameters":{"height":360,"content":"# STEP 3\n\n## FILE ID\nSet Google Drive File ID to update\n"},"typeVersion":1},{"id":"f7098791-889a-4e9a-bd8f-f3b52dfc8839","name":"Clear collection","type":"n8n-nodes-base.httpRequest","position":[-140,220],"parameters":{"url":"http://QDRANTURL/collections/COLLECTION/points/delete","method":"POST","options":{},"jsonBody":"{\n  \"filter\": {}\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json"}]}},"credentials":{"httpHeaderAuth":{"id":"qhny6r5ql9wwotpn","name":"Qdrant API (Hetzner)"}},"typeVersion":4.2},{"id":"d75a193e-e0cd-469a-8222-1ff183e2aa83","name":"Get files","type":"n8n-nodes-base.googleDrive","position":[120,220],"parameters":{"filter":{"driveId":{"__rl":true,"mode":"list","value":"My Drive","cachedResultUrl":"https://drive.google.com/drive/my-drive","cachedResultName":"My Drive"},"folderId":{"__rl":true,"mode":"list","value":"1RO5ByPhq2yvYLmbapTNC_kKdU5lZd4W5","cachedResultUrl":"https://drive.google.com/drive/folders/1RO5ByPhq2yvYLmbapTNC_kKdU5lZd4W5","cachedResultName":"Test Negozio"}},"options":{},"resource":"fileFolder"},"credentials":{"googleDriveOAuth2Api":{"id":"HEy5EuZkgPZVEa9w","name":"Google Drive account (n3w.it)"}},"typeVersion":3},{"id":"4e5d5bd2-2aae-4d3b-978e-3ed29b641bb3","name":"Download files","type":"n8n-nodes-base.googleDrive","position":[700,240],"parameters":{"fileId":{"__rl":true,"mode":"id","value":"={{ $json.id }}"},"options":{"googleFileConversion":{"conversion":{"docsToFormat":"text/plain"}}},"operation":"download"},"credentials":{"googleDriveOAuth2Api":{"id":"HEy5EuZkgPZVEa9w","name":"Google Drive account (n3w.it)"}},"typeVersion":3},{"id":"074333a4-fbcc-42ce-aa05-212d545fdcb1","name":"Download file","type":"n8n-nodes-base.googleDrive","position":[360,980],"parameters":{"fileId":{"__rl":true,"mode":"id","value":"={{ $json.file_id }}"},"options":{"googleFileConversion":{"conversion":{"docsToFormat":"text/plain"}}},"operation":"download"},"credentials":{"googleDriveOAuth2Api":{"id":"HEy5EuZkgPZVEa9w","name":"Google Drive account (n3w.it)"}},"typeVersion":3},{"id":"e4ee0aa9-e140-44b9-b581-6d98cb2857a9","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[-560,1600],"webhookId":"97d60090-1717-4195-bf27-2e3c3105b7f8","parameters":{"options":{}},"typeVersion":1.1},{"id":"db644cc4-da46-4e9e-a092-f91762ca1c6b","name":"Question and Answer Chain","type":"@n8n/n8n-nodes-langchain.chainRetrievalQa","position":[-240,1600],"parameters":{"options":{}},"typeVersion":1.5},{"id":"9e7ebe5e-a854-44dc-8cb3-ec1663121b93","name":"Google Gemini Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[-300,1800],"parameters":{"options":{},"modelName":"models/gemini-1.5-flash"},"credentials":{"googlePalmApi":{"id":"0p34rXqIqy8WuoPg","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"d7e29bec-2b8c-400c-b6d7-a82d7a2865a7","name":"Vector Store Retriever","type":"@n8n/n8n-nodes-langchain.retrieverVectorStore","position":[-80,1820],"parameters":{},"typeVersion":1},{"id":"e490e747-5395-4460-bdea-0781145f30b1","name":"Qdrant Vector Store1","type":"@n8n/n8n-nodes-langchain.vectorStoreQdrant","position":[-60,2020],"parameters":{"options":{},"qdrantCollection":{"__rl":true,"mode":"list","value":"ocr_mistral_test","cachedResultName":"ocr_mistral_test"}},"credentials":{"qdrantApi":{"id":"iyQ6MQiVaF3VMBmt","name":"QdrantApi account (Hetzner)"}},"typeVersion":1.1},{"id":"65261873-4ca5-4e23-bc65-220f971eb5b4","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[240,1600],"parameters":{"width":500,"height":120,"content":"## STEP 4\nTest the RAG"},"typeVersion":1},{"id":"ffbaabd0-7fd7-41db-bb71-4cccadf3e9c8","name":"Embeddings OpenAI","type":"@n8n/n8n-nodes-langchain.embeddingsOpenAi","position":[-180,2160],"parameters":{"options":{}},"credentials":{"openAiApi":{"id":"4zwP0MSr8zkNvvV9","name":"OpenAi account"}},"typeVersion":1.2},{"id":"23053690-c978-4b05-be26-e94f88c9d92f","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-480,100],"parameters":{"color":4,"width":620,"height":520,"content":"# STEP 2\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Documents vectorization with Qdrant and Google Drive\nChange:\n- QDRANTURL\n- COLLECTION"},"typeVersion":1},{"id":"153a5098-56d1-4b7c-bb12-e6054db927a0","name":"Edit Fields3","type":"n8n-nodes-base.set","position":[-100,880],"parameters":{"options":{},"assignments":{"assignments":[{"id":"b413a226-0641-4ed8-9951-d17b6a6a9a4b","name":"file_id","type":"string","value":"DRIVEFILE_ID"}]}},"typeVersion":3.4},{"id":"796f3ad4-e041-4af6-b3a5-72b3c3730c49","name":"Update single file","type":"@n8n/n8n-nodes-langchain.vectorStoreQdrant","position":[700,980],"parameters":{"mode":"insert","options":{},"qdrantCollection":{"__rl":true,"mode":"list","value":"negozio-emporio-verde","cachedResultName":"negozio-emporio-verde"}},"credentials":{"qdrantApi":{"id":"iyQ6MQiVaF3VMBmt","name":"QdrantApi account (Hetzner)"}},"typeVersion":1},{"id":"058c4929-ff59-41ca-8131-178e9038b354","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-200,-580],"parameters":{"color":3,"width":840,"height":220,"content":"# Enables full or incremental updates to documents in RAG system using Qdrant \nThis workflow automates the creation and management of a Retrieval-Augmented Generation (RAG) system using Qdrant as a vector store and Google Drive as the document source. It **enables full or incremental updates to documents** in the Qdrant vector database and integrates with a chatbot using Google Gemini for question answering."},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"630e34d7-6558-49c3-b861-520b33fd0f91","connections":{"Wait":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Get files":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Edit Fields3":{"main":[[{"node":"Download file","type":"main","index":0},{"node":"Delete single file","type":"main","index":0}]]},"Download file":{"main":[[{"node":"Update single file","type":"main","index":0}]]},"Download files":{"main":[[{"node":"Qdrant Vector Store","type":"main","index":0}]]},"Loop Over Items":{"main":[[],[{"node":"Download files","type":"main","index":0}]]},"Clear collection":{"main":[[{"node":"Get files","type":"main","index":0}]]},"Embeddings OpenAI":{"ai_embedding":[[{"node":"Qdrant Vector Store1","type":"ai_embedding","index":0}]]},"Embeddings OpenAI1":{"ai_embedding":[[{"node":"Qdrant Vector Store","type":"ai_embedding","index":0}]]},"Embeddings OpenAI2":{"ai_embedding":[[{"node":"Update single file","type":"ai_embedding","index":0}]]},"Default Data Loader":{"ai_document":[[{"node":"Update single file","type":"ai_document","index":0}]]},"Qdrant Vector Store":{"main":[[{"node":"Wait","type":"main","index":0}]]},"Default Data Loader1":{"ai_document":[[{"node":"Qdrant Vector Store","type":"ai_document","index":0}]]},"Qdrant Vector Store1":{"ai_vectorStore":[[{"node":"Vector Store Retriever","type":"ai_vectorStore","index":0}]]},"Vector Store Retriever":{"ai_retriever":[[{"node":"Question and Answer Chain","type":"ai_retriever","index":0}]]},"Google Gemini Chat Model":{"ai_languageModel":[[{"node":"Question and Answer Chain","type":"ai_languageModel","index":0}]]},"When chat message received":{"main":[[{"node":"Question and Answer Chain","type":"main","index":0}]]},"Recursive Character Text Splitter":{"ai_textSplitter":[[{"node":"Default Data Loader1","type":"ai_textSplitter","index":0}]]},"When clicking ‘Test workflow’":{"main":[[{"node":"Clear collection","type":"main","index":0}]]},"Recursive Character Text Splitter1":{"ai_textSplitter":[[{"node":"Default Data Loader","type":"ai_textSplitter","index":0}]]}}}


name: AI-Powered Email Replies with Spam Filtering & FAQ Lookup using GPT-4o mini & Pinecone
author_name: Matteo
author_username: mattabott
categories: []
created_at: 2025-06-23T09:18:25.356Z
updated_at: 2025-06-23T09:18:25.356Z
url: https://n8n.io/workflows/5142
scraped_at: 2025-07-06 21:16:30
description:
  This n8n workflow automates the handling of incoming emails. It detects and filters out spam, searches a knowledge base (FAQ) stored in a Pinecone vector database, and sends a reply using Gmail — all powered by an AI model (GPT-4o mini).

  How It Works
  Receiving Emails

  The Gmail Trigger node checks a Gmail inbox every hour.

  When a new email arrives, it starts the workflow.

  Fetching Full Email Content

  The get_message node retrieves all the details of the message: sender, subject, text, message ID, etc.

  Spam Filtering

  The Spam checker node uses GPT-4o mini to classify the email as either "spam" or "no spam".

  It detects not only classic spam but also automated messages (e.g. from Google or Microsoft).

  If marked as "spam", the workflow ends and nothing is processed.

  Conditional Filter

  The If node checks the spam result.

  Only "no spam" emails proceed to the AI Agent.

  AI-Based Reply

  The AI Agent node generates a response based on:

  	The email content

  	A system prompt defining the assistant’s behavior (polite, professional, under the name “Total AI Solutions”)

  	Information retrieved from the Pinecone Vector Store, which contains FAQs

  The AI is instructed to always check the vector store before replying.

  The AI prepares both the subject and the body of the reply.

  Sending the Reply

  The Gmail node sends the reply to the original sender.

  It uses the original email's ID to keep the thread intact.

  Language Model

  The OpenAI Chat Model node provides GPT-4o mini as the language engine for generating responses.

  Memory Support

  The Simple Memory node maintains short-term context, helpful in multi-turn conversations.

  Knowledge Base (FAQ)

  The Pinecone Vector Store node connects to a Pinecone index (faqmattabott) containing vectorized FAQ content.

  Vectors are created using the Embeddings OpenAI node.

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

workflow_json:
  {"meta":{"instanceId":"eef1c32da34f97cb889cc6dbc544123406b39d27266f625630b9aa0893bf45d7"},"nodes":[{"id":"d68e1936-eec7-4334-8317-70805c95b0ab","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[140,180],"parameters":{"text":"={{ $('get_message').item.json.text }}","options":{"systemMessage":"You are a polite and professional virtual assistant.\n\nYou receive an email.\n\nYour knowledge base is stored in the Pinecone Vector Store, which contains all relevant FAQs and information needed to assist the user accurately.\n\nAlways consult the Pinecone Vector Store before generating your response.\n\nYour final answer must be sent using the \"Gmail\" tool.\n\nWhen using the Gmail tool, make sure to:\n\nFill in the Message field with the response content\n\nFill in the Subject field with a short subject line (you can use \"Reply\" if unsure)"},"promptType":"define"},"typeVersion":1.8},{"id":"0d136348-a945-43c0-bebe-1599f4aef1bd","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[80,360],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"OTuydMANCBoed1Fr","name":"OpenAi account 2"}},"typeVersion":1.2},{"id":"1f6e0331-b1e0-4450-a41a-acff7f0ccae6","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[240,360],"parameters":{"sessionKey":"={{'key'}}","sessionIdType":"customKey"},"typeVersion":1.3},{"id":"7af79daa-d3e0-4111-9005-0930debe0c03","name":"Gmail","type":"n8n-nodes-base.gmailTool","position":[380,360],"webhookId":"f8feb0d1-c7dd-4172-8ebd-e125f18f2c4c","parameters":{"message":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Message', ``, 'string') }}","options":{"appendAttribution":false},"emailType":"text","messageId":"={{ $('get_message').item.json.id }}","operation":"reply"},"typeVersion":2.1},{"id":"5b1779a5-1cf5-4660-ab6f-456de5f07137","name":"Gmail Trigger","type":"n8n-nodes-base.gmailTrigger","position":[-1160,400],"parameters":{"filters":{},"pollTimes":{"item":[{"mode":"everyHour"},{}]}},"credentials":{"gmailOAuth2":{"id":"1YbI98PAg8EdHQyr","name":"total_ai_solutions"}},"typeVersion":1.2},{"id":"a8fb6a4f-037f-42d0-b5a6-e14acef1bf8a","name":"get_message","type":"n8n-nodes-base.gmail","position":[-880,400],"webhookId":"364e19bb-56a0-4cfe-8f89-1bedce5345ae","parameters":{"simple":false,"options":{},"messageId":"={{ $json.id }}","operation":"get"},"credentials":{"gmailOAuth2":{"id":"1YbI98PAg8EdHQyr","name":"total_ai_solutions"}},"typeVersion":2.1},{"id":"26dd84f5-99e5-4e53-acde-ebbdf8d889d0","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1220,160],"parameters":{"color":3,"width":1220,"height":460,"content":"## Gmail input\n\nGmail trigger get the full email\nSpam checker is a Openai node with specific system prompt.\nIf the email is from services (google, microsoft, ecc) it considered as spam.\nIn this case the model try to extract only business emails.\nThe node print only 2 different output: \"spam\" and \"no spam\".\nIf \"spam\", nothing happen, if \"no spam\" the \"if node\" pass the message to the Agentic node"},"typeVersion":1},{"id":"14915f5c-0375-46b8-90ee-c412a6b0e40c","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[0,0],"parameters":{"color":4,"width":540,"height":620,"content":"## AI Agent\n\nAI Agent get the message and respond to the email autonomously in base of contest.\nHere we have a vector store too, where you can add your data, like FAQ, product prices and so on"},"typeVersion":1},{"id":"09a0c5ca-6d4f-46ef-aa34-09b565f698f7","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[0,620],"parameters":{"color":6,"width":540,"height":300,"content":"## VECTOR STORE\n"},"typeVersion":1},{"id":"4a56b1ab-39d6-424c-a614-06febe5f5f63","name":"Pinecone Vector Store","type":"@n8n/n8n-nodes-langchain.vectorStorePinecone","position":[200,680],"parameters":{"mode":"retrieve-as-tool","options":{},"toolName":"FAQ","pineconeIndex":{"__rl":true,"mode":"list","value":"faqmattabott","cachedResultName":"faqmattabott"}},"typeVersion":1.1},{"id":"435fa9d9-cee9-4aad-a51b-25566a96b2af","name":"Embeddings OpenAI","type":"@n8n/n8n-nodes-langchain.embeddingsOpenAi","position":[60,800],"parameters":{"options":{}},"credentials":{"openAiApi":{"id":"OTuydMANCBoed1Fr","name":"OpenAi account 2"}},"typeVersion":1.2},{"id":"d0801a3b-d336-4e50-a8da-58ff218c3673","name":"If","type":"n8n-nodes-base.if","position":[-280,400],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"921d0426-0dbf-49ac-ab67-b5538856deee","operator":{"type":"string","operation":"notEquals"},"leftValue":"={{ $json.message.content }}","rightValue":"spam"}]}},"typeVersion":2.2},{"id":"ddea4fe7-e458-4949-aba5-57da659ab15c","name":"Spam checker","type":"@n8n/n8n-nodes-langchain.openAi","position":[-640,400],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4o-mini","cachedResultName":"GPT-4O-MINI"},"options":{},"messages":{"values":[{"role":"system","content":"You are a e-mail assistant. You have to check if the received e-mail are spam or not.\nYou have to check not only normal spam, but everything is not sent from a person, for example, automatic e-mail, google email, and anything out of a possible client.\n\nIf an e-mail is considered spam, as I sayd befor, your output will be \"spam\". If not, say \"no spam\".\n\nDon't respond anything else \"spam\" or \"not spam\"."},{"content":"={{ $json.headers.subject }}{{ $json.headers.from }}{{ $json.text }}"}]}},"credentials":{"openAiApi":{"id":"OTuydMANCBoed1Fr","name":"OpenAi account 2"}},"typeVersion":1.8}],"connections":{"If":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Gmail":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"AI Agent":{"main":[[]]},"get_message":{"main":[[{"node":"Spam checker","type":"main","index":0}]]},"Spam checker":{"main":[[{"node":"If","type":"main","index":0}]]},"Gmail Trigger":{"main":[[{"node":"get_message","type":"main","index":0}]]},"Simple Memory":{"ai_memory":[[{"node":"AI Agent","type":"ai_memory","index":0}]]},"Embeddings OpenAI":{"ai_embedding":[[{"node":"Pinecone Vector Store","type":"ai_embedding","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Pinecone Vector Store":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]}}}


name: Convert Markdown content to Google Docs document with automatic formatting
author_name: Roman Rozenberger
author_username: romek
nodes_used: ["n8n-nodes-base.googleDrive","n8n-nodes-base.code"]
categories: []
created_at: 2025-06-23T10:24:50.224Z
updated_at: 2025-06-23T10:24:50.224Z
url: https://n8n.io/workflows/5147
scraped_at: 2025-07-06 21:16:30
description:
  This workflow is perfect for technical writers, content creators, marketers, and developers who write in Markdown but need to collaborate or publish using Google Docs format. Ideal for teams that want to streamline their content creation and review process.

  What problem does this workflow solve?

  Manual conversion from Markdown to Google Docs is time-consuming and often loses formatting. This workflow eliminates the tedious copy-paste process, automatically preserves formatting, and creates organized, timestamped documents in your Google Drive. Perfect for content teams who write in Markdown but need Google Docs for collaboration and review.

  What this workflow does

  Converts Markdown to HTML** with proper formatting preservation (headers, lists, links, tables)
  Creates timestamped Google Docs** documents with automatic naming
  Adds Drive location metadata** for better organization and reference
  Maintains document structure** including emojis, tables, and text formatting
  Automates file creation** in specified Google Drive folders

  Setup

  Google Drive OAuth2 credentials configured in n8n
  Target Google Drive folder URL
  Input your content title and Markdown text in the "Set Input Data" node

  How to customize this workflow to your needs

  Modify HTML formatting options** in the Markdown conversion node
  Change file naming patterns** to match your organization system  
  Adjust Drive folder structure** and metadata inclusion
  Update MIME type handling** for different output requirements
  Add additional processing steps** like notifications or integrations

  Perfect for technical documentation workflows, content publishing pipelines, blog preparation, and automated report generation.

  Setup Instructions - Markdown to Google Docs Converter

  Prerequisites

  n8n instance** (local or cloud)
  Google account** with Google Drive access
  Basic understanding** of n8n workflow configuration

  Step 1: Import the Workflow

  Open n8n and navigate to Workflows
  Click "Add workflow" → "Import from JSON"
  Upload the Export_Markdown_Content_do_Google_Docs_Document.json file
  Save the workflow with a descriptive name

  Step 2: Configure Google Drive Credentials

  Create Google Drive OAuth2 Credentials

  In n8n, go to Settings → Credentials
  Click "Add credential" → "Google Drive OAuth2 API"
  Follow the OAuth setup to authorize n8n access to Google Drive:
     Visit Google Cloud Console
     Create or select a project
     Enable Google Drive API
     Create OAuth2 credentials
     Add authorized redirect URI for your n8n instance
  Name the credential (e.g., "Google Drive - Markdown Converter")

  Configure Google Drive Nodes

  Update these nodes with your Google Drive credentials:
  Create Empty File
  Update Document with Correct HTML Formatting

  In each node:
  Select your Google Drive credential from the dropdown
  Test the connection to ensure it works properly

  Step 3: Prepare Your Google Drive

  Create Target Folder

  Go to Google Drive (drive.google.com)
  Create a new folder for your converted documents
  Copy the folder URL (will look like: https://drive.google.com/drive/folders/FOLDER_ID)
  Ensure the folder has proper permissions for your Google account

  Step 4: Configure Input Data

  Set Your Default Values

  Open the "Set Input Data" node
  Update the assignments with your preferences:

     Google Drive URL:
     Replace the example URL with your target folder URL
     Format: https://drive.google.com/drive/folders/YOUR_FOLDER_ID

     Content Title:
     Set a default title or leave placeholder text
     This will be used in the document filename

     Content in Markdown:
     Add your Markdown content or keep example for testing
     Supports standard Markdown syntax (headers, lists, links, tables)

  Step 5: Test the Workflow

  Initial Test Run

  Ensure all credentials are configured
  Click the "Test workflow" button on the Manual Trigger node
  Monitor the execution - check for any errors in node outputs
  Verify the result:
     Check your Google Drive folder
     Look for a new document with timestamp in the name
     Open the document to verify formatting

  Troubleshooting Common Issues

  Google Drive Permission Errors:
  Verify OAuth2 credentials are properly configured
  Check that the target folder exists and is accessible
  Ensure Google Drive API is enabled in Google Cloud Console

  Markdown Conversion Issues:
  Check that your Markdown syntax is valid
  Test with simple content first (headers, paragraphs, lists)
  Verify the "Change Markdown To HTML" node settings

  File Creation Problems:
  Confirm the Google Drive folder URL format is correct
  Check that the folder ID in the URL is valid
  Ensure your Google account has write permissions to the folder

  Step 6: Customize for Your Needs

  Modify HTML Formatting Options

  In the "Change Markdown To HTML" node:
  Enable/disable emoji support** (currently enabled)
  Adjust table formatting** (currently enabled)
  Modify header ID generation** (currently disabled)
  Configure space requirements** for headers

  Update File Naming Pattern

  In the "Create Empty File" node:
  Change the naming convention**: Currently uses _PUB {Content Title} {timestamp}
  Modify timestamp format**: Currently yyyy-MM-dd HH:mm:ss
  Add prefixes or suffixes** as needed for your organization

  Step 7: Production Usage

  Regular Workflow Execution

  Update the "Set Input Data" node with new content
  Execute the workflow manually or set up triggers
  Monitor execution logs for any issues
  Check Google Drive for generated documents

  Integration Options

  Webhook Integration:
  Add a Webhook trigger to accept external Markdown content
  Useful for automated content publishing workflows

  Email Integration:
  Add email notifications when documents are created
  Include links to generated Google Docs

  Advanced Configuration

  Error Handling

  Add error handling nodes after critical operations
  Implement retry logic for API failures
  Set up notifications for failed executions

  Performance Optimization

  Adjust the "Wait for Document Creation" timing if needed
  Consider file size limits for Google Docs

  Support and Troubleshooting

  Common Solutions

  Timeout errors**: Increase wait time in "Wait for Document Creation"
  Authentication failures**: Refresh Google OAuth2 credentials
  Formatting issues**: Test with simpler Markdown first

  Getting Help

  Check n8n community forums for Google Drive integration issues
  Review Google Drive API documentation for rate limits
  Test with minimal Markdown content to isolate problems

  Total setup time: ~15-20 minutes  
  Difficulty level: Intermediate  
  Requirements: Google account, n8n instance, basic OAuth2 setup knowledge

workflow_json:
  {"id":"ChVvcDCOfzi5pame","meta":{"instanceId":"e8794a4f970040d09c64040698c632aefaa9a59e97e60424e4b5671338351753","templateCredsSetupCompleted":true},"name":"Export Markdown Content do Google Docs Document","tags":[{"id":"vEOXPr8KZp3rtAHw","name":"google docs","createdAt":"2025-05-15T11:30:24.567Z","updatedAt":"2025-05-15T11:30:24.567Z"}],"nodes":[{"id":"9a49370a-1ccc-4763-b00c-0a5d0b923d0c","name":"When clicking ‘Test workflow’","type":"n8n-nodes-base.manualTrigger","position":[-1760,40],"parameters":{},"typeVersion":1},{"id":"22f87c26-b493-407d-8fbe-2c9b1f51e050","name":"Change Markdown To HTML","type":"n8n-nodes-base.markdown","position":[-1320,-60],"parameters":{"mode":"markdownToHtml","options":{"emoji":true,"tables":true,"noHeaderId":true,"requireSpaceBeforeHeadingText":true},"markdown":"={{ $json['Conten in Markdown'] }}","destinationKey":"Content in HTML"},"typeVersion":1},{"id":"e59ed259-efcf-45c6-8b3f-f4e78b5e81d6","name":"Add Information About Google Drive Location","type":"n8n-nodes-base.set","position":[-1100,-60],"parameters":{"options":{},"assignments":{"assignments":[{"id":"927cf00b-a616-4aad-96bd-59c533c1655c","name":"Content","type":"string","value":"=<ul>\n<li>URL DYSKU: <a href=\"{{ $json['Google Drive URL'] }}\">{{ $json['Google Drive URL'] }}</a></li>\n</ul>\n\n{{ $json['Content in HTML'] }}"}]}},"typeVersion":3.4},{"id":"8613265b-6578-4322-a983-4460d72984d5","name":"Convert Content to Text File","type":"n8n-nodes-base.convertToFile","position":[-880,-60],"parameters":{"options":{"fileName":"content.html"},"operation":"toText","sourceProperty":"Content","binaryPropertyName":"file"},"typeVersion":1.1},{"id":"c6da9c1c-ef4a-4f55-bb4d-c7719440ba58","name":"Create Empty File","type":"n8n-nodes-base.googleDrive","position":[-660,140],"parameters":{"name":"=_PUB {{ $json['Content Title'] }} {{ $now.format('yyyy-MM-dd HH:mm:ss') }}","content":"=Dummy File Content","driveId":{"__rl":true,"mode":"list","value":"My Drive","cachedResultUrl":"https://drive.google.com/drive/my-drive","cachedResultName":"My Drive"},"options":{"convertToGoogleDocument":true},"folderId":{"__rl":true,"mode":"url","value":"={{ $json['Google Drive URL'] }}"},"operation":"createFromText"},"credentials":{"googleDriveOAuth2Api":{"id":"kyBDe9djaKd6KX7C","name":"gdrive roman@ibb "}},"typeVersion":3},{"id":"4fca0d05-d308-4da4-a754-7080274c1123","name":"Merge File With About Document ID","type":"n8n-nodes-base.merge","position":[-440,40],"parameters":{"mode":"combine","options":{},"combineBy":"combineByPosition"},"typeVersion":3},{"id":"4926569a-0bd0-41f1-8c45-8cbd2bc89d89","name":"Wait for Document Creation","type":"n8n-nodes-base.wait","position":[-220,40],"webhookId":"201ca2d8-3df8-430a-9a2a-b2619df60882","parameters":{"amount":0.5},"typeVersion":1.1},{"id":"6084b5e5-c4b3-4cee-bded-4365483c3f7e","name":"Change Mime Type of The File","type":"n8n-nodes-base.code","notes":"Mime Type form text/plain to text/html","position":[-660,-60],"parameters":{"mode":"runOnceForEachItem","jsCode":"const item = $input.item;\n\nif (item.binary && item.binary.file) {\n  item.binary.file.mimeType = 'text/html';\n}\n\nreturn item;"},"notesInFlow":true,"typeVersion":2},{"id":"a4c07e9c-5f3b-4c3c-bb14-7d36124a75bf","name":"Set Input Data","type":"n8n-nodes-base.set","position":[-1540,40],"parameters":{"options":{},"assignments":{"assignments":[{"id":"d17f2b49-ee63-4b72-80be-be8dee2375fd","name":"Google Drive URL","type":"string","value":"=https://drive.google.com/drive/folders/1ObGBisk0j56rn93OFxYPd24t4Se6dElY"},{"id":"34970e84-1eb7-41f7-a7f5-ac04668b91b1","name":"Content Title","type":"string","value":"Łyżki do butów"},{"id":"e23af554-c555-49b7-96ac-53b643968cab","name":"Conten in Markdown","type":"string","value":"# Łyżki do butów\n\n## Łyżki do butów - co to jest i do czego służy\n**Łyżka do butów** to niezwykle przydatne akcesorium, które znacząco upraszcza proces **zakładania obuwia**. Dzięki temu prostemu narzędziu możesz uniknąć uszkodzeń pięty oraz deformacji butów. **Łyżka** pozwala na łatwe wsunięcie stopy do buta, eliminując konieczność nadmiernego wyginania materiału czy schylania się.\n\nW sklepach znajdziesz łyżki w różnych długościach, na przykład 51 cm, 60 cm, co sprawia, że każdy może znaleźć model najlepiej dopasowany do swoich potrzeb. Najczęściej są one produkowane z:\n\n- metalu,\n- drewna.\n\nTakie materiały gwarantują ich trwałość oraz komfort użytkowania.\n\n**Łyżka do butów** jest szczególnie przydatna dla:\n\n- osób starszych,\n- kobiet w ciąży,\n- dzieci,\n- osób z problemami kręgosłupa.\n\nUmożliwia wygodne zakładanie obuwia bez zbędnego wysiłku i ryzyka kontuzji. Dzięki niej możesz cieszyć się większą niezależnością w codziennych czynnościach, co z pewnością poprawi jakość Twojego życia.\n## Metalowa łyżka do butów - trwałość i elegancja\nMetalowa łyżka do butów to produkt, który wyróżnia się **niesamowitą trwałością** oraz odpornością na wszelkie uszkodzenia. W przeciwieństwie do plastikowych odpowiedników, jej solidna konstrukcja zapewnia znacznie większą wytrzymałość. Wykonana z wysokiej jakości metalu, posiada **niklowaną powłokę**, która nie tylko chroni przed korozją, ale również nadaje elegancki wygląd.\n\nDzięki **ergonomicznemu kształtowi** i gładkiej powierzchni, korzystanie z metalowej łyżki znacznie ułatwia zakładanie obuwia, eliminując konieczność schylania się. To szczególnie cenne rozwiązanie dla osób starszych oraz tych z ograniczoną mobilnością. Regularne użycie łyżki zapobiega deformacjom zapiętków, co znacząco przedłuża żywotność butów.\n\n**Kluczowe właściwości metalowej łyżki do butów:**\n- **Materiał:** solidny metal z niklowaną powłoką, która chroni przed korozją,  \n- **Długość:** od około 51 cm do 64 cm, co zapewnia wygodę podczas użytkowania,  \n- **Szerokość łuku:** około 45 mm, idealnie dopasowana do różnych typów obuwia,  \n- **Dodatkowe cechy:** ergonomiczny kształt, łatwość w czyszczeniu oraz estetyczny design,  \n\nMetalowe łyżki do butów są niezwykle uniwersalne i doskonale sprawdzą się z każdym rodzajem obuwia — od codziennych modeli po eleganckie buty wizytowe. Ich solidna konstrukcja zapewnia długotrwałe użytkowanie, eliminując ryzyko uszkodzeń czy odkształceń. Dlatego to doskonała inwestycja w komfort oraz ochronę obuwia na wiele lat.\n## Długie łyżki do butów - komfort i wygoda zakładania obuwia\n**Długie łyżki do butów** to niezwykle praktyczne akcesoria, które znacznie upraszczają proces zakładania obuwia. Dzięki nim **nie musisz się schylać**, co znacząco podnosi **komfort** codziennych aktywności. To świetne rozwiązanie, szczególnie dla **osób z ograniczoną mobilnością**.\n\nDługie łyżki są szczególnie polecane dla:\n\n- **osób starszych**, które mogą mieć trudności z pochylaniem się,\n- osób z problemami kręgosłupa lub stawów,\n- osób po urazach czy operacjach, które ograniczają ich ruchomość.\n\nKorzystanie z długich łyżek ma także dodatkową zaletę – **chronią one buty przed deformacją**. Dzięki temu obuwie zachowuje swoją trwałość oraz estetyczny wygląd. Zazwyczaj są one wykonane z lekkiego plastiku lub naturalnego drewna, co zapewnia zarówno **wygodę**, jak i **wytrzymałość**.\n\nUżywanie długiej łyżki pozwala nie tylko na **zachowanie prawidłowego kształtu obuwia**, ale także **minimalizuje ryzyko uszkodzeń materiału** podczas zakładania. W rezultacie codzienne czynności stają się prostsze i bardziej komfortowe dla każdego użytkownika.\n## Zalety używania łyżek do butów dla codziennego wsparcia\n**Łyżki do butów** to niezastąpione akcesoria, które znacznie ułatwiają zakładanie obuwia, eliminując **potrzebę nadmiernego schylania się**. To szczególnie istotne dla osób z bólami kręgosłupa, wadami postawy czy ograniczoną mobilnością. Ograniczenie schylania się przynosi ulgę, zmniejszając napięcie mięśni oraz **ryzyko kontuzji**.\n\nUżywanie łyżek skutecznie chroni buty przed deformacją, co **przedłuża ich żywotność**, zwłaszcza w przypadku modeli skórzanych. Dzięki zachowaniu kształtu i estetyki przez dłuższy czas, obuwie staje się bardziej **ekonomiczne w użytkowaniu**.\n\nŁyżki dostępne są w różnych materiałach, co pozwala na ich dostosowanie do indywidualnych preferencji:\n- **plastik** – lekki i przystępny cenowo,\n- **metal** – trwały i elegancki,\n- **drewno** – naturalne, o klasycznym wyglądzie.\n\nRegularne korzystanie z tych akcesoriów to praktyczny sposób na **dbanie o zdrowie** oraz ochronę obuwia na co dzień.\n## Różne długości łyżek do butów i ich zastosowanie\n**Długości łyżek do butów** odgrywają kluczową rolę w zapewnieniu komfortu podczas zakładania obuwia. Wyróżniamy trzy główne typy: **krótkie**, **długie** oraz **regulowane łyżki**, które można dostosować do indywidualnych potrzeb każdego użytkownika.\n\n**Krótkie łyżki** są niezwykle poręczne i łatwe do przechowywania. Idealnie nadają się do codziennego użytku, zwłaszcza dla osób, które nie mają problemów z mobilnością. Ich kompaktowy rozmiar umożliwia szybkie wsunięcie stopy do buta, choć wymaga to lekkiego schylenia.\n\n**Długie łyżki** stanowią doskonałe rozwiązanie dla osób z ograniczoną sprawnością ruchową, seniorów oraz tych, którzy zmagają się z bólami pleców. Dzięki większej długości, umożliwiają **zakładanie butów bez potrzeby schylania się**, co znacząco zmniejsza ryzyko kontuzji i dyskomfortu. Często wykonane są z **trwałych materiałów**, takich jak metal czy wytrzymałe tworzywa sztuczne, co zapewnia ich długowieczność.\n\n**Regulowane łyżki do butów** to doskonała opcja dla tych, którzy cenią sobie elastyczność. Możliwość dostosowania długości sprawia, że idealnie pasują do różnych rodzajów obuwia oraz potrzeb użytkowników, co czyni je niezwykle praktycznymi.\n\nPrzy wyborze odpowiedniej długości łyżki warto zwrócić uwagę na kilka istotnych aspektów:\n\n- **łatwość zakładania butów**, co jest szczególnie ważne przy ograniczonej mobilności,\n- **ochrona kształtu obuwia** przed odkształceniem,\n- **komfort użytkowania** bez konieczności nadmiernego schylania się,\n- **trwałość materiału**, która powinna być dostosowana do częstotliwości używania.\n\nDłuższe modele znacząco ułatwiają codzienne czynności osobom starszym lub mającym problemy zdrowotne związane z kręgosłupem. Z kolei krótsze łyżki będą idealne dla osób aktywnych i młodszych, które nie potrzebują dodatkowego wsparcia podczas zakładania butów.\n\nWybór odpowiedniej długości łyżki nie tylko zwiększa **komfort noszenia obuwia**, ale również chroni je przed uszkodzeniami mechanicznymi, które mogą powstawać w wyniku niewłaściwego wkładania stopy.\n## Łyżki do butów dla osób z ograniczoną mobilnością i seniorów\nŁyżki do butów to znakomite wsparcie dla **seniorów** oraz osób z ograniczoną mobilnością. Ułatwiają one codzienne zakładanie obuwia, eliminując konieczność schylania się, co czyni cały proces bardziej komfortowym i bezpiecznym.\n\nWiele modeli dedykowanych tej grupie użytkowników wyposażonych jest w **elastyczną końcówkę**, która umożliwia łatwe wsunięcie stopy do buta, nie wywołując przy tym nadmiernego nacisku na materiał. Takie rozwiązanie znacząco redukuje ryzyko uszkodzenia obuwia oraz zapobiega jego rozciąganiu.\n\nCechy, które wyróżniają łyżki dla seniorów i osób z ograniczoną mobilnością, to:\n\n- **stabilna rączka** wykonana z drewna lub tworzywa, zapewniająca pewny chwyt,\n- **wytrzymały metalowy trzonek**, który gwarantuje długotrwałe użytkowanie,\n- **dostosowana długość** – wiele modeli jest wydłużonych, co zwiększa komfort podczas zakupu,\n- **lekka konstrukcja**, która ułatwia obsługę nawet przy osłabionej sile dłoni.\n\nKorzystanie z **łyżki do butów** nie tylko chroni obuwie przed deformacją, ale również wspiera **samodzielność** osób starszych oraz tych z problemami ruchowymi. To praktyczne narzędzie znacząco poprawia jakość życia, redukując ryzyko upadków podczas zakładania butów.\n\nPrzy wyborze odpowiedniej łyżki dla seniora czy osoby z ograniczoną mobilnością warto zwrócić uwagę na ergonomię uchwytu oraz obecność elastycznej końcówki. Te elementy są kluczowe dla zapewnienia komfortu i bezpieczeństwa podczas użytkowania.\n## Jak łyżki do butów chronią obuwie przed uszkodzeniami\nŁyżka do butów **chroni obuwie** przed deformacjami oraz uszkodzeniami, zwłaszcza w okolicy pięty. Dzięki swojemu przemyślanemu kształtowi, pozwala na łatwe wsunięcie stopy do buta, eliminując konieczność zginania tylnej części cholewki. To z kolei **minimalizuje ryzyko zgniatania i pękania materiału**, co ma kluczowe znaczenie, zwłaszcza w przypadku skórzanych modeli.\n\nUżywanie łyżki **przedłuża żywotność butów**. Pomaga uniknąć trwałych odkształceń oraz rozwarstwiania się szwów, a także chroni delikatne elementy wykończenia, które mogą być narażone na uszkodzenia podczas zakładania obuwia.\n\nFunkcje ochronne łyżek do butów można podsumować w następujący sposób:\n\n- **Ochrona pięty przed zgniataniem**, co zapobiega zagnieceniom i pęknięciom,\n- **Minimalizacja ryzyka uszkodzenia cholewki** poprzez równomierne rozłożenie nacisku przy wkładaniu stopy,\n- ułatwienie zakładania butów bez użycia siły, co zmniejsza naprężenia materiału,\n- zabezpieczenie przed deformacją tylnej części obuwia, która często szybko się zużywa.\n\nDzięki tym właściwościom, łyżka jest szczególnie polecana osobom noszącym droższe modele butów oraz tym, którzy pragną dłużej cieszyć się estetyką i funkcjonalnością swojego obuwia. Regularne korzystanie z niej to prosty sposób na **ochronę inwestycji** w wysokiej jakości obuwie.\n## Wybór łyżki do butów - na co zwrócić uwagę\nMateriał, z którego wykonana jest **łyżka do butów**, ma kluczowe znaczenie dla jej **wytrzymałości** oraz **wagi**. Oto najpopularniejsze opcje:\n\n- **Metalowe** modele, charakteryzujące się wysoką odpornością na uszkodzenia, idealne dla osób poszukujących trwałości, chociaż mogą być nieco cięższe,\n- **Drewniane** łyżki, łączące solidność z elegancją, co sprawia, że są nie tylko funkcjonalne, ale i estetyczne,\n- **Plastikowe** wersje, oferujące lekkość oraz szeroką gamę kolorów, co pozwala na dopasowanie do indywidualnych gustów.\n\n**Długość** łyżki również wpływa na komfort użytkowania:\n\n- **Krótsze modele**, sprawdzające się doskonale w codziennym użytkowaniu, ułatwiają szybkie zakładanie obuwia,\n- **Dłuższe** łyżki, umożliwiające zakładanie butów bez konieczności schylania się, co jest szczególnie istotne dla osób z problemami z kręgosłupem lub ograniczoną mobilnością.\n\n**Kształt** łyżki powinien być starannie wyprofilowany i lekko wklęsły. Taki design:\n\n- ułatwia wsuwanie stopy do buta,\n- minimalizuje ryzyko uszkodzenia pięty czy zagnieceń materiału.\n\nWarto unikać modeli z ostrymi krawędziami, które mogą zniszczyć obuwie.\n\n**Uchwyt** łyżki ma znaczący wpływ na komfort użytkowania. Powinien być:\n\n- **ergonomiczny**,\n- dobrze leżeć w dłoni,\n- zapewniać pewny chwyt.\n\nDodatkowym atutem mogą być haczyki lub specjalne zakończenia, które ułatwiają wyciąganie łyżki z buta po założeniu.\n\nWybierając odpowiednią łyżkę do butów, warto zwrócić uwagę na te kluczowe cechy. Dzięki nim można cieszyć się **wygodą** oraz skutecznie chronić obuwie przed deformacjami i uszkodzeniami."}]}},"typeVersion":3.4},{"id":"38130d33-eaf9-4da6-bcd9-dfd0981ea4b0","name":"Update Document with Correct HTML Formatting","type":"n8n-nodes-base.googleDrive","position":[0,40],"parameters":{"fileId":{"__rl":true,"mode":"id","value":"={{ $json.id }}"},"options":{"fields":["webViewLink","id"]},"operation":"update","changeFileContent":true,"inputDataFieldName":"file"},"credentials":{"googleDriveOAuth2Api":{"id":"kyBDe9djaKd6KX7C","name":"gdrive roman@ibb "}},"typeVersion":3},{"id":"8c6b4464-1869-4e4c-8db5-9295749d2b53","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-2260,-260],"parameters":{"width":400,"height":740,"content":"📝 Markdown to Google Docs Converter\n\n🎯 PURPOSE: Convert Markdown content to formatted Google Docs documents with automatic timestamping and Drive organization\n\n⚙️ SETUP REQUIRED:\n• Google Drive OAuth2 credentials configured in n8n\n• Target Google Drive folder URL\n• Content title and Markdown text input\n\n📋 HOW TO USE:\n1. Configure Google Drive credentials in n8n settings\n2. Update \"Set Input Data\" node with:\n   - Google Drive URL (target folder)\n   - Content Title (document name)\n   - Content in Markdown (your text)\n3. Click \"Test workflow\" to execute\n4. Check your Google Drive for timestamped document\n\n🔧 CUSTOMIZE:\n• Modify HTML formatting options in \"Change Markdown To HTML\" node\n• Adjust file naming pattern in \"Create Empty File\" node  \n• Change Drive location metadata in \"Add Information About Google Drive Location\"\n• Update MIME type handling in \"Change Mime Type of The File\"\n\n💡 USE CASES:\n• Technical documentation (README → Google Docs)\n• Content publishing workflow (draft → review)\n• Blog/article preparation (Markdown → collaborative editing)\n• Report generation with automated formatting\n"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"2227fb59-37e1-44fe-8ede-68957e642f29","connections":{"Set Input Data":{"main":[[{"node":"Create Empty File","type":"main","index":0},{"node":"Change Markdown To HTML","type":"main","index":0}]]},"Create Empty File":{"main":[[{"node":"Merge File With About Document ID","type":"main","index":1}]]},"Change Markdown To HTML":{"main":[[{"node":"Add Information About Google Drive Location","type":"main","index":0}]]},"Wait for Document Creation":{"main":[[{"node":"Update Document with Correct HTML Formatting","type":"main","index":0}]]},"Change Mime Type of The File":{"main":[[{"node":"Merge File With About Document ID","type":"main","index":0}]]},"Convert Content to Text File":{"main":[[{"node":"Change Mime Type of The File","type":"main","index":0}]]},"Merge File With About Document ID":{"main":[[{"node":"Wait for Document Creation","type":"main","index":0}]]},"When clicking ‘Test workflow’":{"main":[[{"node":"Set Input Data","type":"main","index":0}]]},"Add Information About Google Drive Location":{"main":[[{"node":"Convert Content to Text File","type":"main","index":0}]]},"Update Document with Correct HTML Formatting":{"main":[[]]}}}


name: Local Chatbot with Retrieval Augmented Generation (RAG)
author_name: Thomas Janssen
author_username: thomasjanssen-tech
categories: []
created_at: 2025-06-23T10:40:17.187Z
updated_at: 2025-06-23T10:40:17.187Z
url: https://n8n.io/workflows/5148
scraped_at: 2025-07-06 21:16:30
description:
  Build a 100% local RAG with n8n, Ollama and Qdrant. This agent uses a semantic database (Qdrant) to answer questions about PDF files.

  Tutorial

  Click here to view the YouTube Tutorial

  How it works
  Build a chatbot that answers based on documents you provide it (Retrieval Augmented Generation). You can upload as many PDF files as you want to the Qdrant database. The chatbot will use its retrieval tool to fetch the chunks and use them to answer questions.

  Installation
  Install n8n + Ollama + Qdrant using the Self-hosted AI starter kit
  Make sure to install Llama 3.2 and mxbai-embed-large as embeddings model.

  How to use it
  First run the "Data Ingestion" part and upload as many PDF files as you want
  Run the Chatbot and start asking questions about the documents you uploaded

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

workflow_json:
  {"id":"L9nteAq0NLYqIGxH","meta":{"instanceId":"558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a","templateCredsSetupCompleted":true},"name":"RAG Pipeline","tags":[],"nodes":[{"id":"a00e5b5b-1cc1-4272-9790-8ffde3c92efb","name":"On form submission","type":"n8n-nodes-base.formTrigger","position":[0,0],"webhookId":"4e1e20d4-f759-42c8-8439-87b93f43aa7c","parameters":{"options":{},"formTitle":"Add your file here","formFields":{"values":[{"fieldType":"file","fieldLabel":"File","requiredField":true,"acceptFileTypes":".pdf"}]}},"typeVersion":2.2},{"id":"1218186e-a93e-4e05-b47e-a395f28cf5f9","name":"Qdrant Vector Store","type":"@n8n/n8n-nodes-langchain.vectorStoreQdrant","position":[220,0],"parameters":{"mode":"insert","options":{},"qdrantCollection":{"__rl":true,"mode":"id","value":"rag_collection"}},"credentials":{"qdrantApi":{"id":"sFfERYppMeBnFNeA","name":"Local QdrantApi database"}},"typeVersion":1.2},{"id":"9c7fb858-b571-4626-b976-d3e1995c464b","name":"Embeddings Ollama","type":"@n8n/n8n-nodes-langchain.embeddingsOllama","position":[60,220],"parameters":{"model":"mxbai-embed-large:latest"},"credentials":{"ollamaApi":{"id":"xHuYe0MDGOs9IpBW","name":"Local Ollama service"}},"typeVersion":1},{"id":"af14443b-ae01-48dc-8552-5ded7a27fce2","name":"Default Data Loader","type":"@n8n/n8n-nodes-langchain.documentDefaultDataLoader","position":[360,220],"parameters":{"options":{},"dataType":"binary"},"typeVersion":1},{"id":"660380c5-63da-4404-98e6-f9c0ee9aaa90","name":"Recursive Character Text Splitter","type":"@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter","position":[460,440],"parameters":{"options":{},"chunkSize":200,"chunkOverlap":50},"typeVersion":1},{"id":"49dbe387-751f-4a2e-8803-290bc2c06ec5","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-140,-100],"parameters":{"color":3,"width":840,"height":700,"content":"## Data Ingestion\n**Add data to the semantic database"},"typeVersion":1},{"id":"45683271-af59-41d0-9e69-af721d566661","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[940,-20],"webhookId":"5e56a263-3a40-44bd-bc9d-1cfb3bc2a87d","parameters":{"options":{}},"typeVersion":1.1},{"id":"af562588-2e8c-4c0b-b041-d6fc8c0affd0","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[1220,-20],"parameters":{"options":{"systemMessage":"You are a helpful assistant. You have access to a tool to retrieve data from a semantic database to answer questions. Always provide arguments when you execute the tool"}},"typeVersion":2},{"id":"4d924b4a-fe07-4606-8385-613d6ea14991","name":"Ollama Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOllama","position":[1060,220],"parameters":{"options":{}},"credentials":{"ollamaApi":{"id":"xHuYe0MDGOs9IpBW","name":"Local Ollama service"}},"typeVersion":1},{"id":"de87b7bb-6fec-4d8f-a77a-25bc3a30a038","name":"Simple Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[1260,220],"parameters":{},"typeVersion":1.3},{"id":"16261539-5218-4df1-8b14-915dd3377167","name":"Qdrant Vector Store1","type":"@n8n/n8n-nodes-langchain.vectorStoreQdrant","position":[1540,240],"parameters":{"mode":"retrieve-as-tool","options":{},"toolName":"retriever","toolDescription":"Retrieve data from a semantic database to answer questions","qdrantCollection":{"__rl":true,"mode":"id","value":"rag_collection"}},"credentials":{"qdrantApi":{"id":"sFfERYppMeBnFNeA","name":"Local QdrantApi database"}},"typeVersion":1.2},{"id":"57d3be1d-73cd-4464-a3f3-7dd4a3157cdf","name":"Embeddings Ollama1","type":"@n8n/n8n-nodes-langchain.embeddingsOllama","position":[1460,440],"parameters":{"model":"mxbai-embed-large:latest"},"credentials":{"ollamaApi":{"id":"xHuYe0MDGOs9IpBW","name":"Local Ollama service"}},"typeVersion":1},{"id":"5919cc58-05f4-42c8-aada-3782a16574d9","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[740,-100],"parameters":{"color":4,"width":1200,"height":700,"content":"## RAG Chatbot\n**Chat with your data"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"895c0261-fbf5-4bb6-9581-4cea3c4d20bd","connections":{"Simple Memory":{"ai_memory":[[{"node":"AI Agent","type":"ai_memory","index":0}]]},"Embeddings Ollama":{"ai_embedding":[[{"node":"Qdrant Vector Store","type":"ai_embedding","index":0}]]},"Ollama Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Embeddings Ollama1":{"ai_embedding":[[{"node":"Qdrant Vector Store1","type":"ai_embedding","index":0}]]},"On form submission":{"main":[[{"node":"Qdrant Vector Store","type":"main","index":0}]]},"Default Data Loader":{"ai_document":[[{"node":"Qdrant Vector Store","type":"ai_document","index":0}]]},"Qdrant Vector Store1":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"When chat message received":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Recursive Character Text Splitter":{"ai_textSplitter":[[{"node":"Default Data Loader","type":"ai_textSplitter","index":0}]]}}}


name: Create PDF from HTML with Gotenberg
author_name: Lucas Peyrin
author_username: lucaspeyrin
nodes_used: ["n8n-nodes-base.httpRequest"]
categories: []
created_at: 2025-06-23T10:48:23.572Z
updated_at: 2025-06-23T10:48:23.572Z
url: https://n8n.io/workflows/5149
scraped_at: 2025-07-06 21:16:30
description:
  How it works

  This workflow converts an HTML string into a polished PDF file using the powerful open-source Gotenberg service. It's designed to be a reusable utility in your automation stack.

  Receives Input: The workflow is triggered with a JSON object containing the full html code as a string and a desired file_name for the output.
  Prepares File: It converts the incoming HTML string into a binary index.html file, which is required for the API call.
  Calls Gotenberg API: It sends the HTML file to a running Gotenberg instance via an HTTP request. It also dynamically sets the output filename and embeds metadata (like Author, Title, and Creation Date) directly into the PDF.
  Returns PDF: The workflow outputs the final binary PDF file, ready to be saved, sent in an email, or used in the next step of your main workflow.

  Set up steps

  Setup time: ~3 minutes

  This workflow has one critical prerequisite: a running Gotenberg instance that your n8n can connect to.

  1. Prerequisite: Run Gotenberg

  You need to have the Gotenberg service running. The easiest way is with Docker. Add the following service to your docker-compose.yml file (the same one you use for n8n):

  services:
  ... your n8n service ...

    gotenberg:
      image: gotenberg/gotenberg:8
      restart: always

  Then, restart your stack with docker compose up -d. This makes Gotenberg available at the address http://gotenberg:3000 from within your n8n container.

  2. Use as a Sub-Workflow

  This workflow is ready to be used as a sub-workflow.

  In your main workflow, add an Execute Sub-Workflow node.
  In the Workflow parameter, select this "Create PDF from HTML" workflow.
  Provide the input data in the required format: a JSON object with html and file_name keys.

workflow_json:
  {"meta":{"instanceId":"e409ea34548a2afe2dffba31130cd1cf2e98ebe2afaeed2a63caf2a0582d1da0"},"nodes":[{"id":"f0636fec-85ad-47e8-ab43-9a313664be80","name":"Create index.html","type":"n8n-nodes-base.convertToFile","position":[100,20],"parameters":{"options":{"encoding":"utf8","fileName":"index.html"},"operation":"toText","sourceProperty":"html"},"typeVersion":1.1},{"id":"efcaebc5-e2cc-4af5-a6f2-c75b58496dec","name":"Convert to PDF with Gotenberg","type":"n8n-nodes-base.httpRequest","position":[320,20],"parameters":{"url":"http://gotenberg:3000/forms/chromium/convert/html","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","sendHeaders":true,"bodyParameters":{"parameters":[{"name":"form file","parameterType":"formBinaryData","inputDataFieldName":"data"},{"name":"scale","value":"1"},{"name":"metadata","value":"={\"Author\":\"IA2S\",\"Copyright\":\"IA2S\",\"CreateDate\":\"{{ $now.format('yyyy-MM-dd') }}\",\"Creator\":\"IA2S\",\"Keywords\":[],\"ModDate\":\"{{ $now.format('yyyy-MM-dd') }}\",\"PDFVersion\":1.7,\"Producer\":\"IA2S\",\"Subject\":\"PDF\",\"Title\":\"IA2S PDF\"}"}]},"headerParameters":{"parameters":[{"name":"Gotenberg-Output-Filename","value":"={{ $('Create PDF from HTML').last().json.file_name }}"}]}},"typeVersion":4.2},{"id":"44f89be8-8516-4d8a-a1e4-959c020ca7ae","name":"Create PDF from HTML","type":"n8n-nodes-base.executeWorkflowTrigger","position":[-120,20],"parameters":{"inputSource":"jsonExample","jsonExample":"{\n  \"html\": \"<h1>Hello World</h1>\",\n  \"file_name\": \"my-report-2024\"\n}"},"typeVersion":1.1},{"id":"710d67d4-db4a-4943-9ff7-49af8101443a","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[260,-340],"parameters":{"color":6,"width":320,"height":540,"content":"### 🚀 GOTENBERG API CALL\n\nThis node sends the HTML file to your Gotenberg service for conversion.\n\n**IMPORTANT:**\nThe default URL is `http://gotenberg:3000`. This works if n8n and Gotenberg are on the same Docker network. **If your Gotenberg is hosted elsewhere, you must update the URL here.**\n\n**Customization:**\nYou can edit the PDF metadata (Author, Title, etc.) in the `metadata` field under Body Parameters."},"typeVersion":1},{"id":"365e90ba-b4fa-42b1-9236-33b2f8fb1e76","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-400,-340],"parameters":{"color":7,"width":440,"height":540,"content":"### ▶️ INPUT & CONFIGURATION\n\nThis workflow requires an input with two fields:\n\n1.  `html`: A string containing the full HTML code to be converted.\n2.  `file_name`: The desired name for the output file (without the `.pdf` extension).\n\n**Example Input:**\n```json\n{\n  \"html\": \"<h1>Hello World</h1>\",\n  \"file_name\": \"my-report-2024\"\n}"},"typeVersion":1},{"id":"c8b440bc-fb02-4b77-89c7-62c2bb88d28e","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-880,-340],"parameters":{"color":3,"width":440,"height":280,"content":"### 🐳 PREREQUISITE: GOTENBERG SERVICE\n\nTo use this workflow, you need a running Gotenberg instance.\n\nThe easiest way is to add this to your `docker-compose.yml` and restart your stack:\n\n```yaml\n  gotenberg:\n    image: gotenberg/gotenberg:8\n    restart: always"},"typeVersion":1}],"connections":{"Create index.html":{"main":[[{"node":"Convert to PDF with Gotenberg","type":"main","index":0}]]},"Create PDF from HTML":{"main":[[{"node":"Create index.html","type":"main","index":0}]]}}}


name: Translate RSS Feed Content to Hindi and Publish to WordPress with OpenAI
author_name: The Higher Pitch
author_username: digvijay
categories: []
created_at: 2025-06-23T10:52:16.997Z
updated_at: 2025-06-23T10:52:16.997Z
url: https://n8n.io/workflows/5150
scraped_at: 2025-07-06 21:16:30
description:
  This workflow automatically pulls articles from an RSS feed, translates the content and title from English to Hindi using OpenAI, extracts the featured image from the HTML content, and publishes the translated post as a draft on a connected WordPress site.

  🔧 Key Features:

  Polls RSS feed every 10 minutes for new articles

  Extracts and parses the featured image from custom HTML tags

  Translates content and title from English to Hindi using OpenAI Assistant

  Uploads the featured image to WordPress media library

  Associates the image with the new draft post

  Publishes the translated article as a draft for review

  🎯 Use Case:
  Ideal for multi-language blog automation or content localization workflows where original content is in English and needs to be localized into Hindi before publishing.

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

workflow_json:
  {"id":"HmlNHuYYzQAhoImx","meta":{"instanceId":"ca7e4439d37f2d7ddaa363ea2b029357e1ee59824d58b9533ac05bf57f803d9d","templateCredsSetupCompleted":true},"name":"Groovenexus English to Hindi Final","tags":[],"nodes":[{"id":"8528c900-c5a9-417f-88b7-b881445b5807","name":"RSS Feed Trigger","type":"n8n-nodes-base.rssFeedReadTrigger","position":[40,0],"parameters":{"feedUrl":"https://www.abc.com/uncategorized-hi/hindi-blog/feed/","pollTimes":{"item":[{"mode":"everyX","unit":"minutes","value":10}]}},"typeVersion":1},{"id":"96448786-b6eb-46ca-b3dc-7d8f1bec3594","name":"Wordpress","type":"n8n-nodes-base.wordpress","position":[1160,0],"parameters":{"title":"={{ $json.output }}","additionalFields":{"status":"draft","content":"={{ $('Content English to Hindi').item.json.output }}","authorId":16,"categories":[130],"postTemplate":{"values":{}}}},"credentials":{"wordpressApi":{"id":"","name":"ABC Hindi Website"}},"typeVersion":1},{"id":"48763deb-8d7f-4e92-ac09-69d5fa54828f","name":"Upload Image to Wordpress","type":"n8n-nodes-base.httpRequest","position":[720,260],"parameters":{"url":"https://www.abc.com/hindi/wp-json/wp/v2/media","method":"POST","options":{},"sendBody":true,"contentType":"binaryData","sendHeaders":true,"authentication":"predefinedCredentialType","headerParameters":{"parameters":[{"name":"Content-Disposition","value":"=attachment; filename=\"cover-image-{{ $('Wordpress').item.json.id }}.jpeg\""}]},"inputDataFieldName":"data","nodeCredentialType":"wordpressApi"},"credentials":{"wordpressApi":{"id":"LTsdRUgRpnQTGZja","name":"Abc Hindi Website"}},"typeVersion":4.2},{"id":"7a684f71-c859-484a-b402-774c4a36c261","name":"Set Image on Wordpress Post","type":"n8n-nodes-base.httpRequest","position":[1000,260],"parameters":{"url":"=https://www.abc.com/hindi/wp-json/wp/v2/posts/{{ $('Wordpress').item.json.id }}","method":"POST","options":{},"sendQuery":true,"authentication":"predefinedCredentialType","queryParameters":{"parameters":[{"name":"=featured_media","value":"={{ $json.id }}"}]},"nodeCredentialType":"wordpressApi"},"credentials":{"wordpressApi":{"id":"","name":"abc Hindi Website"}},"typeVersion":4.2},{"id":"a2208042-6ff8-48e3-a829-6128bde0446e","name":"GET Image","type":"n8n-nodes-base.httpRequest","position":[520,260],"parameters":{"url":"={{ $json[\"image-url\"] }}","options":{}},"typeVersion":4.2},{"id":"1454e0bc-462e-4446-9f66-3cc3429e2f81","name":"Set Image URL","type":"n8n-nodes-base.set","position":[320,260],"parameters":{"options":{},"assignments":{"assignments":[{"id":"1f0541df-05ab-4e3d-a5d8-3904579fc8a9","name":"image-url","type":"string","value":"={{ $('Code1').item.json.featuredImage }}"}]}},"typeVersion":3.4},{"id":"f1720d6b-b344-4866-bcb1-36495fde6a06","name":"Content English to Hindi","type":"@n8n/n8n-nodes-langchain.openAi","position":[440,0],"parameters":{"text":"={{ $json['content:encoded'] }}","prompt":"define","options":{},"resource":"assistant","assistantId":{"__rl":true,"mode":"list","value":"asst_ydjGgj8Sax8qJgRgLh6XfBHB","cachedResultName":"English to Hindi"}},"credentials":{"openAiApi":{"id":"","name":"OpenAi account 3"}},"typeVersion":1.8},{"id":"3d45c40e-642d-4b3e-8a11-bc6c9a0c25ff","name":"Title convert","type":"@n8n/n8n-nodes-langchain.openAi","position":[800,0],"parameters":{"text":"={{ $('RSS Feed Trigger').item.json.title }}","prompt":"define","options":{},"resource":"assistant","assistantId":{"__rl":true,"mode":"list","value":"asst_ydjGgj8Sax8qJgRgLh6XfBHB","cachedResultName":"English to Hindi"}},"credentials":{"openAiApi":{"id":"N9Rmx2XNuFHkb5uR","name":"OpenAi account 3"}},"typeVersion":1.8},{"id":"a551a234-c441-4248-a3b4-2d691b870c51","name":"Code1","type":"n8n-nodes-base.code","position":[240,0],"parameters":{"jsCode":"const items = $input.all();\nconst updatedItems = items.map((item) => {\n  const content = item?.json[\"content:encoded\"];\n  const match = content.match(/<featured-image>(.*?)<\\/featured-image>/);\n  item.json.featuredImage = match ? match[1] : null;\n  return item;\n});\nreturn updatedItems;\n"},"typeVersion":2}],"active":true,"settings":{"executionOrder":"v1"},"versionId":"5b9ae900-cad6-4b32-95f3-3a66650054d4","connections":{"Code1":{"main":[[{"node":"Content English to Hindi","type":"main","index":0}]]},"GET Image":{"main":[[{"node":"Upload Image to Wordpress","type":"main","index":0}]]},"Wordpress":{"main":[[{"node":"Set Image URL","type":"main","index":0}]]},"Set Image URL":{"main":[[{"node":"GET Image","type":"main","index":0}]]},"Title convert":{"main":[[{"node":"Wordpress","type":"main","index":0}]]},"RSS Feed Trigger":{"main":[[{"node":"Code1","type":"main","index":0}]]},"Content English to Hindi":{"main":[[{"node":"Title convert","type":"main","index":0}]]},"Upload Image to Wordpress":{"main":[[{"node":"Set Image on Wordpress Post","type":"main","index":0}]]}}}


name: Automate Customer Support with Gmail, Google Sheets, ERP Data & GPT-4o AI
author_name: AOE Agent Lab
author_username: aoepeople
categories: []
created_at: 2025-06-23T11:45:30.982Z
updated_at: 2025-06-23T11:45:30.982Z
url: https://n8n.io/workflows/5152
scraped_at: 2025-07-06 21:16:30
description:
  🌐 AI Customer Support Assistant - Cloud Version

  What this workflow does:

  This AI-powered customer support automation processes incoming support requests via email or chat, analyzes them using AI, retrieves relevant context, and generates draft responses for support agents.

  Key Features:

  ✅ Multi-channel Input: Email & chat triggers
  ✅ AI-powered Analysis: Extracts sentiment, urgency, and key information
  ✅ Context Integration: Combines product manuals, ERP data, and support history
  ✅ Draft Response Generation: Creates professional responses in German
  ✅ Human-in-the-loop: Approval workflow before sending to customers

  Demo Instructions:
  Use the Chat interface to test with sample customer queries
  Or send test emails to trigger the email workflow
  Watch how AI analyzes and generates contextual responses

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

workflow_json:
  {"id":"tMuFNayeeZYimHLR","meta":{"instanceId":"88b34e051213082619adc89dcb3c4c6a3611f57a17080c0af86efd3b8840b94f","templateCredsSetupCompleted":true},"name":"[MW] AI Customer Support Assistant - Cloud Version","tags":[],"nodes":[{"id":"b617607e-61ae-4107-a72e-2a23b5a57c75","name":"📋 Workflow Overview","type":"n8n-nodes-base.stickyNote","position":[0,0],"parameters":{"width":450,"height":760,"content":"# 🌐 AI Customer Support Assistant - Cloud Version\n\n## What this workflow does:\nThis AI-powered customer support automation processes incoming support requests via email or chat, analyzes them using AI, retrieves relevant context, and generates draft responses for support agents.\n\n## Key Features:\n✅ **Multi-channel Input**: Email & chat triggers\n✅ **AI-powered Analysis**: Extracts sentiment, urgency, and key information\n✅ **Context Integration**: Combines product manuals, ERP data, and support history\n✅ **Draft Response Generation**: Creates professional responses in German\n✅ **Human-in-the-loop**: Approval workflow before sending to customers\n\n## Demo Instructions:\n1. Use the Chat interface to test with sample customer queries\n2. Or send test emails to trigger the email workflow\n3. Watch how AI analyzes and generates contextual responses\n\n**🌐 This is the CLOUD version using OpenAI and Google services**"},"typeVersion":1},{"id":"918dd7a6-1c69-43ed-872d-052ebf20a396","name":"📧 Email Input","type":"n8n-nodes-base.stickyNote","position":[500,300],"parameters":{"color":2,"width":280,"height":320,"content":"## 📧 Email Trigger\n\n**Purpose**: Monitors Gmail for incoming customer support requests\n\n**How it works**:\n• Polls Gmail every minute for new emails\n• Filters can be configured for specific labels/criteria\n• Extracts email content, sender info, and metadata\n\n**Demo tip**: Send a test email to see this in action!"},"typeVersion":1},{"id":"cd753c63-7f5f-4e44-901a-d23eca0cb8e9","name":"📧 Support Email Received","type":"n8n-nodes-base.gmailTrigger","position":[620,660],"parameters":{"filters":{},"pollTimes":{"item":[{"mode":"everyMinute"}]}},"credentials":{"gmailOAuth2":{"id":"I74VnrmPeKRcOolp","name":"Gmail account dummy@mail.com"}},"typeVersion":1.2},{"id":"175a7569-f8d5-49b6-95ca-a83026b2aea4","name":"💬 Chat Input","type":"n8n-nodes-base.stickyNote","position":[480,1160],"parameters":{"color":2,"width":280,"height":320,"content":"## 💬 Chat Trigger\n\n**Purpose**: Provides a real-time chat interface for testing\n\n**How it works**:\n• Creates a webhook URL for chat interactions\n• Ideal for demos and testing scenarios\n• Processes messages instantly\n\n**Demo tip**: Perfect for live demonstrations!"},"typeVersion":1},{"id":"f9f43182-9113-4ba0-b2a9-b82f3f9b5d46","name":"🧠 AI Analysis","type":"n8n-nodes-base.stickyNote","position":[940,300],"parameters":{"color":3,"width":300,"height":380,"content":"## 🧠 AI Information Extractor\n\n**Purpose**: Analyzes customer messages with AI to extract structured data\n\n**Extracts**:\n• Category (technical, billing, sales, etc.)\n• Urgency level (low, medium, high, critical)\n• Customer sentiment\n• Keywords for context search\n• Product identifiers\n• Required action type\n\n**AI Model**: OpenAI GPT-4o-mini"},"typeVersion":1},{"id":"99ce470b-9c71-4303-a515-d197bfbf2d78","name":"🤖 OpenAI Model (Extractor)","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[960,980],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"M0gBX6dGinkN0Qym","name":"OpenAi account (n8n project)"}},"typeVersion":1.2},{"id":"e55da351-bb97-49a8-bbe7-f9f5814f7874","name":"📊 Context Data","type":"n8n-nodes-base.stickyNote","position":[1540,300],"parameters":{"color":4,"width":300,"height":380,"content":"## 📊 Historical Support Data\n\n**Purpose**: Retrieves previous support cases for context\n\n**Data Source**: Google Sheets with historical customer interactions\n\n**Contains**:\n• Previous questions & answers\n• Common issues & solutions\n• Response templates\n• Product-specific guidance\n\n**Why important**: Ensures consistent, high-quality responses"},"typeVersion":1},{"id":"aaf740e0-d78b-41d3-ba92-811c32b06f76","name":"📊 Historical Support Cases","type":"n8n-nodes-base.googleSheets","position":[1540,780],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"list","value":1526853854,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/1iiUzIfOoza0czupn_-4oTY6eOmH4vSENwnjSJ6Uxen4/edit#gid=1526853854","cachedResultName":"zeiss_primotech_support"},"documentId":{"__rl":true,"mode":"list","value":"1iiUzIfOoza0czupn_-4oTY6eOmH4vSENwnjSJ6Uxen4","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1iiUzIfOoza0czupn_-4oTY6eOmH4vSENwnjSJ6Uxen4/edit?usp=drivesdk","cachedResultName":"Zeiss Primotech Demo customer requests"}},"credentials":{"googleSheetsOAuth2Api":{"id":"cZ8QhseWRie9tDzV","name":"Google Sheets account dummy@mail.com"}},"typeVersion":4.5},{"id":"16e63750-b911-458d-b18d-7ced534dbc44","name":"📋 Aggregate Support Data","type":"n8n-nodes-base.aggregate","position":[1740,780],"parameters":{"options":{},"aggregate":"aggregateAllItemData"},"typeVersion":1},{"id":"00c1c023-982b-49f7-a422-f02a3aa1c2a7","name":"📚 Knowledge Base","type":"n8n-nodes-base.stickyNote","position":[1160,980],"parameters":{"color":4,"width":300,"height":440,"content":"## 📚 Product Knowledge Base\n\n**Purpose**: Accesses comprehensive product documentation\n\n**Data Source**: Google Drive (Primotech Manual PDF)\n\n**Contains**:\n• Technical specifications\n• Operating instructions\n• Troubleshooting guides\n• Safety information\n\n**Processing**: PDF text extraction for AI analysis\n\n**Cloud advantage**: Always up-to-date documentation"},"typeVersion":1},{"id":"d4689f32-4c6c-4fab-94ef-4631b7b07632","name":"📚 Download Product Manual","type":"n8n-nodes-base.googleDrive","position":[1540,1140],"parameters":{"fileId":{"__rl":true,"mode":"list","value":"1_MKUQLEw2RS8k-QgAP5rtw-tD49A82lG","cachedResultUrl":"https://drive.google.com/file/d/1_MKUQLEw2RS8k-QgAP5rtw-tD49A82lG/view?usp=drivesdk","cachedResultName":"Primotech_Manual.pdf"},"options":{},"operation":"download"},"credentials":{"googleDriveOAuth2Api":{"id":"urrYsyCll4whiZup","name":"Google Drive account"}},"typeVersion":3},{"id":"c291af40-8db0-4050-ad29-17774465cdb0","name":"📄 Extract PDF Content","type":"n8n-nodes-base.extractFromFile","position":[1740,1140],"parameters":{"options":{},"operation":"pdf"},"typeVersion":1},{"id":"e9a2cbd2-07eb-41a3-9333-2a3d4b936fe2","name":"🏢 ERP Integration","type":"n8n-nodes-base.stickyNote","position":[1500,1700],"parameters":{"color":5,"width":440,"height":360,"content":"## 🏢 ERP System Integration\n\n**Purpose**: Retrieves customer & inventory data\n\n**Data Source**: Mock ERP API (demo purposes)\n\n**Provides**:\n• Customer account information\n• Order history\n• Product availability\n• Spare part pricing\n\n**Note**: In production, this would connect to your real ERP system\n\n**Cloud benefit**: Real-time data access"},"typeVersion":1},{"id":"861dd2a5-b3ad-463c-aa19-f79c7b51c424","name":"🏢 Check ERP System","type":"n8n-nodes-base.httpRequest","position":[1560,1500],"parameters":{"url":"https://run.mocky.io/v3/d8892875-55d6-449d-bab3-3cb7a7b419c0","options":{}},"typeVersion":3},{"id":"578d7499-4c72-4181-b1c8-89b05d3bdae0","name":"🤖 AI Response Generation","type":"n8n-nodes-base.stickyNote","position":[2000,1020],"parameters":{"color":3,"width":320,"height":400,"content":"## 🤖 Response Generation\n\n**Purpose**: Creates professional customer responses using AI\n\n**AI Model**: OpenAI GPT-4o-mini\n\n**Input Context**:\n• Customer's original message\n• Extracted information (sentiment, urgency, etc.)\n• Product manual content\n• Historical support cases\n• ERP data (pricing, availability)\n\n**Output**: Professional German response following company standards"},"typeVersion":1},{"id":"9858ac0e-2f3a-4476-a892-25c51b6dd654","name":"🤖 Generate Customer Response","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[1960,1500],"parameters":{"text":"=This GPT acts as an expert customer support agent designed to draft thoughtful, accurate responses to customer queries. It takes in customer questions and leverages internal product documentation and a history of previously answered queries to prewrite complete and contextually appropriate replies. The GPT uses the full content of \n\n1. the uploaded Primotech Instruction Manual (in German): \n\n2. a CSV dataset of historical customer questions: {{ $('📋 Aggregate Support Data').item.json.data.toJsonString() }}\n\n3. Customer's original query: {{ \n$('Chat Message Received').isExecuted && $('Chat Message Received').last().json.chatInput;\n$('📧 Support Email Received') && $('📧 Support Email Received').item.json.snippet \n$('When clicking ‘Execute workflow’').isExecuted && $('When clicking ‘Execute workflow’').item.json.snippet\n}} \n\nand answers related to ZEISS Primotech microscopes. These sources provide comprehensive technical, usage, troubleshooting, and product-specific guidance.\n\nThe assistant aims to reduce agent workload by anticipating common follow-up questions, referencing appropriate product knowledge, and maintaining a polite, clear, and supportive tone. It is optimized for high response accuracy, minimal ambiguity, and internal efficiency.\n\nThe assistant never performs web searches. When the available context is insufficient to fully answer a query, it does not generate a customer email. Instead, it presents a warning for the human agent and offers any possibly relevant internal context that may assist in formulating a manual response.\n\nIt avoids answering questions that cannot be supported by available documentation and flags those for manual review. When generating responses, it uses complete, customer-facing sentences, structured for easy review and editing by human support agents, and may include links or references when based on internal content. Clarification is only requested when strictly necessary. If required data is missing, the assistant highlights placeholders for agent completion.\n\nAll responses that are complete must follow this structure:\n- Use a proper salutation starting with 'Sehr geehrter Herr' or 'Sehr geehrte Frau' followed by the customer's last name, if available. If no name is provided, use 'Sehr geehrte/r Kunde/in,'.\n- Begin with 'herzlichen Dank für Ihre Nachricht.'\n- Then insert the drafted response body.\n- If the request involves a spare part, the assistant uses the following API response and includes the relevant spare part name and price from the returned JSON: {{ $json.inventory.toJsonString() }}\n- Close with: 'Bei weiteren Fragen stehen wir Ihnen gerne zur Verfügung, gerne können sie auch unsere (HILFE Seite)[http://www.zeiss.de] besuchen.' and 'Ich wünsche Ihnen einen schönen Tag!'\n\nThe assistant uses professional and accessible language, aligned with the tone expected in technical product support, and maintains a helpful and competent demeanor throughout.","promptType":"define"},"typeVersion":1.6,"alwaysOutputData":false},{"id":"263a08b7-c29a-4556-af0d-2a42c7981f0f","name":"🤖 OpenAI Model (Generator)","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[1980,1680],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"M0gBX6dGinkN0Qym","name":"OpenAi account (n8n project)"}},"typeVersion":1.2},{"id":"769b302a-63b2-4801-9b0c-bb25d1f3e432","name":"👥 Quality Control","type":"n8n-nodes-base.stickyNote","position":[2420,900],"parameters":{"color":6,"width":320,"height":460,"content":"## 👥 Human-in-the-Loop Approval\n\n**Purpose**: Ensures quality control before sending responses\n\n**Process**:\n1. AI-generated response is sent to support agent\n2. Agent reviews and can approve/reject/modify\n3. Only approved responses are sent to customers\n\n**Benefits**:\n• Quality assurance\n• Learning from modifications\n• Regulatory compliance\n\n**Note**: Critical for maintaining customer trust"},"typeVersion":1},{"id":"33aa86d8-f613-4d9b-921c-781c796b23d1","name":"📧 Email or Chat?","type":"n8n-nodes-base.if","position":[2280,1500],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"2473fa5c-8b22-479c-95e7-583d4adb934f","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $('📧 Support Email Received').isExecuted }}","rightValue":"true"}]}},"typeVersion":2.2,"alwaysOutputData":false},{"id":"8eee920b-1a44-4a8a-8db9-6ca32d9d0083","name":"📧 Request Approval (Email)","type":"n8n-nodes-base.gmail","position":[2460,1400],"webhookId":"7e79cf64-9f20-4968-9bca-3f4dca48ec4c","parameters":{"sendTo":"dummy@mail.com","message":"=A customer support response has been generated and requires your approval:\n\n**Customer Query**: \n{{ \n$('Chat Message Received').isExecuted ?? $('Chat Message Received').last().json.chatInput\n$('📧 Support Email Received').isExecuted ?? $('📧 Support Email Received').item.json.snippet \n$('When clicking ‘Execute workflow’').isExecuted ?? $('When clicking ‘Execute workflow’').item.json.snippet\n}}\n\n**Generated Response**:\n{{ $json.text }}\n\nPlease review and approve/reject this response.","options":{},"subject":"Customer Support Response - Approval Required","operation":"sendAndWait","approvalOptions":{"values":{"approvalType":"double"}}},"credentials":{"gmailOAuth2":{"id":"I74VnrmPeKRcOolp","name":"Gmail account dummy@mail.com"}},"typeVersion":2.1},{"id":"eee108b0-2d0d-4140-b298-ac0a6bb4422e","name":"📤 Send Response to Customer","type":"n8n-nodes-base.gmail","position":[2680,1400],"webhookId":"c994c7a5-5edb-4167-81dd-22e33625450a","parameters":{"sendTo":"={{ $('📧 Support Email Received').item.json.From }}","message":"={{ $('🤖 Generate Customer Response').item.json.text }}","options":{},"subject":"Re: Your Support Request"},"credentials":{"gmailOAuth2":{"id":"I74VnrmPeKRcOolp","name":"Gmail account dummy@mail.com"}},"typeVersion":2.1},{"id":"b6bb5258-6b1b-48b1-994b-9dbed3062559","name":"📝 Format Chat Response","type":"n8n-nodes-base.set","position":[2460,1600],"parameters":{"options":{},"assignments":{"assignments":[{"id":"409c228d-783f-4e7f-aa47-f0271d8409f8","name":"text","type":"string","value":"={{ $json.text }}"}]}},"typeVersion":3.4},{"id":"3815458b-3b11-472f-9718-f9fd523b3325","name":"Chat Message Received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[620,1020],"webhookId":"3ec1feb8-fc70-4e24-9370-debc47defe81","parameters":{"options":{}},"typeVersion":1.1},{"id":"9f6013c5-f25f-4134-b9b3-9eed10e10db8","name":"AI Information Extractor","type":"@n8n/n8n-nodes-langchain.informationExtractor","position":[940,780],"parameters":{"text":"={{ $json.chatInput ? $json.chatInput : $json.snippet }}","options":{},"schemaType":"manual","inputSchema":"{\n  \"type\": \"object\",\n  \"required\": [\"category\", \"urgency\", \"sentiment\", \"keywords\", \"productIdentifiers\", \"customerInfo\", \"requiredAction\"],\n  \"properties\": {\n    \"category\": {\n      \"type\": \"string\",\n      \"enum\": [\"technical\", \"billing\", \"sales\", \"returns\", \"general\"],\n      \"description\": \"The primary category of the customer request\"\n    },\n    \"urgency\": {\n      \"type\": \"string\",\n      \"enum\": [\"low\", \"medium\", \"high\", \"critical\"],\n      \"description\": \"How time-sensitive the request is\"\n    },\n    \"sentiment\": {\n      \"type\": \"string\",\n      \"enum\": [\"positive\", \"neutral\", \"negative\", \"very_negative\"],\n      \"description\": \"The emotional tone of the customer's message\"\n    },\n    \"keywords\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"string\"\n      },\n      \"description\": \"Key terms extracted from the request for searching knowledge base and ERP\"\n    },\n    \"productIdentifiers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"type\": {\n            \"type\": \"string\",\n            \"enum\": [\"model\", \"serial\", \"part\"]\n          },\n          \"value\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"description\": \"Any product numbers, models, or parts mentioned in the request\"\n    },\n    \"customerInfo\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"firstName\": {\n          \"type\": \"string\"\n        },\n        \"lastName\": {\n          \"type\": \"string\"\n        },\n        \"customerId\": {\n          \"type\": \"string\",\n          \"description\": \"CRM Customer Id\"\n        },\n        \"mentionsCompetitor\": {\n          \"type\": \"boolean\",\n          \"description\": \"Customer references a competitor product or service\"\n        }\n      }\n    },\n    \"requiredAction\": {\n      \"type\": \"string\",\n      \"enum\": [\"information\", \"replacement\", \"refund\", \"repair\", \"callback\", \"escalation\"],\n      \"description\": \"The primary action needed to resolve the customer's request\"\n    }\n  }}"},"typeVersion":1},{"id":"7fc3e443-9653-4706-a612-413fb6df1e23","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[0,800],"parameters":{"color":7,"width":440,"height":200,"content":"## How to run a demo\n- add google / openai credentials\n- change email of approver to something you can access"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"583ed6b5-00f7-4fbf-8354-5740c8c59376","connections":{"📧 Email or Chat?":{"main":[[{"node":"📧 Request Approval (Email)","type":"main","index":0}],[{"node":"📝 Format Chat Response","type":"main","index":0}]]},"Chat Message Received":{"main":[[{"node":"AI Information Extractor","type":"main","index":0}]]},"🏢 Check ERP System":{"main":[[{"node":"🤖 Generate Customer Response","type":"main","index":0}]]},"AI Information Extractor":{"main":[[{"node":"📊 Historical Support Cases","type":"main","index":0}]]},"📄 Extract PDF Content":{"main":[[{"node":"🏢 Check ERP System","type":"main","index":0}]]},"📋 Aggregate Support Data":{"main":[[{"node":"📚 Download Product Manual","type":"main","index":0}]]},"📧 Support Email Received":{"main":[[{"node":"AI Information Extractor","type":"main","index":0}]]},"📚 Download Product Manual":{"main":[[{"node":"📄 Extract PDF Content","type":"main","index":0}]]},"📊 Historical Support Cases":{"main":[[{"node":"📋 Aggregate Support Data","type":"main","index":0}]]},"📧 Request Approval (Email)":{"main":[[{"node":"📤 Send Response to Customer","type":"main","index":0}]]},"🤖 OpenAI Model (Extractor)":{"ai_languageModel":[[{"node":"AI Information Extractor","type":"ai_languageModel","index":0}]]},"🤖 OpenAI Model (Generator)":{"ai_languageModel":[[{"node":"🤖 Generate Customer Response","type":"ai_languageModel","index":0}]]},"🤖 Generate Customer Response":{"main":[[{"node":"📧 Email or Chat?","type":"main","index":0}]]}}}


name: TikTok Post Scraper via Keywords | Bright Data + Sheets Integration
author_name: Shiv Gupta
author_username: shivgupta
nodes_used: ["n8n-nodes-base.googleSheets","n8n-nodes-base.httpRequest"]
categories: []
created_at: 2025-06-23T11:59:55.041Z
updated_at: 2025-06-23T11:59:55.041Z
url: https://n8n.io/workflows/5153
scraped_at: 2025-07-06 21:16:30
description:
  🎵 TikTok Post Scraper via Keywords | Bright Data + Sheets Integration

  📝 Workflow Description
  Automatically scrapes TikTok posts based on keyword search using Bright Data API and stores comprehensive data in Google Sheets for analysis and monitoring.

  🔄 How It Works

  This workflow operates through a simple, automated process:

  Keyword Input:** User submits search keywords through a web form
  Data Scraping:** Bright Data API searches TikTok for posts matching the keywords
  Processing Loop:** Monitors scraping progress and waits for completion
  Data Storage:** Automatically saves all extracted data to Google Sheets
  Result Delivery:** Provides comprehensive post data including metrics, user info, and media URLs

  ⏱️ Setup Information

  Estimated Setup Time: 10-15 minutes

  This includes importing the workflow, configuring credentials, and testing the integration. Most of the process is automated once properly configured.

  ✨ Key Features

  📝 Keyword-Based Search
  Search TikTok posts using specific keywords

  📊 Comprehensive Data Extraction
  Captures post metrics, user profiles, and media URLs

  📋 Google Sheets Integration
  Automatically organizes data in spreadsheets

  🔄 Automated Processing
  Handles scraping progress monitoring

  🛡️ Reliable Scraping
  Uses Bright Data's professional infrastructure

  ⚡ Real-time Updates
  Live status monitoring and data processing

  📊 Data Extracted

  | Field | Description | Example |
  |-------|-------------|---------|
  | url | TikTok post URL | https://www.tiktok.com/@user/video/123456 |
  | post_id | Unique post identifier | 7234567890123456789 |
  | description | Post caption/description | Check out this amazing content! #viral |
  | digg_count | Number of likes | 15400 |
  | share_count | Number of shares | 892 |
  | comment_count | Number of comments | 1250 |
  | play_count | Number of views | 125000 |
  | profile_username | Creator's username | @creativity_master |
  | profile_followers | Creator's follower count | 50000 |
  | hashtags | Post hashtags | #viral #trending #fyp |
  | create_time | Post creation timestamp | 2025-01-15T10:30:00Z |
  | video_url | Direct video URL | https://video.tiktok.com/tos/... |

  🚀 Setup Instructions

  Step 1: Prerequisites

  n8n instance (self-hosted or cloud)
  Bright Data account with TikTok scraping dataset access
  Google account with Sheets access
  Basic understanding of n8n workflows

  Step 2: Import Workflow

  Copy the provided JSON workflow code
  In n8n: Go to Workflows → + Add workflow → Import from JSON
  Paste the JSON code and click Import
  The workflow will appear in your n8n interface

  Step 3: Configure Bright Data

  In n8n: Navigate to Credentials → + Add credential → Bright Data API
  Enter your Bright Data API credentials
  Test the connection to ensure it's working
  Update the workflow nodes with your dataset ID: gd_lu702nij2f790tmv9h
  Replace BRIGHT_DATA_API_KEY with your actual API key

  Step 4: Configure Google Sheets

  Create a new Google Sheet or use an existing one
  Copy the Sheet ID from the URL
  In n8n: Credentials → + Add credential → Google Sheets OAuth2 API
  Complete OAuth setup and test connection
  Update the Google Sheets node with your Sheet ID
  Ensure the sheet has a tab named "Tiktok by keyword"

  Step 5: Test the Workflow

  Activate the workflow using the toggle switch
  Access the form trigger URL to submit a test keyword
  Monitor the workflow execution in n8n
  Verify data appears in your Google Sheet
  Check that all fields are populated correctly

  ⚙️ Configuration Details

  Bright Data API Settings
  Dataset ID:** gd_lu702nij2f790tmv9h
  Discovery Type:** discover_new
  Search Method:** keyword
  Results per Input:** 2 posts per keyword
  Include Errors:** true

  Workflow Parameters
  Wait Time:** 1 minute between status checks
  Status Check:** Monitors until scraping is complete
  Data Format:** JSON response from Bright Data
  Error Handling:** Automatic retry on incomplete scraping

  📋 Usage Guide

  Running the Workflow

  Access the form trigger URL provided by n8n
  Enter your desired keyword (e.g., "viral dance", "cooking tips")
  Submit the form to start the scraping process
  Wait for the workflow to complete (typically 2-5 minutes)
  Check your Google Sheet for the extracted data

  Best Practices

  Use specific, relevant keywords for better results
  Monitor your Bright Data usage to stay within limits
  Regularly backup your Google Sheets data
  Test with simple keywords before complex searches
  Review extracted data for accuracy and completeness

  🔧 Troubleshooting

  Common Issues

  🚨 Scraping Not Starting
  Verify Bright Data API credentials are correct
  Check dataset ID matches your account
  Ensure sufficient credits in Bright Data account

  🚨 No Data in Google Sheets
  Confirm Google Sheets credentials are authenticated
  Verify sheet ID is correct
  Check that the "Tiktok by keyword" tab exists

  🚨 Workflow Timeout
  Increase wait time if scraping takes longer
  Check Bright Data dashboard for scraping status
  Verify keyword produces available results

  📈 Use Cases

  Content Research
  Research trending content and hashtags in your niche to inform your content strategy.

  Competitor Analysis
  Monitor competitor posts and engagement metrics to understand market trends.

  Influencer Discovery
  Find influencers and creators in specific topics or industries.

  Market Intelligence
  Gather data on trending topics, hashtags, and user engagement patterns.

  🔒 Security Notes

  Keep your Bright Data API credentials secure
  Use appropriate Google Sheets sharing permissions
  Monitor API usage to prevent unexpected charges
  Regularly rotate API keys for better security
  Comply with TikTok's terms of service and data usage policies

  🎉 Ready to Use!

  Your TikTok scraper is now configured and ready to extract valuable data. Start with simple keywords and gradually expand your research as you become familiar with the workflow.

  Need Help? Visit the n8n community forum or check the Bright Data documentation for additional support and advanced configuration options.

  For any questions or support, please contact: Email or
  fill out this form

workflow_json:
  {"id":"H2OMONcmT6qIf0p0","meta":{"instanceId":"bc8ca75c203589705ae2e446cad7181d6f2a7cc1766f958ef9f34810e53b8cb2","templateCredsSetupCompleted":true},"name":"TikTok Post Scraper via Keywords | Bright Data + Sheets Integration","tags":[],"nodes":[{"id":"3c96466a-128d-403a-8449-b54001944b1d","name":"Google Sheets","type":"n8n-nodes-base.googleSheets","position":[-540,-560],"parameters":{"columns":{"value":{"url":"={{ $json.url }}","input":"={{ $json.input }}","music":"={{ $json.music }}","ratio":"={{ $json.ratio }}","width":"={{ $json.width }}","region":"={{ $json.region }}","cdn_url":"={{ $json.cdn_url }}","post_id":"={{ $json.post_id }}","secu_id":"={{ $json.secu_id }}","hashtags":"={{ $json.hashtags }}","post_type":"={{ $json.post_type }}","shortcode":"={{ $json.shortcode }}","timestamp":"={{ $json.timestamp }}","video_url":"={{ $json.video_url }}","account_id":"={{ $json.account_id }}","digg_count":"={{ $json.digg_count }}","play_count":"={{ $json.play_count }}","profile_id":"={{ $json.profile_id }}","create_time":"={{ $json.create_time }}","description":"={{ $json.description }}","is_verified":"={{ $json.is_verified }}","profile_url":"={{ $json.profile_url }}","share_count":"={{ $json.share_count }}","offical_item":"={{ $json.offical_item }}","collect_count":"={{ $json.collect_count }}","comment_count":"={{ $json.comment_count }}","original_item":"={{ $json.original_item }}","preview_image":"={{ $json.preview_image }}","original_sound":"={{ $json.original_sound }}","profile_avatar":"={{ $json.profile_avatar }}","tt_chain_token":"={{ $json.tt_chain_token }}","video_duration":"={{ $json.video_duration }}","discovery_input":"={{ $json.discovery_input }}","profile_username":"={{ $json.profile_username }}","profile_biography":"={{ $json.profile_biography }}","profile_followers":"={{ $json.profile_followers }}"},"schema":[{"id":"url","type":"string","display":true,"removed":false,"required":false,"displayName":"url","defaultMatch":false,"canBeUsedToMatch":true},{"id":"post_id","type":"string","display":true,"removed":false,"required":false,"displayName":"post_id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"description","type":"string","display":true,"removed":false,"required":false,"displayName":"description","defaultMatch":false,"canBeUsedToMatch":true},{"id":"create_time","type":"string","display":true,"removed":false,"required":false,"displayName":"create_time","defaultMatch":false,"canBeUsedToMatch":true},{"id":"digg_count","type":"string","display":true,"removed":false,"required":false,"displayName":"digg_count","defaultMatch":false,"canBeUsedToMatch":true},{"id":"share_count","type":"string","display":true,"removed":false,"required":false,"displayName":"share_count","defaultMatch":false,"canBeUsedToMatch":true},{"id":"collect_count","type":"string","display":true,"removed":false,"required":false,"displayName":"collect_count","defaultMatch":false,"canBeUsedToMatch":true},{"id":"comment_count","type":"string","display":true,"removed":false,"required":false,"displayName":"comment_count","defaultMatch":false,"canBeUsedToMatch":true},{"id":"play_count","type":"string","display":true,"removed":false,"required":false,"displayName":"play_count","defaultMatch":false,"canBeUsedToMatch":true},{"id":"video_duration","type":"string","display":true,"removed":false,"required":false,"displayName":"video_duration","defaultMatch":false,"canBeUsedToMatch":true},{"id":"hashtags","type":"string","display":true,"removed":false,"required":false,"displayName":"hashtags","defaultMatch":false,"canBeUsedToMatch":true},{"id":"original_sound","type":"string","display":true,"removed":false,"required":false,"displayName":"original_sound","defaultMatch":false,"canBeUsedToMatch":true},{"id":"profile_id","type":"string","display":true,"removed":false,"required":false,"displayName":"profile_id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"profile_username","type":"string","display":true,"removed":false,"required":false,"displayName":"profile_username","defaultMatch":false,"canBeUsedToMatch":true},{"id":"profile_url","type":"string","display":true,"removed":false,"required":false,"displayName":"profile_url","defaultMatch":false,"canBeUsedToMatch":true},{"id":"profile_avatar","type":"string","display":true,"removed":false,"required":false,"displayName":"profile_avatar","defaultMatch":false,"canBeUsedToMatch":true},{"id":"profile_biography","type":"string","display":true,"removed":false,"required":false,"displayName":"profile_biography","defaultMatch":false,"canBeUsedToMatch":true},{"id":"preview_image","type":"string","display":true,"removed":false,"required":false,"displayName":"preview_image","defaultMatch":false,"canBeUsedToMatch":true},{"id":"post_type","type":"string","display":true,"removed":false,"required":false,"displayName":"post_type","defaultMatch":false,"canBeUsedToMatch":true},{"id":"discovery_input","type":"string","display":true,"removed":false,"required":false,"displayName":"discovery_input","defaultMatch":false,"canBeUsedToMatch":true},{"id":"offical_item","type":"string","display":true,"removed":false,"required":false,"displayName":"offical_item","defaultMatch":false,"canBeUsedToMatch":true},{"id":"secu_id","type":"string","display":true,"removed":false,"required":false,"displayName":"secu_id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"original_item","type":"string","display":true,"removed":false,"required":false,"displayName":"original_item","defaultMatch":false,"canBeUsedToMatch":true},{"id":"shortcode","type":"string","display":true,"removed":false,"required":false,"displayName":"shortcode","defaultMatch":false,"canBeUsedToMatch":true},{"id":"width","type":"string","display":true,"removed":false,"required":false,"displayName":"width","defaultMatch":false,"canBeUsedToMatch":true},{"id":"ratio","type":"string","display":true,"removed":false,"required":false,"displayName":"ratio","defaultMatch":false,"canBeUsedToMatch":true},{"id":"video_url","type":"string","display":true,"removed":false,"required":false,"displayName":"video_url","defaultMatch":false,"canBeUsedToMatch":true},{"id":"music","type":"string","display":true,"removed":false,"required":false,"displayName":"music","defaultMatch":false,"canBeUsedToMatch":true},{"id":"cdn_url","type":"string","display":true,"removed":false,"required":false,"displayName":"cdn_url","defaultMatch":false,"canBeUsedToMatch":true},{"id":"is_verified","type":"string","display":true,"removed":false,"required":false,"displayName":"is_verified","defaultMatch":false,"canBeUsedToMatch":true},{"id":"account_id","type":"string","display":true,"removed":false,"required":false,"displayName":"account_id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"profile_followers","type":"string","display":true,"removed":false,"required":false,"displayName":"profile_followers","defaultMatch":false,"canBeUsedToMatch":true},{"id":"tt_chain_token","type":"string","display":true,"removed":false,"required":false,"displayName":"tt_chain_token","defaultMatch":false,"canBeUsedToMatch":true},{"id":"region","type":"string","display":true,"removed":false,"required":false,"displayName":"region","defaultMatch":false,"canBeUsedToMatch":true},{"id":"timestamp","type":"string","display":true,"removed":false,"required":false,"displayName":"timestamp","defaultMatch":false,"canBeUsedToMatch":true},{"id":"input","type":"string","display":true,"removed":false,"required":false,"displayName":"input","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["url"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"appendOrUpdate","sheetName":{"__rl":true,"mode":"list","value":1067534155,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit#gid=1067534155","cachedResultName":"Tiktok by keyword"},"documentId":{"__rl":true,"mode":"list","value":"YOUR_GOOGLE_SHEET_ID","cachedResultUrl":"https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit?usp=drivesdk","cachedResultName":"Tiktok by keyword data Scraping "}},"credentials":{"googleSheetsOAuth2Api":{"id":"YOUR_GOOGLE_SHEETS_CREDENTIAL_ID","name":"Google Sheets Credential"}},"typeVersion":4.6},{"id":"e7b9dde9-0cd6-429e-b5ea-1e8269d7df7e","name":"Decode Snapshot from Response","type":"n8n-nodes-base.httpRequest","position":[-900,-560],"parameters":{"url":"=https://api.brightdata.com/datasets/v3/snapshot/s_mbghznsg225nzgyhz8","options":{},"sendQuery":true,"sendHeaders":true,"queryParameters":{"parameters":[{"name":"format","value":"json"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"461df00a-925d-4bbf-b28e-7aa367ad54d5","name":"Wait 1 minute","type":"n8n-nodes-base.wait","position":[-1540,-540],"webhookId":"10b45556-5e91-4387-abd0-f9078b220286","parameters":{"unit":"minutes","amount":1},"typeVersion":1.1},{"id":"f15192de-4d53-4716-a2d1-876494712c81","name":"Accepts keyword input from the user.","type":"n8n-nodes-base.formTrigger","position":[-2580,-540],"webhookId":"781b36e7-1076-4ddf-9541-bab8c9d4386c","parameters":{"options":{},"formTitle":"TikTok ","formFields":{"values":[{"fieldLabel":"Keyword"}]}},"typeVersion":2.2},{"id":"a1bcfe64-ac31-43c2-b0d5-33caa9ef50a6","name":"Sends keyword to Bright Data's Discover API to start scraping.","type":"n8n-nodes-base.httpRequest","position":[-2280,-540],"parameters":{"url":"https://api.brightdata.com/datasets/v3/trigger","method":"POST","options":{},"jsonBody":"=[\n  {\n    \"search_keyword\": \"{{ $json.Keyword }}\",\n    \"country\": \"\"\n  },\n  {\n    \"search_keyword\": \"{{ $json.Keyword }}\",\n    \"country\": \"\"\n  },\n  {\n    \"search_keyword\": \"{{ $json.Keyword }}\",\n    \"country\": \"\"\n  }\n]","sendBody":true,"sendQuery":true,"sendHeaders":true,"specifyBody":"json","queryParameters":{"parameters":[{"name":"dataset_id","value":"gd_lu702nij2f790tmv9h"},{"name":"include_errors","value":"true"},{"name":"type","value":"discover_new"},{"name":"discover_by","value":"keyword"},{"name":"limit_per_input","value":"2"}]},"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2},{"id":"da3fc0d4-98a6-48a3-b691-6e29db0969c0","name":"Checks the scraping status using snapshot ID.","type":"n8n-nodes-base.httpRequest","position":[-1880,-540],"parameters":{"url":"=https://api.brightdata.com/datasets/v3/progress/{{ $json.snapshot_id }}","options":{},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"Authorization","value":"Bearer YOUR_TOKEN_HERE"}]}},"typeVersion":4.2,"alwaysOutputData":true},{"id":"76797c1e-d329-4003-af3f-fac14a3fbdc8","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-2660,-680],"parameters":{"color":3,"width":280,"height":340,"content":"🟥 1. Form Trigger Node\n📌 Purpose:\n\nUser submits a keyword input.\n\nThis starts the scraping process.\n\n"},"typeVersion":1},{"id":"b849575e-2a93-42e3-a084-f536e634e035","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-2360,-760],"parameters":{"color":4,"width":340,"height":420,"content":"🟩 2. HTTP Request (Trigger Scraping on Bright Data)\n🔗 POST to Bright Data\n\nSends the keyword to Bright Data.\n\nTriggers scraping using dataset ID.\n\nTikTok keyword-based discovery initiated.\n\n"},"typeVersion":1},{"id":"e3648a2b-a0e7-41ab-9794-bd8fa1faf16a","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-1980,-700],"parameters":{"color":5,"width":320,"height":360,"content":"🟦 3. Snapshot Progress Check\n🔍 GET - snapshot status\n\nFetches the current snapshot_id.\n\nChecks if the scraping task is finished (status == ready)."},"typeVersion":1},{"id":"850f3c9d-2184-42b7-b6c5-e155c2d43f57","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-1320,-720],"parameters":{"color":2,"width":260,"height":360,"content":"🟪 4. IF Node (Check Completion)\n📌 Condition:\n\nIf snapshot is ready → move forward.\n\nElse → wait and retry."},"typeVersion":1},{"id":"3a54a9d4-07ff-4e04-831b-f618e9bdd48b","name":"Check Final Status","type":"n8n-nodes-base.if","position":[-1240,-540],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"or","conditions":[{"id":"35ed620d-b5d5-4e97-bcc5-52b283d85616","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"ready"}]}},"typeVersion":2.2},{"id":"5cca9c7d-d10c-4817-9d10-d0c904ad059b","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-1640,-720],"parameters":{"color":6,"width":280,"height":380,"content":"🟥 5. Wait Node\n🕒 Delays by 1 minute\n\nIf snapshot is not ready, pause for 1 minute.\n\nThen return to recheck loop."},"typeVersion":1},{"id":"75b635ea-6e6c-41e7-8cae-168b2c6f8c00","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-640,-740],"parameters":{"color":3,"width":300,"height":380,"content":"🟨 6. Final Data Storage\n📌 Google Sheets Integration:\n\nStores extracted TikTok data.\n\nIncludes all post metrics and profile info.\n\n"},"typeVersion":1}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"e61d0a2b-f49c-4f76-ae0c-55f397d4ea32","connections":{"Google Sheets":{"main":[[]]},"Wait 1 minute":{"main":[[{"node":"Check Final Status","type":"main","index":0}]]},"Check Final Status":{"main":[[{"node":"Decode Snapshot from Response","type":"main","index":0}],[{"node":"Checks the scraping status using snapshot ID.","type":"main","index":0}]]},"Decode Snapshot from Response":{"main":[[{"node":"Google Sheets","type":"main","index":0}]]},"Accepts keyword input from the user.":{"main":[[{"node":"Sends keyword to Bright Data's Discover API to start scraping.","type":"main","index":0}]]},"Checks the scraping status using snapshot ID.":{"main":[[{"node":"Wait 1 minute","type":"main","index":0}]]},"Sends keyword to Bright Data's Discover API to start scraping.":{"main":[[{"node":"Checks the scraping status using snapshot ID.","type":"main","index":0}]]}}}


name: Change Binary MimeType/Extension
author_name: Lucas Peyrin
author_username: lucaspeyrin
nodes_used: ["n8n-nodes-base.code"]
categories: []
created_at: 2025-06-23T13:02:42.840Z
updated_at: 2025-06-23T13:02:42.840Z
url: https://n8n.io/workflows/5155
scraped_at: 2025-07-06 21:16:30
description:
  How it works

  This workflow changes the file name, and therefore the extension and MIME type, of any binary file passed to it. This is perfect for converting file formats on the fly, like turning a Telegram voice message (.oga) into an MP3 for an AI transcription service.

  Set New File Name: The SET OUTPUT FILE NAME node is where you define the desired output file name and extension (e.g., audio.mp3). It also dynamically captures the property name of the incoming binary (e.g., data).
  Extract Binary Data: The workflow temporarily converts the binary file into a Base64 text string to make it accessible in the next step.
  Rebuild Binary with New Name: A Code node takes the Base64 data and reconstructs it as a binary file, but this time, it assigns the new file name you specified. n8n automatically sets the MIME type based on the new file extension.

  Set up steps

  Setup time: &lt; 1 minute

  This workflow is designed to be used as a sub-workflow.

  In your main workflow, add an Execute Sub-Workflow node where you need to change a file's type.
  In the Workflow parameter, select this "Change Binary MimeType/Extension" workflow.
  Open this workflow and go to the SET OUTPUT FILE NAME node.
  Modify the output_file_name value to your desired file name (e.g., voice_message.mp3 or document.pdf).
  Save this workflow. Now, any binary file you send to it from your main workflow will be returned with the new fileName and mimeType.

workflow_json:
  {"meta":{"instanceId":"e409ea34548a2afe2dffba31130cd1cf2e98ebe2afaeed2a63caf2a0582d1da0"},"nodes":[{"id":"491b237e-9d42-4017-bc80-9301367e4469","name":"Extract from File","type":"n8n-nodes-base.extractFromFile","position":[220,-80],"parameters":{"options":{},"operation":"binaryToPropery","binaryPropertyName":"={{ Object.keys($binary).first() }}"},"typeVersion":1},{"id":"2a7ea7bd-b009-4219-a5da-5d62976185a5","name":"SET OUTPUT FILE NAME","type":"n8n-nodes-base.set","position":[-160,-80],"parameters":{"options":{},"assignments":{"assignments":[{"id":"db6b30b5-a420-430b-87ae-a4887bfe9628","name":"binary_key","type":"string","value":"={{ Object.keys($binary).first() }}"},{"id":"8e1643f7-e794-43b2-a5ac-80b6b621b547","name":"output_file_name","type":"string","value":"SET YOUR OUTPUT FILE NAME AND EXTENSION !! (ex: .mp3 or .png)"}]},"includeOtherFields":true},"typeVersion":3.4},{"id":"b9e1072b-c9c2-4d5b-a13a-4eed7a920203","name":"Change Binary Data Type","type":"n8n-nodes-base.code","position":[440,-80],"parameters":{"jsCode":"const myBuffer = Buffer.from($json.data, 'base64');\n\n$input.item.binary = {\n  [$('SET OUTPUT FILE NAME').last().json.binary_key]: await this.helpers.prepareBinaryData(myBuffer, $('SET OUTPUT FILE NAME').last().json.output_file_name)\n};\n\nreturn $input.item;\n"},"typeVersion":2},{"id":"e5fc3b22-3f86-4cef-b0c7-d2f8b7261784","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-320,-420],"parameters":{"color":3,"width":420,"height":500,"content":"### ⚙️ CONFIGURE HERE ⚙️\n\nThis is the main node you need to edit.\n\n1.  **`output_file_name`**: Change this value to the desired file name and extension. The extension is what determines the new MIME type.\n    *   **Example:** To convert to an MP3, set the value to `audio.mp3`.\n    *   **Example:** To ensure a file is treated as a PNG, set it to `image.png`.\n\n2.  **`binary_key`**: This field is dynamic and automatically finds the name of the incoming binary property. **Do not change this.**"},"typeVersion":1},{"id":"41ac8c2b-6530-46bc-9153-8b3c312076f9","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[140,-340],"parameters":{"color":7,"width":480,"height":420,"content":"### ⚙️ Core Logic (No Edit Needed)\n\nThese nodes work together to perform the conversion:\n\n1.  **Extract from File:** Converts the binary into text (Base64).\n2.  **Code:** Rebuilds the binary file using the new file name you provided in the previous step.\n\nThis process effectively changes the file's perceived format for other n8n nodes or external services."},"typeVersion":1},{"id":"d7de41a8-eb35-4b84-862f-9a2deb438d93","name":"Change Binary MimeType/Extension","type":"n8n-nodes-base.executeWorkflowTrigger","position":[-520,-80],"parameters":{"inputSource":"passthrough"},"typeVersion":1.1}],"connections":{"Extract from File":{"main":[[{"node":"Change Binary Data Type","type":"main","index":0}]]},"SET OUTPUT FILE NAME":{"main":[[{"node":"Extract from File","type":"main","index":0}]]},"Change Binary MimeType/Extension":{"main":[[{"node":"SET OUTPUT FILE NAME","type":"main","index":0}]]}}}


name: Automate Daily AI News with Perplexity Sonar Pro (via Telegram)
author_name: Automate With Marc
author_username: marconi
categories: []
created_at: 2025-06-23T15:09:33.217Z
updated_at: 2025-06-23T15:09:33.217Z
url: https://n8n.io/workflows/5157
scraped_at: 2025-07-06 21:16:30
description:
  This workflow contains community nodes that are only compatible with the self-hosted version of n8n. 

  🧠 Perplexity-Powered Daily AI News Digest (via Telegram)


  This ready-to-deploy n8n workflow automates the entire process of collecting, filtering, formatting, and distributing daily AI industry news summaries directly to your Telegram group or channel.

  Powered by Perplexity and OpenAI, it fetches only high-signal AI updates from trusted sources (e.g. OpenAI, DeepMind, HuggingFace, MIT Tech Review), filters out duplicates based on a Google Sheet archive, and delivers beautifully formatted news directly to your team — every morning at 10AM.

  For more such build and step-by-step tutorials, check out:
  https://www.youtube.com/@Automatewithmarc

  🚀 Key Features:
  Perplexity AI Integration: Automatically fetches the most relevant AI developments from the last 24 hours.

  AI Formatter Agent: Cleans the raw feed, removes duplicates, adds summaries, and ensures human-friendly formatting.

  Google Sheets Log: Tracks previously reported news items to avoid repetition.

  Telegram Delivery: Sends a polished daily digest straight to your chat, ready for immediate team consumption.

  Customizable Scheduling: Preconfigured for daily use, but can be modified to fit your team's preferred cadence.

  💼 Ideal For:
  Anyone who wants to stay ahead of fast-moving AI trends with zero manual effort

  🛠️ Tech Stack:
  Perplexity AI

  OpenAI (GPT-4 or equivalent)

  Google Sheets

  Telegram API

  ✅ Setup Notes:
  You’ll need to connect your own OpenAI, Perplexity, Google Sheets, and Telegram credentials.

  Replace the Google Sheet ID and Telegram channel settings with your own.

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

workflow_json:
  {"id":"ZizcyYq82q3P2ImX","meta":{"instanceId":"1c7b08fed4406d546caf4a44e8b942ca317e7e207bb9a5701955a1a6e1ce1843"},"name":"Perplexity Powered AI News Search","tags":[],"nodes":[{"id":"18a737fb-a33f-4a4b-a5dc-cc5656c46a50","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[720,180],"parameters":{"rule":{"interval":[{"triggerAtHour":10}]}},"typeVersion":1.2},{"id":"ccc439ae-baab-4b1b-a67f-e21a64426407","name":"REDACTED","type":"n8n-nodes-base.googleSheetsTool","position":[1260,360],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"REDACTED","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1cBdqD8JiMLH2uvnK0KbcLHDrEDrFgK076u2x4uvwLP8","cachedResultUrl":"REDACTED","cachedResultName":"REDACTED"}},"typeVersion":4.6},{"id":"b7e99d4c-74fd-4ac4-a008-fcaa7e0b2bb6","name":"Sheet Log","type":"n8n-nodes-base.googleSheets","position":[1820,180],"parameters":{"columns":{"value":{"Date":"={{ $('Schedule Trigger').item.json['Readable date'] }}","News":"={{ $('Formatter Agent').item.json.message.content }}","Thread Ts":"={{ $json.message.ts }}"},"schema":[{"id":"Date","type":"string","display":true,"removed":false,"required":false,"displayName":"Date","defaultMatch":false,"canBeUsedToMatch":true},{"id":"News","type":"string","display":true,"required":false,"displayName":"News","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Thread Ts","type":"string","display":true,"required":false,"displayName":"Thread Ts","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["Date"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"appendOrUpdate","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"REDACTED","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"id","value":"Redacted"}},"credentials":{"googleSheetsOAuth2Api":{"id":"NzCMYdQID9qgVeNJ","name":"Google Sheets account 3"}},"typeVersion":4.6},{"id":"1bb7449f-d243-4d90-9ba4-5e2632dda608","name":"Perplexity Daily Search (Past 24hrs)","type":"n8n-nodes-base.perplexity","position":[960,180],"parameters":{"model":"sonar-reasoning-pro","options":{"searchRecency":"day"},"messages":{"message":[{"role":"system","content":"REDACTED"},{"content":"=Find and summarize the most recent (within the last 24 hours. For reference, today is {{ $json['Readable date'] }}) and relevant news on AI model releases, research breakthroughs, and key announcements by organizations like OpenAI, Anthropic, Google, Meta, Mistral, xAI, and Hugging Face. \n\nPrioritize first primary, credible sources and exclude videos and other news aggregator site.\n\nThen research on potential disrupters that may not be immediately reported on major news outlet (e.g Seedance video generation model, Deepseek etc). \n\nFor each item:\n- Write a clear 2–3 sentence summary\n- Add the full (unshortened) source URL immediately after each summary\n\n#Rule\nIf there are no notable news found in the past 24 hours, respond with \"No Notable AI News found in the past 24 hours\""}]},"simplify":true,"requestOptions":{}},"credentials":{"perplexityApi":{"id":"siBtNJfFZDULtMTv","name":"Perplexity account"}},"typeVersion":1},{"id":"2d281620-be7d-40b0-afba-0d443a89be88","name":"Formatter Agent","type":"@n8n/n8n-nodes-langchain.openAi","position":[1180,180],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4o","cachedResultName":"GPT-4O"},"options":{},"messages":{"values":[{"content":"=Here is today’s AI news list from Perplexity:\n\n\"{{ $json.message }}\"\n\nPlease:\n\n- Remove all thinking or reasoning notes enclosed between </think> tags.\n- Cross-check the news against the “Past News Log Sheet” and remove duplicates. Remove duplicate news from output even if they were reported from different sources. Take some time to infer the past news in the sheet to ensure no duplication, since news might be worded differently. \n- Ensure each item has a clear, 1–2 sentence summary.\n- After each summary, include the full unfurled source URL.\n- Use bold to highlight company names or major updates.\n- Add spacing between news items for readability.\n\n\nStart with:\nHi, Today is {{ $('Schedule Trigger').item.json['Readable date'] }}. Here are the latest AI updates you should know:\n\n#Rule\nIf Perplexity's output shows that there are no notable news in the past 24 hours, or all the news are duplicates/similar from the \"Past News Log Sheet\" respond appropriately with \"No notable AI development news in the past 24 hours\""},{"role":"system","content":"You're a helpful formatter Agent"}]}},"credentials":{"openAiApi":{"id":"mRjDuoQjiE0APh7s","name":"OpenAi account 2"}},"typeVersion":1.8},{"id":"e2d77cb3-e14a-4e69-b3b7-20266d160b09","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[640,60],"parameters":{"height":460,"content":"Scheduled trigger"},"typeVersion":1},{"id":"4c7abefe-918c-4533-946c-5aa771d67388","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[900,60],"parameters":{"color":5,"height":460,"content":"Search"},"typeVersion":1},{"id":"2337cf99-72be-4e19-abee-ba45aec2f2f7","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[1160,60],"parameters":{"color":3,"width":300,"height":460,"content":"Format + Crosscheck Recency\n"},"typeVersion":1},{"id":"63a6b4f8-e2c1-4bd0-aa04-5057e39cab4a","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[1480,60],"parameters":{"color":6,"width":580,"height":460,"content":"Telegram Message & Log"},"typeVersion":1},{"id":"d03f18f6-728f-4981-8c94-d6a96191b4fe","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[0,0],"parameters":{"color":4,"width":600,"height":920,"content":"🧠 Perplexity-Powered Daily AI News Digest (via Telegram)\n\n\nThis ready-to-deploy n8n workflow automates the entire process of collecting, filtering, formatting, and distributing daily AI industry news summaries directly to your Telegram group or channel.\n\nPowered by Perplexity and OpenAI, it fetches only high-signal AI updates from trusted sources (e.g. OpenAI, DeepMind, HuggingFace, MIT Tech Review), filters out duplicates based on a Google Sheet archive, and delivers beautifully formatted news directly to your team — every morning at 10AM.\n\nFor more such build and step-by-step tutorials, check out:\nhttps://www.youtube.com/@Automatewithmarc\n\n🚀 Key Features:\nPerplexity AI Integration: Automatically fetches the most relevant AI developments from the last 24 hours.\n\nAI Formatter Agent: Cleans the raw feed, removes duplicates, adds summaries, and ensures human-friendly formatting.\n\nGoogle Sheets Log: Tracks previously reported news items to avoid repetition.\n\nTelegram Delivery: Sends a polished daily digest straight to your chat, ready for immediate team consumption.\n\nCustomizable Scheduling: Preconfigured for daily use, but can be modified to fit your team's preferred cadence.\n\n💼 Ideal For:\nAnyone who wants to stay ahead of fast-moving AI trends with zero manual effort\n\n🛠️ Tech Stack:\nPerplexity AI\n\nOpenAI (GPT-4 or equivalent)\n\nGoogle Sheets\n\nTelegram API\n\n✅ Setup Notes:\nYou’ll need to connect your own OpenAI, Perplexity, Google Sheets, and Telegram credentials.\n\nReplace the Google Sheet ID and Telegram channel settings with your own."},"typeVersion":1},{"id":"0d6475ab-3b90-47fd-9e9d-2e901cd15a98","name":"Telegram","type":"n8n-nodes-base.telegram","position":[1580,180],"webhookId":"26253147-c419-426f-9b9d-d99df88464c7","parameters":{"additionalFields":{}},"credentials":{"telegramApi":{"id":"dG7fL5iq4O9PeM1G","name":"Telegram n8n"}},"typeVersion":1.2}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"181b62b2-8f1e-41fd-842d-6d341552dc23","connections":{"Telegram":{"main":[[{"node":"Sheet Log","type":"main","index":0}]]},"Formatter Agent":{"main":[[{"node":"Telegram","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Perplexity Daily Search (Past 24hrs)","type":"main","index":0}]]},"Past News Sheet Log":{"ai_tool":[[{"node":"Formatter Agent","type":"ai_tool","index":0}]]},"Perplexity Daily Search (Past 24hrs)":{"main":[[{"node":"Formatter Agent","type":"main","index":0}]]}}}


name: Generate Realistic Sound Effects with CassetteAI and Save to Google Drive
author_name: Davide
author_username: n3witalia
nodes_used: ["n8n-nodes-base.httpRequest","n8n-nodes-base.googleDrive"]
categories: []
created_at: 2025-06-23T15:12:57.125Z
updated_at: 2025-06-23T15:12:57.125Z
url: https://n8n.io/workflows/5158
scraped_at: 2025-07-06 21:16:30
description:
  The Sound Effects Generator is an automated workflow that allows users to create realistic sound effects using AI and save them directly to Google Drive. It generates high-quality sound effects (up to 30 seconds long) based on user prompts.

  How It Works:

  User Input via Web Form
     A form is presented to the user asking for:

     A prompt describing the sound (e.g. "waves crashing", "laser blast").
     A duration in seconds (up to 30 seconds).

  API Request to Generate Audio
     The input is sent to CassetteAI via a POST request using API with proper authentication.

  Status Polling
     The workflow waits for 10 seconds and then checks the status of the request.

  Conditional Flow

     If the audio generation is complete (COMPLETED), it proceeds to fetch the audio file URL.
     If not, it waits and retries.

  Download & Save

     The audio file is downloaded from the URL.
     It is automatically uploaded to a specific folder in the user’s Google Drive, with a timestamped filename.

  Key Advantages

  Fast & Efficient**: Generates up to 30 seconds of audio in just 1 second of processing time.
  No Coding Required**: Entire flow can be triggered via a simple form interface.
  Automated Storage**: Files are automatically saved to a preconfigured Google Drive folder.
  Scalable**: Can be reused for multiple projects by simply changing the input prompts.
  Secure**: Uses secure API key-based authentication for interaction with Fal.run and Google Drive.
  Customizable**: Easy to adapt or extend—for example, sending download links via email or Telegram.

  How It Works  
  Form Submission: The workflow starts with a form where users input a prompt and the desired duration (max 30 seconds) for the sound effect.  
  Audio Creation: The submitted data is sent to the CassetteAI Sound Effects Generator API via an HTTP request, which initiates the sound effect generation process.  
  Status Check: The workflow periodically checks the status of the request. If the status is "COMPLETED," it proceeds to fetch the audio file.  
  Audio Retrieval: The generated audio file is downloaded from the provided URL and uploaded to a specified Google Drive folder, with a timestamped filename for organization.  

  Set Up Steps  
  API Key Configuration:  
     Create an account on fal.ai and obtain an API key.  
     In the "Create audio" node, set the "Header Auth" with:  
       Name: Authorization  
       Value: Key YOURAPIKEY (replace YOURAPIKEY with your actual API key).  

  Google Drive Integration:  
     Ensure the Google Drive node is configured with the correct OAuth2 credentials and folder ID.  
     Adjust the folder ID in the "Upload Audio" node if a different destination is preferred.  

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

workflow_json:
  {"id":"6MbJjFFQ8e6Lq8Rw","meta":{"instanceId":"a4bfc93e975ca233ac45ed7c9227d84cf5a2329310525917adaf3312e10d5462","templateCredsSetupCompleted":true},"name":"Sound Effects Generator","tags":[],"nodes":[{"id":"4183ba34-e5a7-4ee1-866a-e6e725b51589","name":"Get status","type":"n8n-nodes-base.httpRequest","position":[800,660],"parameters":{"url":"=https://queue.fal.run/cassetteai/sound-effects-generator/requests/{{ $('Create audio').item.json.request_id }}/status ","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"daOZafXpRXLtoLUV","name":"Fal.run API"}},"typeVersion":4.2},{"id":"d2b00c1e-be8b-4aeb-8b56-85659be7b607","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-220,-100],"parameters":{"color":3,"width":740,"height":180,"content":"# Sound Effects Generator\n\nCreate stunningly realistic sound effects in seconds - CassetteAI's Sound Effects Model generates high-quality SFX up to 30 seconds long in just 1 second of processing time and save the audio file (.wav) on Google Drive\n\n\n"},"typeVersion":1},{"id":"c3110e24-b0c1-440b-8971-fdfe3f065b72","name":"Completed?","type":"n8n-nodes-base.if","position":[1020,660],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"383d112e-2cc6-4dd4-8985-f09ce0bd1781","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.status }}","rightValue":"COMPLETED"}]}},"typeVersion":2.2},{"id":"5ae7f107-0350-446b-90d3-13ea67969969","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-220,320],"parameters":{"width":740,"height":100,"content":"## STEP 2 - MAIN FLOW\nStart the workflow and type the prompt and the duration (in seconds, max 30)."},"typeVersion":1},{"id":"c3872c07-05fd-4124-97f2-843365cfeb3b","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-220,120],"parameters":{"width":740,"content":"## STEP 1 - GET API KEY (YOURAPIKEY)\nCreate an account [here](https://fal.ai/) and obtain API KEY.\nIn the node \"Create Image\" set \"Header Auth\" and set:\n- Name: \"Authorization\"\n- Value: \"Key YOURAPIKEY\""},"typeVersion":1},{"id":"c3189915-a6a5-4a1e-973c-d0552d1b95cb","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[280,600],"parameters":{"width":180,"height":200,"content":"Set API Key created in Step 2"},"typeVersion":1},{"id":"2de370c0-4c08-4154-8f93-c2856b983466","name":"On form submission","type":"n8n-nodes-base.formTrigger","position":[80,660],"webhookId":"960dd363-daa5-47d2-b5dc-660c93fb5b05","parameters":{"options":{},"formTitle":"Sound Effects Generator","formFields":{"values":[{"fieldLabel":"Prompt","requiredField":true},{"fieldType":"number","fieldLabel":"Duration (max 30 sec.)","requiredField":true}]},"formDescription":"Sound Effects Generator"},"typeVersion":2.2},{"id":"83e7b9fa-13cd-48b2-81e3-2d9fd0f51410","name":"Wait 10 sec.","type":"n8n-nodes-base.wait","position":[580,660],"webhookId":"70185285-4ebd-45a3-9e49-bc0b99120fe9","parameters":{"amount":10},"typeVersion":1.1},{"id":"8264d6a6-d174-474f-804c-17859327e2d1","name":"Create audio","type":"n8n-nodes-base.httpRequest","position":[320,660],"parameters":{"url":"https://queue.fal.run/cassetteai/sound-effects-generator","method":"POST","options":{},"jsonBody":"={\n     \"prompt\": \"{{ $json.Prompt }}\",\n     \"duration\": {{ $json['Duration (max 30 sec.)'] }}\n}","sendBody":true,"sendHeaders":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json"}]}},"credentials":{"httpHeaderAuth":{"id":"daOZafXpRXLtoLUV","name":"Fal.run API"}},"typeVersion":4.2},{"id":"8b00e3d3-9d8a-4d0d-8971-1666c3158c66","name":"Get Audio Url","type":"n8n-nodes-base.httpRequest","position":[100,1000],"parameters":{"url":"=https://queue.fal.run/cassetteai/sound-effects-generator/requests/{{ $json.request_id }}","options":{},"authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"daOZafXpRXLtoLUV","name":"Fal.run API"}},"typeVersion":4.2},{"id":"cda508d2-2f10-4d48-8196-f17e20dbb416","name":"Upload Audio","type":"n8n-nodes-base.googleDrive","position":[560,1000],"parameters":{"name":"={{ $now.format('yyyyLLddHHmmss') }}.{{ $json.audio_file.file_name }}","driveId":{"__rl":true,"mode":"list","value":"My Drive"},"options":{},"folderId":{"__rl":true,"mode":"list","value":"1aHRwLWyrqfzoVC8HoB-YMrBvQ4tLC-NZ","cachedResultUrl":"https://drive.google.com/drive/folders/1aHRwLWyrqfzoVC8HoB-YMrBvQ4tLC-NZ","cachedResultName":"Fal.run"}},"credentials":{"googleDriveOAuth2Api":{"id":"HEy5EuZkgPZVEa9w","name":"Google Drive account (n3w.it)"}},"typeVersion":3},{"id":"ca095dda-3ac1-4e08-ad67-c4cdea232271","name":"Get Audio File","type":"n8n-nodes-base.httpRequest","position":[320,1000],"parameters":{"url":"={{ $json.audio_file.url }}","options":{}},"typeVersion":4.2}],"active":false,"settings":{"executionOrder":"v1"},"versionId":"d6d655d2-8ec6-4807-b17e-fea5d18a9f80","connections":{"Completed?":{"main":[[{"node":"Get Audio Url","type":"main","index":0}],[{"node":"Wait 10 sec.","type":"main","index":0}]]},"Get status":{"main":[[{"node":"Completed?","type":"main","index":0}]]},"Create audio":{"main":[[{"node":"Wait 10 sec.","type":"main","index":0}]]},"Upload Audio":{"main":[[]]},"Wait 10 sec.":{"main":[[{"node":"Get status","type":"main","index":0}]]},"Get Audio Url":{"main":[[{"node":"Get Audio File","type":"main","index":0}]]},"Get Audio File":{"main":[[{"node":"Upload Audio","type":"main","index":0}]]},"On form submission":{"main":[[{"node":"Create audio","type":"main","index":0}]]}}}


name: AI content creation and auto WordPress publishing with Pexels API image workflow
author_name: Mateusz Kosiorek
author_username: mkosiorek
categories: []
created_at: 2025-06-23T15:48:04.145Z
updated_at: 2025-06-23T15:48:04.145Z
url: https://n8n.io/workflows/5159
scraped_at: 2025-07-06 21:16:30
description:
  AI powered content creation and WordPress publishing workflow

  Summary

  This workflow automates the entire process of blog content creation, from idea generation and article writing using Google Gemini, to sourcing images from Pexels and publishing directly to your WordPress site. It uses Google Sheets as a central hub for managing content ideas and tracking their status, all orchestrated through interactive n8n forms.

  Key features

  AI driven content:** Leverages Google Gemini for generating:
      Full blog articles based on prompts.
      Relevant keywords for image searching.
      New blog topic ideas.
  Automated image sourcing:** Searches Pexels for suitable images based on AI generated keywords and downloads them.
  WordPress integration:**
      Creates new posts with AI generated title and content.
      Uploads sourced images to the WordPress media library.
      Sets the uploaded image as the featured image for the post.
  Google Sheets management:**
      Fetches content ideas (prompts) marked as "not generated".
      Updates the sheet after a post is generated with the post ID, title, and generation date.
      Adds newly AI generated blog topic ideas to the sheet.
  Interactive forms:**
      Main trigger form to choose between generating content or adding new ideas.
      Forms to input topics for idea generation.
      Confirmation forms at the end of processes.
  Structured output parsing:** Ensures AI responses for topic generation are correctly formatted as JSON.

  How it works

  The workflow is initiated via an n8n Form Trigger: Select Action, allowing the user to choose one of two main paths:

  1. Generate content path:
      Fetch idea: The Fetch unprocessed ideas (Google Sheets) node retrieves a row from your sheet where the "Generated" column is "no".
      Set prompt: The Set prompt node prepares the topic from the sheet for the AI.
      Generate article: The Generate article AI (Langchain Agent with Google Gemini) node takes the prompt and writes a full article.
      Generate image keyword: The Generate image keyword AI (Langchain Agent with Google Gemini) node creates a concise search term based on the article topic.
      Search image: The Search Pexels image (HTTP Request) node uses the generated keyword to find a relevant image via the Pexels API.
      Create WordPress post: The Create WordPress post node publishes the AI generated article and initial image metadata to your WordPress site.
      Download and upload image: The Download Pexels image (HTTP Request) node fetches the actual image file, and the Upload image (HTTP Request) node uploads it to your WordPress media library.
      Set featured image: The Set featured image (HTTP Request) node links the uploaded image as the featured image for the newly created post.
      Update sheet: The Update Google Sheet node marks the idea as "yes" in your Google Sheet and adds the WordPress post ID and title.
      Confirmation: A Form: End post generation node displays a completion message.

  2. Add ideas path:
      Input topic: The Form: Enter topic for ideas node prompts the user to enter a general subject.
      Generate topics: The Generate blog topics AI (Langchain Agent with Google Gemini and Structured Output Parser) node generates five SEO friendly blog topic ideas based on the user's input, formatted as JSON.
      Process topics: The Split topics node separates the generated list of topics into individual items.
      Add to sheet: For each topic, the Add ideas to sheet (Google Sheets) node appends it as a new row, marked with "Generated: no".
      Loop or end: The Form: Add more topics? node asks the user if they want to generate more ideas or end the process.
          If "NEXT", it loops back to the Form: Enter topic for ideas.
          If "END", a Form: End idea generation node displays a completion message with the list of added topics.

  Nodes used

  Form Trigger
  If
  Google Sheets
  Set
  Langchain Agent (with Google Gemini Chat Model)
  Structured Output Parser (Langchain)
  HTTP Request (for Pexels API and WordPress Media/Post updates)
  WordPress
  Split Out
  Form (for user interaction and completion messages)
  Sticky Note (for instructions within the workflow)

  Setup instructions

  Credentials:
      Google Sheets: Configure your Google Sheets OAuth2 credentials in the Fetch unprocessed ideas, Update Google Sheet, and Add ideas to sheet nodes.
      WordPress: Configure your WordPress API credentials in the Create WordPress post, Upload image, and Set featured image nodes.
      Google Gemini: Configure your Google Gemini (PaLM) API key in the Gemini model for article, Gemini model for image keyword, and Gemini model for topics nodes.
  API keys and URLs:
      Pexels: In the Search Pexels image node, replace &lt;YOUR_PEXELS_API_KEY&gt; in the Authorization header with your actual Pexels API key.
      WordPress URL: In the Upload image and Set featured image nodes, replace &lt;YOUR_WORDPRESS_URL&gt; in the URL field with your WordPress site's domain (e.g., yourblog.com).
  Google Sheet configuration:
      Ensure your Google Sheet (specified by Document ID in Google Sheets nodes) has a sheet named Sheet1 (or update the Sheet Name parameter).
      The sheet should have at least the following columns: Prompt (for the blog idea/topic), Generated (to track status, e.g., "no" or "yes"), row_number (automatically populated by n8n when reading), Date, Title (for the final WordPress post title), Post ID.
  Activate the workflow. The Form Trigger: Select Action will provide a webhook URL to initiate the process.

  Customization ideas

  Modify the AI prompts in the Langchain Agent nodes for different tones, styles, or content structures.
  Change the Google Gemini models used for different cost/performance balances.
  Integrate other image sources instead of or in addition to Pexels.
  Add steps for social media sharing after a post is published.
  Extend the Google Sheet to track more metrics like word count or target keywords.
  Implement more sophisticated error handling.

  Use cases

  Automating blog content generation for personal or company blogs.
  Streamlining content marketing efforts.
  Quickly populating new websites with initial content.
  Assisting SEO agencies in creating draft content for clients.
  Helping solo bloggers maintain a consistent publishing schedule.

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

workflow_json:
  {"meta":{"instanceId":"ee764605661f484417a5505724882cb4f8c547a6bf9bef1f89eacbbcb7cca6ab"},"nodes":[{"id":"aa01f852-aa12-4001-9bc4-94fd0bbd0e88","name":"Fetch Unprocessed Ideas","type":"n8n-nodes-base.googleSheets","position":[-980,800],"parameters":{"options":{"dataLocationOnSheet":{"values":{"rangeDefinition":"detectAutomatically"}}},"filtersUI":{"values":[{"lookupValue":"no","lookupColumn":"Generated"}]},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1UDaTATWOnYorewjEF5-G9edgSBjc2_Rb50BZVFbAu8U/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"id","value":"1UDaTATWOnYorewjEF5-G9edgSBjc2_Rb50BZVFbAu8U"}},"executeOnce":false,"typeVersion":4.5},{"id":"3ab71903-3b38-4891-a769-2d0304cb4bad","name":"Set Prompt","type":"n8n-nodes-base.set","position":[-780,800],"parameters":{"options":{},"assignments":{"assignments":[{"id":"3e8d2523-66aa-46fe-adcc-39dc78b9161e","name":"prompt","type":"string","value":"={{ $json.Prompt }}"}]}},"typeVersion":3.4},{"id":"23e7d119-2d0f-41df-8e94-67bdd95bf6c0","name":"Create WordPress Post","type":"n8n-nodes-base.wordpress","position":[-760,1180],"parameters":{"title":"={{ $('Fetch Unprocessed Ideas').item.json.Prompt }}","additionalFields":{"status":"publish","content":"={{ $('Generate Article AI').item.json.output }}\n\nImage by: {{ $('Search Pexels Image').item.json.photos[0].photographer }}\n{{ $('Search Pexels Image').item.json.photos[0].photographer_url }}"}},"typeVersion":1},{"id":"a07f4264-c011-4925-a8c6-d5fa11ec809b","name":"Upload Image","type":"n8n-nodes-base.httpRequest","onError":"continueRegularOutput","position":[-380,1180],"parameters":{"url":"https://<YOUR_WORDPRESS_URL>/wp-json/wp/v2/media","method":"POST","options":{},"sendBody":true,"contentType":"binaryData","sendHeaders":true,"authentication":"predefinedCredentialType","headerParameters":{"parameters":[{"name":"Content-Disposition","value":"=attachment; filename=\"cover-{{ $('Create WordPress Post').item.json.id }}.jpg\""}]},"inputDataFieldName":"data","nodeCredentialType":"wordpressApi"},"typeVersion":4.2},{"id":"cbbae382-12b2-47c7-8fd8-13df5236bbdc","name":"Set Featured Image","type":"n8n-nodes-base.httpRequest","position":[-200,1180],"parameters":{"url":"=https://<YOUR_WORDPRESS_URL>/wp-json/wp/v2/posts/{{ $('Create WordPress Post').item.json.id }}","method":"POST","options":{},"sendQuery":true,"authentication":"predefinedCredentialType","queryParameters":{"parameters":[{"name":"featured_media","value":"={{ $json.id }}"}]},"nodeCredentialType":"wordpressApi"},"typeVersion":4.2},{"id":"cc2d86a1-cc0f-46fc-81ee-ec02801b29cf","name":"Update Google Sheet","type":"n8n-nodes-base.googleSheets","position":[-20,1180],"parameters":{"columns":{"value":{"Date":"={{ $now.format('dd/LL/yyyy') }}","Title":"={{ $('Create WordPress Post').item.json.title.raw }}","Post ID":"={{ $('Create WordPress Post').item.json.id }}","Generated":"yes","row_number":"={{ $('Fetch Unprocessed Ideas').item.json.row_number }}"},"schema":[{"id":"Date","type":"string","display":true,"removed":false,"required":false,"displayName":"Date","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Prompt","type":"string","display":true,"removed":false,"required":false,"displayName":"Prompt","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Title","type":"string","display":true,"removed":false,"required":false,"displayName":"Title","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Post ID","type":"string","display":true,"removed":false,"required":false,"displayName":"Post ID","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Generated","type":"string","display":true,"removed":false,"required":false,"displayName":"Generated","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/1UDaTATWOnYorewjEF5-G9edgSBjc2_Rb50BZVFbAu8U/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1UDaTATWOnYorewjEF5-G9edgSBjc2_Rb50BZVFbAu8U","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1UDaTATWOnYorewjEF5-G9edgSBjc2_Rb50BZVFbAu8U/edit?usp=drivesdk","cachedResultName":"n8n-wp"}},"typeVersion":4.5},{"id":"74a74b39-d14c-44b7-920b-bfd343225a87","name":"Generate Article AI","type":"@n8n/n8n-nodes-langchain.agent","position":[-600,800],"parameters":{"text":"=You are an SEO expert. Write an article based on this topic: {{ $('Fetch Unprocessed Ideas').item.json.Prompt }}\nInstructions:\n-In the introduction, present the topic that will be discussed in the rest of the text.\n-The introduction should be about 120 words.\n-The conclusion should be about 120 words.\n-In the conclusion, summarize everything said in the article and present the reader with final conclusions.\n-Write a maximum of 4-5 chapters and expand on them.\n-Chapters should maintain a logical sequence and not repeat the same concepts.\n-Chapters should be interconnected, not isolated blocks of text. The text should be fluent and follow a linear logic.\n-Do not start chapters with \"Chapter 1\", \"Chapter 2\", \"Chapter 3\"... just write the chapter title.\n-Use HTML for text formatting, but limit yourself to using bold, italics, paragraphs, lists, and tables.\n-Do not place the result in a ```html code block, only the text itself.\n-Do not use markdown formatting.\n-Delve into the topic you are writing about; do not provide only superficial information.\n-I expect only HTML format in the response.\nDO NOT INCLUDE ```html\nWRITE SO IT DOESN'T LOOK LIKE AI - do not use long dashes, and in titles and subheadings, capitalize only the first word.\n\nIf possible, add data in a table.","options":{},"promptType":"define"},"typeVersion":2},{"id":"0be71cb1-6b52-4227-a70d-c0e01033f8c4","name":"Generate Image Keyword AI","type":"@n8n/n8n-nodes-langchain.agent","position":[-280,800],"parameters":{"text":"=Choose an expression based on which you will find a matching graphic in Pexels API.\nTopic: {{ $('Fetch Unprocessed Ideas').item.json.Prompt }} \nInstructions:\n- Choose one expression that will best match to find a graphic.\n- Use a general category to always match a graphic.\n- Do not use any HTML characters.\n- Return only a string containing the expression.\n- Do not use quotation marks. The only allowed special characters are \":\" and \",\".\n- Make each one unique so there are no 2 identical graphics.","options":{},"promptType":"define"},"typeVersion":2},{"id":"f7da0b58-b5ae-48b3-a69a-739512282179","name":"Gemini Model for Article","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[-620,940],"parameters":{"options":{},"modelName":"models/gemini-1.5-flash-latest"},"typeVersion":1},{"id":"5af891b9-069d-4e48-8b93-e04413d85e7c","name":"Gemini Model for Image Keyword","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[-300,940],"parameters":{"options":{},"modelName":"models/gemini-1.5-flash-latest"},"typeVersion":1},{"id":"3b0f4db2-e2d1-4590-b08b-a37039db7f70","name":"Search Pexels Image","type":"n8n-nodes-base.httpRequest","position":[-960,1180],"parameters":{"url":"=https://api.pexels.com/v1/search?query={{ encodeURIComponent($('Generate Image Keyword AI').item.json.output) }}&per_page=1","options":{},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"Authorization","value":"<YOUR_PEXELS_API_KEY>"}]}},"typeVersion":4.2},{"id":"7fb8b8fe-4e6b-4af8-8d6b-9419096350d2","name":"Download Pexels Image","type":"n8n-nodes-base.httpRequest","onError":"continueRegularOutput","position":[-560,1180],"parameters":{"url":"={{ $('Search Pexels Image').item.json.photos[0].src.large2x }}","options":{"response":{"response":{"responseFormat":"file"}}}},"typeVersion":4.2},{"id":"32b7c739-19e0-4115-8d7e-35a2db6423bb","name":"Form Trigger: Select Action","type":"n8n-nodes-base.formTrigger","position":[-1580,580],"webhookId":"09988680-2d17-4e68-b1e1-81fef6163a0d","parameters":{"options":{"path":"wpcontent","buttonLabel":"Next","appendAttribution":false},"formTitle":"Create Content","formFields":{"values":[{"fieldType":"dropdown","fieldLabel":"Task","fieldOptions":{"values":[{"option":"Generate Content"},{"option":"Add Ideas"}]}}]}},"typeVersion":2.2},{"id":"bc2a6f22-a0f7-4933-b660-a0f4dbd52de4","name":"If Generate Content","type":"n8n-nodes-base.if","position":[-1340,580],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"loose"},"combinator":"and","conditions":[{"id":"41e4b502-f201-47a2-a244-ac705528f843","operator":{"type":"string","operation":"contains"},"leftValue":"={{ $json.Task }}","rightValue":"Generate Content"}]},"looseTypeValidation":true},"typeVersion":2.2},{"id":"18bdad61-7286-4e66-bdc3-f37d404f8dc0","name":"Add Ideas to Sheet","type":"n8n-nodes-base.googleSheets","position":[-40,400],"parameters":{"columns":{"value":{"Title":"=","Prompt":"={{ $json.Topic }}","Generated":"no"},"schema":[{"id":"Date","type":"string","display":true,"required":false,"displayName":"Date","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Prompt","type":"string","display":true,"required":false,"displayName":"Prompt","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Title","type":"string","display":true,"required":false,"displayName":"Title","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Post ID","type":"string","display":true,"required":false,"displayName":"Post ID","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Generated","type":"string","display":true,"required":false,"displayName":"Generated","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/1UDaTATWOnYorewjEF5-G9edgSBjc2_Rb50BZVFbAu8U/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1UDaTATWOnYorewjEF5-G9edgSBjc2_Rb50BZVFbAu8U","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1UDaTATWOnYorewjEF5-G9edgSBjc2_Rb50BZVFbAu8U/edit?usp=drivesdk","cachedResultName":"n8n-wp"}},"typeVersion":4.6},{"id":"d7697c4b-e651-414c-a7eb-171ef43110b6","name":"Generate Blog Topics AI","type":"@n8n/n8n-nodes-langchain.agent","position":[-700,400],"parameters":{"text":"=Prepare a blog topic - Make the title great for SEO.\n\nNOTE.\nGenerate 5 topics.\nIn the response, provide JSON code: \n{\n  \"Topic\": \"Sample topic\"\n}\nDo not add markdown, do not add '''json'.\nDo not add numbers to topics.\n\nWrite about {{ $json.Topic }}","options":{},"promptType":"define","hasOutputParser":true},"executeOnce":false,"typeVersion":2},{"id":"b6c75452-0f77-426e-bf0f-c20ecaf620e4","name":"Form: Enter Topic for Ideas","type":"n8n-nodes-base.form","position":[-980,400],"webhookId":"fcee9395-085e-4831-9bbf-32ce2f571027","parameters":{"options":{"buttonLabel":"NEXT"},"formFields":{"values":[{"fieldLabel":"Topic"}]}},"typeVersion":1},{"id":"63701441-2b94-4a59-804c-ff25494749db","name":"Form: Add More Topics?","type":"n8n-nodes-base.form","position":[240,400],"webhookId":"e897fa2c-f8a3-4e4e-ae03-14725ba1d705","parameters":{"options":{"buttonLabel":"NEXT","formDescription":"={{ $items().map(item => \"- \" + item.json.Prompt).join('\\n') }}"},"formFields":{"values":[{"fieldType":"dropdown","fieldLabel":"What next?","fieldOptions":{"values":[{"option":"END"},{"option":"NEXT"}]}}]}},"typeVersion":1},{"id":"562cd4ea-8fc2-43bb-a0f8-b84e63e55807","name":"If Add More Topics","type":"n8n-nodes-base.if","position":[460,400],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"73836e3b-ce8d-4e69-be29-82971a6bd82c","operator":{"type":"string","operation":"contains"},"leftValue":"={{ $json[\"What next?\"] }}","rightValue":"NEXT"}]}},"typeVersion":2.2},{"id":"754f0694-c09b-46b0-9566-293889ecd68a","name":"Gemini Model for Topics","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[-740,560],"parameters":{"options":{},"modelName":"models/gemini-1.5-flash-latest"},"typeVersion":1},{"id":"72976425-ebbf-4d31-97b4-898648c13b20","name":"Parse AI Topic Output","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[-500,560],"parameters":{"jsonSchemaExample":"[\n  {\n    \"Topic\": \"Example topic 1\"\n  },\n  {\n    \"Topic\": \"Example topic 2\"\n  },\n  {\n    \"Topic\": \"Example topic 3\"\n  },\n    {\n    \"Topic\": \"Example topic 4\"\n  },\n  {\n    \"Topic\": \"Example topic 5\"\n  }\n]"},"typeVersion":1.2},{"id":"c9c8c275-31c0-4a5f-a324-c27f3c18031b","name":"Split Topics","type":"n8n-nodes-base.splitOut","position":[-300,400],"parameters":{"options":{},"fieldToSplitOut":"output"},"typeVersion":1},{"id":"424cab92-8a0a-4407-972a-b82186d600f2","name":"Form: End Idea Generation","type":"n8n-nodes-base.form","position":[680,420],"webhookId":"ea907aa5-971f-4a0d-89a1-d834177d09c8","parameters":{"options":{},"operation":"completion","completionTitle":"END","completionMessage":"={{ $items(\"Generate Blog Topics AI\")[0].json.output.map(item => \"- \" + item.Topic).join('\\n') }}"},"typeVersion":1},{"id":"f15c02d2-44a1-450e-95ee-c95445dbcafc","name":"Form: End Post Generation","type":"n8n-nodes-base.form","position":[180,1180],"webhookId":"ea907aa5-971f-4a0d-89a1-d834177d09c8","parameters":{"options":{},"operation":"completion","completionTitle":"END","completionMessage":"={{ $items().map(item => \"- \" + item.json.Title).join('\\n') }}"},"typeVersion":1},{"id":"f25aabe7-ae32-4db9-9e37-3612a7f21a64","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-1040,260],"parameters":{"color":5,"height":400,"content":"## Generate Topics\nWhat topics should be generated?"},"typeVersion":1},{"id":"d5a4794e-1857-421b-b33f-cc3493f55e0e","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-120,260],"parameters":{"color":5,"height":380,"content":"## Add to Sheet\nAdd as topics for which posts have not yet been generated."},"typeVersion":1},{"id":"a8929634-52bc-414b-8301-e98fcae5e940","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[180,260],"parameters":{"color":5,"width":220,"height":380,"content":"## Add More?\nSelect in the form to add another 5 topics."},"typeVersion":1},{"id":"e2c3d8ad-eb78-441c-9576-082f91568131","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[440,260],"parameters":{"color":4,"width":220,"height":380,"content":"## Start Over or End\n"},"typeVersion":1},{"id":"ad74f19e-8811-4d2e-ba1d-b78df9ada687","name":"API Settings Note","type":"n8n-nodes-base.stickyNote","position":[-1580,1140],"parameters":{"width":960,"height":280,"content":"## WordPress & Pexels API Settings\nEdit settings by entering your WordPress data and Pexels API key.\n- `Search Pexels Image` node: Add Pexels API Key in Headers -> Authorization.\n- `Upload Image` & `Set Featured Image` nodes: Update URL with your WordPress site URL."},"typeVersion":1},{"id":"7f04b46b-0918-4afd-98ec-e1433f9ebdb7","name":"Workflow Instructions","type":"n8n-nodes-base.stickyNote","position":[-1640,-200],"parameters":{"width":500,"height":940,"content":"# Workflow Instructions\n\nThis workflow automates content creation, from idea generation to publishing on WordPress.\n\n**Prerequisites:**\n1.  Google Sheets account & a sheet with columns: `Date`, `Prompt`, `Title`, `Post ID`, `Generated`, `row_number`.\n2.  WordPress site with REST API enabled.\n3.  Google Gemini API Key.\n4.  Pexels API Key.\n\n**Setup Steps:**\n1.  **Credentials:** Configure credentials for Google Sheets, WordPress, and Google Gemini in the respective n8n nodes.\n2.  **API Keys & URLs:**\n    *   In `Search Pexels Image` node: Set your Pexels API key in the `Authorization` header.\n    *   In `Upload Image` & `Set Featured Image` nodes: Replace `<YOUR_WORDPRESS_URL>` with your site's URL.\n3.  **Google Sheet:** Ensure `Document ID` and `Sheet Name` (e.g., `Sheet1`) are correct in all Google Sheets nodes.\n4.  **Activate Workflow.**\n\n**How it works:**\nThe workflow starts with `Form Trigger: Select Action`:\n*   **Generate Content:** Fetches ideas marked `no` in `Generated` column, creates an article, finds an image, posts to WordPress, and updates the sheet.\n*   **Add Ideas:** Prompts for a general topic, generates 5 blog ideas, adds them to the sheet, and asks if you want to generate more."},"typeVersion":1}],"connections":{"Set Prompt":{"main":[[{"node":"Generate Article AI","type":"main","index":0}]]},"Split Topics":{"main":[[{"node":"Add Ideas to Sheet","type":"main","index":0}]]},"Upload Image":{"main":[[{"node":"Set Featured Image","type":"main","index":0}]]},"Add Ideas to Sheet":{"main":[[{"node":"Form: Add More Topics?","type":"main","index":0}]]},"If Add More Topics":{"main":[[{"node":"Form: Enter Topic for Ideas","type":"main","index":0}],[{"node":"Form: End Idea Generation","type":"main","index":0}]]},"Set Featured Image":{"main":[[{"node":"Update Google Sheet","type":"main","index":0}]]},"Generate Article AI":{"main":[[{"node":"Generate Image Keyword AI","type":"main","index":0}]]},"If Generate Content":{"main":[[{"node":"Fetch Unprocessed Ideas","type":"main","index":0}],[{"node":"Form: Enter Topic for Ideas","type":"main","index":0}]]},"Search Pexels Image":{"main":[[{"node":"Create WordPress Post","type":"main","index":0}]]},"Update Google Sheet":{"main":[[{"node":"Form: End Post Generation","type":"main","index":0}]]},"Create WordPress Post":{"main":[[{"node":"Download Pexels Image","type":"main","index":0}]]},"Download Pexels Image":{"main":[[{"node":"Upload Image","type":"main","index":0}]]},"Parse AI Topic Output":{"ai_outputParser":[[{"node":"Generate Blog Topics AI","type":"ai_outputParser","index":0}]]},"Form: Add More Topics?":{"main":[[{"node":"If Add More Topics","type":"main","index":0}]]},"Fetch Unprocessed Ideas":{"main":[[{"node":"Set Prompt","type":"main","index":0}]]},"Gemini Model for Topics":{"ai_languageModel":[[{"node":"Generate Blog Topics AI","type":"ai_languageModel","index":0}]]},"Generate Blog Topics AI":{"main":[[{"node":"Split Topics","type":"main","index":0}]]},"Gemini Model for Article":{"ai_languageModel":[[{"node":"Generate Article AI","type":"ai_languageModel","index":0}]]},"Generate Image Keyword AI":{"main":[[{"node":"Search Pexels Image","type":"main","index":0}]]},"Form Trigger: Select Action":{"main":[[{"node":"If Generate Content","type":"main","index":0}]]},"Form: Enter Topic for Ideas":{"main":[[{"node":"Generate Blog Topics AI","type":"main","index":0}]]},"Gemini Model for Image Keyword":{"ai_languageModel":[[{"node":"Generate Image Keyword AI","type":"ai_languageModel","index":0}]]}}}


