{
  "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
          }
        ]
      ]
    }
  }
}