Booking assistant
A serverless booking assistant on AWS that reads appointment requests, checks Google Calendar, proposes slots that respect your service rules, locks in the customer’s pick, and sends quiet reminders. Seven posts on the same system — one diagram at a time — with an engineering reference at the end.
-
01
A booking assistant on AWS for a few dollars a month
The whole system on one page — a reader, a scheduler, a confirmer, and the four moves they share for every inbound request.
-
02
How a booking request reaches the assistant
Three lanes at the door: web-form fast path for the easy 80%, AI-handle for free-text email, direct escalate for VIPs the AI should never touch.
-
03
How the assistant understands the request
Three small extractors run in parallel: which service, when roughly, and who’s booking. Confidence on every field; anything borderline becomes a draft.
-
04
How the assistant picks slots
Five filters in order: calendar query, working hours, duration plus buffers, blackouts and capacity, then rank. Every constraint comes from your rules file.
-
05
How a booking gets confirmed
Claim, write, confirm, remind — in that order. An atomic claim row prevents double-booking even when two customers click at the same second.
-
06
What the booking assistant costs
A coffee a month at SMB volume. Cents per request, scaling with the email lane — the form lane is essentially free.
-
07
Engineering reference: the booking assistant architecture
Same system, drawn purely for engineers. Service names, resource identifiers, region, Bedrock model IDs, Google Calendar API choices.
Frequently asked questions
- What does the booking assistant do?
- It reads booking requests from a web form or your existing email address, parses fuzzy text like “next Tuesday afternoon for a haircut” into a structured request, queries your Google Calendar for free time, applies your service rules (durations, buffers, working hours, blackouts, capacity), proposes 2–3 viable slots, and on the customer’s pick claims the slot atomically, writes the calendar event, sends a confirmation with an
.icsfile and signed reschedule/cancel links, and schedules quiet reminders the day before and an hour before. - How much does it cost to run?
- About $3/month at typical small-business volume (around 200 booking requests/month). The fixed cost is essentially zero — Lambda, S3, DynamoDB, EventBridge, and CloudWatch sit in or near the always-free tier. Variable cost is per-request pennies: SES inbound and outbound at $0.10 per 1,000 emails, plus Bedrock Haiku tokens (~$0.001 per parsed email-lane request). The web-form lane skips the AI entirely. Most setups land between $1 and $5 a month total.
- Which calendar systems does it support?
- Google Calendar is the primary target — the assistant uses Google Calendar v3
freebusy.queryfor availability andevents.insertfor confirmed bookings, authenticated via a service account with domain-wide delegation. Microsoft 365 swaps in cleanly if you’re on Outlook/Exchange: replace the Google Calendar v3 calls with Microsoft GraphgetScheduleandevents.create. Same shape, different SDK, same atomic-claim and stable-event-id idempotency story. - How does it avoid double-booking?
- An atomic claim step before the calendar write. A small DynamoDB table
tbl-claimsis keyed by(resource_id, slot_start_iso). The confirmer does aPutItemwithConditionExpression: attribute_not_exists(resource_id). The first request for a given slot wins; any second request gets aConditionalCheckFailedExceptionand is bounced back to the proposal stage with fresh slots. The calendar event itself is written with a stable UUID set as the event id, so a retried write returns 409 duplicate instead of creating a second event. - How does it know my service rules?
- A single
rules.ymlfile in a Drive folder holds your service catalogue (durations, prices, qualified resources, aliases), working hours per resource, buffer times, blackout dates, capacity caps, ranking preferences, and confirmation tone. A smallfn-config-syncLambda mirrors the file to S3 on Drivechanges.watchnotifications, chunks and embeds the catalogue with Bedrock Titan Embeddings v2, and writes vectors to an S3 Vectors index namedvec-services. Editing the doc updates the assistant’s behaviour without a deploy. - What happens for VIPs or edge cases?
- Three lanes at the door before any AI runs. Lane 1 (web-form fast path) skips the parser entirely when the form is filled in cleanly. Lane 2 (AI handle) runs the parser on free-text email and partial form notes. Lane 3 (direct escalate) forwards anything from a sender on the allowlist — regulars, partners, first-time VIPs — straight to your normal inbox with an
X-Assistant-Lane: directheader, untouched by the AI. Anything the parser sees with low confidence becomes a one-screen draft you approve before the assistant carries on. - Which AWS services does it use?
- Lambda (with Function URLs for the form intake and confirmer), DynamoDB on-demand (
tbl-requests,tbl-claims,tbl-audit), S3, EventBridge Scheduler (one-time schedules for reminders), SES inbound and outbound, Secrets Manager (the Google service-account key), CloudWatch Logs with seven-day retention, AWS Budgets, and Bedrock (Claude Haiku 4.5 via Global cross-Region inference, plus Titan Text Embeddings v2 with an S3 Vectors index for the service catalogue). No API Gateway, no NAT Gateway, no always-on compute.