A Calendly clone: an admin configures availability once, guests pick a free slot on a public booking page, and Windmill creates the Google Calendar event (with a Meet link) and sends the confirmation email.
Windmill concepts demonstrated
- Two raw apps — a public booking page for guests, an admin page for availability.
- Custom resource type — holds the availability config: hours, days, duration, timezone.
- Resources — Google Calendar and SMTP credentials.
- Datatables — stores the config and the bookings.
- Setup script — creates the schema on first run, safe to re-run.
Layout
calendly_setup_db.ts Create schema + config/bookings tables (idempotent)
calendly_get_config.ts Read the availability config
calendly_update_config.ts Update host, title, hours, duration, timezone
calendly_get_available_slots.ts Free slots for a date (config − existing bookings)
calendly_book_slot.ts Create the Google Calendar event + Meet link, store
the booking, send the confirmation over SMTP
calendly_booking__raw_app/ Public booking page
calendly_dashboard__raw_app/ Admin configuration page
calendly__raw_app/ Leftover scaffold (no raw_app.yaml) — safe to delete
Notable implementation details
- Timezone handling is explicit:
toRfc3339WithOffset()converts a naiveYYYY-MM-DD+HH:MMinto an RFC3339 timestamp carrying the config's IANA offset, so Google Calendar receives an unambiguous instant. - The Meet link is requested through
conferenceDataVersion=1andsendUpdates=allon the Calendar API call. - Scripts and descriptions in this project are written in French.
Try it locally
wmill script preview f/calendly/calendly_get_available_slots -d '{"date_str":"2026-08-03"}'