AutomationFlowsAI & RAG › Route Chatwoot Customer Chats to AI and Live Agents with Groq and Gemini

Route Chatwoot Customer Chats to AI and Live Agents with Groq and Gemini

ByMohan Lal Dhanwani @mohanlaldhanwani on n8n.io

This workflow automates customer chat with Chatwoot & n8n AI agent that handles incoming chats, qualifies leads, answers FAQs from Pinecone knowledge base, and escalates to a live human agent when one is online. Works with any Chatwoot inbox: web widget, WhatsApp, Telegram, and…

Webhook trigger★★★★☆ complexityAI-powered24 nodesHTTP RequestMemory Postgres ChatGmail ToolHTTP Request ToolGroq ChatPinecone Vector StoreGoogle Gemini EmbeddingsGoogle Gemini Chat
AI & RAG Trigger: Webhook Nodes: 24 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #16039 — we link there as the canonical source.

This workflow follows the Agent → Google Gemini Embeddings recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "fnsCDK15mlpcSlyX",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "AI Customer Chat Assistant with Live Agent Escalation (Chatwoot)",
  "tags": [],
  "nodes": [
    {
      "id": "f5f7f98d-08a1-48f7-8cc2-c8d2477af5c8",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2928,
        1504
      ],
      "parameters": {
        "color": 4,
        "width": 368,
        "height": 352,
        "content": "## Format customer reply\n\nTakes the AI Agent output and splits it into multiple short messages suitable for sending as customer-facing chat replies."
      },
      "typeVersion": 1
    },
    {
      "id": "d489c1ac-8c08-4526-910e-c0244e2977f3",
      "name": "Check Live Agent Assignment",
      "type": "n8n-nodes-base.if",
      "position": [
        1376,
        1792
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c0aba6af-d38e-4841-8622-54bd0c1c79e6",
              "operator": {
                "type": "object",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $('Incoming Chat Webhook').item.json.body.conversation.meta.assignee }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "b8bfdbcc-be68-4a11-8b27-935dfaded04f",
      "name": "Split AI Messages",
      "type": "n8n-nodes-base.code",
      "position": [
        3024,
        1680
      ],
      "parameters": {
        "jsCode": "// Split AI Agent output into multiple short messages\n// Splits on double newline (\\n\\n) \u2014 agent should separate thoughts with blank lines\n\nconst agentOutput = $input.first().json.output || \"\";\nconst accountId = $('Prepare Field Edits').first().json.account_id;\nconst conversationId = $('Prepare Field Edits').first().json.conversation_id;\n// \u2699\ufe0f CONFIGURE: Replace with your Chatwoot API access token\nconst chatwootToken = \"Your_API_Access_Token_Here\";\n// \u2699\ufe0f CONFIGURE: Replace with your Chatwoot instance URL (no trailing slash)\nconst chatwootBaseUrl = \"https://your-chatwoot-url.com\";\n\n// Split on double newlines, filter out empty chunks\nconst chunks = agentOutput\n  .split(/\\n\\n+/)\n  .map(c => c.trim())\n  .filter(c => c.length > 0);\n\nconst results = [];\n\nfor (const chunk of chunks) {\n  const response = await this.helpers.httpRequest({\n    method: \"POST\",\n    url: `${chatwootBaseUrl}/api/v1/accounts/${accountId}/conversations/${conversationId}/messages`,\n    headers: {\n      \"api_access_token\": chatwootToken,\n      \"Content-Type\": \"application/json\"\n    },\n    body: {\n      content: chunk,\n      message_type: \"outgoing\"\n    },\n    json: true\n  });\n\n  results.push({\n    json: {\n      chunk,\n      message_id: response.id || null,\n      success: true\n    }\n  });\n\n  // Small delay between messages to preserve order in Chatwoot\n  await new Promise(resolve => setTimeout(resolve, 300));\n}\n\nreturn results;"
      },
      "typeVersion": 2
    },
    {
      "id": "d9ed5c34-eda8-4dbf-bc58-b3d74c231571",
      "name": "Route by Chat Message Type",
      "type": "n8n-nodes-base.switch",
      "position": [
        1072,
        1904
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Incoming",
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "3326acb0-226a-485b-8c96-79c3ca6d5efd",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $('Prepare Field Edits').item.json.message_type }}",
                    "rightValue": "incoming"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Outgoing",
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "3ff79a75-5d26-45c8-b28b-80a9db7eb53a",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $('Prepare Field Edits').item.json.message_type }}",
                    "rightValue": "outgoing"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.4
    },
    {
      "id": "76682f92-5f02-46b6-8f08-ab51000cc08e",
      "name": "Skip Operation",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1376,
        2064
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "a4675092-9cff-411f-a929-fb2ba5d47e1f",
      "name": "Fetch Live Agent Data",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1648,
        1808
      ],
      "parameters": {
        "url": "=https://{Your_Chatwoot_Base_URL}/api/v1/accounts/{{ $('Route by Chat Message Type').first().json.account_id }}/agents",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "api_access_token",
              "value": "Your_API_Access_Token_Here"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "72108f17-ef82-4cbb-a26d-432fa1a83581",
      "name": "Store Chat Memory in Postgres",
      "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
      "position": [
        2480,
        1600
      ],
      "parameters": {
        "sessionKey": "={{ $('Prepare Field Edits').first().json.conversation_id }}",
        "sessionIdType": "customKey",
        "contextWindowLength": 12
      },
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "e4c319a2-2b42-45ea-9e4e-d46cecb00e0d",
      "name": "Send Internal Team Email",
      "type": "n8n-nodes-base.gmailTool",
      "position": [
        2352,
        2128
      ],
      "parameters": {
        "sendTo": "your@email.com",
        "message": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Message', ``, 'string') }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Subject', ``, 'string') }}",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "d5eb4c06-688f-493d-91b4-42dacd5b5ac0",
      "name": "Escalate Chat via HTTP",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        2160,
        2128
      ],
      "parameters": {
        "url": "=https://{Your_Chatwoot_Base_URL}/api/v1/accounts/{{ $('Route by Chat Message Type').first().json.account_id }}/conversations/{{ $('Route by Chat Message Type').first().json.conversation_id }}/assignments",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "assignee_id",
              "value": "={{ $json.assignee_id }}"
            }
          ]
        },
        "toolDescription": "Use this tool to escalate the chat to human agent or when chat user wants to talk with human",
        "headerParameters": {
          "parameters": [
            {
              "name": "api_access_token",
              "value": "Your_API_Access_Token_Here"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "888cd692-7225-4636-9626-f5c1e9b4fdfd",
      "name": "Incoming Chat Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        560,
        1904
      ],
      "parameters": {
        "path": "db587fad-cb47-47a0-9c72-bac02c241a67",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2.1
    },
    {
      "id": "e4c0df30-7265-44be-b36e-e133de959cbb",
      "name": "Prepare Field Edits",
      "type": "n8n-nodes-base.set",
      "position": [
        816,
        1904
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={\n  \"account_id\": \"{{ $json.body.conversation.messages[0].account_id }}\",\n  \"conversation_id\": \"{{ $json.body.conversation.messages[0].conversation_id }}\",\n\n  \"message_type\": \"{{ $json.body.message_type }}\",\n  \"user_name\": \"{{ $json.body.sender.name }}\",\n  \"user_email\": \"{{ $json.body.sender.email || 'no email provided'}}\",\n  \"user_phone_number\": \"{{ $json.body.sender.phone_number  || 'no phone provided' }}\",\n  \"user_message_content\": \"{{ $json.body.content }}\"\n}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "340d2680-6055-4a6e-9bd0-b1e2344e40ad",
      "name": "Use Groq Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGroq",
      "position": [
        2320,
        1600
      ],
      "parameters": {
        "model": "openai/gpt-oss-120b",
        "options": {}
      },
      "credentials": {
        "groqApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e108937d-db0d-4efe-8475-075ae6fd6773",
      "name": "Utilize Pinecone Vector Store",
      "type": "@n8n/n8n-nodes-langchain.vectorStorePinecone",
      "position": [
        2960,
        2304
      ],
      "parameters": {
        "options": {
          "pineconeNamespace": "knowledge_base"
        },
        "pineconeIndex": {
          "__rl": true,
          "mode": "list",
          "value": "mohandhanwani",
          "cachedResultName": "mohandhanwani"
        }
      },
      "credentials": {
        "pineconeApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "c0094f81-13a4-4bb5-8e27-f659505c0236",
      "name": "Generate Google Gemini Embeddings",
      "type": "@n8n/n8n-nodes-langchain.embeddingsGoogleGemini",
      "position": [
        3024,
        2464
      ],
      "parameters": {
        "modelName": "models/gemini-embedding-001"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "11513e14-a768-4282-9d8d-00ab9802b4d7",
      "name": "Implement Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        3280,
        2304
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f67dd766-e364-48a4-8096-3858b5db0c3a",
      "name": "AI Customer Support Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2336,
        1808
      ],
      "parameters": {
        "text": "=user_name: {{ $('Prepare Field Edits').first().json.user_name }}\n\nuser_email: {{ $('Prepare Field Edits').first().json.user_email }}\n\nuser_phone_number: {{ $('Prepare Field Edits').first().json.user_phone_number }}\n\nuser_message: {{ $('Prepare Field Edits').first().json.user_message_content }}\n\n** Notes **\n- user_name provided above can be real name or randomly assigned name from chatwoot at chat start (examples - hidden-glade-157, muddy-morning-816), so if you get randomly assigned names, don't use those as reference for user_name\n- if user provides name, email, phone number, and message in chat, you can use those as the main values for reference in chat. \n- If user name, email, phone etc. are provided in chat... Make sure to keep a log of it and not ask user again for those",
        "options": {
          "systemMessage": "=# Role\nYou are a Professional AI Chat Assistant for [Brand]. Your job is to manage incoming website chats and queries in professional and a friendly way.\n\nYou are mainly to qualify leads, help existing clients, and answer queries that our users have.\n\nYou Representing a personal brand and the services we offers:\n\n- AI Automation & Workflow Creation\n- Email Marketing Strategy, Excution and Automation\n- ActiveCampaign Email Campaign Implementation\n- Website Chatbot Implementation\n- And related digital growth services\n\nYou may respond in the user's preferred language.\n\nCurrent time {{ $now }}\n---\n\n## \u26a1 RESPONSE FORMAT \u2014 HIGHEST PRIORITY\n\n- NEVER write one long, dense message\n- If your answer needs more than 3 lines \u2192 SPLIT into multiple short messages\n- One idea per message. Short. Conversational. Human.\n\n\u2705 CORRECT:\n\u2192 \"Great question! We specialize in building AI-powered workflows that save businesses hours every week. \ud83e\udd16\"\n\u2192 \"This includes automations using tools like n8n, Make, Zapier, and custom AI integrations.\"\n\u2192 \"Want me to grab a few details so Mohan can reach out with something tailored for you?\"\n\n\u274c WRONG:\n\u2192 One giant message with 6 bullet points\n\u2192 Paragraphs explaining every service at once\n\u2192 Repeating the same info in different ways\n\n---\n\n## LEAD DATA \u2014 COLLECT GRADUALLY, NOT ALL AT ONCE\n\nFor new visitors, collect: Name \u2192 Business Email \u2192 Phone \u2192 Requirement\nFor existing clients, collect: Name + Email or Project/Order Reference\n\nRules:\n- Ask for ONE piece of information at a time\n- Never re-ask something already provided\n- Keep it natural: \"Could I also grab your work email to send over the details?\"\n\n---\n\n## CONVERSATION FLOW\n\n**First message \u2014 always:**\n\"Hey there! \ud83d\udc4b I'm Xiao bot from [Your Brand].\n\nI'm here to help answer any questions, and help with any of our service details.\n\nAre you visiting for the first time, or are you an existing client?\"\n\n**New Visitor Path:**\nCollect Name \u2192 Business Email \u2192 Phone \u2192 Requirement or query(one at a time, skip if already shared)\n\u2192 Once collected \u2192 Acknowledge request and see if they'd like to add anything else to it or would like to book a meeting as well \u2192 Once all details are there, send lead summary via internal_team_email and set proper expectations like: \"I've forwarded your requirement as a priority to our team \u2014 you should hear back via email shortly.\" \n\n**Existing Client Path:**\nAsk for Email or Project Reference \u2192 Acknowledge \u2192 Escalate as priority\n\u2192 Assist with queries using available tools wherever possible\n\n---\n\n## TOOLS\n\n### 1. escalate_chat\nUse this tool to escalate the chat to human when required, or when user wants to talk to human\n\n- Call ONLY when `agent_online = \"yes\"` from previous input.\n\u2192 After calling: \"I'm looping one of our Live Agents in right now \u2014 someone will be with you shortly! \ud83d\ude4c\"\n\nIf `agent_online = \"no\"` \u2192 Do NOT call this tool. Use internal_team_email instead.\n\u2192 Say: \"Our team is unavailable at the moment, but I've flagged your message as priority. You'll hear back via email soon!\"\n\n### 2. internal_team_email\nUse when:\n- Lead details have been fully collected\n- No agents online but escalation is needed\n- Query is urgent or time-sensitive\n- Conversation is wrapping up (send a summary)\n- Feedback has been received\n\n\n### 3 Mohan_faqs\nUse when:\n- Lead has provided all the details and asks query about [Your Brand] or our services\n- Use this to fetch answers to any queries related to Case Studies, Average Revenue, Benefits, contact details etc.\n- If details not found in the knowledge base, let the user know and mention that their query has been forwarded as priority to the team \u2014 they should hear back shortly.\n\n---\n\n## CONVERSATION CLOSING\n\n1. Send a summary via internal_team_email\n2. Ask: \"Really glad I could help! \ud83d\ude0a Would you mind sharing quick feedback on your experience today?\"\n3. After feedback: \"Thank you so much \u2014 that means a lot! Have an amazing day! \ud83d\ude4c\"\n\n---\n\n## PRIORITY ORDER\n\n1. Warm greeting + qualify visitor type\n2. Collect lead details (one at a time)\n3. Understand their requirement clearly\n4. Route or escalate correctly\n5. Try answering the query that user has asked\n6. Close the conversation properly\n\n---\n\n## EDGE CASES\n\n- **Strong buying intent detected** \u2192 Fast-track lead capture immediately, skip small talk\n- **Vague or unclear request** \u2192 Ask ONE clarifying question max, keep it simple\n- **User goes quiet** \u2192 Do NOT follow up or send repeated messages\n- **Pricing asked too early** \u2192 \"We put together custom quotes based on your specific needs \u2014 let me grab a few quick details first!\"\n- **Out-of-scope questions** \u2192 Politely redirect: \"That's a bit outside what I can help with here, but our team would be happy to assist \u2014 want me to pass your details along?\"\n\n---\n\n## TONE & BRAND VOICE\n\n- Friendly, confident, and professional \u2014 like a sharp assistant who genuinely wants to help\n- Never robotic. Never overly formal. Keep it conversational.\n- Always reflect that the humans behind [Your Brand] \u2014 someone who builds real solutions for real businesses, and your job is to keep the trust for easier business."
        },
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "ff5423b4-1ddf-43bd-923f-f7d29e811bde",
      "name": "Access Knowledge Base",
      "type": "@n8n/n8n-nodes-langchain.toolVectorStore",
      "position": [
        3024,
        2128
      ],
      "parameters": {
        "description": "Use this tool to search the knowledge base (FAQs, services, case studies, pricing, contact info) and answer user queries based on the stored documents"
      },
      "typeVersion": 1.1
    },
    {
      "id": "d3c86c15-a4a4-42cf-8f6a-ae5fe9f4cf2d",
      "name": "Generate Assignee Agent ID",
      "type": "n8n-nodes-base.code",
      "position": [
        1936,
        1808
      ],
      "parameters": {
        "jsCode": "const agents = $input.all().map(item => item.json);\n\nconst onlineAgents = agents.filter(\n  agent => agent.availability_status === \"online\"\n);\n\nif (onlineAgents.length > 0) {\n  const randomAgent =\n    onlineAgents[Math.floor(Math.random() * onlineAgents.length)];\n\n  return [\n    {\n      json: {\n        agent_online: \"yes\",\n        assignee_id: randomAgent.id // \u2705 renamed here\n      }\n    }\n  ];\n}\n\nreturn [\n  {\n    json: {\n      agent_online: \"no\"\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "de55be31-9dc0-4162-b49a-c890e9c35d78",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -48,
        1472
      ],
      "parameters": {
        "width": 480,
        "height": 896,
        "content": "## AI Customer Chat Assistant with Live Agent Escalation (Chatwoot)\n\n### How it works\n\nThis workflow receives Chatwoot webhook events, normalizes the incoming fields, and routes messages based on their type and live-agent assignment status. Eligible customer messages are checked against Chatwoot live-agent details, then passed into an AI agent that can answer from a knowledge base, use chat memory, email the internal team, or escalate the conversation. The AI response is finally split into short reply messages for sending back to the customer, while irrelevant message types are ignored.\n\n### Setup steps\n\n- Configure the Chatwoot webhook URL and ensure incoming payload fields match the fields expected by the Edit Fields and routing nodes.\n- Set the Chatwoot API base URL and authentication credentials in the live-agent lookup and escalation HTTP request/tool nodes.\n- Configure credentials for Groq, Google Gemini embeddings, Pinecone, Postgres chat memory, and Gmail.\n- Create or select the Pinecone index used by the knowledge base and ensure it contains embedded support content compatible with the Gemini embeddings node.\n- Review the AI Agent prompt/tools so escalation, internal email, and reply behavior match your support process.\n\n### Customization\n\nAdjust the message-type routing rules, live-agent assignment logic, AI agent instructions, knowledge base index, and reply-splitting behavior to match your Chatwoot inbox and customer support policies."
      },
      "typeVersion": 1
    },
    {
      "id": "b12422b7-6b98-4335-926d-bab5c2fc5667",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        512,
        1744
      ],
      "parameters": {
        "color": 4,
        "width": 448,
        "height": 320,
        "content": "## Receive and normalize event\n\nStarts the workflow from a Chatwoot webhook and prepares the incoming payload fields for downstream routing."
      },
      "typeVersion": 1
    },
    {
      "id": "d6f26b05-b8e1-4709-929e-43ca36b104a6",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1024,
        1632
      ],
      "parameters": {
        "color": 3,
        "width": 496,
        "height": 592,
        "content": "## Route message handling\n\nBranches the normalized event by message type, checks whether a live agent is already assigned, and safely ignores events that should not trigger an AI response."
      },
      "typeVersion": 1
    },
    {
      "id": "c5fd623d-ba16-47df-a123-8c1a17ebdcef",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1600,
        1648
      ],
      "parameters": {
        "color": 5,
        "width": 480,
        "height": 320,
        "content": "## Resolve live agent\n\nFetches live-agent details from Chatwoot and extracts the relevant assignee agent ID from the online agents data before AI processing."
      },
      "typeVersion": 1
    },
    {
      "id": "c95527c9-7ba0-4bf6-92d6-2fff41e67931",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2112,
        1472
      ],
      "parameters": {
        "color": 5,
        "width": 768,
        "height": 816,
        "content": "## Run support AI\n\nUses the central AI Agent with a Groq chat model, Postgres conversation memory, and operational tools for escalation and internal team email notifications."
      },
      "typeVersion": 1
    },
    {
      "id": "c40c7e95-68d9-456b-9c30-8f9c174b4da2",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2912,
        1888
      ],
      "parameters": {
        "color": 5,
        "width": 560,
        "height": 736,
        "content": "## Knowledge base retrieval\n\nProvides the AI agent with a vector-store knowledge tool backed by Pinecone and Google Gemini embeddings, grouped as a distinct knowledge cluster on the right side of the canvas."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "c09c384c-ddb5-4e8c-b8ab-693c9acc8009",
  "connections": {
    "Prepare Field Edits": {
      "main": [
        [
          {
            "node": "Route by Chat Message Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Use Groq Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Customer Support Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Access Knowledge Base": {
      "ai_tool": [
        [
          {
            "node": "AI Customer Support Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Live Agent Data": {
      "main": [
        [
          {
            "node": "Generate Assignee Agent ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Incoming Chat Webhook": {
      "main": [
        [
          {
            "node": "Prepare Field Edits",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Escalate Chat via HTTP": {
      "ai_tool": [
        [
          {
            "node": "AI Customer Support Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Send Internal Team Email": {
      "ai_tool": [
        [
          {
            "node": "AI Customer Support Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "AI Customer Support Agent": {
      "main": [
        [
          {
            "node": "Split AI Messages",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Assignee Agent ID": {
      "main": [
        [
          {
            "node": "AI Customer Support Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Chat Message Type": {
      "main": [
        [
          {
            "node": "Check Live Agent Assignment",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Skip Operation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Live Agent Assignment": {
      "main": [
        [],
        [
          {
            "node": "Fetch Live Agent Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Store Chat Memory in Postgres": {
      "ai_memory": [
        [
          {
            "node": "AI Customer Support Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Utilize Pinecone Vector Store": {
      "ai_vectorStore": [
        [
          {
            "node": "Access Knowledge Base",
            "type": "ai_vectorStore",
            "index": 0
          }
        ]
      ]
    },
    "Generate Google Gemini Embeddings": {
      "ai_embedding": [
        [
          {
            "node": "Utilize Pinecone Vector Store",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Implement Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Access Knowledge Base",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow automates customer chat with Chatwoot & n8n AI agent that handles incoming chats, qualifies leads, answers FAQs from Pinecone knowledge base, and escalates to a live human agent when one is online. Works with any Chatwoot inbox: web widget, WhatsApp, Telegram, and…

Source: https://n8n.io/workflows/16039/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Camila IA. Uses postgres, crypto, redis, agent. Webhook trigger; 92 nodes.

Postgres, Crypto, Redis +13
AI & RAG

RAG. Uses httpRequest, agent, lmChatGoogleGemini, memoryPostgresChat. Webhook trigger; 16 nodes.

HTTP Request, Agent, Google Gemini Chat +4
AI & RAG

The "WhatsApp Productivity Assistant with Memory and AI Imaging" is a comprehensive n8n workflow that transforms your WhatsApp into a powerful, multi-talented AI assistant. It's designed to handle a w

WhatsApp Trigger, Agent, HTTP Request +20
AI & RAG

This simple philosophy changes the way we think about automated sales agents. Context changes everything. In this 4-part workflow, we start by creating a knowledge base that will act as context across

Pinecone Vector Store, Document Default Data Loader, Text Splitter Recursive Character Text Splitter +12
AI & RAG

Tech Radar. Uses googleDrive, documentDefaultDataLoader, stickyNote, mySql. Scheduled trigger; 53 nodes.

Google Drive, Document Default Data Loader, MySQL +15