Могу ли я синхронизировать события календаря с помощью Microsoft Graph API?
Я работаю с Microsoft Graph API, чтобы попытаться синхронизировать события календаря из Outlook. Я смотрел на эту статью, касающуюся API Outlook, в которой предлагалось добавить заголовок odata.track-changes
на мой запрос, и я бы получил deltaToken
, который я мог бы использовать в последующем запросе для извлечения только тех событий, которые были обновлены или созданы с момента последней синхронизации.
Я успешно получаю события, но не получаю обратно deltaToken: /
Это поддерживается только в Outlook API? Граф имеет ответ Preference-Applied: odata.track-changes
, так что это подтверждает мой заголовок. Вот мой пример запроса:
GET /v1.0/me/calendar/calendarView
?startDateTime=2016-09-01T00:00:00.0000000
&endDateTime=2099-01-01T00:00:00.0000000
HTTP/1.1
Host: graph.microsoft.com
Authorization: Bearer XXX
Prefer: odata.track-changes
Prefer: odata.maxpagesize=3 //for testing
Cache-Control: no-cache
И мой пример ответа:
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('')/calendar/calendarView",
"value": [
{
"@odata.etag": "",
"id": "",
"createdDateTime": "2016-08-04T14:00:25.8552351Z",
"lastModifiedDateTime": "2016-08-25T14:43:54.9950828Z",
"changeKey": "",
"categories": [
"Orange category"
],
"originalStartTimeZone": "Eastern Standard Time",
"originalEndTimeZone": "Eastern Standard Time",
"responseStatus": {
"response": "organizer",
"time": "0001-01-01T00:00:00Z"
},
"iCalUId": "",
"reminderMinutesBeforeStart": 15,
"isReminderOn": true,
"hasAttachments": false,
"subject": "Closing on House",
"body": {
"contentType": "html",
"content": ""
},
"bodyPreview": "",
"importance": "normal",
"sensitivity": "normal",
"start": {
"dateTime": "2016-09-08T19:30:00.0000000",
"timeZone": "UTC"
},
"end": {
"dateTime": "2016-09-08T21:30:00.0000000",
"timeZone": "UTC"
},
"location": {
"displayName": "245 E Main St",
"address": {
"street": "245 E Main St",
"city": "Somewhere",
"state": "NY",
"countryOrRegion": "United States",
"postalCode": ""
}
},
"isAllDay": false,
"isCancelled": false,
"isOrganizer": true,
"recurrence": null,
"responseRequested": true,
"seriesMasterId": null,
"showAs": "busy",
"type": "singleInstance",
"attendees": [],
"organizer": {
"emailAddress": {
"name": "",
"address": ""
}
},
"webLink": "https://outlook.office365.com/owa/?ItemID="
},
{
"@odata.etag": "",
"id": "",
"createdDateTime": "2016-08-19T18:02:39.0607411Z",
"lastModifiedDateTime": "2016-08-19T18:04:10.548447Z",
"changeKey": "",
"categories": [
"Green category"
],
"originalStartTimeZone": "UTC",
"originalEndTimeZone": "UTC",
"responseStatus": {
"response": "organizer",
"time": "0001-01-01T00:00:00Z"
},
"iCalUId": "",
"reminderMinutesBeforeStart": 15,
"isReminderOn": true,
"hasAttachments": false,
"subject": "Moving (off work)",
"body": {
"contentType": "html",
"content": ""
},
"bodyPreview": "",
"importance": "normal",
"sensitivity": "normal",
"start": {
"dateTime": "2016-09-10T00:00:00.0000000",
"timeZone": "UTC"
},
"end": {
"dateTime": "2016-09-13T00:00:00.0000000",
"timeZone": "UTC"
},
"location": {
"displayName": "",
"address": {}
},
"isAllDay": true,
"isCancelled": false,
"isOrganizer": true,
"recurrence": null,
"responseRequested": true,
"seriesMasterId": null,
"showAs": "oof",
"type": "singleInstance",
"attendees": [],
"organizer": {
"emailAddress": {
"name": "",
"address": ""
}
},
"webLink": "https://outlook.office365.com/owa/?ItemID="
},
{
"@odata.etag": "",
"id": "",
"createdDateTime": "2016-09-13T19:05:20.8438647Z",
"lastModifiedDateTime": "2016-09-13T19:05:22.1899702Z",
"changeKey": "",
"categories": [],
"originalStartTimeZone": "America/New_York",
"originalEndTimeZone": "America/New_York",
"responseStatus": {
"response": "organizer",
"time": "0001-01-01T00:00:00Z"
},
"iCalUId": "",
"reminderMinutesBeforeStart": 15,
"isReminderOn": true,
"hasAttachments": false,
"subject": "Coffee Break",
"body": {
"contentType": "html",
"content": ""
},
"bodyPreview": "",
"importance": "normal",
"sensitivity": "normal",
"start": {
"dateTime": "2016-09-15T20:15:00.0000000",
"timeZone": "UTC"
},
"end": {
"dateTime": "2016-09-15T21:15:00.0000000",
"timeZone": "UTC"
},
"location": {
"displayName": "",
"address": {}
},
"isAllDay": false,
"isCancelled": false,
"isOrganizer": true,
"recurrence": null,
"responseRequested": true,
"seriesMasterId": null,
"showAs": "busy",
"type": "singleInstance",
"attendees": [],
"organizer": {
"emailAddress": {
"name": "",
"address": ""
}
},
"webLink": "https://outlook.office365.com/owa/?ItemID="
}
]
}
Я отредактировал все, что я думал, может быть слегка чувствительным. В конечном счете, мое приложение Laravel пытается синхронизировать события, которые начинаются 4 месяца назад, и идти навсегда в будущее.
Если есть более эффективный / лучший способ сделать это, я открыт для предложений. Если это имеет значение, эти результаты были получены с почтальоном. Любая помощь или ясность по этому вопросу приветствуется.
1 ответ
В итоге я использовал фильтр odata, вот так:
https://graph.microsoft.com/beta/me/calendar/calendarView?startDateTime=2016-05-01T00:00:00Z&endDateTime=2099-01-01T00:00:00Z&$filter=type eq 'singleInstance' and lastModifiedDateTime eq '2016-09-20T07:30:00+00:00'
Это будет получать все события календаря, запланированные между 2016-05-01T00:00:00Z (May 1st, 2016, midnight, UTC
а также 2099-01-01T00:00:00Z (January 1st, 2099, midnight, UTC)
где тип события singleInstance
(не повторяющееся событие) и lastModifiedDateTime
после последней синхронизации (в этом примере 2016-09-20T07:30:00+00:00
).
Несколько подводных камней с этим:
- Очевидно, что это не URL-кодированный. Вы должны были бы сделать это.
- Убедитесь, что + в примере lastModifiedDateTime правильно закодирован в
%2B
иначе Graph API будет рассматривать его как пробел и отклонять его. - Если вы не отфильтровываете повторяющиеся события, вы получите каждое повторяющееся событие с настоящего момента до 2099 года. Это характер выбора списка
calendarViews
в отличие отevents
,
Если бы я мог сделать это снова, я бы, вероятно, вернулся бы и просто сделал полную синхронизацию календаря, которую поддерживает Graph (я полагаю). Я просто не хотел синхронизировать весь календарь, только диапазон дат, но, похоже, это было обреченное усилие.
Но, несмотря на отсутствие повторяющихся событий, это работает.
ОБНОВИТЬ
В итоге я отказался от этой реализации в основном из-за постоянных ловушек, с которыми я столкнулся при поддержании целостности синхронизации данных, отсутствия повторяющихся событий и т. Д. Вместо этого я извлекаю события календаря в реальном времени и поддерживаю кэш. Просто несколько советов на случай, если кто-нибудь еще окажется в моей ситуации.