获取日历视图中事件的增量更改

通过使用 delta 查询,你可以在指定的日历或在日历中定义的事件集合(作为日历视图)中获取新的、更新的或删除的事件。 本文将介绍后一种情况,即在日历视图中获取此类对事件的增量更改。

注意

前者的功能(获取对日历中未绑定到固定开始日期和结束日期范围的事件的增量更改)目前仅在 beta 版本中可用。 有关更多信息,请参阅 delta 函数。

日历视图是日期/时间范围内的事件的集合, (。/me/calendarView) 用户的默认日历或其他指定日历或组日历。 返回的事件可能包括单个实例或定期系列事件的发生和例外情况。 借助 delta 数据,你能够维护和同步本地存储的用户事件,而无需每次从服务器提取整组用户事件。

增量查询既支持可检索指定日历视图中的所有事件的完全同步,也支持可检索自上次同步后日历视图中发生变化的事件的增量同步。 通常情况下,开始时会执行一次完全同步,随后会定期获取该日历视图的增量更改。

跟踪日历视图中的事件更改

在日历视图中对事件执行增量查询专门针对你指定的日历和日期/时间范围。 若要跟踪多个日历中的更改,需要单独跟踪各个日历。

跟踪日历视图中的事件更改通常需要使用 delta 函数按轮发出一个或多个 GET 请求。 初始 GET 请求与 列出 calendarView 非常相似,区别在于要包括 delta 函数。 下面是登录用户的默认日历中,“日历”视图的初始 GET 增量请求:

GET /me/calendarView/delta?startDateTime={start_datetime}&endDateTime={end_datetime}

使用 delta 函数的 GET 请求返回以下任一内容:

  • @odata.nextLink(包含具有 delta 函数调用和 $skipToken 的 URL),或
  • @odata.deltaLink(包含具有 delta 函数调用和 $deltaToken 的 URL)。

这些令牌是状态令牌,负责对 startDateTimeendDateTime 参数以及初始增量查询 GET 请求中的其他任何查询参数进行编码。 在后续请求中,无需包括这些参数,因为它们已在令牌中编码。

状态令牌对客户端完全不透明。 若要继续一轮事件更改跟踪,只需将最后一个 GET 请求返回的 @odata.nextLink@odata.deltaLink URL 复制并应用到同一日历视图的下一个 delta 函数调用即可。 响应中返回的 @odata.deltaLink 表示当前一轮更改跟踪已完成。 可以保存 @odata.deltaLink URL,并在开始下一轮时使用。

要了解如何使用 @odata.nextLink@odata.deltaLink URL,请参阅 示例

在日历视图的增量查询中使用查询参数

  • 添加 startDateTimeendDateTime 参数可以定义日历视图的日期/时间范围。
  • 不支持 $select

可选的请求头

每个 delta 查询 GET 请求在响应中返回包含一个或多个事件的集合。 可以视需要指定请求头 Prefer: odata.maxpagesize={x},设置响应中可包含的事件数上限。

示例:同步日历视图中的事件

以下示例展示了如何通过 3 个请求同步特定时间范围内的用户默认日历。 此日历视图中有 5 个事件。

为简洁起见,示例响应仅显示一部分事件属性。 在实际调用中,大多数事件属性都会返回。

请了解 下一轮 将执行的操作。

第 1 步:示例第一个请求

在该示例中,由于登录用户的默认日历中的指定日历视图为首次同步,因此第一个同步请求不含任何状态令牌。 这一轮将返回此日历视图中的所有事件。

第一个请求指定以下内容:

  • startDateTimeendDateTime 参数的日期/时间值。
  • 可选的请求头odata.maxpagesize,表示一次返回 2 个事件。
GET https://graph.microsoft.com/v1.0/me/calendarView/delta?startdatetime=2016-12-01T00:00:00Z&enddatetime=2016-12-30T00:00:00Z HTTP/1.1
Prefer: odata.maxpagesize=2

示例第一个响应

