Integration
Google Calendar, and the race that causes double bookings
Google Calendar integration lets a Telegram booking bot read live availability and write appointments into the calendars practitioners already use. The hard part is not the API — it is the window between checking a slot and writing it, which is where double bookings come from.
Google Calendar integration: auth, limits and availability
- Auth model
- OAuth 2.0
- Quota
- Per-project and per-user, with writes counting more heavily than reads
- GCC availability
- No regional restriction; Workspace domain-wide delegation preferred
- Data flow
- 5 hops, worker-mediated
As of 2025-10-01, Telegram Bot API 13.4
Why this integration exists
Almost every clinic, salon and consultancy in the Gulf already runs on Google Calendar. Staff can see it on their phones, it syncs to whatever they use, and nobody has to be trained. A booking system that keeps its own diary alongside it creates a second source of truth, and within weeks the two disagree about something that matters.
So the correct architecture is that Google Calendar stays authoritative and the bot is a writer and reader against it. A manually blocked hour is respected because the bot reads it. An appointment created by the bot appears on the practitioner's phone because the bot wrote it there. Nobody reconciles anything, because there is nothing to reconcile.
The defect that appears in careless implementations is a race. The bot lists free slots, the customer takes twenty seconds to choose, and in that window someone else books the same time — through the bot or directly in the calendar. Re-checking at write time narrows the window but does not close it, because the check and the insert are two operations. The design answer is a provisional hold in your own store with a short expiry, taken before the customer is asked to confirm, and reconciled against the calendar on write.
How the data actually moves
Access is via OAuth 2.0 with offline access, so the bot holds a refresh token per connected calendar rather than a user's live session. Tokens are Worker secrets, never client-side. A service account with domain-wide delegation is the better arrangement for a Google Workspace customer, because it survives the practitioner who granted consent leaving the business.
Auth model: OAuth 2.0
Their limits, and what they mean for you
The Calendar API enforces per-project and per-user quotas, with writes counting more heavily than reads.
A busy multi-practitioner clinic can approach the limits during a morning rush. Availability reads are cached briefly and writes are queued with backoff rather than issued as fast as they arrive.
Push notification channels for calendar changes expire and must be renewed.
A channel that silently lapses means the bot stops seeing manual edits, and availability slowly drifts from reality. Renewal runs on a cron and failure to renew raises an alert.
The `freebusy` endpoint returns busy intervals rather than event detail.
It is the right call for availability because it is cheaper and avoids reading appointment content the bot has no business seeing. Anything needing event detail is a separate, narrower request.
Recurring events expand into instances, and an exception to one instance is its own record.
Availability logic works on expanded instances rather than on the recurrence rule. Treating a weekly block as a single event produces a bot that offers slots on the one week it was cancelled.
How it fails, and what happens when it does
Two customers are offered the same slot within seconds of each other.
The first selection takes a hold; the second is told immediately and offered the next available times. Without the hold both believe they have it and one discovers otherwise on arrival.
A refresh token is revoked because the granting user left or changed their password.
Writes start failing for that calendar only. The failure is surfaced to staff rather than retried silently, and it is the main argument for a service account over per-user consent.
Google returns a rate-limit error mid-booking.
The booking is recorded and the calendar write is queued with backoff. The customer receives a confirmation because their appointment exists; telling them it failed because of a third-party quota is not acceptable.
A practitioner deletes a bot-created event directly in Google Calendar.
The watch channel reports it and the booking is marked cancelled, with the customer notified. Treating the bot as the only writer means the calendar and the bot diverge the first time someone uses the tool they already have.
Availability in the UAE and the wider GCC
Global
No regional restriction. Any Google account or Workspace domain can be connected, which is part of why it is the default in this market.
Google Workspace customers
A service account with domain-wide delegation is strongly preferable — it survives staff turnover, whereas per-user OAuth consent does not.
Personal Gmail accounts
Works, using per-user OAuth. Fine for a single practitioner; fragile for a business, because the consent belongs to a person rather than the organisation.
Data residency requirements
Appointment data lives in Google's infrastructure. Where a regulator requires local residency, this is a decision to take with your counsel rather than an implementation detail.
When not to use this integration
- Your practitioners do not actually use Google Calendar. Integrating with the calendar they ignore produces a system that is correct and useless.
- Scheduling depends on a clinical judgement about duration. The calendar will accept whatever the bot writes, including a diary that looks full and runs late.
- Your regulator requires appointment data to stay in-country. That is a decision for counsel, not an integration setting.
- You need a full practice management system. This synchronises a diary; it does not do billing, records or clinical workflow.
What it runs on
| Component | Version | Why |
|---|---|---|
| Cloudflare Workers | current | OAuth token refresh, availability queries and queued writes. |
| Cloudflare D1 | current | Provisional holds, booking records and watch channel state. |
| Cloudflare KV | current | Short-lived availability cache to stay inside quota during a rush. |
| Zod | 4.4 | Validation of API responses and push notification payloads. |
Questions that come up during scoping
What actually causes double bookings?
The gap between offering a slot and writing it. Re-checking at write time narrows it but cannot close it, because the check and the insert are two operations. A short-lived provisional hold taken before the customer confirms is what closes it.
Should we use a service account or per-user OAuth?
A service account with domain-wide delegation if you are on Google Workspace. Per-user consent belongs to the person who granted it, so it breaks when they leave — which tends to happen at the least convenient moment.
Does the bot read the content of existing appointments?
No. Availability uses the freebusy endpoint, which returns busy intervals without event detail. It is cheaper, it avoids reading patient or client information the bot has no reason to see, and it is easier to justify to anyone asking.
What happens when staff edit the calendar directly?
The bot sees it through a push notification channel and updates its own state, including notifying a customer whose appointment was removed. Assuming the bot is the only writer is how the two diverge within a week.
What if Google is rate-limiting us during the morning rush?
The booking is recorded locally and the calendar write is queued with backoff, so the customer still gets a confirmation. Their appointment exists; the calendar catches up. Failing the customer because of a third-party quota would be the wrong trade.
How do recurring blocks work?
Availability is computed against expanded instances rather than recurrence rules, because an exception to a single occurrence is its own record. Handling only the rule produces a bot that cheerfully offers the one week that was cancelled.
Related reading
For businesses on Microsoft 365 rather than Google, the equivalent is the Outlook Calendar integration.
Where scheduling rules already live in a booking tool, compare against the Calendly integration.
The bot this sits behind, including the hold mechanics, is the booking build.
Other systems a booking flow commonly writes to are covered across the full integration list.