mirror of
https://github.com/AsamK/signal-cli.git
synced 2026-05-27 14:44:16 +00:00
Add --no-urgent flag to send command (#1933)
* Add --no-push flag to send command Expose the server's `urgent` parameter so callers can skip sending a push notification (FCM/APNs) to the recipient. The message is still delivered in real-time over WebSocket if the recipient's app is active. The flag is added to the Message record (following the same pattern as viewOnce) and threaded through ManagerImpl and SendHelper, keeping the Manager interface unchanged. * Rename --no-push flag to --no-urgent Align with the protocol naming as suggested by the maintainer. The flag controls the 'urgent' parameter on the server request.
This commit is contained in:
parent
4a35d47515
commit
d4b3816c5d
@ -12,7 +12,8 @@ public record Message(
|
|||||||
Optional<Sticker> sticker,
|
Optional<Sticker> sticker,
|
||||||
List<Preview> previews,
|
List<Preview> previews,
|
||||||
Optional<StoryReply> storyReply,
|
Optional<StoryReply> storyReply,
|
||||||
List<TextStyle> textStyles
|
List<TextStyle> textStyles,
|
||||||
|
boolean noUrgent
|
||||||
) {
|
) {
|
||||||
|
|
||||||
public record Mention(RecipientIdentifier.Single recipient, int start, int length) {}
|
public record Mention(RecipientIdentifier.Single recipient, int start, int length) {}
|
||||||
|
|||||||
@ -682,7 +682,7 @@ public class GroupHelper {
|
|||||||
|
|
||||||
private void sendExpirationTimerUpdate(GroupIdV1 groupId) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException {
|
private void sendExpirationTimerUpdate(GroupIdV1 groupId) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException {
|
||||||
final var messageBuilder = SignalServiceDataMessage.newBuilder().asExpirationUpdate();
|
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(
|
private SendGroupMessageResults updateGroupV2(
|
||||||
|
|||||||
@ -84,7 +84,8 @@ public class SendHelper {
|
|||||||
public SendMessageResult sendMessage(
|
public SendMessageResult sendMessage(
|
||||||
final SignalServiceDataMessage.Builder messageBuilder,
|
final SignalServiceDataMessage.Builder messageBuilder,
|
||||||
final RecipientId recipientId,
|
final RecipientId recipientId,
|
||||||
Optional<Long> editTargetTimestamp
|
Optional<Long> editTargetTimestamp,
|
||||||
|
boolean urgent
|
||||||
) {
|
) {
|
||||||
var contact = account.getContactStore().getContact(recipientId);
|
var contact = account.getContactStore().getContact(recipientId);
|
||||||
if (contact == null || !contact.isProfileSharingEnabled() || contact.isHidden()) {
|
if (contact == null || !contact.isProfileSharingEnabled() || contact.isHidden()) {
|
||||||
@ -102,7 +103,7 @@ public class SendHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final var message = messageBuilder.build();
|
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 SignalServiceDataMessage.Builder messageBuilder,
|
||||||
final GroupId groupId,
|
final GroupId groupId,
|
||||||
final boolean includeSelf,
|
final boolean includeSelf,
|
||||||
final Optional<Long> editTargetTimestamp
|
final Optional<Long> editTargetTimestamp,
|
||||||
|
boolean urgent
|
||||||
) throws IOException, GroupNotFoundException, NotAGroupMemberException, GroupSendingNotAllowedException {
|
) throws IOException, GroupNotFoundException, NotAGroupMemberException, GroupSendingNotAllowedException {
|
||||||
final var g = getGroupForSending(groupId);
|
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<RecipientId> recipientIds,
|
final Set<RecipientId> recipientIds,
|
||||||
final GroupInfo groupInfo
|
final GroupInfo groupInfo
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
return sendGroupMessage(message, recipientIds, groupInfo, ContentHint.IMPLICIT, Optional.empty());
|
return sendGroupMessage(message, recipientIds, groupInfo, ContentHint.IMPLICIT, Optional.empty(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SendMessageResult sendReceiptMessage(
|
public SendMessageResult sendReceiptMessage(
|
||||||
@ -311,7 +313,8 @@ public class SendHelper {
|
|||||||
final SignalServiceDataMessage.Builder messageBuilder,
|
final SignalServiceDataMessage.Builder messageBuilder,
|
||||||
final GroupInfo g,
|
final GroupInfo g,
|
||||||
final boolean includeSelf,
|
final boolean includeSelf,
|
||||||
final Optional<Long> editTargetTimestamp
|
final Optional<Long> editTargetTimestamp,
|
||||||
|
boolean urgent
|
||||||
) throws IOException, GroupSendingNotAllowedException {
|
) throws IOException, GroupSendingNotAllowedException {
|
||||||
GroupUtils.setGroupContext(messageBuilder, g);
|
GroupUtils.setGroupContext(messageBuilder, g);
|
||||||
messageBuilder.withExpiration(g.getMessageExpirationTimer());
|
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<SendMessageResult> sendGroupMessage(
|
private List<SendMessageResult> sendGroupMessage(
|
||||||
@ -338,13 +341,13 @@ public class SendHelper {
|
|||||||
final Set<RecipientId> recipientIds,
|
final Set<RecipientId> recipientIds,
|
||||||
final GroupInfo groupInfo,
|
final GroupInfo groupInfo,
|
||||||
final ContentHint contentHint,
|
final ContentHint contentHint,
|
||||||
final Optional<Long> editTargetTimestamp
|
final Optional<Long> editTargetTimestamp,
|
||||||
|
boolean urgent
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
final var messageSender = dependencies.getMessageSender();
|
final var messageSender = dependencies.getMessageSender();
|
||||||
final var messageSendLogStore = account.getMessageSendLogStore();
|
final var messageSendLogStore = account.getMessageSendLogStore();
|
||||||
final AtomicLong entryId = new AtomicLong(-1);
|
final AtomicLong entryId = new AtomicLong(-1);
|
||||||
|
|
||||||
final var urgent = true;
|
|
||||||
final PartialSendCompleteListener partialSendCompleteListener = sendResult -> {
|
final PartialSendCompleteListener partialSendCompleteListener = sendResult -> {
|
||||||
logger.trace("Partial message send result: {}", sendResult.isSuccess());
|
logger.trace("Partial message send result: {}", sendResult.isSuccess());
|
||||||
synchronized (entryId) {
|
synchronized (entryId) {
|
||||||
@ -712,10 +715,10 @@ public class SendHelper {
|
|||||||
private SendMessageResult sendMessage(
|
private SendMessageResult sendMessage(
|
||||||
SignalServiceDataMessage message,
|
SignalServiceDataMessage message,
|
||||||
RecipientId recipientId,
|
RecipientId recipientId,
|
||||||
Optional<Long> editTargetTimestamp
|
Optional<Long> editTargetTimestamp,
|
||||||
|
boolean urgent
|
||||||
) {
|
) {
|
||||||
final var messageSendLogStore = account.getMessageSendLogStore();
|
final var messageSendLogStore = account.getMessageSendLogStore();
|
||||||
final var urgent = true;
|
|
||||||
final var result = handleSendMessage(recipientId,
|
final var result = handleSendMessage(recipientId,
|
||||||
editTargetTimestamp.isEmpty()
|
editTargetTimestamp.isEmpty()
|
||||||
? (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.sendDataMessage(
|
? (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.sendDataMessage(
|
||||||
|
|||||||
@ -666,14 +666,15 @@ public class ManagerImpl implements Manager {
|
|||||||
Set<RecipientIdentifier> recipients,
|
Set<RecipientIdentifier> recipients,
|
||||||
boolean notifySelf
|
boolean notifySelf
|
||||||
) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException {
|
) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException {
|
||||||
return sendMessage(messageBuilder, recipients, notifySelf, Optional.empty());
|
return sendMessage(messageBuilder, recipients, notifySelf, Optional.empty(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SendMessageResults sendMessage(
|
private SendMessageResults sendMessage(
|
||||||
SignalServiceDataMessage.Builder messageBuilder,
|
SignalServiceDataMessage.Builder messageBuilder,
|
||||||
Set<RecipientIdentifier> recipients,
|
Set<RecipientIdentifier> recipients,
|
||||||
boolean notifySelf,
|
boolean notifySelf,
|
||||||
Optional<Long> editTargetTimestamp
|
Optional<Long> editTargetTimestamp,
|
||||||
|
boolean urgent
|
||||||
) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException {
|
) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException {
|
||||||
var results = new HashMap<RecipientIdentifier, List<SendMessageResult>>();
|
var results = new HashMap<RecipientIdentifier, List<SendMessageResult>>();
|
||||||
long timestamp = getNextMessageTimestamp();
|
long timestamp = getNextMessageTimestamp();
|
||||||
@ -685,14 +686,14 @@ public class ManagerImpl implements Manager {
|
|||||||
)) {
|
)) {
|
||||||
final var result = notifySelf
|
final var result = notifySelf
|
||||||
? context.getSendHelper()
|
? context.getSendHelper()
|
||||||
.sendMessage(messageBuilder, account.getSelfRecipientId(), editTargetTimestamp)
|
.sendMessage(messageBuilder, account.getSelfRecipientId(), editTargetTimestamp, urgent)
|
||||||
: context.getSendHelper().sendSelfMessage(messageBuilder, editTargetTimestamp);
|
: context.getSendHelper().sendSelfMessage(messageBuilder, editTargetTimestamp);
|
||||||
results.put(recipient, List.of(toSendMessageResult(result)));
|
results.put(recipient, List.of(toSendMessageResult(result)));
|
||||||
} else if (recipient instanceof RecipientIdentifier.Single single) {
|
} else if (recipient instanceof RecipientIdentifier.Single single) {
|
||||||
try {
|
try {
|
||||||
final var recipientId = context.getRecipientHelper().resolveRecipient(single);
|
final var recipientId = context.getRecipientHelper().resolveRecipient(single);
|
||||||
final var result = context.getSendHelper()
|
final var result = context.getSendHelper()
|
||||||
.sendMessage(messageBuilder, recipientId, editTargetTimestamp);
|
.sendMessage(messageBuilder, recipientId, editTargetTimestamp, urgent);
|
||||||
results.put(recipient, List.of(toSendMessageResult(result)));
|
results.put(recipient, List.of(toSendMessageResult(result)));
|
||||||
} catch (UnregisteredRecipientException e) {
|
} catch (UnregisteredRecipientException e) {
|
||||||
results.put(recipient,
|
results.put(recipient,
|
||||||
@ -700,7 +701,7 @@ public class ManagerImpl implements Manager {
|
|||||||
}
|
}
|
||||||
} else if (recipient instanceof RecipientIdentifier.Group group) {
|
} else if (recipient instanceof RecipientIdentifier.Group group) {
|
||||||
final var result = context.getSendHelper()
|
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());
|
results.put(recipient, result.stream().map(this::toSendMessageResult).toList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -799,7 +800,7 @@ public class ManagerImpl implements Manager {
|
|||||||
}
|
}
|
||||||
final var messageBuilder = SignalServiceDataMessage.newBuilder();
|
final var messageBuilder = SignalServiceDataMessage.newBuilder();
|
||||||
applyMessage(messageBuilder, message);
|
applyMessage(messageBuilder, message);
|
||||||
return sendMessage(messageBuilder, recipients, notifySelf);
|
return sendMessage(messageBuilder, recipients, notifySelf, Optional.empty(), !message.noUrgent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -810,7 +811,7 @@ public class ManagerImpl implements Manager {
|
|||||||
) throws IOException, AttachmentInvalidException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException, UnregisteredRecipientException, InvalidStickerException {
|
) throws IOException, AttachmentInvalidException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException, UnregisteredRecipientException, InvalidStickerException {
|
||||||
final var messageBuilder = SignalServiceDataMessage.newBuilder();
|
final var messageBuilder = SignalServiceDataMessage.newBuilder();
|
||||||
applyMessage(messageBuilder, message);
|
applyMessage(messageBuilder, message);
|
||||||
return sendMessage(messageBuilder, recipients, false, Optional.of(editTargetTimestamp));
|
return sendMessage(messageBuilder, recipients, false, Optional.of(editTargetTimestamp), !message.noUrgent());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyMessage(
|
private void applyMessage(
|
||||||
|
|||||||
@ -105,6 +105,10 @@ public class SendCommand implements JsonRpcLocalCommand {
|
|||||||
subparser.addArgument("--edit-timestamp")
|
subparser.addArgument("--edit-timestamp")
|
||||||
.type(long.class)
|
.type(long.class)
|
||||||
.help("Specify the timestamp of a previous message with the recipient or group to send an edited message.");
|
.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
|
@Override
|
||||||
@ -115,6 +119,7 @@ public class SendCommand implements JsonRpcLocalCommand {
|
|||||||
) throws CommandException {
|
) throws CommandException {
|
||||||
final var notifySelf = Boolean.TRUE.equals(ns.getBoolean("notify-self"));
|
final var notifySelf = Boolean.TRUE.equals(ns.getBoolean("notify-self"));
|
||||||
final var isNoteToSelf = Boolean.TRUE.equals(ns.getBoolean("note-to-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.<String>getList("recipient");
|
final var recipientStrings = ns.<String>getList("recipient");
|
||||||
final var groupIdStrings = ns.<String>getList("group-id");
|
final var groupIdStrings = ns.<String>getList("group-id");
|
||||||
final var usernameStrings = ns.<String>getList("username");
|
final var usernameStrings = ns.<String>getList("username");
|
||||||
@ -247,7 +252,8 @@ public class SendCommand implements JsonRpcLocalCommand {
|
|||||||
Optional.ofNullable(sticker),
|
Optional.ofNullable(sticker),
|
||||||
previews,
|
previews,
|
||||||
Optional.ofNullable((storyReply)),
|
Optional.ofNullable((storyReply)),
|
||||||
textStyles);
|
textStyles,
|
||||||
|
noUrgent);
|
||||||
var results = editTimestamp != null
|
var results = editTimestamp != null
|
||||||
? m.sendEditMessage(message, recipientIdentifiers, editTimestamp)
|
? m.sendEditMessage(message, recipientIdentifiers, editTimestamp)
|
||||||
: m.sendMessage(message, recipientIdentifiers, notifySelf);
|
: m.sendMessage(message, recipientIdentifiers, notifySelf);
|
||||||
|
|||||||
@ -242,7 +242,8 @@ public class DbusSignalImpl implements Signal, AutoCloseable {
|
|||||||
Optional.empty(),
|
Optional.empty(),
|
||||||
List.of(),
|
List.of(),
|
||||||
Optional.empty(),
|
Optional.empty(),
|
||||||
List.of());
|
List.of(),
|
||||||
|
false);
|
||||||
final var recipientIdentifiers = getSingleRecipientIdentifiers(recipients, m.getSelfNumber()).stream()
|
final var recipientIdentifiers = getSingleRecipientIdentifiers(recipients, m.getSelfNumber()).stream()
|
||||||
.map(RecipientIdentifier.class::cast)
|
.map(RecipientIdentifier.class::cast)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
@ -407,7 +408,8 @@ public class DbusSignalImpl implements Signal, AutoCloseable {
|
|||||||
Optional.empty(),
|
Optional.empty(),
|
||||||
List.of(),
|
List.of(),
|
||||||
Optional.empty(),
|
Optional.empty(),
|
||||||
List.of());
|
List.of(),
|
||||||
|
false);
|
||||||
final var results = m.sendMessage(message, Set.of(RecipientIdentifier.NoteToSelf.INSTANCE), false);
|
final var results = m.sendMessage(message, Set.of(RecipientIdentifier.NoteToSelf.INSTANCE), false);
|
||||||
checkSendMessageResults(results);
|
checkSendMessageResults(results);
|
||||||
return results.timestamp();
|
return results.timestamp();
|
||||||
@ -453,7 +455,8 @@ public class DbusSignalImpl implements Signal, AutoCloseable {
|
|||||||
Optional.empty(),
|
Optional.empty(),
|
||||||
List.of(),
|
List.of(),
|
||||||
Optional.empty(),
|
Optional.empty(),
|
||||||
List.of());
|
List.of(),
|
||||||
|
false);
|
||||||
var results = m.sendMessage(message, Set.of(getGroupRecipientIdentifier(groupId)), false);
|
var results = m.sendMessage(message, Set.of(getGroupRecipientIdentifier(groupId)), false);
|
||||||
checkSendMessageResults(results);
|
checkSendMessageResults(results);
|
||||||
return results.timestamp();
|
return results.timestamp();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user