Back to home

AI Dental Receptionist: Qualify Leads, Book Appointments, and Send Emails — Fully Automated

February 2026

The Idea

Dental clinics lose leads every day — not because the service is bad, but because nobody responds fast enough. A potential patient fills out a form or starts a chat at 9PM on a Sunday, and by Monday morning they've already booked with a competitor.

The solution: an AI receptionist that's available 24/7. It chats with the patient, qualifies their intent, scores the lead on a 1–10 scale, and based on that score — either auto-books a calendar appointment, alerts staff for follow-up, or quietly logs them for later. No human required until it's time to actually see the patient.

I built this entirely in n8n using 3 interconnected workflows. From first chat message to confirmed appointment in Google Calendar, with a CRM row logged in Google Sheets and confirmation emails sent — all automated.

The Stack

  • n8n — workflow orchestration, self-hosted on Railway
  • Claude Sonnet 4.6 — AI receptionist brain (Anthropic API)
  • Google Calendar — availability checking and appointment creation
  • Google Sheets — CRM with 18-column lead tracking
  • Gmail — patient confirmation emails + staff alert emails
  • Google Cloud Console — OAuth 2.0 client for Calendar/Sheets/Gmail

The 3-Workflow Architecture

Rather than one monolithic workflow, I split the system into 3 focused workflows that call each other. This keeps each workflow readable, testable, and independently deployable.

Workflow 1 — AI Receptionist (Chat)

The patient-facing interface. Uses n8n's Chat Trigger so it can be embedded on any website. A Claude Sonnet 4.6 AI Agent node plays the role of a friendly dental receptionist — collecting the patient's name, contact details, treatment interest, insurance status, and urgency. Once enough information is gathered, it calls Workflow 2 to check availability or book. A memory buffer keeps 10 messages of context so the conversation feels natural.

Chat Trigger

→ AI Receptionist (Claude Sonnet 4.6 + memory)

→ Execute Sub-workflow (check availability / book)

→ Respond to Chat

→ Format Chat Error (fallback)

Workflow 2 — Booking & Notifications (Sub-workflow)

The operations engine. Called by both the chat and form workflows. A Route Action switch directs the flow to one of three paths: check calendar availability, create a booking, or send warm-lead notifications. This workflow handles all the Google integrations and email sending in one place.

When Called → Config → Route Action

→ [check] Get Calendar Events → Format Available Slots

→ [book] Book Appointment → Log to CRM → Email Patient + Email Staff

→ [warm] Email Patient Acknowledgment + Email Staff Warm Lead

Workflow 3 — Form Intake (Webhook)

The website form handler. Catches POST submissions from a contact form, runs them through anti-abuse checks, sanitizes the input, scores the lead, and routes them appropriately — auto-booking hot leads, alerting staff for warm leads, and silently logging cold leads.

Form Submission → Anti-Abuse Check → Config

→ Normalize Form Data → Validate & Sanitize

→ Lead Score → Route by Score

→ [Hot 7+] Execute Booking Sub-workflow

→ [Warm 4-6] Log to CRM + Execute Notification Sub-workflow

→ [Cold 1-3] Log to CRM only

Key Features

AI Lead Scoring (1–10)

A JavaScript Code node scores every lead across five dimensions: new vs. returning patient, treatment value (cosmetic scores higher than checkup), insurance coverage, urgency (emergency = maximum score), and contact completeness. The composite score drives all routing decisions — hot leads (7+) book automatically, warm leads (4–6) get a staff alert for manual follow-up, cold leads (1–3) are logged quietly.

Google Calendar Integration

The availability check fetches calendar events for the next 7 days and calculates open 1-hour slots between 9AM and 5PM (Asia/Manila timezone), skipping lunch (12–1PM) and existing bookings. The AI presents these slots to the patient in natural language. On confirmation, a calendar event is created with the patient's name, email, and treatment details — and the event ID is logged to the CRM for cross-referencing.

Google Sheets CRM

Every lead — whether from chat or form — gets a row in the CRM spreadsheet with 18 columns: timestamp, source channel, UTM parameters, patient name, phone, email, insurance, treatment interest, new patient flag, urgency, lead score, status, appointment date/time, calendar event ID, and notes. This gives the dental practice a complete picture of every inbound lead with zero manual data entry.

Automated Email Notifications

Four email templates cover every scenario. Booked patients get a confirmation with their appointment date and time in Philippine Time (PHT). Staff get an alert for every hot booking with the patient's full details. Warm leads trigger a separate staff alert and a patient acknowledgment ("we'll be in touch" message). All sent via Gmail OAuth — no third-party email service needed.

Security & Anti-Abuse

The form intake workflow runs three layers of protection before any data reaches the AI or calendar. An Anti-Abuse Check node validates Content-Type, rejects empty bodies, checks for honeypot fields, and enforces a 10KB payload size limit. A Validate & Sanitize node strips HTML tags, truncates fields to 200 characters, validates email format with regex, enforces phone number length (7–15 digits), and checks required fields. A Config node centralizes secrets (spreadsheet IDs, staff email) so they're never hardcoded in individual nodes.

