Functionele omschrijving
Beheer > Integraties > Google Calendar

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.list op calendars/{calendar-id}/events met een sync-token voor incrementele (delta) sync; bij de eerste run een venster van −90 tot +365 dagen. Pagineren via nextPageToken, het nextSyncToken wordt 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

  1. Matchen op bestaande boeking — eerst op de opgeslagen externe event-id (veld ires_field, default external_id), als fallback op een [boeking_id]-suffix in de titel.
  2. Geannuleerd (event-status cancelled) → de gekoppelde boeking krijgt de annuleer-status en wordt ontkoppeld (mits toegestaan).
  3. 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).
  4. 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 — het ires_field is de betrouwbare koppeling.