# templates

name: RAG Chatbot for Company Documents using Google Drive and Gemini
author_name: Mihai Farcas
author_username: mihailtd
categories: []
created_at: 2025-01-20T00:06:27.623Z
updated_at: 2025-01-20T00:06:27.623Z
url: https://n8n.io/workflows/2753
scraped_at: 2025-06-19 22:07:56
description:
  This workflow implements a Retrieval Augmented Generation (RAG) chatbot that answers employee questions based on company documents stored in Google Drive. It automatically indexes new or updated documents in a Pinecone vector database, allowing the chatbot to provide accurate and up-to-date information. The workflow uses Google's Gemini AI for both embeddings and response generation.

  How it works
  The workflow uses two Google Drive Trigger nodes: one for detecting new files added to a specified Google Drive folder, and another for detecting file updates in that same folder.
  Automated Indexing: When a new or updated document is detected
  The Google Drive node downloads the file.
  The Default Data Loader node loads the document content.
  The Recursive Character Text Splitter node breaks the document into smaller text chunks.
  The Embeddings Google Gemini node generates embeddings for each text chunk using the text-embedding-004 model.
  The Pinecone Vector Store node indexes the text chunks and their embeddings in a specified Pinecone index.
  7.The Chat Trigger node receives user questions through a chat interface. The user's question is passed to an AI Agent node.
  The AI Agent node uses a Vector Store Tool node, linked to a Pinecone Vector Store node in query mode, to retrieve relevant text chunks from Pinecone based on the user's question.
  The AI Agent sends the retrieved information and the user's question to the Google Gemini Chat Model (gemini-pro).
  The Google Gemini Chat Model generates a comprehensive and informative answer based on the retrieved documents.
  A Window Buffer Memory node connected to the AI Agent provides short-term memory, allowing for more natural and context-aware conversations.

  Set up steps

  Google Cloud Project and Vertex AI API:
  Create a Google Cloud project.
  Enable the Vertex AI API for your project.
  Google AI API Key:
  Obtain a Google AI API key from Google AI Studio.
  Pinecone Account:
  Create a free account on the Pinecone website.
  Obtain your API key from your Pinecone dashboard.
  Create an index named company-files in your Pinecone project.
  Google Drive:
  Create a dedicated folder in your Google Drive where company documents will be stored.
  Credentials in n8n: Configure credentials in your n8n environment for:
  Google Drive OAuth2
  Google Gemini(PaLM) Api (using your Google AI API key)
  Pinecone API (using your Pinecone API key)
  Import the Workflow:
  Import this workflow into your n8n instance.
  Configure the Workflow:
  Update both Google Drive Trigger nodes to watch the specific folder you created in your Google Drive.
  Configure the Pinecone Vector Store nodes to use your company-files index.

nodes_used:
  ["n8n-nodes-base.googleDrive","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.memoryBufferWindow","@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter","@n8n/n8n-nodes-langchain.vectorStorePinecone","@n8n/n8n-nodes-langchain.documentDefaultDataLoader","@n8n/n8n-nodes-langchain.embeddingsGoogleGemini","@n8n/n8n-nodes-langchain.lmChatGoogleGemini","@n8n/n8n-nodes-langchain.toolVectorStore"]

workflow_json:
  {"id":"7cXvgkl9170QXzT2","meta":{"instanceId":"69133932b9ba8e1ef14816d0b63297bb44feb97c19f759b5d153ff6b0c59e18d","templateCredsSetupCompleted":true},"name":"RAG Workflow For Company Documents stored in Google Drive","tags":[],"nodes":[{"id":"753455a3-ddc8-4a74-b043-70a0af38ff9e","name":"Pinecone Vector Store","type":"@n8n/n8n-nodes-langchain.vectorStorePinecone","position":[680,0],"parameters":{"mode":"insert","options":{},"pineconeIndex":{"__rl":true,"mode":"list","value":"company-files","cachedResultName":"company-files"}},"credentials":{"pineconeApi":{"id":"bQTNry52ypGLqt47","name":"PineconeApi account"}},"typeVersion":1},{"id":"a7c8fa7f-cad2-4497-a295-30aa2e98cacc","name":"Embeddings Google Gemini","type":"@n8n/n8n-nodes-langchain.embeddingsGoogleGemini","position":[640,280],"parameters":{"modelName":"models/text-embedding-004"},"credentials":{"googlePalmApi":{"id":"jLOqyTR4yTT1nYKi","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"215f0519-4359-4e4b-a90c-7e54b1cc52b5","name":"Default Data Loader","type":"@n8n/n8n-nodes-langchain.documentDefaultDataLoader","position":[840,220],"parameters":{"options":{},"dataType":"binary","binaryMode":"specificField"},"typeVersion":1},{"id":"863d3d1d-1621-406e-8320-688f64b07b09","name":"Recursive Character Text Splitter","type":"@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter","position":[820,420],"parameters":{"options":{},"chunkOverlap":100},"typeVersion":1},{"id":"5af1efb1-ea69-466e-bb3b-2b7e6b1ceef7","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[420,840],"parameters":{"options":{"systemMessage":"You are a helpful HR assistant designed to answer employee questions based on company policies.\n\nRetrieve relevant information from the provided internal documents and provide a concise, accurate, and informative answer to the employee's question.\n\nUse the tool called \"company_documents_tool\" to retrieve any information from the company's documents.\n\nIf the answer cannot be found in the provided documents, respond with \"I cannot find the answer in the available resources.\""}},"typeVersion":1.7},{"id":"825632ac-1edf-4e63-948d-b1a498b2b962","name":"Vector Store Tool","type":"@n8n/n8n-nodes-langchain.toolVectorStore","position":[820,1060],"parameters":{"name":"company_documents_tool","description":"Retrieve information from any company documents"},"typeVersion":1},{"id":"72d2f685-bcc3-4e62-a5e3-72c0fe65f8e8","name":"Pinecone Vector Store (Retrieval)","type":"@n8n/n8n-nodes-langchain.vectorStorePinecone","position":[720,1240],"parameters":{"options":{},"pineconeIndex":{"__rl":true,"mode":"list","value":"company-files","cachedResultName":"company-files"}},"credentials":{"pineconeApi":{"id":"bQTNry52ypGLqt47","name":"PineconeApi account"}},"typeVersion":1},{"id":"eeff81cb-6aec-4e7f-afe0-432d87085fb2","name":"Embeddings Google Gemini (retrieval)","type":"@n8n/n8n-nodes-langchain.embeddingsGoogleGemini","position":[700,1400],"parameters":{"modelName":"models/text-embedding-004"},"credentials":{"googlePalmApi":{"id":"jLOqyTR4yTT1nYKi","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"8bb6ebb1-1deb-498b-8da4-b809a736e097","name":"Download File From Google Drive","type":"n8n-nodes-base.googleDrive","position":[460,0],"parameters":{"fileId":{"__rl":true,"mode":"id","value":"={{ $json.id }}"},"options":{"fileName":"={{ $json.name }}"},"operation":"download"},"credentials":{"googleDriveOAuth2Api":{"id":"uixLsi5TmrfwXPeB","name":"Google Drive account"}},"typeVersion":3},{"id":"bd83bacf-dff1-4b7c-af5c-b249fb16c113","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[420,660],"parameters":{"content":"## Chat with company documents"},"typeVersion":1},{"id":"7b90daab-0fb2-4c8a-93e6-b138bb04f282","name":"Google Drive File Updated","type":"n8n-nodes-base.googleDriveTrigger","position":[140,140],"parameters":{"event":"fileUpdated","options":{},"pollTimes":{"item":[{"mode":"everyMinute"}]},"triggerOn":"specificFolder","folderToWatch":{"__rl":true,"mode":"list","value":"1evDIoHePhjw_LgVFZXSZyK1sZm2GHp9W","cachedResultUrl":"https://drive.google.com/drive/folders/1evDIoHePhjw_LgVFZXSZyK1sZm2GHp9W","cachedResultName":"INNOVI PRO"}},"credentials":{"googleDriveOAuth2Api":{"id":"uixLsi5TmrfwXPeB","name":"Google Drive account"}},"typeVersion":1},{"id":"3a6c6cef-7a19-42ef-8092-eaf57dae4cdd","name":"Google Drive File Created","type":"n8n-nodes-base.googleDriveTrigger","position":[140,-120],"parameters":{"event":"fileCreated","options":{"fileType":"all"},"pollTimes":{"item":[{"mode":"everyMinute"}]},"triggerOn":"specificFolder","folderToWatch":{"__rl":true,"mode":"list","value":"1evDIoHePhjw_LgVFZXSZyK1sZm2GHp9W","cachedResultUrl":"https://drive.google.com/drive/folders/1evDIoHePhjw_LgVFZXSZyK1sZm2GHp9W","cachedResultName":"INNOVI PRO"}},"credentials":{"googleDriveOAuth2Api":{"id":"uixLsi5TmrfwXPeB","name":"Google Drive account"}},"typeVersion":1},{"id":"1e38f1c8-7bd0-4eeb-addc-62339582d350","name":"Window Buffer Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[500,1140],"parameters":{},"typeVersion":1.3},{"id":"4b0ab858-99b1-4337-8c5c-a223519e3662","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[80,840],"webhookId":"5f1c0c82-0ff9-40c7-9e2e-b1a96ffe24cd","parameters":{"options":{}},"typeVersion":1.1},{"id":"bfb684d1-e5c1-41da-8305-b2606a2eade6","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[440,-240],"parameters":{"width":320,"content":"## Add docuemnts to vector store when updating or creating new documents in Google Drive"},"typeVersion":1},{"id":"8f627ec6-4b3f-43ad-a4a3-e2b199a7fe58","name":"Google Gemini Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[320,1140],"parameters":{"options":{},"modelName":"models/gemini-2.0-flash-exp"},"credentials":{"googlePalmApi":{"id":"jLOqyTR4yTT1nYKi","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"f2133a06-0088-46de-9f74-a3f9fe478f98","name":"Google Gemini Chat Model (retrieval)","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[1080,1240],"parameters":{"options":{},"modelName":"models/gemini-2.0-flash-exp"},"credentials":{"googlePalmApi":{"id":"jLOqyTR4yTT1nYKi","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"578deb96-8393-4850-9757-fa97b2bc9992","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-540,220],"parameters":{"width":420,"height":720,"content":"## Set up steps\n\n1. Google Cloud Project and Vertex AI API:\n* Create a Google Cloud project.\n* Enable the Vertex AI API for your project.\n2. Google AI API Key:\n* Obtain a Google AI API key from Google AI Studio.\n3. Pinecone Account:\n* Create a free account on the Pinecone website.\nObtain your API key from your Pinecone dashboard.\n* Create an index named company-files in your Pinecone project.\n4. Google Drive:\n* Create a dedicated folder in your Google Drive where company documents will be stored.\n5. Credentials in n8n: Configure credentials in your n8n environment for:\n* Google Drive OAuth2\n* Google Gemini(PaLM) Api (using your Google AI API key)\n* Pinecone API (using your Pinecone API key)\n5. Import the Workflow:\n* Import this workflow into your n8n instance.\n6. Configure the Workflow:\n* Update both Google Drive Trigger nodes to watch the specific folder you created in your Google Drive.\n* Configure the Pinecone Vector Store nodes to use your company-files index."},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"33b252fb-5d87-4a29-a0a7-97308140699c","connections":{"AI Agent":{"main":[[]]},"Vector Store Tool":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Default Data Loader":{"ai_document":[[{"node":"Pinecone Vector Store","type":"ai_document","index":0}]]},"Window Buffer Memory":{"ai_memory":[[{"node":"AI Agent","type":"ai_memory","index":0}]]},"Pinecone Vector Store":{"main":[[]]},"Embeddings Google Gemini":{"ai_embedding":[[{"node":"Pinecone Vector Store","type":"ai_embedding","index":0}]]},"Google Gemini Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Google Drive File Created":{"main":[[{"node":"Download File From Google Drive","type":"main","index":0}]]},"Google Drive File Updated":{"main":[[{"node":"Download File From Google Drive","type":"main","index":0}]]},"When chat message received":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Download File From Google Drive":{"main":[[{"node":"Pinecone Vector Store","type":"main","index":0}]]},"Pinecone Vector Store (Retrieval)":{"ai_vectorStore":[[{"node":"Vector Store Tool","type":"ai_vectorStore","index":0}]]},"Recursive Character Text Splitter":{"ai_textSplitter":[[{"node":"Default Data Loader","type":"ai_textSplitter","index":0}]]},"Embeddings Google Gemini (retrieval)":{"ai_embedding":[[{"node":"Pinecone Vector Store (Retrieval)","type":"ai_embedding","index":0}]]},"Google Gemini Chat Model (retrieval)":{"ai_languageModel":[[{"node":"Vector Store Tool","type":"ai_languageModel","index":0}]]}}}


name: Create a Branded AI-Powered Website Chatbot
author_name: Wayne Simpson
author_username: nocodecreative
categories: []
created_at: 2025-01-23T17:44:16.860Z
updated_at: 2025-01-23T17:44:16.860Z
url: https://n8n.io/workflows/2786
scraped_at: 2025-06-19 22:07:56
description:
  Create a Branded AI Website Chatbot

  Engage website visitors with an intelligent chat widget powered by OpenAI. This template includes:

  💬 Natural conversation handling
  📅 Microsoft Outlook calendar integration
  📝 Lead capture and information gathering
  🔄 Human handoff capabilities

  Simply add a JavaScript snippet to your website and configure the workflow to match your needs. Follow our detailed setup guide to get started in minutes.



  &gt; Note: Widget includes a "Powered By" affiliate link

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

workflow_json:
  {"meta":{"instanceId":"67d4d33d8b0ad4e5e12f051d8ad92fc35893d7f48d7f801bc6da4f39967b3592","templateCredsSetupCompleted":true},"nodes":[{"id":"22c8d63b-ce3c-4aab-b3f6-4bae8c1b9ec5","name":"Window Buffer Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[1460,880],"parameters":{"sessionKey":"={{ $json.sessionId }}","sessionIdType":"customKey","contextWindowLength":20},"typeVersion":1.2},{"id":"45403d5c-6e85-424f-b40b-c6214b57457b","name":"Respond to Webhook","type":"n8n-nodes-base.respondToWebhook","position":[1880,580],"parameters":{"options":{}},"typeVersion":1.1},{"id":"1111262a-1743-4bae-abf1-f69d2e1a580c","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[1360,760],"parameters":{"model":"gpt-4o-2024-08-06","options":{"temperature":0.4}},"credentials":{"openAiApi":{"id":"XWFTuTtx9oWglhNn","name":"OpenAi account"}},"typeVersion":1},{"id":"df891547-c715-4dc6-bfcc-c0ac5cfcaf02","name":"Make Appointment","type":"@n8n/n8n-nodes-langchain.toolHttpRequest","position":[1820,840],"parameters":{"url":"https://graph.microsoft.com/v1.0/me/events","method":"POST","jsonBody":"{\n  \"subject\": \"Meetings with <name> at <company>\",\n  \"start\": {\n    \"dateTime\": \"{dateStartTime}\",\n    \"timeZone\": \"Europe/London\"\n  },\n  \"end\": {\n    \"dateTime\": \"{dateEndTime}\",\n    \"timeZone\": \"Europe/London\"\n  },\n  \"body\": {\n    \"contentType\": \"HTML\",\n    \"content\": \"{reason}\"\n  },\n  \"attendees\": [\n    {\n      \"emailAddress\": {\n        \"address\": \"{email}\",\n        \"name\": \"{name}\"\n      },\n      \"type\": \"required\"\n    }\n  ],\n  \"location\": {\n    \"displayName\": \"Online Meeting\"\n  },\n  \"isOnlineMeeting\": true,\n  \"onlineMeetingProvider\": \"teamsForBusiness\",\n  \"showAs\": \"busy\",\n  \"categories\": [\n    \"Meeting\"\n  ]\n}","sendBody":true,"sendQuery":true,"specifyBody":"json","authentication":"predefinedCredentialType","parametersQuery":{"values":[{"name":"Content-Type","value":"application/json","valueProvider":"fieldValue"}]},"toolDescription":"Call this tool to make the appointment, ensure you send the user email, name, company, reason for the meeting and the appointment start time and the date in ISO String format with timezone for <timezone>. When creating an appointment, always send JSON.","nodeCredentialType":"microsoftOutlookOAuth2Api","placeholderDefinitions":{"values":[{"name":"dateStartTime","type":"string","description":"The date and start time of the appointment in toISOString format with timezone for Europe/London"},{"name":"dateEndTime","type":"string","description":"The date and end time of the appointment in toISOString format, always 30 minutes after the dateStartTime,  format with timezone for Europe/London"},{"name":"reason","type":"string","description":"Detailed description of the meeting, will be sent to us and the customer"},{"name":"email","type":"string","description":"The customers email address."},{"name":"name","type":"string","description":"The customers full name, must be second and last name"}]}},"credentials":{"microsoftOutlookOAuth2Api":{"id":"E0WY3yUNKgrxIwLU","name":"Microsoft Outlook Business"}},"typeVersion":1.1},{"id":"44141c44-de49-4707-b287-24007c84ca21","name":"Execute Workflow Trigger","type":"n8n-nodes-base.executeWorkflowTrigger","position":[2160,580],"parameters":{},"typeVersion":1},{"id":"795e1451-57d8-4563-8b86-5a75df2427b6","name":"varResponse","type":"n8n-nodes-base.set","position":[3120,460],"parameters":{"options":{},"assignments":{"assignments":[{"id":"c0b6e779-0f7b-41f0-81f8-457f2b31ccfe","name":"response","type":"array","value":"={{ $json.freeTimeSlots.toJsonString() }}"}]}},"typeVersion":3.4},{"id":"4283635f-649c-4cc7-84b9-37524ddb6ce0","name":"freeTimeSlots","type":"n8n-nodes-base.code","position":[2900,460],"parameters":{"jsCode":"// Input: An array with objects containing a 'value' array of events.\nconst businessHoursStart = \"08:00:00Z\";  // Business hours start time\nconst businessHoursEnd = \"17:30:00Z\";    // Business hours end time\n\nconst inputData = items[0].json.value;  // Assuming the input data is in the 'value' array of the first item\n\n// Function to convert ISO datetime string to a Date object with specified time\nfunction getDateWithTime(dateString, time) {\n  const datePart = new Date(dateString).toISOString().split(\"T\")[0];  // Extract the date part (YYYY-MM-DD)\n  return new Date(`${datePart}T${time}`);\n}\n\n// Function to get day of the week from a date string\nfunction getDayOfWeek(dateString) {\n  const daysOfWeek = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\n  return daysOfWeek[new Date(dateString).getUTCDay()];\n}\n\n// Function to add days to a date\nfunction addDays(date, days) {\n  const result = new Date(date);\n  result.setDate(result.getDate() + days);\n  return result;\n}\n\n// Function to format date as YYYY-MM-DD\nfunction formatDate(date) {\n  return date.toISOString().split('T')[0];\n}\n\n// Determine the default timezone from input data\nconst defaultTimeZone = inputData.length > 0 && inputData[0].start && inputData[0].start.timeZone \n  ? inputData[0].start.timeZone \n  : \"UTC\";\n\n// Find min and max dates in the input\nlet minDate = null;\nlet maxDate = null;\n\ninputData.forEach(event => {\n  if (event.start && event.start.dateTime) {\n    const eventDate = new Date(event.start.dateTime);\n    if (!minDate || eventDate < minDate) {\n      minDate = eventDate;\n    }\n    if (!maxDate || eventDate > maxDate) {\n      maxDate = eventDate;\n    }\n  }\n});\n\n// If we have valid dates, ensure they're at the start of the day\nif (minDate && maxDate) {\n  minDate = new Date(minDate.toISOString().split('T')[0]);\n  maxDate = new Date(maxDate.toISOString().split('T')[0]);\n}\n\n// Organise events by date\nconst eventsByDate = {};\ninputData.forEach(event => {\n  if (event.start && event.start.dateTime) {\n    const eventDate = new Date(event.start.dateTime).toISOString().split(\"T\")[0];  // Extract the date\n    if (!eventsByDate[eventDate]) {\n      eventsByDate[eventDate] = [];\n    }\n    if (event.showAs === \"busy\") {\n      eventsByDate[eventDate].push({\n        start: new Date(event.start.dateTime),\n        end: new Date(event.end.dateTime),\n        timeZone: event.start.timeZone || defaultTimeZone\n      });\n    }\n  }\n});\n\n// Find free slots within business hours for each date\nconst freeTimeSlots = [];\n\n// Process all dates in the range\nif (minDate && maxDate) {\n  for (let currentDate = new Date(minDate); currentDate <= maxDate; currentDate = addDays(currentDate, 1)) {\n    const dateStr = formatDate(currentDate);\n    const busyEvents = eventsByDate[dateStr] || [];\n    \n    // Define business start and end times for the current date\n    const businessStart = getDateWithTime(dateStr, businessHoursStart);\n    const businessEnd = getDateWithTime(dateStr, businessHoursEnd);\n    \n    // If there are no busy events for this date, add the entire business day as free\n    if (busyEvents.length === 0) {\n      freeTimeSlots.push({\n        date: dateStr,\n        dayOfWeek: getDayOfWeek(dateStr),\n        freeStart: businessStart.toISOString(),\n        freeEnd: businessEnd.toISOString(),\n        timeZone: defaultTimeZone\n      });\n      continue; // Skip to the next date\n    }\n    \n    // Sort events by their start time\n    busyEvents.sort((a, b) => a.start - b.start);\n    \n    // Check if there's free time before the first busy event\n    if (busyEvents[0].start > businessStart) {\n      freeTimeSlots.push({\n        date: dateStr,\n        dayOfWeek: getDayOfWeek(dateStr),\n        freeStart: businessStart.toISOString(),\n        freeEnd: busyEvents[0].start.toISOString(),\n        timeZone: busyEvents[0].timeZone\n      });\n    }\n    \n    // Check for gaps between busy events\n    for (let i = 0; i < busyEvents.length - 1; i++) {\n      if (busyEvents[i].end < busyEvents[i+1].start) {\n        freeTimeSlots.push({\n          date: dateStr,\n          dayOfWeek: getDayOfWeek(dateStr),\n          freeStart: busyEvents[i].end.toISOString(),\n          freeEnd: busyEvents[i+1].start.toISOString(),\n          timeZone: busyEvents[i].timeZone\n        });\n      }\n    }\n    \n    // Check if there's free time after the last busy event\n    if (busyEvents[busyEvents.length - 1].end < businessEnd) {\n      freeTimeSlots.push({\n        date: dateStr,\n        dayOfWeek: getDayOfWeek(dateStr),\n        freeStart: busyEvents[busyEvents.length - 1].end.toISOString(),\n        freeEnd: businessEnd.toISOString(),\n        timeZone: busyEvents[busyEvents.length - 1].timeZone\n      });\n    }\n  }\n}\n\n// Output the free time slots\nreturn [{ json: { freeTimeSlots } }];\n"},"typeVersion":2},{"id":"0786b561-449e-4c8f-bddb-c2bbd95dc197","name":"Get Events","type":"n8n-nodes-base.httpRequest","position":[2680,460],"parameters":{"url":"=https://graph.microsoft.com/v1.0/me/calendarView","options":{},"sendQuery":true,"sendHeaders":true,"authentication":"predefinedCredentialType","queryParameters":{"parameters":[{"name":"startDateTime","value":"={{ new Date(new Date().setDate(new Date().getDate() + 2)).toISOString() }}"},{"name":"endDateTime","value":"={{ new Date(new Date().setDate(new Date().getDate() + 16)).toISOString() }}"},{"name":"$top","value":"50"},{"name":"select","value":"start,end,categories,importance,isAllDay,recurrence,showAs,subject,type"},{"name":"orderby","value":"start/dateTime asc"}]},"headerParameters":{"parameters":[{"name":"Prefer","value":"outlook.timezone=\"Europe/London\""}]},"nodeCredentialType":"microsoftOutlookOAuth2Api"},"credentials":{"microsoftOutlookOAuth2Api":{"id":"E0WY3yUNKgrxIwLU","name":"Microsoft Outlook Business"}},"typeVersion":4.2},{"id":"55c4233e-d395-4193-9a1d-1884faed6f1e","name":"Get Availability","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[1760,1080],"parameters":{"name":"Get_availability","fields":{"values":[{"name":"route","stringValue":"availability"}]},"workflowId":{"__rl":true,"mode":"list","value":"KD21RG8VeXYDS2Vf","cachedResultName":"Website Chatbot"},"description":"Call this tool to check my calendar for availability before booking an appointment. This will result in all events for the next 2 weeks. Review all events and do not double book."},"typeVersion":1.2},{"id":"096d1962-31e6-4b3b-ba75-7956f70a6a32","name":"Send Message","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[1620,1080],"parameters":{"name":"Send_email","fields":{"values":[{"name":"route","stringValue":"message"}]},"workflowId":{"__rl":true,"mode":"list","value":"KD21RG8VeXYDS2Vf","cachedResultName":"Website Chatbot"},"description":"Call this tool when the customer wants to speak to a human, or is not ready to make an appointment or if the customer has questions outside of your remit. The tool will send an email to our founder, <insert name>. Always send the customer's full name, company and email address along with a detailed message about the enquiry. You must always gather project details.","jsonSchemaExample":"{\n\t\"email\": \"the customer's email\",\n    \"subject\": \"the subject of the email\",\n    \"message\": \"The customer's enquiry, must be a detailed description of their enquiry\",\n    \"name\": \"the customer's full name\",\n    \"company\": \"the customer company name\"\n}","specifyInputSchema":true},"typeVersion":1.2},{"id":"285ddd31-5412-4d1c-ab80-d9960ec902bb","name":"Chat Trigger","type":"@n8n/n8n-nodes-langchain.chatTrigger","disabled":true,"position":[620,600],"webhookId":"f406671e-c954-4691-b39a-66c90aa2f103","parameters":{"mode":"webhook","public":true,"options":{"responseMode":"responseNode","allowedOrigins":"*"}},"typeVersion":1},{"id":"032a26e9-6853-490d-991b-b2af2d845f58","name":"Switch","type":"n8n-nodes-base.switch","position":[2380,580],"parameters":{"rules":{"values":[{"outputKey":"availability","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.route }}","rightValue":"availability"}]},"renameOutput":true},{"outputKey":"message","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"52fd844b-cc8d-471f-a56a-40e119b66194","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.route }}","rightValue":"message"}]},"renameOutput":true}]},"options":{}},"typeVersion":3.2},{"id":"c74905ce-4fd9-486c-abc4-b0b1d57d71a8","name":"varMessageResponse","type":"n8n-nodes-base.set","position":[2900,700],"parameters":{"options":{"ignoreConversionErrors":false},"assignments":{"assignments":[{"id":"0d2ad084-9707-4979-84e4-297d1c21f725","name":"response","type":"string","value":"={{ $json }}"}]}},"typeVersion":3.4},{"id":"04c5d43c-1629-4e11-a6bb-ae73369d7002","name":"Send Message1","type":"n8n-nodes-base.microsoftOutlook","position":[2680,700],"webhookId":"d8acc2cb-fcba-4312-a743-e74abe76d071","parameters":{"subject":"={{ $('Execute Workflow Trigger').item.json.query.subject }}","bodyContent":"=<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>New Webchat Customer Enquiry</title>\n    <style type=\"text/css\">\n        /* Client-specific styles */\n        body, table, td, a { -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }\n        table, td { mso-table-lspace: 0pt; mso-table-rspace: 0pt; }\n        img { -ms-interpolation-mode: bicubic; }\n\n        /* Reset styles */\n        body { margin: 0; padding: 0; }\n        img { border: 0; height: auto; line-height: 100%; outline: none; text-decoration: none; }\n        table { border-collapse: collapse !important; }\n        body { height: 100% !important; margin: 0; padding: 0; width: 100% !important; }\n\n        /* iOS BLUE LINKS */\n        a[x-apple-data-detectors] {\n            color: inherit !important;\n            text-decoration: none !important;\n            font-size: inherit !important;\n            font-family: inherit !important;\n            font-weight: inherit !important;\n            line-height: inherit !important;\n        }\n\n        /* Styles for Outlook and other email clients */\n        .ExternalClass { width: 100%; }\n        .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div { line-height: 100%; }\n        \n        /* Responsive styles */\n        @media screen and (max-width: 600px) {\n            .container { width: 100% !important; }\n            .content { padding: 15px !important; }\n            .field { padding: 10px !important; }\n            .header h1 { font-size: 20px !important; }\n            .header p { font-size: 12px !important; }\n        }\n    </style>\n</head>\n<body style=\"margin: 0; padding: 0; background-color: #f4f4f4;\">\n    <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n        <tr>\n            <td>\n                <table align=\"center\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"600\" style=\"border-collapse: collapse; background-color: #ffffff;\">\n                    <tr>\n                        <td align=\"center\" bgcolor=\"#1a1a1a\" style=\"padding: 30px 0; background: linear-gradient(135deg, #1a1a1a 0%, #2d1f3d 100%);\">\n                            <h1 style=\"color: #ffffff; font-family: Arial, sans-serif; font-size: 24px; font-weight: 700; margin: 0; text-transform: uppercase; letter-spacing: 1px;\">New Customer Enquiry</h1>\n                            <p style=\"color: #ffffff; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; margin: 10px 0 0; opacity: 0.8;\">A potential client has reached out through our webchat</p>\n                        </td>\n                    </tr>\n                    <tr>\n                        <td style=\"padding: 20px;\">\n                            <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n                                <tr>\n                                    <td style=\"padding: 15px; background-color: #f9f9f9; border: 1px solid #e0e0e0; border-radius: 8px;\">\n                                        <p style=\"font-family: Arial, sans-serif; font-size: 14px; line-height: 1.6; color: #6a1b9a; font-weight: bold; margin: 0 0 5px 0;\">FROM</p>\n                                        <p style=\"font-family: Arial, sans-serif; font-size: 16px; line-height: 1.6; color: #333333; margin: 0;\">{{ $('Execute Workflow Trigger').item.json.query.name }}</p>\n                                    </td>\n                                </tr>\n                                <tr><td height=\"20\"></td></tr>\n                                <tr>\n                                    <td style=\"padding: 15px; background-color: #f9f9f9; border: 1px solid #e0e0e0; border-radius: 8px;\">\n                                        <p style=\"font-family: Arial, sans-serif; font-size: 14px; line-height: 1.6; color: #6a1b9a; font-weight: bold; margin: 0 0 5px 0;\">EMAIL</p>\n                                        <p style=\"font-family: Arial, sans-serif; font-size: 16px; line-height: 1.6; color: #333333; margin: 0;\">{{ $('Execute Workflow Trigger').item.json.query.email }}</p>\n                                    </td>\n                                </tr>\n                                <tr><td height=\"20\"></td></tr>\n                                <tr>\n                                    <td style=\"padding: 15px; background-color: #f9f9f9; border: 1px solid #e0e0e0; border-radius: 8px;\">\n                                        <p style=\"font-family: Arial, sans-serif; font-size: 14px; line-height: 1.6; color: #6a1b9a; font-weight: bold; margin: 0 0 5px 0;\">COMPANY</p>\n                                        <p style=\"font-family: Arial, sans-serif; font-size: 16px; line-height: 1.6; color: #333333; margin: 0;\">{{ $('Execute Workflow Trigger').item.json.query.company }}</p>\n                                    </td>\n                                </tr>\n                                <tr><td height=\"20\"></td></tr>\n                                <tr>\n                                    <td style=\"padding: 15px; background-color: #f9f9f9; border: 1px solid #e0e0e0; border-radius: 8px;\">\n                                        <p style=\"font-family: Arial, sans-serif; font-size: 14px; line-height: 1.6; color: #6a1b9a; font-weight: bold; margin: 0 0 5px 0;\">MESSAGE</p>\n                                        <p style=\"font-family: Arial, sans-serif; font-size: 16px; line-height: 1.6; color: #333333; margin: 0;\">{{ $('Execute Workflow Trigger').item.json.query.message }}</p>\n                                    </td>\n                                </tr>\n                            </table>\n                        </td>\n                    </tr>\n                    <tr>\n                        <td align=\"center\" bgcolor=\"#e90ebb\" style=\"padding: 20px; background: linear-gradient(135deg, #e90ebb 0%, #6a1b9a 100%);\">\n                            <p style=\"font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; color: #ffffff; margin: 0;\">This enquiry was automatically generated from our website's chat interface.</p>\n                        </td>\n                    </tr>\n                </table>\n            </td>\n        </tr>\n    </table>\n</body>\n</html>","toRecipients":"you@yourdomain.com","additionalFields":{"importance":"High","bodyContentType":"html"}},"credentials":{"microsoftOutlookOAuth2Api":{"id":"E0WY3yUNKgrxIwLU","name":"Microsoft Outlook Business"}},"typeVersion":2},{"id":"5a2636f1-47d3-4421-840b-56553bf14d82","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[1580,1000],"parameters":{"width":311.6936390497898,"height":205.34013605442183,"content":"Ensure these referance this workflow, replace placeholders"},"typeVersion":1},{"id":"a9fe05d4-6b86-4313-9f11-b20e3ce7db89","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[2600,380],"parameters":{"width":468,"height":238,"content":"modify business hours\nmodify timezones"},"typeVersion":1},{"id":"5dfda5c9-eeeb-421a-a80d-f42c94602080","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[1460,580],"parameters":{"text":"={{ $json.chatInput }}","options":{"systemMessage":"=You are an intelligent personal assistant to Wayne, Founder at nocodecreative.io (ai consultancy and software development agency) responsible for coordinating appointments and gathering relevant information from customers. Your tasks are to:\n\n- Understand when the customer is available by asking for suitable days and times (ensuring they are aware we are in a UK timezone)\n- Check the calendar to identify available slots that match their preferences. Pay attention to each event's start and end time and do not double book, you will be given all events for the next 14 days\n- Ask the customer what they would like to discuss during the appointment to ensure proper preparation.\n- Get the customer's name, company name and email address to book the appointment\n- Make the conversation friendly and natural. Confirm the appointment details with the customer and let them know I’ll be ready to discuss what they’d like.\n- After you have checked the calendar, book the appointment accordingly, without double booking. Confirm the customer's timezone and adjust the appointment for EU/London.\n- If the customer isn't ready to book, you can send an email for a human to respond to, ensure you gather a detailed enquiry from the customer including contact details and project information.Ensure the message contains enough information for a human to respond, always include project details, if the customer hasn't provided project details, ask.\n- Alwways suggest an appointment before sending a message, appointment are you primary goal, message are a fall back\n\nExample questions:\n\n\"Hi there! we'd love to help arrange a time that works for us to meet. Could you let us know which days and times are best for you? We’ll check the calendar and book in a suitable slot.\"\n\n\"Could you please let us know what you’d like to discuss during the appointment? This helps us prepare in advance and make our time together as productive as possible.\"\n\n\"Before we put you in touch with a human, please can you provide more information about the project you have in mind?\" //You must gather project info at all times, even if the enquiry is about pricing/costs.\n\nIf the time the customer suggests is not available, suggest the nearest alternative appointment based on existing events, do not book an appointment outside of freeTimeSlots\n\nImportant information:\n- All appointments need 48 hours' notice from {{ \n  new Date().toLocaleString(\"en-GB\", { timeZone: \"Europe/London\", hour12: false })\n  .split(\", \")[0].split(\"/\").reverse().join(\"-\") \n  + \"T\" + new Date().toLocaleTimeString(\"en-GB\", { timeZone: \"Europe/London\", hour12: false }) + \":00.000Z\" \n}} (current date and time in the UK) // this is non-negotiable, but discuss with care and be friendly, only let the customer know this if required\n- Business hours are 8am - 6pm Monday to Friday only Europe/London timezone, ensure the customer is aware of this and help them book during UK hours, you must confirm their timezone to do this!\n- Do not book appointments on a Saturday or sunday\n- Do not book appointments outside of freeTimeSlots\n- Always check the next 14 days, and review all events before providing availability \n- All appointments are for a max of 30 minutes\n- You must never offer an appointment without checking the calendar, if you cannot check the calendar, you cannot book and must let the customer know you can not book an appointment right now.\n- Always offer the soonest appointment available if the customer's preferred time is unavailable\n- When confirming an appointment, be thankful and excited!\n- Initial 30 minute consultation are free of charge\n\n\nMessages and description:\n- When creating descriptions or sending messages, always ensure enough detail is provided for preparation, meaning you can ask follow-up questions to extract further information as required. For example, if a customer asks about pricing, gather some information about the project so our team can provide accurate pricing, and apply this logic throughout\n\nComments:\n//!IMPORTANT! Do not offer any times without checking the calendar, do not make availability up\n//**Do not discuss anything other than appointment booking, if the query does not relate to an appointment, advise them you cannot help at this time.** be friendly and always offer to book an appointment to discuss their query\n//When the appointment is confirmed, let the customer know, by name, that they will be meeting our founder, Wayne for a 30 minute consultation, and that they will receive a calendar invite by email, ensure they accept the invite to confirm the appointment.\n//Always respond as a highly professional executive PA, remember this is the customer's first engagement, they do not know us or Wayne at this stage\n//Do not refer to yourself as me or I, instead communicate like an organisation, using terms like 'us'\n//Always gather project for descriptions and messages"},"promptType":"define"},"typeVersion":1.6},{"id":"6156ab7e-d411-46b9-ac44-52ad56ee563d","name":"If","type":"n8n-nodes-base.if","position":[840,600],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"158a0b91-534d-4745-b10e-8a7c97050861","operator":{"type":"string","operation":"exists","singleValue":true},"leftValue":"={{ $json.chatInput }}","rightValue":""}]}},"typeVersion":2.2},{"id":"c94171a9-a71d-4f63-bef6-e90361c57abd","name":"Respond With Initial Message","type":"n8n-nodes-base.respondToWebhook","position":[1140,720],"parameters":{"options":{},"respondWith":"json","responseBody":"{\n  \"output\": \"Hi, how can I help you today?\"\n}"},"typeVersion":1.1},{"id":"43129771-e976-41af-8adb-88cb5465628d","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[1340,-240],"parameters":{"color":6,"width":668,"height":111,"content":"# Custom Branded n8n Chatbot\nBuilt by [Wayne Simpson](https://www.linkedin.com/in/simpsonwayne/) at [nocodecreative.io](https://nocodecreative.io)\n☕ If you find this useful, feel free to [buy me a coffee](https://ko-fi.com/waynesimpson)"},"typeVersion":1},{"id":"bb890f44-caf0-4b7d-b95e-0c05c70e8f45","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[1000,-80],"parameters":{"color":7,"width":667,"height":497,"content":"# Watch the Setup Video 📺\n### Watch Set Up Video 👇\n[![Auto Categorise Outlook Emails with AI](https://cdn.jsdelivr.net/gh/WayneSimpson/n8n-chatbot-template/custom-branded-chatbot.png)](https://youtu.be/xQ1tCQZhLaI)\n\n"},"typeVersion":1},{"id":"f0b054cc-f961-4c48-846c-a80ea5e49924","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[1700,-80],"parameters":{"color":7,"width":600,"height":500,"content":"## Read to blog post to get started 📝\n**Follow along to add a custom branded chat widget to your webiste**\n\n[![Custom Branded n8n Chatbot](https://cdn.jsdelivr.net/gh/WayneSimpson/n8n-chatbot-template/chat%20widget.png)](https://blog.nocodecreative.io/create-a-branded-ai-powered-website-chatbot-with-n8n/)"},"typeVersion":1},{"id":"210cef85-6fbe-413e-88b6-b0fed76212ac","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[2600,640],"parameters":{"color":4,"width":260,"height":240,"content":"Customise the email template"},"typeVersion":1},{"id":"17abc6bd-06c3-48e7-8380-e10024daa9f5","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[1760,740],"parameters":{"color":6,"width":208,"height":238,"content":"modify timezones"},"typeVersion":1}],"pinData":{"Execute Workflow Trigger":[{"query":"Check availability for Monday at 9am","route":"availability"}]},"connections":{"If":{"main":[[{"node":"AI Agent","type":"main","index":0}],[{"node":"Respond With Initial Message","type":"main","index":0}]]},"Switch":{"main":[[{"node":"Get Events","type":"main","index":0}],[{"node":"Send Message1","type":"main","index":0}]]},"AI Agent":{"main":[[{"node":"Respond to Webhook","type":"main","index":0}]]},"Get Events":{"main":[[{"node":"freeTimeSlots","type":"main","index":0}]]},"Chat Trigger":{"main":[[{"node":"If","type":"main","index":0}]]},"Send Message":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Send Message1":{"main":[[{"node":"varMessageResponse","type":"main","index":0}]]},"freeTimeSlots":{"main":[[{"node":"varResponse","type":"main","index":0}]]},"Get Availability":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Make Appointment":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Window Buffer Memory":{"ai_memory":[[{"node":"AI Agent","type":"ai_memory","index":0}]]},"Execute Workflow Trigger":{"main":[[{"node":"Switch","type":"main","index":0}]]}}}


name: Chat with Postgresql Database
author_name: KumoHQ
author_username: kumohq
categories: []
created_at: 2025-02-07T10:20:16.255Z
updated_at: 2025-02-07T10:20:16.255Z
url: https://n8n.io/workflows/2859
scraped_at: 2025-06-19 22:07:56
description:
  Who is this template for?

  This workflow template is designed for any professionals seeking relevent data from database using natural language.

  How it works

  Each time user ask's question using the n8n chat interface, the workflow runs.
  Then the message is processed by AI Agent using relevent tools - Execute SQL Query, Get DB Schema and Tables List and Get Table Definition, if required. Agent uses these tool to form and run sql query which are necessary to answer the questions.
  Once AI Agent has the data, it uses it to form answer and returns it to the user.

  Set up instructions

  Complete the Set up credentials step when you first open the workflow. You'll need a Postgresql Credentials, and OpenAI api key.

  Template was created in n8n v1.77.0

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

workflow_json:
  {"id":"eOUewYsEzJmQixI6","meta":{"instanceId":"77c4feba8f41570ef06dc76ece9a6ded0f0d44f7f1477a64c2d71a8508c11faa","templateCredsSetupCompleted":true},"name":"Chat with Postgresql Database","tags":[],"nodes":[{"id":"6501a54f-a68c-452d-b353-d7e871ca3780","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[-300,-80],"webhookId":"cf1de04f-3e38-426c-89f0-3bdb110a5dcf","parameters":{"options":{}},"typeVersion":1.1},{"id":"cd32221b-2a36-408d-b57e-8115fcd810c9","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[0,-80],"parameters":{"agent":"openAiFunctionsAgent","options":{"systemMessage":"You are DB assistant. You need to run queries in DB aligned with user requests.\n\nRun custom SQL query to aggregate data and response to user. Make sure every table has schema prefix to it in sql query which you can get from `Get DB Schema and Tables List` tool.\n\nFetch all data to analyse it for response if needed.\n\n## Tools\n\n- Execute SQL query - Executes any sql query generated by AI\n- Get DB Schema and Tables List - Lists all the tables in database with its schema name\n- Get Table Definition - Gets the table definition from db using table name and schema name"}},"typeVersion":1.7},{"id":"8accbeeb-7eaf-4e9e-aabc-de8ab3a0459b","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-60,160],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"48uG61Ilo8jndw3r","name":"Your OpenAI Account Credentials"}},"typeVersion":1.2},{"id":"11f2013f-a080-4c9e-8773-c90492e2c628","name":"Get Table Definition","type":"n8n-nodes-base.postgresTool","position":[780,140],"parameters":{"query":"select\n  c.column_name,\n  c.data_type,\n  c.is_nullable,\n  c.column_default,\n  tc.constraint_type,\n  ccu.table_name AS referenced_table,\n  ccu.column_name AS referenced_column\nfrom\n  information_schema.columns c\nLEFT join\n  information_schema.key_column_usage kcu\n  ON c.table_name = kcu.table_name\n  AND c.column_name = kcu.column_name\nLEFT join\n  information_schema.table_constraints tc\n  ON kcu.constraint_name = tc.constraint_name\n  AND tc.constraint_type = 'FOREIGN KEY'\nLEFT join\n  information_schema.constraint_column_usage ccu\n  ON tc.constraint_name = ccu.constraint_name\nwhere\n  c.table_name = '{{ $fromAI(\"table_name\") }}'\n  AND c.table_schema = '{{ $fromAI(\"schema_name\") }}'\norder by\n  c.ordinal_position","options":{},"operation":"executeQuery","descriptionType":"manual","toolDescription":"Get table definition to find all columns and types"},"credentials":{"postgres":{"id":"nGI61D0TEEZz18rr","name":"Your Postgresql Database Credentials"}},"typeVersion":2.5},{"id":"760bc9bc-0057-4088-b3f0-3ee37b3519df","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-300,-240],"parameters":{"color":5,"width":560,"height":120,"content":"### 👨‍🎤 Setup\n1. Add your **postgresql** and **OpenAI** credentials.\n2. Click **Chat** button and start asking questions to your database.\n3. Activate the workflow and you can make the chat publicly available."},"typeVersion":1},{"id":"0df33341-c859-4a54-b6d9-a99670e8d76d","name":"Chat History","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[120,160],"parameters":{},"typeVersion":1.3},{"id":"4938b22e-f187-4ca0-b9f1-60835e823799","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[360,300],"parameters":{"color":7,"width":562,"height":156,"content":"🛠️ Tools Used:\n1. Execute SQL Query: Used to execute any query generated by the agent.\n2. Get DB Schema and Tables List: It returns the list of all the tables with its schema name.\n3. Get Table Definition: It returns table details like column names, foreign keys and more of a particular table in a schema."},"typeVersion":1},{"id":"39780c78-4fbc-403e-a220-aa6a4b06df8c","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-100,300],"parameters":{"color":7,"width":162,"height":99,"content":"👆 You can exchange this with any other chat model of your choice."},"typeVersion":1},{"id":"28a5692c-5003-46cb-9a09-b7867734f446","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[100,300],"parameters":{"color":7,"width":162,"height":159,"content":"👆 You can change how many number of messages to keep using `Context Window Length` option. It's 5 by default."},"typeVersion":1},{"id":"c18ced71-6330-4ba0-9c52-1bb5852b3039","name":"Execute SQL Query","type":"n8n-nodes-base.postgresTool","position":[380,140],"parameters":{"query":"{{ $fromAI(\"sql_query\", \"SQL Query\") }}","options":{},"operation":"executeQuery","descriptionType":"manual","toolDescription":"Get all the data from Postgres, make sure you append the tables with correct schema. Every table is associated with some schema in the database."},"credentials":{"postgres":{"id":"nGI61D0TEEZz18rr","name":"Your Postgresql Database Credentials"}},"typeVersion":2.5},{"id":"557623c6-e499-48a6-a066-744f64f8b6f3","name":"Get DB Schema and Tables List","type":"n8n-nodes-base.postgresTool","position":[580,140],"parameters":{"query":"SELECT \n    table_schema,\n    table_name\nFROM information_schema.tables\nWHERE table_type = 'BASE TABLE'\n    AND table_schema NOT IN ('pg_catalog', 'information_schema')\nORDER BY table_schema, table_name;","options":{},"operation":"executeQuery","descriptionType":"manual","toolDescription":"Get list of all tables with their schema in the database"},"credentials":{"postgres":{"id":"nGI61D0TEEZz18rr","name":"Your Postgresql Database Credentials"}},"typeVersion":2.5}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"10c7c74e-b383-4ac7-8cb2-c9a15a2818fe","connections":{"Chat History":{"ai_memory":[[{"node":"AI Agent","type":"ai_memory","index":0}]]},"Execute SQL Query":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Get Table Definition":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"When chat message received":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Get DB Schema and Tables List":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]}}}


name: AI-Powered Social Media Content Generator & Publisher
author_name: Amjid Ali
author_username: amjid
categories: []
created_at: 2025-02-20T12:47:09.520Z
updated_at: 2025-02-20T12:47:09.520Z
url: https://n8n.io/workflows/2950
scraped_at: 2025-06-19 22:07:56
description:
  AI-Powered Social Media Content Generator & Publisher 🚀  

  This AI-driven n8n workflow automates social media content creation and publishing across LinkedIn, Instagram, Facebook, and Twitter (X). It generates engaging, platform-optimized posts using Google Gemini AI, based on user inputs such as a post title, keywords, and an uploaded image. The workflow ensures seamless content generation and publishing, making it a perfect tool for marketers, business owners, influencers, and content creators.  

  🌟 Features & Benefits  

  ✅ AI-Generated Social Media Posts – Uses Google Gemini AI to create high-quality, optimized content.  
  ✅ Multi-Platform Support – Automatically generates posts for LinkedIn, Instagram, Facebook, and Twitter (X).  
  ✅ Hashtag & SEO Optimization – Includes trending hashtags to enhance visibility and engagement.  
  ✅ Image Upload & Processing – Allows image uploads for Instagram and Facebook using imgbb and Facebook Graph API.  
  ✅ Automated Publishing – Posts are automatically published on all selected platforms.  
  ✅ Custom Call-to-Action – Each platform's post is optimized with CTAs for better engagement.  
  ✅ User-Friendly Form Submission – Easy-to-use form where users can enter post titles, keywords, links, and images.  
  ✅ Performance Tracking – Provides confirmation and tracking links for published posts.  

  📌 How It Works  

  1️⃣ User Submission Form  
     Fill out the form with Post Title, Keywords, and an Optional Link.  
     Upload an image for Instagram & Facebook posts.  

  2️⃣ AI Content Generation  
     Google Gemini AI generates optimized content for each platform.  
     The AI ensures professional, engaging, and audience-specific content.  

  3️⃣ Content Review  
     Users review and approve the AI-generated content before publishing.  

  4️⃣ Automated Publishing  
     Posts are automatically published on LinkedIn, Facebook, Instagram, and Twitter (X).  
     Uses Facebook Graph API, LinkedIn API, Twitter API, and Instagram API.  

  5️⃣ Post Confirmation & Tracking  
     Get links to track published posts on each platform.  

  🛠️ Prerequisites  

  Before using this workflow, ensure you have:  

  ✅ n8n Instance (Cloud or Self-Hosted)  
  ✅ Social Media API Credentials (Facebook, Instagram, LinkedIn, Twitter API)  
  ✅ Google Gemini AI API Key  
  ✅ imgbb API Key (for image hosting)  

  Get N8n
  My Affiliate Link
  Buy My Book:  
  Mastering n8n on Amazon

  Full Courses & Tutorials:  
  http://lms.syncbricks.com

  📺 YouTube Video Tutorial 🎥  

  Watch the step-by-step tutorial on how to set up and use this n8n workflow template:  

  🔗 YouTube Tutorial - AI-Powered Social Media Posting in n8n  

  🎯 Use Cases  

  📌 Marketing Agencies – Automate client content scheduling.  
  📌 Businesses & Brands – Maintain a consistent brand presence on social media.  
  📌 Content Creators & Influencers – Generate high-quality posts quickly.  
  📌 E-commerce & Startups – Promote products and services effortlessly.  
  📌 Corporate & Enterprise Teams – Streamline internal and external communications.  

  Important
  Start with n8n  

  Learn n8n with Amjid   
  Get n8n Book 

  👨‍💻 Creator Information  

  👤 Developed by: Amjid Ali  
  🌐 Website: SyncBricks  
  📧 Email: info@syncbricks.com  
  💼 LinkedIn: Amjid Ali  
  📺 YouTube: SyncBricks  

  💡 Support & Contributions  

  If you find this workflow helpful, consider supporting my work:  

  👉 Donate via PayPal  

  For full courses on * AI Automation*, visit:  

  📚 SyncBricks LMS  

  📚 AI and Auotmation Course 

  👉  Get Started with N8N  

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

workflow_json:
  {"id":"LzDLmNc63zyqQBXz","meta":{"instanceId":"942ff96108ceedc60ba777eabc4e8ea2ae87415579996cd64d20cc647c4d3523"},"name":"Social Media Tutorial","tags":[],"nodes":[{"id":"8034d082-f50e-4f6b-8a79-ce7f86012d72","name":"On form submission","type":"n8n-nodes-base.formTrigger","position":[920,20],"webhookId":"syncbricks-social-posting-ai-agent","parameters":{},"typeVersion":2.2},{"id":"e38a74d5-a733-4f5c-a97b-2c761b46919b","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[1180,520],"parameters":{},"typeVersion":1.7},{"id":"ca0a8aef-0251-45ed-bc9b-05ee977febf9","name":"Google Gemini Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[980,780],"parameters":{},"typeVersion":1},{"id":"31e88059-94ca-4d4e-a673-e0f8cd1ac96e","name":"Structured Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[1300,780],"parameters":{},"typeVersion":1.2},{"id":"ffda1c79-faa4-4cc8-8655-6f7fc14b7e2d","name":"Split Form Input","type":"n8n-nodes-base.set","position":[1320,40],"parameters":{},"typeVersion":3.2},{"id":"37e443e1-6925-44a1-a07e-9eb1120e55a9","name":"Upload Image","type":"n8n-nodes-base.form","position":[320,1160],"webhookId":"0dc811ef-b2e0-4213-a0c9-e9b5fb9fcbf1","parameters":{},"typeVersion":1},{"id":"265068ce-22fc-4c41-9ed2-93eadc0ce25f","name":"Split Data","type":"n8n-nodes-base.set","position":[1560,40],"parameters":{},"typeVersion":3.2},{"id":"b8470879-413e-4901-bf39-23a19beaee5f","name":"Data for AI","type":"n8n-nodes-base.set","position":[1880,40],"parameters":{},"typeVersion":3.4},{"id":"eef02dcb-7c7f-4d6c-a1fd-039c8b30f10d","name":"Aggregate","type":"n8n-nodes-base.aggregate","position":[1680,760],"parameters":{},"typeVersion":1},{"id":"097e7724-4dc0-4cc9-b12c-2dbdae4e024f","name":"Form","type":"n8n-nodes-base.form","position":[1820,1960],"webhookId":"e84b9492-038c-4701-a367-c68237ddebf6","parameters":{},"typeVersion":1},{"id":"7b1d64fc-02ad-4b8f-ad1e-be8894abd932","name":"Nest Top Meta","type":"n8n-nodes-base.set","position":[940,1160],"parameters":{},"typeVersion":3.3},{"id":"11ddcfe8-1978-4f5a-8c29-67e72920431a","name":"Rename Image Binary Top Image","type":"n8n-nodes-base.code","position":[-40,1960],"parameters":{},"typeVersion":2},{"id":"19892590-5ddf-47ac-b544-7a72a68bd45e","name":"Publish to Facebook","type":"n8n-nodes-base.facebookGraphApi","position":[440,2080],"parameters":{},"typeVersion":1},{"id":"b3b0068b-c75a-427c-bb2d-77b21bc6ff16","name":"Publish to LinkedIn","type":"n8n-nodes-base.linkedIn","position":[420,1840],"parameters":{},"typeVersion":1},{"id":"ed5fe0c2-a07a-45f1-90cb-65f21d416a1a","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[860,-80],"parameters":{"content":""},"typeVersion":1},{"id":"c4a2e59d-165a-49cc-8074-9868ee4e0d6c","name":"X","type":"n8n-nodes-base.twitter","position":[440,1600],"parameters":{},"typeVersion":2},{"id":"66ba98a9-24c0-4128-9ad9-792a0d400aae","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[860,340],"parameters":{"content":""},"typeVersion":1},{"id":"02fafdc7-0272-4f34-9b66-dfbe8e16e70d","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-240,960],"parameters":{"content":""},"typeVersion":1},{"id":"21d945c3-446c-4bb9-8696-a70034801485","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-240,1480],"parameters":{"content":""},"typeVersion":1},{"id":"c9efdc38-94c6-494e-a932-45b75312bb54","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[1620,1480],"parameters":{"content":""},"typeVersion":1},{"id":"93632f4f-9182-4b76-bbe0-e6d5dd230452","name":"Edit Fields","type":"n8n-nodes-base.set","position":[800,1600],"parameters":{},"typeVersion":3.4},{"id":"89f22cf8-9499-4b7f-872d-97099c5d1e50","name":"Image for Instagram","type":"n8n-nodes-base.httpRequest","position":[740,2280],"parameters":{},"typeVersion":4.2},{"id":"c415eeb9-f916-4c08-afb1-baed3f3280cc","name":"Publish to Instagram","type":"n8n-nodes-base.facebookGraphApi","position":[1060,2280],"parameters":{},"typeVersion":1},{"id":"1c8f6ba6-c28b-45a8-ba0d-3f2f21ccbfa0","name":"Merge1","type":"n8n-nodes-base.merge","position":[1380,1940],"parameters":{},"typeVersion":3},{"id":"d9cfdcd1-18db-4d0d-9b6a-66897600e496","name":"Upload Image to imgbb.com","type":"n8n-nodes-base.httpRequest","position":[440,2280],"parameters":{},"typeVersion":4.2},{"id":"f7e5b1b1-aeaa-4851-be04-53e8255fa343","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[-240,-80],"parameters":{"content":""},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"4a55bf93-ae0c-4aa9-84a8-cd4d02375e51","connections":{"X":{"main":[[{"node":"Edit Fields","type":"main","index":0}]]},"Merge1":{"main":[[{"node":"Form","type":"main","index":0}]]},"AI Agent":{"main":[[{"node":"Aggregate","type":"main","index":0}]]},"Aggregate":{"main":[[{"node":"Upload Image","type":"main","index":0}]]},"Split Data":{"main":[[{"node":"Data for AI","type":"main","index":0}]]},"Data for AI":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Edit Fields":{"main":[[{"node":"Merge1","type":"main","index":0}]]},"Upload Image":{"main":[[{"node":"Nest Top Meta","type":"main","index":0}]]},"Nest Top Meta":{"main":[[{"node":"Rename Image Binary Top Image","type":"main","index":0}]]},"Split Form Input":{"main":[[{"node":"Split Data","type":"main","index":0}]]},"On form submission":{"main":[[{"node":"Split Form Input","type":"main","index":0}]]},"Image for Instagram":{"main":[[{"node":"Publish to Instagram","type":"main","index":0}]]},"Publish to Facebook":{"main":[[{"node":"Merge1","type":"main","index":2}]]},"Publish to LinkedIn":{"main":[[{"node":"Merge1","type":"main","index":1}]]},"Publish to Instagram":{"main":[[{"node":"Merge1","type":"main","index":3}]]},"Google Gemini Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Structured Output Parser":{"ai_outputParser":[[{"node":"AI Agent","type":"ai_outputParser","index":0}]]},"Upload Image to imgbb.com":{"main":[[{"node":"Image for Instagram","type":"main","index":0}]]},"Rename Image Binary Top Image":{"main":[[{"node":"X","type":"main","index":0},{"node":"Publish to LinkedIn","type":"main","index":0},{"node":"Publish to Facebook","type":"main","index":0},{"node":"Upload Image to imgbb.com","type":"main","index":0}]]}}}


name: 🤖 AI Powered RAG Chatbot for Your Docs + Google Drive + Gemini + Qdrant
author_name: Joseph LePage
author_username: joe
categories: []
created_at: 2025-02-23T01:59:29.690Z
updated_at: 2025-02-23T01:59:29.690Z
url: https://n8n.io/workflows/2982
scraped_at: 2025-06-19 22:07:56
description:
  🤖 AI-Powered RAG Chatbot with Google Drive Integration

  This workflow creates a powerful RAG (Retrieval-Augmented Generation) chatbot that can process, store, and interact with documents from Google Drive using Qdrant vector storage and Google's Gemini AI.

  How It Works

  Document Processing & Storage 📚
  Retrieves documents from a specified Google Drive folder
  Processes and splits documents into manageable chunks
  Extracts metadata using AI for enhanced search capabilities
  Stores document vectors in Qdrant for efficient retrieval

  Intelligent Chat Interface 💬
  Provides a conversational interface powered by Google Gemini
  Uses RAG to retrieve relevant context from stored documents
  Maintains chat history in Google Docs for reference
  Delivers accurate, context-aware responses

  Vector Store Management 🗄️
  Features secure delete operations with human verification
  Includes Telegram notifications for important operations
  Maintains data integrity with proper version control
  Supports batch processing of documents

  Setup Steps

  Configure API Credentials:
     Set up Google Drive & Docs access
     Configure Gemini AI API
     Set up Qdrant vector store connection
     Add Telegram bot for notifications
     Add OpenAI Api Key to the 'Delete Qdrant Points by File ID' node

  Configure Document Sources:
     Set Google Drive folder ID
     Define Qdrant collection name
     Set up document processing parameters

  Test and Deploy:
     Verify document processing
     Test chat functionality
     Confirm vector store operations
     Check notification system


  This workflow is ideal for organizations needing to create intelligent chatbots that can access and understand large document repositories while maintaining context and providing accurate responses through RAG technology.

nodes_used:
  ["n8n-nodes-base.telegram","n8n-nodes-base.googleDrive","n8n-nodes-base.googleDocs","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.code","@n8n/n8n-nodes-langchain.embeddingsOpenAi","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.memoryBufferWindow","@n8n/n8n-nodes-langchain.textSplitterTokenSplitter","@n8n/n8n-nodes-langchain.documentDefaultDataLoader","@n8n/n8n-nodes-langchain.vectorStoreQdrant","@n8n/n8n-nodes-langchain.lmChatGoogleGemini","@n8n/n8n-nodes-langchain.informationExtractor"]

workflow_json:
  {"id":"8tusZTTtcyaiznEG","meta":{"instanceId":"31e69f7f4a77bf465b805824e303232f0227212ae922d12133a0f96ffeab4fef","templateCredsSetupCompleted":true},"name":"🤖 AI Powered RAG Chatbot for Your Docs + Google Drive + Gemini + Qdrant","tags":[],"nodes":[{"id":"7ad5796b-d1a0-4cc1-bed6-105ff499beeb","name":"Data Loader","type":"@n8n/n8n-nodes-langchain.documentDefaultDataLoader","position":[620,720],"parameters":{"options":{"metadata":{"metadataValues":[{"name":"file_id","value":"={{ $json.id }}"},{"name":"pubkey","value":"={{ $json.name }}"},{"name":"=overarching_theme","value":"={{ $('Extract Meta Data').item.json.output.overarching_theme }}"},{"name":"recurring_topics","value":"={{ $('Extract Meta Data').item.json.output.recurring_topics }}"},{"name":"pain_points","value":"={{ $('Extract Meta Data').item.json.output.pain_points }}"},{"name":"analytical_insights","value":"={{ $('Extract Meta Data').item.json.output.analytical_insights }}"},{"name":"conclusion","value":"={{ $('Extract Meta Data').item.json.output.conclusion }}"},{"name":"keywords","value":"={{ $('Extract Meta Data').item.json.output.keywords }}"}]}},"dataType":"binary","binaryMode":"specificField"},"typeVersion":1},{"id":"84986ee2-4d79-49e8-8778-b8a955cf2174","name":"Token Splitter","type":"@n8n/n8n-nodes-langchain.textSplitterTokenSplitter","position":[720,860],"parameters":{"chunkSize":3000},"typeVersion":1},{"id":"82aa7016-f3af-4de8-a410-b1c802041213","name":"Qdrant Vector Store","type":"@n8n/n8n-nodes-langchain.vectorStoreQdrant","onError":"continueRegularOutput","position":[540,520],"parameters":{"mode":"insert","options":{},"qdrantCollection":{"__rl":true,"mode":"id","value":"=nostr-damus-user-profiles"}},"credentials":{"qdrantApi":{"id":"DJQ4hVAVdWZytjr2","name":"QdrantApi account"}},"executeOnce":false,"retryOnFail":true,"typeVersion":1},{"id":"07f4d14a-1864-406b-946b-09c776e3038b","name":"Loop Over Items","type":"n8n-nodes-base.splitInBatches","onError":"continueRegularOutput","position":[180,-140],"parameters":{"options":{}},"typeVersion":3},{"id":"b0f9b066-62de-41bc-afce-dcb4d20d100c","name":"Wait","type":"n8n-nodes-base.wait","position":[1020,840],"webhookId":"237d7f8a-aead-479a-b813-f407d1f37fa5","parameters":{},"typeVersion":1.1},{"id":"2a883003-f5ec-409e-97e4-809360ca11ed","name":"When clicking ‘Test workflow’","type":"n8n-nodes-base.manualTrigger","position":[-1160,-280],"parameters":{},"typeVersion":1},{"id":"cfbb6b77-142f-4689-b051-436f40ababe6","name":"Google Gemini Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[1120,-20],"parameters":{"options":{"temperature":0.4},"modelName":"models/gemini-2.0-flash-exp"},"credentials":{"googlePalmApi":{"id":"L9UNQHflYlyF9Ngd","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"c9c50387-64a3-473f-9ea7-509a301836a3","name":"Merge","type":"n8n-nodes-base.merge","position":[820,200],"parameters":{"mode":"combine","options":{},"combineBy":"combineAll"},"typeVersion":3},{"id":"ea143b9f-9bd8-4f3f-8979-5a0fd2691e9d","name":"Extract Meta Data","type":"@n8n/n8n-nodes-langchain.informationExtractor","position":[1020,-180],"parameters":{"text":"={{ $json.data }}","options":{"systemPromptTemplate":"You are an expert extraction algorithm.\nOnly extract relevant information from the text.\nIf you do not know the value of an attribute asked to extract, you may omit the attribute's value."},"attributes":{"attributes":[{"name":"overarching_theme","description":"Summarize the main theme(s) discussed in the \"Overarching Theme\" section."},{"name":"recurring_topics","description":"List the recurring topics mentioned in the \"Common Threads\" section as an array of strings."},{"name":"pain_points","description":"Summarize the user's frustrations or challenges mentioned in the \"Pain Points\" section as an array of strings."},{"name":"analytical_insights","description":"Extract a list of key analytical observations from the \"Analytical Insights\" section, including shifts in tone or behavior."},{"name":"conclusion","description":"Summarize the conclusions drawn about the user’s threads and their overall focus."},{"name":"keywords","description":"Generate a list of 10 keywords that capture the essence of the document (e.g., \"askNostr,\" \"decentralization,\" \"spam filtering\")."}]}},"typeVersion":1},{"id":"2ddd778f-6676-4a4b-b592-536401831bc8","name":"Get File Contents","type":"n8n-nodes-base.extractFromFile","position":[820,-180],"parameters":{"options":{},"operation":"text"},"typeVersion":1},{"id":"cdbb8bbc-967c-4f01-b844-4d31328153df","name":"Download File From Google Drive","type":"n8n-nodes-base.googleDrive","position":[500,-180],"parameters":{"fileId":{"__rl":true,"mode":"id","value":"={{ $json.id }}"},"options":{},"operation":"download"},"credentials":{"googleDriveOAuth2Api":{"id":"UhdXGYLTAJbsa0xX","name":"Google Drive account"}},"typeVersion":3},{"id":"399e196c-76ec-4077-aacc-f669173b0229","name":"Find File Ids in Google Drive Folder","type":"n8n-nodes-base.googleDrive","position":[-620,-160],"parameters":{"filter":{"driveId":{"mode":"list","value":"My Drive"},"folderId":{"__rl":true,"mode":"id","value":"={{ $json.folder_id }}"}},"options":{},"resource":"fileFolder","returnAll":true},"credentials":{"googleDriveOAuth2Api":{"id":"UhdXGYLTAJbsa0xX","name":"Google Drive account"}},"typeVersion":3},{"id":"3bc4f005-c6c8-4f73-816a-1573d6dfb62f","name":"text-embeddings-3-large","type":"@n8n/n8n-nodes-langchain.embeddingsOpenAi","position":[480,720],"parameters":{"model":"text-embedding-3-large","options":{}},"credentials":{"openAiApi":{"id":"jEMSvKmtYfzAkhe6","name":"OpenAi account"}},"typeVersion":1},{"id":"5d42b34a-7156-4163-a2c4-a9cb3c984c96","name":"Google Folder ID","type":"n8n-nodes-base.set","position":[-820,-160],"parameters":{"options":{},"assignments":{"assignments":[{"id":"e6f6188f-c895-4c8c-b39a-0ef55b490fd6","name":"folder_id","type":"string","value":"[Your-Google-Folder-ID]"}]}},"typeVersion":3.4},{"id":"7be310c2-d30f-42a2-8f57-33c7b184e429","name":"gpt-4o-mini1","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-400,940],"parameters":{"options":{}},"credentials":{"openAiApi":{"id":"jEMSvKmtYfzAkhe6","name":"OpenAi account"}},"typeVersion":1},{"id":"18aacfd9-3f6e-4fba-9f68-d8cc95bc667b","name":"Delete Qdrant Points by File ID","type":"@n8n/n8n-nodes-langchain.code","position":[-500,800],"parameters":{"code":{"execute":{"code":"const { QdrantVectorStore } = require(\"@langchain/qdrant\");\nconst { OpenAIEmbeddings } = require(\"@langchain/openai\");\n\n// Qdrant connection details\nconst url = \"http://localhost:6333/\";\nconst apiKey = \"\";\n\n// OpenAI API configuration\nconst openAIApiKey = \"[Your-OpenAI-API-Key]\";\n\n// Get input data\nconst items = this.getInputData()[0];\n// console.log(items)\n\nconst collectionName =  items.json.qdrant_collection_name;\n// console.log(collectionName)\n\nasync function deleteDocumentsFromQdrant() {\n  try {\n    // Initialize OpenAI embeddings\n    const embeddings = new OpenAIEmbeddings({\n      model: \"text-embedding-3-large\",\n      openAIApiKey: openAIApiKey\n    });\n\n    // Connect to existing Qdrant collection\n    const vectorStore = await QdrantVectorStore.fromExistingCollection(embeddings, {\n      url: url,\n      apiKey: apiKey,\n      collectionName: collectionName,\n    });\n\n    const fileIds = items.json.appended_id.map(item => item);\n\n    console.log(fileIds)\n\n    // Delete points by fileId\n    const deletionResults = await Promise.all(fileIds.map(async (file_id) => {\n      const filter = {\n        must: [\n          {\n            key: \"metadata.file_id\",\n            match: { value: file_id }\n          }\n        ]\n      };\n\n      try {\n        // Access the underlying Qdrant client to perform the deletion\n        await vectorStore.client.delete(collectionName, { filter });\n        return { file_id, status: \"deleted\" };\n      } catch (error) {\n        console.error(`Error deleting documents for fileId ${file_id}:`, error);\n        return { file_id, status: \"error\", message: error.message };\n      }\n    }));\n\n    return deletionResults;\n  } catch (error) {\n    console.error(\"An error occurred during the deletion process:\", error);\n    return error.message;\n  }\n}\n\n// Execute the deletion process\ntry {\n  const result = await deleteDocumentsFromQdrant();\n  console.log(\"Deletion process completed:\", result);\n  return [];\n} catch (error) {\n  console.error(\"Failed to execute deletion process:\", error);\n  return [{ json: { error } }];\n}\n\n"}},"inputs":{"input":[{"type":"main","required":true,"maxConnections":1},{"type":"ai_languageModel","required":true,"maxConnections":1}]},"outputs":{"output":[{"type":"main"}]}},"typeVersion":1},{"id":"329cec97-aac1-4714-97ce-add5915b1078","name":"Qdrant Collection Name","type":"n8n-nodes-base.set","position":[-700,100],"parameters":{"options":{},"assignments":{"assignments":[{"id":"11fa71e9-6cbc-4183-9439-e3379b2b970e","name":"qdrant_collection_name","type":"string","value":"nostr-damus-user-profiles"}]}},"typeVersion":3.4},{"id":"82e98da8-530d-4a3c-97e6-5e91ad644a46","name":"File Id List","type":"n8n-nodes-base.summarize","position":[-700,280],"parameters":{"options":{},"fieldsToSummarize":{"values":[{"field":"id","aggregation":"append"}]}},"typeVersion":1.1},{"id":"f3def614-2709-4847-831d-d6a80c86ec1c","name":"Merge1","type":"n8n-nodes-base.merge","position":[-340,340],"parameters":{"mode":"combine","options":{},"combineBy":"combineByPosition"},"typeVersion":3},{"id":"cfe399fb-8560-4ac4-98f7-4f539ae6a52c","name":"Merge2","type":"n8n-nodes-base.merge","position":[-80,-140],"parameters":{},"typeVersion":3},{"id":"1059da47-2abd-4884-b9c2-6b7d1623e31d","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1280,560],"parameters":{"color":3,"width":1180,"height":760,"content":"## Prepare Qdrant Vector Store"},"typeVersion":1},{"id":"2616e08f-070e-45b5-906f-40e832519aa2","name":"Confirm Qdrant Delete Points","type":"n8n-nodes-base.telegram","position":[-1060,760],"webhookId":"29aac1ac-9345-4e44-babf-ebcfae701d88","parameters":{"chatId":"={{ $env.TELEGRAM_CHAT_ID }}","message":"=WARNING - {{ $json.appended_id.length }} Records in the Qdrant vector store collection \"{{ $json.qdrant_collection_name }}\" will be deleted.  Are you sure you want to continue?  This action cannot be undone!","options":{"limitWaitTime":{"values":{"resumeUnit":"minutes","resumeAmount":15}}},"operation":"sendAndWait","approvalOptions":{"values":{"approvalType":"double"}}},"credentials":{"telegramApi":{"id":"pAIFhguJlkO3c7aQ","name":"Telegram account"}},"typeVersion":1.2},{"id":"9d167192-e87b-41be-87f2-d7ddf866bb8d","name":"If","type":"n8n-nodes-base.if","position":[-1060,1000],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"20f530d6-fd55-420d-b8a9-70e5303f688e","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.data.approved }}","rightValue":""}]}},"typeVersion":2.2},{"id":"1178f8cf-ece0-4b11-942d-18dd025da366","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[320,420],"parameters":{"color":7,"width":920,"height":640,"content":"## Perform Qdrant Vector Store Operations"},"typeVersion":1},{"id":"cbf17a08-2f4c-4605-8418-5bf93ade7cf4","name":"Send Declined Message","type":"n8n-nodes-base.telegram","position":[-740,1120],"webhookId":"382a3b43-b83f-47b1-a276-67c6b98a441a","parameters":{"text":"Qdrant vector store upsert declined","chatId":"={{ $env.TELEGRAM_CHAT_ID }}","additionalFields":{"appendAttribution":false}},"credentials":{"telegramApi":{"id":"pAIFhguJlkO3c7aQ","name":"Telegram account"}},"typeVersion":1.2},{"id":"890f478a-e000-418d-8582-4fef946e44d8","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-900,-380],"parameters":{"width":480,"height":840,"content":"## 🌟Workflow Config\n\n- Google Drive Folder Id\n- Qdrant Collection Name\n- List of Google Drive File Id's"},"typeVersion":1},{"id":"d2bc2fed-c134-4e54-bd9d-69996be966a3","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[740,-280],"parameters":{"color":6,"width":640,"height":420,"content":"## Extract Metadata for Qdrant Hybrid Search"},"typeVersion":1},{"id":"61f3c21e-bc2a-47bc-8ab1-678b1f425ee3","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[400,-280],"parameters":{"color":2,"width":300,"height":320,"content":"## Google Drive"},"typeVersion":1},{"id":"61e608e4-ac6a-4131-9ca8-c46a5134bff9","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[80,-360],"parameters":{"color":5,"width":1360,"height":1480,"content":"## ✨ Save Documents to Qdrant Vector Store"},"typeVersion":1},{"id":"410681cb-e757-42c0-89de-902edbe998e3","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-580,680],"parameters":{"color":5,"width":420,"height":400,"content":"## Delete From Qdrant Vector Store\nThis operation can not be undone!!!"},"typeVersion":1},{"id":"238469ce-3710-4681-b1b2-200c1b699d5e","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[-1200,640],"parameters":{"color":4,"width":380,"height":520,"content":"## Human In The Loop\nUser must verify deletion of points from Qdrant vector store"},"typeVersion":1},{"id":"0b2f6ff4-dd02-4f0e-b2eb-60b1ce736cf5","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[-1280,-380],"parameters":{"color":4,"width":340,"height":460,"content":"## 👍Start Here!"},"typeVersion":1},{"id":"abde545b-1a23-4b3e-8046-335b9d0fa445","name":"Webhook","type":"n8n-nodes-base.webhook","disabled":true,"position":[-1160,-100],"webhookId":"3a30557f-9264-4bc8-a253-a9356677c791","parameters":{"path":"upsert","options":{}},"typeVersion":2},{"id":"897d29af-719d-4fe7-93a9-44c693cc6547","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[-600,-1200],"parameters":{"text":"={{ $json.chatInput }}","options":{"systemMessage":"=You are an intelligent assistant specialized in answering user questions using Nostr user profiles. Your primary goal is to provide precise, contextually relevant, and concise answers based on the tools and resources available.\n\n### TOOL\nUse the \"nostr_damus_user_profiles\" tool to:\n- perform semantic similarity searches and retrieve information from Nostr user profiles relevant to the user's query.\n- access detailed information about Nostr and/or Damus users when additional context or specifics are required.\n\n### Key Instructions\n1. **Response Guidelines**:\n   - Clearly explain how the retrieved information addresses the user's query, if applicable.\n   - If no relevant information is found, respond with: \"I cannot find the answer in the available resources.\"\n\n2. **Focus and Relevance**:\n   - Ensure all responses are directly aligned with the user's question.\n   - Avoid including extraneous details or relying solely on internal knowledge.\n"},"promptType":"define"},"typeVersion":1.7},{"id":"316b0d8d-bbc7-4c40-b6d0-d0c762554fca","name":"Window Buffer Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[-580,-1000],"parameters":{"contextWindowLength":40},"typeVersion":1.3},{"id":"f1e342a8-d50e-48a8-9d7a-850f8be93cff","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[-1160,-1200],"webhookId":"5f1c0c82-0ff9-40c7-9e2e-b1a96ffe24cd","parameters":{"options":{}},"typeVersion":1.1},{"id":"12902fa9-5bcb-4e8b-ac13-7f4cb6e7e1d0","name":"Google Gemini Chat Model1","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","position":[-760,-1000],"parameters":{"options":{"maxOutputTokens":8192},"modelName":"models/gemini-2.0-flash-exp"},"credentials":{"googlePalmApi":{"id":"L9UNQHflYlyF9Ngd","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"1c5818d4-6251-4d14-8b4f-d1f3ddfbed38","name":"text-embeddings-3-large1","type":"@n8n/n8n-nodes-langchain.embeddingsOpenAi","position":[-320,-840],"parameters":{"model":"text-embedding-3-large","options":{}},"credentials":{"openAiApi":{"id":"jEMSvKmtYfzAkhe6","name":"OpenAi account"}},"typeVersion":1},{"id":"80056067-5d2b-4ac7-8e69-e75bd66a1ad4","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-900,-1300],"parameters":{"color":5,"width":860,"height":680,"content":"## 🤖Retrieve Content from Qdrant Vector Store"},"typeVersion":1},{"id":"b45b18e4-7773-4eec-837b-f43fc0eeb90c","name":"Sticky Note10","type":"n8n-nodes-base.stickyNote","position":[-1280,-1300],"parameters":{"color":4,"width":340,"height":320,"content":"## 🗣️ Chat with Your Documents"},"typeVersion":1},{"id":"8fe891dd-dee6-4abb-bc09-d90e6d7bf3cb","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[-1360,-480],"parameters":{"color":7,"width":2880,"height":1880,"content":"# Step 1 - Save Documents to Qdrant Vector Store"},"typeVersion":1},{"id":"4a9bf716-3fc3-4ccc-b831-19a1afdb4588","name":"Sticky Note12","type":"n8n-nodes-base.stickyNote","position":[-1360,-1420],"parameters":{"color":7,"width":1780,"height":880,"content":"# Step 2 - Chat with Your Documents from Qdrant Vector Store"},"typeVersion":1},{"id":"fccedfde-c5aa-4237-9d1c-feb9ebabf4f3","name":"Google Drive","type":"n8n-nodes-base.googleDrive","disabled":true,"position":[120,-780],"parameters":{"name":"=Nostr Chatbot - Avatar - {{ $now }}","content":"={{ $json.output }}","driveId":{"__rl":true,"mode":"list","value":"My Drive"},"options":{},"folderId":{"__rl":true,"mode":"list","value":"root","cachedResultName":"/ (Root folder)"},"operation":"createFromText"},"credentials":{"googleDriveOAuth2Api":{"id":"UhdXGYLTAJbsa0xX","name":"Google Drive account"}},"typeVersion":3},{"id":"6d6813f6-4f2e-499a-9e5c-fe15624a91ef","name":"Respond to User","type":"n8n-nodes-base.set","position":[120,-960],"parameters":{"options":{},"assignments":{"assignments":[{"id":"cd8f88e1-19c0-4b9e-914d-e2e7ba21d9fa","name":"output","type":"string","value":"={{ $json.output }}"}]}},"typeVersion":3.4},{"id":"1c73bae9-2bdd-4383-a6f8-3cf43d3c15be","name":"Sticky Note13","type":"n8n-nodes-base.stickyNote","position":[0,-1300],"parameters":{"color":4,"width":340,"height":300,"content":"## Save Chat History"},"typeVersion":1},{"id":"db3dcc69-d1d0-48a1-b949-37f2de802b4a","name":"Update Chat History","type":"n8n-nodes-base.googleDocs","position":[120,-1200],"parameters":{"actionsUi":{"actionFields":[{"text":"=\n-------------------------------\n\n{{ $now }}\n\n{{ $('When chat message received').item.json.chatInput  }}\n\n{{ $json.output }}","action":"insert"}]},"operation":"update","documentURL":"1ej_qLolUFp1h4eZkrb99T3DWQ3JOwXVEMS3VUjWyVf0"},"credentials":{"googleDocsOAuth2Api":{"id":"YWEHuG28zOt532MQ","name":"Google Docs account"}},"typeVersion":2},{"id":"2dd28eed-b71b-44fb-bb78-8cb50b0d0c93","name":"Qdrant Vector Store Tool","type":"@n8n/n8n-nodes-langchain.vectorStoreQdrant","position":[-420,-1000],"parameters":{"mode":"retrieve-as-tool","topK":20,"options":{},"toolName":"nostr_damus_user_profiles","toolDescription":"Retrieve information about Nostr or Damus users","qdrantCollection":{"__rl":true,"mode":"list","value":"nostr-damus-user-profiles","cachedResultName":"nostr-damus-user-profiles"}},"credentials":{"qdrantApi":{"id":"DJQ4hVAVdWZytjr2","name":"QdrantApi account"}},"typeVersion":1},{"id":"3b130cf8-ab8e-4001-a3d0-a129194aee98","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","disabled":true,"position":[-760,-820],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"jEMSvKmtYfzAkhe6","name":"OpenAi account"}},"typeVersion":1.2},{"id":"ccc64645-ad14-4b6b-a507-0b5fb0ac945f","name":"Send Completed Message","type":"n8n-nodes-base.telegram","position":[500,200],"webhookId":"382a3b43-b83f-47b1-a276-67c6b98a441a","parameters":{"text":"Qdrant vector store upsert completed","chatId":"={{ $env.TELEGRAM_CHAT_ID }}","additionalFields":{"appendAttribution":false}},"credentials":{"telegramApi":{"id":"pAIFhguJlkO3c7aQ","name":"Telegram account"}},"typeVersion":1.2},{"id":"885fef53-2246-45b1-a122-ab5b82374585","name":"Sticky Note14","type":"n8n-nodes-base.stickyNote","position":[-2120,-480],"parameters":{"width":700,"height":1240,"content":"# 🤖 AI-Powered RAG Chatbot with Google Drive Integration\n\nThis workflow creates a powerful RAG (Retrieval-Augmented Generation) chatbot that can process, store, and interact with documents from Google Drive using Qdrant vector storage and Google's Gemini AI.\n\n## How It Works\n\n### Document Processing & Storage 📚\n- Retrieves documents from a specified Google Drive folder\n- Processes and splits documents into manageable chunks\n- Extracts metadata using AI for enhanced search capabilities\n- Stores document vectors in Qdrant for efficient retrieval\n\n### Intelligent Chat Interface 💬\n- Provides a conversational interface powered by Google Gemini\n- Uses RAG to retrieve relevant context from stored documents\n- Maintains chat history in Google Docs for reference\n- Delivers accurate, context-aware responses\n\n### Vector Store Management 🗄️\n- Features secure delete operations with human verification\n- Includes Telegram notifications for important operations\n- Maintains data integrity with proper version control\n- Supports batch processing of documents\n\n## Setup Steps\n\n1. Configure API Credentials:\n   - Set up Google Drive & Docs access\n   - Configure Gemini AI API\n   - Set up Qdrant vector store connection\n   - Add Telegram bot for notifications\n\n2. Configure Document Sources:\n   - Set Google Drive folder ID\n   - Define Qdrant collection name\n   - Set up document processing parameters\n\n3. Test and Deploy:\n   - Verify document processing\n   - Test chat functionality\n   - Confirm vector store operations\n   - Check notification system\n\n\nThis workflow is ideal for organizations needing to create intelligent chatbots that can access and understand large document repositories while maintaining context and providing accurate responses through RAG technology.\n"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"timezone":"America/Vancouver","callerPolicy":"workflowsFromSameOwner","executionOrder":"v1"},"versionId":"0c0d90e5-02f9-4169-b477-fd90c52ce44e","connections":{"If":{"main":[[{"node":"Delete Qdrant Points by File ID","type":"main","index":0}],[{"node":"Send Declined Message","type":"main","index":0}]]},"Wait":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Merge":{"main":[[{"node":"Qdrant Vector Store","type":"main","index":0}]]},"Merge1":{"main":[[{"node":"Confirm Qdrant Delete Points","type":"main","index":0}]]},"Merge2":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Webhook":{"main":[[{"node":"Google Folder ID","type":"main","index":0}]]},"AI Agent":{"main":[[{"node":"Update Chat History","type":"main","index":0},{"node":"Respond to User","type":"main","index":0}]]},"Data Loader":{"ai_document":[[{"node":"Qdrant Vector Store","type":"ai_document","index":0}]]},"File Id List":{"main":[[{"node":"Merge1","type":"main","index":1}]]},"gpt-4o-mini1":{"ai_languageModel":[[{"node":"Delete Qdrant Points by File ID","type":"ai_languageModel","index":0}]]},"Token Splitter":{"ai_textSplitter":[[{"node":"Data Loader","type":"ai_textSplitter","index":0}]]},"Loop Over Items":{"main":[[{"node":"Send Completed Message","type":"main","index":0}],[{"node":"Download File From Google Drive","type":"main","index":0}]]},"Respond to User":{"main":[[]]},"Google Folder ID":{"main":[[{"node":"Find File Ids in Google Drive Folder","type":"main","index":0}]]},"Extract Meta Data":{"main":[[{"node":"Merge","type":"main","index":0}]]},"Get File Contents":{"main":[[{"node":"Extract Meta Data","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[]]},"Qdrant Vector Store":{"main":[[{"node":"Wait","type":"main","index":0}]]},"Update Chat History":{"main":[[]]},"Window Buffer Memory":{"ai_memory":[[{"node":"AI Agent","type":"ai_memory","index":0}]]},"Qdrant Collection Name":{"main":[[{"node":"Merge1","type":"main","index":0}]]},"text-embeddings-3-large":{"ai_embedding":[[{"node":"Qdrant Vector Store","type":"ai_embedding","index":0}]]},"Google Gemini Chat Model":{"ai_languageModel":[[{"node":"Extract Meta Data","type":"ai_languageModel","index":0}]]},"Qdrant Vector Store Tool":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]],"ai_vectorStore":[[]]},"text-embeddings-3-large1":{"ai_embedding":[[{"node":"Qdrant Vector Store Tool","type":"ai_embedding","index":0}]]},"Google Gemini Chat Model1":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"When chat message received":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Confirm Qdrant Delete Points":{"main":[[{"node":"If","type":"main","index":0}]]},"Delete Qdrant Points by File ID":{"main":[[{"node":"Merge2","type":"main","index":1}]]},"Download File From Google Drive":{"main":[[{"node":"Get File Contents","type":"main","index":0},{"node":"Merge","type":"main","index":1}]]},"When clicking ‘Test workflow’":{"main":[[{"node":"Google Folder ID","type":"main","index":0}]]},"Find File Ids in Google Drive Folder":{"main":[[{"node":"File Id List","type":"main","index":0},{"node":"Qdrant Collection Name","type":"main","index":0},{"node":"Merge2","type":"main","index":0}]]}}}


name: Build Your First AI Data Analyst Chatbot
author_name: Solomon
author_username: solomon
categories: []
created_at: 2025-03-01T12:08:21.886Z
updated_at: 2025-03-01T12:08:21.886Z
url: https://n8n.io/workflows/3050
scraped_at: 2025-06-19 22:07:56
description:
  Enhance your data analysis by connecting an AI Agent to your dataset, using n8n tools.

  This template teaches you how to build an AI Data Analyst Chatbot that is capable of pulling data from your sources, using tools like Google Sheets or databases. It's designed to be easy and efficient, making it a good starting point for AI-driven data analysis.

  You can easily replace the current Google Sheets tools for databases like Postgres or MySQL.

  How It Works
  The core of the workflow is the AI Agent. It's connected to different data retrieval tools, to get data from Google Sheets (or your preferred database) in many different ways.

  Once the data is retrieved, the Calculator tool allows the AI to perform mathematical operations, making your data analysis precise.

  Who is this template for
  Data Analysts & Researchers:** Pull data from different sources and perform quick calculations.
  Developers & AI Enthusiasts:** Learn to build your first AI Agent with easy dataset access.
  Business Owners:** Streamline your data analysis with AI insights and automate repetitive tasks.
  Automation Experts:** Enhance your automation skills by integrating AI with your existing databases.

  How to Set Up
  You can find detailed instructions in the workflow itself.

  Check out my other templates
  👉 https://n8n.io/creators/solomon/

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

workflow_json:
  {"meta":{"instanceId":"d6b502dfa4d9dd072cdc5c2bb763558661053f651289291352a84403e01b3d1b","templateCredsSetupCompleted":true},"nodes":[{"id":"0951fd33-1811-4a89-b84f-f46dc9e6fde1","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[20,-340],"webhookId":"cdc03fce-33b6-4eed-86b5-f628994e5e31","parameters":{"options":{}},"typeVersion":1.1},{"id":"699c2f89-5547-4d28-92a9-5e216aecb251","name":"AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[240,-340],"parameters":{"options":{"maxIterations":15,"systemMessage":"=You are a helpful assistant.\nCurrent timestamp is {{ $now }}"}},"typeVersion":1.7},{"id":"640c29f7-b67e-49f6-a864-c9b396c446b7","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[160,-100],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o","cachedResultName":"gpt-4o"},"options":{"temperature":0.2}},"credentials":{"openAiApi":{"id":"5LVOlVwHUgB8MAj2","name":"OpenAI - n8n project"}},"typeVersion":1.2},{"id":"807630b4-c138-4b66-a438-fb70eab12a07","name":"Calculator","type":"@n8n/n8n-nodes-langchain.toolCalculator","position":[840,60],"parameters":{},"typeVersion":1},{"id":"132a97a3-239c-403f-843f-55b652e3efc5","name":"Code","type":"n8n-nodes-base.code","position":[840,640],"parameters":{"jsCode":"// Ensure there's at least one input item.\nif (!items || items.length === 0) {\n  throw new Error(\"No input items found.\");\n}\n\n// Our input is expected to have a 'data' property containing the JSONP string.\nconst input = items[0].json;\n\nif (!input.data) {\n  throw new Error(\"Input JSON does not have a 'data' property.\");\n}\n\nconst rawData = input.data;\n\n// Use a regex to extract the JSON content from the Google Visualization JSONP response.\nconst regex = /google\\.visualization\\.Query\\.setResponse\\((.*)\\);?$/s;\nconst match = rawData.match(regex);\n\nif (!match) {\n  throw new Error(\"Input data does not match the expected Google Visualization JSONP format.\");\n}\n\nconst jsonString = match[1];\n\n// Parse the extracted JSON string.\nlet parsed;\ntry {\n  parsed = JSON.parse(jsonString);\n} catch (error) {\n  throw new Error(\"Failed to parse JSON: \" + error.message);\n}\n\n// Verify that the parsed JSON has the expected 'table' structure with 'cols' and 'rows'.\nif (!parsed.table || !Array.isArray(parsed.table.cols) || !Array.isArray(parsed.table.rows)) {\n  throw new Error(\"Parsed JSON does not have the expected 'table' structure with 'cols' and 'rows'.\");\n}\n\nconst cols = parsed.table.cols;\nconst rows = parsed.table.rows;\n\n// Helper function to convert date string from \"Date(YYYY,M,D)\" to \"YYYY-MM-DD\"\nfunction formatDate(dateStr) {\n  const match = dateStr.match(/^Date\\((\\d+),(\\d+),(\\d+)\\)$/);\n  if (!match) return dateStr;\n  const year = parseInt(match[1], 10);\n  const month = parseInt(match[2], 10) + 1; // JavaScript months are 0-indexed\n  const day = parseInt(match[3], 10);\n  // Format with leading zeros\n  return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;\n}\n\n// Map each row into an object using the column labels as keys.\nconst newItems = rows.map(row => {\n  const obj = {};\n  cols.forEach((col, index) => {\n    let value = row.c && row.c[index] ? row.c[index].v : null;\n    // If the column type is \"date\" and the value is a string that looks like \"Date(YYYY,M,D)\"\n    if (col.type === \"date\" && typeof value === \"string\") {\n      value = formatDate(value);\n    }\n    obj[col.label] = value;\n  });\n  return { json: obj };\n});\n\n// Return the new array of items.\nreturn newItems;\n"},"typeVersion":2},{"id":"3dc1e670-bfb1-4b63-b9c8-85656134c843","name":"When Executed by Another Workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[280,640],"parameters":{"workflowInputs":{"values":[{"name":"start_date"},{"name":"end_date"},{"name":"status"}]}},"typeVersion":1.1},{"id":"52a26e43-12a5-4b4a-a224-d70cdabf6aaf","name":"Records by date","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[1020,-120],"parameters":{"name":"records_by_date_and_or_status","workflowId":{"__rl":true,"mode":"list","value":"a2BIIjr2gLBay06M","cachedResultName":"Template | Your first AI Data Analyst"},"description":"Use this tool to get records filtered by date. You can also filter by status at the same time, if you want.","workflowInputs":{"value":{"status":"={{ $fromAI(\"status\", \"Status of the transaction. Can be Completed, Refund or Error. Leave empty if you don't need this now.\", \"string\") }}","end_date":"={{ $fromAI(\"end_date\", \"End date in format YYYY-MM-DD\", \"string\") }}","start_date":"={{ $fromAI(\"start_date\", \"Start date in format YYYY-MM-DD\", \"string\") }}"},"schema":[{"id":"start_date","type":"string","display":true,"required":false,"displayName":"start_date","defaultMatch":false,"canBeUsedToMatch":true},{"id":"end_date","type":"string","display":true,"required":false,"displayName":"end_date","defaultMatch":false,"canBeUsedToMatch":true},{"id":"status","type":"string","display":true,"removed":false,"required":false,"displayName":"status","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false}},"typeVersion":2},{"id":"e1811519-8699-4243-8c64-0db1ab26004d","name":"Aggregate","type":"n8n-nodes-base.aggregate","position":[1280,640],"parameters":{"options":{},"aggregate":"aggregateAllItemData"},"typeVersion":1},{"id":"3b129abd-ac9a-460c-abb3-007e2c94e284","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[1220,400],"parameters":{"color":7,"width":220,"height":400,"content":"To send all the items back to the AI, we need to finish with everything aggregated into one single item.\n\nOtherwise it will respond with one item at a time, and the AI will only get the first item that arrives."},"typeVersion":1},{"id":"645ac0f9-8022-4f2c-8c6c-5aadd6cf09cc","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[460,400],"parameters":{"color":7,"width":300,"height":400,"content":"This node sends a custom HTTP Request to the Google Sheets API.\n\nFiltering by date range in the Google Sheets API is very complicated.\n\nThis node solves that problem.\n\nBut doing the same in a database is much simpler. A tool could do it without needing a sub-workflow."},"typeVersion":1},{"id":"14221a72-914d-4c75-866a-d64ba7f8109f","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[780,400],"parameters":{"color":7,"width":220,"height":400,"content":"The output from this complex request is also messy.\n\nSo we use some code generated by ChatGPT to transform the data into JSON objects."},"typeVersion":1},{"id":"f12668ea-b59d-4caf-a997-381f78b7cfe7","name":"Google Sheets request","type":"n8n-nodes-base.httpRequest","position":[560,640],"parameters":{"url":"https://docs.google.com/spreadsheets/d/18A4d7KYrk8-uEMbu7shoQe_UIzmbTLV1FMN43bjA7qc/gviz/tq","options":{},"sendQuery":true,"authentication":"predefinedCredentialType","queryParameters":{"parameters":[{"name":"sheet","value":"Sheet1"},{"name":"tq","value":"=SELECT * WHERE A >= DATE \"{{ $json.start_date }}\" AND A <= DATE \"{{ $json.end_date }}\""}]},"nodeCredentialType":"googleSheetsOAuth2Api"},"credentials":{"googleSheetsOAuth2Api":{"id":"YR4pbjuZM5Xs4CTD","name":"Google Sheets"}},"typeVersion":4.2},{"id":"f59a2606-0981-43d1-9a07-b802891b9220","name":"Get transactions by product name","type":"n8n-nodes-base.googleSheetsTool","position":[1020,-320],"parameters":{"options":{},"filtersUI":{"values":[{"lookupValue":"={{ $fromAI(\"product_name\", \"The product name\", \"string\") }}","lookupColumn":"Product"}]},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/18A4d7KYrk8-uEMbu7shoQe_UIzmbTLV1FMN43bjA7qc/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"url","value":"https://docs.google.com/spreadsheets/d/18A4d7KYrk8-uEMbu7shoQe_UIzmbTLV1FMN43bjA7qc/edit?usp=sharing"},"descriptionType":"manual","toolDescription":"Find transactions by product.\nOur products are:\n- Widget A\n- Widget B\n- Widget C\n- Widget D"},"credentials":{"googleSheetsOAuth2Api":{"id":"YR4pbjuZM5Xs4CTD","name":"Google Sheets"}},"typeVersion":4.5},{"id":"1ed7168c-1639-4b3b-a3b4-ed162bcef880","name":"Get all transactions","type":"n8n-nodes-base.googleSheetsTool","position":[840,-120],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/18A4d7KYrk8-uEMbu7shoQe_UIzmbTLV1FMN43bjA7qc/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"url","value":"https://docs.google.com/spreadsheets/d/18A4d7KYrk8-uEMbu7shoQe_UIzmbTLV1FMN43bjA7qc/edit?usp=sharing"},"descriptionType":"manual","toolDescription":"Only use this as last resort, because it will pull all data at once."},"credentials":{"googleSheetsOAuth2Api":{"id":"YR4pbjuZM5Xs4CTD","name":"Google Sheets"}},"typeVersion":4.5},{"id":"798453da-8a65-4d14-ae0a-778d64ab02ad","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-360,-340],"parameters":{"color":4,"width":320,"height":340,"content":"## Some questions to try\nThere's a red button on this page that you can click to chat with the AI.\n\nTry asking it these questions:\n\n- How many refunds in January and what was the amount refunded?\n\n- How many successful sales did we have in January 2025 and what was the final income of those?\n\n- What is the most frequent reason for refunds?"},"typeVersion":1},{"id":"b8336f1a-3855-4247-9589-2f9aa35d211f","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-780,-340],"parameters":{"color":4,"width":400,"content":"## Copy this Sheets file to your Google Drive\nhttps://docs.google.com/spreadsheets/d/18A4d7KYrk8-uEMbu7shoQe_UIzmbTLV1FMN43bjA7qc/edit?gid=0#gid=0"},"typeVersion":1},{"id":"99a55b39-965b-4454-b416-d3991f0bdfbc","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[940,60],"parameters":{"color":7,"width":200,"height":140,"content":"### 👈\nThe Calculator is a tool that allows an agent to run mathematical calculations."},"typeVersion":1},{"id":"7ebebf56-e065-41c4-8270-f636785b0def","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-780,-160],"parameters":{"color":4,"width":400,"content":"### How to connect to Google Sheets?\nTo connect your n8n to your Google Sheets you're gonna need Google OAuth credentials\n\nSee documentation **[here](https://docs.n8n.io/integrations/builtin/credentials/google/oauth-single-service/)**"},"typeVersion":1},{"id":"b64df0dd-6425-4fc2-9f60-8c5a85412d61","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[120,20],"parameters":{"color":7,"width":170,"height":260,"content":"## 👆\nYou can use many models here, including the free Google Gemini options.\n\nMake sure to test it thoroughly. Some models are better for data analysis."},"typeVersion":1},{"id":"23c7bb52-b189-45f1-949b-ea588f065583","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[340,20],"parameters":{"color":7,"width":150,"height":260,"content":"## 👆\nThis is a short term memory. It will remember the 5 previous interactions during the chat"},"typeVersion":1},{"id":"6097e5a1-139b-4329-81ff-4fda16ea5221","name":"Buffer Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[360,-100],"parameters":{},"typeVersion":1.3},{"id":"6de4a7f2-5c58-4401-bd7c-19c5a73ba775","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[1160,-320],"parameters":{"color":7,"width":340,"height":180,"content":"The **AI Tools Agent** has access to all the tools at the same time. It uses the name and description to decide when to use each tool.\n\nNotice I'm using `$fromAI` function in all of them.\n\nSee documentations **[here](https://docs.n8n.io/advanced-ai/examples/using-the-fromai-function/)**"},"typeVersion":1},{"id":"a308d895-bc18-4b2c-9567-78f6c29f79e8","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[1160,-120],"parameters":{"color":7,"width":340,"height":320,"content":"## 👈 This is a special tool\nIt is used to call another workflow.\nThis concept is called sub-workflow.\n\nSee documentation [here](https://docs.n8n.io/flow-logic/subworkflows/).\n\nInstead of running a completely separate workflow, we are calling the one below.\n\nIt's contained in the same workflow, but we are using the trigger to define it will run only when called by this tool."},"typeVersion":1},{"id":"0a6d94bc-21e1-4949-b7f4-c93abbecf08c","name":"Sticky Note12","type":"n8n-nodes-base.stickyNote","position":[120,340],"parameters":{"color":7,"width":1380,"height":520,"content":"# Sub-workflow\nThe AI can call this sub-workflow anytime,\nby using the **Records by date** tool.\n\nThe sub-workflow automatically return\n the result of the last executed node to the AI."},"typeVersion":1},{"id":"3e424615-6e49-4bd3-b066-005b9f0f773e","name":"Filter by status","type":"n8n-nodes-base.filter","position":[1060,640],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"e50da873-bbbd-41d3-a418-83193907977c","operator":{"type":"string","operation":"contains"},"leftValue":"={{ $json.Status }}","rightValue":"={{ $('When Executed by Another Workflow').item.json.status }}"}]}},"typeVersion":2.2},{"id":"0ad0102c-adb9-4ec9-bdf3-b1ce425b88ba","name":"Get transactions by status","type":"n8n-nodes-base.googleSheetsTool","position":[840,-320],"parameters":{"options":{},"filtersUI":{"values":[{"lookupValue":"={{ $fromAI(\"transaction_status\", \"Transaction status can be Refund, Completed or Error\", \"string\") }}","lookupColumn":"Status"}]},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/18A4d7KYrk8-uEMbu7shoQe_UIzmbTLV1FMN43bjA7qc/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"url","value":"https://docs.google.com/spreadsheets/d/18A4d7KYrk8-uEMbu7shoQe_UIzmbTLV1FMN43bjA7qc/edit?usp=sharing"},"descriptionType":"manual","toolDescription":"Find transactions by status"},"credentials":{"googleSheetsOAuth2Api":{"id":"YR4pbjuZM5Xs4CTD","name":"Google Sheets"}},"typeVersion":4.5},{"id":"5b80cb08-6e19-47b2-8146-c299e709a34a","name":"Sticky Note13","type":"n8n-nodes-base.stickyNote","position":[820,-540],"parameters":{"color":4,"width":300,"content":"## Change the URL of the Sheets file in all the Sheets tools 👇"},"typeVersion":1},{"id":"ddc1351e-0ad0-480f-9742-30f2aa860d61","name":"Sticky Note14","type":"n8n-nodes-base.stickyNote","position":[500,820],"parameters":{"color":4,"width":260,"height":100,"content":"## 👆 Change the URL of the Sheets file"},"typeVersion":1},{"id":"ab837a10-932f-4b14-8e2c-546077ca2c86","name":"Sticky Note10","type":"n8n-nodes-base.stickyNote","position":[-780,20],"parameters":{"color":7,"width":740,"height":640,"content":"# Author\n![Solomon](https://gravatar.com/avatar/79aa147f090807fe0f618fb47a1de932669e385bb0c84bf3a7f891ae7d174256?r=pg&d=retro&size=200)\n### Solomon\nFreelance consultant from Brazil, specializing in automations and data analysis. I work with select clients, addressing their toughest projects.\n\nFor business inquiries, email me at automations.solomon@gmail.com\nOr message me on [Telegram](https://t.me/salomaoguilherme) for a faster response.\n\n### Check out my other templates\n### 👉 https://n8n.io/creators/solomon/\n"},"typeVersion":1},{"id":"e58351b3-3b18-4c03-9435-27ba853d03bb","name":"Sticky Note15","type":"n8n-nodes-base.stickyNote","position":[-780,680],"parameters":{"width":740,"height":180,"content":"# Need help?\nFor getting help with this workflow, please create a topic on the community forums here:\nhttps://community.n8n.io/c/questions/"},"typeVersion":1},{"id":"4519d880-7448-4fb3-b2dc-ccea787729be","name":"Sticky Note16","type":"n8n-nodes-base.stickyNote","position":[-760,560],"parameters":{"color":4,"width":700,"height":80,"content":"### 💡 **Want to learn advanced n8n skills and earn money building workflows?**\n‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎Check out [Scrapes Academy](https://www.skool.com/scrapes/about?ref=21f10ad99f4d46ba9b8aaea8c9f58c34)"},"typeVersion":1}],"pinData":{},"connections":{"Code":{"main":[[{"node":"Filter by status","type":"main","index":0}]]},"Calculator":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Buffer Memory":{"ai_memory":[[{"node":"AI Agent","type":"ai_memory","index":0}]]},"Records by date":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Filter by status":{"main":[[{"node":"Aggregate","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"AI Agent","type":"ai_languageModel","index":0}]]},"Get all transactions":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"Google Sheets request":{"main":[[{"node":"Code","type":"main","index":0}]]},"Get transactions by status":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"When chat message received":{"main":[[{"node":"AI Agent","type":"main","index":0}]]},"Get transactions by product name":{"ai_tool":[[{"node":"AI Agent","type":"ai_tool","index":0}]]},"When Executed by Another Workflow":{"main":[[{"node":"Google Sheets request","type":"main","index":0}]]}}}


name: ✨🤖Automate Multi-Platform Social Media Content Creation with AI
author_name: Joseph LePage
author_username: joe
categories: []
created_at: 2025-03-03T03:47:15.283Z
updated_at: 2025-03-03T03:47:15.283Z
url: https://n8n.io/workflows/3066
scraped_at: 2025-06-19 22:07:56
description:
  Automate Multi-Platform Social Media Content Creation with AI

  Who is this for?  
  Social Media Managers and Digital Marketers seeking to streamline content production across 7+ platforms (X/Twitter, Instagram, LinkedIn, Facebook, TikTok, Threads, YouTube Shorts) using AI-powered automation.

  What problem does this solve?  
  Creating platform-optimized content at scale while maintaining brand consistency across multiple channels, reducing manual work by 80% through AI generation and automated publishing.

  What this workflow does  
  AI Content Generation:  
     Uses GPT-4/Gemini to create platform-specific posts  
     Automatically generates hashtags, CTAs, and emoji placement  
     Supports image/video suggestions and image creation using OpenAI or Pollinations.ai
     Uses SERP api to search for relavent content

  Approval Workflow:  
     Sends formatted HTML emails for human review  
     Implements double-approval system with Gmail integration  

  Cross-Platform Publishing:  
     One-click deployment to:  
       Instagram/Facebook (via Graph API)  
       X/Twitter (Official API)  
       LinkedIn (Sales Navigator integration)  

  Setup  
  Credentials:  
     OpenAI API key  
     Google Gemini API  
     Social media platform tokens (X, LinkedIn, Facebook)  
     ImgBB for image hosting  
     Gmail
     SERP API
     Telegram

  Configuration:  
     Update all "your-unique-id" placeholders in API nodes  
     Set email recipients in Gmail nodes  
     Customize AI prompts 

  Customization:  
     Adjust character limits per platform  
     Modify approval thresholds  
     Add/remove social platforms as needed  

  How to customize  
  Content Style**: Edit prompt templates in the "Social Media Content Factory" agent node  
  Approval Process**: Modify email templates  
  Analytics**: Connect to Google Sheets for performance tracking  
  Image Generation**: Switch between Pollinations.ai/DALL-E/Midjourney  

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.telegram","n8n-nodes-base.facebookGraphApi","n8n-nodes-base.twitter","n8n-nodes-base.gmail","n8n-nodes-base.linkedIn","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.outputParserStructured","@n8n/n8n-nodes-langchain.toolSerpApi","@n8n/n8n-nodes-langchain.openAi","@n8n/n8n-nodes-langchain.lmChatGoogleGemini"]

workflow_json:
  {"id":"CfdF2XtXC68iJ6Hr","meta":{"instanceId":"31e69f7f4a77bf465b805824e303232f0227212ae922d12133a0f96ffeab4fef","templateCredsSetupCompleted":true},"name":"✨🤖Automated AI Powered Social Media Content Factory for  X + Facebook + Instagram + LinkedIn","tags":[],"nodes":[{"id":"1e77584f-76b4-420b-b6b0-99132d6c0151","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-300,-900],"parameters":{"color":4,"width":360,"height":360,"content":"# 🧑‍🦱 User Input for Social Media Posts \n💡 Unpin default data to get started"},"typeVersion":1},{"id":"dc92fcf1-3618-4188-a30f-6c2205cc3266","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[100,-940],"parameters":{"color":6,"width":640,"height":600,"content":"# 🛠️ Social Media Content Factory\n- LinkedIn\n- Instagram\n- Facebook\n- X\n- TikTok\n- Threads\n- YouTube Shorts\n"},"typeVersion":1},{"id":"02429ea7-be59-49e3-9d85-c1678ee64abd","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[1840,-700],"parameters":{"color":4,"width":400,"height":360,"content":"# 👍 Approve Content Before Proceeding"},"typeVersion":1},{"id":"fa38e25c-89e9-4d9b-be78-03aeb6965e30","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[1300,-900],"parameters":{"color":5,"width":500,"height":560,"content":"# ✉️ Prepare & Format Approval Email"},"typeVersion":1},{"id":"9b6e2038-9f65-4e0f-b13d-6c09e8224ed6","name":"Social Media Content","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[560,-540],"parameters":{"schemaType":"manual","inputSchema":"{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"name\": {\n\t\t\t\"type\": \"string\"\n\t\t},\n\t\t\"description\": {\n\t\t\t\"type\": \"string\"\n\t\t},\n\t\t\"platform_posts\": {\n\t\t\t\"type\": \"object\",\n\t\t\t\"properties\": {\n\t\t\t\t\"LinkedIn\": {\n\t\t\t\t\t\"type\": \"object\",\n\t\t\t\t\t\"properties\": {\n                        \"image_suggestion\": {\n                  \t\t\t\"type\": \"string\"\n                  \t\t},\n\t\t\t\t\t\t\"post\": {\n\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"hashtags\": {\n\t\t\t\t\t\t\t\"type\": \"array\",\n\t\t\t\t\t\t\t\"items\": {\n\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"call_to_action\": {\n\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"Instagram\": {\n\t\t\t\t\t\"type\": \"object\",\n\t\t\t\t\t\"properties\": {\n\t\t\t\t\t\t\"image_suggestion\": {\n\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"caption\": {\n\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"hashtags\": {\n\t\t\t\t\t\t\t\"type\": \"array\",\n\t\t\t\t\t\t\t\"items\": {\n\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"emojis\": {\n\t\t\t\t\t\t\t\"type\": \"array\",\n\t\t\t\t\t\t\t\"items\": {\n\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"call_to_action\": {\n\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"Facebook\": {\n\t\t\t\t\t\"type\": \"object\",\n\t\t\t\t\t\"properties\": {\n\t\t\t\t\t\t\"post\": {\n\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"hashtags\": {\n\t\t\t\t\t\t\t\"type\": \"array\",\n\t\t\t\t\t\t\t\"items\": {\n\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"call_to_action\": {\n\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"image_suggestion\": {\n\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"X-Twitter\": {\n\t\t\t\t\t\"type\": \"object\",\n\t\t\t\t\t\"properties\": {\n                        \"video_suggestion\": {\n                \t\t\t\"type\": \"string\"\n                \t\t},\n                        \"image_suggestion\": {\n\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"post\": {\n\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"hashtags\": {\n\t\t\t\t\t\t\t\"type\": \"array\",\n\t\t\t\t\t\t\t\"items\": {\n\t\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"character_limit\": {\n\t\t\t\t\t\t\t\"type\": \"integer\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n                \"TikTok\": {\n                \t\"type\": \"object\",\n                \t\"properties\": {\n                \t\t\"video_suggestion\": {\n                \t\t\t\"type\": \"string\"\n                \t\t},\n                \t\t\"caption\": {\n                \t\t\t\"type\": \"string\"\n                \t\t},\n                \t\t\"hashtags\": {\n                \t\t\t\"type\": \"array\",\n                \t\t\t\"items\": {\n                \t\t\t\t\"type\": \"string\"\n                \t\t\t}\n                \t\t},\n                \t\t\"call_to_action\": {\n                \t\t\t\"type\": \"string\"\n                \t\t}\n                \t}\n                },\n                \"Threads\": {\n                \t\"type\": \"object\",\n                \t\"properties\": {\n                       \"image_suggestion\": {\n\t\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t\t},\n                \t\t\"text_post\": {\n                \t\t\t\"type\": \"string\"\n                \t\t},\n                \t\t\"hashtags\": {\n                \t\t\t\"type\": \"array\",\n                \t\t\t\"items\": {\n                \t\t\t\t\"type\": \"string\"\n                \t\t\t}\n                \t\t},\n                \t\t\"call_to_action\": {\n                \t\t\t\"type\": \"string\"\n                \t\t}\n                \t}\n                },\n                \"YouTube_Shorts\": {\n                  \t\"type\": \"object\",\n                  \t\"properties\": {\n                  \t\t\"video_suggestion\": {\n                  \t\t\t\"type\": \"string\"\n                  \t\t},\n                  \t\t\"title\": {\n                  \t\t\t\"type\": \"string\"\n                  \t\t},\n                          \"description\": {\n                              \"type\": \"string\"\n                          },\n                          \"hashtags\": {\n                              \"type\": \"array\",\n                              \"items\": {\n                                  \"type\": \"string\"\n                              }\n                          },\n                          \"call_to_action\": {\n                              \"type\": \"string\"\n                          }\n                      }\n                  }\n\t\t\t}\n\t\t},\n\t\t\"additional_notes\": {\n\t\t\t\"type\": \"string\"\n\t\t}\n\t}\n}\n"},"typeVersion":1.2},{"id":"a1211873-05ca-48c7-aa93-57d80b37174b","name":"Google Gemini LLM","type":"@n8n/n8n-nodes-langchain.lmChatGoogleGemini","disabled":true,"position":[320,-540],"parameters":{"options":{"temperature":0.4},"modelName":"models/gemini-2.0-flash-exp"},"credentials":{"googlePalmApi":{"id":"L9UNQHflYlyF9Ngd","name":"Google Gemini(PaLM) Api account"}},"typeVersion":1},{"id":"14327277-1e66-401d-9c74-8fdb6d76445f","name":"gpt-4o-mini","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[1360,-540],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini","cachedResultName":"gpt-4o-mini"},"options":{"responseFormat":"text"}},"credentials":{"openAiApi":{"id":"jEMSvKmtYfzAkhe6","name":"OpenAi account"}},"typeVersion":1.2},{"id":"9a49454b-f518-4388-82a7-2529addae3e5","name":"gpt-4o","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","disabled":true,"position":[1500,-540],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o","cachedResultName":"gpt-4o"},"options":{"responseFormat":"text"}},"credentials":{"openAiApi":{"id":"jEMSvKmtYfzAkhe6","name":"OpenAi account"}},"typeVersion":1.2},{"id":"56eb9c72-87fc-42b2-b576-be68b3a8c7d2","name":"gpt-4o LLM","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[180,-540],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o","cachedResultName":"gpt-4o"},"options":{"responseFormat":"text"}},"credentials":{"openAiApi":{"id":"jEMSvKmtYfzAkhe6","name":"OpenAi account"}},"typeVersion":1.2},{"id":"bf4e6d41-b2be-44fc-8fc7-6dc6bc4ee69a","name":"pollinations.ai","type":"n8n-nodes-base.httpRequest","disabled":true,"position":[980,780],"parameters":{"url":"=https://image.pollinations.ai/prompt/{{$('Social Media Content Factory').item.json.output.description.replaceAll(' ','-').replaceAll(',','').replaceAll('.','') }}","options":{}},"typeVersion":4.2},{"id":"5a950645-8e74-4be8-bad2-73d9f827a6b8","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[880,620],"parameters":{"width":300,"height":340,"content":"## Create Post Image\nhttps://pollinations.ai/\nhttps://image.pollinations.ai/prompt/[your image description]\n\n(alternative)"},"typeVersion":1},{"id":"7b5b53eb-85c6-4a90-b209-7bd8d638f237","name":"Merge","type":"n8n-nodes-base.merge","position":[700,20],"parameters":{"mode":"combine","options":{"includeUnpaired":true},"combineBy":"combineByPosition"},"typeVersion":3},{"id":"daa6773e-0e15-4994-bcee-b3d996655855","name":"Save Image to imgbb.com3","type":"n8n-nodes-base.httpRequest","position":[360,-140],"parameters":{"url":"https://api.imgbb.com/1/upload","method":"POST","options":{"redirect":{"redirect":{}}},"sendBody":true,"sendQuery":true,"contentType":"multipart-form-data","bodyParameters":{"parameters":[{"name":"image","parameterType":"formBinaryData","inputDataFieldName":"data"}]},"queryParameters":{"parameters":[{"name":"expiration","value":"0"},{"name":"key","value":"={{ $env.IMGBB_API_KEY}} "}]}},"typeVersion":4.2},{"id":"af06853c-258e-4dfb-a579-3168c8de96bd","name":"Instagram Image","type":"n8n-nodes-base.httpRequest","onError":"continueRegularOutput","position":[1700,-60],"parameters":{"url":"https://graph.facebook.com/v20.0/[your-unique-id]/media","method":"POST","options":{},"sendQuery":true,"authentication":"predefinedCredentialType","queryParameters":{"parameters":[{"name":"image_url","value":"={{ $json.data.medium.url }}"},{"name":"caption","value":"={{ $('Social Media Content Factory').item.json.output.platform_posts.Instagram.caption }}"}]},"nodeCredentialType":"facebookGraphApi"},"credentials":{"facebookGraphApi":{"id":"PzDfmiwB7GPtmSaP","name":"Facebook Graph account"}},"typeVersion":4.2},{"id":"6ee72138-a8ec-4fbd-8f14-fd6e881edfd1","name":"Instragram Post","type":"n8n-nodes-base.facebookGraphApi","onError":"continueRegularOutput","position":[1700,160],"parameters":{"edge":"media_publish","node":"[your-unique-id]","options":{"queryParameters":{"parameter":[{"name":"creation_id","value":"={{ $json.id }}"},{"name":"caption","value":"={{ $('Social Media Content Factory').item.json.output.platform_posts.Instagram.caption }}"}]}},"graphApiVersion":"v20.0","httpRequestMethod":"POST"},"credentials":{"facebookGraphApi":{"id":"PzDfmiwB7GPtmSaP","name":"Facebook Graph account"}},"typeVersion":1,"alwaysOutputData":true},{"id":"9e168865-1eae-4e53-99c9-91b041426ecb","name":"X Post","type":"n8n-nodes-base.twitter","onError":"continueRegularOutput","position":[1700,380],"parameters":{"text":"={{ $('Social Media Content Factory').item.json.output.platform_posts['X-Twitter'].post }}","additionalFields":{}},"credentials":{"twitterOAuth2Api":{"id":"wRDruLTCqjQ7C5jq","name":"X account"}},"typeVersion":2,"alwaysOutputData":true},{"id":"4ee55c94-7251-445e-8ce7-15eee7165010","name":"Facebook Post","type":"n8n-nodes-base.facebookGraphApi","onError":"continueRegularOutput","position":[1700,600],"parameters":{"edge":"photos","node":"[your-unique-id]","options":{"queryParameters":{"parameter":[{"name":"message","value":"={{ $('Social Media Content Factory').item.json.output.platform_posts.Facebook.post }}\n\n{{ $('Social Media Content Factory').item.json.output.platform_posts.Facebook.call_to_action }}\n"},{"name":"link","value":"={{ $('Social Media Content Factory').item.json.output.platform_posts.Facebook.call_to_action }}"}]}},"sendBinaryData":true,"graphApiVersion":"v20.0","httpRequestMethod":"POST","binaryPropertyName":"data"},"credentials":{"facebookGraphApi":{"id":"PzDfmiwB7GPtmSaP","name":"Facebook Graph account"}},"typeVersion":1,"alwaysOutputData":true},{"id":"3a015f3f-a162-411a-85e8-e1f042d9c653","name":"LinkedIn Post","type":"n8n-nodes-base.linkedIn","onError":"continueRegularOutput","position":[1700,780],"parameters":{"text":"={{ $('Social Media Content Factory').item.json.output.platform_posts.LinkedIn.post }}\n{{ $('Social Media Content Factory').item.json.output.platform_posts.LinkedIn.call_to_action }}\n{{ $('Social Media Content Factory').item.json.output.platform_posts.LinkedIn.hashtags }}\n{{ $('Social Media Content Factory').item.json.output.platform_posts.LinkedIn.call_to_action }}","postAs":"organization","organization":"12345678","additionalFields":{},"binaryPropertyName":"=data","shareMediaCategory":"IMAGE"},"credentials":{"linkedInOAuth2Api":{"id":"WMm6pzAEgNd4wJdO","name":"LinkedIn account"}},"typeVersion":1,"alwaysOutputData":true},{"id":"8ab03d75-b4c5-4271-8fa9-830f449a3a3c","name":"OpenAI","type":"@n8n/n8n-nodes-langchain.openAi","position":[40,-20],"parameters":{"prompt":"={{ $('Social Media Content Factory').item.json.output.platform_posts.Instagram.caption }}","options":{},"resource":"image"},"credentials":{"openAiApi":{"id":"jEMSvKmtYfzAkhe6","name":"OpenAi account"}},"typeVersion":1.8,"alwaysOutputData":true},{"id":"d1ac29b1-128d-4615-b828-89f1f64d1b15","name":"Merge1","type":"n8n-nodes-base.merge","position":[1440,-60],"parameters":{"mode":"combine","options":{},"combineBy":"combineByPosition"},"typeVersion":3},{"id":"71eebce8-027a-4b12-b07e-692121de9a68","name":"Merge2","type":"n8n-nodes-base.merge","position":[1440,680],"parameters":{"mode":"combine","options":{"includeUnpaired":true},"combineBy":"combineByPosition"},"typeVersion":3},{"id":"140cff41-a619-4111-8dc9-3ec8fc45e061","name":"Aggregate","type":"n8n-nodes-base.aggregate","position":[-240,520],"parameters":{"options":{},"aggregate":"aggregateAllItemData"},"typeVersion":1},{"id":"3e96bfac-dad5-4b75-b51b-50329892ee70","name":"gpt-4o-mini1","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-20,540],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini","cachedResultName":"gpt-4o-mini"},"options":{"responseFormat":"text"}},"credentials":{"openAiApi":{"id":"jEMSvKmtYfzAkhe6","name":"OpenAi account"}},"typeVersion":1.2},{"id":"4d73d59f-bb8c-481b-877a-bf4dc64f3277","name":"gpt-4o-mini2","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-20,820],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini","cachedResultName":"gpt-4o-mini"},"options":{"responseFormat":"text"}},"credentials":{"openAiApi":{"id":"jEMSvKmtYfzAkhe6","name":"OpenAi account"}},"typeVersion":1.2},{"id":"aaef70d7-6029-4fae-afc1-72a6a0019b03","name":"Gmail User for Approval","type":"n8n-nodes-base.gmail","position":[2000,-540],"webhookId":"c46cf421-ddb6-45a8-b83b-80b381666f0e","parameters":{"sendTo":"={{ $env.EMAIL_ADDRESS_JOE }} ","message":"={{ $json.output }}","options":{"limitWaitTime":{"values":{"resumeUnit":"minutes","resumeAmount":45}}},"subject":"=🔥FOR APPROVAL🔥{{ $('Social Media Content Factory').item.json.output.name }} - {{ $('Social Media Content Factory').item.json.output.description }}","operation":"sendAndWait","approvalOptions":{"values":{"approvalType":"double"}}},"credentials":{"gmailOAuth2":{"id":"1xpVDEQ1yx8gV022","name":"Gmail account"}},"typeVersion":2.1},{"id":"44e3bada-7665-4268-bb79-12ffb377552e","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1600,-140],"parameters":{"color":6,"width":300,"height":1100,"content":"## Publish to Social Media"},"typeVersion":1},{"id":"75bfc1f4-0afa-4d8d-b5cc-83e29b6570f9","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[1940,80],"parameters":{"color":5,"width":300,"height":880,"content":"## Format Results"},"typeVersion":1},{"id":"ff5d050a-111c-4467-bc61-e51444943cb5","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[-360,240],"parameters":{"color":7,"width":1020,"height":760,"content":"# Step 4️⃣: Send Final Results of Social Media Factory"},"typeVersion":1},{"id":"26a684cc-72d9-40c8-bd30-1d074d914328","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[-40,-100],"parameters":{"color":3,"width":260,"height":260,"content":"## Create Post Image"},"typeVersion":1},{"id":"930e76ac-6e9c-4a3f-9229-28ba18de25a3","name":"Approve Final Post Content","type":"n8n-nodes-base.gmail","disabled":true,"position":[980,380],"webhookId":"c46cf421-ddb6-45a8-b83b-80b381666f0e","parameters":{"sendTo":"={{ $env.EMAIL_ADDRESS_JOE }} ","message":"=<html>\n<body style=\"margin:0; padding:0; font-family: Arial, sans-serif; background-color: #f5f5f5;\">\n  <div style=\"max-width: 600px; margin: 0 auto; padding: 20px;\">\n\n    <h2 style=\"font-size:20px; color:#333; margin:0 0 15px 0;\">LinkedIn</h2>\n      \n    <!-- LinkedIn Card -->\n    <div style=\"background: #ffffff; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.1);\">\n\n      <!-- Card Header Image -->\n      <div style=\"height: 200px; overflow: hidden; border-radius: 8px 8px 0 0;\">\n        <img src=\"{{ $json.data.medium.url }}\" alt=\"Featured Image\" style=\"width: 100%; height: 100%; object-fit: cover;\">\n      </div>\n\n      <!-- Card Content -->\n      <div style=\"padding: 25px;\">\n\n        <p style=\"font-size:16px; color:#555; line-height: 1.6; margin-bottom: 15px;\">\n          {{ $('Social Media Content Factory').item.json.output.platform_posts.LinkedIn.post }}\n        </p>\n        \n        <div style=\"margin: 15px 0;\">\n          <span style=\"display: inline-block; background: #f0f0f0; padding: 4px 8px; margin: 2px; border-radius: 4px; font-size:12px; color:#333;\">\n            {{ $('Social Media Content Factory').item.json.output.platform_posts.LinkedIn.hashtags }}\n          </span>\n        </div>\n\n        <p style=\"font-size:14px; color:#1a0dab; font-weight: 600; margin:15px 0 0 0;\">\n          {{ $('Social Media Content Factory').item.json.output.platform_posts.LinkedIn.call_to_action }}\n        </p>\n      </div>\n    </div>\n  </div>\n</body>\n</html>\n","options":{"limitWaitTime":{"values":{"resumeUnit":"minutes","resumeAmount":45}}},"subject":"=🔥FOR APPROVAL🔥 New LinkedIn Post","operation":"sendAndWait","approvalOptions":{"values":{"approvalType":"double"}}},"credentials":{"gmailOAuth2":{"id":"1xpVDEQ1yx8gV022","name":"Gmail account"}},"typeVersion":2.1},{"id":"051b7ff6-febb-4aba-9790-bc977c11e645","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[880,240],"parameters":{"width":300,"height":340,"content":"## Final Approval before Publishing to Social Feeds\n(optional)"},"typeVersion":1},{"id":"b42df164-47ae-4e08-9099-d0958dd41c8f","name":"Is Approved?","type":"n8n-nodes-base.if","position":[1160,20],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"efe337a1-63e0-4513-873d-421bf41e4868","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.data.approved }}","rightValue":""}]}},"typeVersion":2.2},{"id":"e3193aef-d115-4c3b-87b2-b8ebd5bb0c05","name":"Instagram Result","type":"n8n-nodes-base.set","position":[2040,160],"parameters":{"options":{},"assignments":{"assignments":[{"id":"5c6edc76-1e3b-45b0-8baa-33a14c678150","name":"Instagram Post Result","type":"string","value":"={{ $json }}"}]}},"typeVersion":3.4},{"id":"6f8b248f-5c79-412c-81ef-3c52bef7f257","name":"X Result","type":"n8n-nodes-base.set","position":[2040,380],"parameters":{"options":{},"assignments":{"assignments":[{"id":"5c6edc76-1e3b-45b0-8baa-33a14c678150","name":"X Post Result","type":"string","value":"={{ $json }}"}]}},"typeVersion":3.4},{"id":"4c1ee118-aba1-4632-bd48-27cef9d5e272","name":"Facebook Result","type":"n8n-nodes-base.set","position":[2040,600],"parameters":{"options":{},"assignments":{"assignments":[{"id":"5c6edc76-1e3b-45b0-8baa-33a14c678150","name":"Facebook Post Result","type":"string","value":"={{ $json }}"}]}},"typeVersion":3.4},{"id":"490223f9-9b6a-4617-8829-c8e4b130feb7","name":"LinkedIn Result","type":"n8n-nodes-base.set","position":[2040,780],"parameters":{"options":{},"assignments":{"assignments":[{"id":"5c6edc76-1e3b-45b0-8baa-33a14c678150","name":"LinkedIn Post Result","type":"string","value":"={{ $json }}"}]}},"typeVersion":3.4},{"id":"9732c12e-903e-49ac-8d29-ffc4d78c7ff8","name":"Submit Social Post Details","type":"n8n-nodes-base.formTrigger","position":[-180,-740],"webhookId":"3e762442-715e-47e1-a65e-ae92085857ae","parameters":{"options":{"buttonLabel":"Automatically Generate Social Media Content"},"formTitle":"workflows.diy","formFields":{"values":[{"fieldLabel":"Topic","placeholder":"Provide a concise and clear title or main topic for your post (e.g., \"New Product Launch,\" \"Exciting Company Update\"). This helps the AI accurately capture the focus of your content.","requiredField":true},{"fieldLabel":"Keywords or Hashtags (optional)","placeholder":"Include any specific keywords or hashtags you'd like the AI to incorporate into the post. This ensures the content aligns with your branding and campaign objectives.","requiredField":"={{ false }}"},{"fieldLabel":"Link (optional)","placeholder":"=Provide the URL of any product, service, form, support page, or other resource. This link will be included in the generated post to direct your audience to the relevant content.\n"}]},"responseMode":"lastNode","formDescription":"=Welcome to the workflows.diy AI-Powered Assistant!\n\nThis tool is designed to streamline and enhance your social media content creation process.\n\nSimply provide key inputs like a topic or title and an optional image, and our intelligent agent will generate engaging, platform-specific post descriptions tailored to your audience. \n\nWhether you're a marketer, business owner, or influencer, this assistant saves you time while delivering professional-quality content optimized for maximum impact.\n\n"},"typeVersion":2.2},{"id":"899f658f-4faa-4ba7-ae02-cc8fb1d22c71","name":"Sticky Note10","type":"n8n-nodes-base.stickyNote","position":[-360,-1060],"parameters":{"color":7,"width":2640,"height":760,"content":"# Step 1️⃣: Create Social Media Written Content\nNote:  \nYou could use the output of step 1 to create your written content and manually post if required.  \nYou so not have to implement step 2."},"typeVersion":1},{"id":"a8075b2a-4cd0-4b0c-9b19-8bd58de449c0","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[-360,-260],"parameters":{"color":7,"width":1020,"height":460,"content":"# Step 2️⃣: Create Image or Upload Image for Social Post"},"typeVersion":1},{"id":"1da28ef3-9061-4e83-84e0-3502d254d63a","name":"Sticky Note12","type":"n8n-nodes-base.stickyNote","position":[840,-260],"parameters":{"color":7,"width":1680,"height":1260,"content":"# Step 3️⃣: Publish Final Social Media Posts"},"typeVersion":1},{"id":"1955b762-b9c4-4704-955b-093686e827bd","name":"Merge Results","type":"n8n-nodes-base.merge","onError":"continueRegularOutput","position":[2340,780],"parameters":{"numberInputs":4},"typeVersion":3,"alwaysOutputData":true},{"id":"6dc47749-eb49-4351-89aa-50f2b6c035bb","name":"Social Media Content Factory","type":"@n8n/n8n-nodes-langchain.agent","position":[300,-740],"parameters":{"text":"=You are a **content creation AI** for workflows.diy, a leading creator of **n8n workflow automation solutions and AI Agentic workflows**.\n\nYour goal is to craft **engaging, platform-specific content** for LinkedIn, Instagram, Facebook, Twitter (X), TikTok, Threads, and YouTube Shorts. Each post must align with the platform’s audience preferences, tone, and style while reflecting workflows.diy's expertise. The content should provide **value-driven insights**, tutorials, reviews, and discussions that resonate with tech professionals, automation enthusiasts, businesses, and n8n users.\n\n### Key Objectives:\n1. **Platform Optimization**: Tailor content format, tone, and hashtags to suit each platform’s algorithm and audience engagement patterns.\n2. **SEO & Hashtags**: Use a mix of general automation hashtags and trending platform-specific hashtags to maximize reach.\n3. **Engagement Focus**: Create content that sparks interaction through tutorials, comparisons, reviews, or thought-provoking discussions.\n4. **Consistency**: Maintain a professional yet approachable tone across all platforms while adapting to audience needs.\n5. **Data-Driven Strategy**: Analyze trends and performance data to refine content strategy and hashtag usage.\n\n### General Hashtags:\n#workflowsdiy #n8n #automation #AIWorkflows #WorkflowAutomation #TechSolutions\n\n---\n\n### Platform-Specific Guidelines:\n\n#### 1. LinkedIn\n   - **Style**: Professional and insightful.\n   - **Tone**: Business-oriented; focus on automation use cases, industry insights, and community impact.\n   - **Content Length**: 3-4 sentences; concise but detailed.\n   - **Hashtags**: #Innovation #Automation #WorkflowSolutions #DigitalTransformation #Leadership\n   - **Call to Action (CTA)**: Encourage comments or visits to workflows.diy’s website for more insights.\n\n#### 2. Instagram\n   - **Style**: Visual storytelling with creative captions.\n   - **Tone**: Inspirational and engaging; use emojis for relatability.\n   - **Content Length**: 2-3 sentences paired with eye-catching visuals (e.g., infographics or workflow demos).\n   - **Visuals**: Showcase milestones (e.g., new workflow launches), tutorials, or product highlights.\n   - **CTA**: Use phrases like \"Swipe to learn more,\" \"Tag your team,\" or \"Check out the link below!\"\n   - **Link Placement**: Add the provided link before hashtags; if no link is provided, use \"Visit our website: https://workflows.diy.\"\n   - **Hashtags**: #AutomationLife #TechInnovation #WorkflowTips #Programming #Engineering\n\n#### 3. Facebook\n   - **Style**: Friendly and community-focused.\n   - **Tone**: Relatable; highlight user success stories or company achievements in automation.\n   - **Content Length**: 2-3 sentences; conversational yet professional.\n   - **Hashtags**: #SmallBusinessAutomation #Entrepreneurship #Leadership #WorkflowInnovation\n   - **CTA**: Encourage likes, shares, comments (e.g., “What’s your favorite automation tip?”).\n\n#### 4. Twitter (X)\n   - **Style**: Concise and impactful.\n   - **Tone**: Crisp and engaging; spark curiosity in 150 characters or less.\n   - **Hashtags**: #WorkflowTrends #AIWorkflows #AutomationTips #NoCodeSolutions\n   - **CTA**: Drive quick engagement through retweets or replies (e.g., “What’s your go-to n8n workflow?”).\n\n#### 5. TikTok\n   - **Style**: Short-form video content with trending audio or effects.\n   - **Tone**: Fun yet informative; focus on quick workflow demos or automation tips.\n   - **Content Length**: 15-60 seconds with captions summarizing the key message.\n   - **Hashtags**: Use trending tech-related hashtags relevant to TikTok’s audience (e.g., #n8nTips).\n   - **CTA**: Encourage viewers to follow workflows.diy for more automation hacks.\n\n#### 6. Threads\n   - **Style**: Conversational and community-driven posts.\n   - **Tone**: Casual yet informative; encourage discussions around automation trends or innovations.\n   - **Content Length**: 1-2 short paragraphs with a question or thought-provoking statement at the end.\n   - **Hashtags**: Similar to Instagram but tailored for trending Threads topics related to automation.\n\n#### 7. YouTube Shorts\n   - **Style**: Short-form video content showcasing quick workflow tutorials or use cases.\n   - **Tone**: Authoritative yet approachable; establish workflows.diy as a leader in n8n automation solutions.\n   - Content Length:\n     - Tutorials/Reviews (long-form): 5-10 minutes\n     - Shorts/Highlights (short-form): Under 1 minute\n   - CTA:** Encourage subscriptions**, likes, comments (e.g., “Subscribe for more workflow tips!”).\n\n---\n\n### Content Creation Workflow:\nFor every post:\n1. Use the following input fields:\n    - Topic/About the Post: {{ $json.Topic }}\n    - Keywords/Focus Areas: {{ $json.formMode }}\n    - Link (optional): {{ $json['Link (optional)'] }}\n2. Adapt the tone/style based on the platform guidelines above.\n\nEnsure every post reflects workflows.diy's mission of delivering high-quality automation insights while maximizing engagement across platforms.\n\nFollow the provided JSON schema for your reponse.\n","options":{"systemMessage":"=Use the provided tools to research the topic based on latest information.  Todays date is {{ $now }}"},"promptType":"define","hasOutputParser":true},"retryOnFail":true,"typeVersion":1.7},{"id":"88c548bf-40e5-4b89-aef0-9233c3f5bc9c","name":"Prepare Content Review Email","type":"@n8n/n8n-nodes-langchain.agent","position":[1440,-740],"parameters":{"text":"=Generate clean, modern HTML email content from the provided JSON data with these requirements:\n- Use table-based layout with inline CSS for email compatibility\n- Create card sections for each platform containing:\n  • Title header (20px) \n  • Post content (16px) \n  • Video/image suggestions (italic 14px)\n  • Hashtag list (inline-block with # prefix)\n  • Emoji preservation where present\n  • Call-to-action (bold 14px)\n- Structure using:\n  • 600px max-width container\n  • 20px padding between cards\n  • Left-aligned text hierarchy\n  • Arial/sans-serif font stack\n  • Email-safe colors (#333 text, #555 secondary)\n- Include all platform-specific elements:\n  ▶ Video/image suggestions in italic\n  ▶ Hashtags as linked search terms\n  ▶ Emojis in original positions\n  ▶ Character limits for Twitter\n  ▶ Platform-specific CTAs\n  ▶ Visual quality reminders\n- Format hashtags as:\n  <span style=\"display: inline-block; background: #f0f0f0; padding: 2px 6px; margin: 2px; border-radius: 4px;\">#tag</span>\n\nInput data: {{ $json.output.toJsonString() }}\n\nRemove ALL code blocks and comments. Output ONLY the raw HTML with:\n- Platform cards in JSON order\n- All data elements represented\n- Mobile-responsive tables\n- W3C-valid markup\n\n## Example HTML:\n<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background-color:#fbfcfe;border:1px solid #dbdfe7;border-radius:8px\">\n\t\t<tbody><tr>\n\t\t\t<td align=\"center\" style=\"padding:24px 0\">\n\t\t\t\t<table width=\"448\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"width:100%;max-width:448px;background-color:#ffffff;border:1px solid #dbdfe7;border-radius:8px;padding:24px\">\n\t\t\t\t\t<tbody><tr>\n\t\t\t\t\t\t<td style=\"text-align:center;padding-top:8px;font-family:Arial,sans-serif;font-size:14px;color:#7e8186\">\n\t\t\t\t\t\t\t<p style=\"white-space:pre-line\"></p><table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"max-width:600px;font-family:Arial,sans-serif;color:#333\"><tbody><tr><td style=\"padding:20px\"><table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background-color:#f9f9f9;margin-bottom:20px;padding:20px;border-radius:8px\"><tbody><tr><td style=\"font-size:20px;font-weight:bold;padding-bottom:10px\">LinkedIn</td></tr><tr><td style=\"font-size:16px;padding-bottom:10px\">Discover why n8n stands out as the premier workflow automation tool. Its flexibility and open-source nature empower businesses to create custom solutions that drive efficiency and innovation.</td></tr><tr><td style=\"font-size:14px;font-style:italic;padding-bottom:10px\">Video/Image suggestion pending</td></tr><tr><td style=\"padding-bottom:10px\"><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#Innovation</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#Automation</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>WorkflowSolutions</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>DigitalTransformation</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>Leadership</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#workflowsdiy</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#n8n</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>AIWorkflows</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#WorkflowAutomation</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\"><wbr>#TechSolutions</span></td></tr><tr><td style=\"font-size:14px;font-weight:bold\">Visit workflows.diy to explore how n8n can transform your business processes!</td></tr></tbody></table><table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background-color:#f9f9f9;margin-bottom:20px;padding:20px;border-radius:8px\"><tbody><tr><td style=\"font-size:20px;font-weight:bold;padding-bottom:10px\">Instagram</td></tr><tr><td style=\"font-size:14px;font-style:italic;padding-bottom:10px\">Eye-catching infographic comparing n8n to other automation tools, highlighting its unique features.</td></tr><tr><td style=\"font-size:16px;padding-bottom:10px\">n8n: The ultimate workflow automation tool! <img data-emoji=\"💡\" class=\"an1\" alt=\"💡\" aria-label=\"💡\" draggable=\"false\" src=\"https://fonts.gstatic.com/s/e/notoemoji/16.0/1f4a1/32.png\" loading=\"lazy\"> Unlock limitless possibilities with its open-source platform. Boost your productivity and streamline your processes. <img data-emoji=\"💤\" class=\"an1\" alt=\"💤\" aria-label=\"💤\" draggable=\"false\" src=\"https://fonts.gstatic.com/s/e/notoemoji/16.0/1f4a4/32.png\" loading=\"lazy\"></td></tr><tr><td style=\"padding-bottom:10px\"><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#AutomationLife</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#TechInnovation</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\"><wbr>#WorkflowTips</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#Programming</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>Engineering</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#workflowsdiy</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#n8n</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>AIWorkflows</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#WorkflowAutomation</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\"><wbr>#TechSolutions</span></td></tr><tr><td style=\"font-size:14px;font-weight:bold\">Visit our website: <a href=\"https://n8n.io/\" target=\"_blank\" data-saferedirecturl=\"https://www.google.com/url?q=https://n8n.io/&amp;source=gmail&amp;ust=1741030878129000&amp;usg=AOvVaw1Nr6ek3eGwe94zlbPaJrzT\">https://n8n.io/</a> #AutomationLife #TechInnovation #WorkflowTips #Programming #Engineering</td></tr></tbody></table><table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background-color:#f9f9f9;margin-bottom:20px;padding:20px;border-radius:8px\"><tbody><tr><td style=\"font-size:20px;font-weight:bold;padding-bottom:10px\">Facebook</td></tr><tr><td style=\"font-size:16px;padding-bottom:10px\">See why businesses are choosing n8n for their workflow automation needs. From its user-friendly interface to its powerful customization options, n8n is revolutionizing how companies approach automation.</td></tr><tr><td style=\"font-size:14px;font-style:italic;padding-bottom:10px\">A visually appealing graphic showcasing n8n's key features and benefits.</td></tr><tr><td style=\"padding-bottom:10px\"><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#SmallBusinessAutomation</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>Entrepreneurship</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#Leadership</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>WorkflowInnovation</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>workflowsdiy</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#n8n</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#AIWorkflows</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>WorkflowAutomation</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>TechSolutions</span></td></tr><tr><td style=\"font-size:14px;font-weight:bold\">What's your favorite automation tip? Share in the comments!</td></tr></tbody></table><table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background-color:#f9f9f9;margin-bottom:20px;padding:20px;border-radius:8px\"><tbody><tr><td style=\"font-size:20px;font-weight:bold;padding-bottom:10px\">Twitter</td></tr><tr><td style=\"font-size:16px;padding-bottom:10px\">n8n: The best #WorkflowAutomation tool! Open-source, customizable, and powerful. Transform your business processes today!</td></tr><tr><td style=\"padding-bottom:10px\"><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#WorkflowTrends</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#AIWorkflows</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>AutomationTips</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#NoCodeSolutions</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\"><wbr>#workflowsdiy</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#n8n</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>TechSolutions</span></td></tr></tbody></table><table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background-color:#f9f9f9;margin-bottom:20px;padding:20px;border-radius:8px\"><tbody><tr><td style=\"font-size:20px;font-weight:bold;padding-bottom:10px\">TikTok</td></tr><tr><td style=\"font-size:14px;font-style:italic;padding-bottom:10px\">Quick demo showcasing how n8n simplifies complex workflows with its intuitive interface.</td></tr><tr><td style=\"font-size:16px;padding-bottom:10px\">n8n: Your go-to for effortless workflow automation! <img data-emoji=\"✨\" class=\"an1\" alt=\"✨\" aria-label=\"✨\" draggable=\"false\" src=\"https://fonts.gstatic.com/s/e/notoemoji/16.0/2728/32.png\" loading=\"lazy\"></td></tr><tr><td style=\"padding-bottom:10px\"><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#n8nTips</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#workflowsdiy</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#n8n</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>AIWorkflows</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#WorkflowAutomation</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\"><wbr>#TechSolutions</span></td></tr><tr><td style=\"font-size:14px;font-weight:bold\">Follow workflows.diy for more automation hacks!</td></tr></tbody></table><table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background-color:#f9f9f9;margin-bottom:20px;padding:20px;border-radius:8px\"><tbody><tr><td style=\"font-size:20px;font-weight:bold;padding-bottom:10px\">Threads</td></tr><tr><td style=\"font-size:16px;padding-bottom:10px\">n8n is transforming the automation landscape. Its open-source nature and extensive integrations make it a top choice for businesses of all sizes. What are your thoughts on the future of workflow automation?</td></tr><tr><td style=\"padding-bottom:10px\"><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#workflowsdiy</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#n8n</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#AIWorkflows</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>WorkflowAutomation</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>TechSolutions</span></td></tr><tr><td style=\"font-size:14px;font-weight:bold\">Share your insights below!</td></tr></tbody></table><table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background-color:#f9f9f9;margin-bottom:20px;padding:20px;border-radius:8px\"><tbody><tr><td style=\"font-size:20px;font-weight:bold;padding-bottom:10px\">YouTube Shorts</td></tr><tr><td style=\"font-size:14px;font-style:italic;padding-bottom:10px\">Short tutorial demonstrating how to build a simple automation workflow in n8n.</td></tr><tr><td style=\"font-size:16px;padding-bottom:10px\">Learn why n8n is the top choice for workflow automation. Its open-source platform and powerful features make it a game-changer for businesses.</td></tr><tr><td style=\"padding-bottom:10px\"><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#n8n</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#automation</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>workflowautomation</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#nocode</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>workflowsdiy</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#AIWorkflows</span><span style=\"display:inline-block;background:#f0f0f0;padding:2px 6px;margin:2px;border-radius:4px\">#<wbr>TechSolutions</span></td></tr><tr><td style=\"font-size:14px;font-weight:bold\">Subscribe for more workflow tips!</td></tr></tbody></table></td></tr></tbody></table><p></p>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n</table>\n","agent":"conversationalAgent","options":{},"promptType":"define"},"typeVersion":1.7},{"id":"3b074887-262f-47ab-b69c-c51b3a513993","name":"Prepare Results Email","type":"@n8n/n8n-nodes-langchain.agent","position":[0,380],"parameters":{"text":"=Parse the social media post results and generate a modern single line HTML table showing platform statuses. For each entry:\n\n-Extract platform name from the JSON key\n-Identify status (Success/Error) based on statusCode or error presence\n-Capture error message if present\n-Format as responsive HTML table with professional styling\n-Ensure email client compatibility with inline CSS\n-Include error handling for invalid JSON formats\n-Remove all line breaks and \\n from response.\n-Avoid any preamble or further explanation and remove all ``` and ```html from response.\n\n## Implementation Example:\nThis solution uses the parsed results from your workflow to generate:\n<table style=\"border-collapse: collapse; width: 100%; font-family: Arial, sans-serif; margin: 20px 0; background-color: #f9f9f9; border: 1px solid #ddd;\">\n    <thead>\n        <tr style=\"background-color: #007bff; color: #fff;\">\n            <th style=\"border: 1px solid #ddd; padding: 12px; text-align: left;\">Platform</th>\n            <th style=\"border: 1px solid #ddd; padding: 12px; text-align: left;\">Status</th>\n            <th style=\"border: 1px solid #ddd; padding: 12px; text-align: left;\">Details</th>\n        </tr>\n    </thead>\n    <tbody>\n        <tr style=\"background-color: #ffffff;\">\n            <td style=\"border: 1px solid #ddd; padding: 12px;\">Instagram</td>\n            <td style=\"border: 1px solid #ddd; padding: 12px; color: #dc3545;\">✗ Error</td>\n            <td style=\"border: 1px solid #ddd; padding: 12px;\">Unsupported post request. Object with ID '[your-unique-id]' does not exist, cannot be loaded due to missing permissions.</td>\n        </tr>\n        <tr style=\"background-color: #f8f9fa;\">\n            <td style=\"border: 1px solid #ddd; padding: 12px;\">X (Twitter)</td>\n            <td style=\"border: 1px solid #ddd; padding: 12px; color: #dc3545;\">✗ Error</td>\n            <td style=\"border: 1px solid #ddd; padding: 12px;\">Unable to sign without access token</td>\n        </tr>\n        <tr style=\"background-color: #ffffff;\">\n            <td style=\"border: 1px solid #ddd; padding: 12px;\">Facebook</td>\n            <td style=\"border: 1px solid #ddd; padding: 12px; color: #dc3545;\">✗ Error</td>\n            <td style=\"border: 1px solid #ddd; padding: 12px;\">Unsupported post request. Object with ID '[your-unique-id]' does not exist, cannot be loaded due to missing permissions.</td>\n        </tr>\n        <tr style=\"background-color: #f8f9fa;\">\n            <td style=\"border: 1px solid #ddd; padding: 12px;\">LinkedIn</td>\n            <td style=\"border: 1px solid #ddd; padding: 12px; color: #dc3545;\">✗ Error</td>\n            <td style=\"border: 1px solid #ddd; padding: 12px;\">Unable to sign without access token</td>\n        </tr>\n    </tbody>\n</table>\n\n\nThis is the social media post results: \n{{ $json.data.toJsonString() }}\n","agent":"conversationalAgent","options":{},"promptType":"define"},"typeVersion":1.7},{"id":"abb3994f-bf23-43f8-9c46-28795cfd2017","name":"Prepare Results Message","type":"@n8n/n8n-nodes-langchain.agent","position":[0,660],"parameters":{"text":"=Parse the social media post results and generate a brief summary of the results.\n\nThis is the social media post results: \n{{ $json.data.toJsonString() }}\n\n## Example Response:\nThe social media post results indicate multiple errors when attempting to access or post content on various platforms. \n\n1. Instagram: The response shows a 400 status code with an error message indicating that the specific post request is unsupported due to missing permissions or an invalid object ID. \n\n2. X Post: Success\n\n3. Facebook: Success \n\n4. LinkedIn: Also returned an 'Unable to sign without access token' error. \n\nOverall, access token issues and unsupported requests are frequent problems across these social media platforms.\n","agent":"conversationalAgent","options":{},"promptType":"define"},"typeVersion":1.7},{"id":"b4a4838a-83b0-4f28-a9f3-dea915228325","name":"Image Choice","type":"n8n-nodes-base.form","disabled":true,"position":[-620,-120],"webhookId":"0dc811ef-b2e0-4213-a0c9-e9b5fb9fcbf1","parameters":{"options":{"formTitle":"Generate Post Image","buttonLabel":"Submit"},"formFields":{"values":[{"fieldType":"file","fieldLabel":"Upload Image (optional)","multipleFiles":false,"acceptFileTypes":".jpg, .png, .jpeg"},{"fieldType":"dropdown","fieldLabel":"Generate Custom Image using AI Image Generator","fieldOptions":{"values":[{"option":"Yes"},{"option":"No"}]},"requiredField":true}]}},"typeVersion":1},{"id":"1cf97c10-e60f-4584-b069-3d4506868d8e","name":"Gmail Results","type":"n8n-nodes-base.gmail","position":[360,380],"webhookId":"0a81b95a-cd82-465d-8450-cf38518a4cbb","parameters":{"sendTo":"={{ $env.EMAIL_ADDRESS_JOE }} ","message":"={{ $json.output }}","options":{"appendAttribution":false},"subject":"🔥RESULTS🔥 Social Media Factory"},"credentials":{"gmailOAuth2":{"id":"1xpVDEQ1yx8gV022","name":"Gmail account"}},"typeVersion":2.1},{"id":"c845ae46-9d37-472b-ae0f-49fc6940e685","name":"Telegram Results","type":"n8n-nodes-base.telegram","position":[360,660],"webhookId":"bb40ede7-03cf-493d-b051-196b96725925","parameters":{"text":"={{ $json.output }}","chatId":"={{ $env.TELEGRAM_CHAT_ID }}","additionalFields":{"appendAttribution":false}},"credentials":{"telegramApi":{"id":"pAIFhguJlkO3c7aQ","name":"Telegram account"}},"typeVersion":1.2},{"id":"a33f9431-bede-4f66-ae0d-1e686a3092b7","name":"Sticky Note13","type":"n8n-nodes-base.stickyNote","position":[-320,340],"parameters":{"color":4,"width":940,"height":620,"content":""},"typeVersion":1},{"id":"643b94c6-4535-4876-9660-d82ff69cbcf6","name":"Is Content Approved?","type":"n8n-nodes-base.if","position":[-240,-20],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"e32d270f-f258-4522-94e1-2cb7ee4e8d2a","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.data.approved }}","rightValue":""}]}},"typeVersion":2.2},{"id":"fb7108e2-21cf-4df4-ab20-fe75b15b0a24","name":"Set Default True 2","type":"n8n-nodes-base.set","position":[980,20],"parameters":{"options":{},"assignments":{"assignments":[{"id":"f150aa79-2d20-4869-b60a-350d49a215a5","name":"data","type":"object","value":"={\n  \"approved\": true\n}"}]}},"typeVersion":3.4},{"id":"66364a53-c2fc-43fd-be92-683b373652df","name":"Sticky Note14","type":"n8n-nodes-base.stickyNote","position":[-700,-260],"parameters":{"width":300,"height":580,"content":"## Alternative User Uploaded Image\n(optional)"},"typeVersion":1},{"id":"d0025029-1f6f-4b27-8495-00966f1dae12","name":"Sticky Note15","type":"n8n-nodes-base.stickyNote","position":[880,-140],"parameters":{"width":460,"height":340,"content":"## Implement Additional Approval Here\n(optional)"},"typeVersion":1},{"id":"0a10bca0-c3a8-496b-a22e-120928ad7736","name":"SerpAPI","type":"@n8n/n8n-nodes-langchain.toolSerpApi","position":[460,-540],"parameters":{"options":{}},"credentials":{"serpApi":{"id":"DfdkTTaZtPp0iHYv","name":"SerpAPI account"}},"typeVersion":1},{"id":"fa765062-22ef-4f26-9f02-099235edc771","name":"Sticky Note16","type":"n8n-nodes-base.stickyNote","position":[780,-900],"parameters":{"width":480,"height":500,"content":"### 💡Notes\n\nAdjust the Social Media Content Factory prompts to suit your personal or business requirements.\n\nUpdate Credentials for:\n- OpenAI API Key\nhttps://auth.openai.com/log-in\n\n- Google Studio API\nhttps://aistudio.google.com/app/apikey\n\n- SERP API Key\nhttps://serpapi.com/\n\n- Gmail OAuth\nhttps://docs.n8n.io/integrations/builtin/credentials/google/\n\n- Telegram Bot (Optional)\nhttps://docs.n8n.io/integrations/builtin/credentials/telegram/\n\n- imgbb\nhttps://imgbb.com/"},"typeVersion":1},{"id":"5ffc2b16-61af-4395-a57b-20d1cd125488","name":"Sticky Note17","type":"n8n-nodes-base.stickyNote","position":[1940,-140],"parameters":{"width":300,"height":180,"content":"💡Notes\n\nUpdate all Social Media Platform Credentials as required.\n\nAdjust parameters and content for each platform to suit your needs."},"typeVersion":1},{"id":"b21f527c-5674-49d0-a114-866d669e7ad6","name":"Rename Binary File","type":"n8n-nodes-base.code","position":[-620,120],"parameters":{"jsCode":"$input.first().binary.data = $input.first().binary.Upload_Image__optional_\ndelete $input.first().binary.Upload_Image__optional_\nreturn $input.first()"},"typeVersion":2,"alwaysOutputData":true}],"active":false,"pinData":{"Submit Social Post Details":[{"json":{"Topic":"Why n8n is the Best Workflow Automation Tool","formMode":"test","submittedAt":"2025-03-02T13:32:20.807-05:00","Link (optional)":"https://n8n.io/","Keywords or Hashtags (optional)":"n8n, AIWorkflows, workflows.diy"}}]},"settings":{"executionOrder":"v1"},"versionId":"d44bf3b1-5ba6-48e2-8ab6-1cbe93a260e4","connections":{"Merge":{"main":[[{"node":"Set Default True 2","type":"main","index":0}]]},"Merge1":{"main":[[{"node":"Instagram Image","type":"main","index":0}]]},"Merge2":{"main":[[{"node":"Facebook Post","type":"main","index":0},{"node":"LinkedIn Post","type":"main","index":0}]]},"OpenAI":{"main":[[{"node":"Save Image to imgbb.com3","type":"main","index":0},{"node":"Merge","type":"main","index":1},{"node":"Merge2","type":"main","index":1}]]},"X Post":{"main":[[{"node":"X Result","type":"main","index":0}],[]]},"SerpAPI":{"ai_tool":[[{"node":"Social Media Content Factory","type":"ai_tool","index":0}]]},"X Result":{"main":[[{"node":"Merge Results","type":"main","index":1}]]},"Aggregate":{"main":[[{"node":"Prepare Results Email","type":"main","index":0},{"node":"Prepare Results Message","type":"main","index":0}]]},"gpt-4o LLM":{"ai_languageModel":[[{"node":"Social Media Content Factory","type":"ai_languageModel","index":0}]]},"gpt-4o-mini":{"ai_languageModel":[[{"node":"Prepare Content Review Email","type":"ai_languageModel","index":0}]]},"Image Choice":{"main":[[{"node":"Rename Binary File","type":"main","index":0}]]},"Is Approved?":{"main":[[{"node":"X Post","type":"main","index":0},{"node":"Merge1","type":"main","index":1},{"node":"Merge2","type":"main","index":0}],[]]},"gpt-4o-mini1":{"ai_languageModel":[[{"node":"Prepare Results Email","type":"ai_languageModel","index":0}]]},"gpt-4o-mini2":{"ai_languageModel":[[{"node":"Prepare Results Message","type":"ai_languageModel","index":0}]]},"Facebook Post":{"main":[[{"node":"Facebook Result","type":"main","index":0}],[]]},"LinkedIn Post":{"main":[[{"node":"LinkedIn Result","type":"main","index":0}],[]]},"Merge Results":{"main":[[{"node":"Aggregate","type":"main","index":0}]]},"Facebook Result":{"main":[[{"node":"Merge Results","type":"main","index":2}]]},"Instagram Image":{"main":[[{"node":"Instragram Post","type":"main","index":0}]]},"Instragram Post":{"main":[[{"node":"Instagram Result","type":"main","index":0}],[]]},"LinkedIn Result":{"main":[[{"node":"Merge Results","type":"main","index":3}]]},"pollinations.ai":{"main":[[]]},"Instagram Result":{"main":[[{"node":"Merge Results","type":"main","index":0}]]},"Google Gemini LLM":{"ai_languageModel":[[]]},"Set Default True 2":{"main":[[{"node":"Is Approved?","type":"main","index":0}]]},"Is Content Approved?":{"main":[[{"node":"OpenAI","type":"main","index":0}]]},"Social Media Content":{"ai_outputParser":[[{"node":"Social Media Content Factory","type":"ai_outputParser","index":0}]]},"Prepare Results Email":{"main":[[{"node":"Gmail Results","type":"main","index":0}]]},"Gmail User for Approval":{"main":[[{"node":"Is Content Approved?","type":"main","index":0}]]},"Prepare Results Message":{"main":[[{"node":"Telegram Results","type":"main","index":0}]]},"Save Image to imgbb.com3":{"main":[[{"node":"Merge","type":"main","index":0},{"node":"Merge1","type":"main","index":0}]]},"Approve Final Post Content":{"main":[[]]},"Submit Social Post Details":{"main":[[{"node":"Social Media Content Factory","type":"main","index":0}]]},"Prepare Content Review Email":{"main":[[{"node":"Gmail User for Approval","type":"main","index":0}]]},"Social Media Content Factory":{"main":[[{"node":"Prepare Content Review Email","type":"main","index":0}]]}}}


name: AI-Powered Short-Form Video Generator with OpenAI, Flux, Kling, and ElevenLabs
author_name: Cameron Wills
author_username: camerondwills
categories: []
created_at: 2025-03-10T10:25:20.937Z
updated_at: 2025-03-10T10:25:20.937Z
url: https://n8n.io/workflows/3121
scraped_at: 2025-06-19 22:07:56
description:
  Who is this for?
  Content creators, digital marketers, and social media managers who want to automate the creation of short-form videos for platforms like TikTok, YouTube Shorts, and Instagram Reels without extensive video editing skills.
  What problem does this workflow solve?
  Creating engaging short-form videos consistently is time-consuming and requires multiple tools and skills. This workflow automates the entire process from ideation to publishing, significantly reducing the manual effort needed while maintaining content quality.
  What this workflow does
  This all-in-one solution transforms ideas into fully produced short-form videos through a 5-step process:

  Generate video captions from ideas stored in a Google Sheet
  Create AI-generated images using Flux and the OpenAI API
  Convert images to videos using Kling's API
  Add voice-overs to your content with Eleven Labs
  Complete the video production with Creatomate by adding templates, transitions, and combining all elements

  The workflow handles everything from sourcing content ideas to rendering the final video, and even notifies you on Discord when videos are ready.
  Setup (Est. time: 20-30 minutes)
  Before getting started, you'll need:

  n8n installation (tested on version 1.81.4)
  OpenAI API Key (free trial credits available)
  PiAPI (free trial credits available)
  Eleven Labs (free account)
  Creatomate API Key (free trial credits available)
  Google Sheets API enabled in Google Cloud Console
  Google Drive API enabled in Google Cloud Console
  OAuth 2.0 Client ID and Client Secret from your Google Cloud Console Credentials

  How to customize this workflow to your needs

  Adjust the Google Sheet structure to include additional data like video length, duration, style, etc.
  Modify the prompt templates for each AI service to match your brand voice and content style
  Update the Creatomate template to reflect your visual branding
  Configure notification preferences in Discord to manage your workflow

  This workflow combines multiple AI technologies to create a seamless content production pipeline, saving you hours of work per video and allowing you to focus on strategy rather than production.

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

workflow_json:
  {"id":"aqLL3BAXqQIjeJDt","meta":{"instanceId":"dce6d05169adc9f802863a06c3edb9925b178c4fce2360953cce9c1b509705cc","templateCredsSetupCompleted":true},"name":"AI Automated TikTok/Youtube Shorts/Reels Generator","tags":[{"id":"meqQhJqB377UiY3s","name":"template","createdAt":"2025-03-10T07:30:05.424Z","updatedAt":"2025-03-10T07:30:05.424Z"}],"nodes":[{"id":"e5095169-dc78-4d90-9662-04cfc82c38d9","name":"Get image","type":"n8n-nodes-base.httpRequest","position":[220,40],"parameters":{"url":"=https://api.piapi.ai/api/v1/task/{{ $json.data.task_id }}","options":{},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"X-API-Key","value":"={{ $('Set API Keys').item.json['PiAPI Key'] }}"}]}},"typeVersion":4.2},{"id":"f477250a-fc8e-407e-a632-cffc0e564596","name":"Generate Image","type":"n8n-nodes-base.httpRequest","position":[-60,40],"parameters":{"url":"https://api.piapi.ai/api/v1/task","body":"={\n  \"model\": \"Qubico/flux1-dev\",\n  \"task_type\": \"txt2img\",\n  \"input\": {\n    \"prompt\": \"{{ $('Generate Image Prompts').item.json.choices[0].message.content }} realistic and casual as if taken by an iphone camera by a TikTok influencer\",\n    \"negative_prompt\": \"taking a photo of a room, recording a video of a room, photos app, video recorder, illegible text, blurry text, low quality text, DSLR, unnatural\",\n    \"width\": 540,\n    \"height\": 960\n  }\n}","method":"POST","options":{},"sendBody":true,"contentType":"raw","sendHeaders":true,"rawContentType":"application/json","headerParameters":{"parameters":[{"name":"X-API-Key","value":"={{ $('Set API Keys').item.json['PiAPI Key'] }}"}]}},"retryOnFail":false,"typeVersion":4.2},{"id":"622ce9f5-ad58-485b-a3c6-1265700b04da","name":"Image-to-Video","type":"n8n-nodes-base.httpRequest","position":[-420,560],"parameters":{"url":"https://api.piapi.ai/api/v1/task","body":"={\n  \"model\": \"kling\",\n  \"task_type\": \"video_generation\",\n  \"input\": {\n    \"prompt\": \"{{ $json.data.input.prompt }}\",\n    \"negative_prompt\": \"blurry motion, distorted faces, unnatural lighting, over produced, bad quality\",\n    \"cfg_scale\": 0.5,\n    \"duration\": 5,\n    \"mode\": \"pro\",\n    \"image_url\": \"{{ $json.data.output.image_url }}\",\n    \"version\": \"1.6\",\n    \"camera_control\": {\n      \"type\": \"simple\",\n      \"config\": {\n        \"horizontal\": 0,\n        \"vertical\": 0,\n        \"pan\": 0,\n        \"tilt\": 0,\n        \"roll\": 0,\n        \"zoom\": 5\n      }\n    }\n  },\n  \"config\": {}\n}","method":"POST","options":{},"sendBody":true,"contentType":"raw","sendHeaders":true,"rawContentType":"application/json","headerParameters":{"parameters":[{"name":"X-API-Key","value":"={{ $('Set API Keys').item.json['PiAPI Key'] }}"}]}},"typeVersion":4.2},{"id":"ed14eac3-1d63-481d-871c-a04c52977fc6","name":"Get Video","type":"n8n-nodes-base.httpRequest","position":[-160,560],"parameters":{"url":"=https://api.piapi.ai/api/v1/task/{{ $json.data.task_id }}","options":{},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"X-API-Key","value":"={{ $('Set API Keys').item.json['PiAPI Key'] }}"}]}},"typeVersion":4.2},{"id":"8b68100c-8a5a-405c-825e-d9e8a898f235","name":"List Elements","type":"n8n-nodes-base.code","position":[460,600],"parameters":{"jsCode":"return [\n  {\n    scene_titles: items.map(item => item.json.response.text),\n    video_urls: items.map(item => item.json.data.output.video_url),\n    input_tokens: $('Calculate Token Usage').first().json.total_prompt_tokens,\n    output_tokens: $('Calculate Token Usage').first().json.total_completion_tokens,\n    model: $('Generate Image Prompts').first().json.model\n  }\n];"},"typeVersion":2},{"id":"f8780885-508e-4dc9-b146-f367297d7b68","name":"Wait 10min","type":"n8n-nodes-base.wait","position":[-280,560],"webhookId":"1f9d716f-6544-4e4e-94ec-408ac3ea6e82","parameters":{"unit":"minutes","amount":10},"typeVersion":1.1},{"id":"6290bc91-0eb9-4053-bd93-961cb9e917c0","name":"Wait 3min","type":"n8n-nodes-base.wait","position":[80,40],"webhookId":"77cdee73-5e99-456a-b5e7-410b4d257669","parameters":{"unit":"minutes","amount":3},"typeVersion":1.1},{"id":"818a66ef-b9fa-4efc-85d1-b295300cbed8","name":"Wait 5min","type":"n8n-nodes-base.wait","position":[540,-40],"webhookId":"31d5b1a2-dbb5-4849-ae25-cb491539c16e","parameters":{"unit":"minutes"},"typeVersion":1.1},{"id":"afd66320-dfe0-4872-a09d-d53fe08152ce","name":"Generate voice","type":"n8n-nodes-base.httpRequest","position":[-60,1020],"parameters":{"url":"https://api.elevenlabs.io/v1/text-to-speech/onwK4e9ZLuTAKqWW03F9","method":"POST","options":{},"sendBody":true,"sendHeaders":true,"bodyParameters":{"parameters":[{"name":"text","value":"={{ $json.choices[0].message.content }}"}]},"headerParameters":{"parameters":[{"name":"xi-api-key","value":"={{ $('Set API Keys').item.json['ElevenLabs API Key'] }}"}]}},"retryOnFail":false,"typeVersion":4.2},{"id":"916f19e1-7928-4141-a5c5-ca39bd22b0a0","name":"List Elements1","type":"n8n-nodes-base.code","position":[460,820],"parameters":{"jsCode":"return [\n  {\n    sound_urls: items.map(item => $('Upload Voice Audio').first().json.webContentLink)\n  }\n];"},"typeVersion":2},{"id":"b95fd80c-ec7f-4d50-99ae-f3f544b8a111","name":"Fail check","type":"n8n-nodes-base.if","position":[-20,560],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"a920eb54-fc23-4b68-8f56-2eee907a5481","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.data.status }}","rightValue":"failed"}]}},"typeVersion":2.2},{"id":"7e3f5cda-1d49-4a59-956f-f639daf203e0","name":"Wait to retry","type":"n8n-nodes-base.wait","position":[120,520],"webhookId":"3b0fae8f-4419-45cd-8380-8f72eca05ff8","parameters":{"unit":"minutes"},"typeVersion":1.1},{"id":"48ec39c9-1802-4860-918d-9c660051f27b","name":"Generate Image Prompts","type":"@n8n/n8n-nodes-langchain.openAi","position":[-540,120],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"o3-mini","cachedResultName":"O3-MINI"},"options":{},"messages":{"values":[{"content":"=You are an advanced, unhinged, hilariously entertaining prompt-generation AI specializing in expanding short POV image prompt ideas into detailed, hyper-realistic prompts optimized for Qubico/flux1-dev. Your task is to take a brief input tied to job seeking, job hunting, or resume building and morph it into a cinematic, immersive prompt locked in a first-person perspective, making the viewer feel they’re living the scene.\n\nNEVER include quotation marks or emojis in your response—flux API will choke on them, and that’s a hard no.\n\nThe topic of this narrative is: {{ $('Load Google Sheet').item.json.idea }}\n\nThe short prompt idea to expand for this image generation is: {{ $json.response.text }}\n\nONLY GENERATE ONE PROMPT PER IDEA—NO COMBINING. In at least one scene, weave in this environment descriptor: {{ $('Load Google Sheet').first().json.environment_prompt }}, but go wild with unhinged, edgy, funny twists elsewhere (skip the cringe or cheesy garbage). Most job hunting happens on laptops or desktops, so prioritize those over phones. If a phone sneaks in, it’s only showing job-related content like email, LinkedIn, a resume, or a job posting—never a photo or video app.\n\nEvery prompt has two parts:\n\nForeground: Kick off with First person view POV GoPro shot of... and show the viewer’s hands, limbs, or feet locked in a job-related action.\n\nBackground: Start with In the background,... and paint the scenery, blending the environment descriptor when required, plus sensory zingers.\n\nTop Rules:\n\nNO quotation marks or emojis—EVER. This is life or death for flux.\nStick to first-person POV—the viewer’s in the driver’s seat, not watching from the sidelines.\nShow a limb (hands, feet) doing something job-focused—typing, holding a resume, adjusting a tie.\nKeep it dynamic, like a GoPro clip, with motion and depth mimicking human vision.\nIf tech’s involved (phone, computer), it’s displaying job-hunting gold—email, job boards, resumes—not random trash.\nNo off-topic actions like recording videos or snapping pics—job hunting only, fam.\nExtra Vibes:\n\nFull-body awareness: Drop hints of physical feels—cramping fingers, racing pulse, slumping shoulders.\nSensory overload: Hit sight, touch, sound, smell, temperature for max realism (coffee whiffs, keyboard clacks).\nWorld grip: Limbs interact with the scene—tapping keys, handing over papers, stepping up.\nKeep it under 1000 characters, one slick sentence, no fluff or formatting.\nMake it entertaining, relatable, with an Andrew Tate viral edge for the down-and-out job hustlers.\nExamples:\n\nInput: Updating a LinkedIn profile after a long day\n\nEnvironment_prompt: Tired, cluttered apartment, laptop glow\n\nOutput: First person view POV GoPro shot of my hands hammering a laptop, cheeto-dusted fingers aching from the grind, the screen flashing my LinkedIn profile with a fresh connection ping; in the background, a trashed apartment lit by the laptop’s ghostly glow, pizza boxes toppling, traffic humming outside, stale takeout stench hitting my nose as my back screams from the hustle.\n\nInput: Handing over a resume at a job fair\n\nEnvironment_prompt: Hopeful, busy convention hall, suits everywhere\n\nOutput: First person view POV GoPro shot of my hand thrusting out a crisp resume, fingers twitching with nerves as it brushes another palm; in the background, a buzzing convention hall packed with suits, coffee fumes and shoe polish in the air, chatter drowning my pounding heart as I lock eyes with the recruiter.\n\nNO QUOTATION MARKS. NO EMOJIS. EVER."}]},"simplify":false},"credentials":{"openAiApi":{"id":"UqJ11kHhHtyzaDWx","name":"OpenAi account"}},"typeVersion":1.8},{"id":"5c1b8dc8-4eb3-49fe-81c7-c811d73fac0d","name":"Calculate Token Usage","type":"n8n-nodes-base.code","position":[-240,120],"parameters":{"jsCode":"// Get all input items (the 5 LLM responses)\nconst items = $input.all();\n\n// Calculate total prompt tokens and total completion tokens\nconst totalPromptTokens = items.reduce((sum, item) => sum + item.json.usage.prompt_tokens, 0);\nconst totalCompletionTokens = items.reduce((sum, item) => sum + item.json.usage.completion_tokens, 0);\n\n// Create new items with original data plus the totals\nconst outputItems = items.map(item => ({\n  json: {\n    ...item.json,                   // Spread the original item data\n    total_prompt_tokens: totalPromptTokens,     // Add total prompt tokens\n    total_completion_tokens: totalCompletionTokens // Add total completion tokens\n  }\n}));\n\n// Return the modified items\nreturn outputItems;"},"typeVersion":2},{"id":"efc3d0dd-70dc-4fba-b040-22c773ed5602","name":"Check for failures","type":"n8n-nodes-base.if","position":[360,40],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"567d1fc9-0638-4a44-b5f5-30a9a6683794","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.data.status }}","rightValue":"failed"}]}},"typeVersion":2.2},{"id":"3161c993-5696-4419-9299-fde51719dfc7","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-560,-200],"parameters":{"color":5,"width":1260,"height":460,"content":"## 2. 🖼️Generate images with Flux using [PiAPI](https://piapi.ai/?via=n8n) \n### (total cost: $0.0948 approx. as of 3/9/25)\n1. OpenAI is used to generate 5 Flux image prompts based on the 5 captions generated. Edit this node to see/edit the prompt instructions. \n2. Next we use some custom javascript to total up how many tokens were used for each 5 generations so we can track our costs later.\n3. Then we generate an image with Flux using the [PiAPI service](https://piapi.ai/?via=n8n), waiting to check for failures and retrying if there are any.\n\nYou can change the image model used by editing the Generate Image node API call.\nFlux models available (as of 3/9/25):\n- Qubico/flux1-dev ($0.015) - Currently set\n- Qubico/flux1-schnell ($0.0015)\n- Qubico/flux1-advanced ($0.02)\n\nFor full list of API settings, see the [Flux API Documentation](https://piapi.ai/docs/flux-api/text-to-image?via=n8n)\n"},"typeVersion":1},{"id":"e5cdec7e-cb75-4200-a8e3-615621d20150","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-460,280],"parameters":{"color":6,"width":1040,"height":500,"content":"## 3. 🎬Generate videos with Kling using [PiAPI](https://piapi.ai/?via=n8n)\n### (total cost: $2.30 approx. as of 3/9/25)\n1. We use image-to-video with Kling using [PiAPI](https://piapi.ai/?via=n8n) to generate a video from each image.\n2. Then we wait to check for failures, and repeat the generations the failed if there are any.\n\nYou can edit the video model used in the Image-to-Video node. For testing, I'd recommend switching from pro to std for lower quality and cheaper price.\nKling models available (as of 3/9/25):\n- std (Standard) $0.26 per 5 second video\n- pro (Professional) $0.46 per 5 second video - Currently set\n\nFor full list of API settings, see the [Kling API Documentation](https://piapi.ai/docs/kling-api/create-task?via=n8n)\n"},"typeVersion":1},{"id":"8404a390-a402-4703-8cb5-4a54490dc7bd","name":"Generate Video Captions","type":"@n8n/n8n-nodes-langchain.openAi","position":[-980,780],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4o-mini","cachedResultName":"GPT-4O-MINI"},"options":{},"messages":{"values":[{"role":"system","content":"DO NOT include any quotation marks in your response. Do not put a quote at the beginning or the end of your response.\n\nYou are a prompt-generation AI specializing in crafting unhinged, entertaining TikTok captions for a \"day in the life\" POV story about job hunting or resume writing. Generate five concise, action-driven captions (5-10 words each) that follow a Problem > Action > Reward structure. The first caption should be a shocking or funny hook, and the last should conclude with a satisfying reward. Use emojis sparingly—only one per caption at most, and only when they add impact; skip them if they don’t enhance the message.\n\nGuidelines:\n\nPerspective: Always first-person POV, immersing the viewer in the story.\nTone: Channel Andrew Tate mixed with Charlie Sheen—cursing and sexual innuendos are fair game.\nContent: Focus on job seeking, hunting, or resume building, spotlighting AI as the game-changer.\nNarrative: Start with the grind of unemployment or a shitty job, pivot to using AI for resumes and cover letters, and end with scoring the dream gig.\nScenes: Highlight raw, emotional moments—skip the boring stuff.\nYour captions should be wild and entertaining, not polished or professional. The first caption is the hook—make it shocking, hilarious, or ballsy, something Andrew Tate would growl. Use emojis sparingly—max one per caption, only if it hits harder with it.\n\nYour response should be a list of 5 items separated by \"\\n\" (for example: \"item1\\nitem2\\nitem3\\nitem4\\nitem5\")"},{"content":"={{ $json.idea }}"}]},"simplify":false},"credentials":{"openAiApi":{"id":"UqJ11kHhHtyzaDWx","name":"OpenAi account"}},"typeVersion":1.8},{"id":"f614c784-a3ee-4eb8-aee3-cc0ad3e87556","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-460,800],"parameters":{"color":4,"width":1040,"height":400,"content":"## 4. 🔉Generate voice overs with [Eleven Labs](https://try.elevenlabs.io/n8n)\n1. OpenAI API is used to generate a funny script that relates to the captions. Open this node to see/edit the prompt instructions. \n2. Then we use the [Eleven Labs API](https://try.elevenlabs.io/n8n) to generate the voiceover and upload it to our Google Drive so it can be accessed in the next step.\n\nTo replace the voice, find the voice ID of the voice you want to use in [Eleven Labs](https://try.elevenlabs.io/n8n), then change the URL in the Generate Voice node to: https://api.elevenlabs.io/v1/text-to-speech/{voice ID here}\n\nFor full list of API settings, see the [Eleven Labs API Documentation](https://elevenlabs.io/docs/api-reference/text-to-speech/convert)\n"},"typeVersion":1},{"id":"e59306c1-8efe-4d98-9391-10c68c17787b","name":"Match captions with videos","type":"n8n-nodes-base.merge","position":[300,600],"parameters":{"mode":"combine","options":{},"combineBy":"combineByPosition"},"typeVersion":3},{"id":"8da7e16e-691b-4335-bfc7-e196c36f982d","name":"Generate Script","type":"@n8n/n8n-nodes-langchain.openAi","position":[-420,1020],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4o-mini","cachedResultName":"GPT-4O-MINI"},"options":{},"messages":{"values":[{"role":"system","content":"=You are an unhinged and hilarious TikTok influencer who's like a mix of Andrew Tate and Charlie Sheen. The user is going to provide you with a topic, and then 5 different parts of a story. Your task is to narrate the story as this hilarious character, who isn't afraid to be edgy or curse or use sexual innuendos. However keep each of the 5 talking points brief, as you only have about 5 seconds to speak during each. The entire length of your narration should be around 15 seconds.\n\nEach line item of the users message represents 1 5 second clip, so your response needs to be able to quickly and easily be spoken in those time constraints. Don't say extra things you don't need to. Just quickly tell the story, in order, and make it unhinged, funny, entertaining, and potentially controversially viral. Don't worry about offendeding anyone. Andrew Tate style it.\n\nDo not include any emojis, as your response will be converted from text to speech, so anything but text and punctuation isn't neccesary. Also, don't make your jokes overly corny, speak in a witty, edgy, funny way, but no corny dad jokes or anything cringe."},{"content":"={{ $('Generate Video Captions').item.json.choices[0].message.content }}"}]},"simplify":false},"credentials":{"openAiApi":{"id":"UqJ11kHhHtyzaDWx","name":"OpenAi account"}},"executeOnce":true,"typeVersion":1.8},{"id":"ad87317d-3ed0-4fdf-aea5-7b2fa60fb59f","name":"Upload Voice Audio","type":"n8n-nodes-base.googleDrive","position":[140,1020],"parameters":{"name":"={{ $('Load Google Sheet').item.json.id }}-voiceover.mp3","driveId":{"__rl":true,"mode":"list","value":"My Drive"},"options":{},"folderId":{"__rl":true,"mode":"list","value":"1w1EQ8xyth6w7AbX2wpDI3vInfYeRy8vH","cachedResultUrl":"https://drive.google.com/drive/folders/1w1EQ8xyth6w7AbX2wpDI3vInfYeRy8vH","cachedResultName":"Resume Studio"}},"credentials":{"googleDriveOAuth2Api":{"id":"ZvDuyVfbZJbDJXcS","name":"Google Drive account"}},"typeVersion":3},{"id":"eec529e9-2601-4f7b-b415-63d2ebba1574","name":"Set Access Permissions","type":"n8n-nodes-base.googleDrive","position":[320,1020],"parameters":{"fileId":{"__rl":true,"mode":"id","value":"={{ $json.id }}"},"options":{},"operation":"share","permissionsUi":{"permissionsValues":{"role":"writer","type":"anyone","allowFileDiscovery":true}}},"credentials":{"googleDriveOAuth2Api":{"id":"ZvDuyVfbZJbDJXcS","name":"Google Drive account"}},"typeVersion":3},{"id":"63e72d56-140e-47d8-9f72-b58c764deed9","name":"Pair Videos with Audio","type":"n8n-nodes-base.merge","position":[680,700],"parameters":{"mode":"combine","options":{},"combineBy":"combineByPosition"},"typeVersion":3},{"id":"60a80c6f-0385-48e6-9b71-c23a74cbc15c","name":"Render Final Video","type":"n8n-nodes-base.httpRequest","position":[860,700],"parameters":{"url":"https://api.creatomate.com/v1/renders","body":"={\n  \"template_id\": \"{{ $('Set API Keys').item.json['Creatomate Template ID'] }}\",\n  \"modifications\": {\n    \n    \"Video-1.source\": \"{{ $json.video_urls[0] }}\",\n    \"Video-2.source\": \"{{ $json.video_urls[1] }}\",\n    \"Video-3.source\": \"{{ $json.video_urls[2] }}\",\n    \"Video-4.source\": \"{{ $json.video_urls[3] }}\",\n    \"Video-5.source\": \"{{ $json.video_urls[4] }}\",\n\n    \"Audio-1.source\": \"{{ $json.sound_urls[0] }}\",\n\n    \"Text-1.text\": \"{{ $json.scene_titles[0] }}\",\n    \"Text-2.text\": \"{{ $json.scene_titles[1] }}\",\n    \"Text-3.text\": \"{{ $json.scene_titles[2] }}\",\n    \"Text-4.text\": \"{{ $json.scene_titles[3] }}\",\n    \"Text-5.text\": \"{{ $json.scene_titles[4] }}\"\n  }\n}","method":"POST","options":{},"sendBody":true,"contentType":"raw","sendHeaders":true,"rawContentType":"application/json","headerParameters":{"parameters":[{"name":"Authorization","value":"=Bearer {{ $('Set API Keys').item.json['Creatomate API Key'] }}"},{"name":"Content-Type","value":"application/json"}]}},"executeOnce":true,"typeVersion":4.2},{"id":"89c0e958-7690-4f3d-af49-3e9776f2c979","name":"Notify me on Discord","type":"n8n-nodes-base.discord","position":[1840,700],"webhookId":"1541bc50-06e4-48e8-8c76-23850ee4edf6","parameters":{"content":"=A new Resume Studio POV video has been created: {{ $json.final_output }}","options":{},"authentication":"webhook"},"credentials":{"discordWebhookApi":{"id":"rd9P3JURnEdrsFAZ","name":"Discord Webhook account"}},"typeVersion":2},{"id":"14a09794-5e02-4880-b33d-139a91726dda","name":"Once Per Day","type":"n8n-nodes-base.scheduleTrigger","position":[-1540,780],"parameters":{"rule":{"interval":[{"triggerAtHour":7}]}},"typeVersion":1.2},{"id":"4de1f1c7-52ad-4e00-ad22-b4c3c0f718d8","name":"Load Google Sheet","type":"n8n-nodes-base.googleSheets","position":[-1120,780],"parameters":{"options":{"returnFirstMatch":true},"filtersUI":{"values":[{"lookupValue":"for production","lookupColumn":"production"}]},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1cjd8p_yx-M-3gWLEd5TargtoB35cW-3y66AOTNMQrrM/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1cjd8p_yx-M-3gWLEd5TargtoB35cW-3y66AOTNMQrrM","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1cjd8p_yx-M-3gWLEd5TargtoB35cW-3y66AOTNMQrrM/edit?usp=drivesdk","cachedResultName":"Sheet Template"}},"credentials":{"googleSheetsOAuth2Api":{"id":"CkBO4U0JY0QvkimY","name":"Google Sheets account"}},"typeVersion":4.5,"alwaysOutputData":true},{"id":"e5c83690-1696-43aa-a0db-164ca128dd67","name":"Create List","type":"n8n-nodes-base.code","position":[-660,700],"parameters":{"jsCode":"// Get the text directly from the OpenAI response\nconst text = $input.first().json.choices[0].message.content;\n\n// Split the text on literal '\\\\n', trim, and filter empty lines\nconst lines = text.split('\\\\n').map(line => line.trim()).filter(line => line !== '');\n\n// Create an array of items for n8n\nconst items = lines.map(line => ({\n  json: {\n    response: { text: line }\n  }\n}));\n\n// Return the array of items\nreturn items;"},"typeVersion":2},{"id":"ed99df67-2068-4c8b-a6ba-e67d234f03c4","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[620,480],"parameters":{"color":3,"width":1360,"height":380,"content":"## 5. 📥Complete video with [Creatomate](https://creatomate.com/)\n### (total cost: $0.38 approx. with the Essential plan credits | Free trial credits available)\n1. First, the list of videos/captions is combined with the generated voice over into a single item containing all 3 elements.\n2. Those are then passed over to the Creatomate Template ID you specified, replacing the template captions/video/audio with your generated ones.\n3. When the video is finished rendering, it's then uploaded to Google Drive and the permissions set so it can be accessed with a link.\n4. Then we update the original Google Sheet template with the information from our generation, including tokens to calculate cost, then mark this idea as completed.\n5. Finally, we send a notification to via [webhook to the Discord server](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks) when the video is ready to be downloaded and used!\n\n"},"typeVersion":1},{"id":"e7064a56-c500-4f9f-a54a-c4352c263b56","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-1260,-160],"parameters":{"width":620,"height":420,"content":"# 🤖 AI-Powered Short-Form Video Generator with OpenAI, Flux, Kling, and ElevenLabs\n\n## 📃Before you get started, you'll need:\n- [n8n installation](https://n8n.partnerlinks.io/n8nTTVideoGenTemplate) (tested on version 1.81.4)\n- [OpenAI API Key](https://platform.openai.com/api-keys) (free trial credits available)\n- [PiAPI](https://piapi.ai/?via=n8n) (free trial credits available)\n- [Eleven Labs](https://try.elevenlabs.io/n8n) (free account)\n- [Creatomate API Key](https://creatomate.com/) (free trial credits available)\n- Google Sheets API enabled in [Google Cloud Console](https://console.cloud.google.com/apis/api/sheets.googleapis.com/overview)\n- Google Drive API enabled in [Google Cloud Console](https://console.cloud.google.com/apis/api/drive.googleapis.com/overview)\n- OAuth 2.0 Client ID and Client Secret from your [Google Cloud Console Credentials](https://console.cloud.google.com/apis/credentials)\n"},"typeVersion":1},{"id":"4ddb7249-9785-4f51-b35c-b9a0c6a66e3b","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-1420,340],"parameters":{"color":7,"width":920,"height":700,"content":"## 1. 🗨️Generate video captions from ideas in a Google Sheet\n\n1. Setup your API keys for [PiAPI](https://piapi.ai/?via=n8n), [Eleven Labs](https://try.elevenlabs.io/n8n), and [Creatomate](https://creatomate.com/).\n- Once logged in to your Creatomate account, create a new video template and click \"source code\" in the top right. [Paste this JSON code](https://pastebin.com/c7aMTeLK). This will be your example template for this workflow.\n- In your Creatomate template, click the \"Use Template\" button in the top right and then click \"API Integration\" and you'll see your template_id. Set this value as your Creatomate Template ID in the Set API Keys node\n\n2. The next node will load a Google Sheet, you can copy the [Google Sheet Template](https://docs.google.com/spreadsheets/d/1cjd8p_yx-M-3gWLEd5TargtoB35cW-3y66AOTNMQrrM/edit?usp=sharing), simply choose File > Make a copy. Then in the Google Sheets node, connect to your copied sheet template.\n\n3. Next, we generate 5 captions for our video idea with OpenAI. You can edit this node to see the prompt and change it to your needs.\n\n4. In the final two nodes, we use custom javascript code to turn the OpenAI response into a list. Then, it validates to make sure the list was formed correctly (incase of an OpenAI failure to follow instructions)\n"},"typeVersion":1},{"id":"57ee2f8f-5371-4dab-b661-c58b25c7dd55","name":"Wait1","type":"n8n-nodes-base.wait","position":[980,700],"webhookId":"206d0cdf-b71f-44a7-909f-97df885c471a","parameters":{"unit":"minutes","amount":3},"typeVersion":1.1},{"id":"33781e51-ef30-437b-8499-94e39bfb38fa","name":"Get Final Video","type":"n8n-nodes-base.httpRequest","position":[1100,700],"parameters":{"url":"=https://api.creatomate.com/v1/renders/{{ $('Render Final Video').item.json.id }}","options":{},"sendHeaders":true,"headerParameters":{"parameters":[{"name":"Authorization","value":"=Bearer {{ $('Set API Keys').item.json['Creatomate API Key'] }}"},{"name":"Content-Type","value":"application/json"}]}},"executeOnce":true,"typeVersion":4.2},{"id":"b0d0fe6f-39c2-4da6-9fcf-b0151ed2c351","name":"Upload Final Video","type":"n8n-nodes-base.googleDrive","position":[1360,700],"parameters":{"name":"=POV-{{ $('Render Final Video').item.json.id }}.mp4","driveId":{"__rl":true,"mode":"list","value":"My Drive"},"options":{},"folderId":{"__rl":true,"mode":"list","value":"1w1EQ8xyth6w7AbX2wpDI3vInfYeRy8vH","cachedResultUrl":"https://drive.google.com/drive/folders/1w1EQ8xyth6w7AbX2wpDI3vInfYeRy8vH","cachedResultName":"Resume Studio"}},"credentials":{"googleDriveOAuth2Api":{"id":"ZvDuyVfbZJbDJXcS","name":"Google Drive account"}},"typeVersion":3},{"id":"3893d1de-7464-48ad-91a3-14b867c2a516","name":"Get Raw File","type":"n8n-nodes-base.httpRequest","position":[1220,700],"parameters":{"url":"={{ $json.url }}","options":{"response":{"response":{"responseFormat":"file"}}}},"typeVersion":4.2},{"id":"74de5f28-f081-4ec5-a47e-681eb845f701","name":"Set Permissions","type":"n8n-nodes-base.googleDrive","position":[1500,700],"parameters":{"fileId":{"__rl":true,"mode":"id","value":"={{ $json.id }}"},"options":{},"operation":"share","permissionsUi":{"permissionsValues":{"role":"writer","type":"anyone","allowFileDiscovery":true}}},"credentials":{"googleDriveOAuth2Api":{"id":"ZvDuyVfbZJbDJXcS","name":"Google Drive account"}},"typeVersion":3},{"id":"a2c07158-e949-4b5b-a92e-f4b021742831","name":"Update Google Sheet","type":"n8n-nodes-base.googleSheets","position":[1660,700],"parameters":{"columns":{"value":{"id":"={{ $('Load Google Sheet').first().json.id }}","width":"={{ $('Get Raw File').item.json.width }}","height":"={{ $('Get Raw File').item.json.height }}","model1":"={{ $('Generate Video Captions').item.json.model }}","model2":"={{ $('Pair Videos with Audio').item.json.model }}","model3":"={{ $('Generate Script').item.json.model }}","duration":"={{ $('Get Raw File').item.json.duration }}","fluxCost":"0.075","frameRate":"={{ $('Get Raw File').item.json.frame_rate }}","klingCost":"2.3","production":"done","publishing":"for publishing","final_output":"={{ $('Upload Final Video').item.json.webContentLink }}","prompt1 input tokens":"={{ $('Generate Video Captions').item.json.usage.prompt_tokens }}","prompt2 input tokens":"={{ $('Pair Videos with Audio').item.json.input_tokens }}","prompt3 input tokens":"={{ $('Generate Script').item.json.usage.prompt_tokens }}","prompt1 output tokens":"={{ $('Generate Video Captions').item.json.usage.completion_tokens }}","prompt2 output tokens":"={{ $('Pair Videos with Audio').item.json.output_tokens }}","prompt3 output tokens":"={{ $('Generate Script').item.json.usage.completion_tokens }}"},"schema":[{"id":"id","type":"string","display":true,"removed":false,"required":false,"displayName":"id","defaultMatch":true,"canBeUsedToMatch":true},{"id":"idea","type":"string","display":true,"removed":false,"required":false,"displayName":"idea","defaultMatch":false,"canBeUsedToMatch":true},{"id":"caption","type":"string","display":true,"removed":false,"required":false,"displayName":"caption","defaultMatch":false,"canBeUsedToMatch":true},{"id":"production","type":"string","display":true,"removed":false,"required":false,"displayName":"production","defaultMatch":false,"canBeUsedToMatch":true},{"id":"environment_prompt","type":"string","display":true,"removed":false,"required":false,"displayName":"environment_prompt","defaultMatch":false,"canBeUsedToMatch":true},{"id":"publishing","type":"string","display":true,"removed":false,"required":false,"displayName":"publishing","defaultMatch":false,"canBeUsedToMatch":true},{"id":"final_output","type":"string","display":true,"removed":false,"required":false,"displayName":"final_output","defaultMatch":false,"canBeUsedToMatch":true},{"id":"width","type":"string","display":true,"removed":false,"required":false,"displayName":"width","defaultMatch":false,"canBeUsedToMatch":true},{"id":"height","type":"string","display":true,"removed":false,"required":false,"displayName":"height","defaultMatch":false,"canBeUsedToMatch":true},{"id":"duration","type":"string","display":true,"removed":false,"required":false,"displayName":"duration","defaultMatch":false,"canBeUsedToMatch":true},{"id":"frameRate","type":"string","display":true,"removed":false,"required":false,"displayName":"frameRate","defaultMatch":false,"canBeUsedToMatch":true},{"id":"model1","type":"string","display":true,"removed":false,"required":false,"displayName":"model1","defaultMatch":false,"canBeUsedToMatch":true},{"id":"prompt1 input tokens","type":"string","display":true,"removed":false,"required":false,"displayName":"prompt1 input tokens","defaultMatch":false,"canBeUsedToMatch":true},{"id":"prompt1 output tokens","type":"string","display":true,"removed":false,"required":false,"displayName":"prompt1 output tokens","defaultMatch":false,"canBeUsedToMatch":true},{"id":"model1 cost","type":"string","display":true,"removed":false,"required":false,"displayName":"model1 cost","defaultMatch":false,"canBeUsedToMatch":true},{"id":"model2","type":"string","display":true,"removed":false,"required":false,"displayName":"model2","defaultMatch":false,"canBeUsedToMatch":true},{"id":"prompt2 input tokens","type":"string","display":true,"removed":false,"required":false,"displayName":"prompt2 input tokens","defaultMatch":false,"canBeUsedToMatch":true},{"id":"prompt2 output tokens","type":"string","display":true,"removed":false,"required":false,"displayName":"prompt2 output tokens","defaultMatch":false,"canBeUsedToMatch":true},{"id":"model2 cost","type":"string","display":true,"removed":false,"required":false,"displayName":"model2 cost","defaultMatch":false,"canBeUsedToMatch":true},{"id":"model3","type":"string","display":true,"removed":false,"required":false,"displayName":"model3","defaultMatch":false,"canBeUsedToMatch":true},{"id":"prompt3 input tokens","type":"string","display":true,"removed":false,"required":false,"displayName":"prompt3 input tokens","defaultMatch":false,"canBeUsedToMatch":true},{"id":"prompt3 output tokens","type":"string","display":true,"removed":false,"required":false,"displayName":"prompt3 output tokens","defaultMatch":false,"canBeUsedToMatch":true},{"id":"model3 cost","type":"string","display":true,"removed":false,"required":false,"displayName":"model3 cost","defaultMatch":false,"canBeUsedToMatch":true},{"id":"cmCost","type":"string","display":true,"removed":false,"required":false,"displayName":"cmCost","defaultMatch":false,"canBeUsedToMatch":true},{"id":"upgradeCmCost","type":"string","display":true,"removed":false,"required":false,"displayName":"upgradeCmCost","defaultMatch":false,"canBeUsedToMatch":true},{"id":"fluxCost","type":"string","display":true,"removed":false,"required":false,"displayName":"fluxCost","defaultMatch":false,"canBeUsedToMatch":true},{"id":"klingCost","type":"string","display":true,"removed":false,"required":false,"displayName":"klingCost","defaultMatch":false,"canBeUsedToMatch":true},{"id":"totalCost","type":"string","display":true,"removed":false,"required":false,"displayName":"totalCost","defaultMatch":false,"canBeUsedToMatch":true},{"id":"datePosted","type":"string","display":true,"removed":false,"required":false,"displayName":"datePosted","defaultMatch":false,"canBeUsedToMatch":true},{"id":"row_number","type":"string","display":true,"removed":true,"readOnly":true,"required":false,"displayName":"row_number","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["id"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"update","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1cjd8p_yx-M-3gWLEd5TargtoB35cW-3y66AOTNMQrrM/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1cjd8p_yx-M-3gWLEd5TargtoB35cW-3y66AOTNMQrrM","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1cjd8p_yx-M-3gWLEd5TargtoB35cW-3y66AOTNMQrrM/edit?usp=drivesdk","cachedResultName":"Sheet Template"}},"credentials":{"googleSheetsOAuth2Api":{"id":"CkBO4U0JY0QvkimY","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"62423325-f9da-4cdf-8864-c011fb4fa14f","name":"Set API Keys","type":"n8n-nodes-base.set","notes":"SET BEFORE STARTING","position":[-1320,780],"parameters":{"options":{},"assignments":{"assignments":[{"id":"35659353-d8e2-4677-876b-401b549605a0","name":"PiAPI Key","type":"string","value":""},{"id":"c4927dd6-c597-48fe-b7c1-bbffcf5ff02f","name":"ElevenLabs API Key","type":"string","value":""},{"id":"f5e90c05-dd24-4918-9005-4c87a4fb344d","name":"Creatomate API Key","type":"string","value":""},{"id":"d0ebba50-5a99-4090-adcb-d18aa0b21be2","name":"Creatomate Template ID","type":"string","value":""}]}},"notesInFlow":true,"typeVersion":3.4},{"id":"4252d793-5f16-4d5e-bb78-9b155aef5d3e","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-1380,720],"parameters":{"color":3,"width":220,"height":220,"content":"## DO THIS FIRST\n"},"typeVersion":1},{"id":"845d5b4a-8a3f-4d0d-afce-39aa4e349a7b","name":"Validate list formatting","type":"n8n-nodes-base.if","position":[-660,840],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"2681c0e9-aa45-4f0f-8933-6e6de324c7aa","operator":{"type":"array","operation":"lengthGt","rightType":"number"},"leftValue":"={{$input.all()}}","rightValue":1}]}},"typeVersion":2.2}],"active":false,"pinData":{},"settings":{"timezone":"America/Los_Angeles","callerPolicy":"workflowsFromSameOwner","executionOrder":"v1"},"versionId":"3c7215ae-325c-49e5-865d-78eba07c625c","connections":{"Wait1":{"main":[[{"node":"Get Final Video","type":"main","index":0}]]},"Get Video":{"main":[[{"node":"Fail check","type":"main","index":0}]]},"Get image":{"main":[[{"node":"Check for failures","type":"main","index":0}]]},"Wait 3min":{"main":[[{"node":"Get image","type":"main","index":0}]]},"Wait 5min":{"main":[[{"node":"Generate Image","type":"main","index":0}]]},"Fail check":{"main":[[{"node":"Wait to retry","type":"main","index":0}],[{"node":"Match captions with videos","type":"main","index":1}]]},"Wait 10min":{"main":[[{"node":"Get Video","type":"main","index":0}]]},"Create List":{"main":[[{"node":"Validate list formatting","type":"main","index":0}]]},"Get Raw File":{"main":[[{"node":"Upload Final Video","type":"main","index":0}]]},"Once Per Day":{"main":[[{"node":"Set API Keys","type":"main","index":0}]]},"Set API Keys":{"main":[[{"node":"Load Google Sheet","type":"main","index":0}]]},"List Elements":{"main":[[{"node":"Pair Videos with Audio","type":"main","index":0}]]},"Wait to retry":{"main":[[{"node":"Image-to-Video","type":"main","index":0}]]},"Generate Image":{"main":[[{"node":"Wait 3min","type":"main","index":0}]]},"Generate voice":{"main":[[{"node":"Upload Voice Audio","type":"main","index":0}]]},"Image-to-Video":{"main":[[{"node":"Wait 10min","type":"main","index":0}]]},"List Elements1":{"main":[[{"node":"Pair Videos with Audio","type":"main","index":1}]]},"Generate Script":{"main":[[{"node":"Generate voice","type":"main","index":0}]]},"Get Final Video":{"main":[[{"node":"Get Raw File","type":"main","index":0}]]},"Set Permissions":{"main":[[{"node":"Update Google Sheet","type":"main","index":0}]]},"Load Google Sheet":{"main":[[{"node":"Generate Video Captions","type":"main","index":0}]]},"Check for failures":{"main":[[{"node":"Wait 5min","type":"main","index":0}],[{"node":"Image-to-Video","type":"main","index":0}]]},"Render Final Video":{"main":[[{"node":"Wait1","type":"main","index":0}]]},"Upload Final Video":{"main":[[{"node":"Set Permissions","type":"main","index":0}]]},"Upload Voice Audio":{"main":[[{"node":"Set Access Permissions","type":"main","index":0}]]},"Update Google Sheet":{"main":[[{"node":"Notify me on Discord","type":"main","index":0}]]},"Calculate Token Usage":{"main":[[{"node":"Generate Image","type":"main","index":0}]]},"Generate Image Prompts":{"main":[[{"node":"Calculate Token Usage","type":"main","index":0}]]},"Pair Videos with Audio":{"main":[[{"node":"Render Final Video","type":"main","index":0}]]},"Set Access Permissions":{"main":[[{"node":"List Elements1","type":"main","index":0}]]},"Generate Video Captions":{"main":[[{"node":"Create List","type":"main","index":0}]]},"Validate list formatting":{"main":[[{"node":"Generate Image Prompts","type":"main","index":0},{"node":"Match captions with videos","type":"main","index":0},{"node":"Generate Script","type":"main","index":0}],[{"node":"Generate Video Captions","type":"main","index":0}]]},"Match captions with videos":{"main":[[{"node":"List Elements","type":"main","index":0}]]}}}


name: ✨🩷Automated Social Media Content Publishing Factory + System Prompt Composition
author_name: Joseph LePage
author_username: joe
categories: []
created_at: 2025-03-11T16:46:06.931Z
updated_at: 2025-03-11T16:46:06.931Z
url: https://n8n.io/workflows/3135
scraped_at: 2025-06-19 22:07:56
description:
  Social Media Content Publishing Factory for Streamlined Content Creation Across Platforms

  Who is this for?
  This workflow is designed for content creators, social media managers, and marketing teams who need to efficiently create and publish content across multiple social media platforms. It's perfect for businesses looking to maintain a consistent presence across X (Twitter), Instagram, Facebook, LinkedIn, Threads, and YouTube Shorts without spending hours crafting platform-specific content manually.

  What problem is this workflow solving?
  Creating tailored content for different social media platforms is time-consuming and requires understanding each platform's unique requirements and audience expectations. This workflow solves the challenge of:
  Maintaining consistent messaging across platforms while respecting platform-specific formats
  Generating optimized content that follows best practices for each platform
  Creating accompanying visuals without graphic design skills
  Streamlining the approval process before publishing
  Reducing the time spent on repetitive content creation tasks

  What this workflow does
  This automated content factory takes your content idea and transforms it into platform-optimized posts for all major social media channels. The workflow:

  Accepts your content idea or topic through a chat interface
  Leverages AI to generate tailored content for each platform (X/Twitter, Instagram, Facebook, LinkedIn, Threads, YouTube Shorts)
  Creates appropriate images using AI image generation
  Sends content for approval via email before publishing
  Publishes approved content to selected platforms
  Maintains chat memory to improve future content generation

  Setup
  Connect your social media platform credentials (X/Twitter, Instagram, Facebook, LinkedIn)
  Set up your email account for the approval process
  Configure your OpenAI API key for AI content generation
  Update the image generation service credentials (Pollinations.ai is used by default)
  Customize the system prompts and schemas in the Google Docs nodes with your brand voice and content requirements

  How to customize this workflow to your needs
  Modify the system prompts in the Google Docs nodes to match your brand voice and content strategy
  Adjust the social media schemas to include specific fields relevant to your content
  Update the approval process to include additional stakeholders if needed
  Add or remove social media platforms based on your marketing strategy
  Customize the image generation prompts to better match your visual branding
  Integrate with your existing content calendar or CRM systems

  This workflow eliminates the need to manually craft different versions of the same content for each platform, saving hours of work while ensuring your social media presence remains consistent and optimized for maximum engagement.

nodes_used:
  ["n8n-nodes-base.httpRequest","n8n-nodes-base.telegram","n8n-nodes-base.googleDrive","n8n-nodes-base.facebookGraphApi","n8n-nodes-base.twitter","n8n-nodes-base.gmail","n8n-nodes-base.linkedIn","n8n-nodes-base.googleDocs","n8n-nodes-base.code","@n8n/n8n-nodes-langchain.agent","@n8n/n8n-nodes-langchain.lmChatOpenAi","@n8n/n8n-nodes-langchain.memoryBufferWindow","@n8n/n8n-nodes-langchain.toolSerpApi","@n8n/n8n-nodes-langchain.toolWorkflow"]

workflow_json:
  {"id":"0KZs18Ti2KXKoLIr","meta":{"instanceId":"31e69f7f4a77bf465b805824e303232f0227212ae922d12133a0f96ffeab4fef","templateCredsSetupCompleted":true},"name":"✨🩷Automated Social Media Content Publishing Factory + System Prompt Composition","tags":[],"nodes":[{"id":"74fb48a6-1acd-4693-9b8e-39b36c5649a9","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[-520,-2080],"webhookId":"faddb40a-7048-4398-a0f9-d239a19c32ce","parameters":{"options":{}},"typeVersion":1.1},{"id":"09f4a998-2d69-4683-9251-2694a77efeba","name":"Sticky Note20","type":"n8n-nodes-base.stickyNote","position":[-600,-1720],"parameters":{"color":7,"height":240,"content":"## LLM"},"typeVersion":1},{"id":"03b93e0b-a917-41f6-b99e-5a27ad07cd3e","name":"Sticky Note21","type":"n8n-nodes-base.stickyNote","position":[-600,-1460],"parameters":{"color":7,"height":240,"content":"## Chat Memory"},"typeVersion":1},{"id":"b6c61fe5-a519-4bdb-8641-3149362fbb54","name":"Sticky Note22","type":"n8n-nodes-base.stickyNote","position":[-620,-2160],"parameters":{"color":4,"width":300,"height":280,"content":"## 👍Start Here"},"typeVersion":1},{"id":"2cf0448a-76de-4b2c-a200-953d47e29a52","name":"Sticky Note32","type":"n8n-nodes-base.stickyNote","position":[1980,-2000],"parameters":{"color":2,"width":340,"height":420,"content":"## Social Media Publishing Router"},"typeVersion":1},{"id":"dff757e6-8ef4-4479-a9f8-71cb814fb8ef","name":"Sticky Note33","type":"n8n-nodes-base.stickyNote","position":[-300,-1640],"parameters":{"color":6,"height":240,"content":"## 1️⃣ X - Twitter"},"typeVersion":1},{"id":"fda64627-952a-4be9-b4c5-799d8c7801ad","name":"X-Twiter","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[-220,-1540],"parameters":{"name":"create_x_twitter_posts_tool","fields":{"values":[{"name":"route","stringValue":"=xtwitter"},{"name":"user_prompt","stringValue":"={{ $('When chat message received').item.json.chatInput }}"}]},"workflowId":{"__rl":true,"mode":"id","value":"={{ $workflow.id }}"},"description":"Use this tool to create XTwitter posts","jsonSchemaExample":""},"typeVersion":1.2},{"id":"5023b0b3-468b-4cbb-829c-e06aaf822b99","name":"Sticky Note34","type":"n8n-nodes-base.stickyNote","position":[-40,-1640],"parameters":{"color":6,"height":240,"content":"## 2️⃣ Instagram"},"typeVersion":1},{"id":"781df8c5-0b06-42a4-bbe9-6948ae345599","name":"Instagram","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[40,-1540],"parameters":{"name":"create_instagram_posts_tool","fields":{"values":[{"name":"route","stringValue":"=instagram"},{"name":"user_prompt","stringValue":"={{ $('When chat message received').item.json.chatInput }}"}]},"workflowId":{"__rl":true,"mode":"id","value":"={{ $workflow.id }}"},"description":"Use this tool to create Instagram posts","jsonSchemaExample":""},"typeVersion":1.2},{"id":"8687d1ff-06ee-44c7-a26e-f08da72bbd15","name":"Window Buffer Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[-520,-1360],"parameters":{},"typeVersion":1.3},{"id":"30cbcc50-e19b-43ea-8f0a-5e2021dc5e48","name":"When Executed by Another Workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[-700,-560],"parameters":{"workflowInputs":{"values":[{"name":"user_prompt"},{"name":"route"}]}},"typeVersion":1.1},{"id":"0b9b7f07-d603-4890-96b0-f815feb38185","name":"Sticky Note35","type":"n8n-nodes-base.stickyNote","position":[220,-1640],"parameters":{"color":6,"height":240,"content":"## 3️⃣ Facebook"},"typeVersion":1},{"id":"12b17b82-8f98-4d80-9b49-aa9860827e01","name":"Sticky Note36","type":"n8n-nodes-base.stickyNote","position":[480,-1640],"parameters":{"color":6,"height":240,"content":"## 4️⃣ LinkedIn"},"typeVersion":1},{"id":"71dc9ccf-3691-4c0d-b53b-f3ff10f382a9","name":"Facebook","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[300,-1540],"parameters":{"name":"create_facebook_posts_tool","fields":{"values":[{"name":"route","stringValue":"=facebook"},{"name":"user_prompt","stringValue":"={{ $('When chat message received').item.json.chatInput }}"}]},"workflowId":{"__rl":true,"mode":"id","value":"={{ $workflow.id }}"},"description":"Use this tool to create Facebook posts","jsonSchemaExample":""},"typeVersion":1.2},{"id":"f953cd87-88a8-451f-841e-78227949b64d","name":"LinkedIn","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[560,-1540],"parameters":{"name":"create_linkedin_posts_tool","fields":{"values":[{"name":"route","stringValue":"=linkedin"},{"name":"user_prompt","stringValue":"={{ $('When chat message received').item.json.chatInput }}"}]},"workflowId":{"__rl":true,"mode":"id","value":"={{ $workflow.id }}"},"description":"Use this tool to create LinkedIn posts","jsonSchemaExample":""},"typeVersion":1.2},{"id":"97b6829d-6c9d-410a-8fa0-d89d884fd76e","name":"Sticky Note37","type":"n8n-nodes-base.stickyNote","position":[-40,-1380],"parameters":{"color":6,"height":240,"content":"## 5️⃣Threads"},"typeVersion":1},{"id":"463259f7-71b4-492f-b05a-d1a958917d5c","name":"Sticky Note38","type":"n8n-nodes-base.stickyNote","position":[220,-1380],"parameters":{"color":6,"height":240,"content":"## 6️⃣YouTube Shorts"},"typeVersion":1},{"id":"0cd9003b-8eeb-4e4a-9f1f-5f6b611d5194","name":"Short","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[40,-1280],"parameters":{"name":"create_threads_posts_tool","fields":{"values":[{"name":"route","stringValue":"=threads"},{"name":"user_prompt","stringValue":"={{ $('When chat message received').item.json.chatInput }}"}]},"workflowId":{"__rl":true,"mode":"id","value":"={{ $workflow.id }}"},"description":"Use this tool to create Threads posts","jsonSchemaExample":""},"typeVersion":1.2},{"id":"54c2bf4b-8053-4e9d-beb4-570db66f9bd4","name":"YouTube Short","type":"@n8n/n8n-nodes-langchain.toolWorkflow","position":[300,-1280],"parameters":{"name":"create_youtube_short_tool","fields":{"values":[{"name":"route","stringValue":"=youtube_short"},{"name":"user_prompt","stringValue":"={{ $('When chat message received').item.json.chatInput }}"},{"name":"llm","stringValue":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Value', ``, 'string') }}"}]},"workflowId":{"__rl":true,"mode":"id","value":"={{ $workflow.id }}"},"description":"Use this tool to create a YouTube short","jsonSchemaExample":""},"typeVersion":1.2},{"id":"a72c3242-3a8b-444f-9623-fbcb0b47a817","name":"Sticky Note18","type":"n8n-nodes-base.stickyNote","position":[-340,-1720],"parameters":{"color":7,"width":1100,"height":620,"content":"## Social Media Agent Tools"},"typeVersion":1},{"id":"586a33ae-3546-4b31-9235-9a8fcfd28598","name":"Sticky Note25","type":"n8n-nodes-base.stickyNote","position":[-500,-940],"parameters":{"color":6,"width":3520,"height":820,"content":"# 🏭Social Media Content Factory"},"typeVersion":1},{"id":"153da903-fcd3-4694-aaa4-bef2b300d158","name":"pollinations.ai1","type":"n8n-nodes-base.httpRequest","onError":"continueErrorOutput","maxTries":5,"position":[1440,-560],"parameters":{"url":"=https://image.pollinations.ai/prompt/{{ $json.output.common_schema.image_suggestion.replaceAll(' ','-').replaceAll(',','').replaceAll('.','').slice(0,100) }}","options":{}},"retryOnFail":true,"typeVersion":4.2},{"id":"6c114f0b-1395-4fe6-8de7-0b3d0d9fd6b2","name":"Sticky Note26","type":"n8n-nodes-base.stickyNote","position":[1340,-720],"parameters":{"color":7,"width":300,"height":340,"content":"## Create Post Image\nhttps://pollinations.ai/\nhttps://image.pollinations.ai/prompt/[your image description]\n\n"},"typeVersion":1},{"id":"e196ea9b-f5d0-4fa6-a3d9-bea2f98fd872","name":"Save Image to imgbb.com","type":"n8n-nodes-base.httpRequest","position":[1760,-680],"parameters":{"url":"https://api.imgbb.com/1/upload","method":"POST","options":{"redirect":{"redirect":{}}},"sendBody":true,"sendQuery":true,"contentType":"multipart-form-data","bodyParameters":{"parameters":[{"name":"image","parameterType":"formBinaryData","inputDataFieldName":"data"}]},"queryParameters":{"parameters":[{"name":"expiration","value":"0"},{"name":"key","value":"={{ $env.IMGBB_API_KEY}} "}]}},"typeVersion":4.2},{"id":"225e34be-26ee-40d7-88d6-e866420e083a","name":"Sticky Note41","type":"n8n-nodes-base.stickyNote","position":[1980,-2280],"parameters":{"width":340,"height":180,"content":"💡Notes\n\nUpdate all Social Media Platform Credentials as required.\n\nAdjust parameters and content for each platform to suit your needs."},"typeVersion":1},{"id":"2f48f19d-92c1-478a-b7fa-3fc3b1100993","name":"Sticky Note42","type":"n8n-nodes-base.stickyNote","position":[1240,-1760],"parameters":{"color":4,"width":400,"height":360,"content":"# 👍 Approve Content Before Proceeding"},"typeVersion":1},{"id":"ce4e9f3c-801a-478e-8ffc-008c5e7d4e49","name":"Gmail","type":"n8n-nodes-base.gmail","position":[2640,-780],"webhookId":"cfc2a53d-14a7-47e1-8385-c0b0792d9843","parameters":{"sendTo":"={{ $env.TELEGRAM_CHAT_ID }}","message":"={{ $json.output }}","options":{"appendAttribution":false},"subject":"=Social Media Content - {{ $('Social Content').item.json.output.title }}"},"credentials":{"gmailOAuth2":{"id":"1xpVDEQ1yx8gV022","name":"Gmail account"}},"typeVersion":2.1},{"id":"31ee0735-c863-476c-9c4a-41b50ae9c61a","name":"Social Media Schema","type":"n8n-nodes-base.googleDocs","position":[-320,-700],"parameters":{"operation":"get","documentURL":"=12345"},"credentials":{"googleDocsOAuth2Api":{"id":"YWEHuG28zOt532MQ","name":"Google Docs account"}},"typeVersion":2},{"id":"18cfde4e-2637-496c-acca-070bdb84c2ba","name":"Social Media System Prompt","type":"n8n-nodes-base.googleDocs","position":[-320,-420],"parameters":{"operation":"get","documentURL":"=12345"},"credentials":{"googleDocsOAuth2Api":{"id":"YWEHuG28zOt532MQ","name":"Google Docs account"}},"typeVersion":2},{"id":"383ce472-ccf8-47fb-aa36-5b8aacbcd64f","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-440,-840],"parameters":{"color":7,"width":1120,"height":640,"content":"## Prompt & Schema Composition from External Sources"},"typeVersion":1},{"id":"8d2a2a64-bbaa-4692-94ed-2f541d0d40ca","name":"gpt-40-mini","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[2320,-600],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini","cachedResultName":"gpt-4o-mini"},"options":{"responseFormat":"text"}},"credentials":{"openAiApi":{"id":"jEMSvKmtYfzAkhe6","name":"OpenAi account"}},"typeVersion":1.2},{"id":"6e5faa4d-25a1-4dbe-998e-3255ed181ac5","name":"Instagram Image","type":"n8n-nodes-base.httpRequest","onError":"continueRegularOutput","position":[2440,-1940],"parameters":{"url":"https://graph.facebook.com/v20.0/[your-unique-id]/media","method":"POST","options":{},"sendQuery":true,"authentication":"predefinedCredentialType","queryParameters":{"parameters":[{"name":"image_url","value":"={{ $json.output.social_image.medium.url }}"},{"name":"caption","value":"={{ $json.output.caption }}"}]},"nodeCredentialType":"facebookGraphApi"},"credentials":{"facebookGraphApi":{"id":"PzDfmiwB7GPtmSaP","name":"Facebook Graph account"}},"typeVersion":4.2},{"id":"958793c8-7a74-498f-ac75-256232469fbc","name":"X Post","type":"n8n-nodes-base.twitter","onError":"continueRegularOutput","position":[2640,-2180],"parameters":{"text":"={{ $json.data.social_content.schema.post }}","additionalFields":{}},"credentials":{"twitterOAuth2Api":{"id":"wRDruLTCqjQ7C5jq","name":"X account"}},"typeVersion":2,"alwaysOutputData":true},{"id":"1f04a4b5-e97d-4574-abdb-270265da77fa","name":"Instragram Post","type":"n8n-nodes-base.facebookGraphApi","onError":"continueRegularOutput","position":[2640,-2000],"parameters":{"edge":"media_publish","node":"[your-unique-id]","options":{"queryParameters":{"parameter":[{"name":"creation_id","value":"={{ $json.id }}"},{"name":"caption","value":"={{ $('Social Media Publishing Router').item.json.output.caption }}"}]}},"graphApiVersion":"v20.0","httpRequestMethod":"POST"},"credentials":{"facebookGraphApi":{"id":"PzDfmiwB7GPtmSaP","name":"Facebook Graph account"}},"typeVersion":1,"alwaysOutputData":true},{"id":"92a917ff-d20d-4bbc-be8f-00e17be83ea2","name":"Facebook Post","type":"n8n-nodes-base.facebookGraphApi","onError":"continueRegularOutput","position":[2640,-1820],"parameters":{"edge":"photos","node":"[your-unique-id]","options":{"queryParameters":{"parameter":[{"name":"message","value":"={{ $json.output.post }}\n\n{{ $json.output.call_to_action }}\n"}]}},"sendBinaryData":true,"graphApiVersion":"v20.0","httpRequestMethod":"POST","binaryPropertyName":"data"},"credentials":{"facebookGraphApi":{"id":"PzDfmiwB7GPtmSaP","name":"Facebook Graph account"}},"typeVersion":1,"alwaysOutputData":true},{"id":"6c80332d-1aaf-4f3a-91fd-58c25f20ee0c","name":"LinkedIn Post","type":"n8n-nodes-base.linkedIn","onError":"continueRegularOutput","position":[2640,-1640],"parameters":{"text":"={{ $json.data.social_content.schema.post }}\n{{ $json.data.social_content.schema.call_to_action }}\n{{ $json.data.social_content.common_schema.hashtags }}\n","postAs":"organization","organization":"12345678","additionalFields":{},"binaryPropertyName":"=data","shareMediaCategory":"IMAGE"},"credentials":{"linkedInOAuth2Api":{"id":"WMm6pzAEgNd4wJdO","name":"LinkedIn account"}},"typeVersion":1,"alwaysOutputData":true},{"id":"f9d80261-8543-4a12-969c-eecd58513ef2","name":"Gmail User for Approval","type":"n8n-nodes-base.gmail","position":[1380,-1600],"webhookId":"abfae12d-ddcf-4981-ad33-bb7a8cc115a2","parameters":{"sendTo":"={{ $env.TELEGRAM_CHAT_ID }}","message":"={{ $json.output }}","options":{"limitWaitTime":{"values":{"resumeUnit":"minutes","resumeAmount":45}}},"subject":"=🔥FOR APPROVAL🔥 {{$('Extract as JSON').item.json.data.social_content.root_schema.name  }}","operation":"sendAndWait","approvalOptions":{"values":{"approvalType":"double"}}},"credentials":{"gmailOAuth2":{"id":"1xpVDEQ1yx8gV022","name":"Gmail account"}},"typeVersion":2.1},{"id":"97c2dec9-9e1e-4a42-9538-8a37392114e6","name":"Get Social Post Image","type":"n8n-nodes-base.httpRequest","position":[1640,-1340],"parameters":{"url":"={{ $('Extract as JSON').item.json.data.social_image.medium.url }}","options":{}},"retryOnFail":true,"typeVersion":4.2},{"id":"b5b6b7b9-d275-4c1a-a3c5-195b13be1538","name":"gpt-40-mini1","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[860,-1420],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini","cachedResultName":"gpt-4o-mini"},"options":{"responseFormat":"text"}},"credentials":{"openAiApi":{"id":"jEMSvKmtYfzAkhe6","name":"OpenAi account"}},"typeVersion":1.2},{"id":"0b5b8237-9e34-44b7-82d9-372a12c67546","name":"gpt-4o-mini","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[780,-360],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini","cachedResultName":"gpt-4o-mini"},"options":{"responseFormat":"json_object"}},"credentials":{"openAiApi":{"id":"jEMSvKmtYfzAkhe6","name":"OpenAi account"}},"typeVersion":1.2},{"id":"df61bbeb-1432-434b-9993-18362dba097f","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-1840,-1220],"parameters":{"color":5,"width":760,"height":1540,"content":"<system>\nYou are a specialized content creation AI for social media platforms.\nYour primary function is generating platform-optimized social media content across various platforms including LinkedIn, Instagram, Facebook, Twitter (X), Threads, and YouTube Shorts. Each piece of content must:\nMatch the specific platform's audience expectations and algorithm preferences\nShowcase relevant expertise in your field\nDeliver actionable insights for your target audience\nDrive meaningful engagement through value-driven content\nOBJECTIVES:\nCreate platform-specific content following each platform's best practices\nImplement strategic hashtag usage combining general and trending tags\nDesign content that encourages user interaction and community building\nMaintain consistent brand voice while adapting to platform requirements\nIncorporate data-driven insights to maximize content performance\nOUTPUT REQUIREMENTS:\nDeliver content in valid JSON format according to the platform-specific schema\nInclude all required fields as specified in the schema\nOmit any explanatory text or code fencing in your response\nTailor content specifically to the platform indicated in the user's request\nFor each content request, adapt your output based on the platform guidelines.  Never provide URLS for video or image suggestions and only describe the suggestion.\n</system>\n\n\n<rules>\nOnly provide final response in valid JSON for the appropriate social platform\nNever include any preamble or further explanation\nAlways remove any ``` ```json\n</rules>\n\n\n<linkedin>\n**Style**: Professional and insightful.\n**Tone**: Business-oriented; focus on automation use cases, industry insights, and community impact.\n**Content Length**: 3-4 sentences; concise but detailed.\n**Hashtags**: #Innovation #Automation #WorkflowSolutions #DigitalTransformation #Leadership\n**Call to Action (CTA)**: Encourage comments or visits to workflows.diy's website for more insights.\n</linkedin>\n\n<instagram>\n**Style**: Visual storytelling with creative captions.\n**Tone**: Inspirational and engaging; use emojis for relatability.\n**Content Length**: 2-3 sentences paired with eye-catching visuals (e.g., infographics or workflow demos).\n**Visuals**: Showcase milestones (e.g., new workflow launches), tutorials, or product highlights.\n**CTA**: Use phrases like \"Swipe to learn more,\" \"Tag your team,\" or \"Check out the link below!\"\n**Link Placement**: Add the provided link before hashtags; if no link is provided, use \"Visit our website: https://example.com\"\n**Hashtags**: #AutomationLife #TechInnovation #WorkflowTips #Programming #Engineering\n</instagram>\n\n<facebook>\n**Style**: Friendly and community-focused.\n**Tone**: Relatable; highlight user success stories or company achievements in automation.\n**Content Length**: 2-3 sentences; conversational yet professional.\n**Hashtags**: #SmallBusinessAutomation #Entrepreneurship #Leadership #WorkflowInnovation\n**CTA**: Encourage likes, shares, comments (e.g., \"What's your favorite automation tip?\").\n</facebook>\n\n<xtwitter>\n**Style**: Concise and impactful.\n**Tone**: Crisp and engaging; spark curiosity in 150 characters or less.\n**Hashtags**: #WorkflowTrends #AIWorkflows #AutomationTips #NoCodeSolutions\n**CTA**: Drive quick engagement through retweets or replies (e.g., \"What's your go-to n8n workflow?\").\n</xtwitter>\n\n<threads>\n**Style**: Conversational and community-driven posts.\n**Tone**: Casual yet informative; encourage discussions around automation trends or innovations.\n**Content Length**: 1-2 short paragraphs with a question or thought-provoking statement at the end.\n**Hashtags**: Similar to Instagram but tailored for trending Threads topics related to automation.\n</threads>\n\n<youtube_short>\n**Style**: Short-form video content showcasing quick workflow tutorials or use cases.\n**Tone**: Authoritative yet approachable; establish workflows.diy as a leader in n8n automation solutions.\n**Content Length**:\n  Tutorials/Reviews (long-form): 5-10 minutes\n  Shorts/Highlights (short-form): Under 1 minute\n**CTA**: Encourage subscriptions, likes, comments (e.g., \"Subscribe for more workflow tips!\").\n</youtube_short>\n\n\n\n\n"},"typeVersion":1},{"id":"ddf3d7d3-0218-4ba0-b990-34a6220a53fa","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-1060,-1220],"parameters":{"color":3,"height":1540,"content":"<common>\n{\n    \"type\": \"object\",\n    \"properties\": {\n        \"hashtags\": {\n            \"type\": \"array\",\n            \"items\": {\n                \"type\": \"string\"\n            }\n        },\n        \"image_suggestion\": {\n            \"type\": \"string\"\n        }\n    }\n}\n</common>\n\n<root>\n{\n    \"type\": \"object\",\n    \"properties\": {\n        \"name\": {\n            \"type\": \"string\"\n        },\n        \"description\": {\n            \"type\": \"string\"\n        },\n        \"additional_notes\": {\n            \"type\": \"string\"\n        }\n    }\n}\n</root>\n\n<linkedin>\n{\n    \"type\": \"object\",\n    \"properties\": {\n        \"post\": {\n            \"type\": \"string\"\n        },\n        \"call_to_action\": {\n            \"type\": \"string\"\n        }\n    }\n}\n</linkedin>\n\n<instagram>\n{\n    \"type\": \"object\",\n    \"properties\": {\n        \"caption\": {\n            \"type\": \"string\"\n        },\n        \"emojis\": {\n            \"type\": \"array\",\n            \"items\": {\n                \"type\": \"string\"\n            }\n        },\n        \"call_to_action\": {\n            \"type\": \"string\"\n        }\n    }\n}\n</instagram>\n\n<facebook>\n{\n    \"type\": \"object\",\n    \"properties\": {\n        \"post\": {\n            \"type\": \"string\"\n        },\n        \"call_to_action\": {\n            \"type\": \"string\"\n        }\n    }\n}\n</facebook>\n\n<xtwitter>\n{\n    \"type\": \"object\",\n    \"properties\": {\n        \"video_suggestion\": {\n            \"type\": \"string\"\n        },\n        \"post\": {\n            \"type\": \"string\"\n        },\n        \"character_limit\": {\n            \"type\": \"integer\"\n        }\n    }\n}\n</xtwitter>\n\n<threads>\n{\n    \"type\": \"object\",\n    \"properties\": {\n        \"text_post\": {\n            \"type\": \"string\"\n        },\n        \"call_to_action\": {\n            \"type\": \"string\"\n        }\n    }\n}\n</threads>\n\n<youtube_short>\n{\n    \"type\": \"object\",\n    \"properties\": {\n        \"video_suggestion\": {\n            \"type\": \"string\"\n        },\n        \"title\": {\n            \"type\": \"string\"\n        },\n        \"description\": {\n            \"type\": \"string\"\n        },\n        \"call_to_action\": {\n            \"type\": \"string\"\n        }\n    }\n}\n</youtube_short>\n\n\n\n"},"typeVersion":1},{"id":"72b378bd-6035-45da-8c76-ddd897d107c7","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-400,-480],"parameters":{"color":5,"width":260,"height":240,"content":"### 👈System Prompt"},"typeVersion":1},{"id":"ba60e52d-722a-4f07-86b4-f4ea64cb2bab","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-400,-760],"parameters":{"color":3,"width":260,"height":240,"content":"### 👈Social Media Schema"},"typeVersion":1},{"id":"bc1ff038-26ad-44d6-94d1-2c1f72a9bf87","name":"Schema","type":"n8n-nodes-base.set","position":[-60,-700],"parameters":{"options":{},"assignments":{"assignments":[{"id":"9d6d41f2-7216-4659-af34-7215298494d9","name":"schema","type":"string","value":"={{ $json.content }}"},{"id":"7d8c85f5-3f4a-4d72-bef0-0957c6ce82a4","name":"platform","type":"string","value":"={{ $('When Executed by Another Workflow').item.json.route }}"}]}},"typeVersion":3.4},{"id":"777d231c-f69c-4b48-bec5-6674175703bc","name":"System Prompt","type":"n8n-nodes-base.set","position":[-60,-420],"parameters":{"options":{},"assignments":{"assignments":[{"id":"5f789b37-b021-4cd4-b359-fdfbb9b71c2b","name":"system_prompt_doc_id","type":"string","value":"={{ $json.documentId }}"},{"id":"daac5758-38ad-4afe-966b-a9b4b89691b2","name":"system_prompt","type":"string","value":"={{ $json.content }}"}]}},"typeVersion":3.4},{"id":"3813a552-cf99-49ca-9617-7eaac56f6819","name":"Parse Schema","type":"n8n-nodes-base.code","position":[140,-700],"parameters":{"jsCode":"// Get the input data from previous node\nconst inputData = $input.first().json;\nconst xmlString = inputData.schema;\n\nconsole.log(inputData)\n\n// Function to extract content between XML tags with better regex handling\nfunction extractFromXmlTags(xmlString, tagName) {\n  const regex = new RegExp(`<${tagName}>(.*?)<\\/${tagName}>`, 'gs');\n  const match = regex.exec(xmlString);\n  return match ? match[1].trim() : null;\n}\n\n// Get the platform from the input or use a default\nconst platform = inputData.platform;\n\n// Extract the content from the specified tag\nconst extractedContent = extractFromXmlTags(xmlString, platform);\nconst rootContent = extractFromXmlTags(xmlString, 'root');\nconst commonContent = extractFromXmlTags(xmlString, 'common');\n\njsonData = JSON.parse(extractedContent);\nrootSchema = JSON.parse(rootContent);\ncommonSchema = JSON.parse(commonContent);\n\n// Return the result\nreturn {\n  json: {\n    schema: jsonData,\n    root_schema: rootSchema,\n    common_schema: commonSchema\n  }\n};\n"},"typeVersion":2},{"id":"c55da4a1-91f8-4d17-ad73-730013a99231","name":"Parse System Prompt","type":"n8n-nodes-base.code","position":[140,-420],"parameters":{"jsCode":"// Get the input data from previous node\nconst inputData = $input.first().json;\nconst xmlString = inputData.system_prompt;\n\n// Function to extract all content between XML tags\nfunction extractAllXmlTags(xmlString) {\n  // Create a result object to store tag contents\n  const result = {};\n  \n  // Regular expression to find all XML tags and their content\n  // This regex matches opening tag, content, and closing tag\n  const tagRegex = /<([^>\\/]+)>([\\s\\S]*?)<\\/\\1>/g;\n  \n  // Find all matches\n  let match;\n  while ((match = tagRegex.exec(xmlString)) !== null) {\n    const tagName = match[1].trim();\n    const content = match[2].trim();\n    \n    // Store the content with the tag name as the key\n    result[tagName] = content;\n  }\n  \n  return result;\n}\n\n// Extract all XML tags and their content\nconst extractedTags = extractAllXmlTags(xmlString);\n\n// Return the result as a JSON object\nreturn {\n  json: {\n    system_config: extractedTags\n  }\n};\n"},"typeVersion":2},{"id":"1767c787-943b-43d6-86cb-3fb60eaf878e","name":"Compose Prompt & Schema","type":"n8n-nodes-base.set","position":[520,-560],"parameters":{"options":{},"assignments":{"assignments":[{"id":"9216ad1c-a281-4c94-835d-e20507ef0cb5","name":"route","type":"string","value":"={{ $json.route }}"},{"id":"e6ca5cdf-5139-4db7-b065-ee52028216c5","name":"user_prompt","type":"string","value":"={{ $json.user_prompt }}"},{"id":"2927cd6f-c351-49df-954b-9f87b0338c58","name":"system_config.system","type":"string","value":"={{ $json.system_config.system }}"},{"id":"829b1519-9ffa-44d7-8caa-455e15b30614","name":"system_config.rules","type":"string","value":"={{ $json.system_config.rules }}"},{"id":"b44472ba-6e98-448b-bad6-e02da8b32b0a","name":"={{ $json.route }}","type":"string","value":"={{ $json.system_config[$json.route.toLowerCase()] }}"},{"id":"a96e8c30-1d44-4e23-9ef4-95d7303ea41e","name":"root_schema","type":"object","value":"={{ $json.root_schema }}"},{"id":"6cb68192-10f3-496d-88ca-289ee0c19940","name":"common_schema","type":"object","value":"={{ $json.common_schema }}"},{"id":"8f9b85f0-abaa-46c2-ba98-897f6a677105","name":"schema","type":"object","value":"={{ $json.schema }}"}]}},"typeVersion":3.4},{"id":"b7d78f57-ee83-4e03-ada6-fd6e2048c272","name":"Social Media Content Creator","type":"@n8n/n8n-nodes-langchain.agent","position":[800,-560],"parameters":{"text":"=Social Media Platform: {{ $json.route }}\nUser Prompt: {{ $json.user_prompt }}\n","options":{"systemMessage":"={{ $json.system_config.system }}\n\n<tools>\nYou have been provided with an internet search tool.  Use this tool to find relavent information about the users request before responding.  Todays date is: {{ $now }}\n</tools>\n\n<rules>\n{{ $json.system_config.rules }}\n- Output must conform to provided JSON schema\n</rules>\n\nFollow this Output JSON Schema:\n{\n  root_schema: {{ $json.root_schema.toJsonString() }},\n  common_schema: {{ $json.common_schema.toJsonString()}},\n  schema: {{  $json.schema.toJsonString() }}\n}"},"promptType":"define"},"typeVersion":1.7},{"id":"35469698-0eb5-4238-85d1-c67ccbacf2cb","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-1880,-1400],"parameters":{"color":7,"width":1100,"height":1760,"content":"# External System Prompt and Schema"},"typeVersion":1},{"id":"12b55edd-ff51-423b-a153-96a8a2a09678","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[2380,-2280],"parameters":{"color":6,"width":700,"height":1240,"content":"# 📄 Publish to Social Media "},"typeVersion":1},{"id":"78cd8af0-c10c-4bf5-8420-63061e7687bc","name":"Merge Prompts and Schema","type":"n8n-nodes-base.merge","position":[340,-560],"parameters":{"mode":"combine","options":{},"combineBy":"combineByPosition","numberInputs":3},"typeVersion":3},{"id":"e7a62296-729b-45df-bd15-002ccaae2fa0","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[720,-680],"parameters":{"width":400,"height":480,"content":"## Social Media Content Creator"},"typeVersion":1},{"id":"f6cb5a95-4047-4e41-a635-a73681fe6d8b","name":"Social Content","type":"n8n-nodes-base.set","position":[1180,-560],"parameters":{"options":{},"assignments":{"assignments":[{"id":"8c318996-aa79-4970-b8d7-33ae1931c8c6","name":"output","type":"object","value":"={{ $json.output }}"}]}},"typeVersion":3.4},{"id":"148df311-24db-4243-bc62-1a51579720d7","name":"Save Image to Google Drive","type":"n8n-nodes-base.googleDrive","position":[1760,-480],"parameters":{"name":"={{ $json.output.root_schema.name.replaceAll(' ','-').replaceAll(',','').replaceAll('.','') }}","driveId":{"__rl":true,"mode":"id","value":"=My Drive"},"options":{},"folderId":{"__rl":true,"mode":"id","value":"=12345"}},"credentials":{"googleDriveOAuth2Api":{"id":"UhdXGYLTAJbsa0xX","name":"Google Drive account"}},"typeVersion":3},{"id":"f84ab889-d193-4d9a-8e8b-4f35805edaa4","name":"Merge","type":"n8n-nodes-base.merge","position":[1980,-560],"parameters":{"mode":"combine","options":{"includeUnpaired":true},"combineBy":"combineByPosition","numberInputs":3},"typeVersion":3},{"id":"ca43646b-ca79-4ff6-ac02-da4f668e7aeb","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[2200,-880],"parameters":{"color":7,"width":660,"height":420,"content":"## Send Social Media Image and Post Contents to Gmail\n(optional)"},"typeVersion":1},{"id":"cf7bda38-260f-42c0-b60a-6a93181712de","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[2120,-420],"parameters":{"color":7,"width":840,"height":260,"content":"## Prepare Social Media Post and Save to Google Drive"},"typeVersion":1},{"id":"13cafb9c-5f04-4193-8f0e-0384f68d5e45","name":"Save Social Post to Google Drive","type":"n8n-nodes-base.googleDrive","position":[2560,-340],"parameters":{"name":"={{ $json.response.google_drive_image.id }}","content":"={{ $json.response.toJsonString() }}","driveId":{"__rl":true,"mode":"list","value":"My Drive"},"options":{},"folderId":{"__rl":true,"mode":"id","value":"= 12345"},"operation":"createFromText"},"credentials":{"googleDriveOAuth2Api":{"id":"UhdXGYLTAJbsa0xX","name":"Google Drive account"}},"typeVersion":3},{"id":"2bdecf8d-e180-4795-92c2-6158adf71daf","name":"Google Drive Image Meta","type":"n8n-nodes-base.set","position":[2200,-340],"parameters":{"options":{},"assignments":{"assignments":[{"id":"769d86e6-3764-4023-8932-f25f7d4fe34a","name":"id","type":"string","value":"={{ $json.id }}"},{"id":"4ccae0cc-d246-477c-9e94-3be461134d01","name":"webContentLink","type":"string","value":"={{ $json.webContentLink }}"},{"id":"74e22694-c7e6-4598-8e87-8ea6ae00144e","name":"webViewLink","type":"string","value":"={{ $json.webViewLink }}"},{"id":"e8eedbbf-7d42-475b-a748-0afbe8b730da","name":"thumbnailLink","type":"string","value":"={{ $json.thumbnailLink }}"}]}},"typeVersion":3.4},{"id":"d6e4902a-af19-45a4-8253-432135e17998","name":"Social Post JSON","type":"n8n-nodes-base.set","position":[2380,-340],"parameters":{"options":{},"assignments":{"assignments":[{"id":"b705af39-d286-4461-956c-d963ea151734","name":"response","type":"object","value":"={ \n  \"route\": \"{{ $('When Executed by Another Workflow').item.json.route }}\",\n \"social_image\": {{ $('Merge').item.json.data.toJsonString()  }},\n  \"social_content\": {{ $('Social Content').item.json.output.toJsonString() }},\n  \"google_drive_image\": {{ $json.toJsonString() }}\n}"}]}},"typeVersion":3.4},{"id":"b35623e6-9ddc-4091-905f-7b485efc5d60","name":"Respond with Google Drive Id","type":"n8n-nodes-base.set","position":[2740,-340],"parameters":{"options":{},"assignments":{"assignments":[{"id":"ad353ca7-059a-4108-88b9-fb92720a34fe","name":"response","type":"string","value":"={{ $json.id }}"}]}},"typeVersion":3.4},{"id":"410c3924-1011-480d-874c-a395c243f4c6","name":"Telegram Success Message (Optional)","type":"n8n-nodes-base.telegram","position":[1760,-880],"webhookId":"93342863-02c0-42ee-98c3-a2ec72b3bf12","parameters":{"text":"Image created successfully","chatId":"={{ $env.TELEGRAM_CHAT_ID }}","additionalFields":{"appendAttribution":false}},"credentials":{"telegramApi":{"id":"pAIFhguJlkO3c7aQ","name":"Telegram account"}},"typeVersion":1.2},{"id":"eba8445d-55da-43e2-b2aa-4822168a70ea","name":"Telegram Error Message (Optional)","type":"n8n-nodes-base.telegram","position":[1760,-300],"webhookId":"93342863-02c0-42ee-98c3-a2ec72b3bf12","parameters":{"text":"Error creating image (Debugging)","chatId":"={{ $env.TELEGRAM_CHAT_ID }}","additionalFields":{"appendAttribution":false}},"credentials":{"telegramApi":{"id":"pAIFhguJlkO3c7aQ","name":"Telegram account"}},"typeVersion":1.2},{"id":"af2c4945-0dac-4398-b8ad-329066eefedd","name":"Social Media Publishing Router","type":"n8n-nodes-base.switch","position":[2080,-1900],"parameters":{"rules":{"values":[{"outputKey":"1️⃣X-Twitter","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.data.route }}","rightValue":"xtwitter"}]},"renameOutput":true},{"outputKey":" 2️⃣Instagram","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"86d44336-bab7-422f-9266-fcb513252d19","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.data.route }}","rightValue":"instagram"}]},"renameOutput":true},{"outputKey":" 3️⃣Facebook","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"29f37628-6381-46af-babb-74bf00b4a849","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.data.route }}","rightValue":"facebook"}]},"renameOutput":true},{"outputKey":"4️⃣Linkedin","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"fdb7c8aa-4108-43f6-8f6b-71cd8f383d2a","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.data.route }}","rightValue":"=linkedin"}]},"renameOutput":true},{"outputKey":"5️⃣Threads","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"956baedd-4a0b-4e41-b85c-ef2c84332bdc","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.data.route }}","rightValue":"threads"}]},"renameOutput":true},{"outputKey":"6️⃣YouTube Short","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"4d690442-197c-4ff9-b176-b55dfabaecc9","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.data.route }}","rightValue":"youtube_short"}]},"renameOutput":true}]},"options":{}},"typeVersion":3.2},{"id":"682ee752-8e7f-4ee5-b617-88d7c1f7d4e7","name":"Prepare Email Contents","type":"@n8n/n8n-nodes-langchain.agent","position":[880,-1600],"parameters":{"text":"=Use the HTML template and populate [fields] as required from this: {{ $json.data.social_content.toJsonString() }}\n-----\nOnly output HTML without code block tags, preamble or further explanation in the format provided.\n\n## HTML Template\n<table style=\"max-width:640px;min-width:320px;width:100%;border-collapse:collapse;font-family:Arial,sans-serif;margin:20px auto\">\n    <tbody>\n        <tr>\n            <td colspan=\"2\" style=\"background-color:#ffffff;padding:15px;text-align:left\">\n                <img src=\"{{ $json.data.google_drive_image.thumbnailLink }}\" alt=\"{{ $json.data.social_content.root_schema.name }}\" style=\"max-width:100%;height:auto;\">\n            </td>\n        </tr>\n        <tr>\n            <td colspan=\"2\" style=\"background-color:#efefef;padding:15px;font-size:20px;text-align:left;font-weight:bold\">\n                {{ $json.data.social_content.root_schema.name }}\n            </td>\n        </tr>\n        <tr>\n            <td style=\"background-color:#f9f9f9;padding:15px;width:30%;text-align:left\"><strong>[label_1]:</strong></td>\n            <td style=\"background-color:#f9f9f9;padding:15px;text-align:left\">[content_1]</td>\n        </tr>\n        <tr>\n            <td style=\"background-color:#f1f1f1;padding:15px;text-align:left\"><strong>[label_2]:</strong></td>\n            <td style=\"background-color:#f1f1f1;padding:15px;text-align:left\">[content_2]</td>\n        </tr>\n\n        [continue the pattern ...]\n\n        <tr>\n            <td colspan=\"2\" style=\"background-color:#efefef;padding:15px;text-align:left\">\n                <strong>[footer_label]:</strong> [footer_content]\n            </td>\n        </tr>\n    </tbody>\n</table>\n\n","options":{},"promptType":"define"},"typeVersion":1.7},{"id":"eeab0159-cb24-4653-ba14-461740c8753c","name":"Is Approved?","type":"n8n-nodes-base.if","position":[1380,-1340],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"313cec9b-aad5-4f9c-a209-afe83af53df0","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.data.approved }}","rightValue":""}]}},"typeVersion":2.2},{"id":"dbe7cd63-9ec0-46cd-9255-8c1dc738847d","name":"File Id","type":"n8n-nodes-base.set","position":[1200,-2080],"parameters":{"options":{},"assignments":{"assignments":[{"id":"efb1c03b-8465-443d-a442-b76b8cd86a73","name":"output","type":"object","value":"={{ $json.output }}"}]}},"typeVersion":3.4},{"id":"cdb01e90-c54c-4ae4-87e2-75a3baec2295","name":"Get Social Post from Google Drive","type":"n8n-nodes-base.googleDrive","position":[1380,-2080],"parameters":{"fileId":{"__rl":true,"mode":"id","value":"={{ $json.output.response }}"},"options":{},"operation":"download"},"credentials":{"googleDriveOAuth2Api":{"id":"UhdXGYLTAJbsa0xX","name":"Google Drive account"}},"typeVersion":3},{"id":"aea6ec59-fcf4-4b5a-9fbc-86d9eb834388","name":"Extract as JSON","type":"n8n-nodes-base.extractFromFile","position":[1560,-2080],"parameters":{"options":{},"operation":"fromJson"},"typeVersion":1},{"id":"70ccf82d-3871-40cd-8dc0-961e36acd070","name":"Merge Image and Post Contents","type":"n8n-nodes-base.merge","position":[1820,-1840],"parameters":{"mode":"combine","options":{},"combineBy":"combineByPosition"},"typeVersion":3},{"id":"077f7110-215f-4ccf-8546-41d21c1105ad","name":"Sticky Note10","type":"n8n-nodes-base.stickyNote","position":[2540,-1460],"parameters":{"width":320,"height":380,"content":""},"typeVersion":1},{"id":"650a4191-6ed6-4868-b433-f44a0ddf959b","name":"Implement Threads Here","type":"n8n-nodes-base.noOp","position":[2640,-1420],"parameters":{},"typeVersion":1},{"id":"59651d51-92ce-42e5-a9c7-4faa18526ef2","name":"Implement YouTube Shorts Here","type":"n8n-nodes-base.noOp","position":[2640,-1260],"parameters":{},"typeVersion":1},{"id":"7cb931d5-d890-4ea6-9fca-84b934dd911c","name":"X Response","type":"n8n-nodes-base.set","position":[2840,-2180],"parameters":{"options":{},"assignments":{"assignments":[{"id":"4015bb20-da3b-4781-ab8c-46f4d826138e","name":"output","type":"string","value":"={{ $('Social Media Publishing Router').item.json.data.route }}\n\n{{ $('Social Media Publishing Router').item.json.data.social_content.root_schema.name }}\n\n{{ $('Social Media Publishing Router').item.json.data.social_content.schema.post }}\n\n![{{ $('Social Media Publishing Router').item.json.data.social_content.root_schema.name }}]({{ $('Social Media Publishing Router').item.json.data.social_image.thumb.url }})"}]}},"typeVersion":3.4},{"id":"90c4faa3-3376-41d1-83e7-0c4c2bc03de5","name":"Instagram Response","type":"n8n-nodes-base.set","position":[2840,-2000],"parameters":{"options":{},"assignments":{"assignments":[{"id":"da8fe7e3-e74d-46b6-91eb-1bf4432b73b0","name":"output","type":"string","value":"={{ $('Social Media Publishing Router').item.json.data.route }}  \n{{ $('Social Media Publishing Router').item.json.data.social_content.root_schema.name }}\n{{ $('Social Media Publishing Router').item.json.data.social_content.schema.caption }}\n![{{ $('Social Media Publishing Router').item.json.data.social_content.root_schema.name }}]({{ $('Social Media Publishing Router').item.json.data.social_image.thumb.url }})"}]}},"typeVersion":3.4},{"id":"de57e2c7-acac-4268-a535-e90f00548956","name":"Facebook Response","type":"n8n-nodes-base.set","position":[2840,-1820],"parameters":{"options":{},"assignments":{"assignments":[{"id":"e349e314-2967-456f-856a-85727bdf94f3","name":"output","type":"string","value":"={{ $('Social Media Publishing Router').item.json.data.route }}\n\n{{ $('Social Media Publishing Router').item.json.data.social_content.root_schema.name }}\n\n{{ $('Social Media Publishing Router').item.json.data.social_content.schema.post }}\n\n![{{ $('Social Media Publishing Router').item.json.data.social_content.root_schema.name }}]({{ $('Social Media Publishing Router').item.json.data.social_image.thumb.url }})"}]}},"typeVersion":3.4},{"id":"030e8933-0eae-4e6c-956d-dce0e702b163","name":"LinkedIn Response","type":"n8n-nodes-base.set","position":[2840,-1640],"parameters":{"options":{},"assignments":{"assignments":[{"id":"88404fde-a41b-4da5-bbdb-0e41b879a52c","name":"output","type":"string","value":"={{ $('Social Media Publishing Router').item.json.data.route }}\n\n{{ $('Social Media Publishing Router').item.json.data.social_content.root_schema.name }}\n\n{{ $('Social Media Publishing Router').item.json.data.social_content.schema.post }}\n\n![{{ $('Social Media Publishing Router').item.json.data.social_content.root_schema.name }}]({{ $('Social Media Publishing Router').item.json.data.social_image.thumb.url }})\n"}]}},"typeVersion":3.4},{"id":"d48b6b3a-9410-4012-85bf-f70b4e91eccb","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[-1060,-1300],"parameters":{"color":3,"height":80,"content":"## Social Media Schema"},"typeVersion":1},{"id":"e3ef0a13-42ca-4021-aeb5-2230f4ac7eac","name":"Sticky Note12","type":"n8n-nodes-base.stickyNote","position":[-1840,-1300],"parameters":{"color":5,"width":760,"height":80,"content":"## System Prompt"},"typeVersion":1},{"id":"11457221-fa5e-41f4-93a5-bb3eea3f02a9","name":"Sticky Note13","type":"n8n-nodes-base.stickyNote","position":[-120,-2200],"parameters":{"width":620,"height":320,"content":"# Social Media Router Agent"},"typeVersion":1},{"id":"f40e9cde-1810-4471-9751-6da724a06f6c","name":"🤖Social Media Router Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[60,-2080],"parameters":{"text":"=You are a helpful assistant that uses the provided tools.  Respond with a valid JSON object.\n\nUser prompt:  {{ $json.chatInput }}","options":{"systemMessage":"## RULES\n- You do not answer the users questions directly and your sole purpose is to call the appropriate tool to and provide the verbatim response.\n\n## TOOLS\n- create_x_twitter_posts_tool: Use this tool to create X-Twitter posts\n- create_instagram_posts_tool: Use this tool to create Instagram posts\n- create_facebook_posts_tool: Use this tool to create Facebook posts\n- create_linkedin_posts_tool: Use this tool to create LinkedIn posts\n- create_threads_posts_tool: Use this tool to create Threads posts\n- create_youtube_short_tool: Use this tool to create a YouTube short\n\n\n"},"promptType":"define"},"typeVersion":1.7},{"id":"e6715ea6-f70d-427b-bf3d-499ed8040140","name":"Sticky Note14","type":"n8n-nodes-base.stickyNote","position":[800,-1720],"parameters":{"width":400,"height":440,"content":"## Prepare Email Approval Contents as HTML"},"typeVersion":1},{"id":"cbb2a190-8aad-4e09-9d5c-a43dbcb32184","name":"SerpAPI","type":"@n8n/n8n-nodes-langchain.toolSerpApi","position":[980,-360],"parameters":{"options":{}},"credentials":{"serpApi":{"id":"DfdkTTaZtPp0iHYv","name":"SerpAPI account"}},"typeVersion":1},{"id":"58da1f9e-caa4-4ea2-8b02-3e734758af80","name":"Sticky Note15","type":"n8n-nodes-base.stickyNote","position":[-500,-120],"parameters":{"color":7,"width":3520,"height":680,"content":"# 💫Features & Benefits"},"typeVersion":1},{"id":"e65c6e37-0523-4e7d-b634-d3499aef5516","name":"Sticky Note16","type":"n8n-nodes-base.stickyNote","position":[-440,-40],"parameters":{"color":7,"width":680,"height":280,"content":"## 1️⃣System Prompt Composition from External Source\nCentralized prompt management: Store and update system prompts in Google Docs for easy team collaboration\n\n- Consistent brand voice: Ensure all generated content maintains consistent tone and style across platforms\n\n- Flexible customization: Quickly modify prompts without changing workflow code\n\n- Version control: Track changes to prompts over time with Google Docs revision history\n\n- Role-specific access: Control who can edit core prompts while allowing broader viewing access\n"},"typeVersion":1},{"id":"b7ccbaa4-3c33-4f32-a72d-fb693b9c63d6","name":"Sticky Note17","type":"n8n-nodes-base.stickyNote","position":[-440,260],"parameters":{"color":7,"width":680,"height":260,"content":"## 2️⃣Output Schema Composition from External Source\n- Structured content generation: Enforce consistent JSON output formats for each platform\n\n- Platform-specific optimization: Tailor content structure to each social network's requirements\n\n- Reduced errors: Validate content against schemas before publishing\n\n- Easy updates: Modify schemas as platform requirements change without workflow modifications\n\n- Standardized metadata: Ensure all required fields are included for each platform"},"typeVersion":1},{"id":"b36e874a-a893-439d-bd29-524ea567b695","name":"Sticky Note19","type":"n8n-nodes-base.stickyNote","position":[720,-40],"parameters":{"color":7,"width":400,"height":520,"content":"## 4️⃣ Dynamic Social Media Content Creator Agent with Web Search Tool to Match Social Post and Platform Schema\n\n- Real-time research: Incorporate current events and trending topics into content\n\n- Fact-checking: Verify information before publishing to maintain credibility\n\n- Competitive analysis: Reference industry trends and competitor content\n\n- Contextual relevance: Create content that responds to current market conditions\n\n- Enhanced engagement: Generate content that aligns with trending conversations"},"typeVersion":1},{"id":"d57e47d1-e95e-45b6-95cf-a8952320da35","name":"Sticky Note23","type":"n8n-nodes-base.stickyNote","position":[1160,-40],"parameters":{"color":7,"width":340,"height":520,"content":"## 5️⃣ Dynamic Image Creation to Match Social Post & Platform Schema\n\n- Visual consistency: Generate platform-optimized images that match content themes\n\n- Automated alt text: Create accessibility-compliant image descriptions\n\n- Multi-format output: Generate images in various dimensions for different platforms\n\n- Brand compliance: Ensure all visuals align with brand guidelines\n\n- Reduced design bottlenecks: Eliminate waiting for custom graphics for each post"},"typeVersion":1},{"id":"4323fd33-f2ff-434a-bd44-0ecb59fc4962","name":"Sticky Note24","type":"n8n-nodes-base.stickyNote","position":[1520,-40],"parameters":{"color":7,"width":300,"height":520,"content":"## 6️⃣ Image Archiving to Multiple Cloud Services for Future Use\n\n- Redundant storage: Prevent content loss with multi-location backups\n\n-Searchable repository: Build a library of past content for reference and reuse\n\n- Asset tracking: Maintain records of which images were used for which campaigns\n\n- Compliance documentation: Keep records of published content for regulatory purposes\n\n- Resource optimization: Reuse successful visual assets for future campaigns"},"typeVersion":1},{"id":"e0dc7e2a-275f-4389-973a-e0d92af6de6c","name":"Sticky Note27","type":"n8n-nodes-base.stickyNote","position":[1840,-40],"parameters":{"color":7,"width":260,"height":520,"content":"## 7️⃣ Telegram Messaging for Workflow Status \n\n- Real-time notifications: Get immediate alerts about workflow execution\n\n- Error tracking: Quickly identify and address failures in the content pipeline\n\n- Team coordination: Keep stakeholders informed of content progress\n\n- Audit trail: Maintain records of when content was created and published\n\n- Remote monitoring: Track workflow execution from mobile devices"},"typeVersion":1},{"id":"0d9940df-faad-4adc-a79f-4b89f2f2d16e","name":"Sticky Note28","type":"n8n-nodes-base.stickyNote","position":[2120,-40],"parameters":{"color":7,"width":840,"height":280,"content":"## 8️⃣ Optional Workflow Reporting to Gmail in with Structured HTML Content\n- Executive summaries: Provide management with clean, formatted reports\n\n- Content approval: Enable stakeholders to review content before publishing\n\n- Performance tracking: Document content metrics in standardized formats\n\n- Schedule adherence: Monitor if content is being published according to plan\n\n- Resource allocation: Track time and effort spent on different content types"},"typeVersion":1},{"id":"febb3aa7-d0ed-422a-b115-33863889a152","name":"Sticky Note29","type":"n8n-nodes-base.stickyNote","position":[2120,260],"parameters":{"color":7,"width":840,"height":260,"content":"## 9️⃣ Social Post Archiving to Google Drive for Future Use\n- Content library: Build a searchable repository of all published content\n\n- Performance correlation: Connect content with its performance metrics\n\n- Compliance records: Maintain documentation of published materials\n\n- Content repurposing: Easily find and adapt past successful content\n\n- Campaign documentation: Group related content for campaign analysis"},"typeVersion":1},{"id":"697fab77-d1bb-41d8-8683-193230471721","name":"Sticky Note30","type":"n8n-nodes-base.stickyNote","position":[260,-40],"parameters":{"width":420,"height":960,"content":"## 3️⃣Dynamic System Prompt and Platform Schema Composition based on User Prompt using External Sources\n- Centralized prompt management: Store all system prompts in a single external source for easier maintenance and updates\n\n- Platform-specific optimization: Automatically tailor content to each platform's unique requirements and audience expectations\n\n- Consistent brand voice: Ensure all generated content maintains your brand's tone and messaging guidelines across platforms\n\n- Reduced technical debt: Modify prompts and schemas without changing workflow code or redeploying applications\n\n- Collaborative improvement: Enable marketing teams to refine prompts without developer intervention\n\n- Version control: Track changes to prompts and schemas over time with document revision history\n\n- A/B testing capability: Easily test different prompt variations to optimize content performance\n\n- Scalable content strategy: Add support for new platforms by simply creating new prompt and schema documents\n\n- Dynamic adaptation: Respond to platform algorithm changes by quickly updating external prompt documents\n\n- Knowledge preservation: Maintain institutional knowledge about effective platform-specific content strategies\n\n- Reduced onboarding time: New team members can understand content requirements by reviewing documented prompts\n\n- Compliance management: Ensure all generated content follows legal and brand guidelines by centralizing rules"},"typeVersion":1},{"id":"11ba3bef-7036-416b-a63d-a82cf7cbe30f","name":"Prepare Social Media Email Contents","type":"@n8n/n8n-nodes-langchain.agent","position":[2300,-780],"parameters":{"text":"=Use the HTML template and populate [fields] as required from this: {{ $('pollinations.ai1').item.json.output.toJsonString() }}\n-----\nOnly output HTML without code block tags, preamble or further explanation in the format provided.\n\n## HTML Template\n<table style=\"max-width:640px;min-width:320px;width:100%;border-collapse:collapse;font-family:Arial,sans-serif;margin:20px auto\">\n    <tbody>\n        <tr>\n            <td colspan=\"2\" style=\"background-color:#ffffff;padding:15px;text-align:left\">\n                <img src=\"{{ $json.thumbnailLink }}\" alt=\"{{ $json.output.root_schema.name }}\" style=\"max-width:100%;height:auto;\">\n            </td>\n        </tr>\n        <tr>\n            <td colspan=\"2\" style=\"background-color:#efefef;padding:15px;font-size:20px;text-align:left;font-weight:bold\">\n                {{ $json.output.root_schema.name  }}\n            </td>\n        </tr>\n        <tr>\n            <td style=\"background-color:#f9f9f9;padding:15px;width:30%;text-align:left\"><strong>Platform:</strong></td>\n            <td style=\"background-color:#f9f9f9;padding:15px;text-align:left\">{{ $('Compose Prompt & Schema').item.json.route }}</td>\n        </tr>\n        <tr>\n            <td style=\"background-color:#f9f9f9;padding:15px;width:30%;text-align:left\"><strong>[label_1]:</strong></td>\n            <td style=\"background-color:#f9f9f9;padding:15px;text-align:left\">[content_1]</td>\n        </tr>\n        <tr>\n            <td style=\"background-color:#f1f1f1;padding:15px;text-align:left\"><strong>[label_2]:</strong></td>\n            <td style=\"background-color:#f1f1f1;padding:15px;text-align:left\">[content_2]</td>\n        </tr>\n\n        [continue the pattern ...]\n\n        <tr>\n            <td colspan=\"2\" style=\"background-color:#efefef;padding:15px;text-align:left\">\n                <strong>[footer_label]:</strong> [footer_content]\n            </td>\n        </tr>\n    </tbody>\n</table>\n\n","options":{},"promptType":"define"},"typeVersion":1.7},{"id":"1dc19a25-ff27-4582-a574-279831f7bc28","name":"Sticky Note43","type":"n8n-nodes-base.stickyNote","position":[-760,-340],"parameters":{"height":500,"content":"💡Notes\n\n- Create Google Doc for the Social Media Schema and copy the provided schema.\n\n- Update the Google Doc ID in the Social Media Schema node.\n\n- Create Google Doc for the Social Media System Prompt and copy the provided System Prompt.\n\n- Update the Google Doc ID in the Social Media System Prompt node.\n\n\n\nAdjust system prompt and platform specific prompts to suit your needs."},"typeVersion":1},{"id":"6b1d2ad9-9ad8-4a33-ab7d-430f96dc317c","name":"Sticky Note44","type":"n8n-nodes-base.stickyNote","position":[1340,-360],"parameters":{"width":300,"content":"💡Notes\n\nReplace pollinations.ai with any online image generation service that produces an image file you can download."},"typeVersion":1},{"id":"e7c2d9ba-6b9a-404f-a84d-8e90e4c5f4bb","name":"Sticky Note45","type":"n8n-nodes-base.stickyNote","position":[720,-840],"parameters":{"width":400,"height":140,"content":"💡Notes\n\nReplace Chat model with other LLMs and test out the results.  Add more tools or try other web search tools to suit your use case."},"typeVersion":1},{"id":"00204106-dd0f-46d5-89c8-60fd92f1388e","name":"gpt-4o","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-520,-1620],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o","cachedResultName":"gpt-4o"},"options":{"responseFormat":"json_object"}},"credentials":{"openAiApi":{"id":"jEMSvKmtYfzAkhe6","name":"OpenAi account"}},"typeVersion":1.2}],"active":false,"pinData":{"Social Media Schema":[{"json":{"content":"<common>\n{\n    \"type\": \"object\",\n    \"properties\": {\n        \"hashtags\": {\n            \"type\": \"array\",\n            \"items\": {\n                \"type\": \"string\"\n            }\n        },\n        \"image_suggestion\": {\n            \"type\": \"string\"\n        }\n    }\n}\n</common>\n\n<root>\n{\n    \"type\": \"object\",\n    \"properties\": {\n        \"name\": {\n            \"type\": \"string\"\n        },\n        \"description\": {\n            \"type\": \"string\"\n        },\n        \"additional_notes\": {\n            \"type\": \"string\"\n        }\n    }\n}\n</root>\n\n<linkedin>\n{\n    \"type\": \"object\",\n    \"properties\": {\n        \"post\": {\n            \"type\": \"string\"\n        },\n        \"call_to_action\": {\n            \"type\": \"string\"\n        }\n    }\n}\n</linkedin>\n\n<instagram>\n{\n    \"type\": \"object\",\n    \"properties\": {\n        \"caption\": {\n            \"type\": \"string\"\n        },\n        \"emojis\": {\n            \"type\": \"array\",\n            \"items\": {\n                \"type\": \"string\"\n            }\n        },\n        \"call_to_action\": {\n            \"type\": \"string\"\n        }\n    }\n}\n</instagram>\n\n<facebook>\n{\n    \"type\": \"object\",\n    \"properties\": {\n        \"post\": {\n            \"type\": \"string\"\n        },\n        \"call_to_action\": {\n            \"type\": \"string\"\n        }\n    }\n}\n</facebook>\n\n<xtwitter>\n{\n    \"type\": \"object\",\n    \"properties\": {\n        \"video_suggestion\": {\n            \"type\": \"string\"\n        },\n        \"post\": {\n            \"type\": \"string\"\n        },\n        \"character_limit\": {\n            \"type\": \"integer\"\n        }\n    }\n}\n</xtwitter>\n\n<threads>\n{\n    \"type\": \"object\",\n    \"properties\": {\n        \"text_post\": {\n            \"type\": \"string\"\n        },\n        \"call_to_action\": {\n            \"type\": \"string\"\n        }\n    }\n}\n</threads>\n\n<youtube_short>\n{\n    \"type\": \"object\",\n    \"properties\": {\n        \"video_suggestion\": {\n            \"type\": \"string\"\n        },\n        \"title\": {\n            \"type\": \"string\"\n        },\n        \"description\": {\n            \"type\": \"string\"\n        },\n        \"call_to_action\": {\n            \"type\": \"string\"\n        }\n    }\n}\n</youtube_short>\n\n\n\n","documentId":"[your-doc-id-here]"}}],"Social Media System Prompt":[{"json":{"content":"<system>\nYou are a specialized content creation AI for social media platforms.\nYour primary function is generating platform-optimized social media content across various platforms including LinkedIn, Instagram, Facebook, Twitter (X), Threads, and YouTube Shorts. Each piece of content must:\nMatch the specific platform's audience expectations and algorithm preferences\nShowcase relevant expertise in your field\nDeliver actionable insights for your target audience\nDrive meaningful engagement through value-driven content\nOBJECTIVES:\nCreate platform-specific content following each platform's best practices\nImplement strategic hashtag usage combining general and trending tags\nDesign content that encourages user interaction and community building\nMaintain consistent brand voice while adapting to platform requirements\nIncorporate data-driven insights to maximize content performance\nOUTPUT REQUIREMENTS:\nDeliver content in valid JSON format according to the platform-specific schema\nInclude all required fields as specified in the schema\nOmit any explanatory text or code fencing in your response\nTailor content specifically to the platform indicated in the user's request\nFor each content request, adapt your output based on the platform guidelines and ensure it aligns with your organization's mission and values.  Never provide URLS for video or image suggestions and only describe the suggestion.\n</system>\n\n\n<rules>\n- Only provide final response in valid JSON for the appropriate social platform\n- Never include any preamble or further explanation\n- Always remove any ``` ```json\n</rules>\n\n\n<linkedin>\n**Style**: Professional and insightful.\n**Tone**: Business-oriented; focus on automation use cases, industry insights, and community impact.\n**Content Length**: 3-4 sentences; concise but detailed.\n**Hashtags**: #Innovation #Automation #WorkflowSolutions #DigitalTransformation #Leadership\n**Call to Action (CTA)**: Encourage comments or visits to workflows.diy's website for more insights.\n</linkedin>\n\n<instagram>\n**Style**: Visual storytelling with creative captions.\n**Tone**: Inspirational and engaging; use emojis for relatability.\n**Content Length**: 2-3 sentences paired with eye-catching visuals (e.g., infographics or workflow demos).\n**Visuals**: Showcase milestones (e.g., new workflow launches), tutorials, or product highlights.\n**CTA**: Use phrases like \"Swipe to learn more,\" \"Tag your team,\" or \"Check out the link below!\"\n**Link Placement**: Add the provided link before hashtags; if no link is provided, use \"Visit our website: https://workflows.diy.\"\n**Hashtags**: #AutomationLife #TechInnovation #WorkflowTips #Programming #Engineering\n</instagram>\n\n<facebook>\n**Style**: Friendly and community-focused.\n**Tone**: Relatable; highlight user success stories or company achievements in automation.\n**Content Length**: 2-3 sentences; conversational yet professional.\n**Hashtags**: #SmallBusinessAutomation #Entrepreneurship #Leadership #WorkflowInnovation\n**CTA**: Encourage likes, shares, comments (e.g., \"What's your favorite automation tip?\").\n</facebook>\n\n<xtwitter>\n**Style**: Concise and impactful.\n**Tone**: Crisp and engaging; spark curiosity in 150 characters or less.\n**Hashtags**: #WorkflowTrends #AIWorkflows #AutomationTips #NoCodeSolutions\n**CTA**: Drive quick engagement through retweets or replies (e.g., \"What's your go-to n8n workflow?\").\n</xtwitter>\n\n<threads>\n**Style**: Conversational and community-driven posts.\n**Tone**: Casual yet informative; encourage discussions around automation trends or innovations.\n**Content Length**: 1-2 short paragraphs with a question or thought-provoking statement at the end.\n**Hashtags**: Similar to Instagram but tailored for trending Threads topics related to automation.\n</threads>\n\n<youtube_short>\n**Style**: Short-form video content showcasing quick workflow tutorials or use cases.\n**Tone**: Authoritative yet approachable; establish workflows.diy as a leader in n8n automation solutions.\n**Content Length**:\n  - Tutorials/Reviews (long-form): 5-10 minutes\n  - Shorts/Highlights (short-form): Under 1 minute\n**CTA**: Encourage subscriptions, likes, comments (e.g., \"Subscribe for more workflow tips!\").\n</youtube_short>\n\n\n\n","documentId":"[your-doc-id-here]"}}],"When Executed by Another Workflow":[{"json":{"route":"instagram","user_prompt":"i need an instagram post about using n8n to transform business automation with reference to a related historical fact and example"}}]},"settings":{"executionOrder":"v1"},"versionId":"110ac387-48e7-4ed2-98d6-0e3ddbb34063","connections":{"Gmail":{"main":[[]]},"Merge":{"main":[[{"node":"Prepare Social Media Email Contents","type":"main","index":0},{"node":"Google Drive Image Meta","type":"main","index":0}]]},"Short":{"ai_tool":[[{"node":"🤖Social Media Router Agent","type":"ai_tool","index":0}]]},"Schema":{"main":[[{"node":"Parse Schema","type":"main","index":0}]]},"X Post":{"main":[[{"node":"X Response","type":"main","index":0}]]},"gpt-4o":{"ai_languageModel":[[{"node":"🤖Social Media Router Agent","type":"ai_languageModel","index":0}]]},"File Id":{"main":[[{"node":"Get Social Post from Google Drive","type":"main","index":0}]]},"SerpAPI":{"ai_tool":[[{"node":"Social Media Content Creator","type":"ai_tool","index":0}]]},"Facebook":{"ai_tool":[[{"node":"🤖Social Media Router Agent","type":"ai_tool","index":0}]]},"LinkedIn":{"ai_tool":[[{"node":"🤖Social Media Router Agent","type":"ai_tool","index":0}]]},"X-Twiter":{"ai_tool":[[{"node":"🤖Social Media Router Agent","type":"ai_tool","index":0}]]},"Instagram":{"ai_tool":[[{"node":"🤖Social Media Router Agent","type":"ai_tool","index":0}]]},"gpt-40-mini":{"ai_languageModel":[[{"node":"Prepare Social Media Email Contents","type":"ai_languageModel","index":0}]]},"gpt-4o-mini":{"ai_languageModel":[[{"node":"Social Media Content Creator","type":"ai_languageModel","index":0}]]},"Is Approved?":{"main":[[{"node":"Get Social Post Image","type":"main","index":0}]]},"Parse Schema":{"main":[[{"node":"Merge Prompts and Schema","type":"main","index":0}]]},"gpt-40-mini1":{"ai_languageModel":[[{"node":"Prepare Email Contents","type":"ai_languageModel","index":0}]]},"Facebook Post":{"main":[[{"node":"Facebook Response","type":"main","index":0}]]},"LinkedIn Post":{"main":[[{"node":"LinkedIn Response","type":"main","index":0}]]},"System Prompt":{"main":[[{"node":"Parse System Prompt","type":"main","index":0}]]},"YouTube Short":{"ai_tool":[[{"node":"🤖Social Media Router Agent","type":"ai_tool","index":0}]]},"Social Content":{"main":[[{"node":"pollinations.ai1","type":"main","index":0}]]},"Extract as JSON":{"main":[[{"node":"Merge Image and Post Contents","type":"main","index":0},{"node":"Prepare Email Contents","type":"main","index":0}]]},"Instagram Image":{"main":[[{"node":"Instragram Post","type":"main","index":0}]]},"Instragram Post":{"main":[[{"node":"Instagram Response","type":"main","index":0}]]},"Social Post JSON":{"main":[[{"node":"Save Social Post to Google Drive","type":"main","index":0}]]},"pollinations.ai1":{"main":[[{"node":"Telegram Success Message (Optional)","type":"main","index":0},{"node":"Save Image to imgbb.com","type":"main","index":0},{"node":"Save Image to Google Drive","type":"main","index":0},{"node":"Merge","type":"main","index":1}],[{"node":"Telegram Error Message (Optional)","type":"main","index":0}]]},"Parse System Prompt":{"main":[[{"node":"Merge Prompts and Schema","type":"main","index":2}]]},"Social Media Schema":{"main":[[{"node":"Schema","type":"main","index":0}]]},"Window Buffer Memory":{"ai_memory":[[{"node":"🤖Social Media Router Agent","type":"ai_memory","index":0}]]},"Get Social Post Image":{"main":[[{"node":"Merge Image and Post Contents","type":"main","index":1}]]},"Prepare Email Contents":{"main":[[{"node":"Gmail User for Approval","type":"main","index":0}]]},"Compose Prompt & Schema":{"main":[[{"node":"Social Media Content Creator","type":"main","index":0}]]},"Gmail User for Approval":{"main":[[{"node":"Is Approved?","type":"main","index":0}]]},"Google Drive Image Meta":{"main":[[{"node":"Social Post JSON","type":"main","index":0}]]},"Save Image to imgbb.com":{"main":[[{"node":"Merge","type":"main","index":0}]]},"Merge Prompts and Schema":{"main":[[{"node":"Compose Prompt & Schema","type":"main","index":0}]]},"Save Image to Google Drive":{"main":[[{"node":"Merge","type":"main","index":2}]]},"Social Media System Prompt":{"main":[[{"node":"System Prompt","type":"main","index":0}]]},"When chat message received":{"main":[[{"node":"🤖Social Media Router Agent","type":"main","index":0}]]},"Social Media Content Creator":{"main":[[{"node":"Social Content","type":"main","index":0}]]},"Merge Image and Post Contents":{"main":[[{"node":"Social Media Publishing Router","type":"main","index":0}]]},"🤖Social Media Router Agent":{"main":[[{"node":"File Id","type":"main","index":0}]]},"Social Media Publishing Router":{"main":[[{"node":"X Post","type":"main","index":0}],[{"node":"Instagram Image","type":"main","index":0}],[{"node":"Facebook Post","type":"main","index":0}],[{"node":"LinkedIn Post","type":"main","index":0}],[{"node":"Implement Threads Here","type":"main","index":0}],[{"node":"Implement YouTube Shorts Here","type":"main","index":0}]]},"Save Social Post to Google Drive":{"main":[[{"node":"Respond with Google Drive Id","type":"main","index":0}]]},"Get Social Post from Google Drive":{"main":[[{"node":"Extract as JSON","type":"main","index":0}]]},"When Executed by Another Workflow":{"main":[[{"node":"Social Media System Prompt","type":"main","index":0},{"node":"Social Media Schema","type":"main","index":0},{"node":"Merge Prompts and Schema","type":"main","index":1}]]},"Prepare Social Media Email Contents":{"main":[[{"node":"Gmail","type":"main","index":0}]]}}}


name: Analyze Any Website with OpenAI And Get On-Page SEO Audit
author_name: Not Another Marketer
author_username: notanothermarketer
categories: []
created_at: 2025-03-19T21:20:11.472Z
updated_at: 2025-03-19T21:20:11.472Z
url: https://n8n.io/workflows/3224
scraped_at: 2025-06-19 22:07:56
description:
  Instantly Find & Fix What’s Holding Your Page Back

  You’ve put in the work. Your content is strong. Your design is polished.

  But…

  ❌ Your page isn’t ranking where it should.
  ❌ Your competitors are outranking you—even with weaker content.
  ❌ You have no idea what’s wrong—or how to fix it.

  The truth? SEO isn’t just about keywords.

  Your technical setup, content structure, and on-page elements must work together seamlessly.
  And if anything is off? Google won’t rank your page.

  Who Is This For?
  SaaS Founders & Startups – Get higher rankings & organic traffic that converts.
  Marketing Teams & Agencies – Audit & optimize pages in seconds.
  E-commerce & Content Sites – Improve rankings for product pages, blogs, and landing pages.

  How It Works
  Paste your URL
  Get an instant audit + recommendations list
  Implement changes & watch your rankings jump

  The workflow scrapes the url you input, gets the htlm source code of the landing page, and sends it to OpenAI AI Agent.

  The Agent makes a deep analysis, audit the Technical + Content SEO of the page, and provides 10 Recommendations to improve your SEO.

  Setup Guide
  You will need OpenAI Credentials with an API Key to run the workflow.

  The workflow is using the OpenAI-o1 model to deliver the best results. It costs between $0.20/0.30 per run.

  You can adjust the prompt to your wish in the AI Agent parameters.

  Once the audit has been completed, it will send an email (don't forget to add your email address here)

  Below is an example of what you can expect

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

workflow_json:
  {"id":"iLpBIRuhpWToO22N","meta":{"instanceId":"e8ec316b54e91908f34cbfdc330e5d1d5e97aa0ea8f7277c00d8a8a3892c9983","templateCredsSetupCompleted":true},"name":"🤖 On-Page SEO Audit","tags":[{"id":"TF9zcHoRnyCYBNVV","name":"SEO","createdAt":"2025-03-14T12:08:26.948Z","updatedAt":"2025-03-14T12:08:26.948Z"}],"nodes":[{"id":"f4a971be-a961-4ad6-b38d-830c5fca5407","name":"Landing Page Url","type":"n8n-nodes-base.formTrigger","position":[-180,0],"webhookId":"afe067a5-4878-4c9d-b746-691f77190f54","parameters":{"options":{},"formTitle":"Conversion Rate Optimizer","formFields":{"values":[{"fieldLabel":"Landing Page Url","placeholder":"https://yuzuu.co","requiredField":true}]},"formDescription":"Your Landing Page is Leaking Sales—Fix It Now"},"typeVersion":2.2},{"id":"e280139f-94b8-49dc-91e7-c6ffa0c04716","name":"Scrape Website","type":"n8n-nodes-base.httpRequest","position":[20,0],"parameters":{"url":"={{ $json['Landing Page Url'] }}","options":{}},"typeVersion":4.2},{"id":"de9ff0da-4ef9-4878-af0d-5733e010402c","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[320,20],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini","cachedResultName":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"MtyWeuRTqwi3Yx9H","name":"OpenAi account"}},"typeVersion":1.2},{"id":"25969781-4b1c-42ad-969c-efbb605be9e5","name":"OpenAI Chat Model1","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[360,400],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini","cachedResultName":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"MtyWeuRTqwi3Yx9H","name":"OpenAi account"}},"typeVersion":1.2},{"id":"0f135a2d-156c-43ee-b254-581c7d543a8c","name":"Content Audit","type":"@n8n/n8n-nodes-langchain.agent","position":[380,200],"parameters":{"text":"=You are the best SEO Manager in the country—a world-class expert in optimizing websites to rank on Google.\n\nIn this task, you will analyze the content of the webpage and perform a detailed and structured SEO Content Audit.\n\nAudit Structure\nYou will divide your audit in 2 parts:\n- The first part is the Analysis\n- The second is the Recommendations\n\nIn the Analysis, you will include:\n- Content Quality Assessment – Evaluate the content's overall quality, accuracy, and relevance to the target audience.\n- Keyword Research and Analysis – Identify primary and secondary keywords, keyword density, and keyword placement strategies.\n- Readability Analysis – Assess the content's readability score using metrics such as Flesch-Kincaid Grade Level, Flesch Reading Ease, and Gunning-Fog Index.\n\nIn the Recommendations, you will present your recommendations and actionable suggestions in clear, organized bullet points. Recommendations must improve the rankings in Google but also the user engagement. \n\nEnsure the output is properly formatted, clean, and highly readable. Do not include any introductory or explanatory text—only the audit findings.\n\nHere is the content of my landing page: {{ $json.data }}","options":{},"promptType":"define"},"typeVersion":1.7},{"id":"b693e35c-c0d4-4202-8c5e-2a5646a16cc4","name":"Technical Audit","type":"@n8n/n8n-nodes-langchain.agent","position":[380,-200],"parameters":{"text":"=You are the best SEO Manager in the country—a world-class expert in optimizing websites to rank on Google.\nIn this task, you will analyze the HTML code of a webpage and perform a detailed and structured On-Page Technical SEO Audit.\n\nAudit Structure\nYou will review all technical SEO aspects of the page. Once completed, you will present your findings and recommendations in clear, organized bullet points, categorized into three sections:\n- Critical Issues – Must be fixed immediately.\n- Quick Wins – Easy fixes with a big impact.\n- Opportunities for Improvement – Require more effort but offer potential benefits.\n\nEnsure the output is properly formatted, clean, and highly readable. Do not include any introductory or explanatory text—only the audit findings.\n\nHere is the content of my landing page: {{ $json.data }}","options":{},"promptType":"define"},"typeVersion":1.7},{"id":"3d172f93-7d94-4a43-9403-5cec799bbe47","name":"Merge","type":"n8n-nodes-base.merge","position":[880,0],"parameters":{},"typeVersion":3,"alwaysOutputData":true},{"id":"2081bf62-0e47-497e-8a3e-d30d330f6a9d","name":"Aggregate","type":"n8n-nodes-base.aggregate","position":[1080,0],"parameters":{"options":{},"fieldsToAggregate":{"fieldToAggregate":[{"fieldToAggregate":"output"}]}},"typeVersion":1},{"id":"e1cfc16e-e0dc-4298-9b94-ffb7f23b45aa","name":"Markdown","type":"n8n-nodes-base.markdown","position":[1280,0],"parameters":{"mode":"markdownToHtml","options":{},"markdown":"=# On-Page Technical Audit\n{{ $json.output[0] }}\n\n# On-Page SEO Content Audit\n{{ $json.output[1] }}"},"typeVersion":1},{"id":"7dc41215-e276-439c-be11-92278b1c3a60","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[1360,-160],"parameters":{"color":3,"width":360,"height":100,"content":"## Send Email \nConnect your credentials & Easily send emails from a Gmail address. "},"typeVersion":1},{"id":"28aea6bd-beef-4116-97c2-e8b88e96d5ac","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[320,-380],"parameters":{"color":3,"width":420,"height":140,"content":"## Open AI Setup\n- Add your credentials\n- Select o1 model for (way) better results. \n- One run = one page audit = around $0.3 with o1"},"typeVersion":1},{"id":"3242a0c3-4439-4ad1-8185-47185046080d","name":"Gmail","type":"n8n-nodes-base.gmail","position":[1480,0],"webhookId":"2979e4dc-1689-447e-8cd4-eb907b4eedf4","parameters":{"sendTo":"hello@youremail.com","message":"={{ $json.data }}","options":{},"subject":"=On-Page SEO Audit -  {{ $('Landing Page Url').item.json['Landing Page Url'] }}"},"credentials":{"gmailOAuth2":{"id":"9EELWJ0jA3PIbx13","name":"Gmail account"}},"typeVersion":2.1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"bc4ac79c-71a0-4dae-805d-55b682b0c199","connections":{"Merge":{"main":[[{"node":"Aggregate","type":"main","index":0}]]},"Markdown":{"main":[[{"node":"Gmail","type":"main","index":0}]]},"Aggregate":{"main":[[{"node":"Markdown","type":"main","index":0}]]},"Content Audit":{"main":[[{"node":"Merge","type":"main","index":1}]]},"Scrape Website":{"main":[[{"node":"Content Audit","type":"main","index":0},{"node":"Technical Audit","type":"main","index":0}]]},"Technical Audit":{"main":[[{"node":"Merge","type":"main","index":0}]]},"Landing Page Url":{"main":[[{"node":"Scrape Website","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Technical Audit","type":"ai_languageModel","index":0}]]},"OpenAI Chat Model1":{"ai_languageModel":[[{"node":"Content Audit","type":"ai_languageModel","index":0}]]}}}


name: 🔍🛠️Generate SEO-Optimized WordPress Content with AI Powered Perplexity Research
author_name: Joseph LePage
author_username: joe
categories: []
created_at: 2025-03-23T02:02:14.835Z
updated_at: 2025-03-23T02:02:14.835Z
url: https://n8n.io/workflows/3291
scraped_at: 2025-06-19 22:07:56
description:
  Generate SEO-Optimized WordPress Content with Perplexity Research

  Who is This For?
  This workflow is ideal for content creators, marketers, and businesses looking to streamline the creation of SEO-optimized blog posts for WordPress. It is particularly suited for professionals in the AI consulting and workflow automation industries.

  What Problem Does This Workflow Solve?
  Creating high-quality, SEO-friendly blog posts can be time-consuming and challenging, especially when trying to balance research, formatting, and publishing. This workflow automates the process by integrating research capabilities, AI-driven content creation, and seamless WordPress publishing. It reduces manual effort while ensuring professional-grade output.

  What This Workflow Does
  Research: Gathers detailed insights from Perplexity AI based on user-provided queries.
  Content Generation: Uses OpenAI models to create structured blog posts, including titles, slugs, meta descriptions, and HTML content optimized for WordPress.
  Image Handling: Automatically fetches and uploads featured images to WordPress posts.
  Publishing: Drafts the blog post directly in WordPress with all necessary formatting and metadata.
  Notification: Sends a success message via Telegram upon completion.

  Setup Guide
  Prerequisites:
     A WordPress account with API access.
     OpenAI API credentials.
     Perplexity AI API credentials.
     Telegram bot credentials for notifications.

  Steps:
     Import the workflow into your n8n instance.
     Configure API credentials for WordPress, OpenAI, Perplexity AI, and Telegram.
     Customize the form trigger to define your research query.
     Test the workflow using sample queries to ensure smooth execution.

  How to Customize This Workflow to Your Needs
  Modify the research query prompt in the "Form Trigger" node to suit your industry or niche.
  Adjust content generation guidelines in the "Copywriter AI Agent" node for specific formatting preferences.
  Replace the image URL in the "Set Image URL" node with your own source or dynamic image selection logic.

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

workflow_json:
  {"id":"5lMPjSDuoMvCJnko","meta":{"instanceId":"31e69f7f4a77bf465b805824e303232f0227212ae922d12133a0f96ffeab4fef","templateCredsSetupCompleted":true},"name":"🔍🛠️Generate SEO-Optimized WordPress Content with Perplexity Research","tags":[],"nodes":[{"id":"17ab0b24-b1eb-4e4e-a249-9889c9876fe4","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-1440,460],"parameters":{"color":3,"width":420,"height":440,"content":"## Write SEO Optimized Blog Post\n\n\n"},"typeVersion":1},{"id":"0931aacf-5c47-4bb0-86b6-158c2c7470b1","name":"Wordpress","type":"n8n-nodes-base.wordpress","position":[-1220,1120],"parameters":{"title":"={{ $('Combine Blog Details').item.json.data[2].output.title }}","additionalFields":{"slug":"={{ $('Combine Blog Details').item.json.data[2].output.slug }}","status":"draft","sticky":false,"content":"={{ $json.content }}","authorId":2,"postTemplate":{"values":{}},"commentStatus":"closed"}},"credentials":{"wordpressApi":{"id":"50Ph69y0TPKvO9tn","name":"Wordpress"}},"typeVersion":1},{"id":"81329ff1-b26a-499c-bd82-fd334503ab4f","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[-980,220],"parameters":{"color":7,"width":440,"height":280,"content":"## Create HTML\n\n\n"},"typeVersion":1},{"id":"03de9f23-e5ec-483b-a3dd-97617bd5165d","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[-1320,1020],"parameters":{"color":4,"width":300,"height":280,"content":"## Post on Wordpress\n\n\n"},"typeVersion":1},{"id":"6bf602e0-ad29-47e6-93d7-79fd2a4228c2","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-900,820],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"jEMSvKmtYfzAkhe6","name":"OpenAi account"}},"typeVersion":1.2},{"id":"8a3739ac-9492-400c-b5b8-eeb305647752","name":"Structured Output Parser","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[-680,820],"parameters":{"jsonSchemaExample":"{\n\"slug\": \"rpo-benefits-recruitment\",\n\"title\": \"7 Key Advantages of RPO for Modern Recruitment\",\n\"meta\": \"Explore how Recruitment Process Outsourcing (RPO) enhances hiring efficiency, reduces costs, and expands talent pools for businesses seeking top candidates.\"\n}"},"typeVersion":1.2},{"id":"af02ee94-4c26-4be5-bd21-09e020bff876","name":"Create Title, Slug, Meta","type":"@n8n/n8n-nodes-langchain.agent","position":[-880,640],"parameters":{"text":"=**Create a slug, blog post title, and meta description for the following blog post:**\n\n{{ $json.output }}\n\n**Slug Guidelines:**\n- Keep it concise (4-5 words maximum).\n- Include the primary keyword related to recruitment or HR.\n- Use hyphens to separate words.\n- Avoid unnecessary words, articles, or prepositions.\n- Ensure it reflects the main topic of the blog post.\n- Make it readable and relevant for both users and search engines.\n\n**Title Guidelines:**\n- Avoid AI words like \"Transform\" or \"Revolutionize\" and similar overused terms.\n- Avoid using a colon (:) in the title.\n- Never structure it as a primary/secondary title separated by a colon.\n- Include the primary keyword related to recruitment or HR (e.g., 'AI in recruitment' or 'talent acquisition trends').\n- Clearly inform users what they can expect from reading the blog post.\n- Be concise and engaging, ideally 50-60 characters long.\n- Incorporate power words that appeal to HR professionals and recruiters.\n\n**Meta Description Guidelines:**\n- Avoid AI words like \"Transform\" or \"Revolutionize\" and similar overused terms.\n- Be concise: Limit to 150-160 characters to ensure full visibility in search results.\n- Include keywords: Naturally incorporate primary recruitment-related keywords to enhance relevance and visibility.\n- Provide value: Clearly convey the benefits or insights readers will gain from the article.\n- Be engaging: Use action-oriented language or a thought-provoking question to encourage clicks.\n- Align with content: Accurately reflect the blog post's content to meet user expectations and reduce bounce rates.\n- Highlight expertise: Subtly emphasize SocialFind's authority in the recruitment field.\n\nYour output must be a single valid JSON object with these 3 fields:\n-slug: The slug\n-title: The blog post title\n-meta: The meta description  \n\nEach should be presented without any additional text, explanation, quotation marks, or formatting.\n","options":{},"promptType":"define","hasOutputParser":true},"typeVersion":1.8},{"id":"115c4043-6fda-42a4-ac3c-c7979b2f327e","name":"Create HTML","type":"@n8n/n8n-nodes-langchain.openAi","position":[-880,300],"parameters":{"modelId":{"__rl":true,"mode":"list","value":"gpt-4o-mini","cachedResultName":"GPT-4O-MINI"},"options":{},"messages":{"values":[{"content":"=Only output the HTML content without preamble or further explanation. Generate WordPress-compatible HTML for a blog post based on the provided content.\n\n### CONTENT PROCESSING:\n- Process all content from {{ $json.output }}\n- Preserve all original facts, information, and URLs\n- Format according to the specifications below\n\n### REQUIRED STRUCTURE (IN THIS ORDER):\n1. Title (H2)\n2. Estimated reading time\n3. Key takeaways (3-5 bullet points)\n4. Table of contents (linked to all headings)\n5. Main content (with proper heading hierarchy)\n6. FAQ section\n\n### STYLING REQUIREMENTS:\n- Style Override: Include a style section with !important declarations\n- Links: All hyperlinks, TOC items, and FAQ questions must be #00c2ff (blue)\n- Headings: All headings need a bottom border in #00c2ff with padding\n- Spacing: Add <br><br> between each major section\n\n### ENGAGEMENT FORMATTING:\n- Use bold, italics, bullet points, quotes, and highlighting for emphasis\n- Create proper paragraph structure with appropriate line breaks\n- NO emojis allowed\n- Use whitespace strategically for readability\n\n### HYPERLINK HANDLING (CRITICAL):\n- When URLs appear next to keyphrases (e.g., \"AI tools (https://example.com)\")\n- Convert to: <a href=\"https://example.com\" style=\"color: #00c2ff !important;\">AI tools</a>\n- The KEYPHRASE must be linked, never the URL itself\n\n### WORDPRESS COMPATIBILITY:\n- Use WordPress block classes (wp-block-heading, wp-block-paragraph, etc.)\n- Add heading IDs starting with \"h-\" for better TOC linking\n- Ensure all styles use !important to override theme styles\n\nDO NOT include any explanations, code tags, or comments. Output ONLY the raw HTML.\n"}]}},"credentials":{"openAiApi":{"id":"jEMSvKmtYfzAkhe6","name":"OpenAi account"}},"typeVersion":1.8},{"id":"4756c8f2-406e-4a56-adb0-0c4708dabe6a","name":"Merge","type":"n8n-nodes-base.merge","position":[-420,560],"parameters":{"numberInputs":3},"typeVersion":3},{"id":"1205aecf-08a1-499d-ac9e-822dd66b295f","name":"Upload Image to Wordpress","type":"n8n-nodes-base.httpRequest","position":[-520,1120],"parameters":{"url":"https://commonclone.com/wp-json/wp/v2/media","method":"POST","options":{},"sendBody":true,"contentType":"binaryData","sendHeaders":true,"authentication":"predefinedCredentialType","headerParameters":{"parameters":[{"name":"Content-Disposition","value":"=attachment; filename=\"cover-image-{{ $('Wordpress').item.json.id }}.jpeg\""}]},"inputDataFieldName":"data","nodeCredentialType":"wordpressApi"},"credentials":{"wordpressApi":{"id":"50Ph69y0TPKvO9tn","name":"Wordpress CommonClone.com RazorCX"}},"typeVersion":4.2},{"id":"b4437d9e-8b90-4d15-a96d-46645618a56d","name":"Set Image on Wordpress Post","type":"n8n-nodes-base.httpRequest","position":[-320,1120],"parameters":{"url":"=https://commonclone.com/wp-json/wp/v2/posts/{{ $('Wordpress').item.json.id }}","method":"POST","options":{},"sendQuery":true,"authentication":"predefinedCredentialType","queryParameters":{"parameters":[{"name":"featured_media","value":"={{ $json.id }}"}]},"nodeCredentialType":"wordpressApi"},"credentials":{"wordpressApi":{"id":"50Ph69y0TPKvO9tn","name":"Wordpress CommonClone.com RazorCX"}},"typeVersion":4.2},{"id":"bf05eaf3-2522-488e-893d-1ed9b2ed88b2","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[-1940,460],"parameters":{"color":4,"width":460,"height":300,"content":"## Perplexity Research\n\n\n"},"typeVersion":1},{"id":"22e8c044-ed98-495a-957e-c5e3fecc2b7d","name":"On form submission","type":"n8n-nodes-base.formTrigger","position":[-2120,560],"webhookId":"a29cbcd3-9d11-4f7c-9aad-14681c356c53","parameters":{"options":{},"formTitle":"Blog Factory","formFields":{"values":[{"fieldType":"textarea","fieldLabel":"Research Query","placeholder":"=What are the most common challenges facing Canadian employers regarding recruitment and why would they want to hire a recruiting firm to solve these problems.","requiredField":true}]},"formDescription":"Create SEO optimized blog posts"},"typeVersion":2.2},{"id":"6e6d4952-793f-4dc5-8d29-219d420149a9","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-1940,800],"parameters":{"width":460,"height":500,"content":"## Sample Generic Search Terms\nAdd your own or try these for your specific geo location.\n\n1. **Severe skills shortages in healthcare, construction, and education sectors.**  \n2. **Aging workforce widens employment gaps in key industries.**  \n3. **Tight labor market with 110 vacancies per 100 unemployed people.**  \n4. **High demand for specialized skills due to economic changes.**  \n5. **Housing shortages deter international candidates from relocating to the Netherlands.**  \n6. **Strict employment regulations complicate hiring processes for non-EU workers.**  \n7. **Intense competition for talent due to low unemployment rates.**  \n8. **Mismatch between available talent and job-specific skill requirements.**  \n9. **Candidates expect high benefits packages, increasing recruitment costs significantly.**  \n10. **Difficulty navigating compliance and labor laws for international hiring processes.**"},"typeVersion":1},{"id":"bb94017e-dc2a-43e3-ae5c-1f3227b1f0ef","name":"Perplexity Research","type":"n8n-nodes-base.httpRequest","position":[-1860,560],"parameters":{"url":"https://api.perplexity.ai/chat/completions","method":"POST","options":{},"jsonBody":"={\n  \"model\": \"sonar-pro\",\n  \"messages\": [\n    {\n      \"role\": \"system\",\n      \"content\": \"Act as a professional news researcher who is capable of finding detailed summaries about a news topic from highly reputable sources.\"\n    },\n    {\n      \"role\": \"user\",\n      \"content\": \" Research the following topic and return everything you can find about: '{{ $json['Research Query'] }}'.\"\n    }\n  ]\n}\n","sendBody":true,"specifyBody":"json","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"05RfNG280MisTyPP","name":"Perplexity"}},"typeVersion":4.2},{"id":"66086876-4b49-45fe-aecc-f7f062a59dba","name":"Cleanup Links","type":"n8n-nodes-base.set","position":[-1660,560],"parameters":{"options":{},"assignments":{"assignments":[{"id":"23b8e8c4-9191-415a-9661-1b60d413528a","name":"research","type":"string","value":"={{ $json.choices[0].message.content.replaceAll(\"[1]\", \" - source: \" +$json.citations[0]).replaceAll(\"[2]\",\" - source:\" +$json.citations[1]).replaceAll(\"[3]\",\" - source: \" +$json.citations[2]).replaceAll(\"[4]\",\" - source: \"+$json.citations[3]).replaceAll(\"[5]\",\" - source: \"+$json.citations[4]).replaceAll(\"[6]\",\" - source: \"+$json.citations[5]).replaceAll(\"[7]\",\" - source: \"+$json.citations[6]).replaceAll(\"[8]\",\" - source: \"+$json.citations[7]).replaceAll(\"[9]\",\" - source: \"+$json.citations[8]).replaceAll(\"[10]\",\" - source: \"+$json.citations[9]) }}"}]}},"typeVersion":3.4},{"id":"f81c9505-111f-473a-94b6-c79364410810","name":"Copywriter AI Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[-1360,560],"parameters":{"text":"=You are part of a marketing team that creates high-quality blog posts for the AI consulting and workflow automation industry based in Canada. Your goal is to produce engaging, SEO-optimized content that positions the company as an authority in the AI consulting industry and attracts inbound leads.\n\nEvery 2 days, your team posts a blog on the most trending topics in AI consulting and n8n workflows. As the copywriter, you are provided with the following information:\n\n- Query: The main topic for this week's blog post, representing the most trending news in the recruitment space.\n\n- Other keywords: A list of high-search-volume keywords related to AI consulting and n8n workflows. Incorporate these naturally into the blog post where relevant, without forcing them or changing the post's meaning.\n\n- Research findings: Detailed information from reputable sources related to the blog topic. Your post must be based on this research.\n\nGiven this information, write a comprehensive blog post that:\n\n- Includes the query in the blog title, H2 header, and early in the introduction.\n- Incorporates all details from the research findings, including source URLs for potential hyperlinks.\n- Is detailed and informative, showcasing the companies expertise in AI consulting and n8n workflows to automate business processes.\n- Uses a professional yet engaging tone, highlighting the exciting developments and challenges in the recruitment industry.\n- Flows naturally and logically, making it easy for readers to follow.\n- Is between 1500 to 2000 words long.\n- Is written at a level accessible to HR professionals and business leaders.\n\nAdditional requirements:\n- Include practical takeaways or actionable advice for recruiters and HR professionals.\n- Highlight how the topic relates to the companies services or expertise.\n- Include a call-to-action (CTA) that encourages readers to explore the comapnies services or contact for more information.\n\nCreate the entire blog post draft in your first output. Don't stop or cut it short.\n\nYour output must be the blog post and nothing else.\n\nHere are the details of this blog post project:\n\nQuery:\n{{ $('On form submission').item.json['Research Query'] }}\n\nDetailed Research:\n{{ $('Cleanup Links').item.json.research }}\n\n\n","options":{},"promptType":"define"},"typeVersion":1.8},{"id":"1ee6bb8f-6441-4ed9-83e0-d0839b2d0e01","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[-980,540],"parameters":{"color":7,"width":440,"height":440,"content":"## Create Title, Slug & Meta\n\n\n"},"typeVersion":1},{"id":"cc53a2af-ef22-446b-a9ee-b6f4ee649865","name":"Cleanup HTML ","type":"n8n-nodes-base.set","position":[-220,820],"parameters":{"options":{},"assignments":{"assignments":[{"id":"0afb2988-1481-4b04-b16d-fb33c50a16d0","name":"content","type":"string","value":"={{ $json.data[0].message.content.replaceAll('```html', '').replaceAll('```','') }}"}]}},"typeVersion":3.4},{"id":"b31c8afe-e402-49c4-ba49-ee418cecc44e","name":"GET Image","type":"n8n-nodes-base.httpRequest","position":[-720,1120],"parameters":{"url":"={{ $json['image-url'] }}","options":{}},"typeVersion":4.2},{"id":"1089466a-1307-4f22-a242-d324c9165379","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-980,1020],"parameters":{"width":820,"height":280,"content":"## Set Image for Wordpress Post"},"typeVersion":1},{"id":"288e212b-5aa5-452e-87d6-ae06c6ad062a","name":"Set Image URL","type":"n8n-nodes-base.set","position":[-920,1120],"parameters":{"options":{},"assignments":{"assignments":[{"id":"1f0541df-05ab-4e3d-a5d8-3904579fc8a9","name":"image-url","type":"string","value":"=https://smartcdn.gprod.postmedia.digital/healthing/wp-content/uploads/2024/07/GettyImages-1455799246.jpg?quality=90&strip=all&w=704&h=395"}]}},"typeVersion":3.4},{"id":"38bf38e5-888e-4d63-a48e-e6affab28158","name":"Send Success Message to Telegram","type":"n8n-nodes-base.telegram","position":[-80,1120],"webhookId":"91f7d710-450a-4b66-8e46-82f53492351e","parameters":{"text":"=Success! Your blog post was created at {{ $now }}","chatId":"={{ $env.TELEGRAM_CHAT_ID }}","additionalFields":{"appendAttribution":false}},"credentials":{"telegramApi":{"id":"pAIFhguJlkO3c7aQ","name":"Telegram account"}},"typeVersion":1.2},{"id":"30f0fa84-9918-4bf6-86e4-ef8f1dcf079c","name":"gpt-4o-mini","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[-1360,760],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"jEMSvKmtYfzAkhe6","name":"OpenAi account"}},"typeVersion":1.2},{"id":"d2d83cc5-1502-4b04-ac12-0bb351a90e58","name":"Combine Blog Details","type":"n8n-nodes-base.aggregate","position":[-220,560],"parameters":{"options":{},"aggregate":"aggregateAllItemData"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"4209c818-8b02-453e-9254-c70bde66f743","connections":{"Merge":{"main":[[{"node":"Combine Blog Details","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}]]},"Create HTML":{"main":[[{"node":"Merge","type":"main","index":0}]]},"gpt-4o-mini":{"ai_languageModel":[[{"node":"Copywriter AI Agent","type":"ai_languageModel","index":0}]]},"Cleanup HTML ":{"main":[[{"node":"Wordpress","type":"main","index":0}]]},"Cleanup Links":{"main":[[{"node":"Copywriter AI Agent","type":"main","index":0}]]},"Set Image URL":{"main":[[{"node":"GET Image","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Create Title, Slug, Meta","type":"ai_languageModel","index":0}]]},"On form submission":{"main":[[{"node":"Perplexity Research","type":"main","index":0}]]},"Copywriter AI Agent":{"main":[[{"node":"Create HTML","type":"main","index":0},{"node":"Create Title, Slug, Meta","type":"main","index":0},{"node":"Merge","type":"main","index":1}]]},"Perplexity Research":{"main":[[{"node":"Cleanup Links","type":"main","index":0}]]},"Combine Blog Details":{"main":[[{"node":"Cleanup HTML ","type":"main","index":0}]]},"Create Title, Slug, Meta":{"main":[[{"node":"Merge","type":"main","index":2}]]},"Structured Output Parser":{"ai_outputParser":[[{"node":"Create Title, Slug, Meta","type":"ai_outputParser","index":0}]]},"Upload Image to Wordpress":{"main":[[{"node":"Set Image on Wordpress Post","type":"main","index":0}]]},"Set Image on Wordpress Post":{"main":[[{"node":"Send Success Message to Telegram","type":"main","index":0}]]}}}


name: Automate Product Training & Customer Support via WhatsApp, GPT-4 & Google Sheets
author_name: Dr. Firas
author_username: drfiras
categories: []
created_at: 2025-03-30T16:46:52.017Z
updated_at: 2025-03-30T16:46:52.017Z
url: https://n8n.io/workflows/3379
scraped_at: 2025-06-19 22:07:56
description:
  WhatsApp AI Agent: Auto-Train Product Data & Handle Customer Support

  Who Is This For

  This workflow is ideal for eCommerce founders, product managers, customer support teams, and automation builders who rely on WhatsApp to manage product information and interact with clients.

  It’s perfect for businesses that want to automate product data entry and support responses directly from WhatsApp messages using GPT-4 and Google Sheets.

  What Problem Does This Workflow Solve

  Manual Product Data Entry**: Collecting and organizing product data from links is tedious and error-prone.  
  Slow Customer Response Times**: Responding to client questions manually leads to delays and inconsistent support.  
  No Logging System for Issues**: Without automation, support issues often go undocumented, making it harder to learn and improve.

  What This Workflow Does

  Step 1 – Incoming Message Detection
  Listens for incoming messages via WhatsApp.
  If the message starts with train:, it routes to the product training process.
  Otherwise, it routes to the customer support assistant.

  Step 2 – Product Data Training
  Extracts URL** from the message using a regex script.
  Fetches HTML content** from the URL.
  Cleans HTML data** to extract readable product description.
  Saves raw data** (URL + description) into Google Sheets.
  Uses GPT-4** to enhance product data:  
    → Name, price (one-time or subscription), topic, and FAQs.  
  Updates the product row** in Google Sheets with structured information.

  Step 3 – Customer Support Flow
  Analyzes user messages with GPT-4 to understand the request or issue.
  Looks up relevant product info in Google Sheets.
  Detects potential problems (e.g. payment, login, delivery).
  Suggests an appropriate solution.
  Logs the problem, solution, and category to the Customer Issues sheet.
  Sends a response back to the client via WhatsApp.

  Step 4 – Client Response
  Sends the AI-generated response to the client via WhatsApp.
  Keeps the communication fast, clear, and professional.

  Setup Guide

  Prerequisites

  WhatsApp Business API access**
  OpenAI API Key**
  Google Account** with Google Sheets access
  A hosted instance of n8n (Cloud or self-hosted)

  Setup Steps

  Import the Workflow into your n8n instance.
  Connect your credentials for WhatsApp, OpenAI, and Google Sheets.
  Customize Google Sheet IDs and names as needed.
  Test by sending a train: message or a regular customer message to WhatsApp.
  Activate the workflow to make it live.

  How to Customize This Workflow

  Edit AI prompts** to reflect your product type, language style, or tone.
  Change the trigger keyword** (e.g. from train: to add: or anything else).
  Add integrations** like Notion, Airtable, or CRM tools.
  Expand the Sheets structure** with more product fields (e.g. stock status, image link).
  Add notifications** to Slack or email after product updates or issue logging.

  📄 Documentation: Notion Guide

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

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

workflow_json:
  {"id":"GvlLeSOUPfar0DQS","meta":{"instanceId":"a2b23892dd6989fda7c1209b381f5850373a7d2b85609624d7c2b7a092671d44","templateCredsSetupCompleted":true},"name":"Automate Product Data Collection & Customer Support via WhatsApp + GPT-4 + Google Sheets","tags":[],"nodes":[{"id":"370611ee-2725-4ee4-a73a-68d4eaabfe3a","name":"WhatsApp Business Cloud","type":"n8n-nodes-base.whatsApp","position":[1020,220],"webhookId":"ef261fd4-e3b8-42e9-a0e2-2c3c44b6b15e","parameters":{"textBody":"={{ $json.output }}","operation":"send","phoneNumberId":"574583382412256","additionalFields":{},"recipientPhoneNumber":"+212722542056"},"credentials":{"whatsAppApi":{"id":"TzeEzaeiZOOqcLOZ","name":"WhatsApp account"}},"typeVersion":1},{"id":"30520fe8-a423-4942-85b2-9e8776b45939","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[-740,-20],"parameters":{"width":400,"height":440,"content":"## 🟡 STEP 1 – Incoming WhatsApp Message\nListens for new WhatsApp messages.\nIf the message starts with train:, it triggers the product training flow.\nOtherwise, it goes to the customer support flow.\n**WhatsApp Business Cloud node** : [Here](https://www.notion.so/automatisation/WHATSAPP-WORKFLOW-1c63d6550fd980559679e7535938a68d?pvs=4#1c63d6550fd980f9a2a5e25a3654da82)"},"typeVersion":1},{"id":"d3259e0e-5368-407d-8ac6-993784c939c9","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-300,280],"parameters":{"color":6,"width":1180,"height":420,"content":"## 🔵 STEP 3 – Customer Support Flow\nTriggered when the message **does NOT start with `train:`**.\n\n1. **AI Analyzes the Message**  \n   Understands the customer's question or problem.\n\n2. **Fetch Product Data if Needed**  \n   Reads relevant product info from Google Sheets.\n\n3. **Detect Issues Automatically**  \n   Identifies if the user is facing a specific issue.\n\n4. **Suggest Solutions**  \n   Proposes a helpful, clear response to solve the issue.\n\n5. **Log Customer Problems**  \n   Saves the problem, suggested solution, and category.\n\n6. **Respond to the User**  \n   Sends a professional and helpful WhatsApp reply."},"typeVersion":1},{"id":"455ce4ab-6d14-4d4e-8ff8-04612cf532b9","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-300,-400],"parameters":{"color":3,"width":1180,"height":660,"content":"## 🔴 STEP 2 – Product Data Training (Triggered by train:)\nTriggered when the message starts with `train:`.\n**OpenAI API keys** : [Here](https://platform.openai.com/api-keys)\n\n\n\n\n\n\n\n\n\n\n\n\n1. **Extract URL from Message**  \n   Uses regex to detect and extract the product link.\n\n2. **Fetch HTML Content**  \n   Sends an HTTP request to retrieve the full page content.\n\n3. **Clean HTML Data**  \n   Strips HTML tags, scripts, and formats the text.\n\n4. **Save Raw Product Info**  \n   Appends the cleaned content and URL into Google Sheets.\n\n5. **AI: Enhance Product Details**  \n   - Extracts Product Name  \n   - Detects Price (subscription or one-time)  \n   - Identifies Product Topic  \n   - Generates FAQs\n\n6. **Update Product Sheet**  \n   Enriches the row in Sheets with structured product data.\n"},"typeVersion":1},{"id":"15251a04-a139-4a71-9e96-d5ecd9c2e66c","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[920,-20],"parameters":{"color":4,"width":320,"height":440,"content":"## 🟢 STEP 4 – Client Response\nFinal step of the flow.\n\n- Sends the AI-generated response back to the customer via WhatsApp.\n- Ensures the message is clear, helpful, and personalized."},"typeVersion":1},{"id":"f028f5a3-fed3-4f90-89cc-2af211da7362","name":"Incoming Message Trigger","type":"n8n-nodes-base.whatsAppTrigger","position":[-700,220],"webhookId":"48ce9bac-c7ea-4cb7-a40a-b010ea5ac743","parameters":{"options":{},"updates":["messages"]},"credentials":{"whatsAppTriggerApi":{"id":"zYvcHcxGBNdN9Ptf","name":"WhatsApp OAuth account"}},"typeVersion":1},{"id":"54edaa0c-005e-4810-a2fa-76fbcc009b2b","name":"Check If Training","type":"n8n-nodes-base.switch","position":[-520,220],"parameters":{"rules":{"values":[{"outputKey":"train","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"9865cb5b-33da-490c-afc3-186457d5b564","operator":{"type":"string","operation":"startsWith"},"leftValue":"={{ $json.messages[0].text.body }}","rightValue":"train:"}]},"renameOutput":true},{"outputKey":"text","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"5a9a1fee-b408-469f-a08c-e8d690fc9792","operator":{"type":"string","operation":"notStartsWith"},"leftValue":"={{ $json.messages[0].text.body }}","rightValue":"train:"}]},"renameOutput":true}]},"options":{}},"typeVersion":3.2},{"id":"b4187b28-efd9-46cb-8d1c-23d89d3f6125","name":"Extract URL from Text","type":"n8n-nodes-base.code","position":[-260,-320],"parameters":{"jsCode":"// Récupérer le texte à analyser depuis l'input\nconst texteExemple = $input.first().json.messages[0].text.body;\n\n// Expression régulière modifiée pour capturer les URL avec ou sans protocole\nconst regex = /((?:https?:\\/\\/)?(?:www\\.)?[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}(?:\\/\\S*)?)/g;\n\n// Extraction des URL à partir du texte\nconst matches = texteExemple.match(regex) || [];\n\n// Si des URL ont été trouvées, on les mappe en objets\nif (matches.length > 0) {\n    const output = matches.map(url => ({ url }));\n    return output;\n} else {\n    // Si aucune URL n'est trouvée, on retourne les items d'entrée pour que le workflow continue\n    return $input.all();\n}\n"},"typeVersion":2},{"id":"dbbcc8cf-2544-4de1-bcfd-6292d96a1017","name":"Fetch HTML Page","type":"n8n-nodes-base.httpRequest","position":[-100,-320],"parameters":{"url":"={{ $json.url }}","options":{"response":{"response":{"responseFormat":"text"}}}},"typeVersion":4.2},{"id":"91e711d0-26c0-41dd-a9c5-28100f0f44f6","name":"Clean HTML Content","type":"n8n-nodes-base.code","position":[60,-320],"parameters":{"jsCode":"// Exemple : récupération du contenu HTML depuis le premier item\n// Si vous avez un champ nommé \"html\" dans un noeud précédent.\nconst htmlContent = $input.first().json.html;\n\n// Fonction de nettoyage du HTML\nfunction nettoyerHTML(input) {\n  if (typeof input !== 'string') {\n    throw new Error(\"Expected HTML content as a string.\");\n  }\n  let cleanedText = input;\n\n  // 1. Retirer les liens <a> et leur contenu\n  cleanedText = cleanedText.replace(/<a[^>]*>.*?<\\/a>/gs, '');\n\n  // 2. Retirer <script>, <style>, commentaires, etc.\n  cleanedText = cleanedText.replace(/<script[^>]*>.*?<\\/script>/gs, '');\n  cleanedText = cleanedText.replace(/<style[^>]*>.*?<\\/style>/gs, '');\n  cleanedText = cleanedText.replace(/<!--[\\s\\S]*?-->/g, '');\n\n  // 3. Insérer des retours à la ligne pour certaines balises\n  cleanedText = cleanedText.replace(/<h[1-6][^>]*>/gi, '\\n');\n  cleanedText = cleanedText.replace(/<\\/h[1-6]>/gi, '\\n');\n  cleanedText = cleanedText.replace(/<p[^>]*>/gi, '\\n');\n  cleanedText = cleanedText.replace(/<\\/p>/gi, '\\n');\n  cleanedText = cleanedText.replace(/<ul[^>]*>/gi, '\\n');\n  cleanedText = cleanedText.replace(/<\\/ul>/gi, '\\n');\n  cleanedText = cleanedText.replace(/<ol[^>]*>/gi, '\\n');\n  cleanedText = cleanedText.replace(/<\\/ol>/gi, '\\n');\n  cleanedText = cleanedText.replace(/<li[^>]*>/gi, '- ');\n  cleanedText = cleanedText.replace(/<\\/li>/gi, '\\n');\n\n  // 4. Supprimer toutes les balises HTML restantes\n  cleanedText = cleanedText.replace(/<[^>]+>/g, '');\n\n  // 5. Supprimer (ou ajuster) les caractères spéciaux\n  cleanedText = cleanedText.replace(/[^\\w\\sÀ-ÖØ-öø-ÿ]+/g, '');\n\n  // 6. Normaliser les espaces multiples et trim\n  cleanedText = cleanedText.replace(/\\s+/g, ' ').trim();\n\n  return cleanedText;\n}\n\n// Nettoyage\nconst result = nettoyerHTML($input.first().json.data);\n\n// Retour d'un tableau contenant l'objet final\nreturn [\n  {\n    json: {\n      cleanedText: result\n    }\n  }\n];\n"},"typeVersion":2},{"id":"7e457450-42ef-417e-b5f9-3248c9c7c2ae","name":"Save Raw Product Info","type":"n8n-nodes-base.googleSheets","position":[240,-320],"parameters":{"columns":{"value":{"Product Link":"={{ $('Extract URL from Text').item.json.url }}","Product Description":"={{ $json.cleanedText }}"},"schema":[{"id":"Product Link","type":"string","display":true,"required":false,"displayName":"Product Link","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Product Name","type":"string","display":true,"required":false,"displayName":"Product Name","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Product Price","type":"string","display":true,"required":false,"displayName":"Product Price","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Product Description","type":"string","display":true,"required":false,"displayName":"Product Description","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Product Topic","type":"string","display":true,"required":false,"displayName":"Product Topic","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"list","value":689245338,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/1wa41S888Ya3sqEkBdzYiDq-5FOu_V30BOe-toX_78xQ/edit#gid=689245338","cachedResultName":"Products"},"documentId":{"__rl":true,"mode":"list","value":"1wa41S888Ya3sqEkBdzYiDq-5FOu_V30BOe-toX_78xQ","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1wa41S888Ya3sqEkBdzYiDq-5FOu_V30BOe-toX_78xQ/edit?usp=drivesdk","cachedResultName":"Product Sales - AI Agent WhatsApp"}},"credentials":{"googleSheetsOAuth2Api":{"id":"51us92xkOlrvArhV","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"d3dfa439-4056-4ce9-b874-100500967de6","name":"OpenAI Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[320,-40],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"6h3DfVhNPw9I25nO","name":"OpenAi account"}},"typeVersion":1.2},{"id":"10217317-f6dd-4890-b05d-197d3d2adb79","name":"Short-Term Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[500,-40],"parameters":{"sessionKey":"={{ $('Incoming Message Trigger').item.json.messages[0].id }}","sessionIdType":"customKey","contextWindowLength":50},"typeVersion":1.3},{"id":"58ce0f46-fabc-4b6e-97d7-857dc6f1e568","name":"Update Product Sheet","type":"n8n-nodes-base.googleSheetsTool","position":[680,-40],"parameters":{"columns":{"value":{"F&Q":"={{ $fromAI(\"product_faq\", \"these are the most common questions users might have about the product, including answers if available\") }}\n","Product Link":"={{ $fromAI(\"product_url\",\"this is the website link of the product\") }}","Product Name":"={{ $fromAI(\"product_name\",\"this is the name of the product\") }}","Product Price":"={{ $fromAI(\"product_price\",\"this is the price of the product\") }}","Product Topic":"={{ $fromAI(\"product_topic\",\"this is the topic of the product that specifies what it is for, who it is for and what the key benefits are\") }}"},"schema":[{"id":"Product Link","type":"string","display":true,"removed":false,"required":false,"displayName":"Product Link","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Product Name","type":"string","display":true,"required":false,"displayName":"Product Name","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Product Price","type":"string","display":true,"required":false,"displayName":"Product Price","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Product Description","type":"string","display":true,"removed":true,"required":false,"displayName":"Product Description","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Product Topic","type":"string","display":true,"required":false,"displayName":"Product Topic","defaultMatch":false,"canBeUsedToMatch":true},{"id":"F&Q","type":"string","display":true,"removed":false,"required":false,"displayName":"F&Q","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["Product Link"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"appendOrUpdate","sheetName":{"__rl":true,"mode":"list","value":689245338,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/1wa41S888Ya3sqEkBdzYiDq-5FOu_V30BOe-toX_78xQ/edit#gid=689245338","cachedResultName":"Products"},"documentId":{"__rl":true,"mode":"list","value":"1wa41S888Ya3sqEkBdzYiDq-5FOu_V30BOe-toX_78xQ","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1wa41S888Ya3sqEkBdzYiDq-5FOu_V30BOe-toX_78xQ/edit?usp=drivesdk","cachedResultName":"Product Sales - AI Agent WhatsApp"}},"credentials":{"googleSheetsOAuth2Api":{"id":"51us92xkOlrvArhV","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"020714ae-5668-4fa5-8ba8-f1e476a8060e","name":"AI Agent -  Customer Support Agent","type":"@n8n/n8n-nodes-langchain.agent","position":[380,300],"parameters":{"text":"={{ $json.messages[0].text.body }}","options":{"systemMessage":"You are a helpful and intelligent customer support assistant.\n\nYou have access to a Google Sheets tool that allows you to read any content from a specific sheet to gather necessary information.\nNever mention to the user that you accessed Google Sheets to retrieve any data.\n\nYour main responsibilities:\n\nUnderstand the user’s request or issue.\n\nIf the user is asking about a product, retrieve the relevant product name, price, and details as needed.\n\nDetermine whether the product price is a subscription or a one-time payment, based on the description.\n\nIf you detect that the user is facing a problem:\n\nIdentify and describe the problem clearly.\n\nPropose a practical and helpful solution.\n\nLog this interaction by adding a new row to the Google Sheet with the following columns:\n\nProblem\n\nSuggested Solution\n\nCategory (e.g., payment, login, access, delivery, technical issue, etc.)\n\nBe professional, concise, and empathetic in your responses.\nAlways aim to resolve the issue or provide the next best action."},"promptType":"define"},"typeVersion":1.7},{"id":"53e49985-e1b9-48fd-9ea8-3352a63484e0","name":"AI Agent - Enhance Product Details","type":"@n8n/n8n-nodes-langchain.agent","position":[420,-320],"parameters":{"text":"=My product description :  {{ $json['Product Description'] }}\n\nMy product link : {{ $json['Product Link'] }}","options":{"systemMessage":"You are a helpful and intelligent assistant.\n\nYou receive the text content of a product page.\n\nYour tasks are:\n\nExtract the product name.\n\nExtract the product price, and determine whether it is a subscription or a one-time payment.\n\nIdentify the product topic.\n\nExtract the most frequently asked questions (FAQs) related to the product.\n\nYou have access to a Google Sheets tool that allows you to update specific columns and cells.\n\nAlways add the following data to the same row as the product URL in the Google Sheet:\n\nProduct Name\n\nProduct Price (with subscription/one-time label)\n\nProduct Topic\n\nFAQs\n\nBe accurate, structured, and consistent when filling in the sheet.\nDo not mention Google Sheets in your responses."},"promptType":"define"},"typeVersion":1.8},{"id":"194136b5-872a-492b-882b-d26a2890cbcf","name":"OpenAI Model1","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[220,560],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini"},"options":{}},"credentials":{"openAiApi":{"id":"6h3DfVhNPw9I25nO","name":"OpenAi account"}},"typeVersion":1.2},{"id":"efc89a9b-3141-4735-adaf-7b9e2b6879ed","name":"Conversation Memory","type":"@n8n/n8n-nodes-langchain.memoryBufferWindow","position":[400,560],"parameters":{"sessionKey":"={{ $json.messages[0].id }}","sessionIdType":"customKey","contextWindowLength":50},"typeVersion":1.3},{"id":"d1a21094-0237-4b17-818c-3af7760b405f","name":"Read Product Sheet","type":"n8n-nodes-base.googleSheetsTool","position":[560,560],"parameters":{"options":{"dataLocationOnSheet":{"values":{"readRowsUntil":"firstEmptyRow","rangeDefinition":"detectAutomatically"}}},"sheetName":{"__rl":true,"mode":"list","value":689245338,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/1wa41S888Ya3sqEkBdzYiDq-5FOu_V30BOe-toX_78xQ/edit#gid=689245338","cachedResultName":"Products"},"documentId":{"__rl":true,"mode":"list","value":"1wa41S888Ya3sqEkBdzYiDq-5FOu_V30BOe-toX_78xQ","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1wa41S888Ya3sqEkBdzYiDq-5FOu_V30BOe-toX_78xQ/edit?usp=drivesdk","cachedResultName":"Product Sales - AI Agent WhatsApp"}},"credentials":{"googleSheetsOAuth2Api":{"id":"51us92xkOlrvArhV","name":"Google Sheets account"}},"typeVersion":4.5},{"id":"2c2dcf9b-5578-4bd4-85b6-27621927a0a0","name":"Log Customer Issues","type":"n8n-nodes-base.googleSheetsTool","position":[740,560],"parameters":{"columns":{"value":{"Category":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Category', ``, 'string') }}","Solution":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Solution', ``, 'string') }}","Support Problem":"={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Support_Problem', ``, 'string') }}"},"schema":[{"id":"Support Problem","type":"string","display":true,"required":false,"displayName":"Support Problem","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Solution","type":"string","display":true,"required":false,"displayName":"Solution","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Category","type":"string","display":true,"required":false,"displayName":"Category","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"list","value":1725207764,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/1wa41S888Ya3sqEkBdzYiDq-5FOu_V30BOe-toX_78xQ/edit#gid=1725207764","cachedResultName":"Customer Issues"},"documentId":{"__rl":true,"mode":"list","value":"1wa41S888Ya3sqEkBdzYiDq-5FOu_V30BOe-toX_78xQ","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1wa41S888Ya3sqEkBdzYiDq-5FOu_V30BOe-toX_78xQ/edit?usp=drivesdk","cachedResultName":"Product Sales - AI Agent WhatsApp"}},"credentials":{"googleSheetsOAuth2Api":{"id":"51us92xkOlrvArhV","name":"Google Sheets account"}},"typeVersion":4.5}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"2e8ea310-e164-4d5d-ae0b-ade129b07a4a","connections":{"OpenAI Model":{"ai_languageModel":[[{"node":"AI Agent - Enhance Product Details","type":"ai_languageModel","index":0}]]},"OpenAI Model1":{"ai_languageModel":[[{"node":"AI Agent -  Customer Support Agent","type":"ai_languageModel","index":0}]]},"Fetch HTML Page":{"main":[[{"node":"Clean HTML Content","type":"main","index":0}]]},"Check If Training":{"main":[[{"node":"Extract URL from Text","type":"main","index":0}],[{"node":"AI Agent -  Customer Support Agent","type":"main","index":0}]]},"Short-Term Memory":{"ai_memory":[[{"node":"AI Agent - Enhance Product Details","type":"ai_memory","index":0}]]},"Clean HTML Content":{"main":[[{"node":"Save Raw Product Info","type":"main","index":0}]]},"Read Product Sheet":{"ai_tool":[[{"node":"AI Agent -  Customer Support Agent","type":"ai_tool","index":0}]]},"Conversation Memory":{"ai_memory":[[{"node":"AI Agent -  Customer Support Agent","type":"ai_memory","index":0}]]},"Log Customer Issues":{"ai_tool":[[{"node":"AI Agent -  Customer Support Agent","type":"ai_tool","index":0}]]},"Update Product Sheet":{"ai_tool":[[{"node":"AI Agent - Enhance Product Details","type":"ai_tool","index":0}]]},"Extract URL from Text":{"main":[[{"node":"Fetch HTML Page","type":"main","index":0}]]},"Save Raw Product Info":{"main":[[{"node":"AI Agent - Enhance Product Details","type":"main","index":0}]]},"WhatsApp Business Cloud":{"main":[[]]},"Incoming Message Trigger":{"main":[[{"node":"Check If Training","type":"main","index":0}]]},"AI Agent -  Customer Support Agent":{"main":[[{"node":"WhatsApp Business Cloud","type":"main","index":0}]]},"AI Agent - Enhance Product Details":{"main":[[{"node":"WhatsApp Business Cloud","type":"main","index":0}]]}}}


name: Automate Call Scheduling with Voice AI Receptionist using Vapi, Google Calendar & Airtable
author_name: SuperAgent
author_username: customaistudio
nodes_used: ["n8n-nodes-base.airtable","n8n-nodes-base.googleCalendar","n8n-nodes-base.code"]
categories: []
created_at: 2025-04-03T19:05:21.114Z
updated_at: 2025-04-03T19:05:21.114Z
url: https://n8n.io/workflows/3427
scraped_at: 2025-06-19 22:07:56
description:
  Who is this template for?

  This template is ideal for small businesses, agencies, and solo professionals who want to automate appointment scheduling and caller follow-up through a voice-based AI receptionist. If you’re using tools like Google Calendar, Airtable, and Vapi (Twilio), this setup is for you.

  What problem does this workflow solve?

  Manual call handling, appointment booking, and email coordination can be time-consuming and prone to errors. This workflow solves that by automating the receptionist role: answering calls, checking calendar availability, managing appointments, and storing call summaries—all without human intervention.

  What this workflow does

  This Agent Receptionist manages inbound voice calls and scheduling tasks using Vapi and Google Calendar. It checks availability, books or updates calendar events, sends email confirmations, and logs call details into Airtable. The workflow includes built-in logic for slot management, email triggers, and storing call transcripts. 

  Setup Instructions

  Duplicate Airtable Base: Use this Airtable base templateBASE LINK 

  Import Workflow: Load provided JSON into your n8n instance.

  Credentials: Connect your Google Calendar and Airtable credentials in n8n.

  Activate Workflow: Enable workflow to get live webhook URLs.

  Vapi Configuration:

  Paste provided system prompt into Vapi Assistant. 

  Link the appropriate webhook URLs from n8n (GetSlots, BookSlots, UpdateSlots, CancelSlots, and end-of-call report).



  Disclaimer

  Optimized for cloud-hosted n8n instances. Self-hosted users should verify webhook and credential setups.

workflow_json:
  {"meta":{"instanceId":"1954c8c806bedb8f0628725b26b786028ade16c78a82bc25deb9dd961e036832"},"nodes":[{"id":"36d0b0d4-b454-4a9b-8168-bcc7942a7cc7","name":"Input Arguments","type":"n8n-nodes-base.set","position":[520,740],"parameters":{"options":{},"assignments":{"assignments":[{"id":"ccabe9f4-7911-4488-a75b-7c5779fb2014","name":"timeZone","type":"string","value":"=America/Chicago"},{"id":"b802d976-78f5-4c00-8764-f8c49eaded29","name":"endtime","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.endtime }}"},{"id":"02d58122-6a0f-4bdb-9914-6f50d2af6df4","name":"starttime","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.starttime }}"},{"id":"c1249493-a1d7-4a91-9468-9e5c49430d2e","name":"body.message.toolCalls[0].id","type":"string","value":"={{ $json.body.message.toolCalls[0].id }}"},{"id":"2d1e0d9a-4c70-488e-b430-b8137fd54970","name":"customer.number","type":"string","value":"={{ $json.body.message.call.customer.number }}"}]}},"typeVersion":3.3},{"id":"2d8485ad-9007-4664-9182-7eda25fc96ee","name":"Format response","type":"n8n-nodes-base.itemLists","position":[2000,840],"parameters":{"include":"allFieldsExcept","options":{},"aggregate":"aggregateAllItemData","operation":"concatenateItems","fieldsToExclude":"sort","destinationFieldName":"response"},"typeVersion":3},{"id":"b23c75e0-3697-4137-a595-cf26fedaa898","name":"Sort","type":"n8n-nodes-base.itemLists","position":[1760,840],"parameters":{"options":{},"operation":"sort","sortFieldsUi":{"sortField":[{"fieldName":"sort"}]}},"typeVersion":3},{"id":"660e3d2f-a424-4e76-8c13-5b62b9f22202","name":"Available Start Times & Ranges","type":"n8n-nodes-base.code","position":[2240,840],"parameters":{"jsCode":"// Input data\nconst inputData = $input.all()[0].json.response;\n\n// Define workday hours in CST\nconst WORKDAY_START = \"09:00:00 CST\";\nconst WORKDAY_END = \"18:00:00 CST\";\nconst SLOT_DURATION = 30 * 60 * 1000; // 30 minutes in milliseconds\n\n// Helper to parse CST datetime strings\nconst parseCST = (datetime) => {\n  const parsedDate = new Date(datetime.replace(\" CST\", \"-06:00\"));\n  return isNaN(parsedDate) ? null : parsedDate;\n};\n\n// Function to generate 30-minute start times\nconst generateStartTimes = (start, end) => {\n  const startTimes = [];\n  let current = new Date(start);\n\n  while (current < end) {\n    startTimes.push(\n      current.toLocaleTimeString('en-US', {\n        timeZone: 'CST',\n        hour: '2-digit',\n        minute: '2-digit',\n      })\n    );\n    current = new Date(current.getTime() + SLOT_DURATION);\n  }\n\n  return startTimes;\n};\n\n// Function to find wide open ranges\nconst findWideOpenRanges = (startTimes) => {\n  if (startTimes.length < 3) return []; // Not enough slots for a wide open range\n\n  const ranges = [];\n  let rangeStart = null;\n  let consecutiveCount = 0;\n\n  for (let i = 0; i < startTimes.length - 1; i++) {\n    const currentTime = parseCST(`2000-01-01 ${startTimes[i]} CST`);\n    const nextTime = parseCST(`2000-01-01 ${startTimes[i + 1]} CST`);\n    const diff = nextTime - currentTime;\n\n    if (diff === SLOT_DURATION) {\n      consecutiveCount += 1;\n      if (rangeStart === null) rangeStart = startTimes[i];\n    } else {\n      if (consecutiveCount >= 2) {\n        ranges.push(`${rangeStart} to ${startTimes[i]}`);\n      }\n      rangeStart = null;\n      consecutiveCount = 0;\n    }\n  }\n\n  // Handle the final range\n  if (consecutiveCount >= 2) {\n    ranges.push(`${rangeStart} to ${startTimes[startTimes.length - 1]}`);\n  }\n\n  return ranges;\n};\n\n// Group meetings by date, ignoring invalid dates\nconst meetingsByDate = inputData.reduce((acc, meeting) => {\n  const start = parseCST(meeting.start);\n  const end = parseCST(meeting.end);\n\n  if (!start || !end) {\n    return acc; // Ignore invalid dates\n  }\n\n  const dateKey = start.toISOString().split('T')[0];\n\n  if (!acc[dateKey]) {\n    acc[dateKey] = [];\n  }\n\n  acc[dateKey].push({ start, end });\n  return acc;\n}, {});\n\n// Generate availability\nconst availability = Object.keys(meetingsByDate)\n  .filter((date) => {\n    // Exclude Saturdays (6) and Sundays (0)\n    const dayOfWeek = new Date(date).getUTCDay();\n    return dayOfWeek !== 0 && dayOfWeek !== 6;\n  })\n  .map((date) => {\n    const workdayStart = parseCST(`${date} ${WORKDAY_START}`);\n    const workdayEnd = parseCST(`${date} ${WORKDAY_END}`);\n\n    const dayMeetings = meetingsByDate[date].sort((a, b) => a.start - b.start);\n\n    let availableStartTimes = [];\n    let lastEnd = workdayStart;\n\n    for (const meeting of dayMeetings) {\n      if (meeting.start > lastEnd) {\n        availableStartTimes = availableStartTimes.concat(generateStartTimes(lastEnd, meeting.start));\n      }\n      lastEnd = meeting.end > lastEnd ? meeting.end : lastEnd;\n    }\n\n    if (lastEnd < workdayEnd) {\n      availableStartTimes = availableStartTimes.concat(generateStartTimes(lastEnd, workdayEnd));\n    }\n\n    const wideOpenRanges = findWideOpenRanges(availableStartTimes);\n\n    return {\n      date: new Date(date).toLocaleDateString('en-US', {\n        weekday: 'long',\n        year: 'numeric',\n        month: 'long',\n        day: 'numeric',\n      }),\n      availableStartTimes,\n      wideOpenRanges,\n    };\n  });\n\n// Format output as plaintext\nconst availableTimes = availability\n  .map(({ date, availableStartTimes, wideOpenRanges }) => {\n    const times = availableStartTimes.map((time) => `- ${time}`).join('\\n');\n    const ranges = wideOpenRanges.length\n      ? `Wide Open Ranges:\\n${wideOpenRanges.map((range) => `- ${range}`).join('\\n')}`\n      : \"Wide Open Ranges: None\";\n\n    return `### ${date}\\nAvailable Start Times:\\n${times}\\n\\n${ranges}`;\n  })\n  .join('\\n\\n');\n\n// Set the output\nreturn {\n  json: {\n    availableTimes,\n  },\n};\n"},"typeVersion":2},{"id":"f3110658-2f90-4b19-9874-7d6c4e108895","name":"Flatten Slots","type":"n8n-nodes-base.code","position":[2460,840],"parameters":{"mode":"runOnceForEachItem","jsCode":"const flattenSlots = (data) => {\n  // If data is missing or empty, return an empty array of slots\n  if (!data) {\n    return { slots: [] };\n  }\n\n  // data is an object whose keys are dates\n  // each date key has an array of slot objects\n  // we just need to flatten them all into one array\n  const flattened = Object.values(data).flat();  // merges all arrays from each date key\n\n  // Return a new object with a single 'slots' array\n  return { slots: flattened };\n};\n\n// Then assign the flattened slots back to $input.item.json.data\n$input.item.json.data = flattenSlots($input.item.json.data);\nreturn $input.item;\n"},"typeVersion":2},{"id":"5065439e-34e3-4eaf-8226-8ba7393a5cf3","name":"Enrich Date","type":"n8n-nodes-base.code","position":[2680,840],"parameters":{"mode":"runOnceForEachItem","jsCode":"function formatTimeSlot(dateString) {\n  // Format options for date/time with America/Chicago timezone\n  const options = {\n    timeZone: 'America/Chicago',\n    weekday: 'long',\n    month: 'long',\n    day: 'numeric',\n    hour: 'numeric',\n    minute: 'numeric',\n    hour12: true\n  };\n\n  // Create a formatter with timezone support\n  const dateFormatter = new Intl.DateTimeFormat('en-US', options);\n  \n  // Format the date/time string\n  return dateFormatter.format(new Date(dateString));\n}\n\n// Process each slot and add formatted time strings to the result\nconst slots = $input.item.json.data.slots;\nconst formattedSlots = slots.map(slot => formatTimeSlot(slot.start));\n\n// Attach formatted results to the output\n$input.item.json.data.slots = formattedSlots;\n\nreturn $input.item;\n"},"typeVersion":2},{"id":"d8ed3a92-697b-4718-b65f-5276c9a9bfaf","name":"Build Response Payload","type":"n8n-nodes-base.set","position":[2900,840],"parameters":{"options":{},"assignments":{"assignments":[{"id":"5cb05b10-e916-459e-84a2-9c314a859a07","name":"results[0].toolCallId","type":"string","value":"={{ $('Input Arguments').item.json.body.message.toolCalls[0].id }}"},{"id":"552246f9-7afd-404e-9fb3-cb38c7447359","name":"results[0].result","type":"string","value":"={{ $json.availableTimes }}"}]}},"typeVersion":3.4},{"id":"a0697944-c5a6-4ca1-9948-8248940841b2","name":"Booking Payload","type":"n8n-nodes-base.set","position":[1980,1400],"parameters":{"options":{"ignoreConversionErrors":true},"assignments":{"assignments":[{"id":"05bbc797-b781-489c-ab70-e234fe17eb62","name":"id","type":"number","value":"={{ $json.id }}"},{"id":"4bb68abf-18c8-4445-b446-21667abd95aa","name":"description","type":"string","value":"={{ $json.description }}"},{"id":"74a98b77-b9fe-40cc-84c8-fc7303c5cfa6","name":"startTime","type":"string","value":"={{ $json.start.dateTime }}"},{"id":"2934d6a7-9e6b-4038-891c-0b05ba18cb21","name":"endTime","type":"string","value":"={{ $json.end.dateTime }}"},{"id":"10f091c8-5e52-40dc-a294-87625be9af99","name":"status","type":"string","value":"={{ $json.status }}"},{"id":"cdc5e1ab-a29b-447f-8343-ff1c1b168717","name":"Timezone","type":"string","value":"={{ $json.end.timeZone }}"},{"id":"f5b6820c-ab4b-496c-9957-f86753243388","name":"attendees","type":"array","value":"={{ $json.attendees }}"},{"id":"b39a06a5-4fbf-4fdf-9d9a-a07dcb37d157","name":"hangoutLink","type":"string","value":"={{ $json.hangoutLink }}"},{"id":"345f49fc-93bc-48b8-9ced-326139a82119","name":"Title","type":"string","value":"={{ $json.summary }}"}]}},"typeVersion":3.4},{"id":"4f7b157c-f657-48fa-8bb5-a1e074b042eb","name":"Success Response","type":"n8n-nodes-base.set","position":[2200,1400],"parameters":{"options":{},"assignments":{"assignments":[{"id":"2c3894da-7bf7-4a35-95c0-d3d9199dd0ad","name":"results[0].toolCallId","type":"string","value":"={{ $('Input Arguments from booking tools').item.json.toolCallId }}"},{"id":"685c67c7-a30b-4bcc-b9ba-827c4b570548","name":"results[0].result","type":"string","value":"={{ $json.status }}"}]}},"typeVersion":3.3},{"id":"b7fe16e3-b625-4cb4-b971-9c26698af89b","name":"Add Friendly Error","type":"n8n-nodes-base.code","position":[1980,1760],"parameters":{"mode":"runOnceForEachItem","jsCode":"function replaceValue(value) {\n  if (error.message.include('no_available_users_found_error')) {\n    return \"This time slot is no longer available.\";\n  }\n  return value;\n}\n\n$input.item.json.message = replaceValue($input.item.json.error.description);\n\nreturn $input.item;"},"typeVersion":2},{"id":"b5bff0df-2bef-4c43-9fcf-91cadc68b7ca","name":"Error Response","type":"n8n-nodes-base.set","position":[2200,1760],"parameters":{"options":{},"assignments":{"assignments":[{"id":"2c3894da-7bf7-4a35-95c0-d3d9199dd0ad","name":"results[0].toolCallId","type":"string","value":"={{ $('Input Arguments from booking tools').item.json.toolCallId }}"},{"id":"93e45166-de94-4fa5-9148-2b8d0e4b960c","name":"results[0].result","type":"string","value":"={{ $json.message || $json.status }}"}]}},"typeVersion":3.3},{"id":"fe62c0bc-2d73-4f14-8e76-02847ef4e14a","name":"Escape Json","type":"n8n-nodes-base.code","position":[1260,1580],"parameters":{"mode":"runOnceForEachItem","jsCode":"const escapeStringForJson = (str) => {\n    return str\n        .replace(/\\\\/g, '\\\\\\\\') // Escape backslashes\n        .replace(/\"/g, '\\\\\"')    // Escape double quotes\n        .replace(/\\n/g, '\\\\n')   // Escape newlines\n        .replace(/\\r/g, '\\\\r')   // Escape carriage returns\n        .replace(/\\t/g, '\\\\t');  // Escape tabs\n};\n\n// Escape the notes field\n$input.item.json.notes = escapeStringForJson($input.item.json.notes);\n\nreturn $input.item;\n"},"typeVersion":2},{"id":"17927aa4-8f91-4134-b914-1160a724226f","name":"Has all information","type":"n8n-nodes-base.if","position":[940,1800],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"e0af7f69-0c89-4a02-a49f-dd5a90e31dff","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ ($json.email || \"\").isEmail() }}","rightValue":""}]}},"typeVersion":2.2},{"id":"6f0bb9e6-9d82-4cc6-a98f-4d00c47ed910","name":"Respond with Error","type":"n8n-nodes-base.respondToWebhook","position":[1480,1900],"parameters":{"options":{}},"typeVersion":1.1},{"id":"fdedba34-a374-405d-a86e-0b0a1759ede9","name":"Build Error Response Payload","type":"n8n-nodes-base.set","position":[1260,1900],"parameters":{"options":{},"assignments":{"assignments":[{"id":"5cb05b10-e916-459e-84a2-9c314a859a07","name":"results[0].toolCallId","type":"string","value":"={{ $('Input Arguments from booking tools').item.json.toolCallId }}"},{"id":"552246f9-7afd-404e-9fb3-cb38c7447359","name":"results[0].result","type":"string","value":"=You must provide an email, name and notes to call this tool"}]}},"typeVersion":3.4},{"id":"1e111f9d-bb43-4126-b7a2-3353e7c7c72f","name":"Build Error Response Payload2","type":"n8n-nodes-base.set","position":[1560,2840],"parameters":{"options":{},"assignments":{"assignments":[{"id":"5cb05b10-e916-459e-84a2-9c314a859a07","name":"results[0].toolCallId","type":"string","value":"={{ $('Input Arguments from updateslot tool').item.json.toolCallId || $json.Calls[0].id }}"},{"id":"552246f9-7afd-404e-9fb3-cb38c7447359","name":"results[0].result","type":"string","value":"=You must provide an email, name , previous starttime & endtime and resceduled starttime to call this tool"}]}},"typeVersion":3.4},{"id":"d6cbad26-d974-4a11-b0fd-2a35bb555378","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[260,620],"parameters":{"color":4,"width":190,"height":80,"content":"# Get Slots"},"typeVersion":1},{"id":"bcccc8cb-2e9d-4f8b-9964-e4d656e794ed","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[740,920],"parameters":{"width":230,"height":80,"content":"## Check Availability\n"},"typeVersion":1},{"id":"30b34e37-ee7a-434c-ab4d-445df994459a","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[1320,520],"parameters":{"width":310,"height":80,"content":"## If time available Respond\n"},"typeVersion":1},{"id":"725a9b59-ea66-4326-a410-93a723157ced","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1280,1020],"parameters":{"width":190,"height":80,"content":"## Get All Events\n"},"typeVersion":1},{"id":"1f2bf4a3-8aeb-4a56-8bff-0bb370e12718","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[2140,1020],"parameters":{"width":350,"height":100,"content":"## Get Available Slots\n\nFormat the slots and Enrich the date and timings\n"},"typeVersion":1},{"id":"5909d88f-b9c6-4e62-b1e3-bdc1d05ad7aa","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[3280,1000],"parameters":{"width":230,"height":80,"content":"## Respond to Vapi"},"typeVersion":1},{"id":"f627c5b0-f3b6-4f95-a3a3-2c1b7e2860c7","name":"Sticky Note BookSlot Webhook","type":"n8n-nodes-base.stickyNote","position":[380,1680],"parameters":{"color":5,"width":190,"height":80,"content":"# Book Slot"},"typeVersion":1},{"id":"9c3e8b9f-3fe3-4380-8cbc-413146d752b9","name":"Sticky Note BookSlot Check","type":"n8n-nodes-base.stickyNote","position":[880,1700],"parameters":{"width":230,"height":80,"content":"Checks if required booking info (email, name, etc.) is provided."},"typeVersion":1},{"id":"c723bbd0-5a04-4efb-ba67-59bc722b9d4e","name":"Sticky Note BookSlot Error","type":"n8n-nodes-base.stickyNote","position":[1440,2060],"parameters":{"width":190,"height":80,"content":"If info missing, sends error back."},"typeVersion":1},{"id":"a843e795-8046-4538-93e0-2de2e688c863","name":"Sticky Note BookSlot GCal","type":"n8n-nodes-base.stickyNote","position":[1660,1740],"parameters":{"width":190,"height":80,"content":"Books the appointment in Google Calendar."},"typeVersion":1},{"id":"a7627281-15fc-438a-b031-b00cbc4b9fa4","name":"Sticky Note BookSlot Error Handle","type":"n8n-nodes-base.stickyNote","position":[1920,1920],"parameters":{"width":230,"height":80,"content":"Handles potential booking errors (e.g., slot taken)."},"typeVersion":1},{"id":"71c0c722-b5df-47d7-97e6-3d23533a4a4e","name":"Sticky Note BookSlot Response","type":"n8n-nodes-base.stickyNote","position":[2420,1740],"parameters":{"width":210,"height":80,"content":"Sends confirmation/error back to Vapi."},"typeVersion":1},{"id":"4e598ebb-cfdb-432f-a01a-bb76d1d20f24","name":"Sticky Note BookSlot Airtable","type":"n8n-nodes-base.stickyNote","position":[3100,1740],"parameters":{"width":230,"height":80,"content":"Logs the confirmed booking details to Airtable."},"typeVersion":1},{"id":"cc085c75-d45f-4453-b78b-1b9b480fb02c","name":"Sticky Note CancelSlot Webhook","type":"n8n-nodes-base.stickyNote","position":[440,3480],"parameters":{"color":3,"width":250,"height":80,"content":"# Cancel Slots"},"typeVersion":1},{"id":"9504b7e8-7964-4a0e-bfa4-32540c1fb895","name":"Sticky Note CancelSlot Check","type":"n8n-nodes-base.stickyNote","position":[960,3780],"parameters":{"width":230,"height":80,"content":"Checks if required info (email, name, start time) is provided."},"typeVersion":1},{"id":"3bb9d976-d922-4016-839c-22e8b1adcf35","name":"Sticky Note CancelSlot Error","type":"n8n-nodes-base.stickyNote","position":[1520,3940],"parameters":{"width":150,"height":80,"content":"If info missing, sends error back."},"typeVersion":1},{"id":"87442b3a-b8eb-43e6-b15d-0240a58bff79","name":"Sticky Note CancelSlot Search","type":"n8n-nodes-base.stickyNote","position":[1300,3440],"parameters":{"width":190,"height":100,"content":"Finds the appointment record in Airtable by phone number to get event ID."},"typeVersion":1},{"id":"4e0cec59-1acc-4604-80ce-09479c7a6652","name":"Sticky Note CancelSlot GCal Delete","type":"n8n-nodes-base.stickyNote","position":[1720,3720],"parameters":{"width":190,"height":80,"content":"Deletes the event from Google Calendar using event ID."},"typeVersion":1},{"id":"68e00556-93d2-45a8-9fee-deb1477ffff2","name":"Sticky Note CancelSlot Airtable Update","type":"n8n-nodes-base.stickyNote","position":[2060,3400],"parameters":{"width":190,"height":80,"content":"Updates Airtable record status to 'Canceled'."},"typeVersion":1},{"id":"5853b0f6-1e73-435e-aff8-5d9d8de53693","name":"Sticky Note CancelSlot Response","type":"n8n-nodes-base.stickyNote","position":[2380,3740],"parameters":{"width":190,"height":80,"content":"Sends cancellation confirmation/error back to Vapi."},"typeVersion":1},{"id":"660cdb51-84ac-434e-b7d8-f7b17ef7ef5b","name":"Sticky Note UpdateSlot Webhook","type":"n8n-nodes-base.stickyNote","position":[460,2600],"parameters":{"color":6,"width":250,"height":80,"content":"# Update Slots"},"typeVersion":1},{"id":"030e4bce-4b8b-42b7-8cf4-86b3a88f375b","name":"Sticky Note UpdateSlot Check","type":"n8n-nodes-base.stickyNote","position":[1000,2900],"parameters":{"width":230,"height":80,"content":"Checks if required info (email, name, old/new times) is provided."},"typeVersion":1},{"id":"02e9f8e3-7561-4ace-95a2-2b1807940f1a","name":"Sticky Note UpdateSlot Error","type":"n8n-nodes-base.stickyNote","position":[1500,3020],"parameters":{"width":190,"height":80,"content":"If info missing, sends error back."},"typeVersion":1},{"id":"4820cb6c-de15-4e9a-bca7-e3f172af6b80","name":"Sticky Note UpdateSlot Search","type":"n8n-nodes-base.stickyNote","position":[1580,2460],"parameters":{"width":190,"height":80,"content":"Finds original appointment in Airtable by old phone number"},"typeVersion":1},{"id":"5dd3075e-8e0b-4f76-8d21-39aa66d449da","name":"Sticky Note UpdateSlot GCal Update","type":"n8n-nodes-base.stickyNote","position":[1940,2720],"parameters":{"width":190,"height":80,"content":"Updates the event time in Google Calendar."},"typeVersion":1},{"id":"2e08b4f6-f279-4a9e-9bd3-d6a6283b45f4","name":"Sticky Note UpdateSlot Airtable Update","type":"n8n-nodes-base.stickyNote","position":[2240,2320],"parameters":{"width":170,"height":100,"content":"Updates Airtable record with new times & 'Updated' status."},"typeVersion":1},{"id":"d1369c19-401e-4ce2-a21e-0d5ae01af119","name":"Sticky Note UpdateSlot Response","type":"n8n-nodes-base.stickyNote","position":[2720,2460],"parameters":{"width":230,"height":80,"content":"Sends rescheduling confirmation/error back to Vapi."},"typeVersion":1},{"id":"ca064fbe-b175-443f-b8e8-70a2a7551ba9","name":"Sticky Note CallResults Webhook","type":"n8n-nodes-base.stickyNote","position":[440,4160],"parameters":{"color":2,"width":390,"height":120,"content":"# Call Result logs\nReceives call summary and recording details post-call."},"typeVersion":1},{"id":"4941246b-82d1-4f16-b7b8-e1fdb6e7c833","name":"Sticky Note CallResults Airtable","type":"n8n-nodes-base.stickyNote","position":[860,4460],"parameters":{"width":230,"height":80,"content":"Logs call transcript, recording URL, summary, cost, customer number to Airtable."},"typeVersion":1},{"id":"e5622e9e-9b0a-43b2-ab80-e3e33a4b0409","name":"Getslot_tool","type":"n8n-nodes-base.webhook","position":[260,740],"webhookId":"42afdbc1-afd0-4d65-a713-cf7a59062d6c","parameters":{"path":"getslots","options":{},"httpMethod":"POST","responseMode":"responseNode"},"typeVersion":2},{"id":"e15781cf-5405-4f60-aa6d-ba19d1b7dabc","name":"Check Availability","type":"n8n-nodes-base.googleCalendar","position":[800,740],"parameters":{"options":{},"timeMax":"={{ $json.endtime.toDateTime() || $now.plus(1, 'hour').toISO() }}","timeMin":"={{ $json.starttime.toDateTime() }}","calendar":{"__rl":true,"mode":"list","value":"pratik@customaistudio.io","cachedResultName":"pratik@customaistudio.io"},"resource":"calendar"},"credentials":{},"typeVersion":1.3},{"id":"1e064283-2964-4eba-a893-e4270157c603","name":"Response","type":"n8n-nodes-base.respondToWebhook","position":[1540,640],"parameters":{"options":{},"respondWith":"json","responseBody":"={\n    \"results\":[\n        {\n            \"toolCallId\":\"{{ $('Getslot_tool').first().json.body.message.toolCalls[0].id }}\",\n            \"result\":\"available:{{ $json.available }}\"\n        }\n    ]\n}"},"typeVersion":1.1},{"id":"498401cb-00e5-4fdd-b6a9-dd3e91376993","name":"Check if time is available or not","type":"n8n-nodes-base.if","position":[1020,740],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"4a8741a2-a903-4fb7-b0a3-5c74c7eea6ca","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.available }}","rightValue":"="}]}},"typeVersion":2.2},{"id":"96e43c15-a332-4acf-af04-80dd989d5660","name":"Time available (true) & Call_id","type":"n8n-nodes-base.set","position":[1320,640],"parameters":{"options":{},"assignments":{"assignments":[{"id":"f582d965-af15-4ecf-8a8c-d8bf6c0d15c1","name":"body.message.toolCalls[0].id","type":"string","value":"={{ $('Input Arguments').item.json.body.message.toolCalls[0].id }}"},{"id":"834ee925-5c8d-4e46-aeee-f399dc1ff40c","name":"available","type":"boolean","value":"={{ $json.available }}"}]}},"typeVersion":3.4},{"id":"fb7ad8c6-9f78-4518-b955-60f3f7088cb9","name":"Get All Calendar Events","type":"n8n-nodes-base.googleCalendar","position":[1320,840],"parameters":{"options":{"orderBy":"startTime","timeMax":"={{ $now.plus(1, 'week').toISO() }}","timeMin":"={{ $now.toISO() }}","singleEvents":true},"calendar":{"__rl":true,"mode":"list","value":"pratik@customaistudio.io","cachedResultName":"pratik@customaistudio.io"},"operation":"getAll","returnAll":true},"credentials":{},"typeVersion":1,"alwaysOutputData":true},{"id":"390599ee-ddeb-4628-af0b-36fbdd357cee","name":"Extract start, end and name","type":"n8n-nodes-base.set","position":[1540,840],"parameters":{"options":{"ignoreConversionErrors":true},"assignments":{"assignments":[{"id":"1045b97f-c76f-450e-8f57-008602000848","name":"start","type":"string","value":"={{ DateTime.fromISO($json.start.dateTime).toLocaleString(DateTime.DATE_HUGE) }}, {{ DateTime.fromISO($json.start.dateTime).toLocaleString(DateTime.TIME_24_WITH_SHORT_OFFSET) }}"},{"id":"457e3a2b-d33e-4a65-b2da-d19ad9d754ac","name":"end","type":"string","value":"={{ DateTime.fromISO($json.end.dateTime).toLocaleString(DateTime.DATE_HUGE) }}, {{ DateTime.fromISO($json.end.dateTime).toLocaleString(DateTime.TIME_24_WITH_SHORT_OFFSET) }}"},{"id":"b6802452-557e-4568-af14-4574e8ecc013","name":"name","type":"string","value":"={{ $json.summary }}"},{"id":"799b656f-68b6-467c-88a1-217ff7c7801b","name":"sort","type":"string","value":"={{ $json.start.dateTime }}"}]}},"typeVersion":3.4},{"id":"2c9a73da-37b7-4abd-af5e-695036cd2c2b","name":"Convert into Json format for Vapi","type":"n8n-nodes-base.code","position":[3120,840],"parameters":{"jsCode":"// Get the input data for the first item\nconst inputData = $input.first().json;\nconsole.log(\"Input Data:\", inputData); // Log input for debugging\n\n// Access the message string from the correct path within the input structure.\n// The input comes from the \"Build Response Payload\" node, which structures data under 'results'.\n// Use optional chaining (?.) for safety in case the structure is not as expected.\nlet message = inputData.results?.[0]?.result;\n\n// Check if the message was found and is a string\nif (typeof message !== 'string') {\n    console.error(\"Could not find the message string at inputData.results[0].result or it's not a string. Input:\", inputData);\n    // Return an object with an empty message or an error indicator\n    return { message: \"\" }; // Or potentially throw an error: throw new Error(\"Input message not found or not a string\");\n}\n\n// Start cleaning the message string\n\n// 1. Replace the literal string \"\\\\n\" (backslash followed by n) with a space.\n// This handles the newline representation seen in the input screenshot.\nlet cleanedMessage = message.replace(/\\\\n/g, ' ');\n\n// 2. Remove spaces immediately surrounding colons (e.g., \"Times : \" becomes \"Times:\").\ncleanedMessage = cleanedMessage.replace(/\\s*:\\s*/g, ':');\n\n// 3. Replace sequences of multiple whitespace characters (including spaces from replaced \\n)\n// with a single space. Then, trim any leading or trailing whitespace from the result.\ncleanedMessage = cleanedMessage.replace(/\\s+/g, ' ').trim();\n\n// Create the final output JSON object containing the cleaned message.\nconst output = {\n    message: cleanedMessage\n};\n\n// Return the output object. This will be the output of the Code node.\nreturn output;"},"typeVersion":2},{"id":"e00cf72a-af6a-441b-9b76-81bd8096d3df","name":"Response to Vapi","type":"n8n-nodes-base.respondToWebhook","position":[3360,840],"parameters":{"options":{},"respondWith":"json","responseBody":"={\n    \"results\":[\n        {\n            \"toolCallId\":\"{{ $('Getslot_tool').first().json.body.message.toolCalls[0].id }}\",\n            \"result\":\"The original time is not available, here are available slots:{{ $json.message }}\"\n        }\n    ]\n}"},"typeVersion":1.1},{"id":"facf3bf9-e05e-4953-a221-bf7f566a3b0f","name":"bookslots_tool","type":"n8n-nodes-base.webhook","position":[400,1800],"webhookId":"42afdbc1-afd0-4d65-a713-cf7a59062d6c","parameters":{"path":"bookslots","options":{},"httpMethod":"POST","responseMode":"responseNode"},"typeVersion":2},{"id":"9266904b-300f-4c83-a518-4cd69b13de41","name":"Input Arguments from booking tools","type":"n8n-nodes-base.set","position":[720,1800],"parameters":{"options":{},"assignments":{"assignments":[{"id":"eac930a3-ba65-4b0d-b236-aa167d7edb3f","name":"toolCallId","type":"string","value":"={{ $json.body.message.toolCalls[0].id }}"},{"id":"492186b8-e3a3-4ab9-87f4-45d8cbc38c13","name":"timeZone","type":"string","value":"=America/Chicago"},{"id":"12aeec42-9414-4d43-8837-1ff747f49305","name":"name","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.name || \"John Smith\" }}"},{"id":"36673f27-c026-4ad9-81da-ad11e71bbfb6","name":"email","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.email }}"},{"id":"469ddc00-a399-47a5-8c55-97cd3adf4143","name":"language","type":"string","value":"en"},{"id":"b191cd98-f3f7-48b1-a2e0-2c9e248a4983","name":"notes","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.notes || \"\"}}"},{"id":"783cb161-65e4-4829-ac90-5c6c2c55585f","name":"starttime","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.starttime }}"},{"id":"bfcdade9-14c8-4867-8a22-3865a2bcc116","name":"endtime","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.endtime }}"},{"id":"26ca39ef-48f5-41ed-990e-40c2a26d6132","name":"Tittle","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.Title }}"},{"id":"43575f7a-3873-4d74-90c5-4467c7779514","name":"customer_number","type":"string","value":"={{ $json.body.message.call.customer.number }}"}]}},"typeVersion":3.3},{"id":"b4bc5cee-d631-4aa8-a3ff-59a0b647d36a","name":"Convert time to CST America / Chicago","type":"n8n-nodes-base.code","position":[1480,1580],"parameters":{"jsCode":"// Get all input items\nconst items = $input.all();\n\n// Loop through each item\nfor (const item of items) {\n  // Get the values from the current item's JSON data\n  const startTimeUTC = item.json.starttime;\n  const endTimeUTC = item.json.endtime;\n  const targetTimeZone = item.json.timeZone; // e.g., \"America/Chicago\"\n\n  // Basic validation: ensure the necessary fields exist\n  if (!startTimeUTC || !endTimeUTC || !targetTimeZone) {\n    console.warn(`Skipping item due to missing time data or timezone. Item JSON: ${JSON.stringify(item.json)}`);\n    item.json.conversionError = \"Missing starttime, endtime, or timeZone\";\n    continue; // Move to the next item\n  }\n\n  try {\n    // --- Start Time Conversion ---\n    // Parse the original UTC ISO string using Luxon (NO $ prefix)\n    const startDt = luxon.DateTime.fromISO(startTimeUTC, { zone: 'utc' });\n\n    // Convert the DateTime object to the target timezone\n    const startDtTargetZone = startDt.setZone(targetTimeZone);\n\n    // Check if the conversion was valid\n    if (!startDtTargetZone.isValid) {\n      throw new Error(`Failed to convert start time. Reason: ${startDtTargetZone.invalidReason || 'Unknown'}`);\n    }\n\n    // Format the result back into an ISO string with the correct offset\n    item.json.starttime = startDtTargetZone.toISO();\n\n    // --- End Time Conversion ---\n    // Parse the original UTC ISO string using Luxon (NO $ prefix)\n    const endDt = luxon.DateTime.fromISO(endTimeUTC, { zone: 'utc' });\n\n    // Convert the DateTime object to the target timezone\n    const endDtTargetZone = endDt.setZone(targetTimeZone);\n\n     // Check if the conversion was valid\n    if (!endDtTargetZone.isValid) {\n      throw new Error(`Failed to convert end time. Reason: ${endDtTargetZone.invalidReason || 'Unknown'}`);\n    }\n\n    // Format the result back into an ISO string with the correct offset\n    item.json.endtime = endDtTargetZone.toISO();\n\n    // Optionally remove the error flag if conversion was successful this time\n    delete item.json.conversionError;\n\n  } catch (error) {\n    console.error(`Error converting time for item: ${JSON.stringify(item.json)}. Error: ${error.message}`);\n    // Add/update the error flag to the item's JSON\n    item.json.conversionError = error.message;\n  }\n}\n// Return the modified array of items\nreturn items;"},"typeVersion":2},{"id":"2c8b2884-14d3-4bd4-92d8-6e402ca3a8de","name":"Create Event","type":"n8n-nodes-base.googleCalendar","onError":"continueErrorOutput","position":[1700,1580],"parameters":{"end":"={{ $json.endtime }}","start":"={{ $json.starttime }}","calendar":{"__rl":true,"mode":"list","value":"pratik@customaistudio.io","cachedResultName":"pratik@customaistudio.io"},"additionalFields":{"allday":"no","summary":"={{ $json.Tittle }}","showMeAs":"opaque","attendees":["={{ $json.email }}"],"description":"={{ $json.notes }}","conferenceDataUi":{"conferenceDataValues":{"conferenceSolution":"hangoutsMeet"}}}},"credentials":{},"typeVersion":1.3},{"id":"b8890ab2-9850-4608-996d-45c8a6d3a52e","name":"Respond to Vapi","type":"n8n-nodes-base.respondToWebhook","onError":"continueRegularOutput","position":[2480,1580],"parameters":{"options":{},"respondWith":"json","responseBody":"={\n    \"results\":[\n        {\n            \"toolCallId\":\"{{ $json.results[0].toolCallId }}\",\n            \"result\":\"available:{{ $json.results[0].result }}\"\n        }\n    ]\n}"},"typeVersion":1.1,"alwaysOutputData":true},{"id":"77f75f42-46bb-47f5-8a43-55543ae46f10","name":"If the booking is confirmed then true","type":"n8n-nodes-base.if","position":[2700,1580],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"loose"},"combinator":"and","conditions":[{"id":"932dd430-309b-4d3b-8bf6-768f84fd2dd2","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.results[0].result }}","rightValue":"=confirmed"}]},"looseTypeValidation":true},"typeVersion":2.2},{"id":"230ddb29-67f0-4486-a6f3-f4dd3dbbee42","name":"Information to be Saved in Airtable","type":"n8n-nodes-base.set","position":[2940,1560],"parameters":{"options":{},"assignments":{"assignments":[{"id":"b103265d-86da-4256-994d-85a78f33f933","name":"startTime","type":"string","value":"={{ $('Booking Payload').item.json.startTime }}"},{"id":"a8e6e9c5-6ebb-48d8-951f-b007bed2421d","name":"endTime","type":"string","value":"={{ $('Booking Payload').item.json.endTime }}"},{"id":"d4bcb1d1-043a-4205-8488-0a67b4e7b582","name":"status","type":"string","value":"={{ $('Booking Payload').item.json.status }}"},{"id":"92ac8c99-ad94-4b3c-9c5e-ba032dac2255","name":"description","type":"string","value":"={{ $('Booking Payload').item.json.description }}"},{"id":"98c5653d-1e0e-4a6a-8630-17802d437593","name":"attendees[0].email","type":"string","value":"={{ $('Booking Payload').item.json.attendees[0].email }}"},{"id":"f94bdfc1-dc74-4675-ad29-19244fb21ebe","name":"attendees[0].responseStatus","type":"string","value":"={{ $('Booking Payload').item.json.attendees[0].responseStatus }}"},{"id":"12bd5ed5-4934-4c19-a9b9-54fe989eaa4f","name":"hangoutLink","type":"string","value":"={{ $('Booking Payload').item.json.hangoutLink }}"},{"id":"5b1f9356-7d62-4999-ae4e-86f3f20d72bf","name":"attendee.name","type":"string","value":"={{ $('bookslots_tool').item.json.body.message.toolCalls[0].function.arguments.name }}"},{"id":"6e93805e-8754-4f92-870f-7b46525f3eb3","name":"call.id","type":"string","value":"={{ $('bookslots_tool').item.json.body.message.call.id }}"},{"id":"f174e2be-3230-4fc9-970b-971aff6e9b8e","name":"assistant.name","type":"string","value":"={{ $('bookslots_tool').item.json.body.message.assistant.name }}"},{"id":"a4bc9d70-7d51-487f-b622-433e767ef71f","name":"event.id","type":"string","value":"={{ $('Create Event').item.json.id }}"},{"id":"9259b1d3-3658-4ab5-b434-364e6a84d145","name":"Title","type":"string","value":"={{ $('Booking Payload').item.json.Title }}"},{"id":"2102a7be-5d74-458f-bafd-21651e24adb1","name":"customer_number","type":"string","value":"={{ $('Input Arguments from booking tools').item.json.customer_number}}"}]}},"typeVersion":3.4},{"id":"f6c7774d-a8c7-466a-ba77-401194fe6fb4","name":"Logs the confirmed booking details","type":"n8n-nodes-base.airtable","position":[3160,1560],"parameters":{"base":{"__rl":true,"mode":"list","value":"appnj853UnMRnJ8D3","cachedResultUrl":"https://airtable.com/appnj853UnMRnJ8D3","cachedResultName":"Voice Receptionist Agent"},"table":{"__rl":true,"mode":"list","value":"tblF8LF9lmkHMbk7v","cachedResultUrl":"https://airtable.com/appnj853UnMRnJ8D3/tblF8LF9lmkHMbk7v","cachedResultName":"Appointments"},"columns":{"value":{"Name":"={{ $json.attendee.name }}","Email":"={{ $json.attendees[0].email }}","endtime":"={{ $json.endTime }}","eventId":"={{ $json.event.id }}","meetlink":"={{ $json.hangoutLink }}","starttime":"={{ $json.startTime }}","Voice Agent":"={{ [$json.assistant.name] }}","Phone Number":"={{ $json.customer_number }}","Booking Status":"={{ $json.status }}","CallRecordingId":"={{ [$json.call.id] }}","meetdescription":"={{ $json.Title }} {{ $json.description }}"},"schema":[{"id":"Email","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Email","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Phone Number","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Phone Number","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Name","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Name","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Booking Status","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Booking Status","defaultMatch":false,"canBeUsedToMatch":true},{"id":"CallRecordingId","type":"array","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"CallRecordingId","defaultMatch":false,"canBeUsedToMatch":true},{"id":"starttime","type":"dateTime","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"starttime","defaultMatch":false,"canBeUsedToMatch":true},{"id":"endtime","type":"dateTime","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"endtime","defaultMatch":false,"canBeUsedToMatch":true},{"id":"meetlink","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"meetlink","defaultMatch":false,"canBeUsedToMatch":true},{"id":"meetdescription","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"meetdescription","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Voice Agent","type":"array","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Voice Agent","defaultMatch":false,"canBeUsedToMatch":true},{"id":"eventId","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"eventId","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Appointments","type":"string","display":true,"removed":true,"readOnly":true,"required":false,"displayName":"Appointments","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["Email"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{"typecast":true},"operation":"create"},"credentials":{},"typeVersion":2.1},{"id":"154bee14-9281-4b92-8204-57c5436785ba","name":"Updateslots_tool","type":"n8n-nodes-base.webhook","position":[460,2720],"webhookId":"66b278fe-97d1-4413-b6dd-4288d8ec66b2","parameters":{"path":"updateslots","options":{},"httpMethod":"POST","responseMode":"responseNode"},"typeVersion":2},{"id":"891fb4ec-3a82-4433-bebf-3f0616027e3d","name":"Input Arguments from updateslot tool","type":"n8n-nodes-base.set","position":[840,2720],"parameters":{"options":{},"assignments":{"assignments":[{"id":"6f6388ab-a233-4643-9b28-917ad6bdfe22","name":"Calls[0].id","type":"string","value":"={{ $json.body.message.toolCalls[0].id }}"},{"id":"40888d2c-b99d-401d-a6b9-944ba41543c6","name":"name","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.name }}"},{"id":"17be6cf6-8c48-4a4e-a0e8-b5b714f94242","name":"email","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.email }}"},{"id":"d06fd547-39c1-457b-8422-393f140aead6","name":"starttime","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.starttime }}"},{"id":"c224df67-ec82-40f3-9af2-3472731a57fa","name":"endtime","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.endtime }}"},{"id":"b2fb0887-5545-409c-bba8-fae76a71f660","name":"call.id","type":"string","value":"={{ $json.body.message.call.id }}"},{"id":"19efa4c6-25e0-4fe8-a00e-0b37f16b6de0","name":"Rescheduled_starttime","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.Rescheduled_starttime }}"},{"id":"ad47dfdb-66fa-478d-899f-1d9d202aac6f","name":"Rescheduled_endttime","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.Rescheduled_endttime }}"},{"id":"6d1bf6c0-a4b4-41d4-826e-e7c73f920905","name":"customer_number","type":"string","value":"={{ $json.body.message.call.customer.number }}"}]}},"typeVersion":3.4},{"id":"617a7742-299a-4c91-be82-cba598d1bb82","name":"Checks if required info is provided.","type":"n8n-nodes-base.if","position":[1060,2720],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"loose"},"combinator":"and","conditions":[{"id":"87304425-5f17-4637-8aa3-cd84b2f8d856","operator":{"type":"string","operation":"exists","singleValue":true},"leftValue":"={{ $json.name }}","rightValue":""},{"id":"fdc6ffb0-f234-4869-8f5e-482c394ab860","operator":{"type":"string","operation":"exists","singleValue":true},"leftValue":"={{ $json.email }}","rightValue":""},{"id":"7950d7bc-7416-48b6-8ec5-a635a9161013","operator":{"type":"dateTime","operation":"exists","singleValue":true},"leftValue":"={{ $json.Rescheduled_starttime }}","rightValue":"={{ $json.Rescheduledtime }}"},{"id":"aa54ee15-1273-48b0-863f-939597af04e6","operator":{"type":"dateTime","operation":"exists","singleValue":true},"leftValue":"={{ $json.Rescheduled_endttime }}","rightValue":""},{"id":"8ceefa9d-360c-48b6-8faf-e156459f2c07","operator":{"type":"dateTime","operation":"exists","singleValue":true},"leftValue":"={{ $json.starttime }}","rightValue":""}]},"looseTypeValidation":true},"typeVersion":2.2},{"id":"dded1cfa-ce89-481f-967b-6843854a32bd","name":"Finds original appointment","type":"n8n-nodes-base.airtable","maxTries":2,"position":[1600,2560],"parameters":{"base":{"__rl":true,"mode":"list","value":"appnj853UnMRnJ8D3","cachedResultUrl":"https://airtable.com/appnj853UnMRnJ8D3","cachedResultName":"Voice Receptionist Agent"},"table":{"__rl":true,"mode":"list","value":"tblF8LF9lmkHMbk7v","cachedResultUrl":"https://airtable.com/appnj853UnMRnJ8D3/tblF8LF9lmkHMbk7v","cachedResultName":"Appointments"},"options":{"fields":["Email","Name","starttime","eventId"]},"operation":"search","filterByFormula":"={Phone Number} = (\"{{ $json.customer_number }}\")"},"credentials":{},"retryOnFail":false,"typeVersion":2.1,"alwaysOutputData":false},{"id":"a3fd9971-20bb-414a-b06c-1af4da053241","name":"Response with Error","type":"n8n-nodes-base.respondToWebhook","position":[1780,2840],"parameters":{"options":{}},"typeVersion":1.1},{"id":"0731f0ae-fbdb-4149-890a-0a44c95b2691","name":"Update Event","type":"n8n-nodes-base.googleCalendar","onError":"continueErrorOutput","position":[1980,2560],"parameters":{"eventId":"={{ $json.eventId }}","calendar":{"__rl":true,"mode":"list","value":"pratik@customaistudio.io","cachedResultName":"pratik@customaistudio.io"},"operation":"update","updateFields":{"end":"={{ $('Checks if required info is provided.').item.json.Rescheduled_endttime }}","start":"={{ $('Checks if required info is provided.').item.json.Rescheduled_starttime }}","allday":"no"}},"credentials":{},"typeVersion":1.3},{"id":"1e7af704-6c5d-4e6b-a606-2c5c7ef64b10","name":"Updates Airtable record","type":"n8n-nodes-base.airtable","position":[2280,2440],"parameters":{"base":{"__rl":true,"mode":"list","value":"appnj853UnMRnJ8D3","cachedResultUrl":"https://airtable.com/appnj853UnMRnJ8D3","cachedResultName":"Voice Receptionist Agent"},"table":{"__rl":true,"mode":"list","value":"tblF8LF9lmkHMbk7v","cachedResultUrl":"https://airtable.com/appnj853UnMRnJ8D3/tblF8LF9lmkHMbk7v","cachedResultName":"Appointments"},"columns":{"value":{"endtime":"={{ $json.end.dateTime }}","eventId":"={{ $('Finds original appointment').item.json.eventId }}","starttime":"={{ $json.start.dateTime }}","Booking Status":"Updated/Rescheduled"},"schema":[{"id":"id","type":"string","display":true,"removed":true,"readOnly":true,"required":false,"displayName":"id","defaultMatch":true},{"id":"Email","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"Email","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Phone Number","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"Phone Number","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Name","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"Name","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Booking Status","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Booking Status","defaultMatch":false,"canBeUsedToMatch":true},{"id":"CallRecordingId","type":"array","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"CallRecordingId","defaultMatch":false,"canBeUsedToMatch":true},{"id":"starttime","type":"dateTime","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"starttime","defaultMatch":false,"canBeUsedToMatch":true},{"id":"endtime","type":"dateTime","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"endtime","defaultMatch":false,"canBeUsedToMatch":true},{"id":"meetlink","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"meetlink","defaultMatch":false,"canBeUsedToMatch":true},{"id":"meetdescription","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"meetdescription","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Voice Agent","type":"array","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"Voice Agent","defaultMatch":false,"canBeUsedToMatch":true},{"id":"eventId","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"eventId","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Appointments","type":"string","display":true,"removed":true,"readOnly":true,"required":false,"displayName":"Appointments","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["eventId"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"update"},"credentials":{},"typeVersion":2.1},{"id":"5a74d949-f08e-422c-afde-e41690a8512b","name":"Response & call_id","type":"n8n-nodes-base.set","position":[2620,2580],"parameters":{"options":{},"assignments":{"assignments":[{"id":"074d1ef3-e96b-4149-a12c-b8aa71c9c117","name":"results[0].toolCallId","type":"string","value":"={{ $('Updateslots_tool').item.json.body.message.toolCalls[0].id }}"},{"id":"098bb88d-9b17-4aeb-850c-819406aa0f3b","name":"results[0].result","type":"string","value":"={{ $json.error || $json.fields['Booking Status']  }}"}]}},"typeVersion":3.4},{"id":"bb7dc099-c4ac-48d4-bf8c-50f4f8858dd4","name":"Respond to Vapi about Updating slots","type":"n8n-nodes-base.respondToWebhook","position":[2820,2580],"parameters":{"options":{},"respondWith":"json","responseBody":"={\n    \"results\":[\n        {\n            \"toolCallId\":\"{{ $json.results[0].toolCallId }}\",\n            \"result\":\"{{ $json.results[0].result }}\"\n        }\n    ]\n}"},"typeVersion":1.1},{"id":"2154c9c8-acd3-4144-9fa6-f6f7de7bbf48","name":"CancelSlots_tool","type":"n8n-nodes-base.webhook","position":[440,3620],"webhookId":"00fedd5a-c03d-4302-b8e0-22c79f26ed05","parameters":{"path":"cancelslots","options":{},"httpMethod":"POST","responseMode":"responseNode"},"typeVersion":2},{"id":"aeabd266-4b0e-436f-9c8c-607fb7b6734a","name":"Input Arguments from cancelslot tool","type":"n8n-nodes-base.set","position":[800,3620],"parameters":{"options":{},"assignments":{"assignments":[{"id":"6f6388ab-a233-4643-9b28-917ad6bdfe22","name":"Calls[0].id","type":"string","value":"={{ $json.body.message.toolCalls[0].id }}"},{"id":"40888d2c-b99d-401d-a6b9-944ba41543c6","name":"name","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.name }}"},{"id":"17be6cf6-8c48-4a4e-a0e8-b5b714f94242","name":"email","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.email }}"},{"id":"d06fd547-39c1-457b-8422-393f140aead6","name":"starttime","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.starttime }}"},{"id":"0a0243b2-afc4-44f1-92cd-81572df79cc5","name":"Cancelnotes","type":"string","value":"={{ $json.body.message.toolCalls[0].function.arguments.Cancelnotes }}"},{"id":"b2fb0887-5545-409c-bba8-fae76a71f660","name":"call.id","type":"string","value":"={{ $json.body.message.call.id }}"},{"id":"8d528786-75d7-466e-8e8f-2013e4638bc2","name":"customer_number","type":"string","value":"={{ $json.body.message.call.customer.number }}"}]}},"typeVersion":3.4},{"id":"b702973e-15f0-4bbe-98ac-d4af7a57cff1","name":"Checks if required info is provided for cancelation","type":"n8n-nodes-base.if","position":[1020,3620],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"loose"},"combinator":"and","conditions":[{"id":"87304425-5f17-4637-8aa3-cd84b2f8d856","operator":{"type":"string","operation":"exists","singleValue":true},"leftValue":"={{ $json.name }}","rightValue":""},{"id":"fdc6ffb0-f234-4869-8f5e-482c394ab860","operator":{"type":"string","operation":"exists","singleValue":true},"leftValue":"={{ $json.email }}","rightValue":""},{"id":"c0b869e4-9490-4c01-b138-835bb34eb1ba","operator":{"type":"dateTime","operation":"exists","singleValue":true},"leftValue":"={{ $json.starttime }}","rightValue":""}]},"looseTypeValidation":true},"typeVersion":2.2},{"id":"c5e49060-7b76-4622-bc23-b389f1665215","name":"Finds the appointment record","type":"n8n-nodes-base.airtable","position":[1300,3560],"parameters":{"base":{"__rl":true,"mode":"list","value":"appnj853UnMRnJ8D3","cachedResultUrl":"https://airtable.com/appnj853UnMRnJ8D3","cachedResultName":"Voice Receptionist Agent"},"table":{"__rl":true,"mode":"list","value":"tblF8LF9lmkHMbk7v","cachedResultUrl":"https://airtable.com/appnj853UnMRnJ8D3/tblF8LF9lmkHMbk7v","cachedResultName":"Appointments"},"options":{"fields":["Email","Name","starttime","eventId"]},"operation":"search","filterByFormula":"={Phone Number} = (\"{{ $json.customer_number }}\")"},"credentials":{},"typeVersion":2.1,"alwaysOutputData":true},{"id":"dd83c017-6f5b-49b4-83f9-ec2f33ca5ed0","name":"Build Error Response","type":"n8n-nodes-base.set","position":[1300,3780],"parameters":{"options":{},"assignments":{"assignments":[{"id":"5cb05b10-e916-459e-84a2-9c314a859a07","name":"results[0].toolCallId","type":"string","value":"={{ $('Input Arguments from booking tools').item.json.toolCallId }}"},{"id":"552246f9-7afd-404e-9fb3-cb38c7447359","name":"results[0].result","type":"string","value":"=You must provide an email, name and starttime to call this tool"}]}},"typeVersion":3.4},{"id":"ca74e845-ee23-4f8a-ba8e-789186fe7add","name":"Respond with Error to Vapi","type":"n8n-nodes-base.respondToWebhook","position":[1500,3780],"parameters":{"options":{}},"typeVersion":1.1},{"id":"ad3c2ad0-ba5e-48a6-865f-a8da63173562","name":"Delete Event","type":"n8n-nodes-base.googleCalendar","onError":"continueErrorOutput","position":[1720,3560],"parameters":{"eventId":"={{ $json.eventId }}","options":{"sendUpdates":"all"},"calendar":{"__rl":true,"mode":"list","value":"pratik@customaistudio.io","cachedResultName":"pratik@customaistudio.io"},"operation":"delete"},"credentials":{},"typeVersion":1.3},{"id":"177a1297-8e96-4d04-a0ff-e16aab71d5b9","name":"Update Airtable record","type":"n8n-nodes-base.airtable","position":[1940,3440],"parameters":{"base":{"__rl":true,"mode":"list","value":"appnj853UnMRnJ8D3","cachedResultUrl":"https://airtable.com/appnj853UnMRnJ8D3","cachedResultName":"Voice Receptionist Agent"},"table":{"__rl":true,"mode":"list","value":"tblF8LF9lmkHMbk7v","cachedResultUrl":"https://airtable.com/appnj853UnMRnJ8D3/tblF8LF9lmkHMbk7v","cachedResultName":"Appointments"},"columns":{"value":{"eventId":"={{ $('Finds the appointment record').item.json.eventId }}","Booking Status":"Canceled"},"schema":[{"id":"id","type":"string","display":true,"removed":true,"readOnly":true,"required":false,"displayName":"id","defaultMatch":true},{"id":"Email","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"Email","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Phone Number","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"Phone Number","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Name","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"Name","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Booking Status","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Booking Status","defaultMatch":false,"canBeUsedToMatch":true},{"id":"CallRecordingId","type":"array","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"CallRecordingId","defaultMatch":false,"canBeUsedToMatch":true},{"id":"starttime","type":"dateTime","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"starttime","defaultMatch":false,"canBeUsedToMatch":true},{"id":"endtime","type":"dateTime","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"endtime","defaultMatch":false,"canBeUsedToMatch":true},{"id":"meetlink","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"meetlink","defaultMatch":false,"canBeUsedToMatch":true},{"id":"meetdescription","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"meetdescription","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Voice Agent","type":"array","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"Voice Agent","defaultMatch":false,"canBeUsedToMatch":true},{"id":"eventId","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"eventId","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Appointments","type":"string","display":true,"removed":true,"readOnly":true,"required":false,"displayName":"Appointments","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["eventId"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"update"},"credentials":{},"typeVersion":2.1},{"id":"4d0c155c-68ad-4f70-b9c6-0dbd4db70fd1","name":"Call_id & Response","type":"n8n-nodes-base.set","position":[2160,3580],"parameters":{"options":{},"assignments":{"assignments":[{"id":"074d1ef3-e96b-4149-a12c-b8aa71c9c117","name":"results[0].toolCallId","type":"string","value":"={{ $('CancelSlots_tool').item.json.body.message.toolCalls[0].id }}"},{"id":"098bb88d-9b17-4aeb-850c-819406aa0f3b","name":"results[0].result","type":"string","value":"={{ $json.error || $json.fields['Booking Status']  }}"}]}},"typeVersion":3.4},{"id":"41ff13bf-0793-4082-8be6-51f0617ab0f8","name":"Respond to Vapi about cancelation","type":"n8n-nodes-base.respondToWebhook","position":[2400,3580],"parameters":{"options":{},"respondWith":"json","responseBody":"={\n    \"results\":[\n        {\n            \"toolCallId\":\"{{ $json.results[0].toolCallId }}\",\n            \"result\":\"{{ $json.results[0].result }}\"\n        }\n    ]\n}"},"typeVersion":1.1},{"id":"599592b1-214c-4e99-84f6-e244e690ed79","name":"call_results","type":"n8n-nodes-base.webhook","position":[440,4300],"webhookId":"4a6205cd-4277-4686-8008-540b802b99fe","parameters":{"path":"callresults","options":{},"httpMethod":"POST"},"typeVersion":2},{"id":"baf3ce79-f302-42ad-bb7e-49f2d9197eae","name":"All Input Arguments","type":"n8n-nodes-base.set","position":[720,4300],"parameters":{"options":{"ignoreConversionErrors":true},"assignments":{"assignments":[{"id":"fd00208a-e833-4834-8c37-0034c44fb47d","name":"transcript","type":"string","value":"={{ $json.body.message.artifact.transcript }}"},{"id":"b72ffa4d-aef3-4d7c-8b81-9238a3c5890b","name":"recordingUrl","type":"string","value":"={{ $json.body.message.artifact.recordingUrl }}"},{"id":"e45d90de-0103-46ba-9fcb-f4c969816da0","name":"call.summary","type":"string","value":"={{ $json.body.message.analysis.summary }}"},{"id":"b0a5557f-483f-47c9-955a-c12ce84f270b","name":"cost","type":"number","value":"={{ $json.body.message.cost }}"},{"id":"2bfcfe4f-4eaf-4274-b3f2-cdaea8c2cc46","name":"call.id","type":"string","value":"={{ $json.body.message.call.id }}"},{"id":"2b7b1638-0d0e-4c48-9989-287fd4e0babd","name":"call.orgId","type":"string","value":"={{ $json.body.message.call.orgId }}"},{"id":"adf4d062-bbfd-4f97-bda4-bdfec1e40ee4","name":"assistant.name","type":"string","value":"={{ $json.body.message.assistant.name }}"},{"id":"3c2af504-d320-45f0-9008-79b3bc1ff897","name":"startedAt","type":"string","value":"={{ $json.body.message.startedAt }}"},{"id":"0486dbfa-ca10-45b5-a79a-3ce1064f13fa","name":"endedAt","type":"string","value":"={{ $json.body.message.endedAt }}"},{"id":"bf97b5eb-5baa-4a87-b34e-2f64c97c0d42","name":"assistant.id","type":"string","value":"={{ $json.body.message.assistant.id }}"},{"id":"58ee9b29-7aa1-4a15-bf83-606287a964a6","name":"assistant.model","type":"string","value":"={{ $json.body.message.assistant.model.model }}"},{"id":"36e2bbef-e12d-4fc4-a0af-bb65aa446023","name":"body.message.assistant","type":"object","value":"={{ $json.body.message.assistant }}"},{"id":"dfa93dbb-67dc-417b-874a-32fbd55d92b0","name":"assistantId","type":"string","value":"={{ $json.body.message.call.assistantId }}"},{"id":"4bc2b480-92a1-470e-bdf0-d6609f346ed2","name":"body.message.assistant.model.emotionRecognitionEnabled","type":"boolean","value":"={{ $json.body.message.assistant.model.emotionRecognitionEnabled }}"},{"id":"acb64bba-e295-4dd0-9ab3-b4166ef5d0ad","name":"customer.number","type":"string","value":"={{ $json.body.message.call.customer.number }}"}]}},"typeVersion":3.4},{"id":"f3394750-7438-47e9-8aa3-996accfa9bac","name":"Save all information","type":"n8n-nodes-base.airtable","position":[900,4300],"parameters":{"base":{"__rl":true,"mode":"list","value":"appnj853UnMRnJ8D3","cachedResultUrl":"https://airtable.com/appnj853UnMRnJ8D3","cachedResultName":"Voice Receptionist Agent"},"table":{"__rl":true,"mode":"list","value":"tbl1b6vMhq9IT9JEZ","cachedResultUrl":"https://airtable.com/appnj853UnMRnJ8D3/tbl1b6vMhq9IT9JEZ","cachedResultName":"Call Recording"},"columns":{"value":{"Cost":"={{ $json.cost }}","endedAt":"={{ $json.endedAt }}","startedAt":"={{ $json.startedAt }}","transcript":"={{ $json.transcript }}","callsummary":"={{ $json.call.summary }}","customer_Number":"={{ $json.customer.number }}","callrecording_id":"={{ $json.call.id }}","Call recording Url":"={{ $json.recordingUrl }}"},"schema":[{"id":"id","type":"string","display":true,"removed":true,"readOnly":true,"required":false,"displayName":"id","defaultMatch":true},{"id":"callrecording_id","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"callrecording_id","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Cost","type":"number","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Cost","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Call recording Url","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"Call recording Url","defaultMatch":false,"canBeUsedToMatch":true},{"id":"transcript","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"transcript","defaultMatch":false,"canBeUsedToMatch":true},{"id":"customer_Number","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"customer_Number","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Appointments","type":"array","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"Appointments","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Appointment time (from Appointments)","type":"string","display":true,"removed":true,"readOnly":true,"required":false,"displayName":"Appointment time (from Appointments)","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Voice Agent (from Appointments)","type":"string","display":true,"removed":true,"readOnly":true,"required":false,"displayName":"Voice Agent (from Appointments)","defaultMatch":false,"canBeUsedToMatch":true},{"id":"startedAt","type":"dateTime","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"startedAt","defaultMatch":false,"canBeUsedToMatch":true},{"id":"endedAt","type":"dateTime","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"endedAt","defaultMatch":false,"canBeUsedToMatch":true},{"id":"call_Length (in secs)","type":"string","display":true,"removed":true,"readOnly":true,"required":false,"displayName":"call_Length (in secs)","defaultMatch":false,"canBeUsedToMatch":true},{"id":"callsummary","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"callsummary","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["callrecording_id"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{"typecast":true},"operation":"upsert"},"credentials":{},"typeVersion":2.1},{"id":"5671dcff-8894-42a8-af77-df01d0b6c190","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[-1800,1980],"parameters":{"color":4,"width":1680,"height":2700,"content":"# Vapi System Prompt\n\n### First Message: \nHi, this is Ellie with Harrison Climate Solutions how can I help you?\n\n----**END**----\n\n### System Prompt:\n\n[Identity]  \nYou are Ellie, the friendly and knowledgeable voice receptionist for Harrison Climate Solutions, an HVAC service company based in San Antonio, Texas.\n- Current Date and Time: {{\"now\" | date: \"%b %d, %Y, %I:%M %p\", \"America/Chicago\"}}\n\n[Style]  \n- Use a friendly, conversational tone with a hint of Texan warmth.\n- Be warm, approachable, and slightly humorous to create a comfortable and friendly experience for callers.\n- Use casual, conversational language, incorporating friendly fillers like “Umm...,” “Well...,” or “I mean.”\n- Keep responses brief and engaging, mirroring a natural conversation style to suit the voice format.\n\n[Response Guideline]  \n- Use a friendly and conversational tone, never saying \"Asterisk\" or similar technical terms.\n- Limit responses to essential information only, breaking up information into bite-sized pieces when possible.\n- Remember this is a telephone conversation. Give the caller opportunities to talk.\n- Politely redirect any off-topic questions back to Harrison Climate Solutions' services or appointment scheduling.\n- If they hadn't requested an endtime always assume for 30 mins meeting.\n- When asking for EMAIL always say: \" Can you spell your email please ? \".\n\n[Reminder]  \n- Use your knowledge base to access more information about the business.\n- Current Date and Time: {{\"now\" | date: \"%b %d, %Y, %I:%M %p\", \"America/Chicago\"}}\n- Do not repeat the caller.\n- Do not Book Calls on Saturday and Sunday and on Holidays (Always getslots)\n- Mention that Harrison Climate Solutions operates Monday through Friday, 8 a.m. to 5 p.m.\n- ONLY MOVE FORWARD when you have correct NAME, EMAIL and TIMMINGS. \n\n- When people ask about your phone number, your phone number is 4158923245\n **Guideline**\nWhen speaking the phone number, transform the format as follows:\n- Input formats like 4158923245, (415) 892-3245, or 415-892-3245\n- Should be pronounced as: \"four one five - eight nine two - three two four five\"\n- Important: Don't omit the space around the dash when speaking\n\nAlways ask to spell the email out. \n**How to spell out**\nThe possible email format is name@company.com\nto spell out an email address is N - A - M - E - @company.com,\nYOU MUST read them out with regular words like 'company' or 'blue'.\nFor names, you must read them out letter by letter, for example, 'P - R - A - T - I - K'.\n@ is pronounced by \"at\" or \"at direct\".\n\n- State Numbers, Times & Dates Slowly\nFor 1:00 PM, say “One PM.”\nFor 3:30 PM, say “Three thirty PM.”\nFor 8:45 AM, say “Eight forty-five AM.”\nNever say “O’Clock.” Instead just say O-Clock never O'clock, This is non-negotiable—always say “AM” or “PM.\n\n[Tool Usage Guidelines]  \n\n1. **Booking Appointments (BookSlot Tool)**  \n   - **Purpose**: Use the `BookSlot` function to finalize an appointment when all required details (name, email, start time, and notes) are gathered.\n   - **Parameters**: Ensure the following parameters are complete before calling:\n     - `name`: The attendee's name (never make up or use a placeholder).\n     - `email`: The attendee's email (never make up or use a placeholder).\n     - `start`: Appointment start time in ISO 8601 format (e.g., `\"2023-04-25T15:00:00Z\"`) in America/Chicago timezone.\n     - `notes`: A brief description (2-3 sentences) summarizing what the customer is looking for and why they need the appointment.\n \n2. **Finding Available Slots (GetSlots Tool)**  \n   - **Purpose**: Use `GetSlots` to check available time slots for an appointment when date parameters (start and end time in ISO format) are known.\n   - **Parameters**:\n     - `startTime`: Start of the search window.\n     - `endTime`: End of the search window.\n   - **Directive**: Immediately call `GetSlots` without waiting for any additional user response if you have all required information for `startTime` and `endTime`. Do not pause or expect further input before calling.\n\n3. **Canceling Appointments (CancelSlots Tool)**  \n   - **Purpose**: Use the `CancelSlots` function to cancel an appointment when all required details (name, email, start time) are gathered.\n   - **Parameters**: Ensure the following parameters are complete before calling:\n     - `name`: The attendee's name (never make up or use a placeholder).\n     - `email`: The attendee's email (never make up or use a placeholder).\n     - `start`: Appointment start time in ISO 8601 format (e.g., `\"2023-04-25T15:00:00Z\"`)  in America/Chicago timezone.\n     - `Cancelnotes`: A brief description (2-3 sentences) summarizing why the customer want to cancel the appointment.\n\n4. **Transferring Calls (TransferCall Tool)**\n**Purpose**: Use the `TransferCall` function to connect the caller to Sam’s forwarding number when absolutely necessary.\n   - **When to Use**: \n     - If the caller says the secret phrase \"Hot Brisket.\"\n     - If you determine the situation is a genuine emergency and requires immediate attention.\n   - **Directive**: Use the `TransferCall` tool immediately when one of the above conditions is met, forwarding the caller to Sam’s specified phone number. Do not attempt to handle emergencies yourself, and do not wait for caller feedback before initiating the transfer. Transfer the call to Sam.\n\n[Task]\n1. **Service Questions**\n   - If the caller has questions about services, provide a concise description of the relevant services based on company offerings.\n   - Mention popular seasonal promotions as relevant (e.g., furnace tune-ups in winter, AC installation deals in summer).\n   - For questions about pricing, explain that Harrison Climate Solutions offers free estimates and stress the transparency of pricing with no hidden fees.\n\n2. **Appointment Scheduling**\n   - Do not try to schedule an appointment for a time in the past. Give a friendly joke about scheduling in the past if they try.\n   - If the caller is interested in scheduling an appointment, **follow these steps**:\n      1. Gather attendee’s email, ask them to spell their email: \" Can you spell your email \" eg: \" P-R-A-T-I-K@gmail.com \", name , preferred time, and reason for the appointment. ONLY MOVE FORWARD when you have correct NAME, EMAIL and TIMMINGS. \n      2. If you have both `startTime` and `endTime`, **immediately call `GetSlots` to check for availability**. Do not wait for caller feedback after confirming you’ll check.\n      3. Only suggest available slots based on confirmed results from `GetSlots`. Never make up availability if none is returned.\n      4. If `GetSlots` returns more than three options, offer just two to three choices to help the caller decide.\n      5. If no availability is found, inform the caller courteously that slots are fully booked and suggest calling back later.\n   - Once a suitable time is identified, use the `BookSlot` tool to schedule the appointment, and confirm the details with the caller. **Only use this tool to book an appointment. Never make up an appointment booking. Do not wait for caller feedback before calling this tool if you have everything you need.**\n   - Mention that Harrison Climate Solutions operates Monday through Friday, 8 a.m. to 5 p.m. If emergency then only 24-hour, 7-day-a-week if needed in America/Chicago time zone.\n\n3. ** Update Appointment** \n- if the caller is interested in Rescheduling/Updating their booking **follow the steps**:\n   1. Gather attendee's name and ask them to spell their email : \" Can you spell your email \", Previous booking timings like starttime and rescheduling time for rescheduling. (ONLY MOVE FORWARD when you have correct NAME, EMAIL and TIMMINGS. )\n   2. If you have 'starttime' and email, **immediately call 'GetSlots' to check if time is not available . Do not wait for caller feedback after confirming you’ll check. \n  3. if time is not available, then Call the 'UpdateSlots' tool for rescheduling.\n  4. If time is available, inform the caller that there is no appointment booked at that time.\n\n4. **Cancel Appointment **\n  - if the caller is interested in canceling a booking, **follow the steps**:\n    1. Gather attendee's name and ask them to spell their email : \" Can you spell your email \", timings and if possible reason for cancelation. ( ONLY MOVE FORWARD when you have correct NAME, EMAIL and TIMMINGS. )\n    2. If you have 'starttime' and email, **immediately call 'GetSlots' to check if time is not available . Do not wait for caller feedback after confirming you’ll check. \n    3. if time is not available, then insists caller to 'Update appointment' first and if he don't want to update appointment then use the 'CancelSlots' tool to cancel the appointment. \n    4. If time is available, inform the caller that there is no appointment booked at that time.\n\n---**END**---"},"typeVersion":1},{"id":"44596616-27ba-47c0-8a6d-cf50f86a136e","name":"Sticky Note15","type":"n8n-nodes-base.stickyNote","position":[280,900],"parameters":{"color":7,"width":191,"height":80,"content":"**☝️ Set up `Getslot` tool and Webhook in Vapi**\n"},"typeVersion":1},{"id":"226635e5-05cf-4da6-bbd5-304e458a7112","name":"Sticky Note16","type":"n8n-nodes-base.stickyNote","position":[400,1960],"parameters":{"color":7,"width":191,"height":80,"content":"**☝️ Set up `Bookslot` tool and Webhook in Vapi**\n"},"typeVersion":1},{"id":"dd2caca4-8669-447f-85ee-b0d829e0e8c4","name":"Sticky Note17","type":"n8n-nodes-base.stickyNote","position":[460,2880],"parameters":{"color":7,"width":191,"height":80,"content":"**☝️ Set up `Updateslot` tool and Webhook in Vapi**\n"},"typeVersion":1},{"id":"be40ca37-c272-4170-a6b1-cf17a28c37ba","name":"Sticky Note18","type":"n8n-nodes-base.stickyNote","position":[440,3780],"parameters":{"color":7,"width":191,"height":80,"content":"**☝️ Set up `Cancelslot` tool and Webhook in Vapi**\n"},"typeVersion":1},{"id":"98af9e21-fb6e-41ef-a15e-f0b914e1dc8d","name":"Sticky Note19","type":"n8n-nodes-base.stickyNote","position":[440,4440],"parameters":{"color":7,"width":191,"height":80,"content":"**☝️ Set up `call_results` as a Server Webhook in Vapi**\n"},"typeVersion":1},{"id":"ab8f9a65-74b1-42ce-ba65-8f0e0e390839","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[-1800,340],"parameters":{"color":7,"width":1460,"height":1540,"content":"## Voice Receptionist for Appointment Management (tools)\n\n## Introduction\n### What This Template Does:\n- This n8n workflow template automates appointment management using a voice AI receptionist powered by Vapi. It integrates Vapi with Google Calendar for real-time scheduling and Airtable for logging and data management. Agent checks availability, books new appointments, reschedules existing ones, or cancels appointments directly within Google Calendar.\n\n### Problem It Solves:\n- Managing appointment scheduling manually can be time-consuming, and limited by business hours. This template solves these issues by providing an automated, 24/7 (within configured business rules) voice-based scheduling system. It frees up human staff from routine scheduling tasks, reduces booking errors, ensures appointments are logged consistently, and enhances the customer experience by offering immediate scheduling capabilities over the phone. It also captures valuable call data like recordings, summaries, and costs for analysis.\n\n## Setup Instructions\n\n### Prerequisites:\n- An active n8n instance.\n- A Vapi account for the voice agent.\n- A Google account with access to Google Calendar.\n- An Airtable account.\n- API Keys/Credentials for Google Calendar and Airtable configured in your n8n instance.\n\n## Step-by-Step Setup:\n### 1. Copy Airtable Base:\n- Duplicate the provided Airtable base structure to your own Airtable account using this link: https://airtable.com/appxDqRoEgG5sF2gu/shrnZU0D29TPMCjpt\n- Note: The n8n workflow is configured to work with the specific tables and fields in this base (\"Appointments\" and \"Call Recording\" tables).\n\n### 2. Import n8n Workflow:\n- Import the provided n8n workflow JSON into your n8n instance.\n\n### 3. Configure n8n Credentials:\n- Locate the Google Calendar nodes within the workflow (e.g., \"Check Availability\", \"Get All Calendar Events\", \"Create Event\", \"Update Event\", \"Delete Event\"). Ensure they are configured to use your Google Calendar credentials in n8n. Select the correct calendar to manage.\n- Locate the Airtable nodes (e.g., \"Logs the confirmed booking details\", \"Finds original appointment\", \"Updates Airtable record\", \"Save all information\"). Ensure they are configured with your Airtable credentials and point to the correct Base and Tables you created in Step 1.\n\n### 4. Activate the n8n Workflow:\n- Save and activate the n8n workflow. This generates the live Webhook URLs needed for Vapi.\n\n### 5. Configure Vapi Assistant:\n- **System Prompt:** Copy the system prompt provided in the large sticky note within the n8n workflow. Adapt it as needed (e.g., business name, hours) and paste it into your Vapi Assistant's System Prompt configuration. This prompt instructs the AI on its role, rules, and how/when to use the tools.\n\n- **Tools Setup:** In your Vapi Assistant configuration, define the following 4 tools:\n  - Getslots Tool:\n    - Purpose: To check calendar availability.\n    - Webhook URL: Copy the Production URL from the \"Getslot_tool\" Webhook node in your active n8n workflow (path: /getslots) and paste it here.\n  - Bookslots Tool:\n    - Purpose: To create a new calendar event.\n    - Webhook URL: Copy the Production URL from the \"bookslots_tool\" Webhook node in your active n8n workflow (path: /bookslots) and paste it here.\n  - Updateslots Tool:\n    - Purpose: To modify an existing calendar event.\n    - Webhook URL: Copy the Production URL from the \"Updateslots_tool\" Webhook node in your active n8n workflow (path: /updateslots) and paste it here.\n  - Cancelslots Tool:\n    - Purpose: To delete a calendar event.\n    - Webhook URL: Copy the Production URL from the \"CancelSlots_tool\" Webhook node in your active n8n workflow (path: /cancelslots) and paste it here.\n- **Server Webhook (End of Call Report):**\n  - In Vapi's server configuration section (often under webhooks or reporting), find the setting for the end-of-call-report or similar event.\n  - Copy the Production URL from the \"call_results\" Webhook node in your active n8n workflow (path: /callresults).\n  - Paste this URL into the Vapi configuration for the end-of-call server webhook. This allows n8n to receive and log call summaries, recordings, etc., after the call ends.\n\n## Video Walkthrough (coming soon)\n### [🎥 Watch set up video (~2min)](https://www.loom.com/share/d379895004374ddc85dc9171ca37c139?sid=0996f0d2-aff2-45a7-aae9-c62df4fb0799)\n"},"typeVersion":1},{"id":"8d984e05-5bca-4c70-beee-16f7cd70594e","name":"Sticky Note12","type":"n8n-nodes-base.stickyNote","position":[40,300],"parameters":{"color":7,"width":3700,"height":4400,"content":"# Workflow"},"typeVersion":1}],"pinData":{},"connections":{"Sort":{"main":[[{"node":"Format response","type":"main","index":0}]]},"Enrich Date":{"main":[[{"node":"Build Response Payload","type":"main","index":0}]]},"Escape Json":{"main":[[{"node":"Convert time to CST America / Chicago","type":"main","index":0}]]},"Create Event":{"main":[[{"node":"Booking Payload","type":"main","index":0}],[{"node":"Add Friendly Error","type":"main","index":0}]]},"Delete Event":{"main":[[{"node":"Update Airtable record","type":"main","index":0}],[{"node":"Call_id & Response","type":"main","index":0}]]},"Getslot_tool":{"main":[[{"node":"Input Arguments","type":"main","index":0}]]},"Update Event":{"main":[[{"node":"Updates Airtable record","type":"main","index":0}],[{"node":"Response & call_id","type":"main","index":0}]]},"call_results":{"main":[[{"node":"All Input Arguments","type":"main","index":0}]]},"Flatten Slots":{"main":[[{"node":"Enrich Date","type":"main","index":0}]]},"Error Response":{"main":[[{"node":"Respond to Vapi","type":"main","index":0}]]},"bookslots_tool":{"main":[[{"node":"Input Arguments from booking tools","type":"main","index":0}]]},"Booking Payload":{"main":[[{"node":"Success Response","type":"main","index":0}]]},"Format response":{"main":[[{"node":"Available Start Times & Ranges","type":"main","index":0}]]},"Input Arguments":{"main":[[{"node":"Check Availability","type":"main","index":0}]]},"Respond to Vapi":{"main":[[{"node":"If the booking is confirmed then true","type":"main","index":0}]]},"CancelSlots_tool":{"main":[[{"node":"Input Arguments from cancelslot tool","type":"main","index":0}]]},"Success Response":{"main":[[{"node":"Respond to Vapi","type":"main","index":0}]]},"Updateslots_tool":{"main":[[{"node":"Input Arguments from updateslot tool","type":"main","index":0}]]},"Add Friendly Error":{"main":[[{"node":"Error Response","type":"main","index":0}]]},"Call_id & Response":{"main":[[{"node":"Respond to Vapi about cancelation","type":"main","index":0}]]},"Check Availability":{"main":[[{"node":"Check if time is available or not","type":"main","index":0}]]},"Response & call_id":{"main":[[{"node":"Respond to Vapi about Updating slots","type":"main","index":0}]]},"All Input Arguments":{"main":[[{"node":"Save all information","type":"main","index":0}]]},"Has all information":{"main":[[{"node":"Escape Json","type":"main","index":0}],[{"node":"Build Error Response Payload","type":"main","index":0}]]},"Build Error Response":{"main":[[{"node":"Respond with Error to Vapi","type":"main","index":0}]]},"Build Response Payload":{"main":[[{"node":"Convert into Json format for Vapi","type":"main","index":0}]]},"Update Airtable record":{"main":[[{"node":"Call_id & Response","type":"main","index":0}]]},"Get All Calendar Events":{"main":[[{"node":"Extract start, end and name","type":"main","index":0}]]},"Updates Airtable record":{"main":[[{"node":"Response & call_id","type":"main","index":0}]]},"Finds original appointment":{"main":[[{"node":"Update Event","type":"main","index":0}]]},"Extract start, end and name":{"main":[[{"node":"Sort","type":"main","index":0}]]},"Build Error Response Payload":{"main":[[{"node":"Respond with Error","type":"main","index":0}]]},"Finds the appointment record":{"main":[[{"node":"Delete Event","type":"main","index":0}]]},"Build Error Response Payload2":{"main":[[{"node":"Response with Error","type":"main","index":0}]]},"Available Start Times & Ranges":{"main":[[{"node":"Flatten Slots","type":"main","index":0}]]},"Time available (true) & Call_id":{"main":[[{"node":"Response","type":"main","index":0}]]},"Check if time is available or not":{"main":[[{"node":"Time available (true) & Call_id","type":"main","index":0}],[{"node":"Get All Calendar Events","type":"main","index":0}]]},"Convert into Json format for Vapi":{"main":[[{"node":"Response to Vapi","type":"main","index":0}]]},"Input Arguments from booking tools":{"main":[[{"node":"Has all information","type":"main","index":0}]]},"Information to be Saved in Airtable":{"main":[[{"node":"Logs the confirmed booking details","type":"main","index":0}]]},"Checks if required info is provided.":{"main":[[{"node":"Finds original appointment","type":"main","index":0}],[{"node":"Build Error Response Payload2","type":"main","index":0}]]},"Input Arguments from cancelslot tool":{"main":[[{"node":"Checks if required info is provided for cancelation","type":"main","index":0}]]},"Input Arguments from updateslot tool":{"main":[[{"node":"Checks if required info is provided.","type":"main","index":0}]]},"Convert time to CST America / Chicago":{"main":[[{"node":"Create Event","type":"main","index":0}]]},"If the booking is confirmed then true":{"main":[[{"node":"Information to be Saved in Airtable","type":"main","index":0}]]},"Checks if required info is provided for cancelation":{"main":[[{"node":"Finds the appointment record","type":"main","index":0}],[{"node":"Build Error Response","type":"main","index":0}]]}}}


