Crear un chatbot RAG que se actualiza solo (Google Drive, Gemini y Supabase)
Este es unContent Creation, Multimodal AIflujo de automatización del dominio deautomatización que contiene 45 nodos.Utiliza principalmente nodos como Set, Code, Merge, Switch, Postgres. Usar Google Drive, Gemini y Supabase para crear un chatbot RAG que se actualiza automáticamente
- •Información de conexión de la base de datos PostgreSQL
- •URL y Clave de API de Supabase
- •Credenciales de API de Google Drive
- •Clave de API de Google Gemini
Nodos utilizados (45)
Categoría
{
"meta": {
"instanceId": "3d5da29ecb74ce7e2d987bbf535eab46b9724880017cbe267c2cb8d22899447c"
},
"nodes": [
{
"id": "fbeb9ada-34d8-440a-b843-ff139e8e979c",
"name": "Reranker Cohere",
"type": "@n8n/n8n-nodes-langchain.rerankerCohere",
"position": [
1456,
368
],
"parameters": {},
"typeVersion": 1
},
{
"id": "11e0434a-904c-48ca-b119-978dd68996db",
"name": "Supabase Vector Store",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"position": [
1216,
224
],
"parameters": {
"mode": "retrieve-as-tool",
"topK": 20,
"options": {},
"tableName": {
"__rl": true,
"mode": "list",
"value": "documents",
"cachedResultName": "documents"
},
"useReranker": true,
"toolDescription": "Use this tool to search the database"
},
"typeVersion": 1.3
},
{
"id": "68112d8c-e204-451f-b5b3-a10f69738506",
"name": "Nota adhesiva1",
"type": "n8n-nodes-base.stickyNote",
"position": [
272,
80
],
"parameters": {
"color": 4,
"width": 1372,
"height": 396,
"content": "## RAG Agent (Step 2)\n"
},
"typeVersion": 1
},
{
"id": "b011d310-348d-4726-b2b3-785ac9b081e0",
"name": "Nota adhesiva2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1072,
80
],
"parameters": {
"color": 6,
"width": 572,
"height": 396,
"content": "## Vector Store\n"
},
"typeVersion": 1
},
{
"id": "9f12dcc8-423c-42f6-a0de-522b5897c620",
"name": "Agente RAG",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
528,
176
],
"parameters": {
"options": {
"systemMessage": "=You are a helpful and friendly AI assistant for our company. Your primary goal is to assist users by answering their questions based on a knowledge base, but you should also be ableto handle simple conversation. You have access to the Supabase tool. Always call on this tool to answer questions if the user is asking for information.\n\nFirst, analyze the user's message to determine their intent.\n\n**Behavior 1: If the user's message is a simple greeting, thank you, or other conversational filler (e.g., \"hello\", \"thanks!\", \"how are you?\").**\n- You should respond politely and conversationally.\n- Do NOT use the provided [CONTEXT].\n- Do NOT mention the documents or your knowledge base.\n\n**Behavior 2: If the user's message is a question asking for information, instructions, or specific details.**\n- You must switch to your role as a specialized knowledge base assistant and follow these strict rules:\n1. **Analyze the Context:** Carefully read the provided [CONTEXT] section. This is your only source of truth.\n2. **Answer the Question:** Formulate a direct and concise answer to the [QUESTION] using only the information from the [CONTEXT].\n3. **Strictly Adhere to Context:** Do NOT use any external knowledge, make assumptions, or fill in gaps.\n4. **Handling Insufficient Information:** If the answer cannot be found within the [CONTEXT], you must respond with the exact phrase: \"I could not find an answer in the provided documents.\" Do not apologize or offer to search elsewhere.\n5. **Cite Your Sources:** After your answer, add a \"Sources:\" section. List the title of each source document you used. Use the metadata provided in the context to format each source as a clickable Markdown link.\n\n**[CONTEXT]**\n{context_from_retriever}\n**[/CONTEXT]**\n\n**[QUESTION]**\n{user_question}\n**[/QUESTION]**"
}
},
"typeVersion": 2
},
{
"id": "61d43f61-e071-4d2d-a714-eac42d4acbd2",
"name": "Archivo creado",
"type": "n8n-nodes-base.googleDriveTrigger",
"disabled": true,
"position": [
128,
560
],
"parameters": {
"event": "fileCreated",
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"triggerOn": "specificFolder",
"folderToWatch": {
"__rl": true,
"mode": "list",
"value": "Your Folder ID",
"cachedResultUrl": "https://drive.google.com/drive/folders/Your Folder ID",
"cachedResultName": "1) RAG Demo"
}
},
"typeVersion": 1
},
{
"id": "52fa8440-7c5a-4a2e-bd6b-17cbb22c7d6a",
"name": "Archivo actualizado",
"type": "n8n-nodes-base.googleDriveTrigger",
"disabled": true,
"position": [
128,
1024
],
"parameters": {
"event": "fileUpdated",
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"triggerOn": "specificFolder",
"folderToWatch": {
"__rl": true,
"mode": "list",
"value": "Your Folder ID",
"cachedResultUrl": "https://drive.google.com/drive/folders/Your Folder ID",
"cachedResultName": "1) RAG Demo"
}
},
"typeVersion": 1
},
{
"id": "06cd8ce9-4d3c-412e-9688-a181f6aadc38",
"name": "Extraer texto del documento",
"type": "n8n-nodes-base.extractFromFile",
"position": [
1296,
944
],
"parameters": {
"options": {},
"operation": "text"
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "8a280ac3-a27f-469c-9885-3482051e2268",
"name": "Eliminar filas de documento antiguo",
"type": "n8n-nodes-base.supabase",
"position": [
576,
880
],
"parameters": {
"tableId": "documents",
"operation": "delete",
"filterType": "string",
"filterString": "=metadata->>file_id=like.*{{ $json.file_id }}*"
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "2fca17ab-ec90-4877-936b-45a651a567d1",
"name": "Establecer ID de archivo",
"type": "n8n-nodes-base.set",
"position": [
672,
624
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "10646eae-ae46-4327-a4dc-9987c2d76173",
"name": "file_id",
"type": "string",
"value": "={{ $json.id }}"
},
{
"id": "f4536df5-d0b1-4392-bf17-b8137fb31a44",
"name": "file_type",
"type": "string",
"value": "={{ $json.mimeType }}"
},
{
"id": "77d782de-169d-4a46-8a8e-a3831c04d90f",
"name": "file_title",
"type": "string",
"value": "={{ $json.name }}"
},
{
"id": "9bde4d7f-e4f3-4ebd-9338-dce1350f9eab",
"name": "file_url",
"type": "string",
"value": "={{ $json.webViewLink }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "a3a6aca4-5932-4b13-9466-de1fadee3392",
"name": "Extraer texto de PDF",
"type": "n8n-nodes-base.extractFromFile",
"position": [
1296,
784
],
"parameters": {
"options": {},
"operation": "pdf"
},
"typeVersion": 1
},
{
"id": "86094f10-2a02-431f-b0ec-d7cd5dffb98b",
"name": "Separador de texto por caracteres",
"type": "@n8n/n8n-nodes-langchain.textSplitterCharacterTextSplitter",
"position": [
1552,
1280
],
"parameters": {
"chunkSize": 750,
"chunkOverlap": 200
},
"typeVersion": 1
},
{
"id": "35366f16-4f00-4544-9f7e-aac1a5571e7f",
"name": "Switch",
"type": "n8n-nodes-base.switch",
"position": [
1072,
880
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $('Set File ID').item.json.file_type }}",
"rightValue": "application/pdf"
}
]
}
},
{
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "b69f5605-0179-4b02-9a32-e34bb085f82d",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $('Set File ID').item.json.file_type }}",
"rightValue": "application/vnd.google-apps.document"
}
]
}
}
]
},
"options": {
"fallbackOutput": 3
}
},
"typeVersion": 3
},
{
"id": "0edf1ac5-2469-451e-81cb-6b6267427b9f",
"name": "Insertar en Supabase Vectorstore",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"onError": "continueRegularOutput",
"position": [
1552,
928
],
"parameters": {
"mode": "insert",
"options": {
"queryName": "match_documents"
},
"tableName": {
"__rl": true,
"mode": "list",
"value": "documents",
"cachedResultName": "documents"
}
},
"typeVersion": 1
},
{
"id": "f5c2d73e-fdb7-4e2c-8fae-74e2dd483b99",
"name": "Iterar sobre elementos",
"type": "n8n-nodes-base.splitInBatches",
"position": [
448,
608
],
"parameters": {
"options": {
"reset": false
}
},
"typeVersion": 3
},
{
"id": "80ca7123-c4d6-4184-83db-3a9cd7eea5be",
"name": "Insertar metadatos del documento",
"type": "n8n-nodes-base.postgres",
"position": [
752,
880
],
"parameters": {
"table": {
"__rl": true,
"mode": "list",
"value": "document_metadata",
"cachedResultName": "document_metadata"
},
"schema": {
"__rl": true,
"mode": "list",
"value": "public"
},
"columns": {
"value": {
"id": "={{ $('Set File ID').item.json.file_id }}",
"url": "={{ $('Set File ID').item.json.file_url }}",
"title": "={{ $('Set File ID').item.json.file_title }}"
},
"schema": [
{
"id": "id",
"type": "string",
"display": true,
"removed": false,
"required": true,
"displayName": "id",
"defaultMatch": true,
"canBeUsedToMatch": true
},
{
"id": "title",
"type": "string",
"display": true,
"required": false,
"displayName": "title",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "url",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "url",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "created_at",
"type": "dateTime",
"display": true,
"removed": true,
"required": false,
"displayName": "created_at",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "schema",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "schema",
"defaultMatch": false,
"canBeUsedToMatch": false
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"id"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "upsert"
},
"executeOnce": true,
"typeVersion": 2.5
},
{
"id": "75602bb9-30a7-409c-8aaa-38f9923cf08d",
"name": "Default Data Loader1",
"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
"position": [
1632,
1136
],
"parameters": {
"options": {
"metadata": {
"metadataValues": [
{
"name": "=file_id",
"value": "={{ $('Set File ID').first().json.file_id }}"
},
{
"name": "file_title",
"value": "={{ $('Set File ID').first().json.file_title }}"
},
{
"name": "url",
"value": "={{ $('Set File ID').first().json.file_url }}"
}
]
}
},
"jsonData": "={{ $json.data || $json.text || $json.concatenated_data }}",
"jsonMode": "expressionData"
},
"typeVersion": 1
},
{
"id": "902bfe64-17c3-45aa-8434-cb4241aa150b",
"name": "Descargar archivo1",
"type": "n8n-nodes-base.googleDrive",
"position": [
928,
880
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Set File ID').item.json.file_id }}"
},
"options": {
"googleFileConversion": {
"conversion": {
"docsToFormat": "text/plain"
}
}
},
"operation": "download"
},
"executeOnce": true,
"retryOnFail": true,
"typeVersion": 3
},
{
"id": "87aecf50-86dc-48db-9eac-b34fd6a4938d",
"name": "Nota adhesiva",
"type": "n8n-nodes-base.stickyNote",
"position": [
-144,
480
],
"parameters": {
"color": 3,
"width": 2192,
"height": 976,
"content": "## RAG Ingestion System (Step 1)\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n"
},
"typeVersion": 1
},
{
"id": "e67da326-ff09-4f72-a146-19c342dc8b1f",
"name": "Obtener IDs de archivo",
"type": "n8n-nodes-base.googleDrive",
"position": [
816,
1568
],
"parameters": {
"filter": {},
"options": {
"fields": [
"id"
]
},
"resource": "fileFolder",
"returnAll": true,
"queryString": "'Your Folder ID' in parents and trashed=false",
"searchMethod": "query"
},
"typeVersion": 3
},
{
"id": "b5b91dde-0afb-493f-b336-ea84017d8171",
"name": "Combinar",
"type": "n8n-nodes-base.merge",
"position": [
1088,
1648
],
"parameters": {},
"typeVersion": 3
},
{
"id": "74a8e170-040a-42f4-b593-a2206527f655",
"name": "Supabase",
"type": "n8n-nodes-base.supabase",
"position": [
816,
1728
],
"parameters": {
"tableId": "documents",
"operation": "getAll",
"returnAll": true
},
"typeVersion": 1
},
{
"id": "a763d918-e045-461a-b081-2670f7d3f1af",
"name": "Código1",
"type": "n8n-nodes-base.code",
"position": [
1312,
1648
],
"parameters": {
"jsCode": "// Grab the raw data from all inputs\nconst inputData = $input.all().map(item => item.json);\n\n// Separate out the Google Drive items (no \"metadata\") vs. Supabase items (have \"metadata\")\nconst googleDriveItems = inputData.filter(item => item.id && !item.metadata);\nconst supabaseItems = inputData.filter(item => item.metadata);\n\n// Extract just the file IDs from Google Drive\nconst googleDriveIds = googleDriveItems.map(item => item.id);\n\n// Build a Set for quick membership checks (recommended for large arrays)\nconst driveIdSet = new Set(googleDriveIds);\n\n// Filter Supabase rows to find those whose file_id is not in the Drive set\nconst orphanedSupabaseRows = supabaseItems.filter(item => {\n return !driveIdSet.has(item.metadata.file_id);\n});\n\n// Return each orphaned row as a separate n8n item\nreturn orphanedSupabaseRows.map(row => ({ json: row }));\n"
},
"typeVersion": 2
},
{
"id": "c5a5c9c8-07fe-4c09-87ac-c0dd0dbaf17e",
"name": "Activador programado",
"type": "n8n-nodes-base.scheduleTrigger",
"disabled": true,
"position": [
512,
1904
],
"parameters": {
"rule": {
"interval": [
{}
]
}
},
"typeVersion": 1.2
},
{
"id": "ec4c1998-6079-4a91-a8ba-b6fed99e93a7",
"name": "Al hacer clic en 'Probar flujo'",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-112,
784
],
"parameters": {},
"typeVersion": 1
},
{
"id": "29b49cd7-64ce-4752-a07b-3afebf19219b",
"name": "Eliminar filas",
"type": "n8n-nodes-base.supabase",
"position": [
1536,
1648
],
"parameters": {
"filters": {
"conditions": [
{
"keyName": "id",
"keyValue": "={{ $json.id }}",
"condition": "eq"
}
]
},
"tableId": "documents",
"matchType": "allFilters",
"operation": "delete"
},
"typeVersion": 1
},
{
"id": "3c1b0427-02df-481a-94b1-63a22ca243af",
"name": "Nota adhesiva5",
"type": "n8n-nodes-base.stickyNote",
"position": [
368,
1456
],
"parameters": {
"color": 6,
"width": 1440,
"height": 956,
"content": "## RAG: Clean up (Step 3)"
},
"typeVersion": 1
},
{
"id": "3ea2baf0-fac7-440b-bd6c-4f7f689844cc",
"name": "Obtener IDs de archivo2",
"type": "n8n-nodes-base.googleDrive",
"position": [
816,
1968
],
"parameters": {
"filter": {},
"options": {
"fields": [
"id"
]
},
"resource": "fileFolder",
"returnAll": true,
"queryString": "'Your Folder ID' in parents and trashed=false",
"searchMethod": "query"
},
"typeVersion": 3
},
{
"id": "8002bd2f-29da-40fe-b909-cdcc7d3f5fde",
"name": "Supabase2",
"type": "n8n-nodes-base.supabase",
"position": [
816,
2192
],
"parameters": {
"tableId": "document_metadata",
"operation": "getAll",
"returnAll": true
},
"typeVersion": 1
},
{
"id": "f11e2063-d42c-4d07-86d8-b916467b5b3a",
"name": "Combinar2",
"type": "n8n-nodes-base.merge",
"position": [
1104,
2048
],
"parameters": {},
"typeVersion": 3
},
{
"id": "4b4a4689-2767-49a9-8f8f-2a33d9cd7e84",
"name": "Código2",
"type": "n8n-nodes-base.code",
"position": [
1328,
2048
],
"parameters": {
"jsCode": "// Simple code to handle empty Google Drive\n\n// Determine if we have Google Drive data\nlet hasDriveData = false;\nlet driveFileIds = new Set();\n\n// Check the first item to see if it's a Google Drive file or a file list\nif (items[0] && items[0].json) {\n // Is it a files array?\n if (items[0].json.files && Array.isArray(items[0].json.files)) {\n hasDriveData = true;\n for (const file of items[0].json.files) {\n if (file && file.id) driveFileIds.add(file.id);\n }\n }\n // Is it a single file with no metadata-like properties?\n else if (items[0].json.id && !items[0].json.title && !items[0].json.created_at) {\n hasDriveData = true;\n driveFileIds.add(items[0].json.id);\n }\n}\n\nconsole.log(\"Has Drive data:\", hasDriveData);\nconsole.log(\"Drive file IDs:\", Array.from(driveFileIds));\n\n// Determine which items are metadata records\nlet metadataRecords = [];\n\n// If the first item looks like a metadata record (has title, url, created_at)\nif (!hasDriveData) {\n // All items are metadata records\n metadataRecords = items.map(item => item.json).filter(Boolean);\n console.log(\"All items are metadata records:\", metadataRecords.length);\n} else {\n // Only items after the first are metadata records\n metadataRecords = items.slice(1).map(item => item.json).filter(Boolean);\n console.log(\"Items after first are metadata records:\", metadataRecords.length);\n}\n\n// If there are no Drive files, mark all metadata records for deletion\nconst recordsToDelete = [];\n\nif (driveFileIds.size === 0) {\n console.log(\"No Drive files, marking ALL metadata records for deletion\");\n for (const record of metadataRecords) {\n if (record && record.id) {\n recordsToDelete.push({\n ...record,\n _shouldDelete: true\n });\n }\n }\n} else {\n // Otherwise, only mark records not in Drive\n console.log(\"Checking metadata records against Drive files\");\n for (const record of metadataRecords) {\n if (record && record.id && !driveFileIds.has(record.id)) {\n recordsToDelete.push({\n ...record,\n _shouldDelete: true\n });\n }\n }\n}\n\nconsole.log(\"Records to delete:\", recordsToDelete.length);\nreturn recordsToDelete;"
},
"typeVersion": 2
},
{
"id": "d12aeac5-f570-49c7-8276-5a53648026cb",
"name": "Eliminar filas2",
"type": "n8n-nodes-base.supabase",
"position": [
1568,
2048
],
"parameters": {
"filters": {
"conditions": [
{
"keyName": "id",
"keyValue": "={{ $json.id }}",
"condition": "eq"
}
]
},
"tableId": "document_metadata",
"matchType": "allFilters",
"operation": "delete"
},
"typeVersion": 1
},
{
"id": "5b4cd434-4799-4981-a585-21c69d8329d5",
"name": "Buscar archivos y carpetas",
"type": "n8n-nodes-base.googleDrive",
"position": [
128,
784
],
"parameters": {
"filter": {},
"options": {
"fields": [
"webViewLink",
"id",
"name",
"mimeType"
]
},
"resource": "fileFolder",
"returnAll": true,
"queryString": "='Your Folder ID' in parents and trashed=false",
"searchMethod": "query"
},
"typeVersion": 3
},
{
"id": "e2bbc2ba-cce7-4410-b5e9-60fc1bf7dacb",
"name": "Memoria de chat Postgres",
"type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
"position": [
592,
352
],
"parameters": {},
"typeVersion": 1.3
},
{
"id": "33dbd2eb-d1dc-426c-9939-45461780cffe",
"name": "Al recibir mensaje de chat",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
304,
176
],
"webhookId": "d105c3ad-3488-438c-b405-b856c90ce80e",
"parameters": {
"options": {}
},
"typeVersion": 1.1
},
{
"id": "554ad606-2bd7-49c9-a415-0c9f88ae4ac8",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
448,
352
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "0b83f6fc-e67c-4a00-a26d-80efdf87213b",
"name": "Embeddings Google Gemini",
"type": "@n8n/n8n-nodes-langchain.embeddingsGoogleGemini",
"position": [
1200,
368
],
"parameters": {},
"typeVersion": 1
},
{
"id": "052b2e8f-de1a-4bea-b67c-387c362f23f7",
"name": "Embeddings Google Gemini1",
"type": "@n8n/n8n-nodes-langchain.embeddingsGoogleGemini",
"position": [
1488,
1136
],
"parameters": {},
"typeVersion": 1
},
{
"id": "17f0d107-e2e4-4719-826d-33e647c96ed5",
"name": "Nota adhesiva3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-400,
-688
],
"parameters": {
"width": 560,
"height": 320,
"content": "=========================\n RAG Agent with G-Drive Sync\n=======================================\nFor any questions or support, please contact:\n anirudh.n.aeran@gmail.com\n\nExplore more tips here:\n - LinkedIn: https://www.linkedin.com/in/anirudh-narayan-a-/\n\nHappy learning! -- Anirudh Aeran\n\n\n======================================="
},
"typeVersion": 1
},
{
"id": "0a09459f-ceeb-44f9-93ee-c3bdbfa3a527",
"name": "Nota adhesiva6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-416,
752
],
"parameters": {
"width": 256,
"height": 208,
"content": "#### This Manual Trigger is Used \n#### for the Initial Ingestion of \n#### Documents to the Vectorbase\n\n**-->After the initial ingestion, \n activate the 2 Google drive \ntriggers to make this \nworkflow Production Ready**"
},
"typeVersion": 1
},
{
"id": "7a52403a-8ba4-4a07-81fe-f5ee0c3b63d8",
"name": "Nota adhesiva7",
"type": "n8n-nodes-base.stickyNote",
"position": [
512,
-16
],
"parameters": {
"width": 272,
"height": 80,
"content": "\n**--> The Prompt inside the RAG agent can be fine tuned according to your needs**"
},
"typeVersion": 1
},
{
"id": "1a0f8c51-1376-4520-a123-75d400095ecf",
"name": "Nota adhesiva8",
"type": "n8n-nodes-base.stickyNote",
"position": [
-400,
-336
],
"parameters": {
"color": 5,
"width": 380,
"height": 776,
"content": "## Try It Out!\n\nThis is a comprehensive, production-ready Retrieval-Augmented Generation (RAG) system. It builds a sophisticated AI agent that can answer questions based on documents in a specific Google Drive folder, and it automatically keeps its knowledge base up-to-date as you add, update, or remove files.\n\n**To get started:**\n\n1. **Connect all credentials** (Gemini, supabase, postgres, drive, and Cohere). Refer the Sticky Notes and [n8n docs](https://docs.n8n.io/)\n\n2. **Create the Tables** inside Supabase by copying the code from here. If You don't have an account create one and then on the side panel click on SQL Editor to copy paste the code [Code](https://docs.google.com/document/d/1tLJ7fndrDjYMfyQ1R61q5NbqDs5ZMgvhzcMzkoIzj5M/edit?usp=sharing)\n\n3. **Activate the workflow** by replacing the [Folder ID] with your drive folder ID inside \"Search files and folders\" Node and then upload file(s) which are of doc or pdf format.\n\n4. **For the First Time** use the manual Trigger to vectorize and push the contents of the files to Supabase\n\n5. **Ask any question** related to the the contents of the file using the Chat Trigger in Step 2 and Experience the magic of the RAG Agent.\n\n6. **Once The test is completed**, activate both the google drive trigger nodes in the step 1 flow. This will make sure that the workflow is production ready."
},
"typeVersion": 1
},
{
"id": "9c12acb0-3516-4573-8468-eabb1548fbac",
"name": "Nota adhesiva9",
"type": "n8n-nodes-base.stickyNote",
"position": [
816,
-224
],
"parameters": {
"width": 304,
"height": 288,
"content": "## --> Postgres Connection\n\nClick on \"connect\" on the top of your Supabase account. Then click on the \"Connection Pooling\" tab and make sure the \"Transaction\" pooler is selected. \n\nYou will see something similar to this screenshot: [View Image](https://i.postimg.cc/htxnsprc/Screenshot-2025-10-02-143424.png)\n\nReplace the fields inside your n8n Postgres credential with the matching values from that page."
},
"typeVersion": 1
},
{
"id": "67aac6f9-e5aa-4c7f-aea3-e19d32e36367",
"name": "Nota adhesiva10",
"type": "n8n-nodes-base.stickyNote",
"position": [
1664,
336
],
"parameters": {
"height": 128,
"content": "**Go to this website, https://dashboard.cohere.com/ create an account and copy the API key to connect Reranker Cohere**"
},
"typeVersion": 1
},
{
"id": "a34b0cd1-51fd-469e-9ba0-7961cea3f2d1",
"name": "Nota adhesiva4",
"type": "n8n-nodes-base.stickyNote",
"position": [
16,
1536
],
"parameters": {
"width": 304,
"height": 576,
"content": "## How the Cleanup Works\n\nThis is a scheduled process that runs automatically once every day. Its purpose is to keep your knowledge base synchronized by removing data from files that have been deleted in Google Drive.\n\nHere’s the step-by-step process:\n\n* The workflow fetches a list of all current file IDs from your designated Google Drive folder.\n* It also fetches a list of all file IDs stored in your Supabase tables.\n* A **Code node** compares these two lists to identify \"orphaned\" data—entries in Supabase that no longer have a matching file in Google Drive.\n* Finally, the workflow deletes all data associated with those orphaned IDs.\n\nThis cleanup process targets **two separate tables** to ensure all related information is removed: the main `documents` table (storing the content) and the `document_metadata` table (storing the file titles and URLs)."
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"a763d918-e045-461a-b081-2670f7d3f1af": {
"main": [
[
{
"node": "29b49cd7-64ce-4752-a07b-3afebf19219b",
"type": "main",
"index": 0
}
]
]
},
"4b4a4689-2767-49a9-8f8f-2a33d9cd7e84": {
"main": [
[
{
"node": "d12aeac5-f570-49c7-8276-5a53648026cb",
"type": "main",
"index": 0
}
]
]
},
"b5b91dde-0afb-493f-b336-ea84017d8171": {
"main": [
[
{
"node": "a763d918-e045-461a-b081-2670f7d3f1af",
"type": "main",
"index": 0
}
]
]
},
"f11e2063-d42c-4d07-86d8-b916467b5b3a": {
"main": [
[
{
"node": "4b4a4689-2767-49a9-8f8f-2a33d9cd7e84",
"type": "main",
"index": 0
}
]
]
},
"35366f16-4f00-4544-9f7e-aac1a5571e7f": {
"main": [
[
{
"node": "a3a6aca4-5932-4b13-9466-de1fadee3392",
"type": "main",
"index": 0
}
],
[
{
"node": "06cd8ce9-4d3c-412e-9688-a181f6aadc38",
"type": "main",
"index": 0
}
]
]
},
"74a8e170-040a-42f4-b593-a2206527f655": {
"main": [
[
{
"node": "b5b91dde-0afb-493f-b336-ea84017d8171",
"type": "main",
"index": 1
}
]
]
},
"8002bd2f-29da-40fe-b909-cdcc7d3f5fde": {
"main": [
[
{
"node": "f11e2063-d42c-4d07-86d8-b916467b5b3a",
"type": "main",
"index": 1
}
]
]
},
"2fca17ab-ec90-4877-936b-45a651a567d1": {
"main": [
[
{
"node": "8a280ac3-a27f-469c-9885-3482051e2268",
"type": "main",
"index": 0
}
]
]
},
"61d43f61-e071-4d2d-a714-eac42d4acbd2": {
"main": [
[
{
"node": "f5c2d73e-fdb7-4e2c-8fae-74e2dd483b99",
"type": "main",
"index": 0
}
]
]
},
"52fa8440-7c5a-4a2e-bd6b-17cbb22c7d6a": {
"main": [
[
{
"node": "f5c2d73e-fdb7-4e2c-8fae-74e2dd483b99",
"type": "main",
"index": 0
}
]
]
},
"e67da326-ff09-4f72-a146-19c342dc8b1f": {
"main": [
[
{
"node": "b5b91dde-0afb-493f-b336-ea84017d8171",
"type": "main",
"index": 0
}
]
]
},
"3ea2baf0-fac7-440b-bd6c-4f7f689844cc": {
"main": [
[
{
"node": "f11e2063-d42c-4d07-86d8-b916467b5b3a",
"type": "main",
"index": 0
}
]
]
},
"902bfe64-17c3-45aa-8434-cb4241aa150b": {
"main": [
[
{
"node": "35366f16-4f00-4544-9f7e-aac1a5571e7f",
"type": "main",
"index": 0
}
]
]
},
"f5c2d73e-fdb7-4e2c-8fae-74e2dd483b99": {
"main": [
[],
[
{
"node": "2fca17ab-ec90-4877-936b-45a651a567d1",
"type": "main",
"index": 0
}
]
]
},
"fbeb9ada-34d8-440a-b843-ff139e8e979c": {
"ai_reranker": [
[
{
"node": "11e0434a-904c-48ca-b119-978dd68996db",
"type": "ai_reranker",
"index": 0
}
]
]
},
"a3a6aca4-5932-4b13-9466-de1fadee3392": {
"main": [
[
{
"node": "0edf1ac5-2469-451e-81cb-6b6267427b9f",
"type": "main",
"index": 0
}
]
]
},
"c5a5c9c8-07fe-4c09-87ac-c0dd0dbaf17e": {
"main": [
[
{
"node": "e67da326-ff09-4f72-a146-19c342dc8b1f",
"type": "main",
"index": 0
},
{
"node": "74a8e170-040a-42f4-b593-a2206527f655",
"type": "main",
"index": 0
},
{
"node": "3ea2baf0-fac7-440b-bd6c-4f7f689844cc",
"type": "main",
"index": 0
},
{
"node": "8002bd2f-29da-40fe-b909-cdcc7d3f5fde",
"type": "main",
"index": 0
}
]
]
},
"8a280ac3-a27f-469c-9885-3482051e2268": {
"main": [
[
{
"node": "80ca7123-c4d6-4184-83db-3a9cd7eea5be",
"type": "main",
"index": 0
}
]
]
},
"75602bb9-30a7-409c-8aaa-38f9923cf08d": {
"ai_document": [
[
{
"node": "0edf1ac5-2469-451e-81cb-6b6267427b9f",
"type": "ai_document",
"index": 0
}
]
]
},
"e2bbc2ba-cce7-4410-b5e9-60fc1bf7dacb": {
"ai_memory": [
[
{
"node": "9f12dcc8-423c-42f6-a0de-522b5897c620",
"type": "ai_memory",
"index": 0
}
]
]
},
"06cd8ce9-4d3c-412e-9688-a181f6aadc38": {
"main": [
[
{
"node": "0edf1ac5-2469-451e-81cb-6b6267427b9f",
"type": "main",
"index": 0
}
]
]
},
"11e0434a-904c-48ca-b119-978dd68996db": {
"ai_tool": [
[
{
"node": "9f12dcc8-423c-42f6-a0de-522b5897c620",
"type": "ai_tool",
"index": 0
}
]
]
},
"86094f10-2a02-431f-b0ec-d7cd5dffb98b": {
"ai_textSplitter": [
[
{
"node": "75602bb9-30a7-409c-8aaa-38f9923cf08d",
"type": "ai_textSplitter",
"index": 0
}
]
]
},
"0b83f6fc-e67c-4a00-a26d-80efdf87213b": {
"ai_embedding": [
[
{
"node": "11e0434a-904c-48ca-b119-978dd68996db",
"type": "ai_embedding",
"index": 0
}
]
]
},
"554ad606-2bd7-49c9-a415-0c9f88ae4ac8": {
"ai_languageModel": [
[
{
"node": "9f12dcc8-423c-42f6-a0de-522b5897c620",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"80ca7123-c4d6-4184-83db-3a9cd7eea5be": {
"main": [
[
{
"node": "902bfe64-17c3-45aa-8434-cb4241aa150b",
"type": "main",
"index": 0
}
]
]
},
"5b4cd434-4799-4981-a585-21c69d8329d5": {
"main": [
[
{
"node": "f5c2d73e-fdb7-4e2c-8fae-74e2dd483b99",
"type": "main",
"index": 0
}
]
]
},
"052b2e8f-de1a-4bea-b67c-387c362f23f7": {
"ai_embedding": [
[
{
"node": "0edf1ac5-2469-451e-81cb-6b6267427b9f",
"type": "ai_embedding",
"index": 0
}
]
]
},
"33dbd2eb-d1dc-426c-9939-45461780cffe": {
"main": [
[
{
"node": "9f12dcc8-423c-42f6-a0de-522b5897c620",
"type": "main",
"index": 0
}
]
]
},
"0edf1ac5-2469-451e-81cb-6b6267427b9f": {
"main": [
[
{
"node": "f5c2d73e-fdb7-4e2c-8fae-74e2dd483b99",
"type": "main",
"index": 0
}
]
]
},
"ec4c1998-6079-4a91-a8ba-b6fed99e93a7": {
"main": [
[
{
"node": "5b4cd434-4799-4981-a585-21c69d8329d5",
"type": "main",
"index": 0
}
]
]
}
}
}¿Cómo usar este flujo de trabajo?
Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.
¿En qué escenarios es adecuado este flujo de trabajo?
Avanzado - Creación de contenido, IA Multimodal
¿Es de pago?
Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.
Flujos de trabajo relacionados recomendados
Anirudh Aeran
@anirudhaeranCompartir este flujo de trabajo