AutomationFlowsAI & RAG › Answer Support Faqs with Google Gemini, Supabase, Google Sheets and Whatsapp

Answer Support Faqs with Google Gemini, Supabase, Google Sheets and Whatsapp

ByAyaan Sheikh @ayaansheikh77 on n8n.io

This workflow ingests FAQs from Google Sheets into a Supabase vector table using Google Gemini embeddings, then serves a webhook-based support chatbot that answers only from that FAQ knowledge base and escalates unanswered questions to a human via UltraMsg WhatsApp. Runs…

Webhook trigger★★★★☆ complexityAI-powered21 nodesAgentGoogle Gemini ChatSupabase Vector StoreGoogle Gemini EmbeddingsHTTP RequestMemory Buffer WindowGoogle SheetsDocument Default Data Loader
AI & RAG Trigger: Webhook Nodes: 21 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Agent → Documentdefaultdataloader 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": "D49yDRhEsjtIWn5Z",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "AI CHATBOT AND FAQs INGESTION",
  "tags": [],
  "nodes": [
    {
      "id": "69c7828a-2fea-4759-8522-c0ffb3a46026",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        320,
        -960
      ],
      "parameters": {
        "color": 3,
        "width": 484,
        "height": 924,
        "content": "## AI Support Chatbot + FAQ Ingestion\n\n**How it works**\nThis workflow answers customer questions using only a FAQ knowledge base stored in Supabase. When a visitor sends a message, the AI Agent searches the FAQ vector store for a matching answer. If nothing relevant is found, it collects the customer's email/WhatsApp number and alerts a human agent via WhatsApp (UltraMsg). A second, separate flow (top row) ingests FAQ data from a Google Sheet into the same Supabase vector store.\n\n**Setup steps**\n- Add your Google Gemini (PaLM) API credentials\n- Connect your Supabase account and create the \"FAQs Data Table\" vector table\n- Connect Google Sheets and point it at your FAQ spreadsheet (Question / Answer columns)\n- Add your UltraMsg instance ID and token, and set the destination WhatsApp number\n- Run the FAQ Ingestion flow (top) once to populate the knowledge base before going live\n\n**Customization**\n- Edit the AI Agent's system message to change tone or escalation wording\n- Adjust `topK` on the Supabase Vector Store node to return more/fewer FAQ matches\n- Change `contextWindowLength` on Simple Memory to remember more/less conversation history\n- Swap the WhatsApp alert for email or Slack by replacing the HTTP Request node"
      },
      "typeVersion": 1
    },
    {
      "id": "1d480b29-928b-4f46-9d11-d71556450328",
      "name": "FAQ Ingestion Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1024,
        -944
      ],
      "parameters": {
        "color": 4,
        "width": 1608,
        "height": 488,
        "content": "### FAQ Ingestion\n\nLoads Question/Answer rows from a Google Sheet, formats each as `Q: ... A: ...`, embeds them with Gemini, and inserts them into the Supabase FAQ vector table. Run this manually whenever the FAQ sheet is updated."
      },
      "typeVersion": 1
    },
    {
      "id": "e50347a6-9015-4e3e-8e7d-c2538fc340ba",
      "name": "Trigger Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1024,
        -416
      ],
      "parameters": {
        "color": 4,
        "width": 308,
        "height": 380,
        "content": "### Trigger\n\nReceives incoming chat messages via a POST webhook. Expects `message` and `sessionId` in the request body."
      },
      "typeVersion": 1
    },
    {
      "id": "4c5b9890-143f-4544-af3d-0ffe2aa7dbae",
      "name": "AI Agent Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1344,
        -416
      ],
      "parameters": {
        "color": 6,
        "width": 1300,
        "height": 376,
        "content": "### Answer from FAQ knowledge base\n\nThe AI Agent searches the Supabase FAQ vector store (via Gemini embeddings) and answers strictly from what it finds. Conversation context is kept per `sessionId` using Simple Memory. If no matching FAQ answer exists, it asks for the customer's email/WhatsApp instead of guessing."
      },
      "typeVersion": 1
    },
    {
      "id": "46d171ba-e237-4d69-a4a0-cfc308d1c75e",
      "name": "Escalation Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1664,
        -32
      ],
      "parameters": {
        "color": 5,
        "width": 652,
        "height": 352,
        "content": "### Escalate or respond\n\nChecks the AI Agent's reply for \"human agent\". If found, sends a WhatsApp alert (UltraMsg) with the original question and contact details, then confirms to the customer. Otherwise, the FAQ answer is sent straight back to the webhook."
      },
      "typeVersion": 1
    },
    {
      "id": "235e6eee-ddc4-485c-bb3d-282e04d58641",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1408,
        -208
      ],
      "parameters": {
        "text": "={{ $json.body.message }}",
        "options": {
          "systemMessage": "You are a professional customer support assistant.\n\nRemember the conversation during the current session using the connected Memory node.\n\nONLY answer questions using the FAQ knowledge base tool.\n\nIf the answer is found in the FAQ knowledge base, answer it clearly and professionally.\n\nIf the answer is NOT found in the FAQ knowledge base, respond with EXACTLY this message:\n\n\"Thank you for reaching out! Unfortunately, I don't have the answer to your question. However, our support team would be happy to assist you personally. Please reply with your email address or Whatsapp Contact No so we can contact you within 24 hours \ud83d\ude0a.\"\n\nIf the user's message contains an email address (for example: user@example.com) or WhatsApp no (for example: +35XXXXXXXXX) , use the conversation memory to remember the ORIGINAL question the user asked before providing their email.\n\nThen respond EXACTLY in this format:\n\nThank you! \u2705 Our human agent has been notified.\n\n\ud83d\udc64 Customer Question:\n<original question>\n\n\ud83d\udce7 Customer Email OR WhatsApp Number\n<user's email>\n\nWe will contact you within 24 hours. Have a great day!\n\nSTRICT RULES:\n\n- Never make up answers.\n- Only use information from the FAQ knowledge base.\n- Never answer questions that are not in the FAQ.\n- Never ask for the email unless the answer is not available in the FAQ.\n- Never ask the user to repeat information they have already provided.\n- When an email address is detected, always use Memory to recall the original customer question.\n- Always return a SINGLE response.\n- Do not include any extra text before or after the required response."
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "45a1b1c3-561f-4c68-b716-daa0f20f13fb",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        1360,
        48
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "bb98cc7d-6268-41ba-b5e1-90e3a4a4b728",
      "name": "Supabase Vector Store",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "position": [
        2304,
        -160
      ],
      "parameters": {
        "mode": "retrieve-as-tool",
        "topK": 3,
        "options": {},
        "tableName": {
          "__rl": true,
          "mode": "list",
          "value": "FAQs Data Table",
          "cachedResultName": "FAQs Data Table"
        },
        "toolDescription": "Search the FAQ knowledge base to find relevant answers"
      },
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "46fea408-0722-4f72-8c88-148ad3884ad6",
      "name": "Embeddings Google Gemini",
      "type": "@n8n/n8n-nodes-langchain.embeddingsGoogleGemini",
      "position": [
        2384,
        32
      ],
      "parameters": {
        "modelName": "models/gemini-embedding-2"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "827663db-f2e9-4c8c-bc87-db841185962b",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        1120,
        -208
      ],
      "parameters": {
        "path": "chat",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "fdd96310-5251-4395-b3d7-d554b885f15c",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        1808,
        -208
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "5042fbf3-ce19-4c54-b201-cdbe12cf5a58",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.output }}",
              "rightValue": "human agent"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "6f23587f-13f7-4b1a-a334-65449335a6b8",
      "name": "HTTP Request",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1792,
        144
      ],
      "parameters": {
        "url": "=https://api.ultramsg.com/instance183479/messages/chat",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "token",
              "value": "b23rfd9iwpi2bl3s"
            },
            {
              "name": "to",
              "value": "+1234567890"
            },
            {
              "name": "body",
              "value": "={{\n\"\ud83d\udea8 New Support Request!\\n\\n\" +\n$('AI Agent').item.json.output +\n\"\\n\\n\u23f0 Time: \" +\nDateTime.utc().toFormat(\"yyyy-MM-dd HH:mm:ss 'UTC'\") +\n\"\\n\\n\ud83d\udca1 Please respond within 24 hours!\"\n}}"
            }
          ]
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "fc053e09-644a-4467-87cb-485f37588a5d",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        2080,
        -192
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={ \"reply\": \"{{ $json.output }}\" }"
      },
      "typeVersion": 1.5
    },
    {
      "id": "b384c390-0aeb-409d-b73d-ff78a30b61b8",
      "name": "Simple Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        1536,
        48
      ],
      "parameters": {
        "sessionKey": "={{ $json.body.sessionId }}",
        "sessionIdType": "customKey",
        "contextWindowLength": 15
      },
      "typeVersion": 1.4
    },
    {
      "id": "bf563df4-62e5-4624-ba1d-221042b06462",
      "name": "Respond to Webhook1",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        2048,
        144
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "{\n  \"reply\": \"Thank you! \u2705 Our human agent has been notified and will reach you at your email shortly. We typically respond within 24 hours. Have a great day!\"\n}"
      },
      "typeVersion": 1.5
    },
    {
      "id": "f9b0cdaf-7a3f-4dee-95e5-ec46d48064d9",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        1104,
        -768
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "be5f4b5f-2850-4f43-8ce5-c26572d75ef9",
      "name": "Get row(s) in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1472,
        -768
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1bDIFDZMEAzLOWRmv1cWe4sxaHMNTxc9HhTiXHqjggPQ/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1bDIFDZMEAzLOWRmv1cWe4sxaHMNTxc9HhTiXHqjggPQ",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1bDIFDZMEAzLOWRmv1cWe4sxaHMNTxc9HhTiXHqjggPQ/edit?usp=drivesdk",
          "cachedResultName": "FAQ DATA"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "2d053b6e-c700-460a-8b6a-a61367394f9a",
      "name": "Code in JavaScript",
      "type": "n8n-nodes-base.code",
      "position": [
        1808,
        -768
      ],
      "parameters": {
        "jsCode": "return items.map(item => ({\n  json: {\n    content: `Q: ${item.json['Question']} A: ${item.json['Answer']}`\n  }\n}));"
      },
      "typeVersion": 2
    },
    {
      "id": "48c4b831-b414-45fd-8a91-d86c8ffd7945",
      "name": "Default Data Loader",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "position": [
        2352,
        -592
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "bb7e1c91-86d3-4c21-97ac-616e18230372",
      "name": "Supabase Vector Store1",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "position": [
        2176,
        -768
      ],
      "parameters": {
        "mode": "insert",
        "options": {},
        "tableName": {
          "__rl": true,
          "mode": "list",
          "value": "FAQs Data Table",
          "cachedResultName": "FAQs Data Table"
        }
      },
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "acc78577-9a02-4533-861f-4140fea35d23",
      "name": "Embeddings Google Gemini1",
      "type": "@n8n/n8n-nodes-langchain.embeddingsGoogleGemini",
      "position": [
        2144,
        -592
      ],
      "parameters": {
        "modelName": "models/gemini-embedding-2"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "9039ef5f-d7a6-4875-b032-b051b7ebf5f4",
  "nodeGroups": [],
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "main": [
        [
          {
            "node": "Respond to Webhook1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "Supabase Vector Store1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Default Data Loader": {
      "ai_document": [
        [
          {
            "node": "Supabase Vector Store1",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s) in sheet": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Supabase Vector Store": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings Google Gemini": {
      "ai_embedding": [
        [
          {
            "node": "Supabase Vector Store",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings Google Gemini1": {
      "ai_embedding": [
        [
          {
            "node": "Supabase Vector Store1",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Get row(s) in sheet",
            "type": "main",
            "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 ingests FAQs from Google Sheets into a Supabase vector table using Google Gemini embeddings, then serves a webhook-based support chatbot that answers only from that FAQ knowledge base and escalates unanswered questions to a human via UltraMsg WhatsApp. Runs…

Source: https://n8n.io/workflows/16974/ — 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

Rag Workflow. Uses googleDrive, vectorStorePinecone, embeddingsGoogleGemini, documentDefaultDataLoader. Webhook trigger; 17 nodes.

Google Drive, Pinecone Vector Store, Google Gemini Embeddings +8
AI & RAG

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

Postgres, Crypto, Redis +13
AI & RAG

⚡AI-Powered YouTube Playlist & Video Summarization and Analysis v2. Uses lmChatGoogleGemini, agent, splitOut, chainLlm. Chat trigger; 72 nodes.

Google Gemini Chat, Agent, Chain Llm +11
AI & RAG

This n8n workflow transforms entire YouTube playlists or single videos into interactive knowledge bases you can chat with. Ask questions and get summaries without needing to watch hours of content. 🔗

Google Gemini Chat, Agent, Chain Llm +11
AI & RAG

AI-Powered YouTube Playlist & Video Summarization and Analysis v2. Uses lmChatGoogleGemini, agent, chainLlm, vectorStoreQdrant. Chat trigger; 72 nodes.

Google Gemini Chat, Agent, Chain Llm +11