This workflow corresponds to n8n.io template #10221 — we link there as the canonical source.
This workflow follows the Agent → Google Sheets 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 →
{
"id": "do05AK6BdVAE5AWC",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "AI-Driven Speaker & Session Recommendation Engine",
"tags": [],
"nodes": [
{
"id": "82c1fcd7-57b9-4a6d-b298-82efa2d9327c",
"name": "Webhook Trigger",
"type": "n8n-nodes-base.webhook",
"position": [
-1792,
288
],
"parameters": {
"path": "speaker-recommendations",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2
},
{
"id": "f86fd196-b2fe-4970-bf5c-2e3f23a7fdf0",
"name": "Sticky Note - Webhook",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1856,
-128
],
"parameters": {
"color": 4,
"width": 208,
"height": 728,
"content": "## Webhook Trigger\n\nReceives requests from voice agents or external systems with event requirements and audience preferences.\n\nExpected payload:\n{\n \"eventType\": \"string\",\n \"eventGoals\": \"string\",\n \"audienceSize\": number,\n \"preferredTopics\": []\n}"
},
"typeVersion": 1
},
{
"id": "59e086b3-19bd-4e54-858a-9346171072c6",
"name": "Parse Voice Request",
"type": "n8n-nodes-base.code",
"position": [
-1552,
288
],
"parameters": {
"jsCode": "// Extract and validate webhook payload\nconst payload = $input.first().json.body || $input.first().json;\n\n// Default values if not provided\nconst requestData = {\n eventType: payload.eventType || \"Technology Conference\",\n eventGoals: payload.eventGoals || \"Engaging and innovative sessions\",\n audienceSize: payload.audienceSize || 500,\n preferredTopics: payload.preferredTopics || [\"AI\", \"Cloud Computing\", \"Innovation\"],\n sessionCount: payload.sessionCount || 5,\n requestId: payload.requestId || Date.now().toString(),\n timestamp: new Date().toISOString(),\n source: payload.source || \"voice-agent\"\n};\n\nreturn { json: requestData };"
},
"typeVersion": 2
},
{
"id": "a49e4d7f-dc5a-45d9-beac-693466ceae3c",
"name": "Fetch Speakers Data",
"type": "n8n-nodes-base.googleSheets",
"position": [
-1328,
144
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultName": "Speakers"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "YOUR_SPREADSHEET_ID",
"cachedResultName": "Event Data"
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"name": "<your credential>"
}
},
"typeVersion": 4
},
{
"id": "5758dbac-06ec-4694-abbe-81797aaad24f",
"name": "Sticky Note - Fetch",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1584,
0
],
"parameters": {
"color": 3,
"width": 176,
"height": 592,
"content": "## Fetch Speaker Database\n\nRetrieve speaker profiles, expertise areas, past sessions, ratings, and availability from Google Sheets."
},
"typeVersion": 1
},
{
"id": "9abf905a-74ac-473f-80ee-35c13ba36291",
"name": "Fetch Audience Data",
"type": "n8n-nodes-base.googleSheets",
"position": [
-1328,
432
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=1",
"cachedResultName": "Audience Interests"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "YOUR_SPREADSHEET_ID",
"cachedResultName": "Event Data"
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"name": "<your credential>"
}
},
"typeVersion": 4
},
{
"id": "ecf1cd22-a0b7-432a-9fe1-32a7cefb9da5",
"name": "Aggregate All Data",
"type": "n8n-nodes-base.code",
"position": [
-1104,
288
],
"parameters": {
"jsCode": "// Get data from all previous nodes\nconst requestData = $input.all()[0].json;\nconst speakers = $input.all()[1].json;\nconst audienceData = $input.all()[2].json;\n\n// Combine and structure data for AI analysis\nconst combinedData = {\n request: requestData,\n speakers: Array.isArray(speakers) ? speakers : [speakers],\n audienceInterests: Array.isArray(audienceData) ? audienceData : [audienceData],\n eventDetails: {\n type: requestData.eventType,\n goals: requestData.eventGoals,\n audienceSize: requestData.audienceSize,\n preferredTopics: requestData.preferredTopics,\n sessionCount: requestData.sessionCount\n },\n metadata: {\n requestId: requestData.requestId,\n timestamp: requestData.timestamp,\n source: requestData.source\n }\n};\n\nreturn { json: combinedData };"
},
"typeVersion": 2
},
{
"id": "53436f73-bf40-4cc8-9bab-dfbfb412ad50",
"name": "Sticky Note - Process",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1376,
0
],
"parameters": {
"color": 5,
"width": 384,
"height": 592,
"content": "## Calculate & Analyze\n\nCombine voice request data with speaker profiles and audience insights for comprehensive matching."
},
"typeVersion": 1
},
{
"id": "bdf79855-c196-4638-afd4-3a0b81190c80",
"name": "Sticky Note - AI Analysis",
"type": "n8n-nodes-base.stickyNote",
"position": [
-928,
96
],
"parameters": {
"color": 6,
"width": 320,
"height": 480,
"content": "## AI Optimization Engine\n\nClaude analyzes speaker-audience fit, diversity, and engagement potential to recommend optimal session lineup."
},
"typeVersion": 1
},
{
"id": "53634ee8-bd33-460a-bb51-48807b2f78bb",
"name": "Format for Voice Response",
"type": "n8n-nodes-base.code",
"position": [
-528,
288
],
"parameters": {
"jsCode": "// Parse AI response and format recommendations\nconst aiResponse = $json.text || $json.message || JSON.stringify($json);\nconst requestMetadata = $input.first().json.metadata || {};\n\nlet recommendations;\ntry {\n // Extract JSON from the response\n const jsonMatch = aiResponse.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n recommendations = JSON.parse(jsonMatch[0]);\n } else {\n // Try parsing the entire response\n recommendations = typeof aiResponse === 'string' ? JSON.parse(aiResponse) : aiResponse;\n }\n} catch (error) {\n recommendations = {\n error: \"Error parsing recommendations: \" + error.message,\n rawResponse: aiResponse.substring(0, 500)\n };\n}\n\n// Format for output and voice agent response\nconst formattedOutput = {\n status: \"success\",\n requestId: requestMetadata.requestId || \"unknown\",\n timestamp: new Date().toISOString(),\n source: requestMetadata.source || \"unknown\",\n totalRecommendations: recommendations.recommendations?.length || 0,\n recommendations: recommendations.recommendations || [],\n alternativeSpeakers: recommendations.alternativeSpeakers || [],\n eventOptimization: recommendations.eventOptimizationSuggestions || \"\",\n diversityScore: recommendations.diversityScore || 0,\n topicCoverage: recommendations.topicCoverage || [],\n summary: recommendations.summary || \"Recommendations generated successfully\",\n voiceResponse: generateVoiceResponse(recommendations)\n};\n\nfunction generateVoiceResponse(data) {\n if (!data.recommendations || data.recommendations.length === 0) {\n return \"I apologize, but I couldn't generate speaker recommendations at this time. Please try again.\";\n }\n \n const topSpeaker = data.recommendations[0];\n const speakerCount = data.recommendations.length;\n \n return `I've analyzed your event requirements and found ${speakerCount} excellent speaker matches. ` +\n `My top recommendation is ${topSpeaker.speakerName} for a ${topSpeaker.sessionFormat} on ${topSpeaker.sessionTopic}. ` +\n `This speaker has a match score of ${topSpeaker.matchScore}% and would be perfect because ${topSpeaker.reasoning.substring(0, 150)}. ` +\n `Would you like to hear more details about this speaker or the other ${speakerCount - 1} recommendations?`;\n}\n\nreturn { json: formattedOutput };"
},
"typeVersion": 2
},
{
"id": "89f49fa5-6b35-498e-ada4-7ebe54ca4312",
"name": "Sticky Note - Format",
"type": "n8n-nodes-base.stickyNote",
"position": [
-576,
-16
],
"parameters": {
"color": 3,
"width": 192,
"height": 592,
"content": "## Format Recommendations\n\nStructure AI output for both voice agent responses and system storage with match scores and reasoning."
},
"typeVersion": 1
},
{
"id": "2be490a9-eec1-4b73-aa09-628417ac893c",
"name": "Save to Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
-304,
288
],
"parameters": {
"columns": {
"value": {},
"schema": [],
"mappingMode": "autoMapInputData",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=2",
"cachedResultName": "Recommendations"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "YOUR_SPREADSHEET_ID",
"cachedResultName": "Event Data"
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"name": "<your credential>"
}
},
"typeVersion": 4
},
{
"id": "d95839b4-b4ad-4ecb-a3f1-30653e826eec",
"name": "Sticky Note - Save",
"type": "n8n-nodes-base.stickyNote",
"position": [
-96,
256
],
"parameters": {
"color": 2,
"width": 352,
"height": 400,
"content": "## Update Tracking Sheet\n\nSave recommendation history and analytics to Google Sheets for tracking and reporting."
},
"typeVersion": 1
},
{
"id": "ddfdb838-d4a2-4f7a-b301-a6fdabf04f5d",
"name": "Send Voice Agent Response",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
-304,
96
],
"parameters": {
"options": {
"responseCode": 200,
"responseHeaders": {
"entries": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"respondWith": "json",
"responseBody": "={{ JSON.stringify($json, null, 2) }}"
},
"typeVersion": 1
},
{
"id": "b9a4fd45-b837-4ce5-8113-be8ab9b497b1",
"name": "Sticky Note - Response",
"type": "n8n-nodes-base.stickyNote",
"position": [
-336,
-160
],
"parameters": {
"width": 176,
"height": 784,
"content": "## Voice Agent Response\n\nReturn formatted recommendations to the voice agent with natural language summary and structured data."
},
"typeVersion": 1
},
{
"id": "c35f3ea0-1a0f-4d9b-8765-2ee34f88b4a4",
"name": "Check for Errors",
"type": "n8n-nodes-base.if",
"position": [
-304,
480
],
"parameters": {
"options": {},
"conditions": {
"options": {
"combineOperation": "any"
},
"conditions": [
{
"id": "error-check",
"operator": {
"type": "string",
"operation": "notEmpty"
},
"leftValue": "={{ $json.error }}",
"rightValue": ""
},
{
"id": "empty-check",
"operator": {
"type": "number",
"operation": "equals"
},
"leftValue": "={{ $json.recommendations?.length || 0 }}",
"rightValue": 0
}
]
}
},
"typeVersion": 2
},
{
"id": "7dd590b4-8091-4029-9153-14c17a0da604",
"name": "Format Error Response",
"type": "n8n-nodes-base.code",
"position": [
-80,
480
],
"parameters": {
"jsCode": "// Generate error response for voice agent\nconst errorData = $input.first().json;\n\nconst errorResponse = {\n status: \"error\",\n requestId: errorData.requestId || \"unknown\",\n timestamp: new Date().toISOString(),\n error: errorData.error || \"Unable to generate recommendations\",\n voiceResponse: \"I apologize, but I encountered an issue while generating speaker recommendations. This could be due to insufficient data or a temporary system issue. Please try again or provide more specific event details.\",\n recommendations: [],\n totalRecommendations: 0\n};\n\nreturn { json: errorResponse };"
},
"typeVersion": 2
},
{
"id": "8bf40bc3-6934-4e00-a3be-3c4d58e823e5",
"name": "Send Error Response",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
144,
480
],
"parameters": {
"options": {
"responseCode": 500,
"responseHeaders": {
"entries": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"respondWith": "json",
"responseBody": "={{ JSON.stringify($json, null, 2) }}"
},
"typeVersion": 1
},
{
"id": "3fb741b2-6c6f-4d5e-aa3d-a5857dea1c4d",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-880,
288
],
"parameters": {
"options": {}
},
"typeVersion": 2.2
},
{
"id": "14e6e626-d90b-4ab6-b487-ee4c6d9d50e2",
"name": "Anthropic Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
-1024,
496
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "claude-sonnet-4-20250514",
"cachedResultName": "Claude 4 Sonnet"
},
"options": {}
},
"credentials": {
"anthropicApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "28462451-7f45-407e-a072-dc9ae8d4ac56",
"connections": {
"AI Agent": {
"main": [
[
{
"node": "Format for Voice Response",
"type": "main",
"index": 0
}
]
]
},
"Webhook Trigger": {
"main": [
[
{
"node": "Parse Voice Request",
"type": "main",
"index": 0
}
]
]
},
"Check for Errors": {
"main": [
[
{
"node": "Format Error Response",
"type": "main",
"index": 0
}
]
]
},
"Aggregate All Data": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Fetch Audience Data": {
"main": [
[
{
"node": "Aggregate All Data",
"type": "main",
"index": 0
}
]
]
},
"Fetch Speakers Data": {
"main": [
[
{
"node": "Aggregate All Data",
"type": "main",
"index": 0
}
]
]
},
"Parse Voice Request": {
"main": [
[
{
"node": "Fetch Speakers Data",
"type": "main",
"index": 0
},
{
"node": "Fetch Audience Data",
"type": "main",
"index": 0
},
{
"node": "Aggregate All Data",
"type": "main",
"index": 0
}
]
]
},
"Anthropic Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Format Error Response": {
"main": [
[
{
"node": "Send Error Response",
"type": "main",
"index": 0
}
]
]
},
"Format for Voice Response": {
"main": [
[
{
"node": "Send Voice Agent Response",
"type": "main",
"index": 0
},
{
"node": "Save to Google Sheets",
"type": "main",
"index": 0
},
{
"node": "Check for Errors",
"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.
anthropicApigoogleApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Simplify event planning with this automated n8n workflow. Triggered by incoming requests, it fetches speaker and audience data from Google Sheets, analyzes profiles and preferences, and generates optimized session recommendations. The workflow delivers formatted voice responses…
Source: https://n8n.io/workflows/10221/ — 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.
⏺ 🚀 How it works
Fully automates your service order pipeline from incoming booking to supplier confirmation — with built-in SLA enforcement and automatic escalation if a supplier goes silent. 📥 Receives orders via web
Tired of grinding out YouTube content? This n8n workflow turns AI into your personal video factory—creating engaging, faceless shorts on autopilot. Perfect for creators, marketers, or side-hustlers lo
Faceless YouTube Generator. Uses httpRequest, limit, googleDrive, googleSheets. Webhook trigger; 49 nodes.
This workflow turns your WhatsApp Business number into a 24/7 AI-powered customer assistant — without any third-party chatbot platform. It receives incoming WhatsApp messages via Evolution API, unders