This workflow follows the Google Drive → HTTP Request 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 →
{
"name": "Cross-Platform Knowledge Search Tool",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "cross-platform-search",
"responseMode": "responseNode",
"options": {}
},
"id": "cross-platform-search-webhook",
"name": "Cross-Platform Search Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
200,
400
]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "search-query",
"name": "searchQuery",
"value": "={{ $json.body.query || $json.body.searchTerm || '' }}",
"type": "string"
},
{
"id": "target-platforms",
"name": "targetPlatforms",
"value": "={{ $json.body.platforms || ['appflowy', 'affine', 'google_drive', 'vector_db'] }}",
"type": "array"
},
{
"id": "search-mode",
"name": "searchMode",
"value": "={{ $json.body.mode || 'comprehensive' }}",
"type": "string"
},
{
"id": "result-limit-cross",
"name": "resultLimit",
"value": "={{ $json.body.limit || 20 }}",
"type": "number"
},
{
"id": "enable-deduplication",
"name": "enableDeduplication",
"value": "={{ $json.body.enableDeduplication || true }}",
"type": "boolean"
},
{
"id": "priority-sources",
"name": "prioritySources",
"value": "={{ $json.body.prioritySources || [] }}",
"type": "array"
},
{
"id": "search-timestamp",
"name": "timestamp",
"value": "={{ $now }}",
"type": "string"
},
{
"id": "enable-analytics",
"name": "enableAnalytics",
"value": "={{ $json.body.enableAnalytics || true }}",
"type": "boolean"
}
]
},
"options": {}
},
"id": "process-cross-platform-query",
"name": "Process Cross-Platform Query",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
450,
400
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "appflowy-enabled",
"leftValue": "={{ $json.targetPlatforms.includes('appflowy') }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "check-appflowy-enabled",
"name": "Check AppFlowy Enabled",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
700,
200
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "affine-enabled",
"leftValue": "={{ $json.targetPlatforms.includes('affine') }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "check-affine-enabled",
"name": "Check Affine Enabled",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
700,
300
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "vector-db-enabled",
"leftValue": "={{ $json.targetPlatforms.includes('vector_db') }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "check-vector-db-enabled",
"name": "Check Vector DB Enabled",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
700,
400
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "google-drive-enabled",
"leftValue": "={{ $json.targetPlatforms.includes('google_drive') }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "check-google-drive-enabled",
"name": "Check Google Drive Enabled",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
700,
500
]
},
{
"parameters": {
"url": "https://n8n.{{ $vars.domain_name }}/webhook/appflowy-query-tool",
"options": {
"timeout": 30000
},
"sendBody": true,
"contentType": "json",
"body": {
"query": "={{ $('Process Cross-Platform Query').item.json.searchQuery }}",
"queryType": "semantic_search",
"limit": "={{ Math.ceil($('Process Cross-Platform Query').item.json.resultLimit / 4) }}",
"includeMetadata": true
}
},
"id": "query-appflowy",
"name": "Query AppFlowy",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
950,
150
]
},
{
"parameters": {
"url": "https://n8n.{{ $vars.domain_name }}/webhook/affine-query-tool",
"options": {
"timeout": 30000
},
"sendBody": true,
"contentType": "json",
"body": {
"query": "={{ $('Process Cross-Platform Query').item.json.searchQuery }}",
"queryType": "semantic_search",
"limit": "={{ Math.ceil($('Process Cross-Platform Query').item.json.resultLimit / 4) }}",
"includeMetadata": true
}
},
"id": "query-affine",
"name": "Query Affine",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
950,
250
]
},
{
"parameters": {
"code": {
"execute": {
"code": "const { QdrantVectorStore } = require(\"@langchain/qdrant\");\nconst { OllamaEmbeddings } = require(\"@langchain/community/embeddings/ollama\");\n\nconst embeddings = new OllamaEmbeddings({\n model: \"nomic-embed-text\",\n baseUrl: \"http://ollama:11434\"\n});\n\nconst vectorStore = await QdrantVectorStore.fromExistingCollection(\n embeddings,\n {\n url: \"http://qdrant:6333\",\n collectionName: \"knowledge_base\",\n }\n);\n\nconst queryText = this.getInputData()[0].json.searchQuery;\nconst resultLimit = Math.ceil(this.getInputData()[0].json.resultLimit / 4) || 5;\n\n// Comprehensive search across all sources in vector DB\nconst results = await vectorStore.similaritySearch(queryText, resultLimit);\n\n// Format results with enhanced metadata\nconst formattedResults = results.map((doc, index) => ({\n id: `vector_${index}`,\n content: doc.pageContent,\n metadata: {\n ...doc.metadata,\n searchSource: 'vector_database',\n queryMatched: queryText\n },\n source: 'vector_database',\n relevanceScore: doc.score || 0,\n platform: doc.metadata?.source || 'unknown'\n}));\n\nreturn [{ json: { results: formattedResults, searchType: 'vector_search', totalResults: formattedResults.length } }];"
}
},
"inputs": {
"input": [
{
"type": "main",
"required": true
}
]
},
"outputs": {
"output": [
{
"type": "main"
}
]
}
},
"id": "query-vector-database",
"name": "Query Vector Database",
"type": "@n8n/n8n-nodes-langchain.code",
"typeVersion": 1,
"position": [
950,
350
]
},
{
"parameters": {
"authentication": "oAuth2",
"resource": "file",
"operation": "search",
"q": "={{ $('Process Cross-Platform Query').item.json.searchQuery }}",
"options": {
"fields": [
"id",
"name",
"mimeType",
"createdTime",
"modifiedTime",
"size",
"webViewLink"
]
}
},
"id": "query-google-drive",
"name": "Query Google Drive",
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
950,
450
],
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "format-google-drive-results",
"name": "formattedResults",
"value": "={{ $json.files?.map((file, index) => ({\n id: `gdrive_${file.id}`,\n content: `${file.name}\\n\\nFile Type: ${file.mimeType}\\nCreated: ${file.createdTime}\\nModified: ${file.modifiedTime}\\nSize: ${file.size || 'Unknown'} bytes`,\n metadata: {\n source: 'google_drive',\n type: 'file',\n file_id: file.id,\n file_name: file.name,\n mime_type: file.mimeType,\n created_time: file.createdTime,\n modified_time: file.modifiedTime,\n web_view_link: file.webViewLink,\n searchSource: 'google_drive_api'\n },\n source: 'google_drive',\n relevanceScore: 0.8, // Base relevance for Google Drive matches\n platform: 'google_drive'\n})) || [] }}",
"type": "array"
}
]
},
"options": {}
},
"id": "format-google-drive-results",
"name": "Format Google Drive Results",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1200,
450
]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "aggregate-all-results",
"name": "allResults",
"value": "={{ [\n ...($('Query AppFlowy').all().flatMap(item => item.rankedResults || [])),\n ...($('Query Affine').all().flatMap(item => item.rankedResults || [])),\n ...($('Query Vector Database').all().flatMap(item => item.results || [])),\n ...($('Format Google Drive Results').all().flatMap(item => item.formattedResults || []))\n] }}",
"type": "array"
},
{
"id": "platform-summary",
"name": "platformSummary",
"value": "={{ {\n appflowy: ($('Query AppFlowy').all().flatMap(item => item.rankedResults || [])).length,\n affine: ($('Query Affine').all().flatMap(item => item.rankedResults || [])).length,\n vector_database: ($('Query Vector Database').all().flatMap(item => item.results || [])).length,\n google_drive: ($('Format Google Drive Results').all().flatMap(item => item.formattedResults || [])).length\n} }}",
"type": "object"
}
]
},
"options": {}
},
"id": "aggregate-platform-results",
"name": "Aggregate Platform Results",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1450,
400
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "deduplication-enabled",
"leftValue": "={{ $('Process Cross-Platform Query').item.json.enableDeduplication }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "check-deduplication-enabled",
"name": "Check Deduplication Enabled",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1700,
400
]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "deduplicated-results",
"name": "deduplicatedResults",
"value": "={{ (() => {\n const results = $json.allResults;\n const seen = new Set();\n const deduplicated = [];\n \n for (const result of results) {\n // Create a content fingerprint for deduplication\n const contentFingerprint = result.content?.substring(0, 100).toLowerCase().replace(/\\s+/g, ' ').trim();\n const titleFingerprint = result.metadata?.title?.toLowerCase();\n const fingerprint = titleFingerprint || contentFingerprint;\n \n if (fingerprint && !seen.has(fingerprint)) {\n seen.add(fingerprint);\n deduplicated.push({\n ...result,\n deduplicationFingerprint: fingerprint\n });\n }\n }\n \n return deduplicated;\n})() }}",
"type": "array"
}
]
},
"options": {}
},
"id": "perform-deduplication",
"name": "Perform Deduplication",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1950,
300
]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "final-ranked-results",
"name": "finalResults",
"value": "={{ (() => {\n const results = $('Perform Deduplication').all().length > 0 \n ? $('Perform Deduplication').item.json.deduplicatedResults \n : $json.allResults;\n \n const prioritySources = $('Process Cross-Platform Query').item.json.prioritySources;\n const resultLimit = $('Process Cross-Platform Query').item.json.resultLimit;\n \n // Apply priority boosting\n const boostedResults = results.map(result => ({\n ...result,\n finalScore: result.relevanceScore + (prioritySources.includes(result.platform) ? 0.2 : 0)\n }));\n \n // Sort by final score and limit results\n return boostedResults\n .sort((a, b) => b.finalScore - a.finalScore)\n .slice(0, resultLimit);\n})() }}",
"type": "array"
},
{
"id": "search-analytics",
"name": "searchAnalytics",
"value": "={{ {\n queryText: $('Process Cross-Platform Query').item.json.searchQuery,\n searchMode: $('Process Cross-Platform Query').item.json.searchMode,\n platformsSearched: $('Process Cross-Platform Query').item.json.targetPlatforms,\n totalResultsFound: $json.finalResults.length,\n platformBreakdown: $('Aggregate Platform Results').item.json.platformSummary,\n deduplicationEnabled: $('Process Cross-Platform Query').item.json.enableDeduplication,\n prioritySourcesUsed: $('Process Cross-Platform Query').item.json.prioritySources,\n searchTimestamp: $('Process Cross-Platform Query').item.json.timestamp,\n processingTimeMs: $now - $('Process Cross-Platform Query').item.json.timestamp\n} }}",
"type": "object"
}
]
},
"options": {}
},
"id": "finalize-cross-platform-results",
"name": "Finalize Cross-Platform Results",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
2200,
400
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "analytics-enabled",
"leftValue": "={{ $('Process Cross-Platform Query').item.json.enableAnalytics }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "check-analytics-enabled",
"name": "Check Analytics Enabled",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
2450,
400
]
},
{
"parameters": {
"operation": "insert",
"table": {
"__rl": true,
"value": "cross_platform_search_analytics",
"mode": "list"
},
"data": {
"insert": [
{
"column": "query_text",
"value": "={{ $('Finalize Cross-Platform Results').item.json.searchAnalytics.queryText }}"
},
{
"column": "search_mode",
"value": "={{ $('Finalize Cross-Platform Results').item.json.searchAnalytics.searchMode }}"
},
{
"column": "platforms_searched",
"value": "={{ $('Finalize Cross-Platform Results').item.json.searchAnalytics.platformsSearched }}"
},
{
"column": "total_results",
"value": "={{ $('Finalize Cross-Platform Results').item.json.searchAnalytics.totalResultsFound }}"
},
{
"column": "platform_breakdown",
"value": "={{ $('Finalize Cross-Platform Results').item.json.searchAnalytics.platformBreakdown }}"
},
{
"column": "processing_time_ms",
"value": "={{ $('Finalize Cross-Platform Results').item.json.searchAnalytics.processingTimeMs }}"
},
{
"column": "deduplication_enabled",
"value": "={{ $('Finalize Cross-Platform Results').item.json.searchAnalytics.deduplicationEnabled }}"
},
{
"column": "created_at",
"value": "={{ $now }}"
}
]
},
"options": {}
},
"id": "log-cross-platform-analytics",
"name": "Log Cross-Platform Analytics",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
2700,
300
],
"credentials": {
"postgres": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "api-response",
"name": "response",
"value": "={{ {\n results: $('Finalize Cross-Platform Results').item.json.finalResults,\n analytics: $('Finalize Cross-Platform Results').item.json.searchAnalytics,\n metadata: {\n queryProcessed: $('Process Cross-Platform Query').item.json.searchQuery,\n totalPlatforms: $('Process Cross-Platform Query').item.json.targetPlatforms.length,\n resultsReturned: $('Finalize Cross-Platform Results').item.json.finalResults.length,\n timestamp: $now\n }\n} }}",
"type": "object"
}
]
},
"options": {}
},
"id": "prepare-api-response",
"name": "Prepare API Response",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
2950,
400
]
},
{
"parameters": {
"options": {}
},
"id": "respond-to-cross-platform-search",
"name": "Respond to Cross-Platform Search",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [
3200,
400
]
},
{
"parameters": {
"content": "## Cross-Platform Knowledge Search Tool\n\n**Purpose:** Unified search interface across all knowledge management platforms with intelligent result aggregation and deduplication.\n\n**Supported Platforms:**\n- **AppFlowy**: Database rows, pages, and documents\n- **Affine**: Documents, whiteboards, and databases\n- **Vector Database**: Semantic search across all ingested content\n- **Google Drive**: Files, documents, and folders\n\n**Key Features:**\n- **Multi-Platform Search**: Simultaneous search across all enabled platforms\n- **Intelligent Deduplication**: Remove duplicate content across platforms\n- **Priority Sources**: Boost results from specified platforms\n- **Relevance Ranking**: Smart scoring and result prioritization\n- **Analytics**: Comprehensive search performance tracking\n- **Flexible Configuration**: Enable/disable platforms per search\n\n**Search Modes:**\n- `comprehensive`: Search all enabled platforms (default)\n- `semantic_only`: Vector database semantic search only\n- `direct_only`: Platform-specific direct queries only\n- `hybrid`: Combination approach with relevance scoring\n\n**API Parameters:**\n- `query`: Search text/question\n- `platforms`: Array of platforms to search\n- `mode`: Search mode to use\n- `limit`: Maximum total results\n- `enableDeduplication`: Remove duplicate content\n- `prioritySources`: Platforms to prioritize in results\n- `enableAnalytics`: Track search performance\n\n**Response Format:**\n```json\n{\n \"results\": [...],\n \"analytics\": {...},\n \"metadata\": {...}\n}\n```",
"height": 700,
"width": 800,
"color": 6
},
"id": "cross-platform-search-documentation",
"name": "Cross-Platform Search Documentation",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
100,
100
]
}
],
"connections": {
"Cross-Platform Search Webhook": {
"main": [
[
{
"node": "Process Cross-Platform Query",
"type": "main",
"index": 0
}
]
]
},
"Process Cross-Platform Query": {
"main": [
[
{
"node": "Check AppFlowy Enabled",
"type": "main",
"index": 0
},
{
"node": "Check Affine Enabled",
"type": "main",
"index": 0
},
{
"node": "Check Vector DB Enabled",
"type": "main",
"index": 0
},
{
"node": "Check Google Drive Enabled",
"type": "main",
"index": 0
}
]
]
},
"Check AppFlowy Enabled": {
"main": [
[
{
"node": "Query AppFlowy",
"type": "main",
"index": 0
}
]
]
},
"Check Affine Enabled": {
"main": [
[
{
"node": "Query Affine",
"type": "main",
"index": 0
}
]
]
},
"Check Vector DB Enabled": {
"main": [
[
{
"node": "Query Vector Database",
"type": "main",
"index": 0
}
]
]
},
"Check Google Drive Enabled": {
"main": [
[
{
"node": "Query Google Drive",
"type": "main",
"index": 0
}
]
]
},
"Query Google Drive": {
"main": [
[
{
"node": "Format Google Drive Results",
"type": "main",
"index": 0
}
]
]
},
"Format Google Drive Results": {
"main": [
[
{
"node": "Aggregate Platform Results",
"type": "main",
"index": 0
}
]
]
},
"Query AppFlowy": {
"main": [
[
{
"node": "Aggregate Platform Results",
"type": "main",
"index": 0
}
]
]
},
"Query Affine": {
"main": [
[
{
"node": "Aggregate Platform Results",
"type": "main",
"index": 0
}
]
]
},
"Query Vector Database": {
"main": [
[
{
"node": "Aggregate Platform Results",
"type": "main",
"index": 0
}
]
]
},
"Aggregate Platform Results": {
"main": [
[
{
"node": "Check Deduplication Enabled",
"type": "main",
"index": 0
}
]
]
},
"Check Deduplication Enabled": {
"main": [
[
{
"node": "Perform Deduplication",
"type": "main",
"index": 0
}
],
[
{
"node": "Finalize Cross-Platform Results",
"type": "main",
"index": 0
}
]
]
},
"Perform Deduplication": {
"main": [
[
{
"node": "Finalize Cross-Platform Results",
"type": "main",
"index": 0
}
]
]
},
"Finalize Cross-Platform Results": {
"main": [
[
{
"node": "Check Analytics Enabled",
"type": "main",
"index": 0
}
]
]
},
"Check Analytics Enabled": {
"main": [
[
{
"node": "Log Cross-Platform Analytics",
"type": "main",
"index": 0
}
],
[
{
"node": "Prepare API Response",
"type": "main",
"index": 0
}
]
]
},
"Log Cross-Platform Analytics": {
"main": [
[
{
"node": "Prepare API Response",
"type": "main",
"index": 0
}
]
]
},
"Prepare API Response": {
"main": [
[
{
"node": "Respond to Cross-Platform Search",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "cross-platform-search-v1",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "CrossPlatformSearch",
"tags": [
"cross-platform",
"search",
"aggregation",
"deduplication",
"knowledge-management"
]
}
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.
googleDriveOAuth2Apipostgres
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Cross-Platform Knowledge Search Tool. Uses httpRequest, googleDrive, postgres. Webhook trigger; 20 nodes.
Source: https://github.com/161sam/n8n-installer/blob/main/modularium/ai-workspace/Cross-Platform-Search.json — 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.
upload_answer. Uses httpRequest, openAi, googleDrive, googleSheets. Webhook trigger; 27 nodes.
This n8n workflow automates the transformation of spreadsheet data into professional charts and graphs using AI-driven analysis. Triggered via Slack, it processes uploaded files (Excel, CSV, Google Sh
Postgres. Uses openAi, postgres, postgresTool, httpRequest. Webhook trigger; 19 nodes.
Affine Direct Query Tool. Uses httpRequest, postgres. Webhook trigger; 17 nodes.
Crop Planning. Uses postgres, httpRequest, respondToWebhook, googleGemini. Webhook trigger; 11 nodes.