响应包括两个事件和一个 @odata.nextLink 带有 的 skipToken响应标头。 URL 表示此日历视图中还有更多事件可获取。

HTTP/1.1 200 OK
Content-type: application/json

{
    "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#Collection(event)",
    "@odata.nextLink":"https://graph.microsoft.com/v1.0/me/calendarView/delta?$skiptoken=R0usmcCM996atia_s",
    "value":[
        {
            "@odata.type":"#microsoft.graph.event",
            "@odata.etag":"W/\"EZ9r3czxY0m2jz8c45czkwAAFXcvIQ==\"",
            "subject":"Plan shopping list",
            "body":{
                "contentType":"html",
                "content":""
            },
            "start":{
                "dateTime":"2016-12-09T20:30:00.0000000",
                "timeZone":"UTC"
            },
            "end":{
                "dateTime":"2016-12-09T22:00:00.0000000",
                "timeZone":"UTC"
            },
            "attendees":[

            ],
            "organizer":{
                "emailAddress":{
                    "name":"Samantha Booth",
                    "address":"samanthab@contoso.com"
                }
            },
            "id":"AAMkADNVxRAAA="
        },
        {
            "@odata.type":"#microsoft.graph.event",
            "@odata.etag":"W/\"EZ9r3czxY0m2jz8c45czkwAAFXcvIg==\"",
            "subject":"Pick up car",
            "body":{
                "contentType":"html",
                "content":""
            },
            "start":{
                "dateTime":"2016-12-10T01:00:00.0000000",
                "timeZone":"UTC"
            },
            "end":{
                "dateTime":"2016-12-10T02:00:00.0000000",
                "timeZone":"UTC"
            },
            "attendees":[

            ],
            "organizer":{
                "emailAddress":{
                    "name":"Samantha Booth",
                    "address":"samanthab@contoso.com"
                }
            },
            "id":"AAMkADVxSAAA="
        }
    ]
}

第 2 步:示例第二个请求

第二个请求指定上一个响应中返回的 @odata.nextLink URL。 请注意,不再需要像第一个请求一样指定相同的 startDateTimeendDateTime 参数,因为 skipToken URL 中的 @odata.nextLink 已将其编码并包含在内。

GET https://graph.microsoft.com/v1.0/me/calendarView/delta?$skiptoken=R0usmcCM996atia_s HTTP/1.1
Prefer: odata.maxpagesize=2

示例第二个响应

第二个响应中返回此日历视图中接下来的 2 个事件和另一个 @odata.nextLink(表示此日历视图中还有更多事件可获取)。

HTTP/1.1 200 OK
Content-type: application/json

{
    "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#Collection(event)",
    "@odata.nextLink":"https://graph.microsoft.com/v1.0/me/calendarView/delta?$skiptoken=R0usmci39OQxqJrxK4",
    "value":[
        {
            "@odata.type":"#microsoft.graph.event",
            "@odata.etag":"W/\"EZ9r3czxY0m2jz8c45czkwAAFXcvIw==\"",
            "subject":"Get food",
            "body":{
                "contentType":"html",
                "content":""
            },
            "start":{
                "dateTime":"2016-12-10T19:30:00.0000000",
                "timeZone":"UTC"
            },
            "end":{
                "dateTime":"2016-12-10T21:30:00.0000000",
                "timeZone":"UTC"
            },
            "attendees":[

            ],
            "organizer":{
                "emailAddress":{
                    "name":"Samantha Booth",
                    "address":"samanthab@contoso.com"
                }
            },
            "id":"AAMkADVxTAAA="
        },
        {
            "@odata.type":"#microsoft.graph.event",
            "@odata.etag":"W/\"EZ9r3czxY0m2jz8c45czkwAAFXcvJA==\"",
            "subject":"Prepare food",
            "body":{
                "contentType":"html",
                "content":""
            },
            "start":{
                "dateTime":"2016-12-10T22:00:00.0000000",
                "timeZone":"UTC"
            },
            "end":{
                "dateTime":"2016-12-11T00:00:00.0000000",
                "timeZone":"UTC"
            },
            "attendees":[

            ],
            "organizer":{
                "emailAddress":{
                    "name":"Samantha Booth",
                    "address":"samanthab@contoso.com"
                }
            },
            "id":"AAMkADVxUAAA="
        }
    ]
}

