AutomationFlowsAI & RAG › Build a Google Drive Internal Knowledge Base with Openai and Pinecone

Build a Google Drive Internal Knowledge Base with Openai and Pinecone

ByRahul Joshi @rahul08 on n8n.io

Every company has documents sitting in Google Drive that nobody reads. HR policies, sales playbooks, product FAQs, financial guidelines — all written once, never found again. This workflow turns all of those documents into a live, searchable AI knowledge base that any team…

Event trigger★★★★★ complexityAI-powered38 nodesGoogle SheetsGmailGoogle DrivePinecone Vector StoreDocument Default Data LoaderText Splitter Recursive Character Text SplitterOpenAI EmbeddingsOpenAI
AI & RAG Trigger: Event Nodes: 38 Complexity: ★★★★★ AI nodes: yes Added:

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

This workflow follows the Documentdefaultdataloader → OpenAI Embeddings recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

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

Download .json
{
  "id": "dicgY5oenP5i3xT9",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Turn Your Google Drive into an AI-Powered Internal Knowledge Base with Semantic Search",
  "tags": [],
  "nodes": [
    {
      "id": "4e498901-71b0-4531-a13f-73cbc515bf3e",
      "name": "Log to Document Registry",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        816,
        -96
      ],
      "parameters": {
        "columns": {
          "value": {
            "doc_id": "={{ $('Download Doc as Text').item.json.id }}",
            "status": "ingested",
            "doc_name": "={{ $json.metadata.doc_name }}",
            "last_ingested": "={{ new Date().toISOString().split('T')[0] }}"
          },
          "schema": [
            {
              "id": "doc_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "doc_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "doc_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "doc_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "last_ingested",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "last_ingested",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1678464927,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hRkINd-uSw1QbagKca0_Xs2A5KdRloHf9yxPvQb6woY/edit#gid=1678464927",
          "cachedResultName": "Document Registry"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1hRkINd-uSw1QbagKca0_Xs2A5KdRloHf9yxPvQb6woY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hRkINd-uSw1QbagKca0_Xs2A5KdRloHf9yxPvQb6woY/edit?usp=drivesdk",
          "cachedResultName": "Internal Knowledge Brain automation"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "ab20bb84-ff23-4b27-bcfa-313745cec10c",
      "name": "Notify Ingestion Complete",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1040,
        -96
      ],
      "parameters": {
        "sendTo": "your_email_id",
        "message": "=Knowledge Base Ingestion Complete\n\nDocuments successfully stored in Pinecone.\nDate: {{ new Date().toISOString().split('T')[0] }}\n\nCheck your Pinecone dashboard to verify vectors.",
        "options": {},
        "subject": "\u2705 Knowledge Base Updated",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "typeVersion": 2.2
    },
    {
      "id": "081355ec-701b-4cf1-b118-af1545180a59",
      "name": "Read Document Registry",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        160,
        1200
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1678464927,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hRkINd-uSw1QbagKca0_Xs2A5KdRloHf9yxPvQb6woY/edit#gid=1678464927",
          "cachedResultName": "Document Registry"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1hRkINd-uSw1QbagKca0_Xs2A5KdRloHf9yxPvQb6woY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hRkINd-uSw1QbagKca0_Xs2A5KdRloHf9yxPvQb6woY/edit?usp=drivesdk",
          "cachedResultName": "Internal Knowledge Brain automation"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "typeVersion": 4.7
    },
    {
      "id": "1f300b91-98f4-4c93-a683-a28ad57d6dac",
      "name": "Update Document Registry",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1776,
        1104
      ],
      "parameters": {
        "columns": {
          "value": {
            "doc_id": "={{ $('Prepare Docs for Re-ingestion').item.json.id }}",
            "status": "={{ $('Prepare Docs for Re-ingestion').item.json.status }}",
            "doc_name": "={{ $('Prepare Docs for Re-ingestion').item.json.name }}",
            "last_ingested": "={{ new Date().toISOString().split('T')[0] }}"
          },
          "schema": [
            {
              "id": "doc_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "doc_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "doc_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "doc_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "last_ingested",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "last_ingested",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1678464927,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hRkINd-uSw1QbagKca0_Xs2A5KdRloHf9yxPvQb6woY/edit#gid=1678464927",
          "cachedResultName": "Document Registry"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1hRkINd-uSw1QbagKca0_Xs2A5KdRloHf9yxPvQb6woY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hRkINd-uSw1QbagKca0_Xs2A5KdRloHf9yxPvQb6woY/edit?usp=drivesdk",
          "cachedResultName": "Internal Knowledge Brain automation"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "2f8e444f-82d7-4d13-9431-bd1ea81980bf",
      "name": "Manual Ingestion Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -240,
        -96
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "d2e30c18-88dc-40e6-a6bf-464d7a79662d",
      "name": "List Knowledge Base Docs",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -16,
        -96
      ],
      "parameters": {
        "filter": {
          "folderId": {
            "__rl": true,
            "mode": "list",
            "value": "1I2ixpzpmSKe6GDXVAqDAWiMNBVDygiI8",
            "cachedResultUrl": "https://drive.google.com/drive/folders/1I2ixpzpmSKe6GDXVAqDAWiMNBVDygiI8",
            "cachedResultName": "Knowledge Base"
          }
        },
        "options": {},
        "resource": "fileFolder"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "d4da2a9e-078a-4637-b445-e6fd1fc375ed",
      "name": "Download Doc as Text",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        192,
        -96
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {
          "googleFileConversion": {
            "conversion": {
              "docsToFormat": "text/plain"
            }
          }
        },
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "f3ec1400-d62f-4c9e-a192-24c66c6efc86",
      "name": "Store Embeddings in Pinecone",
      "type": "@n8n/n8n-nodes-langchain.vectorStorePinecone",
      "position": [
        480,
        -96
      ],
      "parameters": {
        "mode": "insert",
        "options": {
          "pineconeNamespace": "Test Team"
        },
        "pineconeIndex": {
          "__rl": true,
          "mode": "list",
          "value": "meeting-sentiment-index"
        }
      },
      "credentials": {
        "pineconeApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "a61f500f-fa9a-4a19-b701-c00a9ba4d67d",
      "name": "Load Document Data",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "position": [
        656,
        128
      ],
      "parameters": {
        "options": {
          "metadata": {
            "metadataValues": [
              {
                "name": "doc_name",
                "value": "={{ $('Download Doc as Text').item.json.name }}"
              }
            ]
          }
        },
        "dataType": "binary",
        "textSplittingMode": "custom"
      },
      "typeVersion": 1.1
    },
    {
      "id": "aab901d9-7927-4212-9aa4-db8e670dc326",
      "name": "Split Into Chunks",
      "type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter",
      "position": [
        656,
        288
      ],
      "parameters": {
        "options": {},
        "chunkSize": 500,
        "chunkOverlap": 100
      },
      "typeVersion": 1
    },
    {
      "id": "d18aa2c3-9339-4e18-b0ed-12d849ab12d4",
      "name": "Generate Embeddings",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        448,
        144
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "7662ee08-55b8-4136-b12b-ebce56d1c8b0",
      "name": "Question Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -240,
        592
      ],
      "parameters": {
        "path": "knowledge-brain",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "3fdda52b-72a1-4bbb-9fd1-fe0e2ead8ffb",
      "name": "Extract Question & User",
      "type": "n8n-nodes-base.code",
      "position": [
        -32,
        592
      ],
      "parameters": {
        "jsCode": "return [{\n  json: {\n    question: items[0].json.body.question,\n    asked_by: items[0].json.body.asked_by || 'anonymous',\n    timestamp: new Date().toISOString()\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "20b8ac27-bb21-48c4-970e-47c901b48928",
      "name": "Search Knowledge Base",
      "type": "@n8n/n8n-nodes-langchain.vectorStorePinecone",
      "position": [
        240,
        592
      ],
      "parameters": {
        "mode": "load",
        "topK": 5,
        "prompt": "={{ $json.question }}",
        "options": {
          "pineconeNamespace": "Test Team"
        },
        "pineconeIndex": {
          "__rl": true,
          "mode": "list",
          "value": "meeting-sentiment-index"
        }
      },
      "credentials": {
        "pineconeApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "c588c289-f8be-4d81-9232-6f74b2ca0a3c",
      "name": "Generate Query Embedding",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        208,
        832
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "9666c6f5-8111-4358-90d9-ad2404efa47f",
      "name": "Build RAG Prompt",
      "type": "n8n-nodes-base.code",
      "position": [
        592,
        592
      ],
      "parameters": {
        "jsCode": "const question = $('Extract Question & User').first().json.question;\nconst asked_by = $('Extract Question & User').first().json.asked_by;\nconst docs = items;\n\n// Only use relevant chunks above score threshold\nconst relevantDocs = docs.filter(doc => doc.json.score > 0.3);\n\nlet context = '';\nconst sources = [];\n\nrelevantDocs.forEach((doc, index) => {\n  const text = doc.json.document?.pageContent || '';\n  const docName = doc.json.document?.metadata?.doc_name || 'Unknown';\n\n  if (text) {\n    context += `\\n[Source ${index + 1}: ${docName}]\\n${text}\\n`;\n    if (!sources.includes(docName)) sources.push(docName);\n  }\n});\n\n// If no relevant context found\nif (context.trim() === '') {\n  context = 'No relevant documents found in the knowledge base.';\n}\n\nconst prompt = `You are an internal company knowledge assistant. Answer the employee's question using ONLY the context provided below. \n\nIf the answer is not found in the context, say exactly: \"I don't have that information in the knowledge base. Please check with the relevant team.\"\n\nNever make up information. Always cite which document your answer comes from.\n\nCONTEXT:\n${context}\n\nQUESTION: ${question}\n\nRespond in this JSON format:\n{\n  \"answer\": \"string\",\n  \"sources\": [\"doc name 1\", \"doc name 2\"],\n  \"confidence\": \"high | medium | low\",\n  \"found_in_kb\": true or false\n}`;\n\nreturn [{\n  json: {\n    prompt,\n    question,\n    asked_by,\n    sources: sources.join(', ')\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "30135c15-c7e1-476d-b44f-c1d265f6e508",
      "name": "Answer Generator",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        800,
        592
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o",
          "cachedResultName": "GPT-4O"
        },
        "options": {},
        "responses": {
          "values": [
            {
              "content": "={{ $json.prompt }}"
            }
          ]
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "ff012edb-c097-49a4-9463-bbb1e4bafa0d",
      "name": "Parse AI Answer",
      "type": "n8n-nodes-base.code",
      "position": [
        1152,
        592
      ],
      "parameters": {
        "jsCode": "const response = items[0].json.output[0].content[0].text;\nconst cleaned = response.replace(/```json|```/g, '').trim();\nconst parsed = JSON.parse(cleaned);\n\nconst question = $('Extract Question & User').first().json.question;\nconst asked_by = $('Extract Question & User').first().json.asked_by;\n\nreturn [{\n  json: {\n    question,\n    asked_by,\n    answer: parsed.answer,\n    sources: parsed.sources.join(', '),\n    confidence: parsed.confidence,\n    found_in_kb: parsed.found_in_kb,\n    timestamp: new Date().toISOString()\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "d71d33a2-379d-4413-a507-d811eadef9a0",
      "name": "Log Q&A to Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1376,
        592
      ],
      "parameters": {
        "columns": {
          "value": {
            "date": "={{ $json.timestamp }}",
            "answer": "={{ $json.answer }}",
            "sources": "={{ $json.sources }}",
            "asked_by": "={{ $json.asked_by }}",
            "question": "={{ $json.question }}",
            "confidence": "={{ $json.confidence }}",
            "found_in_kb": "={{ $json.found_in_kb }}"
          },
          "schema": [
            {
              "id": "date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "question",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "question",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "answer",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "answer",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "sources",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "sources",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "asked_by",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "asked_by",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "confidence",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "confidence",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "found_in_kb",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "found_in_kb",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hRkINd-uSw1QbagKca0_Xs2A5KdRloHf9yxPvQb6woY/edit#gid=0",
          "cachedResultName": "Q&A Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1hRkINd-uSw1QbagKca0_Xs2A5KdRloHf9yxPvQb6woY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1hRkINd-uSw1QbagKca0_Xs2A5KdRloHf9yxPvQb6woY/edit?usp=drivesdk",
          "cachedResultName": "Internal Knowledge Brain automation"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "d2bf69f8-c574-4d24-8131-3089614ab464",
      "name": "Send Answer Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        1584,
        592
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={\n  \"question\": \"{{ $json.question }}\",\n  \"answer\": \"{{ $json.answer }}\",\n  \"sources\": \"{{ $json.sources }}\",\n  \"confidence\": \"{{ $json.confidence }}\",\n  \"asked_by\": \"{{ $json.asked_by }}\"\n}"
      },
      "executeOnce": true,
      "typeVersion": 1.5
    },
    {
      "id": "e762c285-11e8-4094-bb4a-6787ebd9c943",
      "name": "Weekly Sunday 11AM Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -304,
        1200
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtHour": 11
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "561dc99f-904c-4cff-885b-8f00be3c5a57",
      "name": "List Knowledge Base Docs1",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -80,
        1200
      ],
      "parameters": {
        "filter": {
          "folderId": {
            "__rl": true,
            "mode": "list",
            "value": "1I2ixpzpmSKe6GDXVAqDAWiMNBVDygiI8",
            "cachedResultUrl": "https://drive.google.com/drive/folders/1I2ixpzpmSKe6GDXVAqDAWiMNBVDygiI8",
            "cachedResultName": "Knowledge Base"
          }
        },
        "options": {},
        "resource": "fileFolder"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "1e1e6217-3c3f-4055-abf4-a7119e873641",
      "name": "Detect New or Updated Docs",
      "type": "n8n-nodes-base.code",
      "position": [
        384,
        1200
      ],
      "parameters": {
        "jsCode": "const driveDocs = $('List Knowledge Base Docs1').all();\nconst registry = $('Read Document Registry').all();\n\n// Build registry lookup by doc_id\nconst registryMap = {};\nregistry.forEach(r => {\n  registryMap[r.json.doc_id] = r.json;\n});\n\nconst newDocs = [];\nconst existingDocs = [];\nconst allDocs = [];\n\ndriveDocs.forEach(doc => {\n  const docId = doc.json.id;\n  const docName = doc.json.name;\n  const modifiedTime = doc.json.modifiedTime || '';\n\n  const inRegistry = registryMap[docId];\n\n  if (!inRegistry) {\n    // Brand new document never ingested\n    newDocs.push({ docId, docName, status: 'new' });\n  } else {\n    // Check if modified after last ingestion\n    const lastIngested = new Date(inRegistry.last_ingested);\n    const lastModified = new Date(modifiedTime);\n    if (lastModified > lastIngested) {\n      newDocs.push({ docId, docName, status: 'updated' });\n    } else {\n      existingDocs.push({ docId, docName, status: 'current' });\n    }\n  }\n\n  allDocs.push({\n    docId,\n    docName,\n    status: registryMap[docId] ? 'current' : 'new'\n  });\n});\n\nreturn [{\n  json: {\n    new_or_updated: newDocs,\n    existing: existingDocs,\n    all_docs: allDocs,\n    total_docs: driveDocs.length,\n    new_count: newDocs.length,\n    existing_count: existingDocs.length,\n    needs_ingestion: newDocs.length > 0\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "87b6e7f3-1d48-4bb9-af3b-297e5c64efdd",
      "name": "IF New Docs Found",
      "type": "n8n-nodes-base.if",
      "position": [
        592,
        1200
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e52d7fb4-130d-487a-904c-1a687a557211",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.needs_ingestion }}",
              "rightValue": false
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "f25316cc-8eb9-4446-9d6b-6737261b706e",
      "name": "Prepare Docs for Re-ingestion",
      "type": "n8n-nodes-base.code",
      "position": [
        848,
        1104
      ],
      "parameters": {
        "jsCode": "const newDocs = items[0].json.new_or_updated;\n\n// Return one item per new/updated doc for processing\nreturn newDocs.map(doc => ({\n  json: {\n    id: doc.docId,\n    name: doc.docName,\n    status: doc.status\n  }\n}));"
      },
      "typeVersion": 2
    },
    {
      "id": "11af64f5-608e-4f83-9776-cda58253ea8a",
      "name": "Download Updated Docs",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1056,
        1104
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {
          "googleFileConversion": {
            "conversion": {
              "docsToFormat": "text/plain"
            }
          }
        },
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "954505bc-450b-41e1-9d88-be0dba2bebf5",
      "name": "Re-ingest into Pinecone",
      "type": "@n8n/n8n-nodes-langchain.vectorStorePinecone",
      "position": [
        1280,
        1104
      ],
      "parameters": {
        "mode": "insert",
        "options": {
          "pineconeNamespace": "Test Team"
        },
        "pineconeIndex": {
          "__rl": true,
          "mode": "list",
          "value": "meeting-sentiment-index"
        }
      },
      "credentials": {
        "pineconeApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "57a5e123-b40f-4304-bf7d-41d3b9917871",
      "name": "Load Document Data1",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "position": [
        1456,
        1328
      ],
      "parameters": {
        "options": {
          "metadata": {
            "metadataValues": [
              {
                "name": "doc_name",
                "value": "={{ $('Prepare Docs for Re-ingestion').item.json.name }}"
              }
            ]
          }
        },
        "dataType": "binary",
        "textSplittingMode": "custom"
      },
      "typeVersion": 1.1
    },
    {
      "id": "0ba757d1-dcfa-439a-9868-daca975ad6da",
      "name": "Split Into Chunks1",
      "type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter",
      "position": [
        1456,
        1488
      ],
      "parameters": {
        "options": {},
        "chunkSize": 500,
        "chunkOverlap": 100
      },
      "typeVersion": 1
    },
    {
      "id": "5c0e34d0-51ed-4f05-8212-dde1270a7e90",
      "name": "Generate Embeddings1",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        1248,
        1344
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "a14a1e5b-51f6-4cc4-819f-c85c7264ec31",
      "name": "Build KB Digest Email",
      "type": "n8n-nodes-base.code",
      "position": [
        1968,
        1104
      ],
      "parameters": {
        "jsCode": "const data = $('Detect New or Updated Docs').first().json;\n\nlet email = `\ud83e\udde0 Knowledge Base Weekly Digest\\n`;\nemail += `Generated: ${new Date().toDateString()}\\n`;\nemail += `\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n\\n`;\n\nemail += `\ud83d\udcca KNOWLEDGE BASE STATUS\\n\\n`;\nemail += `Total Documents: ${data.total_docs}\\n`;\nemail += `New or Updated This Week: ${data.new_count}\\n`;\nemail += `Already Current: ${data.existing_count}\\n\\n`;\n\nif (data.new_or_updated && data.new_or_updated.length > 0) {\n  email += `\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n`;\n  email += `\ud83c\udd95 NEW OR UPDATED DOCUMENTS\\n\\n`;\n  data.new_or_updated.forEach(doc => {\n    const emoji = doc.status === 'new' ? '\u2705 NEW' : '\ud83d\udd04 UPDATED';\n    email += `${emoji} \u2014 ${doc.docName}\\n`;\n  });\n  email += `\\nThese documents have been re-ingested into Pinecone.\\n\\n`;\n}\n\nif (data.existing && data.existing.length > 0) {\n  email += `\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n`;\n  email += `\u2705 CURRENT DOCUMENTS (No changes)\\n\\n`;\n  data.existing.forEach(doc => {\n    email += `\u2022 ${doc.docName}\\n`;\n  });\n  email += `\\n`;\n}\n\nemail += `\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n`;\nemail += `Knowledge Base is up to date and ready to answer questions.\\n`;\nemail += `Webhook: POST /webhook/knowledge-brain\\n\\n`;\nemail += `Generated by Internal Knowledge Brain`;\n\nreturn [{ json: { email_body: email, total_docs: data.total_docs, new_count: data.new_count } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "a576a867-f567-4198-bd7a-1e648781d14d",
      "name": "Build KB Digest Email1",
      "type": "n8n-nodes-base.code",
      "position": [
        928,
        1664
      ],
      "parameters": {
        "jsCode": "const data = $('Detect New or Updated Docs').first().json;\n\nlet email = `\ud83e\udde0 Knowledge Base Weekly Digest\\n`;\nemail += `Generated: ${new Date().toDateString()}\\n`;\nemail += `\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n\\n`;\n\nemail += `\ud83d\udcca KNOWLEDGE BASE STATUS\\n\\n`;\nemail += `Total Documents: ${data.total_docs}\\n`;\nemail += `New or Updated This Week: ${data.new_count}\\n`;\nemail += `Already Current: ${data.existing_count}\\n\\n`;\n\nif (data.new_or_updated && data.new_or_updated.length > 0) {\n  email += `\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n`;\n  email += `\ud83c\udd95 NEW OR UPDATED DOCUMENTS\\n\\n`;\n  data.new_or_updated.forEach(doc => {\n    const emoji = doc.status === 'new' ? '\u2705 NEW' : '\ud83d\udd04 UPDATED';\n    email += `${emoji} \u2014 ${doc.docName}\\n`;\n  });\n  email += `\\nThese documents have been re-ingested into Pinecone.\\n\\n`;\n}\n\nif (data.existing && data.existing.length > 0) {\n  email += `\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n`;\n  email += `\u2705 CURRENT DOCUMENTS (No changes)\\n\\n`;\n  data.existing.forEach(doc => {\n    email += `\u2022 ${doc.docName}\\n`;\n  });\n  email += `\\n`;\n}\n\nemail += `\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n`;\nemail += `Knowledge Base is up to date and ready to answer questions.\\n`;\nemail += `Webhook: POST /webhook/knowledge-brain\\n\\n`;\nemail += `Generated by Internal Knowledge Brain`;\n\nreturn [{ json: { email_body: email, total_docs: data.total_docs, new_count: data.new_count } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "a24dbe19-e6e2-4ffa-8239-42c7ddc16e43",
      "name": "Send Weekly KB Digest",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2176,
        1104
      ],
      "parameters": {
        "sendTo": "your_email_id",
        "message": "={{ $json.email_body }}",
        "options": {},
        "subject": "=\ud83e\udde0 Weekly KB Digest \u2014 {{ $json.total_docs }} Docs | {{ $json.new_count }} Updated",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c876e977-e549-4071-8813-ad3a5e8782d2",
      "name": "Send Weekly KB Digest1",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1136,
        1664
      ],
      "parameters": {
        "sendTo": "your_email_id",
        "message": "={{ $json.email_body }}",
        "options": {},
        "subject": "=\ud83e\udde0 Weekly KB Digest \u2014 {{ $json.total_docs }} Docs | {{ $json.new_count }} Updated",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "1b5f30c3-ef49-45f2-bbc6-584c88db4258",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -944,
        -832
      ],
      "parameters": {
        "width": 400,
        "height": 720,
        "content": "## Workflow Overview\n\n\n\nStop answering the same company questions over and \nover. This workflow turns your Google Drive documents \ninto a searchable AI knowledge base. Ask it anything \nabout your company \u2014 HR policies, financials, sales \nprocess, product details \u2014 and it answers instantly \nwith the exact source it pulled from.\n\n### HOW IT WORKS\n\nSW1 ingests your Google Docs into Pinecone as vector \nembeddings. SW2 takes any question via webhook, finds \nthe most relevant chunks using semantic search, and \nsends them to GPT-4o for a grounded answer with source \ncitation. SW3 runs every Sunday to check for new or \nupdated documents and keeps the knowledge base fresh.\n\n### SETUP STEPS\n\n1. Create a Google Drive folder called Knowledge Base\n2. Add your company documents as Google Docs\n3. Create a Pinecone index \u2014 dimensions 1536, metric cosine\n4. Add Pinecone, OpenAI, Google Drive, Sheets and Gmail credentials\n5. Send POST requests to the webhook to ask questions"
      },
      "typeVersion": 1
    },
    {
      "id": "39959dab-ce20-444a-ba2a-d886fffbf70b",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -304,
        -272
      ],
      "parameters": {
        "color": 7,
        "width": 1536,
        "height": 704,
        "content": "Run this manually when adding new documents. Reads  all Google Docs from your Knowledge Base folder,  splits them into chunks, converts to embeddings,  and stores everything in Pinecone. Logs each doc  to the Document Registry sheet."
      },
      "typeVersion": 1
    },
    {
      "id": "70976dfe-7d68-4c60-801f-c7237d836519",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -368,
        480
      ],
      "parameters": {
        "color": 7,
        "width": 2144,
        "height": 496,
        "content": "Always active via webhook. Takes any question as a POST request, searches Pinecone for the 5 most  relevant chunks, sends context to GPT-4o, and  returns a grounded answer with source citation  and confidence score. All Q&A logged to Sheets."
      },
      "typeVersion": 1
    },
    {
      "id": "72c868a8-636b-432c-8536-cf75f162b191",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -352,
        1024
      ],
      "parameters": {
        "color": 7,
        "width": 2816,
        "height": 832,
        "content": "Runs every Sunday at 11AM. Compares your Drive folder against the Document Registry, detects new  or updated docs, re-ingests them into Pinecone automatically, and emails a weekly digest of your full knowledge base status."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "ff578ef0-1aab-4265-9846-fcc7340b5a97",
  "connections": {
    "Parse AI Answer": {
      "main": [
        [
          {
            "node": "Log Q&A to Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Answer Generator": {
      "main": [
        [
          {
            "node": "Parse AI Answer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build RAG Prompt": {
      "main": [
        [
          {
            "node": "Answer Generator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Question Webhook": {
      "main": [
        [
          {
            "node": "Extract Question & User",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF New Docs Found": {
      "main": [
        [
          {
            "node": "Prepare Docs for Re-ingestion",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Build KB Digest Email1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Q&A to Sheets": {
      "main": [
        [
          {
            "node": "Send Answer Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Into Chunks": {
      "ai_textSplitter": [
        [
          {
            "node": "Load Document Data",
            "type": "ai_textSplitter",
            "index": 0
          }
        ]
      ]
    },
    "Load Document Data": {
      "ai_document": [
        [
          {
            "node": "Store Embeddings in Pinecone",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    },
    "Split Into Chunks1": {
      "ai_textSplitter": [
        [
          {
            "node": "Load Document Data1",
            "type": "ai_textSplitter",
            "index": 0
          }
        ]
      ]
    },
    "Generate Embeddings": {
      "ai_embedding": [
        [
          {
            "node": "Store Embeddings in Pinecone",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Load Document Data1": {
      "ai_document": [
        [
          {
            "node": "Re-ingest into Pinecone",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    },
    "Download Doc as Text": {
      "main": [
        [
          {
            "node": "Store Embeddings in Pinecone",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Embeddings1": {
      "ai_embedding": [
        [
          {
            "node": "Re-ingest into Pinecone",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Build KB Digest Email": {
      "main": [
        [
          {
            "node": "Send Weekly KB Digest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Updated Docs": {
      "main": [
        [
          {
            "node": "Re-ingest into Pinecone",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search Knowledge Base": {
      "main": [
        [
          {
            "node": "Build RAG Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Weekly KB Digest": {
      "main": [
        []
      ]
    },
    "Build KB Digest Email1": {
      "main": [
        [
          {
            "node": "Send Weekly KB Digest1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Document Registry": {
      "main": [
        [
          {
            "node": "Detect New or Updated Docs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Question & User": {
      "main": [
        [
          {
            "node": "Search Knowledge Base",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Re-ingest into Pinecone": {
      "main": [
        [
          {
            "node": "Update Document Registry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Query Embedding": {
      "ai_embedding": [
        [
          {
            "node": "Search Knowledge Base",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "List Knowledge Base Docs": {
      "main": [
        [
          {
            "node": "Download Doc as Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log to Document Registry": {
      "main": [
        [
          {
            "node": "Notify Ingestion Complete",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Manual Ingestion Trigger": {
      "main": [
        [
          {
            "node": "List Knowledge Base Docs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Document Registry": {
      "main": [
        [
          {
            "node": "Build KB Digest Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List Knowledge Base Docs1": {
      "main": [
        [
          {
            "node": "Read Document Registry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Detect New or Updated Docs": {
      "main": [
        [
          {
            "node": "IF New Docs Found",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Weekly Sunday 11AM Trigger": {
      "main": [
        [
          {
            "node": "List Knowledge Base Docs1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Store Embeddings in Pinecone": {
      "main": [
        [
          {
            "node": "Log to Document Registry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Docs for Re-ingestion": {
      "main": [
        [
          {
            "node": "Download Updated Docs",
            "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

Every company has documents sitting in Google Drive that nobody reads. HR policies, sales playbooks, product FAQs, financial guidelines — all written once, never found again. This workflow turns all of those documents into a live, searchable AI knowledge base that any team…

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

Your AI workforce is ready. Are you?

Google Sheets Tool, Mcp Trigger, Google Drive +29
AI & RAG

This advanced n8n workflow automates the full lead enrichment, qualification, and personalized outreach process tailored specifically for the B2B real estate sector. Integrating top platforms like Api

N8N Nodes Fillout, OpenAI Chat, Pinecone Vector Store +11
AI & RAG

This n8n template automatically classifies incoming emails (Sales, Support, Internal, Finance, Promotions) and routes them to a dedicated OpenAI LLM Agent for processing. Depending on the category, th

OpenAI, Gmail, Text Classifier +16
AI & RAG

Automate Outreach Prospect automates finding, enriching, and messaging potential partners (like restaurants, malls, and bars) using Apify Google Maps scraping, Perplexity enrichment, OpenAI LLMs, Goog

@Devlikeapro/N8N Nodes Waha, Google Drive Trigger, @Apify/N8N Nodes Apify +14
AI & RAG

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

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