N
n8n Store
Workflow Market
WhatsApp Support Bot with Google Drive RAG, GPT-4.1-mini and Cohere Reranking

WhatsApp Support Bot with Google Drive RAG, GPT-4.1-mini and Cohere Reranking

by basil0 views

Description

Categories

⚙️ Automation

Nodes Used

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
PriceKostenlos
Views0
Last Updated11/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
          }
        ]
      ]
    }
  }
}

相关工作流