This workflow corresponds to n8n.io template #15415 — we link there as the canonical source.
This workflow follows the Agent → Chat Trigger 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 →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "cfb1fdf8-41a3-4ff4-81f7-ff2be701223b",
"name": "When chat message received",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
3344,
912
],
"parameters": {
"mode": "webhook",
"public": true,
"options": {}
},
"typeVersion": 1.4
},
{
"id": "e486fe08-9624-47dd-9558-87b2a3e0442d",
"name": "Simple Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
3856,
1216
],
"parameters": {
"contextWindowLength": 10
},
"typeVersion": 1.3
},
{
"id": "24ae52da-2673-4127-b3f0-c0fe62c917be",
"name": "Send a message in Gmail",
"type": "n8n-nodes-base.gmailTool",
"position": [
4176,
1200
],
"parameters": {
"sendTo": "user@example.com",
"message": "={{ $fromAI('Message', ``, 'string') }}",
"options": {
"appendAttribution": false
},
"subject": "NEW SUPPORT REQUEST",
"emailType": "text"
},
"typeVersion": 2.2
},
{
"id": "b058335d-d652-4a03-9839-554b65fddb1f",
"name": "Run Indexing",
"type": "n8n-nodes-base.manualTrigger",
"position": [
3216,
2880
],
"parameters": {},
"typeVersion": 1
},
{
"id": "7734e624-417e-401e-b0dc-ff7a1734e2f6",
"name": "Qdrant Vector Store",
"type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant",
"position": [
4816,
2352
],
"parameters": {
"mode": "insert",
"options": {},
"qdrantCollection": {
"__rl": true,
"mode": "list",
"value": "your-collection-name",
"cachedResultName": "your-collection-name"
},
"embeddingBatchSize": 100
},
"typeVersion": 1.3
},
{
"id": "cd21d54f-e213-43ae-ad08-c55fc6665852",
"name": "Default Data Loader",
"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
"position": [
4912,
2576
],
"parameters": {
"options": {},
"textSplittingMode": "custom"
},
"typeVersion": 1.1
},
{
"id": "a5887993-16a7-404d-aa99-c39a8e352aed",
"name": "Map Site",
"type": "@mendable/n8n-nodes-firecrawl.firecrawl",
"position": [
3888,
2880
],
"parameters": {
"url": "={{ $json.url }}",
"resource": "MapSearch",
"operation": "map",
"requestOptions": {},
"includeSubdomains": true
},
"retryOnFail": true,
"typeVersion": 1
},
{
"id": "af28a652-e8eb-468e-903d-cd05c2614545",
"name": "Remove Duplicates",
"type": "n8n-nodes-base.removeDuplicates",
"position": [
3888,
2528
],
"parameters": {
"options": {}
},
"typeVersion": 2
},
{
"id": "7a7dd937-8ee2-4d00-9a5d-752258ce83fa",
"name": "Loop Over Items1",
"type": "n8n-nodes-base.splitInBatches",
"position": [
4112,
2528
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "82570cba-9e22-473e-86ce-f6e07a5fd4d2",
"name": "Single Scrape",
"type": "@mendable/n8n-nodes-firecrawl.firecrawl",
"position": [
4336,
2352
],
"parameters": {
"url": "={{ $json.url }}",
"operation": "scrape",
"scrapeOptions": {
"options": {
"formats": {
"format": [
{}
]
},
"headers": {},
"waitFor": 10
}
},
"requestOptions": {}
},
"retryOnFail": true,
"typeVersion": 1
},
{
"id": "5e8dd746-480b-4956-ad3c-d27a5576d931",
"name": "Recursive Character Text Splitter",
"type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter",
"position": [
4992,
2784
],
"parameters": {
"options": {},
"chunkOverlap": 200
},
"typeVersion": 1
},
{
"id": "7f7b3fb8-32f9-4c40-841d-73fcb164c5d8",
"name": "set urls to scrape",
"type": "n8n-nodes-base.code",
"position": [
3440,
2880
],
"parameters": {
"jsCode": "// IMPORTANT: Track which URLs you have already indexed in the comment below.\n// If you run this workflow again with a URL that was already indexed,\n// it will create duplicate data in your vector store \u2014 which hurts retrieval quality.\n// Update the 'used' list each time you successfully index a new URL.\n//\n// used: none\n\nreturn [\n { json: { url: \"https://your-site.com\" } },\n { json: { url: \"https://blog.your-site.com\" } }\n];"
},
"typeVersion": 2
},
{
"id": "876d352f-30ad-4c8c-9161-5a058b270dbc",
"name": "Loop Over urls",
"type": "n8n-nodes-base.splitInBatches",
"position": [
3664,
2880
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "aa54bf61-eaef-4ccb-a113-d268e4398be1",
"name": "Split Out links",
"type": "n8n-nodes-base.splitOut",
"position": [
4112,
2880
],
"parameters": {
"options": {},
"fieldToSplitOut": "links"
},
"typeVersion": 1
},
{
"id": "0f414450-6fbb-400e-bb04-5eb6c28ee599",
"name": "extract only urls",
"type": "n8n-nodes-base.set",
"position": [
4336,
2944
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "f6b96b52-aff5-4e3e-b6bd-0623cdbeb989",
"name": "url",
"type": "string",
"value": "={{ $json.url }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "da115c9c-2e78-4c08-9c78-b1b89523dace",
"name": "remove irrelevant params",
"type": "n8n-nodes-base.set",
"position": [
4560,
2352
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "f26d46aa-a4af-4e62-8634-58ef1470fbc1",
"name": "data.markdown",
"type": "string",
"value": "={{ $json.data }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "ec6cb02c-2900-4aeb-8622-5a56ddc7ad69",
"name": "Embeddings Mistral Cloud",
"type": "@n8n/n8n-nodes-langchain.embeddingsMistralCloud",
"position": [
4784,
2576
],
"parameters": {
"model": "codestral-embed-2505",
"options": {}
},
"retryOnFail": true,
"typeVersion": 1,
"waitBetweenTries": 5000
},
{
"id": "d528a40a-cb2d-4411-bc04-cb2556723f47",
"name": "Wait",
"type": "n8n-nodes-base.wait",
"position": [
5280,
2528
],
"parameters": {
"amount": 1
},
"typeVersion": 1.1
},
{
"id": "fd22a2aa-43ac-4c40-b04f-243641a02702",
"name": "Qdrant Vector Store1",
"type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant",
"position": [
4704,
1104
],
"parameters": {
"mode": "retrieve-as-tool",
"topK": 3,
"options": {},
"toolDescription": "Search the website knowledge base for information about features, how-tos, help articles, blog posts, and community guides.",
"qdrantCollection": {
"__rl": true,
"mode": "list",
"value": "your-collection-name",
"cachedResultName": "your-collection-name"
}
},
"credentials": {
"qdrantApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "40f8fdee-a980-4510-956a-6dce6f839f99",
"name": "Embeddings Mistral Cloud1",
"type": "@n8n/n8n-nodes-langchain.embeddingsMistralCloud",
"position": [
4496,
1232
],
"parameters": {
"model": "codestral-embed-2505",
"options": {}
},
"typeVersion": 1
},
{
"id": "409c08f5-1ff9-45de-b37d-d738f9fdfc9f",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
4224,
928
],
"parameters": {
"options": {
"systemMessage": "## Identity\nYou are the Colnect Assistant, a helpful AI built into colnect.com \u2014 a global community where collectors manage, buy, sell, and swap stamps, coins, banknotes, and dozens of other collectibles. You are part of this website. Never direct users to \"visit Colnect\" or \"check the website\" \u2014 they are already here.\n\n## Who you are talking to\nThe people coming to you are collectors \u2014 some are beginners who just discovered Colnect, some are experienced collectors who are lost or frustrated. Almost nobody is here just to chat. They have a real question, a real problem, or they need to find something specific. Treat every message like it came from someone who genuinely needs help.\n\n## Your job\nHelp users find what they are looking for. That means:\n- Answering directly when you know the answer\n- Pointing them to the exact right place on Colnect with a working link when you don't\n- Being honest when something is beyond what you can look up, and offering a clear next step\n\nYou are not here to impress anyone with how much you know. You are here to make sure no user walks away more confused than when they arrived.\n\n## How to respond\nBe conversational and warm, but get to the point. Give enough detail that the user actually knows what to do next \u2014 a one-line answer to a real question is rarely enough. Do not pad responses with filler. Do not repeat what the user just said back to them.\n\nIf a user asks something you can look up, look it up and answer. If you cannot find it in your knowledge base, say so clearly and point them somewhere useful. Never guess statistics, user counts, prices, or any platform data you are not certain about \u2014 a wrong answer is worse than no answer.\n\n## Rules\n- Never use em dashes\n- Never say \"visit the Colnect website\", \"check their website\", \"head over to\", or any variation \u2014 you are the website\n- Never fabricate numbers, statistics, or facts you are not certain about\n- When you don't have an answer, always give the user a direction \u2014 a relevant link, a suggestion, or an offer to escalate\n- When troubleshooting, ask one question at a time and walk the user through it step by step\n- Do not list every possible solution upfront\n- Do not offer examples or options unless the user asks for them\n- Do not ask clarifying questions if you can just look it up yourself\n- Do not preview what you are about to do \u2014 just do it\n- Do not add dates to summaries\n\n## Human Support Escalation\nIf a question or issue is beyond what you can resolve, offer to connect the user with human support. If they agree:\n1. Ask for their registered email\n2. Write a clear summary of the issue based on the conversation, then ask if they are happy with it before sending\n3. If they approve, send it using the Gmail tool\n4. If they want to change it, ask them to describe the issue in their own words and send that instead\n\n## Email Format\nEvery support email must follow this structure:\n- Subject: short and descriptive\n- Email: their registered email\n- [blank line]\n- Clear, concise summary of the issue and what was already tried"
}
},
"typeVersion": 3.1
},
{
"id": "80c1afae-f2c7-42b6-b16e-18faa091bc3c",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
3552,
1216
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "gpt-4o-mini"
},
"options": {},
"builtInTools": {}
},
"typeVersion": 1.3
},
{
"id": "daa47c3a-ccd9-4efe-be68-6587990e1cb1",
"name": "Start Here",
"type": "n8n-nodes-base.stickyNote",
"position": [
2016,
928
],
"parameters": {
"color": 4,
"width": 500,
"height": 616,
"content": "## \ud83d\ude80 Start Here \u2014 Setup Checklist\n\nComplete every item below before running anything.\n\n**Credentials (add in n8n Settings > Credentials):**\n- [ ] Firecrawl API key \u2014 sign up at firecrawl.dev\n- [ ] Mistral Cloud API key \u2014 sign up at console.mistral.ai\n- [ ] Qdrant Cloud API key + cluster URL \u2014 sign up at cloud.qdrant.io\n- [ ] OpenAI API key \u2014 sign up at platform.openai.com\n- [ ] Gmail OAuth2 \u2014 set up in n8n credentials\n\n**Qdrant Setup (do this before running the indexing pipeline):**\n- [ ] Create a Qdrant Cloud account and cluster\n- [ ] Create a new collection with these exact settings:\n - Dimensions: 1536 (matches codestral-embed-2505)\n - Distance: Cosine\n- [ ] Copy your collection name into the two Qdrant Vector Store nodes\n\n**Gmail Setup:**\n- [ ] Open the Gmail tool node\n- [ ] Replace YOUR_SUPPORT_EMAIL@example.com with your actual support inbox\n\n**Workflow Config:**\n- [ ] Open the \"set urls to scrape\" Code node\n- [ ] Replace the placeholder URLs with your own site's root domains\n\nOnce all boxes are checked, run the indexing pipeline first.\nDo not run the chatbot until indexing is complete."
},
"typeVersion": 1
},
{
"id": "9c54f3f7-40d5-4fa5-bc44-cccefc58f354",
"name": "Workflow Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
2000,
1648
],
"parameters": {
"color": 6,
"width": 500,
"height": 396,
"content": "## Workflow Overview\n\nThis workflow has two independent parts that work together.\n\n**Part 1 \u2014 Indexing Pipeline (bottom half)**\nRun this once to crawl your website and store its content in a Qdrant vector database. Each page is scraped, chunked, converted into a vector embedding, and stored. Run it again whenever your site content changes \u2014 but read the note on the \"set urls to scrape\" node first to avoid duplicates.\n\n**Part 2 \u2014 AI Chatbot (top half)**\nAlways-on. When a user sends a message, the AI Agent searches the vector database for relevant content and responds. If it cannot help, it offers to escalate to your support team via Gmail.\n\nThe two parts share the same embedding model (Mistral codestral-embed-2505). This is intentional \u2014 the model used to index content must be identical to the model used to search it."
},
"typeVersion": 1
},
{
"id": "a62b8c0c-762d-43d2-8c5d-4e726c939dae",
"name": "Indexing Pipeline",
"type": "n8n-nodes-base.stickyNote",
"position": [
3216,
1840
],
"parameters": {
"color": 3,
"width": 2552,
"height": 1348,
"content": "## Part 1 \u2014 Indexing Pipeline\n\n**set urls to scrape**\nThis is where you define which root domains to crawl. Replace the placeholder URLs with your own.\n\nImportant: the comment at the top of this node (`// used: none`) is a manual tracking system. Each time you successfully index a URL, add it to the used list. This prevents you from accidentally re-indexing the same URL on a future run. Re-indexing the same URL will not overwrite existing data \u2014 it will create duplicates in your vector store, which degrades retrieval quality.\n\n**Map Site**\nFirecrawl maps every link across the domain (including subdomains) without scraping content yet. This gives you a full list of URLs to work with before spending any scraping credits.\n\n**Remove Duplicates**\nMultiple root domains can return overlapping links. This node deduplicates the full URL list before scraping begins so no page is scraped twice in a single run.\n\n**Loop + Single Scrape**\nEach unique URL is scraped one at a time. Firecrawl returns clean markdown \u2014 no HTML noise, no scripts. The retry setting is on because large sites can occasionally time out on individual pages.\n\n**remove irrelevant params**\nStrips the scrape response down to just the content needed for embedding.\n\n**Text Splitter > Data Loader > Embeddings > Qdrant**\nThe markdown is split into overlapping chunks (1000 characters, 200 overlap). The overlap ensures sentences that fall on a chunk boundary are not lost \u2014 they appear in both the chunk before and after. Each chunk is embedded and inserted into Qdrant in batches of 100.\n\n**Wait**\nA 1-second pause between each page scrape and the next loop iteration. This prevents hitting Firecrawl and Mistral API rate limits when indexing large sites."
},
"typeVersion": 1
},
{
"id": "30889c2f-5abf-4c6d-977d-f07bd6deff88",
"name": "AI Chatbot",
"type": "n8n-nodes-base.stickyNote",
"position": [
3232,
176
],
"parameters": {
"color": 5,
"width": 1876,
"height": 1220,
"content": "## Part 2 \u2014 AI Chatbot\n\n**When chat message received**\nThe public chat trigger. Once the workflow is active, this generates a shareable URL you can embed directly on your website.\n\n**AI Agent + GPT-4o-mini**\nThe brain of the chatbot. GPT-4o-mini was chosen for its balance of speed and cost. It holds a 10-message memory window so users can have a natural back-and-forth conversation without repeating themselves.\n\n**Qdrant Vector Store (retrieve-as-tool)**\nThe agent uses this as a tool, not a fixed pipeline step. That means it only searches the vector store when the question actually requires it. It retrieves the top 3 most relevant chunks per query \u2014 enough context without overloading the model.\n\n**Embeddings Mistral Cloud (retrieval)**\nThis must be the same model used during indexing. When a user asks a question, this node converts the question into a vector using the same embedding space as the stored content. If the models do not match, search results will be meaningless.\n\n**Gmail Tool**\nWhen the agent cannot resolve an issue, it offers to escalate to human support. The agent collects the user's email, writes a summary, confirms with the user, then sends it. Replace the sendTo address with your actual support inbox before going live."
},
"typeVersion": 1
},
{
"id": "94279abf-c1ec-4160-b761-c16b1fc6e6dc",
"name": "Why It Was Built This Way",
"type": "n8n-nodes-base.stickyNote",
"position": [
5856,
1856
],
"parameters": {
"color": 2,
"width": 1172,
"height": 356,
"content": "## Why It Was Built This Way\n\n**Map then scrape, not crawl**\nFirecrawl's map operation returns every URL on a domain in seconds without fetching any content. This means you know exactly what you are indexing before spending a single scraping credit. A direct crawl would scrape and discover at the same time, giving you less control and more wasted calls on irrelevant pages.\n\n**Two separate loops**\nThe outer loop iterates over root domains (e.g. your main site and blog). The inner loop iterates over every discovered URL within each domain. This separation means you can add new domains to the list at any time without changing how the scraping logic works.\n\n**Wait node**\nEmbedding and inserting happen inside the loop deliberately \u2014 this means each page is processed and saved before moving to the next. The Wait node adds a small pause between iterations to prevent hitting Firecrawl and Mistral API rate limits on large sites.\n\n**Same embedding model in both pipelines**\nMistral codestral-embed-2505 is used for both indexing and retrieval. This is not optional \u2014 it is a hard requirement. Vector search works by comparing numbers in the same mathematical space. If you index with one model and retrieve with another, the numbers are incomparable and search breaks completely. If you ever change the embedding model, you must delete the Qdrant collection, recreate it with the correct dimensions, and re-index everything from scratch."
},
"typeVersion": 1
},
{
"id": "03e2ad7d-aca2-4b89-9787-19d88f2c1787",
"name": "What You Can Tweak",
"type": "n8n-nodes-base.stickyNote",
"position": [
1984,
2224
],
"parameters": {
"width": 500,
"height": 896,
"content": "## What You Can Tweak\n\n**Swap the chat model**\nGPT-4o-mini is fast and affordable. You can replace it with Gemini 2.5 Flash Lite, Mistral Small, or any model supported by n8n's LangChain nodes. Groq-hosted models are a good option if you need sub-second response times.\n\n**Change the embedding model**\nIf you switch to a different embedding model, you must also update the Qdrant collection dimensions to match. Delete the existing collection, recreate it with the correct dimensions, and re-run the indexing pipeline. Both embedding nodes (indexing and retrieval) must always use the same model.\n\n**Add more URLs**\nOpen the \"set urls to scrape\" Code node and add more objects to the array. Remember to update the used comment to track what you have already indexed.\n\n**Adjust chunk size**\nThe Recursive Character Text Splitter defaults to 1000 characters with 200 overlap. Increase chunk size for dense, long-form content. Decrease it for short pages where precision matters more than context.\n\n**Change retrieval depth**\nThe Qdrant retrieve-as-tool node defaults to 3 results per query. Increase this if answers feel incomplete. Decrease it to speed up responses.\n\n**Replace Gmail with another tool**\nThe escalation tool can be swapped for any messaging or ticketing service supported by n8n \u2014 Slack, Zendesk, Intercom, or a simple webhook.\n\n**Adapt the system prompt**\nThe AI Agent's system prompt is written for a collectibles platform. Replace the identity, tone, and escalation instructions with whatever fits your website and audience."
},
"typeVersion": 1
},
{
"id": "f1a66dab-834a-4876-8ad7-2343b6fed385",
"name": "Why It Was Built This Way1",
"type": "n8n-nodes-base.stickyNote",
"position": [
5168,
176
],
"parameters": {
"color": 2,
"width": 1172,
"height": 228,
"content": "## Why It Was Built This Way\n\n**Qdrant as a tool, not a fixed step**\nAttaching Qdrant as an AI tool rather than a node in the main pipeline lets the agent decide when a search is actually needed. This makes responses faster for questions the model can answer directly, and more accurate for questions that genuinely require looking something up.\n\n**Make Chat Publicly Available**\nNotice it has 'Make Chat Publicly Available' toggled on because we are going to be using this chat bot on a website. you will find the details in the docs in the same node but this is the link again, for convenience: https://www.npmjs.com/package/@n8n/chat"
},
"typeVersion": 1
},
{
"id": "9dc6b2d0-ef05-4fc8-a65c-bc20e5f39970",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
3376,
2560
],
"parameters": {
"height": 448,
"content": "## Set Your URLs Here\n\nAdd your root domains here before running.\n\nThe comment at the top tracks which URLs you have already indexed. Update it after each successful run. If you index the same URL twice, it will not overwrite \u2014 it will create duplicate data in your vector store and hurt retrieval quality."
},
"typeVersion": 1
},
{
"id": "ce3231f8-5fbf-49ae-ad2a-a26536965815",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
5872,
2416
],
"parameters": {
"width": 1184,
"height": 176,
"content": "## Why Are There Two Qdrant Nodes?\n\nThese two nodes do different jobs.\n\nThe one in the indexing pipeline (bottom) writes data into Qdrant during indexing. The one connected to the AI Agent (top) reads from Qdrant at query time and acts as a search tool.\n\nBoth must use the same embedding model and the same collection name or search will return meaningless results."
},
"typeVersion": 1
},
{
"id": "a5e07df2-d252-4b37-aa78-fe00d8e72ed6",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
5232,
2224
],
"parameters": {
"height": 464,
"content": "## Why Is There a Wait Node?\n\nThis pause exists to protect you from API rate limits.\n\nWhen indexing a large site, requests to Firecrawl and Mistral stack up fast. Without this delay, you will start seeing failed or empty responses mid-run. If your site is small (under 50 pages) you can reduce or remove this. For large sites, keep it or increase it."
},
"typeVersion": 1
},
{
"id": "cb2ff712-b93a-40a8-a38f-5c8f03520215",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
4176,
592
],
"parameters": {
"width": 336,
"height": 480,
"content": "## Adapt This to Your Website\n\nThe AI Agent's system prompt is currently written for a collectibles platform. Before going live, update it to match your own website and audience.\n\nFind the AI Agent node and replace:\n- The assistant name and website description in the Identity section\n- Any platform-specific language throughout\n- The tone and escalation instructions to match your brand\n\nThe structure of the prompt is solid \u2014 you are just swapping out the context."
},
"typeVersion": 1
}
],
"connections": {
"Wait": {
"main": [
[
{
"node": "Loop Over Items1",
"type": "main",
"index": 0
}
]
]
},
"Map Site": {
"main": [
[
{
"node": "Split Out links",
"type": "main",
"index": 0
}
]
]
},
"Run Indexing": {
"main": [
[
{
"node": "set urls to scrape",
"type": "main",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "AI Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"Single Scrape": {
"main": [
[
{
"node": "remove irrelevant params",
"type": "main",
"index": 0
}
]
]
},
"Loop Over urls": {
"main": [
[
{
"node": "Remove Duplicates",
"type": "main",
"index": 0
}
],
[
{
"node": "Map Site",
"type": "main",
"index": 0
}
]
]
},
"Split Out links": {
"main": [
[
{
"node": "extract only urls",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items1": {
"main": [
[],
[
{
"node": "Single Scrape",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Remove Duplicates": {
"main": [
[
{
"node": "Loop Over Items1",
"type": "main",
"index": 0
}
]
]
},
"extract only urls": {
"main": [
[
{
"node": "Loop Over urls",
"type": "main",
"index": 0
}
]
]
},
"set urls to scrape": {
"main": [
[
{
"node": "Loop Over urls",
"type": "main",
"index": 0
}
]
]
},
"Default Data Loader": {
"ai_document": [
[
{
"node": "Qdrant Vector Store",
"type": "ai_document",
"index": 0
}
]
]
},
"Qdrant Vector Store": {
"main": [
[
{
"node": "Wait",
"type": "main",
"index": 0
}
]
]
},
"Qdrant Vector Store1": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Send a message in Gmail": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Embeddings Mistral Cloud": {
"ai_embedding": [
[
{
"node": "Qdrant Vector Store",
"type": "ai_embedding",
"index": 0
}
]
]
},
"remove irrelevant params": {
"main": [
[
{
"node": "Qdrant Vector Store",
"type": "main",
"index": 0
}
]
]
},
"Embeddings Mistral Cloud1": {
"ai_embedding": [
[
{
"node": "Qdrant Vector Store1",
"type": "ai_embedding",
"index": 0
}
]
]
},
"When chat message received": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Recursive Character Text Splitter": {
"ai_textSplitter": [
[
{
"node": "Default Data Loader",
"type": "ai_textSplitter",
"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.
qdrantApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Build a fully functional AI chatbot for any website using Retrieval-Augmented Generation (RAG). This workflow automatically crawls and indexes your entire site into a Qdrant vector database, then powers a conversational chatbot that searches your content to answer user questions…
Source: https://n8n.io/workflows/15415/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
• Create a Google Drive folder to watch. • Connect your Google Drive account in n8n and authorize access. • Point the Google Drive Trigger node to this folder (new/modified files trigger the flow).
⚡AI-Powered YouTube Playlist & Video Summarization and Analysis v2. Uses lmChatGoogleGemini, agent, splitOut, chainLlm. Chat trigger; 72 nodes.
This n8n workflow transforms entire YouTube playlists or single videos into interactive knowledge bases you can chat with. Ask questions and get summaries without needing to watch hours of content. 🔗
Advanced Ai Demo Presented At Ai Developers 14 Meetup. Uses slack, stickyNote, textSplitterRecursiveCharacterTextSplitter, embeddingsOpenAi. Chat trigger; 39 nodes.
Advanced Ai Demo (Presented At Ai Developers #14 Meetup). Uses slack, stickyNote, textSplitterRecursiveCharacterTextSplitter, embeddingsOpenAi. Chat trigger; 39 nodes.