Настройка push-уведомлений в API Gmail

В этом документе объясняется, как управлять push-уведомлениями в API Gmail.

API Gmail предоставляет серверные push-уведомления, позволяющие отслеживать изменения в почтовых ящиках Gmail. Используйте эту функцию для повышения производительности вашего приложения. Она исключает дополнительные сетевые и вычислительные затраты, связанные с опросом ресурсов для определения изменений. При каждом изменении почтового ящика API Gmail уведомляет ваше серверное приложение.

Первоначальная настройка облачной системы публикации/подписки

API Gmail использует API Cloud Pub/Sub для доставки push-уведомлений. Это позволяет отправлять уведомления различными способами, включая веб-хуки и опрос через единую конечную точку подписки.

Предварительные требования

Для завершения настройки выполните предварительные условия для Cloud Pub/Sub , а затем настройте клиент Cloud Pub/Sub .

Создать тему

С помощью клиента Cloud Pub/Sub создайте тему , в которую API Gmail должен отправлять уведомления. Имя темы может быть любым, которое вы выберете в рамках своего проекта (например, соответствовать projects/myproject/topics/* , где myproject — это идентификатор проекта, указанный для вашего проекта в консоли Google Cloud).

Создать подписку

Чтобы настроить подписку на созданную вами тему, следуйте руководству по типам подписки Cloud Pub/Sub . Настройте тип подписки либо как push-уведомление через веб-перехватчик (то есть, HTTP POST-запрос), либо как pull-уведомление (то есть, инициированное вашим приложением). Таким образом ваше приложение будет получать уведомления об обновлениях.

Предоставьте права на публикацию по вашей теме.

Для работы Cloud Pub/Sub необходимо предоставить Gmail права на публикацию уведомлений в вашей теме.

Для этого предоставьте права publish пользователю gmail-api-push@system.gserviceaccount.com . Это можно сделать с помощью консоли разрешений Cloud Pub/Sub в консоли Google Cloud, следуя этим инструкциям по управлению доступом .

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

Получайте обновления почтового ящика Gmail

После завершения первоначальной настройки Cloud Pub/Sub настройте учетные записи Gmail для отправки уведомлений об обновлениях почтового ящика.

Запрос на просмотр

Чтобы настроить отправку уведомлений в тему Cloud Pub/Sub через учетные записи Gmail, используйте клиент API Gmail для вызова метода watch для почтового ящика пользователя Gmail. Это аналогично любому другому вызову API Gmail. Укажите имя созданной вами темы и любые другие параметры в запросе watch , например, labels для фильтрации. Например, используйте следующий запрос, чтобы получать уведомления о любых изменениях во входящих сообщениях:

Протокол

POST "https://www.googleapis.com/gmail/v1/users/me/watch"
Content-type: application/json

{
  topicName: "projects/myproject/topics/mytopic",
  labelIds: ["INBOX"],
  labelFilterBehavior: "INCLUDE",
}

Python

request = {
  'labelIds': ['INBOX'],
  'topicName': 'projects/myproject/topics/mytopic',
  'labelFilterBehavior': 'INCLUDE'
}
gmail.users().watch(userId='me', body=request).execute()

Ответ на просмотр

Если запрос watch пройдет успешно, вы получите ответ примерно следующего вида:

{ historyId: 1234567890 expiration: 1431990098200 }

В ответе содержится текущий historyId почтового ящика пользователя. Ваш клиент получает уведомления обо всех изменениях, произошедших после этого historyId . Если вам необходимо обработать изменения, произошедшие до этого historyId , обратитесь к разделу «Синхронизация клиентов с API Gmail» .

Кроме того, успешный вызов watch приводит к немедленной отправке уведомления в вашу тему Cloud Pub/Sub.

Если при вызове функции watch возникает ошибка, в подробностях должна быть указана причина проблемы. Обычно это связано с настройкой темы и подписки Cloud Pub/Sub. Обратитесь к документации Cloud Pub/Sub , чтобы убедиться в правильности настройки и получить помощь в отладке проблем с темой и подпиской.

Продлить наблюдение за почтовым ящиком

Необходимо вызывать функцию watch как минимум раз в 7 дней, иначе вы перестанете получать обновления для пользователя. Мы рекомендуем вызывать watch один раз в день. В ответе метода watch также содержится поле expiration с меткой времени истечения срока действия watch .

Получать уведомления

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

Если вы настроили push-подписку, уведомление веб-хука на ваш сервер будет соответствовать типу PubsubMessage :

POST https://yourserver.example.com/yourUrl
Content-type: application/json

{
  message:
  {
    // This is the actual notification data, as Base64URL-encoded JSON.
    data: "eyJlbWFpbEFkZHJlc3MiOiAidXNlckBleGFtcGxlLmNvbSIsICJoaXN0b3J5SWQiOiAiMTIzNDU2Nzg5MCJ9",

    // This is a Cloud Pub/Sub message id, unrelated to Gmail messages.
    "messageId": "2070443601311540",

    // This is the publish time of the message.
    "publishTime": "2021-02-26T19:13:55.749Z",
  }

  subscription: "projects/myproject/subscriptions/mysubscription"
}

Тело HTTP POST-запроса представляет собой JSON, а фактическая полезная нагрузка уведомления Gmail находится в поле message.data . Поле message.data — это строка, закодированная в Base64URL, которая декодируется в объект JSON, содержащий адрес электронной почты и идентификатор истории новых почтовых ящиков пользователя:

{"emailAddress": "user@example.com", "historyId": "9876543210"}

Затем вы можете использовать метод history.list , чтобы получить подробную информацию об изменениях пользователя с момента его последнего известного historyId , как описано в разделе «Синхронизация клиентов с API Gmail» .

Например, используйте метод history.list для отслеживания изменений, произошедших между вашим первоначальным запросом watch и получением уведомления, приведенного в предыдущем примере. Передайте значение 1234567890 в качестве startHistoryId в history.list . После этого вы можете сохранить значение 9876543210 в качестве последнего известного historyId для дальнейшего использования.

Если вы настроили подписку по принципу "pull subscription", обратитесь к примерам кода в руководстве Cloud Pub/Sub по подпискам по принципу "pull subscription" для получения более подробной информации о получении сообщений.

Отвечать на уведомления

Все уведомления должны быть подтверждены. Если вы используете push-уведомления через веб-перехватчик, то успешный ответ (например, HTTP 200) подтверждает получение уведомления.

Если вы используете метод получения данных по запросу ( REST Pull , RPC Pull или RPC StreamingPull ), необходимо выполнить подтверждающий вызов ( REST или RPC ). Более подробную информацию о подтверждении сообщений асинхронно или синхронно с использованием официальных клиентских библиотек на основе RPC можно найти в примерах кода в руководстве по подпискам на основе запроса в Cloud Pub/Sub.

Если вы не подтвердите получение уведомлений (например, если ваш обратный вызов веб-перехватчика вернет ошибку или истечет время ожидания), Cloud Pub/Sub повторит отправку уведомления позже.

Остановить обновления почтового ящика

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

Ограничения

Ниже перечислены ограничения работы с серверными push-уведомлениями:

Максимальная скорость уведомления

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

Надежность

Как правило, все уведомления доставляются надежно в течение нескольких секунд; однако в некоторых экстремальных ситуациях уведомления могут задерживаться или отбрасываться. Необходимо корректно обрабатывать эту возможность, чтобы приложение продолжало синхронизироваться, даже если push-уведомления не получены. Например, можно периодически вызывать метод history.list после периода отсутствия уведомлений для пользователя.

Ограничения Cloud Pub/Sub

API Cloud Pub/Sub также имеет свои ограничения, которые подробно описаны в документации по ценам и квотам .