Chatbot Architecture
Chatbot Architecture
Section titled “Chatbot Architecture”The WhatsApp conversation engine that powers patient self-service booking.
Conversation Pipeline
Section titled “Conversation Pipeline”sequenceDiagram autonumber actor P as Patient participant WA as WhatsApp Client participant Meta as Meta Cloud API participant BE as ClinicFlow Backend participant Redis as Redis (Cache) participant Claude as Claude Haiku NLU participant DB as Supabase PostgreSQL
rect rgb(30, 41, 59) Note right of P: 1. Intent & Auth Phase P->>WA: "Hola, quisiera agendar una cita" WA->>Meta: Inbound Message Meta->>BE: POST /webhooks/whatsapp BE->>BE: HMAC-SHA256 Signature Verification BE->>Redis: Check 24h Message Deduplication Redis-->>BE: Not Duplicate BE->>Redis: Acquire Per-Phone Concurrency Lock BE->>DB: Load or Create chat_session end
rect rgb(15, 23, 42) Note right of BE: 2. Intelligence Phase BE->>DB: Fetch Clinic Context & Availability Slots BE->>DB: Validate bot_enabled and patient status BE->>Claude: NLU Query (Context + Slots + History) Claude-->>BE: Response { action: "ask", collected: {...}, reply: "..." } BE->>Meta: Dispatch WhatsApp Text Payload Meta->>WA: Deliver Message WA->>P: "¡Con gusto! ¿Qué día te gustaría venir?" end
Note over P,BE: Conversation loops until date & time slot are selected
rect rgb(3, 105, 161) Note right of P: 3. Booking & Confirmation P->>WA: "Mañana a las 3:30 PM" WA->>Meta: Inbound Message Meta->>BE: POST /webhooks/whatsapp BE->>Claude: NLU Evaluation Claude-->>BE: Response { action: "confirm", readyToConfirm: true } BE->>DB: Verify Slot Availability & Insert Appointment BE->>BE: Enqueue BullMQ Reminders (24h + 2h) BE->>Meta: Dispatch Interactive Confirmation Card Meta->>WA: Deliver Interactive Buttons (Confirm / Edit / Cancel) WA->>P: "✅ Cita reservada — Mañana 3:30 PM" BE->>Redis: Release Concurrency Lock endState Machine
Section titled “State Machine”stateDiagram-v2 [*] --> IDLE IDLE --> COLLECTING_DATE : Inbound Message COLLECTING_DATE --> COLLECTING_TIME : Date Selected COLLECTING_TIME --> COLLECTING_NAME : Time Selected COLLECTING_NAME --> CONFIRMING : Name Confirmed CONFIRMING --> CONFIRMED : Button Click / Confirmation CONFIRMED --> [*]
state IDLE { [*] --> Waiting }
COLLECTING_DATE --> IDLE : RESET / Timeout COLLECTING_TIME --> IDLE : RESET / Timeout COLLECTING_NAME --> IDLE : RESET / Timeout CONFIRMING --> COLLECTING_DATE : EDIT_BOOKING ClickEach state is tracked in chat_sessions.current_state with collected fields stored in chat_sessions.collected_fields (JSONB).
Claude Haiku Prompt
Section titled “Claude Haiku Prompt”The system prompt injects live clinic context:
- Clinic name and address
- Doctor names and specialties
- Real-time availability slots for the requested date
- FAQ entries for keyword matching
Known Button IDs
Section titled “Known Button IDs”| Button ID | Action |
|---|---|
CONFIRM_BOOKING |
Short-circuit: write appointment, send confirmation |
EDIT_BOOKING |
Reset to COLLECTING_DATE |
CANCEL_BOOKING |
Cancel appointment flow |
RESET |
Reset entire conversation |
RECALL_REPLY_* |
Dental recall campaign responses |
Short-circuits skip the Claude API call entirely — faster and cheaper.