Logo Lanfrica

fahiiim/BookaBL

Domain:

digital infrastructure

Record type:

software
Creator:
fah
Host:
This project "BookABL" is from a South African Client "Ross_Champbell" # BOOKABL BOOKABL Milestone 1 is a multi-tenant AI WhatsApp receptionist backend for South African dental clinics. It accepts signed WhatsApp Cloud API webhooks, runs a deterministic booking conversation, stores bookings in Supabase, mirrors them to Google Calendar when configured, and notifies clinic owners through Telegram. Only M1 is implemented. Waitlists, review and recall campaigns, payments, an admin dashboard, deployment automation, and spreadsheet FAQs are intentionally absent. ## What is included - Signed, deduplicated, persist-first WhatsApp webhook ingress. - Tenant resolution from Meta `metadata.phone_number_id`. - Config-driven trial access, hours, services, timezone, reminders, templates, and branding. - Service, slot, medical-aid, and self-pay booking conversation states. - Three availability candidates combining clinic hours, Google free/busy, and open DB bookings. - One transactional `finalize_booking` RPC for the appointment, reminder/no-show jobs, and outbox. - Calendar failure isolation through durable `calendar_retry` jobs. - Telegram booking alerts and authorized `today's bookings` / `/bookings` commands. - Confirm, reschedule, cancel, reminder, no-show, and patient no-show-count handling. - Optional WhatsApp voice-note transcription through OpenAI `whisper-1`. - Network-free fakes, a deterministic demo, and end-to-end signed-webhook acceptance tests. ## Prerequisites - Python 3.12 (the project deliberately excludes 3.13+). - A Supabase project for production-style persistence. - Meta WhatsApp Cloud API and Telegram Bot credentials. - An OpenAI API key for structured intent output and voice-note transcription. - Optional Google OAuth client credentials and refresh token. - Optional Supabase CLI for `make migrate`; the SQL Editor route below needs no CLI. Never commit `.env`. The repository ignores it, and settings use `SecretStr` so secrets are not rendered accidentally. If a secret has been pasted into chat, logs, or a ticket, rotate i …