mirror of
https://github.com/khoaliber/n8nworkflows.xyz.git
synced 2026-04-19 17:14:37 +00:00
1 line
19 KiB
Plaintext
1 line
19 KiB
Plaintext
{"meta":{"instanceId":"YOUR_INSTANCE_ID","templateCredsSetupCompleted":true},"nodes":[{"id":"","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[2272,-544],"webhookId":"","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":{"id":"credential-id","name":"Google Calendar account"}},"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":{"id":"credential-id","name":"Google Calendar account"}},"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":{"id":"credential-id","name":"Google Calendar account"}},"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":{"id":"credential-id","name":"OpenRouter"}},"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":{"id":"credential-id","name":"Google Calendar account"}},"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éfono"}]},"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":{"id":"credential-id","name":"Google Sheets account"}},"typeVersion":4.7},{"id":"da321299-e79a-4ea8-8b47-fe38ca5cfd48","name":"María","type":"@n8n/n8n-nodes-langchain.agent","position":[2736,-544],"parameters":{"text":"={{ $json.message }}","options":{"systemMessage":"=# OVERVIEW\nYou are María 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ía, no hay problema. El turno de las 16 hs ya está ocupado, pero te puedo ofrecer cambiarlo a las 16:30 o a las 17:00. ¿Qué horario te viene mejor?\n\n2.\nOutput when an appointment has been changed: Hecho! Tu cita ya está cambiada para hoy a las 17:00. Nos vemos en un rato!\n\n3.\nInput: hola, necesito un turno\nOutput: Hola, soy María de Patitas Felices. ¡Encantada! No te encuentro en el sistema, pero no te preocupes, te registro en un segundo. ¿Me podrías decir tu nombre completo y contarme un poco de tu mascota: cómo se llama y qué animalito es?\nInput: claro, soy Antonella Diaz y mi caracol se llama Pepito\nOutput: Genial, ya estás agendada! Tengo algunos turnos libres para hoy: 11:30, 12:00 o 12:30. ¿Cuál prefieres? Y para ir preparandonos, ¿qué le anda pasando a Pepito?\n\n4.\nInput: Hola, necesito un turno\nOutput: Hola [user's name], ¿cómo estás? Tengo algunos turnos libres para hoy: [Available slots]. ¿Cuál prefieres? Y para ir preparándonos, ¿qué le anda pasando a [nombre de la mascota]?\n\n5.\nOutput: ¡Hecho! Tu cita para el chequeo anual de Muni está confirmada para hoy a las 10:30. Nos vemos pronto. 🐶 Si tienes alguna otra pregunta o necesitas algo más, aquí estoy para ayudarte.\nInput: Gracias!\nOutput: ¡Encantada, 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á agendada a las 12:30. ¿La cambiamos igual? ¿Qué día 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éfono":"={{ $('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éfono","type":"string","display":true,"removed":false,"required":false,"displayName":"Teléfono","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["Teléfono"],"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":{"id":"credential-id","name":"Google Sheets account"}},"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":{"id":"credential-id","name":"OpenAi"}},"typeVersion":1.3},{"id":"7341ca34-fe9d-497f-852f-3812f37bc524","name":"Send a message in Gmail","type":"n8n-nodes-base.gmailTool","position":[3488,-208],"webhookId":"","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éfono: {{ $json.phone_number }}<br>\nMensaje: {{ $json.message }}<br><br>\n\nSaludos,<br>\nMaría","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":{"id":"credential-id","name":"Gmail"}},"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) – 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":"## 🛠️ 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éfono\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],"webhookId":"","parameters":{"sendTo":"user@example.com","message":"=<h2>🔴 Workflow Error</h2><p>The LinkedIn PDF → 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":"=🔴 Workflow Error: LinkedIn PDF → JobAdder Sync"},"credentials":{"gmailOAuth2":{"id":"credential-id","name":"Gmail"}},"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}],"pinData":{},"connections":{"María":{"main":[[]]},"Normalize":{"main":[[{"node":"María","type":"main","index":0}]]},"Add client":{"ai_tool":[[{"node":"María","type":"ai_tool","index":0}]]},"Get events":{"ai_tool":[[{"node":"María","type":"ai_tool","index":0}]]},"New client?":{"ai_tool":[[{"node":"María","type":"ai_tool","index":0}]]},"Create event":{"ai_tool":[[{"node":"María","type":"ai_tool","index":0}]]},"Delete event":{"ai_tool":[[{"node":"María","type":"ai_tool","index":0}]]},"Update event":{"ai_tool":[[{"node":"María","type":"ai_tool","index":0}]]},"Simple Memory":{"ai_memory":[[{"node":"María","type":"ai_memory","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"María","type":"ai_languageModel","index":1}]]},"OpenRouter Chat Model":{"ai_languageModel":[[{"node":"María","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ía","type":"ai_tool","index":0}]]},"When chat message received":{"main":[[{"node":"Normalize","type":"main","index":0}]]}}} |