Start your EVOTECH request in under a minute.
AI Chatbot Google Calendar Integration That Books Only Genuinely Open Slots
A chatbot connected to Google Calendar has three jobs: read when you are actually free, write a correctly formed event the moment a visitor commits, and notice when someone later moves or deletes that event by hand. Each job maps to a specific part of Google’s Calendar API (free/busy queries, event inserts, and push channels paired with sync tokens), and each has a failure mode that quietly produces double bookings or ghost appointments. Here is how we wire all three, what we store, and how we test the whole loop before it touches your live calendar.
What happens between “Are you free Tuesday?” and a calendar invite
The language model inside a chatbot knows nothing about your schedule. It cannot look at a calendar, and it must never be allowed to guess one. Every time it talks about availability, it is reading from a list your server handed it seconds earlier.
A working Google Calendar booking loop runs in six steps:
- The visitor asks for a time. The model recognises a scheduling request and calls a tool we define, something like find_open_slots, passing the service type and a rough date window (“next week, mornings”).
- Your server builds candidates. From your business rules it generates possible start times: working hours for that weekday, the service’s duration, buffers, minimum notice and how far ahead bookings are allowed.
- Google subtracts what is taken. One free/busy request returns every busy interval across the calendars that matter. Candidates that overlap a busy block are dropped.
- The model offers a short list. Three or four options, each carrying an opaque slot ID, shown in the visitor’s own time zone.
- The visitor commits. The bot collects a name, an email and a one-line reason, then calls book_slot with the chosen ID.
- Your server re-checks and writes. It confirms the slot is still open, inserts the event, and only then returns a confirmation that the bot relays word for word.
Reading availability: why we query free/busy instead of listing your events
Google offers two ways to learn when you are busy. The events list returns full event objects: titles, attendees, descriptions, locations. The free/busy endpoint returns nothing but start and end times of busy blocks for the calendars you name.
We default to free/busy for a security reason as much as a technical one. A chatbot is a public text box, and people will try to talk it into revealing things. If the only calendar data that ever reaches the bot’s context is “busy 10:00–11:30,” there is no client name, no meeting subject and no private note for a manipulated prompt to leak.
When listing events is justified
Some rules depend on what an event is, not just when it happens. Two examples: adding drive time after any appointment that has a street address in its location, or allowing bookings over events titled “Hold.” In those cases the server reads events itself, applies the rule, and still passes only computed slots to the model.
Several calendars, one answer
A free/busy request accepts multiple calendar IDs at once. A typical setup checks the person’s primary calendar, a shared team or “Bookings” calendar, and sometimes a company holidays calendar. The busy intervals are merged before any slot is offered.
Your rules live in our configuration, not in Google
| Rule | Example setting | Why it matters |
|---|---|---|
| Working hours | Different per weekday, with a lunch block | Google only knows what is on the calendar, not when you are willing to work |
| Duration by service | Discovery call shorter than an on-site review | The bot must ask which service before it can search |
| Buffers | Gap before and after each booking | Stops back-to-back stacking |
| Minimum notice | No same-day bookings after midday | Avoids a booking you will not see in time |
| Booking horizon | A few weeks out, not months | Keeps the calendar from filling with far-off tentative interest |
| Daily cap | A maximum number of bot-made bookings per day | Protects the rest of the day for existing work |
One trap worth knowing: Google Calendar creates all-day events as “Available” unless someone changes that setting. A vacation entered as an all-day event therefore does not appear as busy, and a calendar-connected bot will book straight into it. We check for this during setup and either switch those entries to Busy, use Google’s out-of-office event type, or have the server treat all-day entries on a chosen calendar as blocking.
The event we write, field by field
Once the slot passes its final check, the server inserts one event. Every field is filled deliberately:
| Event field | What goes in it | Reason |
|---|---|---|
| summary | Service name plus the visitor’s name | Readable at a glance in week view |
| start / end | RFC 3339 times with an IANA zone such as America/Chicago | Named zones keep daylight-saving shifts correct |
| attendees | The visitor’s email, if you want Google to invite them | Controls whether an invitation is sent at all |
| description | A short summary of what the visitor asked for | Context for the meeting, without pasting the whole transcript |
| extendedProperties.private | Booking reference, conversation ID, source “chatbot” | Invisible to guests; lets us find and reconcile the event later |
| conferenceData | A request for a Google Meet link, only for virtual services | Requires the conferenceDataVersion=1 parameter on the insert |
| id | Derived from the booking reference | Makes retries safe (see below) |
One confirmation, not two
The insert call takes a sendUpdates parameter. Set to “all,” Google emails the visitor an invitation. Set to “none,” it stays silent and your own confirmation email or text does the job. Decide which system speaks, because visitors who get two confirmations with different wording start to wonder which is real.
Retries that cannot duplicate
Networks fail at awkward moments. The worst case is a timeout after Google created the event but before the response reached us. A naive retry creates a second copy. Google lets the caller supply its own event ID, provided it uses only base32hex characters (lowercase a–v and digits). We derive that ID from the booking reference, so a retry of the same booking gets a conflict response instead of a twin, and the server treats that conflict as success.
Whose Google account is the bot acting as?
There is no Google password anywhere in this design. Access comes from one of three authorisation patterns, and the right one depends on how many calendars are bookable and what kind of Google account you run.
1. One owner, one consent
For a solo practitioner or a single shared calendar, the account owner clicks through Google’s OAuth consent screen once. We request the narrowest scopes that work: write access to events, plus read access for availability. The resulting refresh token is stored encrypted on the server and never reaches the browser. This works for personal Gmail accounts as well as Google Workspace.
A common reason these integrations die a week after launch: a Google Cloud project whose OAuth consent screen is still in “Testing” status issues refresh tokens that expire after seven days. We publish the app properly, or mark it Internal when everyone who authorises it belongs to your own Workspace organisation. Calendar scopes are classed as sensitive, so an external app may also need Google’s verification review; we confirm what applies to your setup during scoping.
2. A team on Google Workspace
When the bot must book across several staff calendars, asking each person to authorise separately becomes fragile. Workspace administrators can instead grant a service account domain-wide delegation for specific scopes, letting the integration act on behalf of named users. It is powerful, so we restrict the delegation to calendar scopes only and document exactly which scope strings were approved.
3. A dedicated bookings calendar shared with a service account
The lightest option is a calendar created just for bookings and shared with the service account’s address. It avoids delegation entirely. The catch: Google does not let a service account without delegation add attendees, so no invitation goes to the visitor from Google. Your own confirmation message fills that gap.
When someone edits the calendar by hand
Bookings do not stay put. A receptionist drags an appointment to Thursday, the owner deletes one, a visitor declines the invite. If the bot’s records are not updated, it will cheerfully confirm a time that no longer exists, or send a reminder for a cancelled visit.
Push channels do the noticing
Google’s watch mechanism registers an HTTPS endpoint on our server for a given calendar. When anything on that calendar changes, Google sends a small notification: the channel’s identity and a resource state, but not the changed event itself. That notification simply means “look now.”
Sync tokens do the fetching
After a first full read, each events list response carries a sync token. Presenting that token on the next request returns only what changed since. Our handler does exactly that on every notification, then matches changed events to bookings using the private booking reference stored on each event.
The maintenance nobody mentions
- Channels expire. A scheduled job renews each one well before its expiry time.
- Notifications can be forged. We set a secret channel token when registering and discard any notification that does not carry it.
- Sync tokens can be invalidated. Google answers with HTTP 410; the handler performs a fresh full read of the booking window and stores the new token.
- Webhooks can be missed. During a deploy or outage, a periodic reconciliation pass compares recent bookings with the calendar and fixes drift.
Reschedules and cancellations started in chat
A reschedule patches the existing event, keeping the same ID and invitation thread, rather than deleting and recreating it. Before any change, the bot verifies the person: a link or short code sent to the email on the booking. Typing someone’s name is not enough to cancel their appointment.
Seven ways calendar bots fail, and the guard for each
- Two visitors grab the same slot. A short-lived hold is placed in our database when a slot is offered, and free/busy is queried again immediately before the insert. Whoever loses the race is offered the next open times instead of an error.
- Time zones drift. A visitor in Arizona, which skips daylight saving, books with a business in Texas. We store UTC, use named zones rather than fixed offsets, and restate every confirmed time with its zone abbreviation.
- Relative dates are ambiguous. “Next Friday” said on a Friday means different things to different people. The bot echoes the full date back before booking.
- Recurring meetings hide. Free/busy expands recurring series on its own. When we list events directly, we request single-event expansion so each weekly occurrence is checked individually.
- Google throttles requests. Rate-limit responses trigger exponential backoff with jitter. While retrying, the bot says it is confirming, never that the booking is done.
- Access is revoked. A refresh that fails with an invalid-grant error alerts the owner at once, and the bot switches to taking callback requests instead of pretending it can still book.
- The model claims success on its own. Confirmation text is built from the API response, including the event time Google actually stored. No response with an event ID, no confirmation.
How we test before it touches your real calendar
All development happens against a separate test calendar seeded with the awkward cases: a weekly recurring meeting, an all-day entry, events straddling a daylight-saving change, back-to-back blocks, and a tentative invitation. Then we run scripted conversations against it:
- “Tomorrow morning” typed a few minutes before midnight.
- A visitor two time zones away asking for “3 o’clock.”
- A booking, then a reschedule, then a cancellation, all through chat.
- Two simulated visitors choosing the same slot within a second of each other.
- An event moved by hand while the webhook endpoint is deliberately offline, to prove reconciliation catches it.
- A revoked token, to confirm the alert fires and the bot degrades gracefully.
After that, the bot runs on your real calendar in a supervised mode: it proposes slots and a person approves each booking. Automatic booking is switched on only after you are comfortable with what it proposes.
How EVOTECH delivers a Google Calendar–connected chatbot
EVOTECH IT LLC has operated for more than 20 years and is rated 5.0 on Google by its customers. Every project is handled remotely, wherever in the United States you are, by US-based people near Houston. For calendar work, the sequence looks like this:
- Free consultation by phone or video. We map your services, their durations, who can be booked, and which calendars reflect real availability.
- Fixed-scope written quote. It names the authorisation pattern, the business rules, the confirmation channel and what happens on failure.
- Build on the test calendar, using the conversation and failure scripts above.
- Authorisation by you. Your account owner or Workspace admin grants access through Google’s own screens. We never ask for a Google password.
- Supervised launch, then automatic booking, with alerts for revoked access, expired channels and failed inserts.
- Handover notes explaining where tokens live, how to revoke them and how to change hours or buffers.
If you already schedule through Calendly on top of Google, connecting the bot to Calendly may be the simpler route; see our Calendly integration page. The calendar connection usually sits inside a broader AI chatbot build, and reminder messages are covered under appointment reminders.
Related services
Frequently asked questions
Can the chatbot see the details of my appointments?
Will visitors receive a Google Calendar invitation?
Does this work with a free Gmail account, or only Google Workspace?
Can it book across several team members?
What happens if Google rejects the booking or is unreachable?
Can visitors reschedule or cancel through the chat?
Let your chatbot book real time on Google Calendar
Tell us which calendars and services should be bookable: ring (832) 359-2425 for a free consultation, and the scope comes back as a fixed written quote.
Book a Free Consultation
Ready for EVOTECH to help?
Before you leave, send the quick version. We will review the page you came from and reply with the clean next step.
