Calendar bots: which calendar is right when two disagree
Two-way sync, timezones, recurring events and changes made outside the bot. The integration problems that decide whether scheduling works.
On this page
- What we'll cover
- A calendar is not a booking system
- Which source is authoritative
- Changes made outside the bot
- Timezones, and the ways they bite
- Building it with CodeWords
- Recurring events
- What "busy" actually means
- Multiple calendars for one person
- Writing an event somebody else will read
- Making it survive
- Limits worth knowing about
- What to settle first
- Frequently asked questions
- Related reading
Connecting a bot to a calendar reads like a small integration task. Read the free slots, write the new event, done. It stays small until the calendar is a real one belonging to real people, at which point a set of problems arrives that have nothing to do with conversation design and everything to do with the calendar being a shared, mutable thing that other software is also writing to.
Those problems are ordinary and well understood, and they are the reason scheduling bots feel unreliable. Almost all of them come down to one question: when two sources disagree about what is happening on Thursday, which one is right.
What we'll cover
- A calendar is not a booking system
- Which source is authoritative
- Changes made outside the bot
- Timezones, and the ways they bite
- Building it with CodeWords
- Recurring events
- What "busy" actually means
- Multiple calendars for one person
- Writing an event somebody else will read
- Making it survive
- Limits worth knowing about
- What to settle first
- Frequently asked questions
A calendar is not a booking system
The distinction worth making before any code.
A calendar records what people intend to do. It is personal, mutable by its owner, full of things that are not appointments, and it has no concept of capacity, resources or rules.
A booking system manages appointments against capacity. It knows what a service is, how long it takes, who can do it and what else must be free.
Bots built directly on a calendar inherit all of the calendar's assumptions, which is fine for a consultant booking calls and wrong for anything with resources or rules. Where you have a booking system, use it and let it own the calendar. Where you do not, know that you are building the missing rules yourself.
Which source is authoritative
The question everything else depends on, and it needs a single answer written down.
If the bot keeps its own record of bookings and also writes to a calendar, you have two systems that can disagree. They will disagree, because somebody will edit the calendar entry directly.
Two workable designs.
The calendar is the truth. The bot reads it before every decision and writes to it, holding no state of its own about what is booked. Simple, resilient, and limited to what a calendar can express.
Your own record is the truth, and the calendar is a view. More capable, and you must handle somebody editing the view, either by ignoring those edits and overwriting them or by detecting and reconciling them.
The design to avoid is both being partly authoritative, which produces failures nobody can reproduce. Pick one, write it down, and make every part of the system behave as though it is true.
Changes made outside the bot
People move things. They drag an appointment an hour later, delete one, or accept an invitation that overlaps.
Three things to decide explicitly.
Does the bot notice? Polling on a schedule or subscribing to change notifications. Without either, the bot's view drifts and it starts offering slots that are taken.
Who gets told? A customer whose appointment was moved by somebody dragging it in a calendar should hear about it, and that is easy to forget because the change did not happen in your system.
What wins? If the bot booked it and a person moved it, the person is usually right, and your system needs to accept that rather than restoring its own version.
The failure mode people hit is silent divergence: the calendar says one thing, the bot believes another, and the customer gets a reminder for an appointment that moved last Tuesday.
Timezones, and the ways they bite
The classic source of scheduling bugs, and the failures are specific.
Store instants, not wall-clock times. An appointment is a moment, and rendering it for a viewer is a separate step.
Three timezones can be involved: the customer's, the business's, and whatever the server thinks it is. Be explicit about which one any given time is expressed in.
Daylight saving transitions break recurring events and anything computed by adding hours. An appointment "same time next week" across a transition is not the same instant.
Always show the zone when the customer might be elsewhere, and show the day name alongside the date so an off-by-one is visible.
Ambiguous local times exist. During a clock change some local times occur twice or not at all, which sounds pedantic until somebody books into one.
A simple safeguard: echo the confirmed time back in the customer's own terms, with the day name, and let them correct it.
Building it with CodeWords
CodeWords connects to more than 3,000 integrations, and the connection is made once and reused.
- Open CodeWords and start a new automation.
- Describe what should happen in plain language to Cody, the automation builder, including which source is authoritative and what happens when somebody changes something directly.
- Authorize the connections to your calendar or booking system and the channel customers use.
- Describe the exceptions: a slot taken since it was offered, an event moved outside the bot, a customer in another timezone, a recurring appointment.
- Recheck availability at the moment of confirmation rather than trusting the check from the start of the conversation.
You describe the outcome; Cody builds it, connects it, and deploys it. The free plan covers light use, with Pro at $39 per month and Business at $100 per month as usage grows; details are on the pricing page.
Recurring events
Deceptively hard, and the source of a good share of scheduling bugs.
A recurring event is a rule plus a set of exceptions, and the exceptions are where the trouble lives. One occurrence moved. One cancelled. The series edited from a date forwards. The series ended and recreated.
Two practical rules. When somebody changes one occurrence, be clear whether you are changing that one or the series, and ask rather than assuming, because getting it wrong moves appointments for people who were not involved. And when reading availability, expand the series properly including its exceptions rather than assuming every occurrence happens, or you will treat cancelled slots as busy.
Where a business genuinely runs on recurring appointments, this is an argument for a booking system that models them rather than a calendar that represents them.
What "busy" actually means
A calendar contains many things, and treating them all as unavailable produces a diary with no space in it.
Tentative invitations somebody has not accepted. All-day events, which usually mean a note rather than a whole day blocked. Events marked free. Declined invitations that remain visible. Personal entries in a calendar shared for work.
Decide which of these block a booking and which do not, and be explicit. The common default of treating anything present as busy makes the bot useless within a week, because people's calendars are full of things that are not appointments.
The opposite failure, ignoring everything without a confirmed attendee, books over genuine commitments. There is no universal answer, which is why it has to be a stated rule.
Multiple calendars for one person
Most people have several: work, personal, a shared team one, and something from another system.
Availability is the union of the ones that matter, and which matter is a decision. Reading only the work calendar books over a personal commitment. Reading everything exposes personal information to a system that did not need it.
The workable pattern is to read availability from a nominated set, treat the detail of personal entries as opaque, and write only to one calendar so there is no ambiguity about where a booking lives.
Writing an event somebody else will read
The event your bot creates is read by a person on their phone, usually in a hurry.
Put what it is and who it is with in the title, since that may be all that is visible. Put the context in the description: what they asked for, how to contact them, anything they said that matters. Include the location or the link. Set a reminder that matches how your team actually works.
And write it in the language of whoever reads it. An event titled with an internal reference number is a calendar entry nobody can act on without looking something up.
Making it survive
Write down which source is authoritative, and make everything obey it.
Detect external changes by polling or subscription, and tell the customer.
Store instants and render per viewer.
Recheck at confirmation, never rely on the earlier read.
Reconcile periodically, comparing your record against the calendar to catch drift.
Limits worth knowing about
A calendar has no concept of capacity or resources, so any rules of that kind are yours to build.
Two authoritative sources produce unreproducible failures.
Recurring events are rules with exceptions, and the exceptions are most of the difficulty.
Busy is ambiguous, and deciding what counts is a business rule rather than a technical one.
Someone will always change something directly, so a design assuming otherwise fails in week one.
What to settle first
Which source is authoritative, written down in one sentence, before any integration work. Either the calendar is the truth and your system reads it every time, or your record is the truth and the calendar is a view you maintain. Everything ambiguous in a scheduling bot traces back to this having been left unanswered.
Two habits make the difference. Recheck availability at the moment of confirmation rather than trusting the read from the start of the conversation, since that gap is where double-bookings are born. And echo the time back with the day name and the timezone, because it costs one line and catches nearly every date error before it becomes somebody arriving on the wrong day.
Frequently asked questions
Is a calendar enough to build a booking bot on?
For simple cases like booking calls, yes. For anything involving capacity, resources or rules, a calendar has no concept of those and you are building the missing booking system yourself.
What is the most important design decision?
Which source is authoritative. Either the calendar is the truth or your own record is, and any design where both are partly authoritative produces failures nobody can reproduce.
What happens when someone edits the calendar directly?
They will, so the bot has to notice through polling or change notifications, decide what wins, and tell the customer if their appointment moved. Silent divergence is the commonest failure here.
How should timezones be handled?
Store instants rather than wall-clock times, be explicit about which zone any time is expressed in, and always show the zone and the day name when the customer might be elsewhere.
What breaks around daylight saving?
Recurring events and anything computed by adding hours. Some local times also occur twice or not at all during a transition, which matters if somebody books into one.
Why are recurring events difficult?
They are a rule plus exceptions, and the exceptions carry the complexity. Always ask whether a change applies to one occurrence or the series, and expand exceptions properly when reading availability.
What counts as busy?
A decision you have to make. Tentative invitations, all-day events, events marked free, declined invitations and personal entries all need an explicit rule, or the diary will look either completely full or wrongly empty.
How do I handle someone with several calendars?
Read availability from a nominated set, treat personal entry detail as opaque, and write bookings to exactly one calendar so there is no ambiguity about where they live.
What should the created event contain?
What it is and who it is with in the title, context and contact details in the description, the location or link, and a reminder matching how the team works. Never an internal reference alone.
How do I prevent double-booking?
Recheck availability at the moment of confirmation rather than relying on the read from the start of the conversation, and hold offered slots briefly while waiting for a reply.