Problems & Solutions

Empty Calendar Broke the Workflow

Problem: When the Google Calendar had zero events, n8n skipped every node downstream of the Calendar fetch — including the Format Available Slots node. The sub-workflow returned nothing.

Fix: Added alwaysOutputData: true on the Get Calendar Events node. This forces n8n to pass an empty item downstream so the Format Slots node always runs and can return "no existing bookings — all slots open."

Google Calendar Rejected Attendees

Problem: The Book Appointment node was failing with a type error. The Google Calendar node expects attendees as an array, but the expression was passing a plain string (the email address).

Fix: Wrapped the email in an array: ={{ [$json.email] }}. Also added the required summary field (event title) which the node needs but doesn't shout about.

CRM Rows Were Empty

Problem: After a successful booking, the Google Sheets Log to CRM node was configured with mappingMode: "defineBelow" but an empty value: {}. Every row was blank.

Fix: Added the full 17-column mapping explicitly, pulling patient data from the originating trigger node and the calendar event ID from the booking response.

Timezone Confusion

Problem: Calendar slots were showing in UTC. Patients would see "2:00 AM" when the actual appointment was 10:00 AM in the Philippines.

Fix: Set workflow timezone to Asia/Manila in all 3 workflows. Rewrote all date/time Code nodes to use n8n's built-in $now DateTime object (avoiding the word "luxon" in code — Railway does a string scan that blocks nodes containing it). All time displays now show "(PHT)" explicitly.

n8n Validator Blocking Active Workflow Updates

Problem: Using n8n_update_partial_workflow on an active workflow triggered strict publish validation, which failed on pre-existing false-positive errors (JS }} parsed as expression syntax, Google nodes with "Invalid operation" due to typeVersion).

Fix: Switched to n8n_update_full_workflow with the name param — bypasses strict publish validation while still saving the workflow correctly.

Error Handling Strategy

Production workflows need to fail gracefully. Here's how errors are handled at each critical point:

  • -AI Agent erroronError: continueErrorOutput routes to a "Format Chat Error" node that returns a friendly message to the patient instead of a raw crash.
  • -Calendar API failure — Calendar Error Response Set node returns a structured error so the AI can tell the patient "I couldn't check availability right now, please try again."
  • -Booking failure — Booking Error Response Set node catches it so the AI can ask the patient to pick a different time.
  • -CRM write failure — CRM Log Error node silently logs the issue and still lets the staff alert email go through — no appointment data is lost.
  • -Gmail failures — All 4 email nodes have continueOnFail so an email error doesn't cancel an already-booked appointment.
  • -Sheets nodes — Use continueRegularOutput so downstream processing continues even if logging fails.

What I Learned

  • -Sub-workflows are worth the setup cost — splitting booking logic into a sub-workflow means both the chat and form can reuse the same calendar/email code. Any fix in one place fixes both channels.
  • -Google OAuth is the hardest part — setting up the OAuth client in Google Cloud Console, wiring the correct redirect URIs, and getting Calendar + Sheets + Gmail all under one credential took longer than building the actual workflow logic.
  • -n8n skips nodes on empty data by default — this catches you off guard with external APIs. Any node calling a service that could return zero results needs alwaysOutputData: true or an explicit fallback.
  • -Lead scoring is business logic, not AI logic — the scoring is deterministic JavaScript, not an LLM call. Using AI for scoring would add latency and cost for a task that's actually just a set of rules.
  • -Always test with a real calendar — the schema differences between a brand-new calendar (zero events) and an active one exposed the empty data bug immediately. Simulate both states before going live.

How This Scales

Short-Term

  • Persistent conversation memory — upgrade from buffer window to Postgres chat memory
  • Webhook Header Auth on the form intake for extra security
  • Multi-practitioner support — route bookings to different calendars by treatment type

Medium-Term

  • SMS notifications via Twilio for appointment reminders
  • Automated follow-up sequences for warm leads
  • No-show handling — detect missed appointments and trigger a re-booking workflow
  • Patient portal — a simple Next.js frontend for patients to view and reschedule

Long-Term

  • White-label template for any service-based business (legal, accounting, physio)
  • CRM dashboard — replace Google Sheets with a proper Supabase + Next.js admin panel
  • AI follow-up calls — outbound voice AI for warm lead nurturing

The Takeaway

This project demonstrates a pattern that applies far beyond dental clinics: any service business that qualifies leads and books appointments can be automated with this exact architecture. The AI handles the conversation, the scoring logic handles routing, and n8n handles every integration.

The 3-workflow split — receptionist, operations, intake — keeps complexity manageable. Each workflow has a single responsibility and a clear interface. It's maintainable, extensible, and the kind of system a small clinic can actually rely on.


Built with n8n, Claude Sonnet 4.6 (Anthropic API), Google Calendar, Google Sheets, Gmail, and Railway. Orchestrated by Claude Code.

More Case Studies