Google Calendar-koppeling: methode en functionele achtergrond
De Google Calendar-koppeling synchroniseert afspraken tussen een Google Calendar (Google Workspace of een gewoon Google-account) en i-Reserve. De koppeling praat rechtstreeks met de Google Calendar API v3 over OAuth 2.0. Dit artikel beschrijft de functionele achtergrond: de koppelmethode, hoe de synchronisatie werkt en wat de beperkingen zijn.
Koppelmethode: gedelegeerde OAuth
De koppeling werkt met gedelegeerde authenticatie (OAuth 2.0 authorization-code-flow): één Google-gebruiker logt eenmalig in en geeft toestemming, waarna i-Reserve een access_token + refresh_token bewaart en de tokens automatisch ververst. Er is geen service-account- of domain-wide-delegation-modus (anders dan bij Outlook, dat ook een app-only modus voor zaal-mailboxen kent). De koppeling is dus gebruikersgericht: hij werkt vanuit de agenda's waar die ene gebruiker toegang toe heeft.
Gevraagde scopes:
https://www.googleapis.com/auth/calendar.readonly— agenda's lijsten en afspraken lezen.https://www.googleapis.com/auth/calendar.events— afspraken aanmaken, wijzigen en verwijderen.
De consent wordt aangevraagd met access_type=offline (levert het refresh-token) en prompt=consent.
Meerdere agenda's: object → agenda-mapping
Eén koppeling kan meerdere Google-agenda's bedienen via een object → agenda-mapping: per i-Reserve-object kies je naar welke Google-agenda (calendar-id) afspraken gaan. Een wildcard (*) dient als standaard-agenda voor objecten zonder eigen regel. Voor outbound wordt de agenda van het object van de boeking gebruikt; voor inbound wordt de agenda gevolgd die bij het inbound-object hoort (of de eerste gekoppelde agenda).
Anders dan de Outlook-koppeling is er geen apart zaal-/resource-mailbox-concept; resources koppel je door de betreffende Google-agenda aan een i-Reserve-object te mappen.
Hoe de synchronisatie werkt
De koppeling is bidirectioneel en gebruikt zowel push als polling.
- Inbound (Google → i-Reserve) leest via
events.listopcalendars/{calendar-id}/eventsmet een sync-token voor incrementele (delta) sync; bij de eerste run een venster van −90 tot +365 dagen. Pagineren vianextPageToken, hetnextSyncTokenwordt bewaard voor de volgende ronde. - Push: i-Reserve registreert een Google watch-channel (
events/watch) die wijzigingen naar een publiek endpoint pusht. Het channel verloopt en wordt door de cron automatisch vernieuwd zodra het binnen 2 dagen verloopt. Notificaties worden gerouteerd op channel-id. - Polling-fallback: had een agenda langer dan 30 minuten geen sync, dan queue't de cron een inbound-sync zodat gemiste notificaties alsnog worden opgehaald.
- Echo-preventie: tijdens het verwerken van inbound-events worden outbound-triggers bewust onderdrukt, zodat een binnenkomende wijziging niet meteen weer naar Google wordt teruggepusht (geen oneindige lus).
Inbound: van Google-afspraak naar boeking
- Matchen op bestaande boeking — eerst op de opgeslagen externe event-id (veld
ires_field, defaultexternal_id), als fallback op een[boeking_id]-suffix in de titel. - Geannuleerd (event-status
cancelled) → de gekoppelde boeking krijgt de annuleer-status en wordt ontkoppeld (mits toegestaan). - Bestaande boeking → alleen datum/tijd worden bijgewerkt; de boekingsstatus blijft. Toegestaan als het event via deze koppeling is aangemaakt (kanaal
external), of als “toestaan boeking-update” aanstaat. Met “negeer validatiefouten bij update” worden wijzigingen ook bij een conflict toegepast (anders gelogd als opmerking). - Nieuw → er wordt een boeking aangemaakt op het gekoppelde object (kanaal
external/google), met de afspraak-titel/omschrijving als opmerking, in de ingestelde “inbound status”.
Outbound: van boeking naar Google-afspraak
Op basis van de boekingsstatus maakt i-Reserve afspraken aan (POST events), werkt ze bij (PATCH events/{id}) of verwijdert ze (DELETE events/{id}), gestuurd door “aanmaken op status” en “verwijderen op status” (de annuleer-status verwijdert altijd). Extra mogelijkheden:
- Google Meet-link aanmaken (optioneel) en de join-URL in een boekingsveld bewaren. Bij een update wordt een bestaande Meet-link behouden (niet opnieuw gegenereerd).
- Herinneringen: een popup- en/of e-mailherinnering, in minuten voor aanvang.
- Klant als deelnemer toevoegen (optioneel) op basis van de klantgegevens.
Beperkingen
- Alleen gedelegeerd (één OAuth-gebruiker). Geen service-account / domain-wide delegation; resources koppel je via de object→agenda-mapping.
- De koppeling werkt binnen de toegang van die ene gebruiker en binnen de Google Calendar API-quota van het project.
- Inbound-matching valt bij ontbrekende externe id terug op een
[boeking_id]-titel-suffix; een hergebruikte titel kan theoretisch de verkeerde boeking raken — hetires_fieldis de betrouwbare koppeling.





