From 205cc8d6c25fa6acd22a6cc6c181ff5026996124 Mon Sep 17 00:00:00 2001 From: John Freed Date: Mon, 20 Sep 2021 20:10:32 +0200 Subject: [PATCH] DbusMention and DbusAttachment, with signals Two new data types: `DbusMention` (created by @0b11001111) and `DbusAttachment`. Two new signals, `MessageReceivedV2` and `SyncMessageReceivedV2`. This is to address #671 #316 #658 and #491, in particular addressing the issues raised by @AsamK in #658. The new signals provide the new data structures to the user program, while the existing signals, `MessageReceived` and `SyncMessageReceived`, continue to provide the old data types (with no information about mentions or attachment metadata). As a result, for each message received, two signals will be emitted: the legacy signal and the V2 signal. Existing (old-style) programs will not see the V2 signal, and so nothing will break. New programs can ignore the legacy signal and process the enhanced data. --- .gitignore | 5 + man/signal-cli-dbus.5.adoc | 60 ++++- src/main/java/org/asamk/Signal.java | 144 +++++++++-- .../signal/JsonDbusReceiveMessageHandler.java | 66 ++++- .../asamk/signal/commands/ReceiveCommand.java | 12 +- .../org/asamk/signal/dbus/DbusAttachment.java | 231 ++++++++++++++++++ .../org/asamk/signal/dbus/DbusMention.java | 28 +++ .../asamk/signal/json/JsonDataMessage.java | 4 +- 8 files changed, 518 insertions(+), 32 deletions(-) create mode 100644 src/main/java/org/asamk/signal/dbus/DbusAttachment.java create mode 100644 src/main/java/org/asamk/signal/dbus/DbusMention.java diff --git a/.gitignore b/.gitignore index 8fa9c8bd..18b11c03 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.gitignore .gradle/ .idea/* !.idea/codeStyles/ @@ -11,3 +12,7 @@ local.properties .settings/ out/ .DS_Store +.asciidoctorconfig.adoc +patches/ +signal-cli +/bin/ diff --git a/man/signal-cli-dbus.5.adoc b/man/signal-cli-dbus.5.adoc index 4ff5e994..f8bdfcca 100755 --- a/man/signal-cli-dbus.5.adoc +++ b/man/signal-cli-dbus.5.adoc @@ -238,14 +238,9 @@ isRegistred -> result:: == Signals SyncMessageReceived (timestamp, sender, destination, groupId,message, attachments):: + The sync message is received when the user sends a message from a linked device. -ReceiptReceived (timestamp, sender):: -* timestamp : Integer value that can be used to associate this e.g. with a sendMessage() -* sender : Phone number of the sender - -This signal is sent by each recipient (e.g. each group member) after the message was successfully delivered to the device - MessageReceived(timestamp, sender, groupId, message, attachments):: * timestamp : Integer value that is used by the system to send a ReceiptReceived reply * sender : Phone number of the sender @@ -255,6 +250,59 @@ MessageReceived(timestamp, sender, groupId, message, attachments, sender, destination, groupId, message, mentions, attachments):: +* timestamp : Integer value that is used by the system to send a ReceiptReceived reply +* sender : Phone number of the sender +* destination : UUID (legacy identifier) of the destination +* groupId : Byte array representing the internal group identifier (empty when private message) +* message : Message text +* mentions : Struct array of mentions: number, position, length +** number : String phone number +** position : Integer starting position of mention within message +** length : Integer length of mention within message +* attachments : Struct array of attachment metadata. +** contentType : String representing the MIME type of the attachment +** fileName : String representing file name if given by the Signal servers +** id : String representing remote identifier of attachment. This the name used by signal-cli to store the attachment, and the current user needs to have read access +** size : Long representing size of attachment in bytes +** keyLength : Integer representing key length +** voiceNote : boolean representing whether this attachment is a voice note +** width : Integer representation of width in pixels (0 if not image) +** height : Integer representation of height in pixels (0 if not image) +** caption : String representing photo caption +** blurHash : String representing blur hash + +The sync message is received when the user sends a message from a linked device. + +MessageReceivedV2(timestamp, sender, groupId, message, mentions, attachments):: +* timestamp : Integer value that is used by the system to send a ReceiptReceived reply +* sender : Phone number of the sender +* groupId : Byte array representing the internal group identifier (empty when private message) +* message : Message text +* mentions : Struct array of mentions: number, position, length +** number : String phone number +** position : Integer starting position of mention within message +** length : Integer length of mention within message +* attachments : Struct array of attachment metadata. +** contentType : String representing the MIME type of the attachment +** fileName : String representing file name if given by the Signal servers +** id : String representing remote identifier of attachment. This the name used by signal-cli to store the attachment, and the current user needs to have read access +** size : Long representing size of attachment in bytes +** keyLength : Integer representing key length +** voiceNote : boolean representing whether this attachment is a voice note +** width : Integer representation of width in pixels (0 if not image) +** height : Integer representation of height in pixels (0 if not image) +** caption : String representing photo caption +** blurHash : String representing blur hash + +This signal is received whenever we get a private message or a message is posted in a group we are an active member + +ReceiptReceived (timestamp, sender):: +* timestamp : Integer value that can be used to associate this e.g. with a sendMessage() +* sender : Phone number of the sender + +This signal is sent by each recipient (e.g. each group member) after the message was successfully delivered to the device + == Examples Send a text message (without attachment) to a contact:: diff --git a/src/main/java/org/asamk/Signal.java b/src/main/java/org/asamk/Signal.java index 868de02b..22a467aa 100644 --- a/src/main/java/org/asamk/Signal.java +++ b/src/main/java/org/asamk/Signal.java @@ -1,11 +1,15 @@ 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; import org.freedesktop.dbus.interfaces.DBusInterface; import org.freedesktop.dbus.messages.DBusSignal; +import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * DBus interface for the org.asamk.Signal service. @@ -14,11 +18,11 @@ import java.util.List; public interface Signal extends DBusInterface { long sendMessage( - String message, List attachments, String recipient + String message, List attachmentNames, String recipient ) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.UntrustedIdentity; long sendMessage( - String message, List attachments, List recipients + String message, List attachmentNames, List recipients ) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.UntrustedIdentity; void sendTyping( @@ -50,13 +54,13 @@ public interface Signal extends DBusInterface { ) throws Error.InvalidNumber, Error.Failure; long sendNoteToSelfMessage( - String message, List attachments + String message, List attachmentNames ) throws Error.AttachmentInvalid, Error.Failure; void sendEndSessionMessage(List recipients) throws Error.Failure, Error.InvalidNumber, Error.UntrustedIdentity; long sendGroupMessage( - String message, List attachments, byte[] groupId + String message, List attachmentNames, byte[] groupId ) throws Error.GroupNotFound, Error.Failure, Error.AttachmentInvalid, Error.InvalidGroupId; long sendGroupMessageReaction( @@ -77,12 +81,12 @@ public interface Signal extends DBusInterface { List getGroupMembers(byte[] groupId) throws Error.InvalidGroupId; + boolean isRegistered(); + byte[] updateGroup( byte[] groupId, String name, List members, String avatar ) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.GroupNotFound, Error.InvalidGroupId; - boolean isRegistered(); - void updateProfile( String name, String about, String aboutEmoji, String avatarPath, boolean removeAvatar ) throws Error.Failure; @@ -109,7 +113,7 @@ public interface Signal extends DBusInterface { private final String sender; private final byte[] groupId; private final String message; - private final List attachments; + private final List attachmentNames; public MessageReceived( String objectpath, @@ -117,13 +121,61 @@ public interface Signal extends DBusInterface { String sender, byte[] groupId, String message, - List attachments + List attachmentNames ) throws DBusException { - super(objectpath, timestamp, sender, groupId, message, attachments); + 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 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 mentions; + private final List attachments; + + public MessageReceivedV2( + String objectpath, + long timestamp, + String sender, + byte[] groupId, + String message, + List mentions, + List attachments + ) throws DBusException { + super(objectpath, timestamp, sender, groupId, message, mentions, attachments); + this.timestamp = timestamp; + this.sender = sender; + this.groupId = groupId; + this.message = message; + this.mentions = mentions; this.attachments = attachments; } @@ -143,7 +195,11 @@ public interface Signal extends DBusInterface { return message; } - public List getAttachments() { + public List getMentions() { + return mentions; + } + + public List getAttachments() { return attachments; } } @@ -175,7 +231,7 @@ public interface Signal extends DBusInterface { private final String destination; private final byte[] groupId; private final String message; - private final List attachments; + private final List attachmentNames; public SyncMessageReceived( String objectpath, @@ -184,15 +240,15 @@ public interface Signal extends DBusInterface { String destination, byte[] groupId, String message, - List attachments + List attachmentNames ) throws DBusException { - super(objectpath, timestamp, source, destination, groupId, message, attachments); + super(objectpath, timestamp, source, destination, groupId, message, attachmentNames); this.timestamp = timestamp; this.source = source; this.destination = destination; this.groupId = groupId; this.message = message; - this.attachments = attachments; + this.attachmentNames = attachmentNames; } public long getTimestamp() { @@ -215,7 +271,65 @@ public interface Signal extends DBusInterface { return message; } - public List getAttachments() { + public List 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 mentions; + private final List attachments; + + public SyncMessageReceivedV2( + String objectpath, + long timestamp, + String source, + String destination, + byte[] groupId, + String message, + List mentions, + List attachments + ) throws DBusException { + super(objectpath, timestamp, source, destination, groupId, message, mentions, attachments); + this.timestamp = timestamp; + this.source = source; + this.destination = destination; + this.groupId = groupId; + this.message = message; + this.mentions = mentions; + this.attachments = attachments; + } + 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 getMentions() { + return mentions; + } + + public List getAttachments() { return attachments; } } diff --git a/src/main/java/org/asamk/signal/JsonDbusReceiveMessageHandler.java b/src/main/java/org/asamk/signal/JsonDbusReceiveMessageHandler.java index 9433d209..a7bdbabf 100644 --- a/src/main/java/org/asamk/signal/JsonDbusReceiveMessageHandler.java +++ b/src/main/java/org/asamk/signal/JsonDbusReceiveMessageHandler.java @@ -1,6 +1,8 @@ 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; import org.freedesktop.dbus.connections.impl.DBusConnection; @@ -9,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; @@ -71,12 +74,23 @@ public class JsonDbusReceiveMessageHandler extends JsonReceiveMessageHandler { || message.getGroupContext().get().getGroupV1Type() == SignalServiceGroup.Type.DELIVER )) { try { + List attachments = JsonDbusReceiveMessageHandler.getAttachments(message); + List dBusAttachments = JsonDbusReceiveMessageHandler.convertSignalAttachmentsToDbus(attachments); + //send both signals; only one is relevant + 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), + dBusAttachments + )); conn.sendMessage(new Signal.MessageReceived(objectPath, message.getTimestamp(), getLegacyIdentifier(sender), groupId != null ? groupId : new byte[0], message.getBody().isPresent() ? message.getBody().get() : "", - JsonDbusReceiveMessageHandler.getAttachments(message, m))); + JsonDbusReceiveMessageHandler.getAttachmentNames(message, m))); } catch (DBusException e) { e.printStackTrace(); } @@ -93,6 +107,19 @@ public class JsonDbusReceiveMessageHandler extends JsonReceiveMessageHandler { var groupId = getGroupId(message); try { + List attachments = JsonDbusReceiveMessageHandler.getAttachments(message); + List dBusAttachments = JsonDbusReceiveMessageHandler.convertSignalAttachmentsToDbus(attachments); + conn.sendMessage(new Signal.SyncMessageReceivedV2(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.getMentions(message, m), + dBusAttachments + )); conn.sendMessage(new Signal.SyncMessageReceived(objectPath, transcript.getTimestamp(), getLegacyIdentifier(sender), @@ -101,7 +128,7 @@ public class JsonDbusReceiveMessageHandler extends JsonReceiveMessageHandler { : "", groupId != null ? groupId : new byte[0], message.getBody().isPresent() ? message.getBody().get() : "", - JsonDbusReceiveMessageHandler.getAttachments(message, m))); + JsonDbusReceiveMessageHandler.getAttachmentNames(message, m))); } catch (DBusException e) { e.printStackTrace(); } @@ -116,7 +143,7 @@ public class JsonDbusReceiveMessageHandler extends JsonReceiveMessageHandler { .serialize() : null; } - static private List getAttachments(SignalServiceDataMessage message, Manager m) { + static private List getAttachmentNames(SignalServiceDataMessage message, Manager m) { var attachments = new ArrayList(); if (message.getAttachments().isPresent()) { for (var attachment : message.getAttachments().get()) { @@ -128,10 +155,43 @@ public class JsonDbusReceiveMessageHandler extends JsonReceiveMessageHandler { return attachments; } + static private List getMentions(SignalServiceDataMessage message, Manager m) { + var mentions = new ArrayList(); + if (message.getMentions().isPresent()) { + for (var mention : message.getMentions().get()) { + mentions.add(new DbusMention(mention, m)); + } + } + return mentions; + } + + static private List getAttachments(SignalServiceDataMessage message) { + var attachments = new ArrayList(); + 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 convertSignalAttachmentsToDbus(List attachments) { + ArrayList dBusAttachments = new ArrayList<>(); + if (!attachments.isEmpty()) { + for (SignalServiceAttachment attachment : attachments) { + DbusAttachment dBusAttachment = new DbusAttachment(attachment); + dBusAttachments.add(dBusAttachment); + } + } + return dBusAttachments; + } } diff --git a/src/main/java/org/asamk/signal/commands/ReceiveCommand.java b/src/main/java/org/asamk/signal/commands/ReceiveCommand.java index 62b3164b..92b2a4c8 100644 --- a/src/main/java/org/asamk/signal/commands/ReceiveCommand.java +++ b/src/main/java/org/asamk/signal/commands/ReceiveCommand.java @@ -90,10 +90,10 @@ public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand { writer.indentedWriter() .println("Id: {}", Base64.getEncoder().encodeToString(messageReceived.getGroupId())); } - if (messageReceived.getAttachments().size() > 0) { + if (messageReceived.getAttachmentNames().size() > 0) { writer.println("Attachments:"); - for (var attachment : messageReceived.getAttachments()) { - writer.println("- Stored plaintext in: {}", attachment); + for (var attachmentName : messageReceived.getAttachmentNames()) { + writer.println("- Stored plaintext in: {}", attachmentName); } } writer.println(); @@ -115,10 +115,10 @@ public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand { writer.indentedWriter() .println("Id: {}", Base64.getEncoder().encodeToString(syncReceived.getGroupId())); } - if (syncReceived.getAttachments().size() > 0) { + if (syncReceived.getAttachmentNames().size() > 0) { writer.println("Attachments:"); - for (var attachment : syncReceived.getAttachments()) { - writer.println("- Stored plaintext in: {}", attachment); + for (var attachmentName : syncReceived.getAttachmentNames()) { + writer.println("- Stored plaintext in: {}", attachmentName); } } writer.println(); diff --git a/src/main/java/org/asamk/signal/dbus/DbusAttachment.java b/src/main/java/org/asamk/signal/dbus/DbusAttachment.java new file mode 100644 index 00000000..1cc2113f --- /dev/null +++ b/src/main/java/org/asamk/signal/dbus/DbusAttachment.java @@ -0,0 +1,231 @@ +package org.asamk.signal.dbus; + +import org.asamk.signal.commands.exceptions.UserErrorException; +import org.asamk.signal.manager.util.Utils; +import org.freedesktop.dbus.Struct; +import org.freedesktop.dbus.annotations.Position; +import org.whispersystems.signalservice.api.messages.SignalServiceAttachment; + +import java.io.File; +import java.io.IOException; +import java.net.URL; + +public final class DbusAttachment extends Struct +{ + @Position(0) + private String contentType; + @Position(1) + private String fileName; + @Position(2) + private String id; + @Position(3) + private Long size; + @Position(4) + private Integer keyLength; + @Position(5) + private boolean voiceNote; + @Position(6) + private Integer width; + @Position(7) + private Integer height; + @Position(8) + private String caption; + @Position(9) + private String blurHash; + +/* + * API = 2.15.3 from https://github.com/Turasa/libsignal-service-java (nonstandard) + public SignalServiceAttachmentStream(InputStream inputStream, + String contentType, + long length, + Optional fileName, + boolean voiceNote, + boolean borderless, + boolean gif, //nonstandard + Optional preview, + int width, + int height, + long uploadTimestamp, + Optional caption, + Optional blurHash, + ProgressListener listener, //Android OS + CancellationSignal cancellationSignal, //Android OS, Signal developers misspelled class name + Optional resumableUploadSpec) + + + public SignalServiceAttachmentPointer(int cdnNumber, + SignalServiceAttachmentRemoteId remoteId, + String contentType, + byte[] key, + Optional size, + Optional preview, + int width, + int height, + Optional digest, + Optional fileName, + boolean voiceNote, + boolean borderless, + Optional caption, + Optional blurHash, + long uploadTimestamp) + +other stuff : + private long id; // used by v2 attachments, see note + private int keyLength; //TODO: if you're going to do that, probably should have previewLength and digestLength + +notes : +"size" appears to be the same as "length" but is int rather than long +"length" represents file size (or stream/attachment size) +"preview" is also known as "thumbnail" + +from SignalServiceAttachmentRemoteId.java : + * Represents a signal service attachment identifier. This can be either a CDN key or a long, but + * not both at once. Attachments V2 used a long as an attachment identifier. This lacks sufficient + * entropy to reduce the likelihood of any two uploads going to the same location within a 30-day + * window. Attachments V3 uses an opaque string as an attachment identifier which provides more + * flexibility in the amount of entropy present. + + */ + + public DbusAttachment(SignalServiceAttachment attachment) { + this.contentType = attachment.getContentType(); + + if (attachment.isPointer()) { + final var pointer = attachment.asPointer(); + this.id = pointer.getRemoteId().toString(); + this.fileName = pointer.getFileName().orNull(); + if (this.fileName == null) { + this.fileName = ""; + } + this.size = pointer.getSize().transform(Integer::longValue).orNull(); + if (this.size == null) { + this.size = 0L; + } + this.setKeyLength(pointer.getKey().length); + this.setWidth(pointer.getWidth()); + this.setHeight(pointer.getHeight()); + this.setVoiceNote(pointer.getVoiceNote()); + if (pointer.getCaption().isPresent()) { + this.setCaption(pointer.getCaption().get()); + } else { + this.setCaption(""); + } + this.setBlurHash(""); + } else { + final var stream = attachment.asStream(); + this.fileName = stream.getFileName().orNull(); + if (this.fileName == null) { + this.fileName = ""; + } + this.id = ""; + this.size = stream.getLength(); + this.setKeyLength(0); + this.setWidth(0); + this.setHeight(0); + this.setVoiceNote(false); + this.setCaption(""); + this.setBlurHash(""); + } + } + + public DbusAttachment(String fileName) throws UserErrorException { + this.contentType = "application/octet-stream"; + try { + final File file = new File(fileName); + this.contentType = Utils.getFileMimeType(file, "application/octet-stream"); + this.size = file.length(); + } catch (IOException e) { + //no such file, try URL + try { + final URL aURL = new URL(fileName); + this.contentType = aURL.openConnection().getContentType(); + this.size = aURL.openConnection().getContentLengthLong(); + } catch (IOException f) { + throw new UserErrorException("Cannot find attachment " + fileName + ". " + f.getMessage()); + } + } + this.fileName = fileName; + this.id = ""; + this.setKeyLength(0); + this.setWidth(0); + this.setHeight(0); + this.setVoiceNote(false); + this.setCaption(""); + this.setBlurHash(""); + } + + public String getContentType() { + return contentType; + } + public void setContentType(String contentType) { + this.contentType = contentType; + } + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + + public String getFileName() { + return fileName; + } + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public Long getFileSize() { + return size; + } + public void setFileSize(Long size) { + this.size = size; + } + + public Integer getKeyLength() { + return keyLength; + } + public void setKeyLength(Integer keyLength) { + this.keyLength = keyLength; + } + + public Integer getWidth() { + return width; + } + public void setWidth(Integer width) { + this.width = width; + } + + public Integer getHeight() { + return height; + } + public void setHeight(Integer height) { + this.height = height; + } + + public boolean isVoiceNote() { + return voiceNote; + } + public boolean getVoiceNote() { + return voiceNote; + } + public void setVoiceNote(boolean voiceNote) { + this.voiceNote = voiceNote; + } + + public String getCaption() { + return caption; + } + public void setCaption(String caption) { + this.caption = caption; + } + + public String getBlurHash() { + return blurHash; + } + public void setBlurHash(String blurHash) { + this.blurHash = blurHash; + } + +} + diff --git a/src/main/java/org/asamk/signal/dbus/DbusMention.java b/src/main/java/org/asamk/signal/dbus/DbusMention.java new file mode 100644 index 00000000..52d08f3a --- /dev/null +++ b/src/main/java/org/asamk/signal/dbus/DbusMention.java @@ -0,0 +1,28 @@ +package org.asamk.signal.dbus; + +import org.asamk.signal.manager.Manager; +import org.freedesktop.dbus.Struct; +import org.freedesktop.dbus.annotations.Position; +import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; +import org.whispersystems.signalservice.api.push.SignalServiceAddress; + +import static org.asamk.signal.util.Util.getLegacyIdentifier; + +public final class DbusMention extends Struct { + + @Position(0) + public final String name; + + @Position(1) + public final int start; + + @Position(2) + public final int length; + + public DbusMention(SignalServiceDataMessage.Mention mention, Manager m) { + this.name = getLegacyIdentifier(m.resolveSignalServiceAddress(new SignalServiceAddress(mention.getUuid()))); + this.start = mention.getStart(); + this.length = mention.getLength(); + } +} + diff --git a/src/main/java/org/asamk/signal/json/JsonDataMessage.java b/src/main/java/org/asamk/signal/json/JsonDataMessage.java index 6dbda978..4d16760e 100644 --- a/src/main/java/org/asamk/signal/json/JsonDataMessage.java +++ b/src/main/java/org/asamk/signal/json/JsonDataMessage.java @@ -125,7 +125,7 @@ class JsonDataMessage { mentions = null; sticker = null; contacts = null; - attachments = messageReceived.getAttachments().stream().map(JsonAttachment::new).collect(Collectors.toList()); + attachments = messageReceived.getAttachmentNames().stream().map(JsonAttachment::new).collect(Collectors.toList()); } public JsonDataMessage(Signal.SyncMessageReceived messageReceived) { @@ -140,6 +140,6 @@ class JsonDataMessage { mentions = null; sticker = null; contacts = null; - attachments = messageReceived.getAttachments().stream().map(JsonAttachment::new).collect(Collectors.toList()); + attachments = messageReceived.getAttachmentNames().stream().map(JsonAttachment::new).collect(Collectors.toList()); } }