From 074ed6014cc7e243ce907052dc86444c0d23ccdd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 28 Mar 2023 09:10:53 -0700 Subject: Handle Traccar push errors --- .../traccar/notificators/NotificatorTraccar.java | 60 +++++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/traccar/notificators/NotificatorTraccar.java b/src/main/java/org/traccar/notificators/NotificatorTraccar.java index e32229506..fb9632ad0 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTraccar.java +++ b/src/main/java/org/traccar/notificators/NotificatorTraccar.java @@ -16,23 +16,41 @@ package org.traccar.notificators; import com.fasterxml.jackson.annotation.JsonProperty; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; import org.traccar.notification.NotificationFormatter; +import org.traccar.session.cache.CacheManager; +import org.traccar.storage.Storage; +import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; import javax.inject.Singleton; +import javax.json.JsonObject; import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; @Singleton public class NotificatorTraccar implements Notificator { + private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorTraccar.class); + private final NotificationFormatter notificationFormatter; private final Client client; + private final Storage storage; + private final CacheManager cacheManager; private final String url; private final String key; @@ -54,9 +72,13 @@ public class NotificatorTraccar implements Notificator { } @Inject - public NotificatorTraccar(Config config, NotificationFormatter notificationFormatter, Client client) { + public NotificatorTraccar( + Config config, NotificationFormatter notificationFormatter, Client client, + Storage storage, CacheManager cacheManager) { this.notificationFormatter = notificationFormatter; this.client = client; + this.storage = storage; + this.cacheManager = cacheManager; this.url = "https://www.traccar.org/push/"; this.key = config.getString(Keys.NOTIFICATOR_TRACCAR_KEY); } @@ -72,11 +94,45 @@ public class NotificatorTraccar implements Notificator { item.body = shortMessage.getBody(); item.sound = "default"; + String[] tokenArray = user.getString("notificationTokens").split("[, ]"); + List registrationTokens = new ArrayList<>(Arrays.asList(tokenArray)); + Message message = new Message(); message.tokens = user.getString("notificationTokens").split("[, ]"); message.notification = item; - client.target(url).request().header("Authorization", "key=" + key).post(Entity.json(message)).close(); + var request = client.target(url).request().header("Authorization", "key=" + key); + try (Response result = request.post(Entity.json(message))) { + var json = result.readEntity(JsonObject.class); + List failedTokens = new LinkedList<>(); + var responses = json.getJsonArray("responses"); + for (int i = 0; i < responses.size(); i++) { + var response = responses.getJsonObject(i); + if (!response.getBoolean("success")) { + var error = response.getJsonObject("error"); + String errorCode = error.getString("code"); + if (errorCode.equals("messaging/invalid-argument") + || errorCode.equals("messaging/registration-token-not-registered")) { + failedTokens.add(registrationTokens.get(i)); + } + LOGGER.warn("Push user {} error - {}", user.getId(), error.getString("message")); + } + } + if (!failedTokens.isEmpty()) { + registrationTokens.removeAll(failedTokens); + if (registrationTokens.isEmpty()) { + user.getAttributes().remove("notificationTokens"); + } else { + user.set("notificationTokens", String.join(",", registrationTokens)); + } + storage.updateObject(user, new Request( + new Columns.Include("attributes"), + new Condition.Equals("id", user.getId()))); + cacheManager.updateOrInvalidate(true, user); + } + } catch (StorageException e) { + LOGGER.warn("Push error", e); + } } } -- cgit v1.2.3