第 3 步:示例第三个请求

第三个请求继续使用上一个同步请求返回的最新 @odata.nextLink

GET https://graph.microsoft.com/v1.0/me/calendarView/delta?$skiptoken=R0usmci39OQxqJrxK4 HTTP/1.1
Prefer: odata.maxpagesize=2

示例第三个响应(即最终响应)

第三个响应中返回此日历视图中仅剩的事件,以及表示已完成同步此日历视图的 @odata.deltaLink URL。 保存并使用 @odata.deltaLink URL 在下一轮中同步此日历视图

HTTP/1.1 200 OK
Content-type: application/json

{
    "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#Collection(event)",
    "@odata.deltaLink":"https://graph.microsoft.com/v1.0/me/calendarView/delta?$deltatoken=R0usmcMDNGg0J1E",
    "value":[
        {
            "@odata.type":"#microsoft.graph.event",
            "@odata.etag":"W/\"EZ9r3czxY0m2jz8c45czkwAALZu97g==\"",
            "subject":"Rest!",
            "body":{
                "contentType":"html",
                "content":""
            },
            "start":{
                "dateTime":"2016-12-12T02:00:00.0000000",
                "timeZone":"UTC"
            },
            "end":{
                "dateTime":"2016-12-12T07:30:00.0000000",
                "timeZone":"UTC"
            },
            "location":{
                "displayName":"Home"
            },
            "attendees":[

            ],
            "organizer":{
                "emailAddress":{
                    "name":"Samantha Booth",
                    "address":"samanthab@contoso.com"
                }
            },
            "id":"AAMkADj1HuAAA="
        }
    ]
}

下一轮:示例第一个请求

使用上一轮中@odata.deltaLink返回的 ,可以只获取从那以后此日历视图中发生变化(已添加、删除或更新)的事件。 假设你愿意在响应中保持页面大小上限不变,下一轮的第一个请求如下所示:

GET https://graph.microsoft.com/v1.0/me/calendarView/delta?$deltatoken=R0usmcMDNGg0J1E HTTP/1.1
Prefer: odata.maxpagesize=2

下一轮:示例第一个响应

HTTP/1.1 200 OK
Content-type: application/json

{
    "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#Collection(event)",
    "@odata.deltaLink":"https://graph.microsoft.com/v1.0/me/calendarView/delta?$deltatoken=R0usmcFuQtZdtpk4",
    "value":[
        {
            "@odata.type": "#microsoft.graph.event",
            "id": "AAMkADk0MGFkODE3LWE4MmYtNDRhOS04OGQLkRkXbBznTvAADb6ytyAAA=",
            "@removed": {
                "reason": "deleted"
            }
        },
        {
            "@odata.type":"#microsoft.graph.event",
            "@odata.etag":"W/\"EZ9r3czxY0m2jz8c45czkwAALZu97w==\"",
            "subject":"Attend service",
            "body":{
                "contentType":"html",
                "content":""
            },
            "start":{
                "dateTime":"2016-12-25T06:00:00.0000000",
                "timeZone":"UTC"
            },
            "end":{
                "dateTime":"2016-12-25T07:30:00.0000000",
                "timeZone":"UTC"
            },
            "location":{
                "displayName":"Chapel of Saint Ignatius",
                "address":{
                    "street":"900 Broadway",
                    "city":"Seattle",
                    "state":"WA",
                    "countryOrRegion":"United States",
                    "postalCode":""
                },
                "coordinates":{
                    "latitude":47.6105,
                    "longitude":-122.321
                }
            },
            "attendees":[

            ],
            "organizer":{
                "emailAddress":{
                    "name":"Samantha Booth",
                    "address":"samanthab@contoso.com"
                }
            },
            "id":"AAMkADj1HvAAA="
        }
    ]
}