mirror of
https://github.com/AsamK/signal-cli
synced 2025-09-02 20:40:38 +00:00
extend DBus signals for DbusAttachments
This change creates the DBus signals `SyncMessageReceivedV2` and `MessageReceivedV2`, as well as the new data type `DbusAttachment`. A DbusAttachment is a struct that contains considerably more information than the filename. To maintain backward compatibility, `SyncMessageReceived` and `MessageReceived` remain unchanged. V2 includes Mentions and DbusAttachments. This change also permits sending arbitrary URLs as attachment names.
This commit is contained in:
parent
114b932386
commit
c77b2e9511
18 changed files with 446 additions and 47 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -11,3 +11,6 @@ local.properties
|
|||
.settings/
|
||||
out/
|
||||
.DS_Store
|
||||
.git/
|
||||
signal-cli
|
||||
bin/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# signal-cli
|
||||
|
||||
signal-cli is a commandline interface for [libsignal-service-java](https://github.com/WhisperSystems/libsignal-service-java). It supports registering, verifying, sending and receiving messages.
|
||||
To be able to link to an existing Signal-Android/signal-cli instance, signal-cli uses a [patched libsignal-service-java](https://github.com/AsamK/libsignal-service-java), because libsignal-service-java does not yet support [provisioning as a slave device](https://github.com/WhisperSystems/libsignal-service-java/pull/21).
|
||||
To be able to link to an existing Signal-Android/signal-cli instance, signal-cli uses a [patched libsignal-service-java](https://github.com/AsamK/libsignal-service-java), because libsignal-service-java does not yet support [provisioning as a secondary device](https://github.com/WhisperSystems/libsignal-service-java/pull/21).
|
||||
For registering you need a phone number where you can receive SMS or incoming calls.
|
||||
signal-cli is primarily intended to be used on servers to notify admins of important events. For this use-case, it has a dbus interface ([man page](https://github.com/AsamK/signal-cli/blob/master/man/signal-cli-dbus.5.adoc)), that can be used to send messages from any programming language that has dbus bindings.
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ plugins {
|
|||
`check-lib-versions`
|
||||
}
|
||||
|
||||
version = "0.8.5"
|
||||
version = "0.8.6"
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
|
|
|
@ -1274,7 +1274,7 @@ public class Manager implements Closeable {
|
|||
) throws IOException, AttachmentInvalidException, InvalidNumberException {
|
||||
final var messageBuilder = SignalServiceDataMessage.newBuilder().withBody(messageText);
|
||||
if (attachments != null) {
|
||||
var attachmentStreams = AttachmentUtils.getSignalServiceAttachments(attachments);
|
||||
List<SignalServiceAttachment> attachmentStreams = AttachmentUtils.getSignalServiceAttachments(attachments);
|
||||
|
||||
// Upload attachments here, so we only upload once even for multiple recipients
|
||||
var messageSender = createMessageSender();
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.net.URL;
|
||||
|
||||
public class AttachmentUtils {
|
||||
|
||||
|
@ -21,8 +22,13 @@ public class AttachmentUtils {
|
|||
for (var attachment : attachments) {
|
||||
try {
|
||||
signalServiceAttachments.add(createAttachment(new File(attachment)));
|
||||
} catch (IOException e) {
|
||||
throw new AttachmentInvalidException(attachment, e);
|
||||
} catch (IOException f) {
|
||||
// no such file, send it as URL
|
||||
try {
|
||||
signalServiceAttachments.add(createAttachment(new URL(attachment)));
|
||||
} catch (IOException e) {
|
||||
throw new AttachmentInvalidException(attachment, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,25 +40,39 @@ public class AttachmentUtils {
|
|||
return createAttachment(streamDetails, Optional.of(attachmentFile.getName()));
|
||||
}
|
||||
|
||||
public static SignalServiceAttachmentStream createAttachment(URL aURL) throws IOException {
|
||||
final var streamDetails = Utils.createStreamDetailsFromURL(aURL);
|
||||
String path = aURL.getPath();
|
||||
String name = path.substring(path.lastIndexOf('/') + 1);
|
||||
return createAttachment(streamDetails, Optional.of(name));
|
||||
}
|
||||
|
||||
public static SignalServiceAttachmentStream createAttachment(
|
||||
StreamDetails streamDetails, Optional<String> name
|
||||
) {
|
||||
// TODO mabybe add a parameter to set the voiceNote, borderless, preview, width, height and caption option
|
||||
// TODO maybe add a parameter to set the voiceNote, borderless, preview, width, height, caption, blurHash options
|
||||
final var uploadTimestamp = System.currentTimeMillis();
|
||||
boolean voicenote = false;
|
||||
boolean borderless = false;
|
||||
Optional<byte[]> preview = Optional.absent();
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
Optional<String> caption = Optional.absent();
|
||||
Optional<String> blurHash = Optional.absent();
|
||||
final Optional<ResumableUploadSpec> resumableUploadSpec = Optional.absent();
|
||||
//ProgressListener listener = null; //Android OS
|
||||
//CancellationSignal cancellationSignal = null; //Android OS; Signal developers misspelled class name
|
||||
|
||||
return new SignalServiceAttachmentStream(streamDetails.getStream(),
|
||||
streamDetails.getContentType(),
|
||||
streamDetails.getLength(),
|
||||
name,
|
||||
false,
|
||||
false,
|
||||
voicenote,
|
||||
borderless,
|
||||
false,
|
||||
preview,
|
||||
0,
|
||||
0,
|
||||
width,
|
||||
height,
|
||||
uploadTimestamp,
|
||||
caption,
|
||||
blurHash,
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.io.File;
|
|||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.file.Files;
|
||||
|
||||
|
@ -36,6 +37,13 @@ public class Utils {
|
|||
return new StreamDetails(stream, mime, size);
|
||||
}
|
||||
|
||||
public static StreamDetails createStreamDetailsFromURL(URL aURL) throws IOException {
|
||||
InputStream stream = aURL.openStream();
|
||||
final var mime = aURL.openConnection().getContentType();
|
||||
final var size = aURL.openConnection().getContentLengthLong();
|
||||
return new StreamDetails(stream, mime, size);
|
||||
}
|
||||
|
||||
public static String computeSafetyNumber(
|
||||
boolean isUuidCapable,
|
||||
SignalServiceAddress ownAddress,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.asamk;
|
||||
|
||||
import org.asamk.signal.dbus.DbusAttachment;
|
||||
import org.asamk.signal.dbus.DbusMention;
|
||||
import org.freedesktop.dbus.exceptions.DBusException;
|
||||
import org.freedesktop.dbus.exceptions.DBusExecutionException;
|
||||
|
@ -16,12 +17,21 @@ import java.util.Map;
|
|||
*/
|
||||
public interface Signal extends DBusInterface {
|
||||
|
||||
long sendMessage(
|
||||
String message, List<String> attachments, String recipient
|
||||
|
||||
long sendMessageV2(
|
||||
String message, List<DbusAttachment> dBusAttachments, String recipient
|
||||
) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.UntrustedIdentity;
|
||||
|
||||
long sendMessageV2(
|
||||
String message, List<DbusAttachment> dBusAttachments, List<String> recipients
|
||||
) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.UntrustedIdentity;
|
||||
|
||||
long sendMessage(
|
||||
String message, List<String> attachments, List<String> recipients
|
||||
String message, List<String> attachmentNames, String recipient
|
||||
) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.UntrustedIdentity;
|
||||
|
||||
long sendMessage(
|
||||
String message, List<String> attachmentNames, List<String> recipients
|
||||
) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.UntrustedIdentity;
|
||||
|
||||
long sendRemoteDeleteMessage(
|
||||
|
@ -45,13 +55,21 @@ public interface Signal extends DBusInterface {
|
|||
) throws Error.InvalidNumber, Error.Failure;
|
||||
|
||||
long sendNoteToSelfMessage(
|
||||
String message, List<String> attachments
|
||||
String message, List<String> attachmentNames
|
||||
) throws Error.AttachmentInvalid, Error.Failure;
|
||||
|
||||
long sendNoteToSelfMessageV2(
|
||||
String message, List<DbusAttachment> dBusAttachments
|
||||
) throws Error.AttachmentInvalid, Error.Failure;
|
||||
|
||||
void sendEndSessionMessage(List<String> recipients) throws Error.Failure, Error.InvalidNumber, Error.UntrustedIdentity;
|
||||
|
||||
long sendGroupMessage(
|
||||
String message, List<String> attachments, byte[] groupId
|
||||
String message, List<String> attachmentNames, byte[] groupId
|
||||
) throws Error.GroupNotFound, Error.Failure, Error.AttachmentInvalid;
|
||||
|
||||
long sendGroupMessageV2(
|
||||
String message, List<DbusAttachment> dBusAttachments, byte[] groupId
|
||||
) throws Error.GroupNotFound, Error.Failure, Error.AttachmentInvalid;
|
||||
|
||||
long sendGroupMessageReaction(
|
||||
|
@ -116,17 +134,62 @@ public interface Signal extends DBusInterface {
|
|||
private final String sender;
|
||||
private final byte[] groupId;
|
||||
private final String message;
|
||||
private final List<DbusMention> mentions;
|
||||
private final List<String> attachments;
|
||||
private final List<String> attachmentNames;
|
||||
|
||||
public MessageReceived(
|
||||
String objectpath,
|
||||
long timestamp,
|
||||
String sender,
|
||||
byte[] groupId,
|
||||
String message,
|
||||
List<String> attachmentNames
|
||||
) throws DBusException {
|
||||
super(objectpath, timestamp, sender, groupId, message, attachmentNames);
|
||||
this.timestamp = timestamp;
|
||||
this.sender = sender;
|
||||
this.groupId = groupId;
|
||||
this.message = message;
|
||||
this.attachmentNames = attachmentNames;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public String getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
public byte[] getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public List<String> getAttachmentNames() {
|
||||
return attachmentNames;
|
||||
}
|
||||
}
|
||||
|
||||
class MessageReceivedV2 extends DBusSignal {
|
||||
|
||||
private final long timestamp;
|
||||
private final String sender;
|
||||
private final byte[] groupId;
|
||||
private final String message;
|
||||
private final List<DbusMention> mentions;
|
||||
private final List<DbusAttachment> attachments;
|
||||
|
||||
public MessageReceivedV2(
|
||||
String objectpath,
|
||||
long timestamp,
|
||||
String sender,
|
||||
byte[] groupId,
|
||||
String message,
|
||||
List<DbusMention> mentions,
|
||||
List<String> attachments
|
||||
List<DbusAttachment> attachments
|
||||
) throws DBusException {
|
||||
super(objectpath, timestamp, sender, groupId, message, mentions, attachments);
|
||||
this.timestamp = timestamp;
|
||||
|
@ -157,7 +220,7 @@ public interface Signal extends DBusInterface {
|
|||
return mentions;
|
||||
}
|
||||
|
||||
public List<String> getAttachments() {
|
||||
public List<DbusAttachment> getAttachments() {
|
||||
return attachments;
|
||||
}
|
||||
}
|
||||
|
@ -189,10 +252,62 @@ public interface Signal extends DBusInterface {
|
|||
private final String destination;
|
||||
private final byte[] groupId;
|
||||
private final String message;
|
||||
private final List<DbusMention> mentions;
|
||||
private final List<String> attachments;
|
||||
private final List<String> attachmentNames;
|
||||
|
||||
public SyncMessageReceived(
|
||||
String objectpath,
|
||||
long timestamp,
|
||||
String source,
|
||||
String destination,
|
||||
byte[] groupId,
|
||||
String message,
|
||||
List<String> attachmentNames
|
||||
) throws DBusException {
|
||||
super(objectpath, timestamp, source, destination, groupId, message, attachmentNames);
|
||||
this.timestamp = timestamp;
|
||||
this.source = source;
|
||||
this.destination = destination;
|
||||
this.groupId = groupId;
|
||||
this.message = message;
|
||||
this.attachmentNames = attachmentNames;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public String getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public String getDestination() {
|
||||
return destination;
|
||||
}
|
||||
|
||||
public byte[] getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public List<String> getAttachmentNames() {
|
||||
return attachmentNames;
|
||||
}
|
||||
}
|
||||
|
||||
class SyncMessageReceivedV2 extends DBusSignal {
|
||||
|
||||
private final long timestamp;
|
||||
private final String source;
|
||||
private final String destination;
|
||||
private final byte[] groupId;
|
||||
private final String message;
|
||||
private final List<DbusMention> mentions;
|
||||
private final List<DbusAttachment> attachments;
|
||||
|
||||
public SyncMessageReceivedV2(
|
||||
String objectpath,
|
||||
long timestamp,
|
||||
String source,
|
||||
|
@ -200,7 +315,7 @@ public interface Signal extends DBusInterface {
|
|||
byte[] groupId,
|
||||
String message,
|
||||
List<DbusMention> mentions,
|
||||
List<String> attachments
|
||||
List<DbusAttachment> attachments
|
||||
) throws DBusException {
|
||||
super(objectpath, timestamp, source, destination, groupId, message, mentions, attachments);
|
||||
this.timestamp = timestamp;
|
||||
|
@ -236,7 +351,7 @@ public interface Signal extends DBusInterface {
|
|||
return mentions;
|
||||
}
|
||||
|
||||
public List<String> getAttachments() {
|
||||
public List<DbusAttachment> getAttachments() {
|
||||
return attachments;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ public class App {
|
|||
|
||||
username = usernames.get(0);
|
||||
} else if (!PhoneNumberFormatter.isValidNumber(username, null)) {
|
||||
throw new UserErrorException("Invalid username (phone number), make sure you include the country code.");
|
||||
throw new UserErrorException("Invalid username (phone number), make sure you include a plus sign (+) followed by the country code.");
|
||||
}
|
||||
|
||||
if (command instanceof RegistrationCommand) {
|
||||
|
@ -264,6 +264,7 @@ public class App {
|
|||
try {
|
||||
manager = Manager.init(username, dataPath, serviceEnvironment, BaseConfig.USER_AGENT);
|
||||
} catch (NotRegisteredException e) {
|
||||
logger.debug("dataPath=" + dataPath + " serviceEnvironment=" + serviceEnvironment, e);
|
||||
throw new UserErrorException("User " + username + " is not registered.");
|
||||
} catch (Throwable e) {
|
||||
logger.debug("Loading state file failed", e);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.asamk.signal;
|
||||
|
||||
import org.asamk.Signal;
|
||||
import org.asamk.signal.dbus.DbusAttachment;
|
||||
import org.asamk.signal.dbus.DbusMention;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.asamk.signal.manager.groups.GroupUtils;
|
||||
|
@ -10,6 +11,7 @@ import org.whispersystems.signalservice.api.messages.SignalServiceContent;
|
|||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -72,13 +74,23 @@ public class JsonDbusReceiveMessageHandler extends JsonReceiveMessageHandler {
|
|||
|| message.getGroupContext().get().getGroupV1Type() == SignalServiceGroup.Type.DELIVER
|
||||
)) {
|
||||
try {
|
||||
conn.sendMessage(new Signal.MessageReceived(objectPath,
|
||||
List<SignalServiceAttachment> attachments = JsonDbusReceiveMessageHandler.getAttachments(message);
|
||||
List<DbusAttachment> dBusAttachments = JsonDbusReceiveMessageHandler.convertSignalAttachmentsToDbus(attachments);
|
||||
conn.sendMessage(new Signal.MessageReceivedV2(objectPath,
|
||||
message.getTimestamp(),
|
||||
getLegacyIdentifier(sender),
|
||||
groupId != null ? groupId : new byte[0],
|
||||
message.getBody().isPresent() ? message.getBody().get() : "",
|
||||
JsonDbusReceiveMessageHandler.getMentions(message, m),
|
||||
JsonDbusReceiveMessageHandler.getAttachments(message, m)));
|
||||
dBusAttachments
|
||||
));
|
||||
conn.sendMessage(new Signal.MessageReceived(objectPath,
|
||||
message.getTimestamp(),
|
||||
getLegacyIdentifier(sender),
|
||||
groupId != null ? groupId : new byte[0],
|
||||
message.getBody().isPresent() ? message.getBody().get() : "",
|
||||
JsonDbusReceiveMessageHandler.getAttachmentNames(message, m)
|
||||
));
|
||||
} catch (DBusException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -95,7 +107,9 @@ public class JsonDbusReceiveMessageHandler extends JsonReceiveMessageHandler {
|
|||
var groupId = getGroupId(message);
|
||||
|
||||
try {
|
||||
conn.sendMessage(new Signal.SyncMessageReceived(objectPath,
|
||||
List<SignalServiceAttachment> attachments = JsonDbusReceiveMessageHandler.getAttachments(message);
|
||||
List<DbusAttachment> dBusAttachments = JsonDbusReceiveMessageHandler.convertSignalAttachmentsToDbus(attachments);
|
||||
conn.sendMessage(new Signal.SyncMessageReceivedV2(objectPath,
|
||||
transcript.getTimestamp(),
|
||||
getLegacyIdentifier(sender),
|
||||
transcript.getDestination().isPresent()
|
||||
|
@ -104,7 +118,18 @@ public class JsonDbusReceiveMessageHandler extends JsonReceiveMessageHandler {
|
|||
groupId != null ? groupId : new byte[0],
|
||||
message.getBody().isPresent() ? message.getBody().get() : "",
|
||||
JsonDbusReceiveMessageHandler.getMentions(message, m),
|
||||
JsonDbusReceiveMessageHandler.getAttachments(message, m)));
|
||||
dBusAttachments
|
||||
));
|
||||
conn.sendMessage(new Signal.SyncMessageReceived(objectPath,
|
||||
transcript.getTimestamp(),
|
||||
getLegacyIdentifier(sender),
|
||||
transcript.getDestination().isPresent()
|
||||
? getLegacyIdentifier(transcript.getDestination().get())
|
||||
: "",
|
||||
groupId != null ? groupId : new byte[0],
|
||||
message.getBody().isPresent() ? message.getBody().get() : "",
|
||||
JsonDbusReceiveMessageHandler.getAttachmentNames(message, m)
|
||||
));
|
||||
} catch (DBusException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -119,7 +144,7 @@ public class JsonDbusReceiveMessageHandler extends JsonReceiveMessageHandler {
|
|||
.serialize() : null;
|
||||
}
|
||||
|
||||
static private List<String> getAttachments(SignalServiceDataMessage message, Manager m) {
|
||||
static private List<String> getAttachmentNames(SignalServiceDataMessage message, Manager m) {
|
||||
var attachments = new ArrayList<String>();
|
||||
if (message.getAttachments().isPresent()) {
|
||||
for (var attachment : message.getAttachments().get()) {
|
||||
|
@ -141,10 +166,34 @@ public class JsonDbusReceiveMessageHandler extends JsonReceiveMessageHandler {
|
|||
return mentions;
|
||||
}
|
||||
|
||||
|
||||
static private List<SignalServiceAttachment> getAttachments(SignalServiceDataMessage message) {
|
||||
var attachments = new ArrayList<SignalServiceAttachment>();
|
||||
if (message.getAttachments().isPresent()) {
|
||||
for (var attachment : message.getAttachments().get()) {
|
||||
if (attachment.isPointer()) {
|
||||
attachments.add(attachment);
|
||||
}
|
||||
}
|
||||
}
|
||||
return attachments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(SignalServiceEnvelope envelope, SignalServiceContent content, Throwable exception) {
|
||||
super.handleMessage(envelope, content, exception);
|
||||
|
||||
sendReceivedMessageToDbus(envelope, content, conn, objectPath, m);
|
||||
}
|
||||
|
||||
static private List<DbusAttachment> convertSignalAttachmentsToDbus(List<SignalServiceAttachment> attachments) {
|
||||
ArrayList<DbusAttachment> dBusAttachments = new ArrayList<>();
|
||||
if (!attachments.isEmpty()) {
|
||||
for (SignalServiceAttachment attachment : attachments) {
|
||||
DbusAttachment dBusAttachment = new DbusAttachment(attachment);
|
||||
dBusAttachments.add(dBusAttachment);
|
||||
}
|
||||
}
|
||||
return dBusAttachments;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -646,6 +646,9 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler {
|
|||
if (pointer.getCaption().isPresent()) {
|
||||
writer.println("Caption: {}", pointer.getCaption().get());
|
||||
}
|
||||
if (pointer.getBlurHash().isPresent()) {
|
||||
writer.println("Blur Hash: {}", pointer.getBlurHash().get());
|
||||
}
|
||||
if (pointer.getFileName().isPresent()) {
|
||||
writer.println("Filename: {}", pointer.getFileName().get());
|
||||
}
|
||||
|
|
|
@ -65,7 +65,12 @@ public class DaemonCommand implements MultiLocalCommand {
|
|||
var objectPath = DbusConfig.getObjectPath();
|
||||
var t = run(conn, objectPath, m, ignoreAttachments);
|
||||
|
||||
conn.requestBusName(DbusConfig.getBusname());
|
||||
try {
|
||||
conn.requestBusName(DbusConfig.getBusname());
|
||||
} catch (DBusException e) {
|
||||
logger.error("Dbus request command failed", e);
|
||||
throw new UnexpectedErrorException("Dbus request command failed");
|
||||
}
|
||||
|
||||
try {
|
||||
t.join();
|
||||
|
|
|
@ -81,6 +81,24 @@ public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand {
|
|||
final var writer = (PlainTextWriter) outputWriter;
|
||||
|
||||
dbusconnection.addSigHandler(Signal.MessageReceived.class, signal, messageReceived -> {
|
||||
writer.println("Envelope from: {}", messageReceived.getSender());
|
||||
writer.println("Timestamp: {}", DateUtils.formatTimestamp(messageReceived.getTimestamp()));
|
||||
writer.println("Body: {}", messageReceived.getMessage());
|
||||
if (messageReceived.getGroupId().length > 0) {
|
||||
writer.println("Group info:");
|
||||
writer.indentedWriter()
|
||||
.println("Id: {}", Base64.getEncoder().encodeToString(messageReceived.getGroupId()));
|
||||
}
|
||||
if (messageReceived.getAttachmentNames().size() > 0) {
|
||||
writer.println("Attachments:");
|
||||
for (var attachment : messageReceived.getAttachmentNames()) {
|
||||
writer.println("- Stored plaintext in: {}", attachment);
|
||||
}
|
||||
}
|
||||
writer.println();
|
||||
});
|
||||
|
||||
dbusconnection.addSigHandler(Signal.MessageReceivedV2.class, signal, messageReceived -> {
|
||||
writer.println("Envelope from: {}", messageReceived.getSender());
|
||||
writer.println("Timestamp: {}", DateUtils.formatTimestamp(messageReceived.getTimestamp()));
|
||||
writer.println("Body: {}", messageReceived.getMessage());
|
||||
|
@ -104,6 +122,26 @@ public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand {
|
|||
});
|
||||
|
||||
dbusconnection.addSigHandler(Signal.SyncMessageReceived.class, signal, syncReceived -> {
|
||||
writer.println("Sync Envelope from: {} to: {}",
|
||||
syncReceived.getSource(),
|
||||
syncReceived.getDestination());
|
||||
writer.println("Timestamp: {}", DateUtils.formatTimestamp(syncReceived.getTimestamp()));
|
||||
writer.println("Body: {}", syncReceived.getMessage());
|
||||
if (syncReceived.getGroupId().length > 0) {
|
||||
writer.println("Group info:");
|
||||
writer.indentedWriter()
|
||||
.println("Id: {}", Base64.getEncoder().encodeToString(syncReceived.getGroupId()));
|
||||
}
|
||||
if (syncReceived.getAttachmentNames().size() > 0) {
|
||||
writer.println("Attachments:");
|
||||
for (var attachment : syncReceived.getAttachmentNames()) {
|
||||
writer.println("- Stored plaintext in: {}", attachment);
|
||||
}
|
||||
}
|
||||
writer.println();
|
||||
});
|
||||
|
||||
dbusconnection.addSigHandler(Signal.SyncMessageReceivedV2.class, signal, syncReceived -> {
|
||||
writer.println("Sync Envelope from: {} to: {}",
|
||||
syncReceived.getSource(),
|
||||
syncReceived.getDestination());
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.asamk.signal.commands.exceptions.CommandException;
|
|||
import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UntrustedKeyErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.dbus.DbusAttachment;
|
||||
import org.asamk.signal.dbus.DbusSignalImpl;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.asamk.signal.manager.groups.GroupIdFormatException;
|
||||
|
@ -21,9 +22,11 @@ import org.freedesktop.dbus.errors.UnknownObject;
|
|||
import org.freedesktop.dbus.exceptions.DBusExecutionException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -91,9 +94,17 @@ public class SendCommand implements DbusCommand, JsonRpcLocalCommand {
|
|||
}
|
||||
}
|
||||
|
||||
List<String> attachments = ns.getList("attachment");
|
||||
if (attachments == null) {
|
||||
attachments = List.of();
|
||||
List<String> attachmentNames = ns.getList("attachment");
|
||||
if (attachmentNames == null) {
|
||||
attachmentNames = List.of();
|
||||
}
|
||||
|
||||
ArrayList<DbusAttachment> dBusAttachments = new ArrayList<>();
|
||||
if (!attachmentNames.isEmpty()) {
|
||||
for (var attachmentName : attachmentNames) {
|
||||
DbusAttachment dBusAttachment = new DbusAttachment(attachmentName);
|
||||
dBusAttachments.add(dBusAttachment);
|
||||
}
|
||||
}
|
||||
|
||||
if (groupIdString != null) {
|
||||
|
@ -105,7 +116,7 @@ public class SendCommand implements DbusCommand, JsonRpcLocalCommand {
|
|||
}
|
||||
|
||||
try {
|
||||
var timestamp = signal.sendGroupMessage(messageText, attachments, groupId);
|
||||
var timestamp = signal.sendGroupMessage(messageText, attachmentNames, groupId);
|
||||
outputResult(timestamp);
|
||||
return;
|
||||
} catch (DBusExecutionException e) {
|
||||
|
@ -115,25 +126,25 @@ public class SendCommand implements DbusCommand, JsonRpcLocalCommand {
|
|||
|
||||
if (isNoteToSelf) {
|
||||
try {
|
||||
var timestamp = signal.sendNoteToSelfMessage(messageText, attachments);
|
||||
var timestamp = signal.sendNoteToSelfMessage(messageText, attachmentNames);
|
||||
outputResult(timestamp);
|
||||
return;
|
||||
} catch (Signal.Error.UntrustedIdentity e) {
|
||||
throw new UntrustedKeyErrorException("Failed to send message: " + e.getMessage());
|
||||
throw new UntrustedKeyErrorException("Failed to send note to self message: " + e.getMessage());
|
||||
} catch (DBusExecutionException e) {
|
||||
throw new UnexpectedErrorException("Failed to send note to self message: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
var timestamp = signal.sendMessage(messageText, attachments, recipients);
|
||||
var timestamp = signal.sendMessageV2(messageText, dBusAttachments, recipients);
|
||||
outputResult(timestamp);
|
||||
} catch (UnknownObject e) {
|
||||
throw new UserErrorException("Failed to find dbus object, maybe missing the -u flag: " + e.getMessage());
|
||||
} catch (Signal.Error.UntrustedIdentity e) {
|
||||
throw new UntrustedKeyErrorException("Failed to send message: " + e.getMessage());
|
||||
} catch (DBusExecutionException e) {
|
||||
throw new UnexpectedErrorException("Failed to send message: " + e.getMessage());
|
||||
throw new UnexpectedErrorException("Failed to send message, did not find attachment: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -150,7 +150,6 @@ public class DbusSignalControlImpl implements org.asamk.SignalControl {
|
|||
return BaseConfig.PROJECT_VERSION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DBusPath> listAccounts() {
|
||||
synchronized (receiveThreads) {
|
||||
return receiveThreads.stream()
|
||||
|
|
|
@ -110,11 +110,38 @@ public class DbusSignalImpl implements Signal {
|
|||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long sendMessage(final String message, final List<String> attachments, final String recipient) {
|
||||
public long sendMessageV2(final String message, final List<DbusAttachment> dBusAttachments, final String recipient) {
|
||||
var recipients = new ArrayList<String>(1);
|
||||
recipients.add(recipient);
|
||||
return sendMessage(message, attachments, recipients);
|
||||
return sendMessageV2(message, dBusAttachments, recipients);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long sendMessageV2(final String message, final List<DbusAttachment> dBusAttachments, final List<String> recipients) {
|
||||
try {
|
||||
ArrayList<String> attachmentNames = new ArrayList<>();
|
||||
for (var dBusAttachment : dBusAttachments) {
|
||||
attachmentNames.add(dBusAttachment.getFileName());
|
||||
}
|
||||
final var results = m.sendMessage(message, attachmentNames, recipients);
|
||||
checkSendMessageResults(results.first(), results.second());
|
||||
return results.first();
|
||||
} catch (InvalidNumberException e) {
|
||||
throw new Error.InvalidNumber(e.getMessage());
|
||||
} catch (AttachmentInvalidException e) {
|
||||
throw new Error.AttachmentInvalid(e.getMessage());
|
||||
} catch (IOException e) {
|
||||
throw new Error.Failure(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long sendMessage(final String message, final List<String> attachmentNames, final String recipient) {
|
||||
var recipients = new ArrayList<String>(1);
|
||||
recipients.add(recipient);
|
||||
return sendMessage(message, attachmentNames, recipients);
|
||||
}
|
||||
|
||||
private static void checkSendMessageResult(long timestamp, SendMessageResult result) throws DBusExecutionException {
|
||||
|
@ -157,9 +184,9 @@ public class DbusSignalImpl implements Signal {
|
|||
}
|
||||
|
||||
@Override
|
||||
public long sendMessage(final String message, final List<String> attachments, final List<String> recipients) {
|
||||
public long sendMessage(final String message, final List<String> attachmentNames, final List<String> recipients) {
|
||||
try {
|
||||
final var results = m.sendMessage(message, attachments, recipients);
|
||||
final var results = m.sendMessage(message, attachmentNames, recipients);
|
||||
checkSendMessageResults(results.first(), results.second());
|
||||
return results.first();
|
||||
} catch (InvalidNumberException e) {
|
||||
|
@ -244,10 +271,29 @@ public class DbusSignalImpl implements Signal {
|
|||
|
||||
@Override
|
||||
public long sendNoteToSelfMessage(
|
||||
final String message, final List<String> attachments
|
||||
final String message, final List<String> attachmentNames
|
||||
) throws Error.AttachmentInvalid, Error.Failure, Error.UntrustedIdentity {
|
||||
try {
|
||||
final var results = m.sendSelfMessage(message, attachments);
|
||||
final var results = m.sendSelfMessage(message, attachmentNames);
|
||||
checkSendMessageResult(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
|
||||
public long sendNoteToSelfMessageV2(
|
||||
final String message, final List<DbusAttachment> dBusAttachments
|
||||
) throws Error.AttachmentInvalid, Error.Failure, Error.UntrustedIdentity {
|
||||
try {
|
||||
ArrayList<String> attachmentNames = new ArrayList<>();
|
||||
for (var dBusAttachment : dBusAttachments) {
|
||||
attachmentNames.add(dBusAttachment.getFileName());
|
||||
}
|
||||
final var results = m.sendSelfMessage(message, attachmentNames);
|
||||
checkSendMessageResult(results.first(), results.second());
|
||||
return results.first();
|
||||
} catch (AttachmentInvalidException e) {
|
||||
|
@ -270,9 +316,28 @@ public class DbusSignalImpl implements Signal {
|
|||
}
|
||||
|
||||
@Override
|
||||
public long sendGroupMessage(final String message, final List<String> attachments, final byte[] groupId) {
|
||||
public long sendGroupMessage(final String message, final List<String> attachmentNames, final byte[] groupId) {
|
||||
try {
|
||||
var results = m.sendGroupMessage(message, attachments, GroupId.unknownVersion(groupId));
|
||||
var results = m.sendGroupMessage(message, attachmentNames, GroupId.unknownVersion(groupId));
|
||||
checkSendMessageResults(results.first(), results.second());
|
||||
return results.first();
|
||||
} catch (IOException e) {
|
||||
throw new Error.Failure(e.getMessage());
|
||||
} catch (GroupNotFoundException | NotAGroupMemberException e) {
|
||||
throw new Error.GroupNotFound(e.getMessage());
|
||||
} catch (AttachmentInvalidException e) {
|
||||
throw new Error.AttachmentInvalid(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long sendGroupMessageV2(final String message, final List<DbusAttachment> dBusAttachments, final byte[] groupId) {
|
||||
try {
|
||||
ArrayList<String> attachmentNames = new ArrayList<>();
|
||||
for (var dBusAttachment : dBusAttachments) {
|
||||
attachmentNames.add(dBusAttachment.getFileName());
|
||||
}
|
||||
var results = m.sendGroupMessage(message, attachmentNames, GroupId.unknownVersion(groupId));
|
||||
checkSendMessageResults(results.first(), results.second());
|
||||
return results.first();
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
||||
|
||||
import org.asamk.signal.dbus.DbusAttachment;
|
||||
|
||||
class JsonAttachment {
|
||||
|
||||
@JsonProperty
|
||||
|
@ -18,6 +20,33 @@ class JsonAttachment {
|
|||
@JsonProperty
|
||||
final Long size;
|
||||
|
||||
@JsonProperty
|
||||
Integer keyLength;
|
||||
|
||||
@JsonProperty
|
||||
Integer width;
|
||||
|
||||
@JsonProperty
|
||||
Integer height;
|
||||
|
||||
@JsonProperty
|
||||
boolean voiceNote;
|
||||
|
||||
@JsonProperty
|
||||
String caption;
|
||||
|
||||
@JsonProperty
|
||||
String relay;
|
||||
|
||||
@JsonProperty
|
||||
byte[] preview;
|
||||
|
||||
@JsonProperty
|
||||
String digest;
|
||||
|
||||
@JsonProperty
|
||||
String blurHash;
|
||||
|
||||
JsonAttachment(SignalServiceAttachment attachment) {
|
||||
this.contentType = attachment.getContentType();
|
||||
|
||||
|
@ -26,6 +55,11 @@ class JsonAttachment {
|
|||
this.id = pointer.getRemoteId().toString();
|
||||
this.filename = pointer.getFileName().orNull();
|
||||
this.size = pointer.getSize().transform(Integer::longValue).orNull();
|
||||
this.keyLength = pointer.getKey().length;
|
||||
this.width = pointer.getWidth();
|
||||
this.height = pointer.getHeight();
|
||||
this.voiceNote = pointer.getVoiceNote();
|
||||
if (pointer.getCaption().isPresent()) {this.caption = pointer.getCaption().get();}
|
||||
} else {
|
||||
final var stream = attachment.asStream();
|
||||
this.id = null;
|
||||
|
@ -40,4 +74,17 @@ class JsonAttachment {
|
|||
this.id = null;
|
||||
this.size = null;
|
||||
}
|
||||
|
||||
JsonAttachment(DbusAttachment attachment) {
|
||||
this.contentType = attachment.getContentType();
|
||||
this.id = attachment.getId();
|
||||
this.filename = attachment.getFileName();
|
||||
this.size = attachment.getFileSize();
|
||||
this.keyLength = attachment.getKeyLength();
|
||||
this.width = attachment.getWidth();
|
||||
this.height = attachment.getHeight();
|
||||
this.voiceNote = attachment.getVoiceNote();
|
||||
this.caption = attachment.getCaption();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||
|
||||
import org.asamk.Signal;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.asamk.signal.dbus.DbusAttachment;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -114,6 +115,22 @@ class JsonDataMessage {
|
|||
}
|
||||
|
||||
public JsonDataMessage(Signal.MessageReceived messageReceived) {
|
||||
timestamp = messageReceived.getTimestamp();
|
||||
message = messageReceived.getMessage();
|
||||
groupInfo = messageReceived.getGroupId().length > 0 ? new JsonGroupInfo(messageReceived.getGroupId()) : null;
|
||||
expiresInSeconds = null;
|
||||
viewOnce = null;
|
||||
remoteDelete = null;
|
||||
reaction = null; // TODO Replace these 5 with the proper commands
|
||||
quote = null;
|
||||
mentions = null;
|
||||
sticker = null;
|
||||
contacts = null;
|
||||
attachments = messageReceived.getAttachmentNames().stream().map(JsonAttachment::new).collect(Collectors.toList());
|
||||
|
||||
}
|
||||
|
||||
public JsonDataMessage(Signal.MessageReceivedV2 messageReceived) {
|
||||
timestamp = messageReceived.getTimestamp();
|
||||
message = messageReceived.getMessage();
|
||||
groupInfo = messageReceived.getGroupId().length > 0 ? new JsonGroupInfo(messageReceived.getGroupId()) : null;
|
||||
|
@ -126,9 +143,25 @@ class JsonDataMessage {
|
|||
sticker = null;
|
||||
contacts = null;
|
||||
attachments = messageReceived.getAttachments().stream().map(JsonAttachment::new).collect(Collectors.toList());
|
||||
|
||||
}
|
||||
|
||||
public JsonDataMessage(Signal.SyncMessageReceived messageReceived) {
|
||||
timestamp = messageReceived.getTimestamp();
|
||||
message = messageReceived.getMessage();
|
||||
groupInfo = messageReceived.getGroupId().length > 0 ? new JsonGroupInfo(messageReceived.getGroupId()) : null;
|
||||
expiresInSeconds = null;
|
||||
viewOnce = null;
|
||||
remoteDelete = null;
|
||||
reaction = null; // TODO Replace these 5 with the proper commands
|
||||
quote = null;
|
||||
mentions = null;
|
||||
sticker = null;
|
||||
contacts = null;
|
||||
attachments = messageReceived.getAttachmentNames().stream().map(JsonAttachment::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public JsonDataMessage(Signal.SyncMessageReceivedV2 messageReceived) {
|
||||
timestamp = messageReceived.getTimestamp();
|
||||
message = messageReceived.getMessage();
|
||||
groupInfo = messageReceived.getGroupId().length > 0 ? new JsonGroupInfo(messageReceived.getGroupId()) : null;
|
||||
|
|
|
@ -7,7 +7,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||
|
||||
import org.asamk.signal.manager.groups.GroupId;
|
||||
import org.asamk.signal.manager.groups.GroupIdFormatException;
|
||||
import org.asamk.signal.dbus.DbusAttachment;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue