aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/traccar/notificators/NotificatorTraccar.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/traccar/notificators/NotificatorTraccar.java')
-rw-r--r--src/main/java/org/traccar/notificators/NotificatorTraccar.java92
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);
+ }
}
}