Build a Calendly-style meeting scheduler in Bubble with configurable available time slots, a shareable booking link, attendee slot selection with confirmation emails, and calendar integration. This tutorial walks through the data model for availability, the booking UI, conflict prevention, and automated email notifications.
Overview: Building a Meeting Scheduler in Bubble
This tutorial shows you how to build a Calendly-style meeting scheduler in Bubble. You will create a system where hosts define their available time slots, share a booking link, attendees select an open slot, and both parties receive confirmation emails. The system prevents double-booking and supports recurring availability patterns.
Prerequisites
- A Bubble account with a new or existing app
- User authentication already set up
- Basic familiarity with Bubble's Data tab and workflows
- Understanding of date and time handling in Bubble
Step-by-step guide
Create the Availability and Booking Data Types
Create the Availability and Booking Data Types
Go to the Data tab. Create a Data Type called Availability with fields: Host (User), Day of Week (text or Option Set with Monday through Sunday), Start Time (text such as 09:00), End Time (text such as 17:00), Slot Duration (number in minutes, such as 30), and Is Active (yes/no). Then create a Booking Data Type with: Host (User), Attendee Name (text), Attendee Email (text), Date (date), Start Time (date), End Time (date), Status (Option Set: Confirmed, Cancelled), and Notes (text).
Expected result: Two Data Types (Availability and Booking) appear in your Data tab.
Build the availability settings page for hosts
Build the availability settings page for hosts
Create a page called availability-settings. Add a Repeating Group with Type set to Availability, Data source: Search for Availabilities where Host equals Current User. In each cell, show the Day of Week, Start Time, End Time, and Slot Duration as editable inputs, plus a toggle for Is Active. Add a button to create new availability entries for each day. Hosts set their recurring weekly schedule here: for example, Monday 9:00 to 17:00 with 30-minute slots.
Pro tip: Use an Option Set for Day of Week to keep values consistent. Pre-create all seven days when a user first visits the settings page.
Expected result: Hosts can configure their weekly availability for each day, including start time, end time, and slot duration.
Generate available time slots on the booking page
Generate available time slots on the booking page
Create a page called book with a URL parameter for the host's user ID. Add a Date Picker for the attendee to select a date. When a date is selected, determine the day of week and find the host's Availability for that day. Use a Repeating Group to display available slots. Generate the slots by calculating from Start Time to End Time in increments of Slot Duration. For each potential slot, check if a Booking already exists for that host, date, and time range with Status equals Confirmed. Only show slots where no booking conflict exists.
Expected result: The booking page shows available time slots for the selected date, automatically hiding slots that are already booked.
Create the booking workflow with conflict prevention
Create the booking workflow with conflict prevention
When the attendee selects a slot and clicks Book, add an Input for their name, email, and optional notes. Create the workflow: first search for existing Bookings for that host, date, and time where Status equals Confirmed. Add an Only when condition: the search count is 0. If no conflict, Create a new Booking with Host, Attendee Name, Attendee Email, Date, Start Time, End Time, Status as Confirmed, and Notes. If a conflict exists, show an alert saying the slot has been taken.
Pro tip: Run the conflict check in a Backend Workflow for extra safety since frontend workflows can have race conditions if two people book simultaneously.
Expected result: Clicking Book creates a confirmed booking only if the slot is still available, preventing double-booking.
Send confirmation emails to both parties
Send confirmation emails to both parties
After the Create Booking action, add two Send email actions. The first goes to the attendee: To equals Attendee Email, Subject is Meeting Confirmed with the host's name, Body includes the date, time, and any meeting link. The second email goes to the host: To equals Host's email, Subject is New booking from the attendee name, Body includes the attendee details and meeting time. Include a link to a cancellation page with the booking ID as a URL parameter.
Expected result: Both the attendee and host receive confirmation emails with meeting details immediately after booking.
Build a booking management page for hosts
Build a booking management page for hosts
Create a page called my-bookings. Add a Repeating Group with Type Booking, Data source: Search for Bookings where Host equals Current User, sorted by Date ascending. In each cell, display the attendee name, date, time, and status. Add a Cancel button with a workflow that changes the Booking Status to Cancelled and sends a cancellation email to the attendee. Add a tab or filter to show upcoming versus past bookings using a constraint on Date compared to Current date/time.
Expected result: Hosts can view all their bookings, see upcoming and past meetings, and cancel bookings with automatic attendee notification.
Complete working example
1MEETING SCHEDULER — WORKFLOW SUMMARY2=====================================34DATA TYPES:5 Availability6 - Host (User)7 - Day of Week (Option Set: Mon-Sun)8 - Start Time (text, e.g. '09:00')9 - End Time (text, e.g. '17:00')10 - Slot Duration (number, minutes)11 - Is Active (yes/no)1213 Booking14 - Host (User)15 - Attendee Name (text)16 - Attendee Email (text)17 - Date (date)18 - Start Time (date)19 - End Time (date)20 - Status (Option Set: Confirmed, Cancelled)21 - Notes (text)2223PAGE: availability-settings (host-only)24 Repeating Group (Availability, Host=Current User)25 Each row: Day, Start Time, End Time, Duration, Active toggle26 Button: Save changes to each Availability2728PAGE: book?host=[user_id] (public)29 Date Picker → selected date30 Repeating Group: available time slots31 Generated from Availability for that day of week32 Filtered: no existing Confirmed Booking at that time33 Booking form: Name, Email, Notes inputs34 Button: Book Meeting3536WORKFLOW: Create Booking37 Trigger: Book button clicked38 Condition: Search Bookings (Host, Date, Time, Confirmed):count = 039 Actions:40 1. Create Booking (all fields, Status = Confirmed)41 2. Send email to Attendee (confirmation)42 3. Send email to Host (new booking notification)4344WORKFLOW: Cancel Booking45 Trigger: Cancel button clicked46 Actions:47 1. Make changes to Booking → Status = Cancelled48 2. Send email to Attendee (cancellation)4950PAGE: my-bookings (host-only)51 Tab: Upcoming (Date >= today, Status = Confirmed)52 Tab: Past (Date < today)53 Tab: Cancelled (Status = Cancelled)54 Each row: Attendee, Date, Time, Status, Cancel buttonCommon mistakes when building a meeting scheduler in Bubble
Why it's a problem: Not checking for existing bookings before creating a new one
How to avoid: Always search for existing Confirmed bookings at the same host, date, and time before creating a new booking
Why it's a problem: Storing times as text strings instead of date objects
How to avoid: Store Start Time and End Time as full date-time objects in the Booking Data Type for accurate comparisons
Why it's a problem: Not handling timezone differences between host and attendee
How to avoid: Display times in the viewer's local timezone using Bubble's date formatting options, and store all times in UTC internally
Best practices
- Store booking times as full date-time objects for accurate conflict detection and sorting
- Run booking conflict checks in a Backend Workflow to prevent race conditions
- Display times in the viewer's local timezone and store in UTC internally
- Add a buffer time between slots (e.g., 5-10 minutes) to prevent back-to-back meetings
- Send confirmation emails immediately after booking and reminder emails 24 hours before
- Use Privacy Rules to ensure attendees cannot see other attendees' booking details
- Provide a cancellation link in confirmation emails that includes the booking ID as a parameter
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I want to build a Calendly-like meeting scheduler in Bubble.io where hosts set their weekly availability, attendees pick a time slot, and both get confirmation emails. How should I design the data model and booking workflow?
Create a meeting booking page where a visitor selects a date, sees available time slots for that date, and books a slot. Include conflict prevention so the same slot cannot be booked twice.
Frequently asked questions
Can I integrate this with Zoom to auto-generate meeting links?
Yes. Use the API Connector to call Zoom's Create Meeting API after a booking is confirmed. Store the returned meeting URL on the Booking record and include it in confirmation emails.
How do I handle recurring meetings?
Create multiple Booking records at once using a Backend Workflow that creates bookings for each occurrence. Store a Recurrence ID on each booking so they can be managed as a group.
Can attendees reschedule instead of cancelling?
Yes. Add a Reschedule button that cancels the existing booking and redirects to the booking page with the host pre-selected. Pass the old booking ID via URL parameter so the system can reference the original booking.
How do I send reminder emails before the meeting?
Create a Backend Workflow that runs on a schedule. It searches for Bookings where Date equals tomorrow and Status is Confirmed, then sends reminder emails to both the host and attendee.
Can RapidDev help build a more advanced scheduling platform?
Yes. RapidDev can help you build advanced scheduling features including team scheduling with round-robin assignment, payment collection at booking, Google Calendar integration, and custom branding for the booking page.
Can I limit how far in advance attendees can book?
Yes. Set the Date Picker's minimum date to today and maximum date to a calculated future date like Current date/time plus 30 days. This prevents bookings too far in advance.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation