Google PubSub / Gmail Webhook: постоянное получение нескольких POST-запросов от PubSub при отправке электронной почты - PullRequest
0 голосов
/ 04 декабря 2018

У меня настроен веб-крючок, который прослушивает и обрабатывает изменения в моих папках INBOX и SENT в Gmail с помощью API Cloud PubSub API и Gmail API в Java.

Проблема, с которой я сталкиваюсь, заключается в том, чтокогда я отправляю сообщение другому пользователю, PubSub, кажется, НАЖИМАЕТ к моей конечной точке дважды в течение одной секунды с несколько разными значениями history_id и message_id, но с тем же именем подписки и адресом электронной почты пользователя.

Я понимаю, что PubSub гарантирует хотя бы раз доставку , поэтому не является необычным получение дублированного сообщения, но поскольку оно постоянно происходит и message_id отличается, я думаю, что тамможет быть несколько push-запросов на основе документации PubSub, приведенной ниже:

Cloud Pub / Sub назначает уникальный message_id каждому сообщению, которое может использоваться для обнаружения дубликатов сообщений, полученных подписчиком.Это, однако, не позволит вам обнаружить дубликаты, возникающие в результате нескольких запросов на публикацию одних и тех же данных.

Что я пробовал:

  1. Гарантировано, что есть толькоотдельная тема / подписка на моей консоли Google Cloud.
  2. Установите различные значения крайнего срока Ack в диапазоне от 10 до 600 секунд.
  3. Вызывается service.users().stop(), чтобы убедиться, что я не звонил watch() несколько раз, затем начинаются watch() снова.

Я заглянул в PubSubIO, чтобы обеспечить доставку ровно один раз , но я понимаю, получаю ли я последовательно несколько PubSubсообщения, должно быть что-то в корне не так с тем, как я настроил свой webhook.

Редактировать: вот код, который я должен наблюдать за изменениями в моей учетной записи Gmail.Я использую служебную учетную запись с полномочиями по всему домену для получения доступа к учетным записям во всем домене

public static Map<String, String> watchInbox(Gmail service) throws IOException {
    Map<String, String> watchInboxResponse = new HashMap<>();
    List<String> labelsToWatch = Arrays.asList("INBOX", "SENT");
    String topicName = "projects/subscription-name/topics/topic-name";

    WatchRequest request = new WatchRequest();
    request.setLabelIds(labelsToWatch);
    request.setTopicName(topicName);

    WatchResponse response = service.users().watch("me", request).execute();

    watchInboxResponse.put("historyId", response.getHistoryId().toString());
    watchInboxResponse.put("expiration", response.getExpiration().toString());
    return watchInboxResponse;
}

. Я беру вставку historyid и expiration в базу данных и использую ее для проверки при получении вызова webhook:нужно ли мне снова звонить watch(), если с момента последнего звонка watch прошло более 24 часов (в соответствии с рекомендациями Google).

1 Ответ

0 голосов
/ 14 декабря 2018

У меня было похожее поведение, когда я реализовывал запрос Google Pub / Sub Watch.

Что делает Gmail при составлении почты, так это то, что она создает системные метки «Отправить и черновик» и постоянно сохраняет в черновикс новым идентификатором сообщения и надписью «Отправить и черновик» вы подписаны на любые изменения в «Входящие и отправить», так что вы попадете в ваш веб-крючок дважды или, возможно, больше времени !!

Сообщение из Gmail всегда содержитярлыки, вам нужно будет отфильтровать те сообщения, которые имеют черновик ярлыка.

Я использую Gmail .net SDK для своего кода и должен обрабатывать

//Explicitly avoid further processing
 bool isdraft = y.Message.LabelIds.Contains("DRAFT");

и фильтровать их независимо.

...