Jens Eriksson
Jens Eriksson

Reputation: 91

Microsoft Graph API: How to trace deleted calendar event occurrences?

I'm currently working on a Exchange Online integration project where we are using the Microsoft Graph API 1.0 to replicate the user's calendars to our system. It has been working fine so far but today I ran into a problem that I cannot solve:

How do you keep track of deletions of occurrences of recurring calendar events?

I have tried to work with 'Delta' links without success. Those requests only returns the series master together with all remaining occurrences.

E.g. First request:

GET /v1.0/users/dc7f4032-5f30-4441-a165-428aed9fb471/calendarview/delta?startdatetime=2019-04-11T00:00:00&enddatetime=2019-04-28T23:59:59

Then I request the nextLink so that I get the deltaLink, and then I request the deltaLink:

GET /v1.0/users/dc7f4032-5f30-4441-a165-428aed9fb471/calendarview/delta?$deltatoken=uwMsonT1N46Me49CO...(etc.)

Then I get the response:

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(event)",
    "@odata.deltaLink": "https://graph.microsoft.com/v1.0/users/dc7f4032-5f30-4441-a165-428aed9fb471/calendarview/delta?$deltatoken=uwMsonT1N46Me49COq9SDw0t_wB0xaeZEqH3MS63rea577XfZFFdjg0jwU6FzfSp9LnqeqbpBGm2ppJDuDiIP280MEFjk2Q9GYyNNdCAP__CjSKSGFQ9WKmL3TPyFeXhhYE9KgmWHF1cSrx7OYBT7zPrgwY0x5peeyjBEtqkAueuE2Pb8DH4iODU-vAp-lHVOzPmkkjNyef1NTNkgNv-kg.oOHzptXCwEphbnI7YFO7saexZ_c0hZj1a0o4ZjluzUU",
    "value": []
}

Subsequent calls to the deltaLink will continue to return: "value": [] as long as nothing has changed in the calendar.

Then I delete one of the occurrences in a series and then request the deltaLink again and then the MS Graph API only returns the master together with all remaining occurrences within the original timespan, without any trace of the deleted occurrence!

Anyone out there that has experience the same problem?

Upvotes: 7

Views: 1385

Answers (1)

ahash
ahash

Reputation: 510

I'll detail my implementation in the hope that it helps:

First: our backend is node, and we use the MSGraph node client for all API requests, which is worth mentioning as I am detailing some npms we use.

  • Sync operation ensues via a call to the api: /me/calendarView/delta?startdatetime=${startDate}&enddatetime=${endDate}. Note: this is for the initial sync -- use the nextLink or deltaLink here as per where you are in the sync process.
  • For received recurring events, we use the rrule npm and translate the recurrence pattern MS sends to an RRuleSet.
  • We generate event instances using the RRuleSet.
  • We create a collection of occurrences (type = occurrence) received from the MSGraph api call.
  • We create a collection of exceptions (type = exception) received from the MSGraph api call.
  • We generate a diff of event instances to figure out which occurrence dates are missing.
  • We update our RRuleSet with EXDates based on the date diff generated earlier.
  • Finally, we generate event instances from our updated RRuleSet for the recurring event in question.

Use the exceptions (i.e: one-off edited events in a recurring series) to create events as per your calendar requirements. Note: since one-off exceptions are not sent with type = occurrence, the event instance diff generated to calculate the EXDates is accurate.

Additional notes:

  • For correct daylight saving adjustments, use the windows-iana npm to translate between MS timezones and IANA timezones (if required), and ensure both the RRule and EXDates added to your RRuleSet make use of the tzid property.

  • If a recurring event is cancelled in Outlook calendar, all we get in the callback is the recurring event's id. Ensure you link your local event representation of one-off events with the recurring event's id so you can clean-up event instances / mark events as cancelled.

Things the MS API could do better:

  • Stop sending all occurrences in your only delta-supported calendar api! Send only the recurring event.
  • Send one-off exceptions and cancelled event-instances separately on initial sync unless the recurrence pattern changes in a manner where all event-instances need to be recalculated.
  • If an event instance in a recurring series is cancelled, send just that occurrence with the parent recurring event's id. Same for one-off events.
  • If a recurring event is cancelled, send a cancellation events for exceptions.
  • Send us recurrence rules as per RFC 5545!

Upvotes: 3

Related Questions