aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/traccar/notificators
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/traccar/notificators')
-rw-r--r--src/main/java/org/traccar/notificators/Notificator.java24
-rw-r--r--src/main/java/org/traccar/notificators/NotificatorCommand.java63
-rw-r--r--src/main/java/org/traccar/notificators/NotificatorFirebase.java87
-rw-r--r--src/main/java/org/traccar/notificators/NotificatorMail.java20
-rw-r--r--src/main/java/org/traccar/notificators/NotificatorNull.java34
-rw-r--r--src/main/java/org/traccar/notificators/NotificatorPushover.java20
-rw-r--r--src/main/java/org/traccar/notificators/NotificatorSms.java18
-rw-r--r--src/main/java/org/traccar/notificators/NotificatorTelegram.java20
-rw-r--r--src/main/java/org/traccar/notificators/NotificatorTraccar.java92
-rw-r--r--src/main/java/org/traccar/notificators/NotificatorWeb.java17
10 files changed, 263 insertions, 132 deletions
diff --git a/src/main/java/org/traccar/notificators/Notificator.java b/src/main/java/org/traccar/notificators/Notificator.java
index 052365c7a..59216b1b6 100644
--- a/src/main/java/org/traccar/notificators/Notificator.java
+++ b/src/main/java/org/traccar/notificators/Notificator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org)
+ * Copyright 2018 - 2024 Anton Tananaev (anton@traccar.org)
* Copyright 2018 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,12 +17,30 @@
package org.traccar.notificators;
import org.traccar.model.Event;
+import org.traccar.model.Notification;
import org.traccar.model.Position;
import org.traccar.model.User;
import org.traccar.notification.MessageException;
+import org.traccar.notification.NotificationFormatter;
+import org.traccar.notification.NotificationMessage;
-public interface Notificator {
+public abstract class Notificator {
- void send(User user, Event event, Position position) throws MessageException, InterruptedException;
+ private final NotificationFormatter notificationFormatter;
+ private final String templatePath;
+
+ public Notificator(NotificationFormatter notificationFormatter, String templatePath) {
+ this.notificationFormatter = notificationFormatter;
+ this.templatePath = templatePath;
+ }
+
+ public void send(Notification notification, User user, Event event, Position position) throws MessageException {
+ var message = notificationFormatter.formatMessage(notification, user, event, position, templatePath);
+ send(user, message, event, position);
+ }
+
+ public void send(User user, NotificationMessage message, Event event, Position position) throws MessageException {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/src/main/java/org/traccar/notificators/NotificatorCommand.java b/src/main/java/org/traccar/notificators/NotificatorCommand.java
new file mode 100644
index 000000000..712dda274
--- /dev/null
+++ b/src/main/java/org/traccar/notificators/NotificatorCommand.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2023 - 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.notificators;
+
+import org.traccar.database.CommandsManager;
+import org.traccar.model.Command;
+import org.traccar.model.Event;
+import org.traccar.model.Notification;
+import org.traccar.model.Position;
+import org.traccar.model.User;
+import org.traccar.notification.MessageException;
+import org.traccar.storage.Storage;
+import org.traccar.storage.query.Columns;
+import org.traccar.storage.query.Condition;
+import org.traccar.storage.query.Request;
+
+import jakarta.inject.Inject;
+import jakarta.inject.Singleton;
+
+@Singleton
+public class NotificatorCommand extends Notificator {
+
+ private final Storage storage;
+ private final CommandsManager commandsManager;
+
+ @Inject
+ public NotificatorCommand(Storage storage, CommandsManager commandsManager) {
+ super(null, null);
+ this.storage = storage;
+ this.commandsManager = commandsManager;
+ }
+
+ @Override
+ public void send(Notification notification, User user, Event event, Position position) throws MessageException {
+
+ if (notification == null || notification.getCommandId() <= 0) {
+ throw new MessageException("Saved command not provided");
+ }
+
+ try {
+ Command command = storage.getObject(Command.class, new Request(
+ new Columns.All(), new Condition.Equals("id", notification.getCommandId())));
+ command.setDeviceId(event.getDeviceId());
+ commandsManager.sendCommand(command);
+ } catch (Exception e) {
+ throw new MessageException(e);
+ }
+ }
+
+}
diff --git a/src/main/java/org/traccar/notificators/NotificatorFirebase.java b/src/main/java/org/traccar/notificators/NotificatorFirebase.java
index 5ce2cbc0b..7440068f8 100644
--- a/src/main/java/org/traccar/notificators/NotificatorFirebase.java
+++ b/src/main/java/org/traccar/notificators/NotificatorFirebase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org)
+ * Copyright 2018 - 2024 Anton Tananaev (anton@traccar.org)
* Copyright 2018 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,34 +24,50 @@ import com.google.firebase.messaging.AndroidNotification;
import com.google.firebase.messaging.ApnsConfig;
import com.google.firebase.messaging.Aps;
import com.google.firebase.messaging.FirebaseMessaging;
-import com.google.firebase.messaging.FirebaseMessagingException;
+import com.google.firebase.messaging.MessagingErrorCode;
import com.google.firebase.messaging.MulticastMessage;
-import com.google.firebase.messaging.Notification;
+import jakarta.inject.Inject;
+import jakarta.inject.Singleton;
+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.ObjectOperation;
import org.traccar.model.Position;
import org.traccar.model.User;
import org.traccar.notification.MessageException;
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 java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.LinkedList;
import java.util.List;
@Singleton
-public class NotificatorFirebase implements Notificator {
+public class NotificatorFirebase extends Notificator {
- private final NotificationFormatter notificationFormatter;
+ private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorFirebase.class);
+ private final Storage storage;
+ private final CacheManager cacheManager;
@Inject
- public NotificatorFirebase(Config config, NotificationFormatter notificationFormatter) throws IOException {
+ public NotificatorFirebase(
+ Config config, NotificationFormatter notificationFormatter,
+ Storage storage, CacheManager cacheManager) throws IOException {
- this.notificationFormatter = notificationFormatter;
+ super(notificationFormatter, "short");
+ this.storage = storage;
+ this.cacheManager = cacheManager;
InputStream serviceAccount = new ByteArrayInputStream(
config.getString(Keys.NOTIFICATOR_FIREBASE_SERVICE_ACCOUNT).getBytes());
@@ -64,17 +80,16 @@ public class NotificatorFirebase implements Notificator {
}
@Override
- public void send(User user, Event event, Position position) throws MessageException {
+ public void send(User user, NotificationMessage message, Event event, Position position) throws MessageException {
if (user.hasAttribute("notificationTokens")) {
- var shortMessage = notificationFormatter.formatMessage(user, event, position, "short");
+ List<String> registrationTokens = new ArrayList<>(
+ Arrays.asList(user.getString("notificationTokens").split("[, ]")));
- List<String> registrationTokens = Arrays.asList(user.getString("notificationTokens").split("[, ]"));
-
- MulticastMessage message = MulticastMessage.builder()
- .setNotification(Notification.builder()
- .setTitle(shortMessage.getSubject())
- .setBody(shortMessage.getBody())
+ var messageBuilder = MulticastMessage.builder()
+ .setNotification(com.google.firebase.messaging.Notification.builder()
+ .setTitle(message.getSubject())
+ .setBody(message.getBody())
.build())
.setAndroidConfig(AndroidConfig.builder()
.setNotification(AndroidNotification.builder()
@@ -86,19 +101,41 @@ public class NotificatorFirebase implements Notificator {
.setSound("default")
.build())
.build())
- .addAllTokens(registrationTokens)
- .putData("eventId", String.valueOf(event.getId()))
- .build();
+ .addAllTokens(registrationTokens);
+
+ if (event != null) {
+ messageBuilder.putData("eventId", String.valueOf(event.getId()));
+ }
try {
- var result = FirebaseMessaging.getInstance().sendMulticast(message);
- for (var response : result.getResponses()) {
+ var result = FirebaseMessaging.getInstance().sendEachForMulticast(messageBuilder.build());
+ List<String> failedTokens = new LinkedList<>();
+ var iterator = result.getResponses().listIterator();
+ while (iterator.hasNext()) {
+ int index = iterator.nextIndex();
+ var response = iterator.next();
if (!response.isSuccessful()) {
- throw new MessageException(response.getException());
+ MessagingErrorCode error = response.getException().getMessagingErrorCode();
+ if (error == MessagingErrorCode.INVALID_ARGUMENT || error == MessagingErrorCode.UNREGISTERED) {
+ failedTokens.add(registrationTokens.get(index));
+ }
+ LOGGER.warn("Firebase user {} error", user.getId(), response.getException());
+ }
+ }
+ 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 (FirebaseMessagingException e) {
- throw new MessageException(e);
+ } catch (Exception e) {
+ LOGGER.warn("Firebase error", e);
}
}
}
diff --git a/src/main/java/org/traccar/notificators/NotificatorMail.java b/src/main/java/org/traccar/notificators/NotificatorMail.java
index 19fde6756..e7ca10157 100644
--- a/src/main/java/org/traccar/notificators/NotificatorMail.java
+++ b/src/main/java/org/traccar/notificators/NotificatorMail.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2024 Anton Tananaev (anton@traccar.org)
* Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,34 +16,32 @@
*/
package org.traccar.notificators;
+import jakarta.inject.Inject;
+import jakarta.inject.Singleton;
+import jakarta.mail.MessagingException;
import org.traccar.mail.MailManager;
import org.traccar.model.Event;
import org.traccar.model.Position;
import org.traccar.model.User;
import org.traccar.notification.MessageException;
import org.traccar.notification.NotificationFormatter;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.mail.MessagingException;
+import org.traccar.notification.NotificationMessage;
@Singleton
-public class NotificatorMail implements Notificator {
+public class NotificatorMail extends Notificator {
private final MailManager mailManager;
- private final NotificationFormatter notificationFormatter;
@Inject
public NotificatorMail(MailManager mailManager, NotificationFormatter notificationFormatter) {
+ super(notificationFormatter, "full");
this.mailManager = mailManager;
- this.notificationFormatter = notificationFormatter;
}
@Override
- public void send(User user, Event event, Position position) throws MessageException {
+ public void send(User user, NotificationMessage message, Event event, Position position) throws MessageException {
try {
- var fullMessage = notificationFormatter.formatMessage(user, event, position, "full");
- mailManager.sendMessage(user, fullMessage.getSubject(), fullMessage.getBody());
+ mailManager.sendMessage(user, false, message.getSubject(), message.getBody());
} catch (MessagingException e) {
throw new MessageException(e);
}
diff --git a/src/main/java/org/traccar/notificators/NotificatorNull.java b/src/main/java/org/traccar/notificators/NotificatorNull.java
deleted file mode 100644
index ba9ade9c6..000000000
--- a/src/main/java/org/traccar/notificators/NotificatorNull.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org)
- * Copyright 2018 Andrey Kunitsyn (andrey@traccar.org)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.traccar.notificators;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.traccar.model.Event;
-import org.traccar.model.Position;
-import org.traccar.model.User;
-
-public class NotificatorNull implements Notificator {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(NotificatorNull.class);
-
- @Override
- public void send(User user, Event event, Position position) {
- LOGGER.warn("You are using null notificatior, please check your configuration, notification not sent");
- }
-
-}
diff --git a/src/main/java/org/traccar/notificators/NotificatorPushover.java b/src/main/java/org/traccar/notificators/NotificatorPushover.java
index e00db0579..a9708818b 100644
--- a/src/main/java/org/traccar/notificators/NotificatorPushover.java
+++ b/src/main/java/org/traccar/notificators/NotificatorPushover.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,22 +16,21 @@
package org.traccar.notificators;
import com.fasterxml.jackson.annotation.JsonProperty;
+import jakarta.inject.Inject;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.Entity;
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 javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.Entity;
+import org.traccar.notification.NotificationMessage;
@Singleton
-public class NotificatorPushover implements Notificator {
+public class NotificatorPushover extends Notificator {
- private final NotificationFormatter notificationFormatter;
private final Client client;
private final String url;
@@ -53,7 +52,7 @@ public class NotificatorPushover implements Notificator {
@Inject
public NotificatorPushover(Config config, NotificationFormatter notificationFormatter, Client client) {
- this.notificationFormatter = notificationFormatter;
+ super(notificationFormatter, "short");
this.client = client;
url = "https://api.pushover.net/1/messages.json";
token = config.getString(Keys.NOTIFICATOR_PUSHOVER_TOKEN);
@@ -61,8 +60,7 @@ public class NotificatorPushover implements Notificator {
}
@Override
- public void send(User user, Event event, Position position) {
- var shortMessage = notificationFormatter.formatMessage(user, event, position, "short");
+ public void send(User user, NotificationMessage shortMessage, Event event, Position position) {
Message message = new Message();
message.token = token;
diff --git a/src/main/java/org/traccar/notificators/NotificatorSms.java b/src/main/java/org/traccar/notificators/NotificatorSms.java
index e37d10888..a8086adcc 100644
--- a/src/main/java/org/traccar/notificators/NotificatorSms.java
+++ b/src/main/java/org/traccar/notificators/NotificatorSms.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2024 Anton Tananaev (anton@traccar.org)
* Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,38 +16,36 @@
*/
package org.traccar.notificators;
+import jakarta.inject.Inject;
+import jakarta.inject.Singleton;
import org.traccar.database.StatisticsManager;
import org.traccar.model.Event;
import org.traccar.model.Position;
import org.traccar.model.User;
import org.traccar.notification.MessageException;
import org.traccar.notification.NotificationFormatter;
+import org.traccar.notification.NotificationMessage;
import org.traccar.sms.SmsManager;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
@Singleton
-public class NotificatorSms implements Notificator {
+public class NotificatorSms extends Notificator {
private final SmsManager smsManager;
- private final NotificationFormatter notificationFormatter;
private final StatisticsManager statisticsManager;
@Inject
public NotificatorSms(
SmsManager smsManager, NotificationFormatter notificationFormatter, StatisticsManager statisticsManager) {
+ super(notificationFormatter, "short");
this.smsManager = smsManager;
- this.notificationFormatter = notificationFormatter;
this.statisticsManager = statisticsManager;
}
@Override
- public void send(User user, Event event, Position position) throws MessageException, InterruptedException {
+ public void send(User user, NotificationMessage message, Event event, Position position) throws MessageException {
if (user.getPhone() != null) {
- var shortMessage = notificationFormatter.formatMessage(user, event, position, "short");
statisticsManager.registerSms();
- smsManager.sendMessage(user.getPhone(), shortMessage.getBody(), false);
+ smsManager.sendMessage(user.getPhone(), message.getBody(), false);
}
}
diff --git a/src/main/java/org/traccar/notificators/NotificatorTelegram.java b/src/main/java/org/traccar/notificators/NotificatorTelegram.java
index 38e87c222..4c8d7b8aa 100644
--- a/src/main/java/org/traccar/notificators/NotificatorTelegram.java
+++ b/src/main/java/org/traccar/notificators/NotificatorTelegram.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 - 2022 Anton Tananaev (anton@traccar.org)
+ * Copyright 2019 - 2024 Anton Tananaev (anton@traccar.org)
* Copyright 2021 Rafael Miquelino (rafaelmiquelino@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,22 +17,21 @@
package org.traccar.notificators;
import com.fasterxml.jackson.annotation.JsonProperty;
+import jakarta.inject.Inject;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.Entity;
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 javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.Entity;
+import org.traccar.notification.NotificationMessage;
@Singleton
-public class NotificatorTelegram implements Notificator {
+public class NotificatorTelegram extends Notificator {
- private final NotificationFormatter notificationFormatter;
private final Client client;
private final String urlSendText;
@@ -64,7 +63,7 @@ public class NotificatorTelegram implements Notificator {
@Inject
public NotificatorTelegram(Config config, NotificationFormatter notificationFormatter, Client client) {
- this.notificationFormatter = notificationFormatter;
+ super(notificationFormatter, "short");
this.client = client;
urlSendText = String.format(
"https://api.telegram.org/bot%s/sendMessage", config.getString(Keys.NOTIFICATOR_TELEGRAM_KEY));
@@ -85,8 +84,7 @@ public class NotificatorTelegram implements Notificator {
}
@Override
- public void send(User user, Event event, Position position) {
- var shortMessage = notificationFormatter.formatMessage(user, event, position, "short");
+ public void send(User user, NotificationMessage shortMessage, Event event, Position position) {
TextMessage message = new TextMessage();
message.chatId = user.getString("telegramChatId");
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);
+ }
}
}
diff --git a/src/main/java/org/traccar/notificators/NotificatorWeb.java b/src/main/java/org/traccar/notificators/NotificatorWeb.java
index deabeade1..b7bbdac1b 100644
--- a/src/main/java/org/traccar/notificators/NotificatorWeb.java
+++ b/src/main/java/org/traccar/notificators/NotificatorWeb.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 - 2022 Anton Tananaev (anton@traccar.org)
+ * Copyright 2018 - 2024 Anton Tananaev (anton@traccar.org)
* Copyright 2018 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,29 +17,30 @@
package org.traccar.notificators;
import org.traccar.model.Event;
+import org.traccar.model.Notification;
import org.traccar.model.Position;
import org.traccar.model.User;
import org.traccar.notification.NotificationFormatter;
import org.traccar.session.ConnectionManager;
-import javax.inject.Inject;
-import javax.inject.Singleton;
+import jakarta.inject.Inject;
+import jakarta.inject.Singleton;
@Singleton
-public final class NotificatorWeb implements Notificator {
+public final class NotificatorWeb extends Notificator {
private final ConnectionManager connectionManager;
private final NotificationFormatter notificationFormatter;
@Inject
- public NotificatorWeb(
- ConnectionManager connectionManager, NotificationFormatter notificationFormatter) {
+ public NotificatorWeb(ConnectionManager connectionManager, NotificationFormatter notificationFormatter) {
+ super(null, null);
this.connectionManager = connectionManager;
this.notificationFormatter = notificationFormatter;
}
@Override
- public void send(User user, Event event, Position position) {
+ public void send(Notification notification, User user, Event event, Position position) {
Event copy = new Event();
copy.setId(event.getId());
@@ -51,7 +52,7 @@ public final class NotificatorWeb implements Notificator {
copy.setMaintenanceId(event.getMaintenanceId());
copy.getAttributes().putAll(event.getAttributes());
- var message = notificationFormatter.formatMessage(user, event, position, "short");
+ var message = notificationFormatter.formatMessage(notification, user, event, position, "short");
copy.set("message", message.getBody());
connectionManager.updateEvent(true, user.getId(), copy);