
WhatsApp Support Bot with Google Drive RAG, GPT-4.1-mini and Cohere Reranking
描述
分类
⚙️ Automation
使用的节点
n8n-nodes-base.setn8n-nodes-base.setn8n-nodes-base.mergen8n-nodes-base.switchn8n-nodes-base.whatsAppn8n-nodes-base.stickyNoten8n-nodes-base.stickyNoten8n-nodes-base.stickyNoten8n-nodes-base.stickyNoten8n-nodes-base.googleDrive
价格免费
浏览量0
最后更新11/28/2025
workflow.json
{
"meta": {
"instanceId": "4554bb68a996ee908e0483a438b45e0b09c0f719ece2f844818367ebd1e83f3d",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "8b12986e-ee9a-4320-a8c1-408611d5206e",
"name": "Supabase Vector Store",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"position": [
608,
0
],
"parameters": {
"mode": "insert",
"options": {
"queryName": "match_documents"
},
"tableName": {
"__rl": true,
"mode": "list",
"value": "documents",
"cachedResultName": "documents"
}
},
"credentials": {
"supabaseApi": {
"id": "7XyHzj12T2jBDfJt",
"name": "Basil supa"
}
},
"typeVersion": 1.3
},
{
"id": "fc078081-e9fa-47ce-8ddb-aa1ece9c8971",
"name": "Google Drive Trigger",
"type": "n8n-nodes-base.googleDriveTrigger",
"position": [
0,
0
],
"parameters": {
"event": "fileUpdated",
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyWeek",
"weekday": "0"
}
]
},
"triggerOn": "specificFolder",
"folderToWatch": {
"__rl": true,
"mode": "list",
"value": "1JCjixUoufxZRiFatfq-Nihr_vYRVoo2r",
"cachedResultUrl": "https://drive.google.com/drive/folders/1JCjixUoufxZRiFatfq-Nihr_vYRVoo2r",
"cachedResultName": "Holistic care"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "kqw2ogr63uU80dBU",
"name": "Basil drive"
}
},
"typeVersion": 1
},
{
"id": "25499c2f-015c-4ce2-814f-e5aa74b71882",
"name": "Edit Fields",
"type": "n8n-nodes-base.set",
"position": [
208,
0
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "c33387a9-a6ed-485a-8ed9-c3fdb646de3a",
"name": "id",
"type": "string",
"value": "={{ $json.id }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "26d8fbde-cbbb-4a9d-b3e8-aaa3c6707faa",
"name": "Download file",
"type": "n8n-nodes-base.googleDrive",
"position": [
416,
0
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"options": {
"googleFileConversion": {
"conversion": {
"docsToFormat": "text/plain"
}
}
},
"operation": "download"
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "kqw2ogr63uU80dBU",
"name": "Basil drive"
}
},
"typeVersion": 3
},
{
"id": "0a652935-f8e0-4c2b-94a1-a30448337aae",
"name": "Embeddings OpenAI",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"position": [
560,
176
],
"parameters": {
"options": {}
},
"credentials": {
"openAiApi": {
"id": "LLSGsbD06g4Y8PTw",
"name": "carnival"
}
},
"typeVersion": 1.2
},
{
"id": "1082a42a-6116-441b-8a55-4cacaf400e85",
"name": "Default Data Loader",
"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
"position": [
704,
144
],
"parameters": {
"options": {},
"dataType": "binary",
"textSplittingMode": "custom"
},
"typeVersion": 1.1
},
{
"id": "e92c1b20-a752-44f6-b590-0a5a24898576",
"name": "Character Text Splitter",
"type": "@n8n/n8n-nodes-langchain.textSplitterCharacterTextSplitter",
"position": [
832,
272
],
"parameters": {
"chunkSize": 2000,
"separator": ".",
"chunkOverlap": 300
},
"typeVersion": 1
},
{
"id": "00a4a495-5a62-4c31-814d-66406e3d95e9",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-112,
-64
],
"parameters": {
"color": 4,
"width": 1200,
"height": 464,
"content": "## Add documents to vector store\n"
},
"typeVersion": 1
},
{
"id": "fc14c2fb-e1c6-4e49-86eb-e54a96ac8a33",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
656,
-400
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini",
"cachedResultName": "gpt-4.1-mini"
},
"options": {
"temperature": 0.3
}
},
"credentials": {
"openAiApi": {
"id": "LLSGsbD06g4Y8PTw",
"name": "carnival"
}
},
"typeVersion": 1.2
},
{
"id": "eb8661ab-23d3-42a1-a63f-f9034195f8c0",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"onError": "continueRegularOutput",
"position": [
688,
-592
],
"parameters": {
"text": "={{ $json['text '] }}",
"options": {
"systemMessage": "=SYSTEM ROLE\nYou are intelligent and the best customer support agent for **HolistiCare (DHA, Lahore)**.\nTone: concise, friendly, courteous, professional. No emojis. Spartan wording.Be sympathetic and empathetic with the customer. \n\nCONTEXT \n\nHolistiCare is a multi-specialty clinic in DHA Phase 3, Lahore, providing care across: Dermatology/Aesthetics, Dentistry, Physiotherapy (incl. Hijama), Psychology & Psychiatry, Nutrition/Weight Loss, Pediatrics, Orthopedics, Gastroenterology, Urology, Neurology, Eye/Optometry, Internal Medicine/Diabetology/Endocrinology/Pulmonology, Gynecology, and Lab Testing.\n- The customer are frustrated and want good treatment always treat them in a way they feel appriciated \n- only converse with the user and provide them with information in a friendly manner \n- Ask the problems in a polite way and address them with a solution \n\n\ntool: 'Knowledge_base'\ndescription: use this tool to address user symtopms and their queries regarding the clinic and their symptoms. make sure the output is not more than a single paragraph \n\nBehaviour\n- Always try to sound like a human have two way communication with the user\n- Do not bombard them information guide them towards their needs and then provide them with a solution \n- do not draft an appointment message only address the customer query in a loving manner \n- Do not push the user to make an appointment \n- Only make an appointment when asked for \n- do not mention booking appointment if not asked \n\n\nGUARDRAILS\n- keep the replies under 100 words always \n- Keep replies short and non-repetitive.\n- Do **not** quote prices unless explicitly provided by the clinic in the 'Knowlege_base' tool\n- Do **not** provide medical advice; recommend a consult when needed.If not in the 'Knowledge_base'\n- If user insists on an unavailable service/doctor → suggest nearest department or route to front desk.\n- Prefer WhatsApp/phone handoff upon any ambiguity the agent cannot resolve quickly.\n\n\n"
},
"promptType": "define"
},
"typeVersion": 2
},
{
"id": "741188c9-3dfc-47e4-942b-604a8d248fda",
"name": "Switch",
"type": "n8n-nodes-base.switch",
"position": [
-16,
-592
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "c0d70293-1022-4319-8103-fff749a376de",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.messages[0].type }}",
"rightValue": "text"
}
]
}
},
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "257bc935-a8ea-4a41-83c5-a1c1fecb5198",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.messages[0].type }}",
"rightValue": "audio"
}
]
}
}
]
},
"options": {}
},
"typeVersion": 3.2
},
{
"id": "4d5613df-dbba-480a-9698-2cd7b83fd86a",
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"position": [
-144,
-432
],
"parameters": {
"url": "=https://graph.facebook.com/v21.0/{{ $('WhatsApp Trigger').item.json.messages[0].audio.id }}\n",
"options": {
"response": {
"response": {}
}
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "access_token",
"value": "Your acces token here "
}
]
}
},
"typeVersion": 4.2
},
{
"id": "33301513-6459-4b63-a795-611f7d2bba4e",
"name": "Translate a recording",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
240,
-432
],
"parameters": {
"options": {},
"resource": "audio",
"operation": "translate"
},
"credentials": {
"openAiApi": {
"id": "LLSGsbD06g4Y8PTw",
"name": "carnival"
}
},
"typeVersion": 1.8
},
{
"id": "ef1a43cf-6fac-4d86-8fe5-a025a478b825",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
240,
-592
],
"parameters": {},
"typeVersion": 3.2
},
{
"id": "2c97521c-21f5-4ba0-bf97-e16086f3252e",
"name": "Embeddings OpenAI1",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"position": [
912,
-256
],
"parameters": {
"options": {}
},
"credentials": {
"openAiApi": {
"id": "LLSGsbD06g4Y8PTw",
"name": "carnival"
}
},
"typeVersion": 1.2
},
{
"id": "4cc88c06-dd23-483b-95f6-097690e33a38",
"name": "Reranker Cohere",
"type": "@n8n/n8n-nodes-langchain.rerankerCohere",
"position": [
1072,
-256
],
"parameters": {},
"credentials": {
"cohereApi": {
"id": "wBVFsrsW1BO4F35G",
"name": "CohereApi account"
}
},
"typeVersion": 1
},
{
"id": "6842e6d5-691b-4588-b33d-71c941c0ab54",
"name": "Send message",
"type": "n8n-nodes-base.whatsApp",
"position": [
1152,
-592
],
"webhookId": "9e097e1c-7c81-4286-bb05-df6b1e05d219",
"parameters": {
"textBody": "={{ $json.output }}",
"operation": "send",
"phoneNumberId": "668904212970806",
"additionalFields": {},
"recipientPhoneNumber": "={{ $('WhatsApp Trigger').item.json.messages[0].from }}"
},
"credentials": {
"whatsAppApi": {
"id": "lIJTty4i120llCjY",
"name": "Basil WA"
}
},
"typeVersion": 1
},
{
"id": "102f55f1-a7e9-425d-b4a7-ec7a78e57344",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-464,
-768
],
"parameters": {
"color": 5,
"width": 1856,
"height": 656,
"content": "## Ai agent "
},
"typeVersion": 1
},
{
"id": "900a3b8d-9095-4dd4-a3b2-d2104168e174",
"name": "WhatsApp Trigger",
"type": "n8n-nodes-base.whatsAppTrigger",
"position": [
-272,
-592
],
"webhookId": "3e4086bf-8e46-4489-9844-657dc6f96f73",
"parameters": {
"options": {},
"updates": [
"messages"
]
},
"credentials": {
"whatsAppTriggerApi": {
"id": "AyCa0qekMUCDvlXX",
"name": "basil WA"
}
},
"typeVersion": 1
},
{
"id": "cb6d7ba3-b42c-4644-ab1f-db72269491f5",
"name": "Kknowledge_base",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"position": [
880,
-400
],
"parameters": {
"mode": "retrieve-as-tool",
"topK": 10,
"options": {
"queryName": "match_documents"
},
"tableName": {
"__rl": true,
"mode": "list",
"value": "documents",
"cachedResultName": "documents"
},
"useReranker": true,
"toolDescription": "Use this tool to address customer queries regarding their symptoms and their queries regarding the clinic. "
},
"credentials": {
"supabaseApi": {
"id": "7XyHzj12T2jBDfJt",
"name": "Basil supa"
}
},
"typeVersion": 1.3
},
{
"id": "d0f0ece2-9bc5-49aa-aaf2-5132826b8f48",
"name": "Simple Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
592,
-240
],
"parameters": {
"sessionKey": "={{ $json.Phone }}",
"sessionIdType": "customKey"
},
"typeVersion": 1.3
},
{
"id": "6c1938a5-2674-4061-b5df-f48d34778273",
"name": "HTTP Request1",
"type": "n8n-nodes-base.httpRequest",
"position": [
64,
-432
],
"parameters": {
"url": "={{ $json.url }}",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer your access token here "
}
]
}
},
"typeVersion": 4.2
},
{
"id": "030178e3-1fe6-4ab9-bc3f-e83cbbbb4b8f",
"name": "Edit Fields1",
"type": "n8n-nodes-base.set",
"position": [
416,
-592
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "29681984-eb3c-4c26-8de4-41fe8171abe2",
"name": "Phone",
"type": "string",
"value": "={{ $('WhatsApp Trigger').item.json.messages[0].from }}"
},
{
"id": "8d05b1e7-6035-42b2-8919-677ecd82fcbd",
"name": "text ",
"type": "string",
"value": "={{ $json.text }}{{ $json.messages[0].text.body }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "de45d6c0-1b61-4b0f-90de-d259838b60d4",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1264,
-3280
],
"parameters": {
"width": 768,
"height": 3136,
"content": "# WhatsApp → AI Agent (OpenAI + Supabase KB) → Reply\n\nThis workflow turns incoming **WhatsApp** messages (text or audio) into **short, friendly clinic replies** using an AI Agent with memory and a Supabase-powered knowledge base. It enforces guardrails (≤100 words, no pricing unless in KB, no hard sells).\n\n---\n\n## 0) What you need ready\n\n* **n8n**: running with a public URL.\n* **Meta WhatsApp Business**:\n\n * A phone number connected to the app.\n * **Webhook verified** to your n8n WhatsApp Trigger node (Production URL).\n* **Credentials** configured in n8n:\n\n * **WhatsApp Trigger** (App ID, Secret, Verify Token).\n * **WhatsApp Send** (Phone Number ID + Access Token) for `Send message` node.\n * **OpenAI** (for Chat + Transcription) → used by `OpenAI Chat Model` and `Translate a recording`.\n * **Supabase** (URL + Key) → used by `Kknowledge_base` (vector store).\n * **Cohere** (optional but wired) for reranking.\n* **Supabase Table**: `documents` populated with clinic FAQs/policies/services (chunked & embedded). Keep it accurate—**agent won’t invent prices or services**.\n\n---\n\n## 1) How the flow runs (high level)\n\n1. **Inbound** → `WhatsApp Trigger` receives a user message.\n2. **Branch** → `Switch` checks `messages[0].type`:\n\n * `text` → goes straight to `Merge` → `Edit Fields1`.\n * `audio` → fetch media (`HTTP Request` → `HTTP Request1`) → `Translate a recording` (speech→text) → into `Merge`.\n3. **Normalize fields** → `Edit Fields1` sets:\n\n * `Phone` = sender phone\n * `text` = unified message text (either the typed text or transcription)\n4. **Agent runtime**:\n\n * `OpenAI Chat Model` (gpt-4.1-mini, temp 0.3) provides reasoning/response engine.\n * **Memory** → `Simple Memory` uses `Phone` to keep short conversational context per user.\n * **Knowledge Tool** → `Kknowledge_base` (Supabase vector search, topK=10, with Cohere reranker) is available to the agent **as a tool** for grounding answers.\n * **Agent** → `AI Agent` applies the clinic-specific system prompt and guardrails to produce **≤100 words** replies.\n5. **Deliver** → `Send message` replies on WhatsApp with `{{$json.output}}`.\n\n---\n\n## 2) One-time setup checks\n\n* **WhatsApp Trigger**: subscribe to `messages` updates; set Verify Token; use the **Production** webhook URL in Meta.\n* **Switch** node**: rules check exactly `text` or `audio` on `messages[0].type`.\n* **Audio path**:\n\n * `HTTP Request` GET media metadata from Graph API using `messages[0].audio.id` + `access_token` query.\n * `HTTP Request1` downloads the file using returned `url` and `Authorization: Bearer <PAGE_ACCESS_TOKEN>` header.\n * `Translate a recording` uses your **OpenAI** credential (Whisper/translate) to output text.\n* **Edit Fields1**: confirm the expressions:\n\n ```\n Phone = {{$('WhatsApp Trigger').item.json.messages[0].from}}\n text = {{$json.text}}{{$json.messages[0].text.body}}\n ```\n\n This concatenates either transcription (`$json.text`) or typed text.\n* **Agent**:\n\n * `OpenAI Chat Model`: model `gpt-4.1-mini`, temperature `0.3`.\n * `AI Agent` system message includes tone/guardrails for **HolistiCare (DHA, Lahore)**.\n * **Connect** Memory (`Simple Memory` with `sessionKey = {{$json.Phone}}`) and Tool (`Kknowledge_base`) to the Agent.\n* **Supabase KB** (`Kknowledge_base`): mode `retrieve-as-tool`, table `documents`, `topK=10`, `useReranker=true`. Ensure embeddings in your table align with the model you indexed with.\n* **Reranker Cohere** (optional): wired into the KB for better results; needs valid key.\n* **Send message**: Set `phoneNumberId` and credential to your WhatsApp Business account; recipient is `{{$('WhatsApp Trigger').item.json.messages[0].from}}`.\n\n---\n\n## 3) Guardrails the agent follows (baked in)\n\n* ≤100 words, concise, human, empathetic, no emojis.\n* No prices unless present in **Knowledge_base**.\n* No medical advice; suggest consult when needed.\n* Don’t push bookings; only book if asked.\n* Prefer quick handoff to WhatsApp/phone if unclear.\n\n---\n\n## 4) How to test end‑to‑end (fast)\n\n1. In Meta, send a **text** WhatsApp message to your business number.\n2. Check n8n exec: should follow **text path** → Agent → reply ≤100 words.\n3. Send an **audio** note: verify **audio path** → download → transcribe → Agent → reply.\n4. Ask for **price** not in KB: agent should **avoid quoting** and suggest contacting front desk.\n5. Ask for a **service** not offered: agent should route to nearest department or front desk.\n\n---\n\n## 5) Customization quick wins\n\n* **Tone**: adjust in the Agent system message (keep length & guardrails).\n* **Word limit**: change the guardrail in the system message and test.\n* **Memory window**: configure `Simple Memory` buffer length for more/less context.\n* **Stronger grounding**: lower `topK` or tighten KB content; consider domain tags in your Supabase documents.\n* **Switch language**: rely on OpenAI translate path for audio; for text, add language detection pre‑step if needed.\n\n---\n\n## 6) Troubleshooting\n\n* **No trigger**: ensure Meta webhook points to the **Production** URL of `WhatsApp Trigger` and events are subscribed.\n* **Audio fails to download**: check Graph `access_token` and that `HTTP Request1` sends `Authorization: Bearer <PAGE_ACCESS_TOKEN>`.\n* **Transcription empty**: confirm `Translate a recording` credential and response mapping into `Merge`.\n* **Agent ignores KB**: verify `Kknowledge_base` is connected as a **tool** to `AI Agent` and your Supabase table has data.\n* **Long replies**: tighten the system prompt; reduce temperature; add “strictly under 100 words” at the end.\n* **No outgoing message**: check `Send message` phoneNumberId, token, and WhatsApp Business permissions.\n\n---\n\n## 7) Mental model\n\nWhatsApp in → (text OR audio→text) → normalize → Agent (OpenAI) + Memory + KB tool → short, safe reply → WhatsApp out. Keep the KB clean and the agent stays honest. ✅\n"
},
"typeVersion": 1
},
{
"id": "3d285ec3-4284-4fa9-8dd2-32d756bf5bab",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1392,
-624
],
"parameters": {
"width": 1152,
"height": 2224,
"content": "# : Auto‑ingest Google Drive docs into a Supabase Vector Store (for your KB)\n\nThis workflow watches a Google Drive **folder** and, when a file is updated, it **downloads → chunks → embeds → inserts** the text into a Supabase **`documents`** table for retrieval‑augmented agents.\n\n---\n\n## 0) What you need ready\n\n* **n8n** publicly reachable.\n* **Google Drive** OAuth credential with access to the watched folder.\n* **Supabase** project with a `documents` table that your vector store node is configured to use.\n* **OpenAI** API key (for embeddings).\n\n---\n\n## 1) How it runs (bird’s‑eye)\n\n1. **Trigger** → `Google Drive Trigger` polls **weekly (Sunday)** for `fileUpdated` events in the specified folder.\n2. **Capture file id** → `Edit Fields` sets `id = {{$json.id}}` for clean passing.\n3. **Download** → `Download file` pulls the file by id. If it’s a Google Doc/Sheet/Slide, it **converts Docs to `text/plain`** per options.\n4. **(Optional) Chunking** → `Character Text Splitter` defines chunk strategy (size **2000**, overlap **300**) and feeds `Default Data Loader`.\n5. **Embed + Insert** →\n\n * `Embeddings OpenAI` provides the embedding model to the vector pipeline.\n * `Default Data Loader` hands doc parts to the **`Supabase Vector Store`** (mode **insert**) which writes rows into **`documents`**.\n\n> Result: your updated Drive file is indexed for semantic search in Supabase.\n\n---\n\n## 2) One‑time setup checks\n\n* **Google Drive Trigger**\n\n * `Trigger on`: **Specific folder** → confirm the folder id is correct.\n * `Event`: **fileUpdated** (fires when a file changes in that folder or its children).\n * `Poll schedule`: weekly; adjust if you want faster ingestion.\n* **Download file**\n\n * `operation`: download by file id.\n * **Google Docs conversion**: set to `docsToFormat: text/plain` (already set). Non‑Docs (PDF, .txt, .md) are downloaded as is.\n* **Character Text Splitter**\n\n * `separator`: `.`\n * `chunkSize`: **2000** | `chunkOverlap`: **300** (safe defaults; tune for your model).\n* **Embeddings OpenAI**\n\n * Make sure the credential points to the right key; pick a modern embedding model (e.g., `text-embedding-3-small` or your preferred).\n* **Supabase Vector Store**\n\n * `mode`: **insert**\n * `tableName`: **documents**\n * Has Supabase URL + service key in credentials.\n * `options.queryName`: **match_documents** (the RPC you’ll use at query time).\n\n---\n\n## 3) Supported files & tips\n\n* **Google Docs** → auto‑converted to plain text.\n* **Plain text/Markdown** → ingests directly.\n* **PDF/Images** → not OCR’d by default. Add an OCR/parse step if needed before chunking.\n* Keep content clean: remove boilerplate headers/footers in source to avoid noisy chunks.\n\n---\n\n## 4) Customization quick wins\n\n* **Faster indexing**: change the trigger to `everyHour` or `every15Minutes`.\n* **Selective ingest**: filter by mimeType or filename in the trigger, or add a `Switch` node.\n* **Metadata**: add a `Set` node to attach `source`, `path`, `version`, `updatedAt` and map these to Supabase columns.\n* **De‑duplication**: before insert, call a Supabase function to upsert by `(source, doc_id, chunk_id)`.\n* **Chunking**: for Q&A docs, smaller chunks (e.g., 800/120 overlap) may give tighter hits.\n* **Embeddings model**: stay consistent between **index** and **query** pipelines to avoid vector mismatch.\n\n---\n\n## 5) Troubleshooting (fast)\n\n* **No events**: the file wasn’t actually “updated,” or polling window too wide; shorten schedule or manually bump file versions.\n* **Blank text**: conversion failed or binary file not supported; add a converter/OCR step.\n* **Insert errors**: check Supabase row size/column mapping; ensure your table schema matches what the node sends.\n* **Bad retrieval**: adjust chunking, ensure the same embedding model is used at query time, and verify you’re calling `match_documents` with sensible `topK`.\n\n---\n\n## 6) Mental model\n\nDrive update → Download (+convert) → Split → Embed → Insert into Supabase. Once this is solid, your chatbot/agent can query `match_documents` and stay fresh without manual uploads. ✅\n"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"Merge": {
"main": [
[
{
"node": "Edit Fields1",
"type": "main",
"index": 0
}
]
]
},
"Switch": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
}
],
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[
{
"node": "Send message",
"type": "main",
"index": 0
}
]
]
},
"Edit Fields": {
"main": [
[
{
"node": "Download file",
"type": "main",
"index": 0
}
]
]
},
"Edit Fields1": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[
{
"node": "HTTP Request1",
"type": "main",
"index": 0
}
]
]
},
"Download file": {
"main": [
[
{
"node": "Supabase Vector Store",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request1": {
"main": [
[
{
"node": "Translate a recording",
"type": "main",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "AI Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"Kknowledge_base": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Reranker Cohere": {
"ai_reranker": [
[
{
"node": "Kknowledge_base",
"type": "ai_reranker",
"index": 0
}
]
]
},
"WhatsApp Trigger": {
"main": [
[
{
"node": "Switch",
"type": "main",
"index": 0
}
]
]
},
"Embeddings OpenAI": {
"ai_embedding": [
[
{
"node": "Supabase Vector Store",
"type": "ai_embedding",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Embeddings OpenAI1": {
"ai_embedding": [
[
{
"node": "Kknowledge_base",
"type": "ai_embedding",
"index": 0
}
]
]
},
"Default Data Loader": {
"ai_document": [
[
{
"node": "Supabase Vector Store",
"type": "ai_document",
"index": 0
}
]
]
},
"Google Drive Trigger": {
"main": [
[
{
"node": "Edit Fields",
"type": "main",
"index": 0
}
]
]
},
"Translate a recording": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"Character Text Splitter": {
"ai_textSplitter": [
[
{
"node": "Default Data Loader",
"type": "ai_textSplitter",
"index": 0
}
]
]
}
}
}