{
  "id": "dd2mK6aG4p6XKh09",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Voice RAG Chatbot with ElevenLabs and OpenAI",
  "tags": [],
  "nodes": [
    {
      "id": "ec9a13ea-8141-40e0-bf97-8d8ed059abd9",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2032,
        864
      ],
      "parameters": {
        "color": 7,
        "width": 580,
        "height": 1460,
        "content": "## \ud83c\udf99\ufe0f Voice RAG Chatbot with ElevenLabs and OpenAI\n\nAnswers spoken restaurant questions forwarded by ElevenLabs using a RAG-grounded AI Agent, with a separate one-click flow to (re)build the Qdrant knowledge base from Google Drive documents.\n\n**Perfect for:** Restaurant owners running an ElevenLabs voice assistant who need answers grounded in their own menu/FAQ documents.\n\n---\n\n## How it works\n\n1. **When clicking 'Test workflow'** \u2014 Manual trigger that (re)builds the knowledge base; runs Create collection and Refresh collection in parallel.\n2. **Create collection** \u2014 Creates the Qdrant collection via HTTP request (safe to run once).\n3. **Refresh collection** \u2014 Deletes existing points in the Qdrant collection so it can be rebuilt from scratch.\n4. **Get folder** \u2014 Lists files in the configured Google Drive folder (test-whatsapp).\n5. **Download Files** \u2014 Downloads each file, converting Google Docs to plain text.\n6. **Token Splitter** \u2014 Splits document text into ~300-token chunks with 30-token overlap.\n7. **Default Data Loader** \u2014 Loads the binary file content into LangChain documents, using the Token Splitter.\n8. **Embeddings OpenAI1** \u2014 Generates OpenAI embeddings for each chunk.\n9. **Qdrant Vector Store1** *(insert mode)* \u2014 Writes the embedded chunks into the Qdrant collection.\n10. **Listen** \u2014 Webhook that receives the incoming voice question from ElevenLabs (as body.question).\n11. **AI Agent** \u2014 LangChain agent that answers the question, backed by memory and the vector store tool.\n12. **Window Buffer Memory** \u2014 Keeps recent conversation turns for the agent.\n13. **OpenAI** *(LLM)* \u2014 Powers the AI Agent's reasoning.\n14. **Vector Store Tool** \u2014 Tool the agent calls to search company knowledge (\"company\").\n15. **Qdrant Vector Store** *(retrieve mode)* \u2014 Backs the Vector Store Tool with similarity search over the Qdrant collection.\n16. **Embeddings OpenAI** \u2014 Embeds the incoming query for the retrieval tool.\n17. **OpenAI Chat Model** \u2014 LLM used by the Vector Store Tool for query understanding.\n18. **Respond to ElevenLabs** \u2014 Returns the AI Agent's answer back to ElevenLabs as the webhook response.\n\n---\n\n## Setup (~15 minutes)\n\n1. **Qdrant** \u2014 Set your Qdrant URL in *Create collection*, *Refresh collection*, and the collection name in both *Qdrant Vector Store* nodes; add your Qdrant API header credential.\n2. **Google Drive** \u2014 Connect your account in *Get folder* and *Download Files*; point *Get folder* at the source folder (currently `test-whatsapp`).\n3. **OpenAI** \u2014 Add your API key in *Embeddings OpenAI*, *Embeddings OpenAI1*, *OpenAI*, and *OpenAI Chat Model*.\n4. **ElevenLabs webhook** \u2014 Copy the *Listen* node's production webhook URL (`test_voice_message_elevenlabs`) into your ElevenLabs Conversational AI tool config.\n> Run *When clicking 'Test workflow'* once (or after adding new documents) to rebuild the Qdrant index before going live."
      },
      "typeVersion": 1
    },
    {
      "id": "ebc07f1a-b50d-4804-aad9-a3e91dd7f827",
      "name": "Section 1 - Knowledge Base Setup",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1152,
        864
      ],
      "parameters": {
        "color": 5,
        "width": 1196,
        "height": 700,
        "content": "## 1\ufe0f\u20e3 Knowledge Base Setup\n\nRunning **When clicking 'Test workflow'** kicks off a full reindex: **Create collection** ensures the Qdrant collection exists, **Refresh collection** clears any existing points, **Get folder** lists the source documents in Google Drive, and **Download Files** pulls each one down (converting Google Docs to plain text) ready for embedding."
      },
      "typeVersion": 1
    },
    {
      "id": "e194271b-2e2a-414c-9a70-bf6e9dfa4750",
      "name": "Section 2 - Document Processing & Embedding",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        320,
        1040
      ],
      "parameters": {
        "color": 6,
        "width": 520,
        "height": 800,
        "content": "## 2\ufe0f\u20e3 Document Processing & Embedding\n\nThe **Token Splitter** breaks downloaded documents into 300-token chunks with light overlap, which the **Default Data Loader** feeds into **Embeddings OpenAI1** for vectorization. **Qdrant Vector Store1** then writes the resulting embeddings into the Qdrant collection in insert mode, building the searchable knowledge base."
      },
      "typeVersion": 1
    },
    {
      "id": "3c4d8437-0115-4cd7-a585-071496643bd1",
      "name": "Section 3 - Voice Query & AI Response",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1168,
        1616
      ],
      "parameters": {
        "color": 3,
        "width": 1440,
        "height": 1052,
        "content": "## 3\ufe0f\u20e3 Voice Query & AI Response\n\nThe **Listen** webhook receives each spoken question forwarded by ElevenLabs. The **AI Agent** answers it using **OpenAI** as its reasoning model, **Window Buffer Memory** for conversation context, and the **Vector Store Tool** \u2014 backed by **Qdrant Vector Store**, **Embeddings OpenAI**, and **OpenAI Chat Model** \u2014 to search the indexed knowledge base. **Respond to ElevenLabs** sends the answer back as the webhook response."
      },
      "typeVersion": 1
    },
    {
      "id": "a747efd2-ed2d-4a83-9190-486f9a611884",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -544,
        1808
      ],
      "parameters": {
        "text": "={{ $json.body.question }}",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "a8da5ce6-5805-4900-946b-97d091c96126",
      "name": "Vector Store Tool",
      "type": "@n8n/n8n-nodes-langchain.toolVectorStore",
      "position": [
        -336,
        2048
      ],
      "parameters": {
        "name": "company",
        "description": "Risponde alle domande relative a ci\u00f2 che ti viene chiesto"
      },
      "typeVersion": 1
    },
    {
      "id": "28f7510f-d0d6-47b3-8ed2-2b7051499fab",
      "name": "Qdrant Vector Store",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant",
      "position": [
        -496,
        2304
      ],
      "parameters": {
        "options": {},
        "qdrantCollection": {
          "__rl": true,
          "mode": "id",
          "value": "=COLLECTION"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "64f154a3-e68d-47de-b8f3-f5b523461417",
      "name": "Embeddings OpenAI",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        -496,
        2464
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "90490347-835b-4b94-bc4e-e58a7efd8606",
      "name": "When clicking \u2018Test workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -1024,
        1168
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "24a4c9a2-33ff-4935-a46c-2b26e8312a03",
      "name": "Create collection",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -720,
        1024
      ],
      "parameters": {
        "url": "https://QDRANTURL/collections/COLLECTION",
        "method": "POST",
        "options": {},
        "jsonBody": "{\n \"filter\": {}\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "21cbc377-a03b-4e0a-b003-998a05d7bc68",
      "name": "Refresh collection",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -720,
        1296
      ],
      "parameters": {
        "url": "https://QDRANTURL/collections/COLLECTION/points/delete",
        "method": "POST",
        "options": {},
        "jsonBody": "{\n \"filter\": {}\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "e340ef27-342a-4796-bbec-1470a404eeb2",
      "name": "Get folder",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -496,
        1296
      ],
      "parameters": {
        "filter": {
          "driveId": {
            "__rl": true,
            "mode": "list",
            "value": "My Drive",
            "cachedResultUrl": "https://drive.google.com/drive/my-drive",
            "cachedResultName": "My Drive"
          },
          "folderId": {
            "__rl": true,
            "mode": "id",
            "value": "=test-whatsapp"
          }
        },
        "options": {},
        "resource": "fileFolder"
      },
      "typeVersion": 3
    },
    {
      "id": "b15a9bf1-f86d-4fbe-8189-4f0a230da371",
      "name": "Download Files",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -272,
        1296
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {
          "googleFileConversion": {
            "conversion": {
              "docsToFormat": "text/plain"
            }
          }
        },
        "operation": "download"
      },
      "typeVersion": 3
    },
    {
      "id": "67703d98-b1de-4e4f-bc9e-0d5c60c82784",
      "name": "Default Data Loader",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "position": [
        592,
        1488
      ],
      "parameters": {
        "options": {},
        "dataType": "binary"
      },
      "typeVersion": 1
    },
    {
      "id": "916ce1ae-3d5c-47a4-9c46-7fd45f5c7307",
      "name": "Token Splitter",
      "type": "@n8n/n8n-nodes-langchain.textSplitterTokenSplitter",
      "position": [
        560,
        1648
      ],
      "parameters": {
        "chunkSize": 300,
        "chunkOverlap": 30
      },
      "typeVersion": 1
    },
    {
      "id": "01826335-ba9b-42d8-8f3c-a0c07c2465df",
      "name": "Qdrant Vector Store1",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant",
      "position": [
        448,
        1296
      ],
      "parameters": {
        "mode": "insert",
        "options": {},
        "qdrantCollection": {
          "__rl": true,
          "mode": "id",
          "value": "=COLLECTION"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "6dc96fc7-f9ab-4ea7-8671-a2e52074ba0b",
      "name": "Embeddings OpenAI1",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        432,
        1488
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "2a4f0089-81ed-42a4-9e58-8f5a3b93ebe7",
      "name": "Respond to ElevenLabs",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        32,
        1808
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "5c2263c7-c3f6-4c95-b66f-8adf6cebe086",
      "name": "OpenAI",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -656,
        2048
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "358254e2-2d5c-42f9-bda4-4907bc1f8d61",
      "name": "Listen",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -1056,
        1808
      ],
      "parameters": {
        "path": "test_voice_message_elevenlabs",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "2617c1ec-0802-4dcc-b990-2eaa69c18ccf",
      "name": "Window Buffer Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        -496,
        2048
      ],
      "parameters": {},
      "typeVersion": 1.3
    },
    {
      "id": "4f5dfdca-d3a4-4280-ae6e-072838baae52",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -160,
        2320
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "ddba5089-5fd4-456c-8cdf-2fe469c3962f",
  "nodeGroups": [],
  "connections": {
    "Listen": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Respond to ElevenLabs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get folder": {
      "main": [
        [
          {
            "node": "Download Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Files": {
      "main": [
        [
          {
            "node": "Qdrant Vector Store1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Token Splitter": {
      "ai_textSplitter": [
        [
          {
            "node": "Default Data Loader",
            "type": "ai_textSplitter",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI": {
      "ai_embedding": [
        [
          {
            "node": "Qdrant Vector Store",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Vector Store Tool",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Vector Store Tool": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI1": {
      "ai_embedding": [
        [
          {
            "node": "Qdrant Vector Store1",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Refresh collection": {
      "main": [
        [
          {
            "node": "Get folder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Default Data Loader": {
      "ai_document": [
        [
          {
            "node": "Qdrant Vector Store1",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    },
    "Qdrant Vector Store": {
      "ai_vectorStore": [
        [
          {
            "node": "Vector Store Tool",
            "type": "ai_vectorStore",
            "index": 0
          }
        ]
      ]
    },
    "Window Buffer Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Test workflow\u2019": {
      "main": [
        [
          {
            "node": "Create collection",
            "type": "main",
            "index": 0
          },
          {
            "node": "Refresh collection",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}