diff --git a/lib/src/main/java/org/asamk/signal/manager/api/Message.java b/lib/src/main/java/org/asamk/signal/manager/api/Message.java index 9b372451..09ac0d18 100644 --- a/lib/src/main/java/org/asamk/signal/manager/api/Message.java +++ b/lib/src/main/java/org/asamk/signal/manager/api/Message.java @@ -12,7 +12,8 @@ public record Message( Optional sticker, List previews, Optional storyReply, - List textStyles + List textStyles, + boolean noUrgent ) { public record Mention(RecipientIdentifier.Single recipient, int start, int length) {} diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java index 0bd1d280..516ff1e1 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java @@ -682,7 +682,7 @@ public class GroupHelper { private void sendExpirationTimerUpdate(GroupIdV1 groupId) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException { final var messageBuilder = SignalServiceDataMessage.newBuilder().asExpirationUpdate(); - context.getSendHelper().sendAsGroupMessage(messageBuilder, groupId, false, Optional.empty()); + context.getSendHelper().sendAsGroupMessage(messageBuilder, groupId, false, Optional.empty(), true); } private SendGroupMessageResults updateGroupV2( diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java index bb571a03..10259350 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java @@ -84,7 +84,8 @@ public class SendHelper { public SendMessageResult sendMessage( final SignalServiceDataMessage.Builder messageBuilder, final RecipientId recipientId, - Optional editTargetTimestamp + Optional editTargetTimestamp, + boolean urgent ) { var contact = account.getContactStore().getContact(recipientId); if (contact == null || !contact.isProfileSharingEnabled() || contact.isHidden()) { @@ -102,7 +103,7 @@ public class SendHelper { } final var message = messageBuilder.build(); - return sendMessage(message, recipientId, editTargetTimestamp); + return sendMessage(message, recipientId, editTargetTimestamp, urgent); } /** @@ -113,10 +114,11 @@ public class SendHelper { final SignalServiceDataMessage.Builder messageBuilder, final GroupId groupId, final boolean includeSelf, - final Optional editTargetTimestamp + final Optional editTargetTimestamp, + boolean urgent ) throws IOException, GroupNotFoundException, NotAGroupMemberException, GroupSendingNotAllowedException { final var g = getGroupForSending(groupId); - return sendAsGroupMessage(messageBuilder, g, includeSelf, editTargetTimestamp); + return sendAsGroupMessage(messageBuilder, g, includeSelf, editTargetTimestamp, urgent); } /** @@ -128,7 +130,7 @@ public class SendHelper { final Set recipientIds, final GroupInfo groupInfo ) throws IOException { - return sendGroupMessage(message, recipientIds, groupInfo, ContentHint.IMPLICIT, Optional.empty()); + return sendGroupMessage(message, recipientIds, groupInfo, ContentHint.IMPLICIT, Optional.empty(), true); } public SendMessageResult sendReceiptMessage( @@ -311,7 +313,8 @@ public class SendHelper { final SignalServiceDataMessage.Builder messageBuilder, final GroupInfo g, final boolean includeSelf, - final Optional editTargetTimestamp + final Optional editTargetTimestamp, + boolean urgent ) throws IOException, GroupSendingNotAllowedException { GroupUtils.setGroupContext(messageBuilder, g); messageBuilder.withExpiration(g.getMessageExpirationTimer()); @@ -330,7 +333,7 @@ public class SendHelper { } } - return sendGroupMessage(message, recipients, g, ContentHint.RESENDABLE, editTargetTimestamp); + return sendGroupMessage(message, recipients, g, ContentHint.RESENDABLE, editTargetTimestamp, urgent); } private List sendGroupMessage( @@ -338,13 +341,13 @@ public class SendHelper { final Set recipientIds, final GroupInfo groupInfo, final ContentHint contentHint, - final Optional editTargetTimestamp + final Optional editTargetTimestamp, + boolean urgent ) throws IOException { final var messageSender = dependencies.getMessageSender(); final var messageSendLogStore = account.getMessageSendLogStore(); final AtomicLong entryId = new AtomicLong(-1); - final var urgent = true; final PartialSendCompleteListener partialSendCompleteListener = sendResult -> { logger.trace("Partial message send result: {}", sendResult.isSuccess()); synchronized (entryId) { @@ -712,10 +715,10 @@ public class SendHelper { private SendMessageResult sendMessage( SignalServiceDataMessage message, RecipientId recipientId, - Optional editTargetTimestamp + Optional editTargetTimestamp, + boolean urgent ) { final var messageSendLogStore = account.getMessageSendLogStore(); - final var urgent = true; final var result = handleSendMessage(recipientId, editTargetTimestamp.isEmpty() ? (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.sendDataMessage( diff --git a/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java index 4c34d965..29060403 100644 --- a/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java @@ -666,14 +666,15 @@ public class ManagerImpl implements Manager { Set recipients, boolean notifySelf ) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException { - return sendMessage(messageBuilder, recipients, notifySelf, Optional.empty()); + return sendMessage(messageBuilder, recipients, notifySelf, Optional.empty(), true); } private SendMessageResults sendMessage( SignalServiceDataMessage.Builder messageBuilder, Set recipients, boolean notifySelf, - Optional editTargetTimestamp + Optional editTargetTimestamp, + boolean urgent ) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException { var results = new HashMap>(); long timestamp = getNextMessageTimestamp(); @@ -685,14 +686,14 @@ public class ManagerImpl implements Manager { )) { final var result = notifySelf ? context.getSendHelper() - .sendMessage(messageBuilder, account.getSelfRecipientId(), editTargetTimestamp) + .sendMessage(messageBuilder, account.getSelfRecipientId(), editTargetTimestamp, urgent) : context.getSendHelper().sendSelfMessage(messageBuilder, editTargetTimestamp); results.put(recipient, List.of(toSendMessageResult(result))); } else if (recipient instanceof RecipientIdentifier.Single single) { try { final var recipientId = context.getRecipientHelper().resolveRecipient(single); final var result = context.getSendHelper() - .sendMessage(messageBuilder, recipientId, editTargetTimestamp); + .sendMessage(messageBuilder, recipientId, editTargetTimestamp, urgent); results.put(recipient, List.of(toSendMessageResult(result))); } catch (UnregisteredRecipientException e) { results.put(recipient, @@ -700,7 +701,7 @@ public class ManagerImpl implements Manager { } } else if (recipient instanceof RecipientIdentifier.Group group) { final var result = context.getSendHelper() - .sendAsGroupMessage(messageBuilder, group.groupId(), notifySelf, editTargetTimestamp); + .sendAsGroupMessage(messageBuilder, group.groupId(), notifySelf, editTargetTimestamp, urgent); results.put(recipient, result.stream().map(this::toSendMessageResult).toList()); } } @@ -799,7 +800,7 @@ public class ManagerImpl implements Manager { } final var messageBuilder = SignalServiceDataMessage.newBuilder(); applyMessage(messageBuilder, message); - return sendMessage(messageBuilder, recipients, notifySelf); + return sendMessage(messageBuilder, recipients, notifySelf, Optional.empty(), !message.noUrgent()); } @Override @@ -810,7 +811,7 @@ public class ManagerImpl implements Manager { ) throws IOException, AttachmentInvalidException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException, UnregisteredRecipientException, InvalidStickerException { final var messageBuilder = SignalServiceDataMessage.newBuilder(); applyMessage(messageBuilder, message); - return sendMessage(messageBuilder, recipients, false, Optional.of(editTargetTimestamp)); + return sendMessage(messageBuilder, recipients, false, Optional.of(editTargetTimestamp), !message.noUrgent()); } private void applyMessage( diff --git a/src/main/java/org/asamk/signal/commands/SendCommand.java b/src/main/java/org/asamk/signal/commands/SendCommand.java index a957a161..81d14d05 100644 --- a/src/main/java/org/asamk/signal/commands/SendCommand.java +++ b/src/main/java/org/asamk/signal/commands/SendCommand.java @@ -105,6 +105,10 @@ public class SendCommand implements JsonRpcLocalCommand { subparser.addArgument("--edit-timestamp") .type(long.class) .help("Specify the timestamp of a previous message with the recipient or group to send an edited message."); + subparser.addArgument("--no-urgent") + .action(Arguments.storeTrue()) + .help("Send the message without the urgent flag, so no push notification is triggered for the recipient. " + + "The message will still be delivered in real-time if the recipient's app is active."); } @Override @@ -115,6 +119,7 @@ public class SendCommand implements JsonRpcLocalCommand { ) throws CommandException { final var notifySelf = Boolean.TRUE.equals(ns.getBoolean("notify-self")); final var isNoteToSelf = Boolean.TRUE.equals(ns.getBoolean("note-to-self")); + final var noUrgent = Boolean.TRUE.equals(ns.getBoolean("no-urgent")); final var recipientStrings = ns.getList("recipient"); final var groupIdStrings = ns.getList("group-id"); final var usernameStrings = ns.getList("username"); @@ -247,7 +252,8 @@ public class SendCommand implements JsonRpcLocalCommand { Optional.ofNullable(sticker), previews, Optional.ofNullable((storyReply)), - textStyles); + textStyles, + noUrgent); var results = editTimestamp != null ? m.sendEditMessage(message, recipientIdentifiers, editTimestamp) : m.sendMessage(message, recipientIdentifiers, notifySelf); diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index 98720728..3da66439 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -242,7 +242,8 @@ public class DbusSignalImpl implements Signal, AutoCloseable { Optional.empty(), List.of(), Optional.empty(), - List.of()); + List.of(), + false); final var recipientIdentifiers = getSingleRecipientIdentifiers(recipients, m.getSelfNumber()).stream() .map(RecipientIdentifier.class::cast) .collect(Collectors.toSet()); @@ -407,7 +408,8 @@ public class DbusSignalImpl implements Signal, AutoCloseable { Optional.empty(), List.of(), Optional.empty(), - List.of()); + List.of(), + false); final var results = m.sendMessage(message, Set.of(RecipientIdentifier.NoteToSelf.INSTANCE), false); checkSendMessageResults(results); return results.timestamp(); @@ -453,7 +455,8 @@ public class DbusSignalImpl implements Signal, AutoCloseable { Optional.empty(), List.of(), Optional.empty(), - List.of()); + List.of(), + false); var results = m.sendMessage(message, Set.of(getGroupRecipientIdentifier(groupId)), false); checkSendMessageResults(results); return results.timestamp();