У меня настроен веб-крючок, который прослушивает и обрабатывает изменения в моих папках 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
каждому сообщению, которое может использоваться для обнаружения дубликатов сообщений, полученных подписчиком.Это, однако, не позволит вам обнаружить дубликаты, возникающие в результате нескольких запросов на публикацию одних и тех же данных.
Что я пробовал:
- Гарантировано, что есть толькоотдельная тема / подписка на моей консоли Google Cloud.
- Установите различные значения крайнего срока Ack в диапазоне от 10 до 600 секунд.
- Вызывается
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).