diff options
Diffstat (limited to 'src/main/java/org/traccar/notificators/NotificatorTraccar.java')
-rw-r--r-- | src/main/java/org/traccar/notificators/NotificatorTraccar.java | 92 |
1 files changed, 73 insertions, 19 deletions
diff --git a/src/main/java/org/traccar/notificators/NotificatorTraccar.java b/src/main/java/org/traccar/notificators/NotificatorTraccar.java index 9ae39f975..983c4cda6 100644 --- a/src/main/java/org/traccar/notificators/NotificatorTraccar.java +++ b/src/main/java/org/traccar/notificators/NotificatorTraccar.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 2024 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,28 +16,46 @@ package org.traccar.notificators; import com.fasterxml.jackson.annotation.JsonProperty; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.traccar.model.ObjectOperation; 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.notification.NotificationMessage; +import org.traccar.session.cache.CacheManager; +import org.traccar.storage.Storage; +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.ws.rs.client.Client; -import javax.ws.rs.client.Entity; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.Entity; +import jakarta.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 { +public class NotificatorTraccar extends 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; - public static class Notification { + public static class NotificationObject { @JsonProperty("title") private String title; @JsonProperty("body") @@ -50,33 +68,69 @@ public class NotificatorTraccar implements Notificator { @JsonProperty("registration_ids") private String[] tokens; @JsonProperty("notification") - private Notification notification; + private NotificationObject notification; } @Inject - public NotificatorTraccar(Config config, NotificationFormatter notificationFormatter, Client client) { - this.notificationFormatter = notificationFormatter; + public NotificatorTraccar( + Config config, NotificationFormatter notificationFormatter, Client client, + Storage storage, CacheManager cacheManager) { + super(notificationFormatter, "short"); this.client = client; + this.storage = storage; + this.cacheManager = cacheManager; this.url = "https://www.traccar.org/push/"; this.key = config.getString(Keys.NOTIFICATOR_TRACCAR_KEY); } @Override - public void send(User user, Event event, Position position) { + public void send(User user, NotificationMessage shortMessage, Event event, Position position) { if (user.hasAttribute("notificationTokens")) { - var shortMessage = notificationFormatter.formatMessage(user, event, position, "short"); + NotificationObject item = new NotificationObject(); + item.title = shortMessage.getSubject(); + item.body = shortMessage.getBody(); + item.sound = "default"; - Notification notification = new Notification(); - notification.title = shortMessage.getSubject(); - notification.body = shortMessage.getBody(); - notification.sound = "default"; + String[] tokenArray = user.getString("notificationTokens").split("[, ]"); + List<String> registrationTokens = new ArrayList<>(Arrays.asList(tokenArray)); Message message = new Message(); message.tokens = user.getString("notificationTokens").split("[, ]"); - message.notification = notification; + 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<String> 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.invalidateObject(true, User.class, user.getId(), ObjectOperation.UPDATE); + } + } catch (Exception e) { + LOGGER.warn("Push error", e); + } } } |