Réceptionniste de cabinet dentaire
Ceci est unSupport Chatbot, Multimodal AIworkflow d'automatisation du domainecontenant 14 nœuds.Utilise principalement des nœuds comme If, Code, Gmail, Webhook, GoogleSheets. Automatisation des rendez-vous dentaires via Google Calendar, un assistant IA et les notifications par e-mail
- •Compte Google et informations d'identification Gmail API
- •Point de terminaison HTTP Webhook (généré automatiquement par n8n)
- •Informations d'identification Google Sheets API
Nœuds utilisés (14)
Catégorie
{
"id": "SAqkCDqXBdN0UN0F",
"meta": {
"instanceId": "a419abc01bb0423bd41f1b0c0b1dc4e0a3c69d0074efa38bd450d30bc82d13ad",
"templateCredsSetupCompleted": true
},
"name": "Dental Clinic Receptionist",
"tags": [],
"nodes": [
{
"id": "6cb4cb42-b5e8-446d-9711-d72649c8b6cc",
"name": "Vérifier la disponibilité",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
624,
928
],
"parameters": {
"options": {},
"timeMax": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('End_Time', ``, 'string') }}",
"timeMin": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start_Time', ``, 'string') }}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "c4a4d22b1eaa9e3b8eb300569a8dc61d2eb88934c04fcb471639cf42ee93f8f5@group.calendar.google.com",
"cachedResultName": "n8n"
},
"resource": "calendar"
},
"credentials": {
"googleCalendarOAuth2Api": {
"id": "l0D9Uok2v5Z8pc4U",
"name": "Google Calendar account"
}
},
"typeVersion": 1.3
},
{
"id": "8b070be5-d1b2-4f02-99a4-6278450b9fe7",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
304,
656
],
"webhookId": "f416ff3e-0410-4538-a3ab-7b52dce5b470",
"parameters": {
"path": "getInput",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2.1
},
{
"id": "69b5f76a-3c63-4e0c-b4cb-d52e7dc57cbf",
"name": "Répondre à Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
912,
656
],
"parameters": {
"options": {}
},
"typeVersion": 1.4
},
{
"id": "b55f6c71-39df-46f8-8439-2f6e3e125466",
"name": "Mémoire tampon de fenêtre",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
400,
912
],
"parameters": {
"sessionKey": "={{ $json.body.chatId }}",
"sessionIdType": "customKey",
"contextWindowLength": 100
},
"typeVersion": 1.3
},
{
"id": "d48200d0-fbf4-4cef-bcd9-f0d9a6b66579",
"name": "Modèle de chat OpenRouter",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
240,
896
],
"parameters": {
"model": "openai/gpt-4o-mini",
"options": {}
},
"credentials": {
"openRouterApi": {
"id": "7pnW2IfzgeEN8qVd",
"name": "OpenRouter account"
}
},
"typeVersion": 1
},
{
"id": "39947ea3-452c-4c93-bdaa-9639a16a574a",
"name": "Agent IA",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
560,
656
],
"parameters": {
"text": "={{ $json.body.query }}",
"options": {
"systemMessage": "=You are a virtual assistant specializing in appointment management for Dr. Hakim. \nYour role is to manage consultations accurately, ensuring real availability while providing a smooth experience for patients.\n\nOffice Hours:\n- Monday – Friday: 9:00 AM – 8:00 PM\n- Saturday: 9:00 AM – 1:00 PM\n- Sunday: Closed\n- Consultation Duration: 1 hour\n- Break Between Patients: 15 minutes\n\nBooking Process:\n1. Collect Patient Information:\n - Full Name\n - Phone Number\n - Email Address\n - Desired Date and Time\n If any information is missing, politely ask the patient before proceeding.\n\n2. Availability Check:\n - Always use the \"Check Availability\" tool to verify free slots in Google Calendar.\n - If requested time overlaps with an existing appointment, suggest the next available slot.\n - Do not create or confirm an appointment until the user explicitly approves the slot.\n\n3. Booking Confirmation:\n - Only create the appointment using the \"Create Event\" tool after explicit user confirmation.\n - Do not say \"appointment booked\" unless the tool is actually used.\n - Appointment ID format: APT-YYYYMMDD-XXXXXX (6 random alphanumeric characters).\n - Event Title: Patient Name - Phone Number\n - Event Description: Include full name, phone, email, appointment ID, date & time.\n\nConfirmation Message Format:\nWhen booking is complete, return only this message:\n✅ Appointment Confirmed:\n- Full Name: {full_name}\n- Phone: {phone}\n- Email: {email}\n- Date: {date}\n- Time: {time}\n- Appointment ID: {appointment_id}\n\nDo NOT include:\n- Calendar event links\n- Extra text after the appointment ID\n- Any confirmation without Create Event tool usage\n\nCancellations:\nIf asked to cancel, reply: \"Please check your booking email. I cannot cancel appointments for you.\"\n\nVerification:\nIf asked to check an appointment by ID, reply: \"Check your email we sent when you booked.\"\n\nTools Available:\n- Check Availability → Verify free slots in Google Calendar\n- Create Event → Book confirmed appointment in Google Calendar\n\nCommunication Rules:\n- Always be polite, clear, and friendly.\n- Never assume missing details—ask for them.\n- Never create or cancel without explicit confirmation.\n- Stick strictly to availability check and booking after confirmation.\n\nToday's Date: {{ $now }}"
},
"promptType": "=define"
},
"typeVersion": 1.7
},
{
"id": "cd82287b-0ea8-4e15-a8da-9e5c4bb7bcb2",
"name": "Code",
"type": "n8n-nodes-base.code",
"position": [
1248,
1024
],
"parameters": {
"jsCode": "// Get the AI Agent output (which is a JSON string)\nconst msg = $input.first().json.output || \"\";\n\nif (!msg) {\n throw new Error(\"AI Agent output not found.\");\n}\n\n// Parse the JSON string\nlet data;\ntry {\n data = JSON.parse(msg);\n} catch (err) {\n throw new Error(\"Failed to parse AI Agent output as JSON: \" + err.message);\n}\n\n// Fallback Appointment ID if missing\nif (!data.appointment_id || data.appointment_id === \"null\") {\n const randomId = Math.random().toString(36).substring(2, 8).toUpperCase();\n data.appointment_id = `APT-${randomId}`;\n}\n\nreturn [{ json: data }];\n"
},
"typeVersion": 2
},
{
"id": "2e634902-e4ce-4362-8ca2-5fa1bb4ebd73",
"name": "Si",
"type": "n8n-nodes-base.if",
"position": [
1456,
1024
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "f1cbfa92-a423-4baf-8ab1-f8cc8ab77038",
"operator": {
"type": "string",
"operation": "notEquals"
},
"leftValue": "={{ $json.patient.full_name }}",
"rightValue": "null"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "cd01ecc0-431a-4c8b-a703-dbcef7075fcd",
"name": "Ajouter une ligne dans la feuille",
"type": "n8n-nodes-base.googleSheets",
"position": [
1152,
1232
],
"parameters": {
"columns": {
"value": {
"Time": "={{ $json.appointment.time }}",
"Date ": "={{ $json.appointment.date }}",
"Email": "={{ $json.patient.email }}",
"Name ": "={{ $json.patient.full_name }}",
"Phone Number": "={{ $json.patient.phone }}",
"Appointment ID": "={{ $json.appointment_id }}"
},
"schema": [
{
"id": "Appointment ID",
"type": "string",
"display": true,
"required": false,
"displayName": "Appointment ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Name ",
"type": "string",
"display": true,
"required": false,
"displayName": "Name ",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Email",
"type": "string",
"display": true,
"required": false,
"displayName": "Email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Phone Number",
"type": "string",
"display": true,
"required": false,
"displayName": "Phone Number",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Date ",
"type": "string",
"display": true,
"required": false,
"displayName": "Date ",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Time",
"type": "string",
"display": true,
"required": false,
"displayName": "Time",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/13HOoBmWcxkL8cUZtWFU1-BSY47v486qkfGCA3gE8PKw/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "13HOoBmWcxkL8cUZtWFU1-BSY47v486qkfGCA3gE8PKw",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/13HOoBmWcxkL8cUZtWFU1-BSY47v486qkfGCA3gE8PKw/edit?usp=drivesdk",
"cachedResultName": "dr"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "5Gf7cbek4NAixfUR",
"name": "Google Sheets account"
}
},
"typeVersion": 4.7
},
{
"id": "ac1a8cc3-7d80-4885-8360-0dce48b2af89",
"name": "Pour le médecin",
"type": "n8n-nodes-base.gmail",
"position": [
1376,
1232
],
"webhookId": "297d8c21-35f3-4a69-ab0f-b7497a7a4d73",
"parameters": {
"sendTo": "mdsabirulislam8089@gmail.com",
"message": "=Hello Dr. Hakim,\nA new appointment has been scheduled. Here are the details: \nPatient Name: {{ $json['Name '] }}\nPhone Number: {{ $json['Phone Number'] }}\nEmail: {{ $json.Email }} \nAppointment Date: {{ $json['Date '] }} \nTime: {{ $json.Time }}\nAppointment ID:{{ $json['Appointment ID'] }} \nPlease check your Google Calendar for more details.",
"options": {
"appendAttribution": false
},
"subject": "New Appointment Scheduled",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"id": "vDrwiQhkGDt03Qyw",
"name": "Gmail account"
}
},
"typeVersion": 2.1
},
{
"id": "88e1c616-7014-4d49-8d32-fe9c77f85d86",
"name": "Pour l'utilisateur",
"type": "n8n-nodes-base.gmail",
"position": [
1632,
1232
],
"webhookId": "79c1900a-988d-400f-9d84-b867f441821f",
"parameters": {
"sendTo": "={{ $('Append row in sheet').item.json.Email }}",
"message": "=Dear {{ $('Append row in sheet').item.json['Name '] }},\nYour appointment with Dr. Hakim has been successfully booked! Here are the details: \nName: {{ $('Append row in sheet').item.json['Name '] }}\nPhone Number: {{ $('Append row in sheet').item.json['Phone Number'] }}\nEmail: {{ $('Append row in sheet').item.json.Email }}\nAppointment Date: {{ $('Append row in sheet').item.json['Date '] }}\nTime: {{ $('Append row in sheet').item.json.Time }}\nAppointment ID:{{ $('Append row in sheet').item.json['Appointment ID'] }}\nPlease keep this Appointment ID for your reference. If you have any questions or need to cancel your appointment, feel free to contact us. \nBest regards, \nDr. Hakim's Clinic",
"options": {
"appendAttribution": false
},
"subject": "Appointment Confirmation – Dr. Hakim",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"id": "vDrwiQhkGDt03Qyw",
"name": "Gmail account"
}
},
"typeVersion": 2.1
},
{
"id": "7eec2403-de34-4163-8984-3c5f6be8070c",
"name": "Créer un événement",
"type": "n8n-nodes-base.googleCalendarTool",
"position": [
832,
912
],
"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": "c4a4d22b1eaa9e3b8eb300569a8dc61d2eb88934c04fcb471639cf42ee93f8f5@group.calendar.google.com",
"cachedResultName": "n8n"
},
"additionalFields": {}
},
"credentials": {
"googleCalendarOAuth2Api": {
"id": "l0D9Uok2v5Z8pc4U",
"name": "Google Calendar account"
}
},
"typeVersion": 1.3
},
{
"id": "ab252537-767c-477d-9a0b-941bd4ed8558",
"name": "Agent IA1",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1168,
656
],
"parameters": {
"text": "={{$input.first().json.output}}",
"options": {
"systemMessage": "You are an Appointment Parsing Agent.\nYour job is to extract appointment details from text and return them as clean JSON.\n\n🔹 Rules\n\nAlways return data strictly in this JSON format:\n\n{\n \"patient\": {\n \"full_name\": \"John Doe\",\n \"phone\": \"123456789\",\n \"email\": \"john@example.com\"\n },\n \"appointment\": {\n \"date\": \"29th August 2025\",\n \"time\": \"5 PM\"\n },\n \"appointment_id\": \"APT20250831KY5T4N\"\n}\n\n\nAppointment ID:\n\nIf provided, return it exactly as-is.\n\nDo not add extra text (e.g. \"this is a unique ID for your appointment\").\n\nIf missing, generate one in this format:\n\nAPT + YYYYMMDD + 5 random alphanumeric characters\n\n\nExample: APT20250831KY5T4N\n\nAll fields must always be present in JSON:\n\npatient.full_name\n\npatient.phone\n\npatient.email\n\nappointment.date\n\nappointment.time\n\nappointment_id\n\nIf a value is missing, set it to \"null\" (string).\n\nOutput only valid JSON. No explanations, no Markdown, no extra text."
},
"promptType": "define"
},
"typeVersion": 2.2
},
{
"id": "f07a734c-618e-47a7-81d0-2a8f771f7fe1",
"name": "Modèle de chat OpenRouter1",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
1040,
848
],
"parameters": {
"model": "openai/gpt-4o-mini",
"options": {}
},
"credentials": {
"openRouterApi": {
"id": "7pnW2IfzgeEN8qVd",
"name": "OpenRouter account"
}
},
"typeVersion": 1
}
],
"active": true,
"pinData": {},
"settings": {
"timezone": "Europe/Rome",
"callerPolicy": "workflowsFromSameOwner",
"executionOrder": "v1"
},
"versionId": "0fac2f0e-7ed9-4fbc-91c8-c318f819b03c",
"connections": {
"2e634902-e4ce-4362-8ca2-5fa1bb4ebd73": {
"main": [
[
{
"node": "cd01ecc0-431a-4c8b-a703-dbcef7075fcd",
"type": "main",
"index": 0
}
]
]
},
"cd82287b-0ea8-4e15-a8da-9e5c4bb7bcb2": {
"main": [
[
{
"node": "2e634902-e4ce-4362-8ca2-5fa1bb4ebd73",
"type": "main",
"index": 0
}
]
]
},
"8b070be5-d1b2-4f02-99a4-6278450b9fe7": {
"main": [
[
{
"node": "39947ea3-452c-4c93-bdaa-9639a16a574a",
"type": "main",
"index": 0
}
]
]
},
"39947ea3-452c-4c93-bdaa-9639a16a574a": {
"main": [
[
{
"node": "69b5f76a-3c63-4e0c-b4cb-d52e7dc57cbf",
"type": "main",
"index": 0
}
]
]
},
"ab252537-767c-477d-9a0b-941bd4ed8558": {
"main": [
[
{
"node": "cd82287b-0ea8-4e15-a8da-9e5c4bb7bcb2",
"type": "main",
"index": 0
}
]
]
},
"ac1a8cc3-7d80-4885-8360-0dce48b2af89": {
"main": [
[
{
"node": "88e1c616-7014-4d49-8d32-fe9c77f85d86",
"type": "main",
"index": 0
}
]
]
},
"7eec2403-de34-4163-8984-3c5f6be8070c": {
"ai_tool": [
[
{
"node": "39947ea3-452c-4c93-bdaa-9639a16a574a",
"type": "ai_tool",
"index": 0
}
]
]
},
"6cb4cb42-b5e8-446d-9711-d72649c8b6cc": {
"ai_tool": [
[
{
"node": "39947ea3-452c-4c93-bdaa-9639a16a574a",
"type": "ai_tool",
"index": 0
}
]
]
},
"69b5f76a-3c63-4e0c-b4cb-d52e7dc57cbf": {
"main": [
[
{
"node": "ab252537-767c-477d-9a0b-941bd4ed8558",
"type": "main",
"index": 0
}
]
]
},
"cd01ecc0-431a-4c8b-a703-dbcef7075fcd": {
"main": [
[
{
"node": "ac1a8cc3-7d80-4885-8360-0dce48b2af89",
"type": "main",
"index": 0
}
]
]
},
"b55f6c71-39df-46f8-8439-2f6e3e125466": {
"ai_memory": [
[
{
"node": "39947ea3-452c-4c93-bdaa-9639a16a574a",
"type": "ai_memory",
"index": 0
}
]
]
},
"d48200d0-fbf4-4cef-bcd9-f0d9a6b66579": {
"ai_languageModel": [
[
{
"node": "39947ea3-452c-4c93-bdaa-9639a16a574a",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"f07a734c-618e-47a7-81d0-2a8f771f7fe1": {
"ai_languageModel": [
[
{
"node": "ab252537-767c-477d-9a0b-941bd4ed8558",
"type": "ai_languageModel",
"index": 0
}
]
]
}
}
}Comment utiliser ce workflow ?
Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.
Dans quelles scénarios ce workflow est-il adapté ?
Intermédiaire - Chatbot de support, IA Multimodale
Est-ce payant ?
Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.
Workflows recommandés
Md Sabirul Islam
@shishirislam80Partager ce workflow