How a conversation turns into a Cal.com appointment
During any conversation — WhatsApp, Instagram, or website widget — a lead signals booking intent. "I want to try Botox," "Can I book a consultation?" Karen's AI pipeline classifies this as booking-related and surfaces the appropriate booking actions.
src/prompt-builder.js → selectActionsForContext()src/model.js → intent classification in model responseselectActionsForContext(), which includes [ACTION:suggest_booking] and [ACTION:check_availability] in the available actions list when conversation context is booking-related. The model parses these action tags and triggers the booking flow.conversations, contactsKaren responds with Oshun's Cal.com booking page — cosmetic.oshunja.com/booking. She explains what to expect at the consultation, mentions it's free, and reinforces procedure benefits to reduce drop-off before the click.
src/actions/calendar.js — booking action handlersCALCOM_API_KEY, CALCOM_WEBHOOK_SECRETThe patient clicks the link, picks a date and time, and fills in their name and phone number. Cal.com creates the booking, sends a confirmation email directly to the patient, and fires a webhook back to the system.
src/webhooks/chatwoot.js → app.post('/webhooks/calcom') (line 329)bookings table.bookings, contactsKaren sends a confirmation on whichever channel the patient came in on: "Your consultation for Botox is confirmed for Thursday at 2 PM. Here's what to know before your visit…" Pre-care basics are included so the patient feels prepared from the moment they book.
src/actions/calendar.js — confirmation handlerbooking_reminders — these will fire at configured intervals leading up to the appointment date.booking_remindersThe contact record is updated with the appointment details — procedure type, date, time, and booking source (WhatsApp, IG, direct). This attribution feeds analytics that track which channels convert to bookings most effectively.
src/contacts.js → updateContactIdentifiers() (line 145)src/actions/attribution/resolve.jsupdateContactIdentifiers() merges any new identifiers (phone, email) discovered at booking time into the unified contact record. The attribution resolver logs the booking source channel to attribution_events, enabling reporting on which channel (WhatsApp, IG, widget) drove each conversion.contacts, attribution_events, booking_remindersThe booking triggers the pre-appointment journey. Three days before the appointment, the automated care plan system activates — sending pre-care guides, intake forms, and reminders. That story continues in Journey 3.
src/actions/care/plans.js → startCarePlan() (line 181)startCarePlan() is called with the procedure type from the booking payload. Each procedure (Botox, filler, laser, etc.) has its own pre-care template containing timing rules, guide content, and intake form links. The care plan engine schedules all pre-appointment touchpoints automatically from this point forward.care_plans, care_plan_steps