Outlook-koppeling: methoden en functionele achtergrond
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) | |
|---|---|---|
| Wanneer | Eén persoonlijke of gedeelde agenda | Veel zaal-/resource-mailboxen, op schaal |
| Authenticatie | Interactieve 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-bron | De standaardagenda van de ingelogde gebruiker (me/…). | Per zaal-mailbox (users/{room-upn}/…), elk gekoppeld aan een eigen i-Reserve-object. |
| Richting | Bidirectioneel: 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 object | Eé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.nextLinken bewaart de@odata.deltaLinkals 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:
- Matchen op bestaande boeking — eerst op de opgeslagen externe event-id (veld
ires_field), als fallback op een[boeking_id]-suffix in het onderwerp. - Verwijderd / geannuleerd (
@removedofisCancelled) → de gekoppelde boeking krijgt de annuleer-status en wordt ontkoppeld (mits niet in een lock-status). - 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.
- 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.





