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 →
{
"name": "AI Agent - Lead Capture & Booking",
"nodes": [
{
"parameters": {
"public": true,
"initialMessages": "Hi there! \ud83d\udc4b\nMy name is Nation your AI automation assistant. How can I assist you today?",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"typeVersion": 1.4,
"position": [
-256,
-80
],
"id": "c4a9dfa9-56fb-432b-903c-a07628981f4c",
"name": "When chat message received"
},
{
"parameters": {
"options": {
"systemMessage": "=You are the AI assistant for Insight Analytics, an AI and automation consultancy based in Lusaka, Zambia, serving Zambian SMEs.\n\nYour role:\n- Greet visitors warmly and find out what business problem they're trying to solve (e.g. manual processes, slow customer response, disorganized records, repetitive admin work).\n- Briefly explain how Insight Analytics can help: custom automation workflows, AI-powered tools (like resume screening, invoicing, WhatsApp assistants), and Excel-based systems tailored to their business.\n- Keep responses short and conversational \u2014 this is a WhatsApp-style chat, not an essay. 2-4 sentences per reply unless asked for detail.\n- Use simple, clear language. Avoid technical jargon unless the user demonstrates technical familiarity.\n- If pricing comes up, explain that engagements are retainer-based and mention that a quick call is the best way to scope their specific needs \u2014 don't quote numbers.\n- Always try to capture the lead's name, business name, and the problem they want solved, so it can be logged.\n- If you don't know something specific about current projects or pricing, say a team member will follow up rather than guessing.\n- Stay professional but friendly \u2014 reflect a local, approachable tone rather than a generic corporate one.\n\nNever invent client names, case studies, or pricing figures that haven't been provided to you."
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 3.1,
"position": [
160,
-80
],
"id": "9c7bde19-eccf-459b-8d91-9e3d91ded781",
"name": "AI Agent"
},
{
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-5-mini"
},
"builtInTools": {},
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1.3,
"position": [
-32,
144
],
"id": "58514c5d-6bd1-4c08-9e15-4374a0821054",
"name": "OpenAI Chat Model",
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"contextWindowLength": 20
},
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"typeVersion": 1.4,
"position": [
96,
144
],
"id": "868c9fa6-e5c7-4bc7-8eb8-da36a3de46a2",
"name": "Simple Memory"
},
{
"parameters": {
"description": "use this tool to specify unique data",
"jsCode": "// Code Tool: extract structured lead data from the agent's query\n// Fields: name, email, query, appointment, status, buyer type\n// Input: `query` (string) \u2014 either a JSON string or free/labeled text\n// Output: a single JSON string the agent can read back\n\nfunction extractField(text, labels) {\n for (const label of labels) {\n const regex = new RegExp(label + \"\\\\s*[:\\\\-]\\\\s*([^\\\\n,;]+)\", \"i\");\n const match = text.match(regex);\n if (match) return match[1].trim();\n }\n return null;\n}\n\nlet result;\n\n// Case 1: agent already sent structured JSON\ntry {\n const parsed = JSON.parse(query);\n result = {\n name: parsed.name ?? null,\n email: parsed.email ?? null,\n query: parsed.query ?? null,\n appointment: parsed.appointment ?? null,\n status: parsed.status ?? null,\n buyer_type: parsed.buyer_type ?? parsed.buyerType ?? null,\n };\n} catch (e) {\n // Case 2: fall back to parsing free/labeled text\n const text = query;\n\n const emailMatch = text.match(/[\\w.+-]+@[\\w-]+\\.[\\w.-]+/);\n\n result = {\n name: extractField(text, [\"name\"]),\n email: emailMatch ? emailMatch[0] : extractField(text, [\"email\"]),\n query: extractField(text, [\"query\", \"message\", \"inquiry\"]),\n appointment: extractField(text, [\"appointment\", \"appt\", \"date\", \"meeting\"]),\n status: extractField(text, [\"status\"]),\n buyer_type: extractField(text, [\"buyer type\", \"buyer\", \"type\"]),\n };\n}\n\n// Basic validation flags \u2014 helps the agent know what's still missing\nresult.missing_fields = Object.entries(result)\n .filter(([key, val]) => key !== \"missing_fields\" && !val)\n .map(([key]) => key);\n\nreturn JSON.stringify(result);"
},
"type": "@n8n/n8n-nodes-langchain.toolCode",
"typeVersion": 1.3,
"position": [
224,
144
],
"id": "fb9a10f7-946c-45ee-a41f-b2099ef7fcc0",
"name": "Code Tool"
},
{
"parameters": {
"operation": "appendOrUpdate",
"documentId": {
"__rl": true,
"value": "REPLACE_WITH_YOUR_GOOGLE_SHEET_ID",
"mode": "list",
"cachedResultName": "Leads",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/REPLACE_WITH_YOUR_GOOGLE_SHEET_ID/edit"
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "list",
"cachedResultName": "Sheet1",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/REPLACE_WITH_YOUR_GOOGLE_SHEET_ID/edit#gid=0"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"Name": "={{ $fromAI('username') }}",
"Email": "={{ $fromAI('useremailaddress') }}",
"Query ": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Query_', `let the model define the parameters `, 'string') }}",
"Appointment status ": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Appointment_status_', `let the model define the client plan whether to come to the office or schedule the meeting online `, 'string') }}",
"Buyer type ": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Buyer_type_', `let the model analyze their purpose and classify them into serious and unserious buyers \n`, 'string') }}"
},
"matchingColumns": [
"Email"
],
"schema": [
{
"id": "Name",
"displayName": "Name",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Email",
"displayName": "Email",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Query ",
"displayName": "Query ",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Appointment status ",
"displayName": "Appointment status ",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Buyer type ",
"displayName": "Buyer type ",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"type": "n8n-nodes-base.googleSheetsTool",
"typeVersion": 4.7,
"position": [
352,
144
],
"id": "c1ab93e2-bd35-4cfe-80be-674748ffde85",
"name": "Append or update row in sheet in Google Sheets",
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"calendar": {
"__rl": true,
"value": "your-email@example.com",
"mode": "list",
"cachedResultName": "your-email@example.com"
},
"start": "={{ $fromAI('startdate') }}",
"end": "={{ $fromAI('enddate') }}",
"additionalFields": {
"attendees": [
"={{ $fromAI('useremailaddress') }}",
"your-email@example.com"
],
"summary": "={{ $fromAI('summary') }}"
}
},
"type": "n8n-nodes-base.googleCalendarTool",
"typeVersion": 1.3,
"position": [
480,
144
],
"id": "ccf52e00-62e5-406d-a891-94416c82cfcd",
"name": "Create an event in Google Calendar",
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
}
}
],
"connections": {
"When chat message received": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "AI Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"Code Tool": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Append or update row in sheet in Google Sheets": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Create an event in Google Calendar": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
}
},
"meta": {
"templateCredsSetupCompleted": true
}
}
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.
googleCalendarOAuth2ApigoogleSheetsOAuth2ApiopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
AI Agent - Lead Capture & Booking. Uses chatTrigger, agent, lmChatOpenAi, memoryBufferWindow. Chat trigger; 7 nodes.
Source: https://github.com/buseko-Actuary/n8n-ai-chatbot/blob/main/workflow/ai-agent-lead-capture.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.
Reservation Medcin. Uses chatTrigger, agent, lmChatOpenAi, memoryBufferWindow. Chat trigger; 12 nodes.
This workflow template is designed for dental assistants and anyone looking to automate appointment scheduling. It integrates Google Calendar for booking appointments and Google Sheets as a database t
Automate customer conversations with an AI-powered virtual receptionist. This workflow can chat naturally with clients, answer general business questions (like services, location, and hours), check av
Chatbot Appointment Scheduler With Google Calendar for Dental assistant. Uses chatTrigger, agent, lmChatOpenAi, memoryBufferWindow. Chat trigger; 12 nodes.
2a Intelligent AI Assistant DONE. Uses chatTrigger, agent, lmChatOpenAi, memoryBufferWindow. Chat trigger; 8 nodes.