Functionele omschrijving
Beheer > Integraties > Outlook

De Outlook-koppeling synchroniseert afspraken tussen een Microsoft 365 / Outlook-agenda en i-Reserve. De koppeling praat rechtstreeks met de Microsoft Graph REST API v1.0 over OAuth 2.0 — er wordt geen EWS (Exchange Web Services) of MSAL-SDK gebruikt. Dit artikel beschrijft de functionele achtergrond: welke koppelmethoden er zijn, hoe de synchronisatie werkt en wat de beperkingen zijn.

Twee koppelmethoden

De methode wordt bepaald door de authenticatiemodus (config-key auth_mode). Beide methoden kunnen door dezelfde Azure-app worden bediend; het zijn aparte permissie-typen in Entra ID.

 Gedelegeerd (delegated)Applicatie (application / app-only)
WanneerEén persoonlijke of gedeelde agendaVeel zaal-/resource-mailboxen, op schaal
AuthenticatieInteractieve OAuth (authorization code). Eén gebruiker logt in en geeft toestemming; i-Reserve bewaart een access- en refresh-token.Niet-interactief (client credentials). De app authenticeert als zichzelf en haalt zelf een app-only token op (~1 uur geldig, geen refresh-token).
Agenda-bronDe standaardagenda van de ingelogde gebruiker (me/…).Per zaal-mailbox (users/{room-upn}/…), elk gekoppeld aan een eigen i-Reserve-object.
RichtingBidirectioneel: inbound (Outlook → i-Reserve) én outbound (i-Reserve → Outlook).Alleen inbound. Outbound is uitgeschakeld omdat een app-only token geen ingelogde gebruiker (me) heeft.
Koppeling objectEén i-Reserve-object.Per zaal een eigen object (room → object-tabel). Schaalt naar honderden zalen per klant.

Vuistregel: gebruik gedelegeerd voor één agenda en één object. Gebruik applicatie zodra je zaal-/resource-mailboxen wilt koppelen — die kunnen niet interactief inloggen en hebben geen licentie, dus gedelegeerd werkt daar niet.

Hoe de synchronisatie werkt

Wijzigingen komen near-realtime binnen via een Graph change-notification subscription (webhook); een cron-proces vangt gemiste notificaties op via polling. De koppeling gebruikt dus bewust beide kanalen.

  • Inbound leest met een Graph delta-query (calendarView/delta) over een venster van −90 dagen tot +365 dagen, pagineert via @odata.nextLink en bewaart de @odata.deltaLink als sync-token. Per zaal (application) is er een eigen sync-token en eigen webhook.
  • Webhooks posten naar een publiek endpoint. Een subscription verloopt na 3 dagen en wordt door de cron automatisch vernieuwd zodra die binnen 2 dagen verloopt. In application-modus is er één subscription per zaal; notificaties worden op subscription-id gerouteerd zodat exact de juiste zaal wordt gesynchroniseerd.
  • 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.

Inbound: van Outlook-afspraak naar boeking

Per Outlook-event bepaalt i-Reserve of het een aanmaak, wijziging of annulering is:

  1. Matchen op bestaande boeking — eerst op de opgeslagen externe event-id (veld ires_field), als fallback op een [boeking_id]-suffix in het onderwerp.
  2. Verwijderd / geannuleerd (@removed of isCancelled) → de gekoppelde boeking krijgt de annuleer-status en wordt ontkoppeld (mits niet in een lock-status).
  3. Bestaande boeking → datum en tijd worden bijgewerkt, gegated door “toestaan boeking-update” en “negeer validatiefouten”. Boekingen die via deze koppeling zijn aangemaakt volgen altijd de Outlook-wijziging.
  4. Nieuw → er wordt een boeking aangemaakt op het gekoppelde object (kanaal external/outlook), met onderwerp en omschrijving als opmerking. Kan de organisator aan een bestaande klant worden gekoppeld, dan wordt die klant gekoppeld en (indien ingesteld) de “status met klant” gebruikt.

Outbound (alleen gedelegeerd)

In gedelegeerde modus pusht i-Reserve afspraken naar Outlook op basis van de boekingsstatus: aanmaken (POST me/events), bijwerken (PATCH me/events/{id}) en verwijderen (DELETE me/events/{id}), gestuurd door de statussen “agenda-item aanmaken” en “verwijderen op status”. Optioneel wordt een Teams-vergaderlink aangemaakt en de klant als deelnemer toegevoegd.

Beperkingen

  • Outbound alleen in gedelegeerde modus. In application-modus worden outbound-triggers bewust overgeslagen en gelogd.
  • Per-zaal state (sync-token, webhook) wordt in de koppelconfiguratie opgeslagen; dit schaalt naar honderden zalen, maar één koppeling = één Azure-app/tenant.
  • Een app-only token leeft ~1 uur en wordt automatisch ververst; er is geen refresh-token.
  • Er is geen Graph room-list (places) auto-discovery: zaal-UPN's worden handmatig ingevoerd.