This workflow corresponds to n8n.io template #13864 — 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": "",
"name": "When chat message received",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
2272,
-544
],
"parameters": {
"options": {}
},
"typeVersion": 1.4
},
{
"id": "eba8a2e5-9860-4f58-a5db-51c48f80eca2",
"name": "Normalize",
"type": "n8n-nodes-base.set",
"position": [
2512,
-544
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "563b3849-b286-4eb2-8c2c-5e4fb75c9a10",
"name": "message",
"type": "string",
"value": "={{ $json.chatInput }}"
},
{
"id": "8b4f1194-7976-426a-b81a-ce77b9a391ed",
"name": "phone_number",
"type": "string",
"value": "YOUR_PHONE_NUMBER"
},
{
"id": "1e5a7844-a48d-4017-8b3b-d931af534088",
"name": "session_id",
"type": "string",
"value": "={{ $json.sessionId }}"
},
{
"id": "f0de03eb-540d-47d8-ad55-d77599d1b330",
"name": "10_days_from_now",
"type": "string",
"value": "={{ $now.plus({ days: 10 }).toFormat('yyyy-MM-dd') }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "34b16c60-0b60-4b4e-a62a-504f3d3922e6",
"name": "Update event",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
3216,
-208
],
"parameters": {
"eventId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Event_ID', `The unique ID string from the search result (e.g., 5qasn...)`, 'string') }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "Calendario del Agente de Turnos"
},
"operation": "update",
"updateFields": {
"end": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('End', `The new end date and time. This should be exactly 30 minutes after the start time.`, 'string') }}",
"start": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start', `The new start date and time for the appointment in ISO 8601 format (e.g., 2026-02-17T16:00:00).`, 'string') }}"
},
"descriptionType": "manual",
"toolDescription": "When updating, always provide an end time 30 minutes after the start time unless specified otherwise."
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "f36c8bec-06bb-4dd3-88fb-cbbe349ba666",
"name": "Delete event",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
3344,
-208
],
"parameters": {
"eventId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Event_ID', `The unique ID string from the search result (e.g., 5qasn...)`, 'string') }}",
"options": {},
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "Calendario del Agente de Turnos"
},
"operation": "delete"
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "82866b61-d6b1-4775-87b2-482004963868",
"name": "Create event",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
3088,
-208
],
"parameters": {
"end": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('End', ``, 'string') }}",
"start": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start', ``, 'string') }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "Calendario del Agente de Turnos"
},
"descriptionType": "manual",
"toolDescription": "Use this tool to create an event - Add the user's name and pet name as the title for each event.",
"additionalFields": {
"summary": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Summary', `Title: User's full name - Pet's name`, 'string') }}",
"description": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Description', ``, 'string') }}"
}
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "888d1e0f-53b7-43f8-bda1-2b1d9ce9e74e",
"name": "Simple Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
2576,
-192
],
"parameters": {
"sessionKey": "={{ $json.session_id }}",
"sessionIdType": "customKey",
"contextWindowLength": 10
},
"typeVersion": 1.3
},
{
"id": "051ec537-9d2d-4253-8844-cd255439d822",
"name": "OpenRouter Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
2240,
-192
],
"parameters": {
"model": "openai/gpt-4o",
"options": {}
},
"credentials": {
"openRouterApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "756c9aae-094b-441e-a627-5742132c1a81",
"name": "Get events",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
2976,
-208
],
"parameters": {
"options": {
"timeZone": {
"__rl": true,
"mode": "list",
"value": "Europe/Madrid",
"cachedResultName": "Europe/Madrid"
}
},
"timeMax": "={{ $json['10_days_from_now'] }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "user@example.com",
"cachedResultName": "Calendario del Agente de Turnos"
},
"operation": "getAll",
"returnAll": true,
"descriptionType": "manual",
"toolDescription": "=Use this tool to see if a specific slot is available. If this tool returns data, it means the slot is unavailable/busy. Only look for slots after {{ $now }}."
},
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "1d0a7dcb-d904-47e5-920c-eebe65532027",
"name": "New client?",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
2720,
-208
],
"parameters": {
"options": {},
"filtersUI": {
"values": [
{
"lookupValue": "={{ $('Normalize').item.json.phone_number }}",
"lookupColumn": "Tel\u00e9fono"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEETS_ID/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "YOUR_GOOGLE_SHEETS_ID",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEETS_ID/edit?usp=drivesdk",
"cachedResultName": "Clientes_Veterinaria"
},
"descriptionType": "manual",
"toolDescription": "Get row(s) in sheet in Google Sheets"
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "da321299-e79a-4ea8-8b47-fe38ca5cfd48",
"name": "Mar\u00eda",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
2736,
-544
],
"parameters": {
"text": "={{ $json.message }}",
"options": {
"systemMessage": "=# OVERVIEW\nYou are Mar\u00eda from \"Patitas Felices\", a virtual assistant. Your priority is to call the correct tools.\n\n# TOOLS\n- New client? - Use this tool to check if the client exists in the system\n- Add client - Use this tool to add the client details to the system\n- Get events - Use this tool to search for events or available slots in the calendar\n- Create event - Use this tool to create a new event (check chat_history for user's details)\n- Update event - Use this tool if there's an existing event that needs to be rescheduled\n- Delete event - Use this tool if there's a existing event that needs to be cancelled/deleted\n- Send a message in Gmail - Use this tool if the user is requesting anything else other than booking, rescheduling, or cancelling an appointment.\n\n# TASKS:\n1- Identify the user (mandatory every time)\n2- Check for existing appointments\n3- Book, reschedule, or delete events\n\n# INSTRUCTIONS FOR EACH TASK\n\n## IDENTIFY USER\n1. **ALWAYS** call `New client?` first to identify the user\n - If the user doesn't exist yet, ask for their full name, and pet's name and type, and then call `Add client`. Check on chat_history if the user has already provided any of those items before asking.\n - If the user exists you can continue to step 2 (Check for existing appointments)\n\n## BOOKING INSTRUCTIONS:\n- **Always** call `Get events` before replying. Send the first 2 or 3 **available** slots to the user.\n- If the user is unavailable on those slot suggestions, provide 2-3 more available slots.\n- Once the user agrees to a specific slot, call `Create event`.\n- Confirm the date/time to the user.\n\n\n## RESCHEDULE INSTRUCTIONS:\n- Call `Get events`, and search the meeting titles until you find the user's existing booking (using the user's full name and pet name). **NEVER** skip this step. If the user is rescheduling, you **must** find the user's existing meeting. The user might provide the wrong time/day, you need to find the correct information each time.\n- Based on the information from `Get events`, provide 2-3 different slots to the user. **You must provide slots that are free/available ONLY**.\n- Once the user confirms a new day/time, call `Update event` and make the changes to the date/time. **Make sure to update the correct event, double check the title to make sure it contains the user and pet names**\n\n## CANCEL/DELETE INSTRUCTIONS:\n- **DO NOT** reply to the user before calling `Get events`.\n- Call `Get events`, search for the user's existing slot using the user's full name and pet name, and once you find it call `Delete event`. Delete **ONLY** the user's existing meeting. If there's more than one, ask the user to confirm which one you need to delete.\n\n\n## OTHER REQUESTS INSTRUCTION:\n- If the user is asking for a different request (other than booking, rescheduling or cancel/deleting appointments), let them know you will inform the team, and that they will reach out soon. Don't ask them if they want you to notify the team - **always** use the `Send a message in Gmail` tool to let the team know.\n\n\n# DATE LOGIC\n- Today is {{ $now.toFormat('EEEE, MMMM d, yyyy') }} at {{ $now.toFormat('HH:mm') }}.\n- If the user asks for a day of the week (e.g., \"Thursday\"):\n 1. Calculate the specific date based on Today.\n 2. If today is Wednesday Feb 18, \"Thursday\" MUST be Feb 19.\n 3. Confirm the date (YYYY-MM-DD) before calling the `Create event` tool.\n\n## Additional info\n- Veterinary doctor's name is Doctor Doolittle.\n- Veterinary clinic address is Calle de los animales #1533\n\n\n# Examples:\n1.\nInput: Hola, tengo un turno ahora en un rato pero no llego. Me lo cambiarias para la tarde, a las 4 quizas?\nOutput: Hola Luc\u00eda, no hay problema. El turno de las 16 hs ya est\u00e1 ocupado, pero te puedo ofrecer cambiarlo a las 16:30 o a las 17:00. \u00bfQu\u00e9 horario te viene mejor?\n\n2.\nOutput when an appointment has been changed: Hecho! Tu cita ya est\u00e1 cambiada para hoy a las 17:00. Nos vemos en un rato!\n\n3.\nInput: hola, necesito un turno\nOutput: Hola, soy Mar\u00eda de Patitas Felices. \u00a1Encantada! No te encuentro en el sistema, pero no te preocupes, te registro en un segundo. \u00bfMe podr\u00edas decir tu nombre completo y contarme un poco de tu mascota: c\u00f3mo se llama y qu\u00e9 animalito es?\nInput: claro, soy Antonella Diaz y mi caracol se llama Pepito\nOutput: Genial, ya est\u00e1s agendada! Tengo algunos turnos libres para hoy: 11:30, 12:00 o 12:30. \u00bfCu\u00e1l prefieres? Y para ir preparandonos, \u00bfqu\u00e9 le anda pasando a Pepito?\n\n4.\nInput: Hola, necesito un turno\nOutput: Hola [user's name], \u00bfc\u00f3mo est\u00e1s? Tengo algunos turnos libres para hoy: [Available slots]. \u00bfCu\u00e1l prefieres? Y para ir prepar\u00e1ndonos, \u00bfqu\u00e9 le anda pasando a [nombre de la mascota]?\n\n5.\nOutput: \u00a1Hecho! Tu cita para el chequeo anual de Muni est\u00e1 confirmada para hoy a las 10:30. Nos vemos pronto. \ud83d\udc36 Si tienes alguna otra pregunta o necesitas algo m\u00e1s, aqu\u00ed estoy para ayudarte.\nInput: Gracias!\nOutput: \u00a1Encantada, nos vemos pronto!\n\n6.\nInput: Hola, tengo una cita hoy a las 15 que me gustaria cambiar\n\nOutput: Hola [user's name], he encontrado tu cita pero no es hoy a las 15:00, est\u00e1 agendada a las 12:30. \u00bfLa cambiamos igual? \u00bfQu\u00e9 d\u00eda te viene mejor?"
},
"promptType": "define",
"needsFallback": true
},
"retryOnFail": true,
"typeVersion": 3.1
},
{
"id": "e02fc04c-1440-4494-b85c-c4cceb2e0409",
"name": "Add client",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
2848,
-208
],
"parameters": {
"columns": {
"value": {
"Cliente": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Cliente', ``, 'string') }}",
"Tel\u00e9fono": "={{ $('Normalize').item.json.phone_number }}",
"Tipo de animal": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Tipo_de_animal', ``, 'string') }}",
"Nombre de la mascota": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Nombre_de_la_mascota', ``, 'string') }}"
},
"schema": [
{
"id": "Cliente",
"type": "string",
"display": true,
"required": false,
"displayName": "Cliente",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Nombre de la mascota",
"type": "string",
"display": true,
"required": false,
"displayName": "Nombre de la mascota",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Tipo de animal",
"type": "string",
"display": true,
"required": false,
"displayName": "Tipo de animal",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Raza",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Raza",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Tel\u00e9fono",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Tel\u00e9fono",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Tel\u00e9fono"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEETS_ID/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "YOUR_GOOGLE_SHEETS_ID",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEETS_ID/edit?usp=drivesdk",
"cachedResultName": "Clientes_Veterinaria"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "3894a194-40c3-430d-9f94-b6ca86ffdc2d",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
2416,
-192
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-5-mini"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "7341ca34-fe9d-497f-852f-3812f37bc524",
"name": "Send a message in Gmail",
"type": "n8n-nodes-base.gmailTool",
"position": [
3488,
-208
],
"parameters": {
"sendTo": "user@example.com",
"message": "=Hola,<br><br>\n\nHay una consulta en el chat que necesita tu respuesta cuanto antes!<br><br>\n\nTel\u00e9fono: {{ $json.phone_number }}<br>\nMensaje: {{ $json.message }}<br><br>\n\nSaludos,<br>\nMar\u00eda",
"options": {
"appendAttribution": false
},
"subject": "Importante! Hay un chat que necesita respuesta!!",
"descriptionType": "manual",
"toolDescription": "Use this tool to send a message and notify the team when a user asks for something different than booking, rescheduling or canceling an appointment."
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "3cfb165e-b9c9-4ea8-a056-e806891aeab4",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
1936,
-992
],
"parameters": {
"color": 7,
"width": 592,
"height": 208,
"content": "## AI Appointment Agent (Maria) \u2013 Vet Clinic Demo (Spanish speaking)\nPURPOSE: Autonomous booking, rescheduling, and lead capture via n8n Chat.\nMODELS: GPT-4o (Primary) + GPT-4o-mini/GPT-5-mini (Fallback) via OpenRouter."
},
"typeVersion": 1
},
{
"id": "33c9074f-e965-41bd-bfb3-12ab34b9cb4c",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
2192,
-624
],
"parameters": {
"width": 464,
"height": 240,
"content": "## DATA INGESTION"
},
"typeVersion": 1
},
{
"id": "dcc0a661-6e45-4d1a-88fe-0b0e6a4e9b01",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
2704,
-624
],
"parameters": {
"color": 6,
"width": 352,
"height": 240,
"content": "## AI ORCHESTRATION"
},
"typeVersion": 1
},
{
"id": "9998ea35-831c-440c-a431-8d79c5db5cde",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
2192,
-256
],
"parameters": {
"color": 6,
"width": 496,
"height": 304,
"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## AI ORCHESTRATION"
},
"typeVersion": 1
},
{
"id": "1dd2bb18-62ec-4759-bb54-dd3d65ddc502",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2704,
-256
],
"parameters": {
"color": 4,
"width": 256,
"height": 304,
"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## CLIENT DATABASE"
},
"typeVersion": 1
},
{
"id": "f6f01bde-318e-4f18-85f9-102462d9df8e",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
2976,
-256
],
"parameters": {
"color": 3,
"width": 464,
"height": 304,
"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## APPOINTMENT MANAGEMENT"
},
"typeVersion": 1
},
{
"id": "0d121dcf-b76f-41a7-b2a6-e3723d14b4d9",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
3456,
-256
],
"parameters": {
"color": 5,
"width": 352,
"height": 304,
"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## ESCALATION & FEEDBACK"
},
"typeVersion": 1
},
{
"id": "ffb12d17-7d33-4187-8e98-f849d1a0fa6d",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
1440,
-736
],
"parameters": {
"color": 7,
"width": 592,
"height": 800,
"content": "## \ud83d\udee0\ufe0f SETUP & CONFIGURATION (READ FIRST)\n\n1. PREREQUISITES:\n\nCredentials: You will need to connect your Google Sheets, Google Calendar, and Gmail accounts.\n\nAPI Key: An OpenRouter API Key is required for the AI Agent (Maria).\n\n2. GOOGLE SHEETS SETUP:\n\nCreate a sheet named Clientes_Veterinaria with the following columns:\n\nCliente, Nombre de la mascota, Tipo de animal, Tel\u00e9fono\n\nUpdate the Google Sheets Nodes in this workflow to point to your specific Spreadsheet ID.\n\n3. GOOGLE CALENDAR SETUP:\n\nEnsure your n8n Timezone (in Workflow Settings) matches your Google Calendar timezone to avoid booking errors.\n\nConnect the Calendar Nodes to your primary business calendar.\n\n4. AI AGENT CONFIGURATION:\n\nPrimary Model: GPT-4o (configured in the OpenRouter node).\n\nMemory: The Window Buffer Memory is preset to 10 interactions to maintain context without exceeding token limits.\n\n5. TESTING:\n\nOpen the n8n Chat window on the bottom right.\n\nType: \"Hi, I want to book an appointment for my cat next Tuesday at 10 AM.\"\n\nVerify that Maria checks the sheet, adds you if you're new, and creates the calendar event."
},
"typeVersion": 1
},
{
"id": "27b45ecc-d59b-4056-9ef3-c7d5210878a3",
"name": "Workflow Error Handler",
"type": "n8n-nodes-base.errorTrigger",
"position": [
2192,
288
],
"parameters": {},
"typeVersion": 1
},
{
"id": "ab9d91b8-1e16-4b71-8f4d-94e2ac176804",
"name": "Notify: Workflow Error",
"type": "n8n-nodes-base.gmail",
"position": [
2416,
288
],
"parameters": {
"sendTo": "user@example.com",
"message": "=<h2>\ud83d\udd34 Workflow Error</h2><p>The LinkedIn PDF \u2192 JobAdder Sync workflow encountered an error:</p><pre style='background:#f5f5f5;padding:12px'>{{ $json.execution.error.message }}</pre><p><strong>Last node:</strong> {{ $json.execution.lastNodeExecuted }}</p><hr><em>Check your n8n execution log for full details.</em>",
"options": {},
"subject": "=\ud83d\udd34 Workflow Error: LinkedIn PDF \u2192 JobAdder Sync"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "8331bde0-f7fe-4858-849d-09674e921ee0",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
2112,
192
],
"parameters": {
"width": 496,
"height": 320,
"content": "## ERROR HANDLER"
},
"typeVersion": 1
}
],
"connections": {
"Mar\u00eda": {
"main": [
[]
]
},
"Normalize": {
"main": [
[
{
"node": "Mar\u00eda",
"type": "main",
"index": 0
}
]
]
},
"Add client": {
"ai_tool": [
[
{
"node": "Mar\u00eda",
"type": "ai_tool",
"index": 0
}
]
]
},
"Get events": {
"ai_tool": [
[
{
"node": "Mar\u00eda",
"type": "ai_tool",
"index": 0
}
]
]
},
"New client?": {
"ai_tool": [
[
{
"node": "Mar\u00eda",
"type": "ai_tool",
"index": 0
}
]
]
},
"Create event": {
"ai_tool": [
[
{
"node": "Mar\u00eda",
"type": "ai_tool",
"index": 0
}
]
]
},
"Delete event": {
"ai_tool": [
[
{
"node": "Mar\u00eda",
"type": "ai_tool",
"index": 0
}
]
]
},
"Update event": {
"ai_tool": [
[
{
"node": "Mar\u00eda",
"type": "ai_tool",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "Mar\u00eda",
"type": "ai_memory",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "Mar\u00eda",
"type": "ai_languageModel",
"index": 1
}
]
]
},
"OpenRouter Chat Model": {
"ai_languageModel": [
[
{
"node": "Mar\u00eda",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Workflow Error Handler": {
"main": [
[
{
"node": "Notify: Workflow Error",
"type": "main",
"index": 0
}
]
]
},
"Send a message in Gmail": {
"ai_tool": [
[
{
"node": "Mar\u00eda",
"type": "ai_tool",
"index": 0
}
]
]
},
"When chat message received": {
"main": [
[
{
"node": "Normalize",
"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.
gmailOAuth2googleCalendarOAuth2ApigoogleSheetsOAuth2ApiopenAiApiopenRouterApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Overview Meet Maria, a sophisticated AI Booking Agent designed for Veterinary Clinics (but easily adaptable to any service business). This workflow transforms a simple chat interface into a full-scale administrative assistant that handles client lookups, lead generation, and…
Source: https://n8n.io/workflows/13864/ — 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.
Think Tool. Uses stickyNote, agent, googleCalendarTool, memoryBufferWindow. Chat trigger; 28 nodes.
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.
Personal Assistant MCP server. Uses chatTrigger, lmChatGoogleGemini, memoryBufferWindow, mcpTrigger. Chat trigger; 20 nodes.
Personal Assistant MCP server. Uses chatTrigger, lmChatGoogleGemini, memoryBufferWindow, mcpTrigger. Chat trigger; 20 nodes.
Wouldn't it be cool to just tell your computer or phone to "schedule a meeting with Sarah next Tuesday at 3 PM" or "find John Doe's email address" and have it actually do it? That's the dream of a per