Получение добавочных изменений для сообщений в папке

Дельта-запрос позволяет запрашивать добавления, удаления или обновления сообщений в папке с помощью серии вызовов функции дельта. Дельта-данные позволяют поддерживать и синхронизировать локальное хранилище сообщений пользователя без необходимости каждый раз получать весь набор сообщений пользователя с сервера.

Синхронизация элементов сообщений в локальном хранилище может использовать разностный запрос для начальной полной синхронизации и последующих добавочных синхронизаций. Как правило, вы выполняете начальную полную синхронизацию всех сообщений в папке (например, папки "Входящие" пользователя), а затем периодически получает добавочные изменения в этой папке.

Чтобы получить добавочные изменения только определенного типа ( сообщения, созданные, обновленные или удаленные с момента начальной синхронизации), выполните начальный цикл синхронизации всех сообщений в папке, а затем получить добавочные изменения определенного требуемого типа в последующих раундах. Укажите требуемый тип изменения в качестве параметра запроса в исходном разностном запросе; Microsoft Graph автоматически кодирует все параметры OData и пользовательские запросы в @odata.nextLink или @odata.deltaLink , указанные в ответе.

Отслеживание изменений сообщений в папке

Запрос изменений выполняется отдельно для каждой папки. Чтобы отслеживать изменения сообщений в иерархии папок, необходимо наблюдать за каждой папкой отдельно.

Как правило, цикл отслеживания изменений сообщений в папке почты состоит из одного или нескольких запросов GET с функцией delta. Исходный запрос GET во многом аналогичен получению сообщений, но он также содержит функцию delta:

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

Запрос GET с функцией delta возвращает одно из следующих значений:

  • ссылку @odata.nextLink (содержащую URL-адрес с вызовом функции delta и маркером skipToken);
  • ссылку @odata.deltaLink (содержащую URL-адрес с вызовом функции delta и маркером deltaToken).

Эти маркеры являются маркерами состояния , которые непрозрачны для клиента. Чтобы продолжить цикл отслеживания изменений, скопируйте и примените URL-адрес, возвращенный последним запросом GET, к следующему вызову функции delta для той же папки. Ссылка @odata.deltaLink в ответе означает, что текущий цикл отслеживания изменений завершен. Вы можете сохранить и использовать URL-адрес @odata.deltaLink в начале следующего цикла.

Остальная часть этой статьи содержит 2 примера:

  • См . пример 1 , чтобы узнать, как использовать @odata.nextLink URL-адреса и @odata.deltaLink .
  • См . пример 2 , чтобы узнать, как постепенно получать только сообщения, созданные с момента начального раунда.

Использование параметров запроса изменений для сообщений

  • Вы можете использовать параметр запроса $select так же, как в любом другом запросе GET, чтобы задать только те свойства, которые необходимы для эффективной работы. Свойство id всегда возвращается.
  • Запросы изменений поддерживают параметры $select, $top и $expand для сообщений.
  • Имеется ограниченная поддержка параметров $filter и $orderby:
    • Для параметра $filter поддерживаются только выражения $filter=receivedDateTime+ge+{value} и $filter=receivedDateTime+gt+{value}.
    • При применении $filter в разностном запросе возвращается только до 5 000 сообщений.
    • Для параметра $orderby поддерживается только выражение $orderby=receivedDateTime+desc. Если не включить $orderby выражение, порядок возврата не гарантируется.
  • Параметр $search не поддерживается.

Кроме того, чтобы возвращать в ответе разностного запроса только определенные типы изменений (созданных, обновленных или удаленных), можно при необходимости отфильтровать требуемый тип изменений с помощью настраиваемого параметра changeTypeзапроса . Возможные значения: created, updated или deleted.

GET /me/mailfolders/{id}/messages/delta?changeType=created
GET /me/mailfolders/{id}/messages/delta?changeType=updated
GET /me/mailfolders/{id}/messages/delta?changeType=deleted

Необязательный заголовок запроса

Каждый разностный запрос GET возвращает в отклике коллекцию из одного или нескольких сообщений. При необходимости вы можете указать заголовок запроса Prefer: odata.maxpagesize={x}, чтобы задать максимальное количество сообщений в отклике.

Пример 1. Синхронизация сообщений в папке

В следующем примере показаны 2 раунда синхронизации определенной папки, изначально содержащей 5 сообщений.

В первом цикле выполняется серия из 3 запросов на синхронизацию всех 5 сообщений в папке:

После первого цикла одно из сообщений удаляется, а еще одно помечается как прочитанное. Во втором цикле синхронизации возвращаются только удаленные и обновленные сообщения. При этом не возвращаются сообщения, оставшиеся без изменений.

Пример исходного запроса

В этом примере указанная папка синхронизируется в первый раз, поэтому первоначальный запрос на синхронизацию не включает маркер состояния. Этот раунд возвращает все сообщения в этой папке.

Первый запрос задает следующие параметры:

GET https://graph.microsoft.com/v1.0/me/mailfolders/AQMkADNkNAAAgEMAAAA/messages/delta?$select=subject,sender,isRead HTTP/1.1
Prefer: odata.maxpagesize=2

