mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 10:30:38 +00:00
Send self messages as normal messages, new flag --note-to-self for sync message
Fixes #373
This commit is contained in:
parent
b31e97dd2d
commit
e1134d832a
7 changed files with 98 additions and 18 deletions
|
@ -3,6 +3,11 @@
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
### Added
|
### Added
|
||||||
- `--verbose` flag to increase log level
|
- `--verbose` flag to increase log level
|
||||||
|
- `--note-to-self` flag for `send` command to send a note to linked devices
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Messages sent to self number will be sent as normal Signal messages again, to
|
||||||
|
send a sync message, use the new `--note-to-self` flag
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Disable registration lock before removing the PIN
|
- Disable registration lock before removing the PIN
|
||||||
|
|
|
@ -17,7 +17,7 @@ repositories {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.github.turasa:signal-service-java:2.15.3_unofficial_15'
|
implementation 'com.github.turasa:signal-service-java:2.15.3_unofficial_16'
|
||||||
implementation 'org.bouncycastle:bcprov-jdk15on:1.68'
|
implementation 'org.bouncycastle:bcprov-jdk15on:1.68'
|
||||||
implementation 'net.sourceforge.argparse4j:argparse4j:0.8.1'
|
implementation 'net.sourceforge.argparse4j:argparse4j:0.8.1'
|
||||||
implementation 'com.github.hypfvieh:dbus-java:3.2.4'
|
implementation 'com.github.hypfvieh:dbus-java:3.2.4'
|
||||||
|
|
|
@ -165,6 +165,9 @@ Specify the message, if missing, standard input is used.
|
||||||
*-a* [ATTACHMENT [ATTACHMENT ...]], *--attachment* [ATTACHMENT [ATTACHMENT ...]]::
|
*-a* [ATTACHMENT [ATTACHMENT ...]], *--attachment* [ATTACHMENT [ATTACHMENT ...]]::
|
||||||
Add one or more files as attachment.
|
Add one or more files as attachment.
|
||||||
|
|
||||||
|
*--note-to-self*::
|
||||||
|
Send the message to self without notification.
|
||||||
|
|
||||||
*-e*, *--endsession*::
|
*-e*, *--endsession*::
|
||||||
Clear session state and send end session message.
|
Clear session state and send end session message.
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,10 @@ public interface Signal extends DBusInterface {
|
||||||
String message, List<String> attachments, List<String> recipients
|
String message, List<String> attachments, List<String> recipients
|
||||||
) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.UnregisteredUser, Error.UntrustedIdentity;
|
) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.UnregisteredUser, Error.UntrustedIdentity;
|
||||||
|
|
||||||
|
long sendNoteToSelfMessage(
|
||||||
|
String message, List<String> attachments
|
||||||
|
) throws Error.AttachmentInvalid, Error.Failure, Error.UnregisteredUser, Error.UntrustedIdentity;
|
||||||
|
|
||||||
void sendEndSessionMessage(List<String> recipients) throws Error.Failure, Error.InvalidNumber, Error.UnregisteredUser, Error.UntrustedIdentity;
|
void sendEndSessionMessage(List<String> recipients) throws Error.Failure, Error.InvalidNumber, Error.UnregisteredUser, Error.UntrustedIdentity;
|
||||||
|
|
||||||
long sendGroupMessage(
|
long sendGroupMessage(
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.asamk.signal.commands;
|
package org.asamk.signal.commands;
|
||||||
|
|
||||||
import net.sourceforge.argparse4j.impl.Arguments;
|
import net.sourceforge.argparse4j.impl.Arguments;
|
||||||
|
import net.sourceforge.argparse4j.inf.MutuallyExclusiveGroup;
|
||||||
import net.sourceforge.argparse4j.inf.Namespace;
|
import net.sourceforge.argparse4j.inf.Namespace;
|
||||||
import net.sourceforge.argparse4j.inf.Subparser;
|
import net.sourceforge.argparse4j.inf.Subparser;
|
||||||
|
|
||||||
|
@ -13,7 +14,6 @@ import org.freedesktop.dbus.exceptions.DBusExecutionException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.asamk.signal.util.ErrorUtils.handleAssertionError;
|
import static org.asamk.signal.util.ErrorUtils.handleAssertionError;
|
||||||
|
@ -23,8 +23,13 @@ public class SendCommand implements DbusCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void attachToSubparser(final Subparser subparser) {
|
public void attachToSubparser(final Subparser subparser) {
|
||||||
subparser.addArgument("-g", "--group").help("Specify the recipient group ID.");
|
|
||||||
subparser.addArgument("recipient").help("Specify the recipients' phone number.").nargs("*");
|
subparser.addArgument("recipient").help("Specify the recipients' phone number.").nargs("*");
|
||||||
|
final MutuallyExclusiveGroup mutuallyExclusiveGroup = subparser.addMutuallyExclusiveGroup();
|
||||||
|
mutuallyExclusiveGroup.addArgument("-g", "--group").help("Specify the recipient group ID.");
|
||||||
|
mutuallyExclusiveGroup.addArgument("--note-to-self")
|
||||||
|
.help("Send the message to self without notification.")
|
||||||
|
.action(Arguments.storeTrue());
|
||||||
|
|
||||||
subparser.addArgument("-m", "--message").help("Specify the message, if missing standard input is used.");
|
subparser.addArgument("-m", "--message").help("Specify the message, if missing standard input is used.");
|
||||||
subparser.addArgument("-a", "--attachment").nargs("*").help("Add file as attachment");
|
subparser.addArgument("-a", "--attachment").nargs("*").help("Add file as attachment");
|
||||||
subparser.addArgument("-e", "--endsession")
|
subparser.addArgument("-e", "--endsession")
|
||||||
|
@ -37,9 +42,10 @@ public class SendCommand implements DbusCommand {
|
||||||
final List<String> recipients = ns.getList("recipient");
|
final List<String> recipients = ns.getList("recipient");
|
||||||
final Boolean isEndSession = ns.getBoolean("endsession");
|
final Boolean isEndSession = ns.getBoolean("endsession");
|
||||||
final String groupIdString = ns.getString("group");
|
final String groupIdString = ns.getString("group");
|
||||||
|
final Boolean isNoteToSelf = ns.getBoolean("note_to_self");
|
||||||
|
|
||||||
final boolean noRecipients = recipients == null || recipients.isEmpty();
|
final boolean noRecipients = recipients == null || recipients.isEmpty();
|
||||||
if ((noRecipients && isEndSession) || (noRecipients && groupIdString == null)) {
|
if ((noRecipients && isEndSession) || (noRecipients && groupIdString == null && !isNoteToSelf)) {
|
||||||
System.err.println("No recipients given");
|
System.err.println("No recipients given");
|
||||||
System.err.println("Aborting sending.");
|
System.err.println("Aborting sending.");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -48,6 +54,10 @@ public class SendCommand implements DbusCommand {
|
||||||
System.err.println("You cannot specify recipients by phone number and groups at the same time");
|
System.err.println("You cannot specify recipients by phone number and groups at the same time");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (!noRecipients && isNoteToSelf) {
|
||||||
|
System.err.println("You cannot specify recipients by phone number and not to self at the same time");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (isEndSession) {
|
if (isEndSession) {
|
||||||
try {
|
try {
|
||||||
|
@ -75,11 +85,11 @@ public class SendCommand implements DbusCommand {
|
||||||
|
|
||||||
List<String> attachments = ns.getList("attachment");
|
List<String> attachments = ns.getList("attachment");
|
||||||
if (attachments == null) {
|
if (attachments == null) {
|
||||||
attachments = new ArrayList<>();
|
attachments = List.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
if (groupIdString != null) {
|
if (groupIdString != null) {
|
||||||
|
try {
|
||||||
byte[] groupId;
|
byte[] groupId;
|
||||||
try {
|
try {
|
||||||
groupId = Util.decodeGroupId(groupIdString).serialize();
|
groupId = Util.decodeGroupId(groupIdString).serialize();
|
||||||
|
@ -91,14 +101,28 @@ public class SendCommand implements DbusCommand {
|
||||||
long timestamp = signal.sendGroupMessage(messageText, attachments, groupId);
|
long timestamp = signal.sendGroupMessage(messageText, attachments, groupId);
|
||||||
System.out.println(timestamp);
|
System.out.println(timestamp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
} catch (AssertionError e) {
|
} catch (AssertionError e) {
|
||||||
handleAssertionError(e);
|
handleAssertionError(e);
|
||||||
return 1;
|
return 1;
|
||||||
} catch (DBusExecutionException e) {
|
} catch (DBusExecutionException e) {
|
||||||
System.err.println("Failed to send message: " + e.getMessage());
|
System.err.println("Failed to send group message: " + e.getMessage());
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNoteToSelf) {
|
||||||
|
try {
|
||||||
|
long timestamp = signal.sendNoteToSelfMessage(messageText, attachments);
|
||||||
|
System.out.println(timestamp);
|
||||||
|
return 0;
|
||||||
|
} catch (AssertionError e) {
|
||||||
|
handleAssertionError(e);
|
||||||
|
return 1;
|
||||||
|
} catch (DBusExecutionException e) {
|
||||||
|
System.err.println("Failed to send note to self message: " + e.getMessage());
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
long timestamp = signal.sendMessage(messageText, attachments, recipients);
|
long timestamp = signal.sendMessage(messageText, attachments, recipients);
|
||||||
|
|
|
@ -78,6 +78,21 @@ public class DbusSignalImpl implements Signal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long sendNoteToSelfMessage(
|
||||||
|
final String message, final List<String> attachments
|
||||||
|
) throws Error.AttachmentInvalid, Error.Failure, Error.UnregisteredUser, Error.UntrustedIdentity {
|
||||||
|
try {
|
||||||
|
final Pair<Long, List<SendMessageResult>> results = m.sendSelfMessage(message, attachments);
|
||||||
|
checkSendMessageResults(results.first(), results.second());
|
||||||
|
return results.first();
|
||||||
|
} catch (AttachmentInvalidException e) {
|
||||||
|
throw new Error.AttachmentInvalid(e.getMessage());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error.Failure(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendEndSessionMessage(final List<String> recipients) {
|
public void sendEndSessionMessage(final List<String> recipients) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -953,6 +953,17 @@ public class Manager implements Closeable {
|
||||||
return sendMessage(messageBuilder, getSignalServiceAddresses(recipients));
|
return sendMessage(messageBuilder, getSignalServiceAddresses(recipients));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Pair<Long, List<SendMessageResult>> sendSelfMessage(
|
||||||
|
String messageText, List<String> attachments
|
||||||
|
) throws IOException, AttachmentInvalidException {
|
||||||
|
final SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder()
|
||||||
|
.withBody(messageText);
|
||||||
|
if (attachments != null) {
|
||||||
|
messageBuilder.withAttachments(AttachmentUtils.getSignalServiceAttachments(attachments));
|
||||||
|
}
|
||||||
|
return sendSelfMessage(messageBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
public Pair<Long, List<SendMessageResult>> sendMessageReaction(
|
public Pair<Long, List<SendMessageResult>> sendMessageReaction(
|
||||||
String emoji, boolean remove, String targetAuthor, long targetSentTimestamp, List<String> recipients
|
String emoji, boolean remove, String targetAuthor, long targetSentTimestamp, List<String> recipients
|
||||||
) throws IOException, InvalidNumberException {
|
) throws IOException, InvalidNumberException {
|
||||||
|
@ -1253,12 +1264,8 @@ public class Manager implements Closeable {
|
||||||
final int expirationTime = contact != null ? contact.messageExpirationTime : 0;
|
final int expirationTime = contact != null ? contact.messageExpirationTime : 0;
|
||||||
messageBuilder.withExpiration(expirationTime);
|
messageBuilder.withExpiration(expirationTime);
|
||||||
message = messageBuilder.build();
|
message = messageBuilder.build();
|
||||||
if (address.matches(account.getSelfAddress())) {
|
|
||||||
results.add(sendSelfMessage(message));
|
|
||||||
} else {
|
|
||||||
results.add(sendMessage(address, message));
|
results.add(sendMessage(address, message));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return new Pair<>(timestamp, results);
|
return new Pair<>(timestamp, results);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -1271,6 +1278,28 @@ public class Manager implements Closeable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Pair<Long, List<SendMessageResult>> sendSelfMessage(
|
||||||
|
SignalServiceDataMessage.Builder messageBuilder
|
||||||
|
) throws IOException {
|
||||||
|
final long timestamp = System.currentTimeMillis();
|
||||||
|
messageBuilder.withTimestamp(timestamp);
|
||||||
|
getOrCreateMessagePipe();
|
||||||
|
getOrCreateUnidentifiedMessagePipe();
|
||||||
|
try {
|
||||||
|
final SignalServiceAddress address = getSelfAddress();
|
||||||
|
|
||||||
|
final ContactInfo contact = account.getContactStore().getContact(address);
|
||||||
|
final int expirationTime = contact != null ? contact.messageExpirationTime : 0;
|
||||||
|
messageBuilder.withExpiration(expirationTime);
|
||||||
|
|
||||||
|
SignalServiceDataMessage message = messageBuilder.build();
|
||||||
|
final SendMessageResult result = sendSelfMessage(message);
|
||||||
|
return new Pair<>(timestamp, List.of(result));
|
||||||
|
} finally {
|
||||||
|
account.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private SendMessageResult sendSelfMessage(SignalServiceDataMessage message) throws IOException {
|
private SendMessageResult sendSelfMessage(SignalServiceDataMessage message) throws IOException {
|
||||||
SignalServiceMessageSender messageSender = createMessageSender();
|
SignalServiceMessageSender messageSender = createMessageSender();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue