From 3290a5bf4d642beaef6584a700aab8f2da3af6e0 Mon Sep 17 00:00:00 2001 From: AsamK Date: Fri, 12 Jan 2024 18:07:14 +0100 Subject: [PATCH] Add --notify-self parmeter Fixes #1087 --- CHANGELOG.md | 4 +- .../org/asamk/signal/manager/Manager.java | 2 +- .../signal/manager/helper/GroupHelper.java | 2 +- .../signal/manager/helper/SendHelper.java | 14 +++++-- .../signal/manager/internal/ManagerImpl.java | 39 ++++++++++++------- .../asamk/signal/commands/SendCommand.java | 6 ++- .../asamk/signal/dbus/DbusManagerImpl.java | 2 +- .../org/asamk/signal/dbus/DbusSignalImpl.java | 39 ++++++++++--------- 8 files changed, 66 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25aa6e45..40bb6d37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,12 @@ ## [Unreleased] -**Attention**: Now requires Java 21 +**Attention**: Now requires Java 21 and libsignal-client version 0.37 ### Added - New --hidden parameter for removeContact command +- New --notify-self parameter for send command, for sending a non-sync message when self is part of the recipients or groups. + With this parameter sending to the self number (+XXXX) now behaves the same as the --note-to-self parameter. ### Improved - Better shutdown handling after Ctrl+C and SIGTERM diff --git a/lib/src/main/java/org/asamk/signal/manager/Manager.java b/lib/src/main/java/org/asamk/signal/manager/Manager.java index ac88e2bc..4104a8fb 100644 --- a/lib/src/main/java/org/asamk/signal/manager/Manager.java +++ b/lib/src/main/java/org/asamk/signal/manager/Manager.java @@ -172,7 +172,7 @@ public interface Manager extends Closeable { ); SendMessageResults sendMessage( - Message message, Set recipients + Message message, Set recipients, boolean notifySelf ) throws IOException, AttachmentInvalidException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException, UnregisteredRecipientException, InvalidStickerException; SendMessageResults sendEditMessage( 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 a7a5dfb7..40558a89 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 @@ -551,7 +551,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, Optional.empty()); + context.getSendHelper().sendAsGroupMessage(messageBuilder, groupId, false, Optional.empty()); } 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 2af6337f..38e8de17 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 @@ -101,10 +101,13 @@ public class SendHelper { * The message is extended with the current expiration timer for the group and the group context. */ public List sendAsGroupMessage( - SignalServiceDataMessage.Builder messageBuilder, GroupId groupId, Optional editTargetTimestamp + final SignalServiceDataMessage.Builder messageBuilder, + final GroupId groupId, + final boolean includeSelf, + final Optional editTargetTimestamp ) throws IOException, GroupNotFoundException, NotAGroupMemberException, GroupSendingNotAllowedException { final var g = getGroupForSending(groupId); - return sendAsGroupMessage(messageBuilder, g, editTargetTimestamp); + return sendAsGroupMessage(messageBuilder, g, includeSelf, editTargetTimestamp); } /** @@ -297,13 +300,16 @@ public class SendHelper { } private List sendAsGroupMessage( - final SignalServiceDataMessage.Builder messageBuilder, final GroupInfo g, Optional editTargetTimestamp + final SignalServiceDataMessage.Builder messageBuilder, + final GroupInfo g, + final boolean includeSelf, + final Optional editTargetTimestamp ) throws IOException, GroupSendingNotAllowedException { GroupUtils.setGroupContext(messageBuilder, g); messageBuilder.withExpiration(g.getMessageExpirationTimer()); final var message = messageBuilder.build(); - final var recipients = g.getMembersWithout(account.getSelfRecipientId()); + final var recipients = includeSelf ? g.getMembers() : g.getMembersWithout(account.getSelfRecipientId()); if (g.isAnnouncementGroup() && !g.isAdmin(account.getSelfRecipientId())) { if (message.getBody().isPresent() 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 e87550b1..bc801a28 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 @@ -71,6 +71,7 @@ import org.asamk.signal.manager.storage.AvatarStore; import org.asamk.signal.manager.storage.SignalAccount; import org.asamk.signal.manager.storage.groups.GroupInfo; import org.asamk.signal.manager.storage.identities.IdentityInfo; +import org.asamk.signal.manager.storage.recipients.RecipientAddress; import org.asamk.signal.manager.storage.recipients.RecipientId; import org.asamk.signal.manager.storage.stickerPacks.JsonStickerPack; import org.asamk.signal.manager.storage.stickerPacks.StickerPackStore; @@ -528,21 +529,31 @@ public class ManagerImpl implements Manager { } private SendMessageResults sendMessage( - SignalServiceDataMessage.Builder messageBuilder, Set recipients + SignalServiceDataMessage.Builder messageBuilder, Set recipients, boolean notifySelf ) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException { - return sendMessage(messageBuilder, recipients, Optional.empty()); + return sendMessage(messageBuilder, recipients, notifySelf, Optional.empty()); } private SendMessageResults sendMessage( SignalServiceDataMessage.Builder messageBuilder, Set recipients, + boolean notifySelf, Optional editTargetTimestamp ) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException { var results = new HashMap>(); long timestamp = System.currentTimeMillis(); messageBuilder.withTimestamp(timestamp); for (final var recipient : recipients) { - if (recipient instanceof RecipientIdentifier.Single single) { + if (recipient instanceof RecipientIdentifier.NoteToSelf || ( + recipient instanceof RecipientIdentifier.Single single + && new RecipientAddress(single.toPartialRecipientAddress()).matches(account.getSelfRecipientAddress()) + )) { + final var result = notifySelf + ? context.getSendHelper() + .sendMessage(messageBuilder, account.getSelfRecipientId(), editTargetTimestamp) + : 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() @@ -552,12 +563,9 @@ public class ManagerImpl implements Manager { results.put(recipient, List.of(SendMessageResult.unregisteredFailure(single.toPartialRecipientAddress()))); } - } else if (recipient instanceof RecipientIdentifier.NoteToSelf) { - final var result = context.getSendHelper().sendSelfMessage(messageBuilder, editTargetTimestamp); - results.put(recipient, List.of(toSendMessageResult(result))); } else if (recipient instanceof RecipientIdentifier.Group group) { final var result = context.getSendHelper() - .sendAsGroupMessage(messageBuilder, group.groupId(), editTargetTimestamp); + .sendAsGroupMessage(messageBuilder, group.groupId(), notifySelf, editTargetTimestamp); results.put(recipient, result.stream().map(this::toSendMessageResult).toList()); } } @@ -642,7 +650,7 @@ public class ManagerImpl implements Manager { @Override public SendMessageResults sendMessage( - Message message, Set recipients + Message message, Set recipients, boolean notifySelf ) throws IOException, AttachmentInvalidException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException, UnregisteredRecipientException, InvalidStickerException { final var selfProfile = context.getProfileHelper().getSelfProfile(); if (selfProfile == null || selfProfile.getDisplayName().isEmpty()) { @@ -651,7 +659,7 @@ public class ManagerImpl implements Manager { } final var messageBuilder = SignalServiceDataMessage.newBuilder(); applyMessage(messageBuilder, message); - return sendMessage(messageBuilder, recipients); + return sendMessage(messageBuilder, recipients, notifySelf); } @Override @@ -660,7 +668,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, Optional.of(editTargetTimestamp)); + return sendMessage(messageBuilder, recipients, false, Optional.of(editTargetTimestamp)); } private void applyMessage( @@ -785,7 +793,7 @@ public class ManagerImpl implements Manager { account.getMessageSendLogStore().deleteEntryForGroup(targetSentTimestamp, r.groupId()); } } - return sendMessage(messageBuilder, recipients); + return sendMessage(messageBuilder, recipients, false); } @Override @@ -807,7 +815,7 @@ public class ManagerImpl implements Manager { messageBuilder.withStoryContext(new SignalServiceDataMessage.StoryContext(authorServiceId, targetSentTimestamp)); } - return sendMessage(messageBuilder, recipients); + return sendMessage(messageBuilder, recipients, false); } @Override @@ -818,7 +826,7 @@ public class ManagerImpl implements Manager { final var payment = new SignalServiceDataMessage.Payment(paymentNotification, null); final var messageBuilder = SignalServiceDataMessage.newBuilder().withPayment(payment); try { - return sendMessage(messageBuilder, Set.of(recipient)); + return sendMessage(messageBuilder, Set.of(recipient), false); } catch (NotAGroupMemberException | GroupNotFoundException | GroupSendingNotAllowedException e) { throw new AssertionError(e); } @@ -830,7 +838,8 @@ public class ManagerImpl implements Manager { try { return sendMessage(messageBuilder, - recipients.stream().map(RecipientIdentifier.class::cast).collect(Collectors.toSet())); + recipients.stream().map(RecipientIdentifier.class::cast).collect(Collectors.toSet()), + false); } catch (GroupNotFoundException | NotAGroupMemberException | GroupSendingNotAllowedException e) { throw new AssertionError(e); } finally { @@ -952,7 +961,7 @@ public class ManagerImpl implements Manager { context.getContactHelper().setExpirationTimer(recipientId, messageExpirationTimer); final var messageBuilder = SignalServiceDataMessage.newBuilder().asExpirationUpdate(); try { - sendMessage(messageBuilder, Set.of(recipient)); + sendMessage(messageBuilder, Set.of(recipient), false); } catch (NotAGroupMemberException | GroupNotFoundException | GroupSendingNotAllowedException e) { throw new AssertionError(e); } diff --git a/src/main/java/org/asamk/signal/commands/SendCommand.java b/src/main/java/org/asamk/signal/commands/SendCommand.java index 1d0b46e4..0c38cf7d 100644 --- a/src/main/java/org/asamk/signal/commands/SendCommand.java +++ b/src/main/java/org/asamk/signal/commands/SendCommand.java @@ -51,6 +51,9 @@ public class SendCommand implements JsonRpcLocalCommand { subparser.addArgument("--note-to-self") .help("Send the message to self without notification.") .action(Arguments.storeTrue()); + subparser.addArgument("--notify-self") + .help("If self is part of recipients/groups send a normal message, not a sync message.") + .action(Arguments.storeTrue()); var mut = subparser.addMutuallyExclusiveGroup(); mut.addArgument("-m", "--message").help("Specify the message to be sent."); @@ -105,6 +108,7 @@ public class SendCommand implements JsonRpcLocalCommand { public void handleCommand( final Namespace ns, final Manager m, final OutputWriter outputWriter ) 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 recipientStrings = ns.getList("recipient"); final var groupIdStrings = ns.getList("group-id"); @@ -236,7 +240,7 @@ public class SendCommand implements JsonRpcLocalCommand { textStyles); var results = editTimestamp != null ? m.sendEditMessage(message, recipientIdentifiers, editTimestamp) - : m.sendMessage(message, recipientIdentifiers); + : m.sendMessage(message, recipientIdentifiers, notifySelf); outputResult(outputWriter, results); } catch (AttachmentInvalidException | IOException e) { throw new UnexpectedErrorException("Failed to send message: " + e.getMessage() + " (" + e.getClass() diff --git a/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java b/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java index 985e2674..e149e58c 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java @@ -397,7 +397,7 @@ public class DbusManagerImpl implements Manager { @Override public SendMessageResults sendMessage( - final Message message, final Set recipients + final Message message, final Set recipients, final boolean notifySelf ) throws IOException, AttachmentInvalidException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException { return handleMessage(recipients, numbers -> signal.sendMessage(message.messageText(), message.attachments(), numbers), diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index 6e394eb4..5ad14537 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -225,19 +225,20 @@ public class DbusSignalImpl implements Signal, AutoCloseable { } @Override - public long sendMessage(final String message, final List attachments, final List recipients) { + public long sendMessage(final String messageText, final List attachments, final List recipients) { try { - final var results = m.sendMessage(new Message(message, - attachments, - List.of(), - Optional.empty(), - Optional.empty(), - List.of(), - Optional.empty(), - List.of()), - getSingleRecipientIdentifiers(recipients, m.getSelfNumber()).stream() - .map(RecipientIdentifier.class::cast) - .collect(Collectors.toSet())); + final var message = new Message(messageText, + attachments, + List.of(), + Optional.empty(), + Optional.empty(), + List.of(), + Optional.empty(), + List.of()); + final var recipientIdentifiers = getSingleRecipientIdentifiers(recipients, m.getSelfNumber()).stream() + .map(RecipientIdentifier.class::cast) + .collect(Collectors.toSet()); + final var results = m.sendMessage(message, recipientIdentifiers, false); checkSendMessageResults(results); return results.timestamp(); @@ -384,17 +385,18 @@ public class DbusSignalImpl implements Signal, AutoCloseable { @Override public long sendNoteToSelfMessage( - final String message, final List attachments + final String messageText, final List attachments ) throws Error.AttachmentInvalid, Error.Failure, Error.UntrustedIdentity { try { - final var results = m.sendMessage(new Message(message, + final var message = new Message(messageText, attachments, List.of(), Optional.empty(), Optional.empty(), List.of(), Optional.empty(), - List.of()), Set.of(RecipientIdentifier.NoteToSelf.INSTANCE)); + List.of()); + final var results = m.sendMessage(message, Set.of(RecipientIdentifier.NoteToSelf.INSTANCE), false); checkSendMessageResults(results); return results.timestamp(); } catch (AttachmentInvalidException e) { @@ -429,16 +431,17 @@ public class DbusSignalImpl implements Signal, AutoCloseable { } @Override - public long sendGroupMessage(final String message, final List attachments, final byte[] groupId) { + public long sendGroupMessage(final String messageText, final List attachments, final byte[] groupId) { try { - var results = m.sendMessage(new Message(message, + final var message = new Message(messageText, attachments, List.of(), Optional.empty(), Optional.empty(), List.of(), Optional.empty(), - List.of()), Set.of(getGroupRecipientIdentifier(groupId))); + List.of()); + var results = m.sendMessage(message, Set.of(getGroupRecipientIdentifier(groupId)), false); checkSendMessageResults(results); return results.timestamp(); } catch (IOException | InvalidStickerException e) { -- 2.50.1