Пример исходного ответа

Ответ включает два сообщения и заголовок ответа @odata.nextLink. URL-адрес @odata.nextLink указывает, что в папке еще остались сообщения.

{
  "@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.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.com"
        }
      },
      "id": "AQMkADNkNAAAVRMKAAAAA=="
    }
  ]
}

Пример второго запроса

Второй запрос указывает URL-адрес @odata.nextLink, полученный из предыдущего ответа. Обратите внимание, что в нем больше не требуется указывать тот же параметр $select, что и в исходном запросе, так как маркер skipToken в URL-адресе @odata.nextLink включает его в закодированном виде.

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

Пример второго ответа

Второй ответ содержит следующие 2 сообщения в папке и еще одну ссылку @odata.nextLink, указывающую, что в папке еще остались сообщения.

{
  "@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.com"
        }
      },
      "id": "AQMkADNkNAAAgWJAAAA"
    }
  ]
}

Пример третьего запроса

Третий запрос продолжает использовать URL-адрес @odata.nextLink, полученный из последнего запроса на синхронизацию.

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

Пример третьего и последнего ответа

Третий ответ возвращает единственное оставшееся сообщение в папке и @odata.deltaLink URL-адрес, указывающий, что синхронизация завершена на данный момент для этой папки. Сохраните URL-адрес @odata.deltaLink и используйте его в следующем цикле синхронизации этой папки.

{
  "@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="
    }
  ]
}

Синхронизация сообщений из одной папки в следующем цикле

@odata.deltaLink Используя из последнего запроса в последнем раунде, вы можете получать в этой папке только те сообщения, которые были изменены (путем добавления, удаления или обновления) в этой папке. При условии, что вы не хотите менять максимальный размер страницы ответа, первый запрос следующего цикла будет выглядеть следующим образом:

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

Ответ содержит ссылку @odata.deltaLink. Это означает, что теперь синхронизированы все изменения в удаленной почтовой папке. Одно сообщение было удалено, а еще одно — изменено.

{
  "@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.com"
        }
      },
      "id": "AAMkADNkNAAASq35xAAA="
    }
  ]
}

Пример 2. Синхронизация сообщений в папке на основе типа изменения

В следующем примере показано получение только сообщений, созданных в определенной папке с момента начальной синхронизации. В этом примере используется 2 цикла синхронизации этой папки, которая изначально содержит 4 сообщения.

Первый раунд включает в себя серию из 2 запросов для синхронизации всех 4 сообщений в папке:

После первого раунда создаются еще два сообщения, одно из них удаляется, а другое помечается как прочитанное.

Второй раунд синхронизации возвращает только изменения в папке created типа изменения (созданные два новых сообщения), не возвращая другие сообщения, которые остались прежними, удалены или обновлены с момента последней синхронизации.

Пример начального запроса с указанным типом изменения

В этом примере указанная папка синхронизируется в первый раз, поэтому первоначальный запрос на синхронизацию не включает маркер состояния. Этот раунд возвращает все сообщения в этой папке.

Первый запрос задает следующие параметры:

  • Параметр changeType , возвращающий только созданные сообщения в последующем разностном ответе.
  • параметр $select для возврата свойств subject, sender и isRead для каждого сообщения в ответе;
  • необязательный заголовок запросаodata.maxpagesize, возвращающий 2 сообщения одновременно.
GET https://graph.microsoft.com/v1.0/me/mailFolders/AAMkAGUwNc4LTMzAAA=/messages/delta?changeType=created&$select=subject,sender,isRead HTTP/1.1
Prefer: odata.maxpagesize=2

Пример начального ответа с указанным типом изменения

Ответ включает два сообщения и заголовок ответа @odata.nextLink. URL-адрес @odata.nextLink указывает, что в папке еще остались сообщения.

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(message)",
    "@odata.nextLink": "https://graph.microsoft.com/v1.0/me/mailFolders/AAMkAGUwNc4LTMzAAA=/messages/delta?$skiptoken=P4lmXpjPRrjB6haAQzSkpK89jYTVD2kVtOeXNRnfYzPbCs",
    "value": [
        {
            "@odata.type": "#microsoft.graph.message",
            "@odata.etag": "W/\"CQAAABYAAACQ2fKdhq8oSKEDSVrdi3lRAAId0MBP\"",
            "subject": "Inline Attachments Again",
            "isRead": true,
            "id": "AAMkAGUwNjQ4ZjIxLTQ3Y2YtNDViMi1iZjc4LT2fKdhq8oSKEDSVrdi3lRAAIei5gdAAA=",
            "sender": {
                "emailAddress": {
                    "name": "Megan Brown",
                    "address": "Megan.Brown@contoso.com"
                }
            }
        },
        {
            "@odata.type": "#microsoft.graph.message",
            "@odata.etag": "W/\"CQAAABYAAACQ2fKdhq8oSKEDSVrdi3lRAAId0MBR\"",
            "subject": "RE: Test Outlook TimeZone",
            "isRead": true,
            "id": "AAMkAGUwNjQ4ZjIxLTQ3Y2YtNDViMi1iZjc4LTMKdhq8oSKEDSVrdi3lRAAIei5geAAA=",
            "sender": {
                "emailAddress": {
                    "name": "Megan Brown",
                    "address": "Megan.Brown@contoso.com"
                }
            }
        }
    ]
}

