获取文件夹中邮件的增量更改Get incremental changes to messages in a folder

Delta 查询可通过调用一系列的 delta 函数查询文件夹中邮件的添加、删除或更新。Delta 数据使你可以维护和同步本地存储的用户邮件,而无需每次都从服务器中获取整组邮件。Delta query lets you query for additions, deletions, or updates to messages in a folder, by way of a series of delta function calls. Delta data enables you to maintain and synchronize a local store of a user's messages, without having to fetch the entire set of the user's messages from the server every time.

Delta 查询支持检索文件夹(例如,用户的收件箱)中所有邮件的完全同步,以及检索自上次同步以来该文件夹中所有已更改邮件的增量同步。通常,需要对文件夹中的所有邮件进行初始完全同步,之后可定期获取该文件夹的增量更改。Delta query supports both full synchronization that retrieves all of the messages in a folder (for example, the user's Inbox), and incremental synchronization that retrieves all of the messages that have changed in that folder since the last synchronization. Typically, you would do an initial full synchronization of all the messages in a folder, and subsequently, get incremental changes to that folder periodically.

跟踪文件夹中的邮件更改Track message changes in a folder

Delta 查询对每个文件夹分别执行操作。为跟踪文件夹层次结构中邮件的更改,需要分别跟踪每个文件夹。Delta query is a per-folder operation. To track the changes of the messages in a folder hierarchy, you need to track each folder individually.

跟踪邮件文件夹中的邮件更改通常需要使用 delta 函数按轮发出一个或多个 GET 请求。初始 GET 请求非常类似于获取邮件,区别在于要添加 delta 函数:Tracking message changes in a mail folder typically is a round of one or more GET requests with the delta function. The initial GET request is very much like the way you get messages, except that you include the delta function:

GET https://graph.microsoft.com/v1.0/me/mailFolders/{id}/messages/delta

使用 delta 函数的 GET 请求返回以下任一内容:A GET request with the delta function returns either:

  • nextLink(包含具有 delta 函数调用和 skipToken 的 URL),或A nextLink (that contains a URL with a delta function call and a skipToken), or
  • deltaLink(包含具有 delta 函数调用和 deltaToken 的 URL)。A deltaLink (that contains a URL with a delta function call and deltaToken).

这些令牌是对客户端完全不透明的状态令牌。若要继续一轮邮件更改跟踪,只需将最后一个 GET 请求返回的 URL 复制并应用到同一文件夹的下一个 delta 函数调用即可。响应中返回的 deltaLink 表示当前一轮更改跟踪已完成。可以保存 deltaLink URL,并在开始下一轮时使用。These tokens are state tokens that are completely opaque to the client. To proceed with a round of change tracking, simply copy and apply the URL returned from the last GET request to the next delta function call for the same folder. A deltaLink returned in a response signifies that the current round of change tracking is complete. You can save and use the deltaLink URL when you begin the next round.

若要了解如何使用 nextLinkdeltaLink URL,请参阅下面的示例See the example below to learn how to use the nextLink and deltaLink URLs.

在邮件的增量查询中使用查询参数Use query parameters in a delta query for messages

  • 像在任何 GET 请求中一样,你可以使用 $select 查询参数以仅指定获取最佳性能所需的属性。始终返回 id 属性。You can use a $select query parameter as in any GET request to specify only the properties your need for best performance. The id property is always returned.
  • 对于邮件,Delta 查询支持 $select$top$expandDelta query support $select, $top, and $expand for messages.
  • 提供对 $filter$orderby 的有限支持:There is limited support for $filter and $orderby:
    • 唯一支持的 $filter 表达式是 $filter=receivedDateTime+ge+{value}$filter=receivedDateTime+gt+{value}The only supported $filter expressions are $filter=receivedDateTime+ge+{value} or $filter=receivedDateTime+gt+{value}.
    • 在增量查询中应用 $filter 最多仅返回 5000 个邮件。Applying $filter in a delta query returns only up to 5,000 messages.
    • 唯一支持的 $orderby 表达式是 $orderby=receivedDateTime+desc。如果不包含 $orderby 表达式,则不能保证返回顺序。The only supported $orderby expression is $orderby=receivedDateTime+desc. If you do not include an $orderby expression, the return order is not guaranteed.
  • 不支持 $searchThere is no support for $search.

可选的请求标头Optional request header

每个 delta 查询 GET 请求在响应中返回包含一个或多个邮件的集合。Each delta query GET request returns a collection of one or more messages in the response. 可以视需要指定请求头 Prefer: odata.maxpagesize={x},设置响应中可包含的邮件数上限。You can optionally specify the request header, Prefer: odata.maxpagesize={x}, to set the maximum number of messages in a response.

同步文件夹中邮件的示例Example to synchronize messages in a folder

以下示例显示对最初包含 5 个邮件的特定文件夹进行的 2 轮同步。The following example shows 2 rounds of synchronization of a specific folder which initially contains 5 messages.

第一轮包含一系列用于同步文件夹中所有 5 个邮件的 3 个请求:The first round involves a series of 3 requests to synchronize all 5 messages in the folder:

第一轮后,将删除其中一个邮件,并将其他邮件标记为已读。After the first round, one of the messages is deleted, and another is marked as read. 第二轮同步仅返回 delta(删除和更新),而无需返回保持不变的其他邮件。The second round of synchronization returns only the delta (the deletion and update), without returning the other messages that have remained the same.

示例:初始请求Sample initial request

本示例中,指定文件夹正在进行首次同步,因此初始同步请求未包含任何状态令牌。此轮将返回该文件夹中的所有邮件。In this example, the specified folder is being synchronized for the first time, so the initial sync request does not include any state token. This round will return all the messages in that folder.

第一个请求指定以下内容:The first request specifies the following:

  • $select 参数用于在响应中返回每个邮件的 subjectsenderisRead 属性。A $select parameter to return the subject, sender, and isRead properties for each message in the response.
  • 可选的请求标头 odata.maxpagesize,一次返回两封邮件。The optional request header, odata.maxpagesize, returning 2 messages at a time.
GET https://graph.microsoft.com/v1.0/me/mailfolders/AQMkADNkNAAAgEMAAAA/messages/delta?$select=subject,sender,isRead HTTP/1.1
Prefer: odata.maxpagesize=2

示例第一个响应Sample initial response

响应中返回两封邮件和一个 @odata.nextLink 响应头。nextLink URL 表示此文件夹中还更多邮件可获取。The response includes two messages and an @odata.nextLink response header. The nextLink URL indicates there are more messages in the folder to get.

{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(message)",
  "@odata.nextLink": "https://graph.microsoft.com/v1.0/me/mailfolders('AQMkADNkNAAAgEMAAAA')/messages/delta?$skiptoken=GwcBoTmPuoTQWfcsAbkYM",
  "value": [
    {
      "@odata.type": "#microsoft.graph.message",
      "@odata.etag": "W/\"CQAAABYAAAARn2vdzPFjSbaPPxzjlzOTAAASsKZz\"",
      "subject": "Holiday hours update",
      "isRead": "false",
      "sender": {
        "emailAddress": {
          "name": "Dana Swope",
          "address": "danas@contoso.onmicrosoft.com"
        }
      },
      "id": "AAMkADNkNAAASq35xAAA="
    },
    {
      "@odata.type": "#microsoft.graph.message",
      "@odata.etag": "W/\"CQAAABYAAAARn2vdzPFjSbaPPxzjlzOTAAAEfYB/\"",
      "subject": "Holiday promotion sale",
      "isRead": "true",
      "sender": {
        "emailAddress": {
          "name": "Samantha Booth",
          "address": "samanthab@contoso.onmicrosoft.com"
        }
      },
      "id": "AQMkADNkNAAAVRMKAAAAA=="
    }
  ]
}

示例第二个请求Sample second request

第二个请求指定上一个响应中返回的 nextLink URL。请注意,不再需要像第一个请求一样指定相同的 $select 参数,因为 nextLink URL 中的 skipToken 已将其编码并包含在内。The second request specifies the nextLink URL returned from the previous response. Notice that it no longer has to specify the same $select parameter as in the initial request, as the skipToken in the nextLink URL encodes and includes it.

GET https://graph.microsoft.com/v1.0/me/mailfolders/AQMkADNkNAAAgEMAAAA/messages/delta?$skiptoken=GwcBoTmPuoTQWfcsAbkYM HTTP/1.1
Prefer: odata.maxpagesize=2

示例第二个响应Sample second response

第二个响应中返回此文件夹中接下来的 2 封邮件和另一个 nextLink(表示此文件夹中还有更多邮件可获取)。The second response returns the next 2 messages in the folder and another nextLink, indicating there are more messages to get from the folder.

{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(message)",
  "@odata.nextLink": "https://graph.microsoft.com/v1.0/me/mailfolders('AQMkADNkNAAAgEMAAAA')/messages/delta?$skiptoken=GwcBoTmPKILK4jLH7mAd1lLU",
  "value": [
    {
      "@odata.type": "#microsoft.graph.message",
      "@odata.etag": "W/\"CQAAABYAAAARn2vdzPFjSbaPPxzjlqfdAAAEfYB+\"",
      "subject": "Microsoft Virtual Academy at Contoso",
      "isRead": true,
      "sender": {
        "emailAddress": {
          "name": "Elliot Hyde",
          "address": "elliot-hyde@tailspintoys.com"
        }
      },
      "id": "AQMkADNkNAAAgWkAAAA"
    },
    {
      "@odata.type": "#microsoft.graph.message",
      "@odata.etag": "W/\"CQAAABYAAAARn2vdzPFjSbaPPxzjlzOTAAAEfYB+\"",
      "subject": "New or modified user account information",
      "isRead": true,
      "sender": {
        "emailAddress": {
          "name": "Randi Welch",
          "address": "randiw@contoso.onmicrosoft.com"
        }
      },
      "id": "AQMkADNkNAAAgWJAAAA"
    }
  ]
}

示例第三个请求Sample third request

第三个请求继续使用上一个同步请求返回的最新 nextLink URL。The third request continues to use the latest nextLink URL returned from the last sync request.

GET https://graph.microsoft.com/v1.0/me/mailFolders/AQMkADNkNAAAgEMAAAA/messages/delta?$skiptoken=GwcBoTmPKILK4jLH7mAd1lLU HTTP/1.1
Prefer: odata.maxpagesize=2

示例第三个响应(即最终响应)Sample third and final response

第三个响应中返回此文件夹中仅剩的邮件,以及表示目前已完成同步此文件夹的 deltaLink URL。保存并使用 deltaLink URL 在下一轮中同步同一文件夹The third response returns the only remaining message in the folder, and a deltaLink URL which indicates synchronization is complete for the time being for this folder. Save and use the deltaLink URL to synchronize the same folder in the next round.

{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(message)",
  "@odata.deltaLink": "https://graph.microsoft.com/v1.0/me/mailfolders('AQMkADNkNAAAgEMAAAA')/messages/delta?$deltatoken=GwcBoTmPuoGNlgXgF1nyUNMXY",
  "value": [
    {
      "@odata.type": "#microsoft.graph.message",
      "@odata.etag": "W/\"CQAAABYAAAARn2vdzFPjSbaPPxzjlzOTAAAEfYB+\"",
      "subject": "Fabric CDN now available",
      "isRead": true,
      "sender": {
        "emailAddress": {
          "name": "Jodie Sharp",
          "address": "Jodie.Sharp@contoso.com"
        }
      },
      "id": "AAMkADk0MGFkODE3LWEAAA="
    }
  ]
}

在下一轮中同步同一文件夹中的邮件Synchronize messages in the same folder in the next round

使用上一轮中最后一个请求返回的 deltaLink,可以只获取从那以后此文件夹中发生变化(已添加、删除或更新)的邮件。假设你愿意在响应中保持页面大小上限不变,下一轮的第一个请求如下所示:Using the deltaLink from the last request in the last round, you will be able to get only those messages that have changed (by being added, deleted, or updated) in that folder since then. Your first request in the next round will look like the following, assuming you prefer to keep the same maximum page size in the response:

GET https://graph.microsoft.com/v1.0/me/mailfolders/AQMkADNkNAAAgEMAAAA/messages/delta?$deltatoken=GwcBoTmPuoGNlgXgF1nyUNMXY HTTP/1.1
Prefer: odata.maxpagesize=2

响应包含 deltaLinkThe response contains a deltaLink. 这表示现已同步远程邮件文件夹中的所有更改。This indicates that all changes in the remote mail folder are now synchronized. 已删除一个邮件并更改其他邮件。One message was deleted and the other message was changed.

{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(message)",
  "@odata.deltaLink": "https://graph.microsoft.com/v1.0/me/mailfolders('AQMkADNkNAAAgEMAAAA')/messages/delta?$deltatoken=GwcBoTmPuoGNlgXgF1nyUNMXY",
  "value": [
    {
      "@odata.type": "#microsoft.graph.message",
      "id": "AAMkADk0MGFkODE3LWE4MmYtNDRhOS0Dh_6qB-pB2Sa2pUum19a6YAAKnLuxoAAA=",
      "@removed": {
        "reason": "deleted"
      }
    },
    {
      "@odata.type": "#microsoft.graph.message",
      "@odata.etag": "W/\"CQAAABYAAAARn2vdzPFjSbaPPxzjlzOTAAASsKZz\"",
      "subject": "Holiday hours update",
      "isRead": "true",
      "sender": {
        "emailAddress": {
          "name": "Dana Swope",
          "address": "danas@contoso.onmicrosoft.com"
        }
      },
      "id": "AAMkADNkNAAASq35xAAA="
    }
  ]
}

另请参阅See also