Пример второго запроса с указанным типом изменения

Второй запрос указывает URL-адрес @odata.nextLink, полученный из предыдущего ответа. Обратите внимание, что больше не нужно указывать тот же $selectchangeType или параметр, что и в первоначальном запросе skipToken , так как в @odata.nextLink URL-адресе кодируется и включает его.

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

Пример второго ответа с указанным типом изменения

Второй ответ возвращает следующие 2 сообщения в папке и @odata.deltaLink URL-адресе, которые указывают, что синхронизация завершена на данный момент для этой папки. Сохраните URL-адрес @odata.deltaLink и используйте его в следующем цикле синхронизации этой папки.

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(message)",
    "@odata.deltaLink": "https://graph.microsoft.com/v1.0/me/mailFolders/AAMkAGUwNc4LTMzAAA=/messages/delta?$deltatoken=P4lmXpjPRrjB6haAQ_37roqIbjXe66KoV7SMlLH--Jgi8",
    "value": [
        {
            "@odata.type": "#microsoft.graph.message",
            "@odata.etag": "W/\"CQAAABYAAACQ2fKdhq8oSKEDSVrdi3lRAAId0MBu\"",
            "subject": "Your preview of the new Briefing email",
            "isRead": true,
            "id": "AAMkAGUwNjQ4ZjIxLTQ3Y2YtNDViMi1iZjc4LTMzNjMwNWM0ZGE2YQBGAAAAAADbrwBIJ",
            "sender": {
                "emailAddress": {
                    "name": "Cortana",
                    "address": "cortana@contoso.com"
                }
            }
        },
        {
            "@odata.type": "#microsoft.graph.message",
            "@odata.etag": "W/\"CQAAABYAAACQ2fKdhq8oSKEDSVrdi3lRAAId0MBw\"",
            "subject": "Char Coding HTML",
            "isRead": true,
            "id": "AAMkAGUwNjQ4ZjIxLTQ3Y2YtNDViMi1iZjc4LTMzNjMwNWM0ZGE2YQBGAAAAAADbrwBA=",
            "sender": {
                "emailAddress": {
                    "name": "John Doe",
                    "address": "John.Doe@contoso.com"
                }
            }
        }
    ]
}

Синхронизация сообщений в той же папке в следующем раунде на основе указанного типа изменения

@odata.deltaLink Используя из последнего ответа в последнем раунде, вы можете получить только те сообщения, которые были добавлены в эту папку с тех пор. При условии, что вы не хотите менять максимальный размер страницы ответа, первый запрос следующего цикла будет выглядеть следующим образом:

GET https://graph.microsoft.com/v1.0/me/mailFolders/AAMkAGUwNc4LTMzAAA=/messages/delta?$deltatoken=P4lmXpjPRrjB6haAQ_37roqIbjXe66KoV7SMlLH--Jgi8 HTTP/1.1
Prefer: odata.maxpagesize=2

Ответ содержит ссылку @odata.deltaLink. Это означает, что теперь синхронизированы все изменения в удаленной почтовой папке. С момента последней синхронизации было добавлено два сообщения. Сообщения, обновленные & удаленные с момента последней синхронизации, не возвращаются в этом разностном ответе.

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(message)",
    "@odata.deltaLink": "https://graph.microsoft.com/v1.0/me/mailFolders/AAMkAGUwNc4LTMzAAA=/messages/delta?$skiptoken=EPuhZPRDHo-r3EBfscYE444fuGSBRV1eXex3JZkLzT9fRM",
    "value": [
        {
            "@odata.type": "#microsoft.graph.message",
            "@odata.etag": "W/\"CQAAABYAAACQ2fKdhq8oSKEDSVrdi3lRAAId0MCP\"",
            "subject": "Nested Attachment",
            "isRead": true,
            "id": "AAMkAGUwNjQ4ZjIxLTQ3Y2YtNDViMi1iZjc4LTMzNjMwNWM0ZGE2YQBGAAAAAADbrwBIJ",
            "sender": {
                "emailAddress": {
                    "name": "Patti Fernandez",
                    "address": "PattiF@contoso.com"
                }
            }
        },
        {
            "@odata.type": "#microsoft.graph.message",
            "@odata.etag": "W/\"CQAAABYAAACQ2fKdhq8oSKEDSVrdi3lRAAId0MCN\"",
            "subject": "Attachment Testing",
            "isRead": true,
            "id": "AAMkAGUwNjQ4ZjIxLTQ3Y2YtNDViMi1iZjc4LTMzNjMwNWM0ZGE2YQBGAAAAAADbrwZA=",
            "sender": {
                "emailAddress": {
                    "name": "Patti Fernandez",
                    "address": "PattiF@contoso.com"
                }
            }
        }
    ]
}