Refactor receive api

This commit is contained in:
AsamK 2021-11-03 20:43:39 +01:00
parent b615a4b04d
commit 9075cc1a30
36 changed files with 1510 additions and 970 deletions

View file

@ -1,22 +1,14 @@
package org.asamk.signal.json;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
import org.asamk.signal.manager.api.MessageEnvelope;
record JsonAttachment(String contentType, String filename, String id, Long size) {
static JsonAttachment from(SignalServiceAttachment attachment) {
if (attachment.isPointer()) {
final var pointer = attachment.asPointer();
final var id = pointer.getRemoteId().toString();
final var filename = pointer.getFileName().orNull();
final var size = pointer.getSize().transform(Integer::longValue).orNull();
return new JsonAttachment(attachment.getContentType(), filename, id, size);
} else {
final var stream = attachment.asStream();
final var filename = stream.getFileName().orNull();
final var size = stream.getLength();
return new JsonAttachment(attachment.getContentType(), filename, null, size);
}
static JsonAttachment from(MessageEnvelope.Data.Attachment attachment) {
final var id = attachment.id().orElse(null);
final var filename = attachment.fileName().orElse(null);
final var size = attachment.size().orElse(null);
return new JsonAttachment(attachment.contentType(), filename, id, size);
}
static JsonAttachment from(String filename) {

View file

@ -2,28 +2,65 @@ package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.whispersystems.signalservice.api.messages.calls.AnswerMessage;
import org.whispersystems.signalservice.api.messages.calls.BusyMessage;
import org.whispersystems.signalservice.api.messages.calls.HangupMessage;
import org.whispersystems.signalservice.api.messages.calls.IceUpdateMessage;
import org.whispersystems.signalservice.api.messages.calls.OfferMessage;
import org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMessage;
import org.asamk.signal.manager.api.MessageEnvelope;
import java.util.Base64;
import java.util.List;
import java.util.stream.Collectors;
record JsonCallMessage(
@JsonInclude(JsonInclude.Include.NON_NULL) OfferMessage offerMessage,
@JsonInclude(JsonInclude.Include.NON_NULL) AnswerMessage answerMessage,
@JsonInclude(JsonInclude.Include.NON_NULL) BusyMessage busyMessage,
@JsonInclude(JsonInclude.Include.NON_NULL) HangupMessage hangupMessage,
@JsonInclude(JsonInclude.Include.NON_NULL) List<IceUpdateMessage> iceUpdateMessages
@JsonInclude(JsonInclude.Include.NON_NULL) Offer offerMessage,
@JsonInclude(JsonInclude.Include.NON_NULL) Answer answerMessage,
@JsonInclude(JsonInclude.Include.NON_NULL) Busy busyMessage,
@JsonInclude(JsonInclude.Include.NON_NULL) Hangup hangupMessage,
@JsonInclude(JsonInclude.Include.NON_EMPTY) List<IceUpdate> iceUpdateMessages
) {
static JsonCallMessage from(SignalServiceCallMessage callMessage) {
return new JsonCallMessage(callMessage.getOfferMessage().orNull(),
callMessage.getAnswerMessage().orNull(),
callMessage.getBusyMessage().orNull(),
callMessage.getHangupMessage().orNull(),
callMessage.getIceUpdateMessages().orNull());
static JsonCallMessage from(MessageEnvelope.Call callMessage) {
return new JsonCallMessage(callMessage.offer().map(Offer::from).orElse(null),
callMessage.answer().map(Answer::from).orElse(null),
callMessage.busy().map(Busy::from).orElse(null),
callMessage.hangup().map(Hangup::from).orElse(null),
callMessage.iceUpdate().stream().map(IceUpdate::from).collect(Collectors.toList()));
}
record Offer(long id, String sdp, String type, String opaque) {
public static Offer from(final MessageEnvelope.Call.Offer offer) {
return new Offer(offer.id(),
offer.sdp(),
offer.type().name(),
Base64.getEncoder().encodeToString(offer.opaque()));
}
}
public record Answer(long id, String sdp, String opaque) {
public static Answer from(final MessageEnvelope.Call.Answer answer) {
return new Answer(answer.id(), answer.sdp(), Base64.getEncoder().encodeToString(answer.opaque()));
}
}
public record Busy(long id) {
public static Busy from(final MessageEnvelope.Call.Busy busy) {
return new Busy(busy.id());
}
}
public record Hangup(long id, String type, int deviceId, boolean isLegacy) {
public static Hangup from(final MessageEnvelope.Call.Hangup hangup) {
return new Hangup(hangup.id(), hangup.type().name(), hangup.deviceId(), hangup.isLegacy());
}
}
public record IceUpdate(long id, String sdp, String opaque) {
public static IceUpdate from(final MessageEnvelope.Call.IceUpdate iceUpdate) {
return new IceUpdate(iceUpdate.id(),
iceUpdate.sdp(),
Base64.getEncoder().encodeToString(iceUpdate.opaque()));
}
}
}

View file

@ -1,10 +1,10 @@
package org.asamk.signal.json;
import org.asamk.signal.manager.api.MessageEnvelope;
import org.asamk.signal.util.Util;
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
public record JsonContactAddress(
SharedContact.PostalAddress.Type type,
String type,
String label,
String street,
String pobox,
@ -15,15 +15,15 @@ public record JsonContactAddress(
String country
) {
static JsonContactAddress from(SharedContact.PostalAddress address) {
return new JsonContactAddress(address.getType(),
Util.getStringIfNotBlank(address.getLabel()),
Util.getStringIfNotBlank(address.getStreet()),
Util.getStringIfNotBlank(address.getPobox()),
Util.getStringIfNotBlank(address.getNeighborhood()),
Util.getStringIfNotBlank(address.getCity()),
Util.getStringIfNotBlank(address.getRegion()),
Util.getStringIfNotBlank(address.getPostcode()),
Util.getStringIfNotBlank(address.getCountry()));
static JsonContactAddress from(MessageEnvelope.Data.SharedContact.Address address) {
return new JsonContactAddress(address.type().name(),
Util.getStringIfNotBlank(address.label()),
Util.getStringIfNotBlank(address.street()),
Util.getStringIfNotBlank(address.pobox()),
Util.getStringIfNotBlank(address.neighborhood()),
Util.getStringIfNotBlank(address.city()),
Util.getStringIfNotBlank(address.region()),
Util.getStringIfNotBlank(address.postcode()),
Util.getStringIfNotBlank(address.country()));
}
}

View file

@ -1,10 +1,10 @@
package org.asamk.signal.json;
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
import org.asamk.signal.manager.api.MessageEnvelope;
public record JsonContactAvatar(JsonAttachment attachment, boolean isProfile) {
static JsonContactAvatar from(SharedContact.Avatar avatar) {
return new JsonContactAvatar(JsonAttachment.from(avatar.getAttachment()), avatar.isProfile());
static JsonContactAvatar from(MessageEnvelope.Data.SharedContact.Avatar avatar) {
return new JsonContactAvatar(JsonAttachment.from(avatar.attachment()), avatar.isProfile());
}
}

View file

@ -1,11 +1,11 @@
package org.asamk.signal.json;
import org.asamk.signal.manager.api.MessageEnvelope;
import org.asamk.signal.util.Util;
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
public record JsonContactEmail(String value, SharedContact.Email.Type type, String label) {
public record JsonContactEmail(String value, String type, String label) {
static JsonContactEmail from(SharedContact.Email email) {
return new JsonContactEmail(email.getValue(), email.getType(), Util.getStringIfNotBlank(email.getLabel()));
static JsonContactEmail from(MessageEnvelope.Data.SharedContact.Email email) {
return new JsonContactEmail(email.value(), email.type().name(), Util.getStringIfNotBlank(email.label()));
}
}

View file

@ -1,18 +1,18 @@
package org.asamk.signal.json;
import org.asamk.signal.manager.api.MessageEnvelope;
import org.asamk.signal.util.Util;
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
public record JsonContactName(
String display, String given, String family, String prefix, String suffix, String middle
) {
static JsonContactName from(SharedContact.Name name) {
return new JsonContactName(Util.getStringIfNotBlank(name.getDisplay()),
Util.getStringIfNotBlank(name.getGiven()),
Util.getStringIfNotBlank(name.getFamily()),
Util.getStringIfNotBlank(name.getPrefix()),
Util.getStringIfNotBlank(name.getSuffix()),
Util.getStringIfNotBlank(name.getMiddle()));
static JsonContactName from(MessageEnvelope.Data.SharedContact.Name name) {
return new JsonContactName(Util.getStringIfNotBlank(name.display()),
Util.getStringIfNotBlank(name.given()),
Util.getStringIfNotBlank(name.family()),
Util.getStringIfNotBlank(name.prefix()),
Util.getStringIfNotBlank(name.suffix()),
Util.getStringIfNotBlank(name.middle()));
}
}

View file

@ -1,11 +1,11 @@
package org.asamk.signal.json;
import org.asamk.signal.manager.api.MessageEnvelope;
import org.asamk.signal.util.Util;
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
public record JsonContactPhone(String value, SharedContact.Phone.Type type, String label) {
public record JsonContactPhone(String value, String type, String label) {
static JsonContactPhone from(SharedContact.Phone phone) {
return new JsonContactPhone(phone.getValue(), phone.getType(), Util.getStringIfNotBlank(phone.getLabel()));
static JsonContactPhone from(MessageEnvelope.Data.SharedContact.Phone phone) {
return new JsonContactPhone(phone.value(), phone.type().name(), Util.getStringIfNotBlank(phone.label()));
}
}

View file

@ -3,8 +3,7 @@ package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.asamk.Signal;
import org.asamk.signal.manager.Manager;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
import org.asamk.signal.manager.api.MessageEnvelope;
import java.util.List;
import java.util.stream.Collectors;
@ -24,66 +23,32 @@ record JsonDataMessage(
@JsonInclude(JsonInclude.Include.NON_NULL) JsonGroupInfo groupInfo
) {
static JsonDataMessage from(SignalServiceDataMessage dataMessage, Manager m) {
final var timestamp = dataMessage.getTimestamp();
final JsonGroupInfo groupInfo;
if (dataMessage.getGroupContext().isPresent()) {
final var groupContext = dataMessage.getGroupContext().get();
if (groupContext.getGroupV1().isPresent()) {
var group = groupContext.getGroupV1().get();
groupInfo = JsonGroupInfo.from(group);
} else if (groupContext.getGroupV2().isPresent()) {
var group = groupContext.getGroupV2().get();
groupInfo = JsonGroupInfo.from(group);
} else {
groupInfo = null;
}
} else {
groupInfo = null;
}
final var message = dataMessage.getBody().orNull();
final var expiresInSeconds = dataMessage.getExpiresInSeconds();
static JsonDataMessage from(MessageEnvelope.Data dataMessage) {
final var timestamp = dataMessage.timestamp();
final var groupInfo = dataMessage.groupContext().isPresent() ? JsonGroupInfo.from(dataMessage.groupContext()
.get()) : null;
final var message = dataMessage.body().orElse(null);
final var expiresInSeconds = dataMessage.expiresInSeconds();
final var viewOnce = dataMessage.isViewOnce();
final var reaction = dataMessage.getReaction().isPresent() ? JsonReaction.from(dataMessage.getReaction().get(),
m) : null;
final var quote = dataMessage.getQuote().isPresent() ? JsonQuote.from(dataMessage.getQuote().get(), m) : null;
final List<JsonMention> mentions;
if (dataMessage.getMentions().isPresent()) {
mentions = dataMessage.getMentions()
.get()
.stream()
.map(mention -> JsonMention.from(mention, m))
.collect(Collectors.toList());
} else {
mentions = List.of();
}
final var remoteDelete = dataMessage.getRemoteDelete().isPresent()
? JsonRemoteDelete.from(dataMessage.getRemoteDelete().get())
: null;
final List<JsonAttachment> attachments;
if (dataMessage.getAttachments().isPresent()) {
attachments = dataMessage.getAttachments()
.get()
.stream()
.map(JsonAttachment::from)
.collect(Collectors.toList());
} else {
attachments = List.of();
}
final var sticker = dataMessage.getSticker().isPresent()
? JsonSticker.from(dataMessage.getSticker().get())
final var reaction = dataMessage.reaction().map(JsonReaction::from).orElse(null);
final var quote = dataMessage.quote().isPresent() ? JsonQuote.from(dataMessage.quote().get()) : null;
final var mentions = dataMessage.mentions().size() > 0 ? dataMessage.mentions()
.stream()
.map(JsonMention::from)
.collect(Collectors.toList()) : null;
final var remoteDelete = dataMessage.remoteDeleteId().isPresent()
? new JsonRemoteDelete(dataMessage.remoteDeleteId().get())
: null;
final var attachments = dataMessage.attachments().size() > 0 ? dataMessage.attachments()
.stream()
.map(JsonAttachment::from)
.collect(Collectors.toList()) : null;
final var sticker = dataMessage.sticker().isPresent() ? JsonSticker.from(dataMessage.sticker().get()) : null;
final List<JsonSharedContact> contacts;
if (dataMessage.getSharedContacts().isPresent()) {
contacts = dataMessage.getSharedContacts()
.get()
.stream()
.map(JsonSharedContact::from)
.collect(Collectors.toList());
} else {
contacts = List.of();
}
final var contacts = dataMessage.sharedContacts().size() > 0 ? dataMessage.sharedContacts()
.stream()
.map(JsonSharedContact::from)
.collect(Collectors.toList()) : null;
return new JsonDataMessage(timestamp,
message,
expiresInSeconds,

View file

@ -1,42 +1,17 @@
package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.asamk.signal.manager.groups.GroupUtils;
import org.asamk.signal.util.Util;
import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
import org.whispersystems.signalservice.api.messages.SignalServiceGroupV2;
import org.asamk.signal.manager.api.MessageEnvelope;
import java.util.Base64;
import java.util.List;
import java.util.stream.Collectors;
record JsonGroupInfo(
String groupId,
String type,
@JsonInclude(JsonInclude.Include.NON_NULL) String name,
@JsonInclude(JsonInclude.Include.NON_NULL) List<String> members
) {
record JsonGroupInfo(String groupId, String type) {
static JsonGroupInfo from(SignalServiceGroup groupInfo) {
return new JsonGroupInfo(Base64.getEncoder().encodeToString(groupInfo.getGroupId()),
groupInfo.getType().toString(),
groupInfo.getName().orNull(),
groupInfo.getMembers().isPresent() ? groupInfo.getMembers()
.get()
.stream()
.map(Util::getLegacyIdentifier)
.collect(Collectors.toList()) : null);
}
static JsonGroupInfo from(SignalServiceGroupV2 groupInfo) {
return new JsonGroupInfo(GroupUtils.getGroupIdV2(groupInfo.getMasterKey()).toBase64(),
groupInfo.hasSignedGroupChange() ? "UPDATE" : "DELIVER",
null,
null);
static JsonGroupInfo from(MessageEnvelope.Data.GroupContext groupContext) {
return new JsonGroupInfo(groupContext.groupId().toBase64(),
groupContext.isGroupUpdate() ? "UPDATE" : "DELIVER");
}
static JsonGroupInfo from(byte[] groupId) {
return new JsonGroupInfo(Base64.getEncoder().encodeToString(groupId), "DELIVER", null, null);
return new JsonGroupInfo(Base64.getEncoder().encodeToString(groupId), "DELIVER");
}
}

View file

@ -1,19 +1,17 @@
package org.asamk.signal.json;
import org.asamk.signal.manager.Manager;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.asamk.signal.manager.api.MessageEnvelope;
import static org.asamk.signal.util.Util.getLegacyIdentifier;
import java.util.UUID;
public record JsonMention(@Deprecated String name, String number, String uuid, int start, int length) {
static JsonMention from(SignalServiceDataMessage.Mention mention, Manager m) {
final var address = m.resolveSignalServiceAddress(new SignalServiceAddress(mention.getUuid()));
return new JsonMention(getLegacyIdentifier(address),
address.getNumber().orNull(),
address.getUuid().toString(),
mention.getStart(),
mention.getLength());
static JsonMention from(MessageEnvelope.Data.Mention mention) {
final var address = mention.recipient();
return new JsonMention(address.getLegacyIdentifier(),
address.getNumber().orElse(null),
address.getUuid().map(UUID::toString).orElse(null),
mention.start(),
mention.length());
}
}

View file

@ -5,14 +5,12 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import org.asamk.Signal;
import org.asamk.signal.manager.Manager;
import org.asamk.signal.manager.UntrustedIdentityException;
import org.asamk.signal.manager.api.MessageEnvelope;
import org.asamk.signal.manager.api.RecipientIdentifier;
import org.whispersystems.signalservice.api.messages.SignalServiceContent;
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
import org.whispersystems.signalservice.api.util.InvalidNumberException;
import java.util.List;
import static org.asamk.signal.util.Util.getLegacyIdentifier;
import java.util.UUID;
public record JsonMessageEnvelope(
@Deprecated String source,
@ -29,29 +27,23 @@ public record JsonMessageEnvelope(
) {
public static JsonMessageEnvelope from(
SignalServiceEnvelope envelope, SignalServiceContent content, Throwable exception, Manager m
MessageEnvelope envelope, Throwable exception, Manager m
) {
final String source;
final String sourceNumber;
final String sourceUuid;
final Integer sourceDevice;
if (!envelope.isUnidentifiedSender() && envelope.hasSourceUuid()) {
final var sourceAddress = m.resolveSignalServiceAddress(envelope.getSourceAddress());
source = getLegacyIdentifier(sourceAddress);
sourceNumber = sourceAddress.getNumber().orNull();
sourceUuid = sourceAddress.getUuid().toString();
sourceDevice = envelope.getSourceDevice();
} else if (envelope.isUnidentifiedSender() && content != null) {
final var sender = m.resolveSignalServiceAddress(content.getSender());
source = getLegacyIdentifier(sender);
sourceNumber = sender.getNumber().orNull();
sourceUuid = sender.getUuid().toString();
sourceDevice = content.getSenderDevice();
if (envelope.sourceAddress().isPresent()) {
final var sourceAddress = envelope.sourceAddress().get();
source = sourceAddress.getLegacyIdentifier();
sourceNumber = sourceAddress.getNumber().orElse(null);
sourceUuid = sourceAddress.getUuid().map(UUID::toString).orElse(null);
sourceDevice = envelope.sourceDevice();
} else if (exception instanceof UntrustedIdentityException e) {
final var sender = m.resolveSignalServiceAddress(e.getSender());
source = getLegacyIdentifier(sender);
sourceNumber = sender.getNumber().orNull();
sourceUuid = sender.getUuid().toString();
final var sender = e.getSender();
source = sender.getLegacyIdentifier();
sourceNumber = sender.getNumber().orElse(null);
sourceUuid = sender.getUuid().map(UUID::toString).orElse(null);
sourceDevice = e.getSenderDevice();
} else {
source = null;
@ -66,27 +58,13 @@ public record JsonMessageEnvelope(
name = null;
}
final var sourceName = name;
final var timestamp = envelope.getTimestamp();
final JsonReceiptMessage receiptMessage;
if (envelope.isReceipt()) {
receiptMessage = JsonReceiptMessage.deliveryReceipt(timestamp, List.of(timestamp));
} else if (content != null && content.getReceiptMessage().isPresent()) {
receiptMessage = JsonReceiptMessage.from(content.getReceiptMessage().get());
} else {
receiptMessage = null;
}
final var typingMessage = content != null && content.getTypingMessage().isPresent() ? JsonTypingMessage.from(
content.getTypingMessage().get()) : null;
final var timestamp = envelope.timestamp();
final var receiptMessage = envelope.receipt().map(JsonReceiptMessage::from).orElse(null);
final var typingMessage = envelope.typing().map(JsonTypingMessage::from).orElse(null);
final var dataMessage = content != null && content.getDataMessage().isPresent()
? JsonDataMessage.from(content.getDataMessage().get(), m)
: null;
final var syncMessage = content != null && content.getSyncMessage().isPresent()
? JsonSyncMessage.from(content.getSyncMessage().get(), m)
: null;
final var callMessage = content != null && content.getCallMessage().isPresent()
? JsonCallMessage.from(content.getCallMessage().get())
: null;
final var dataMessage = envelope.data().map(JsonDataMessage::from).orElse(null);
final var syncMessage = envelope.sync().map(JsonSyncMessage::from).orElse(null);
final var callMessage = envelope.call().map(JsonCallMessage::from).orElse(null);
return new JsonMessageEnvelope(source,
sourceNumber,

View file

@ -2,15 +2,13 @@ package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.asamk.signal.manager.Manager;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
import org.asamk.signal.manager.api.MessageEnvelope;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import static org.asamk.signal.util.Util.getLegacyIdentifier;
public record JsonQuote(
long id,
@Deprecated String author,
@ -21,30 +19,23 @@ public record JsonQuote(
List<JsonQuotedAttachment> attachments
) {
static JsonQuote from(SignalServiceDataMessage.Quote quote, Manager m) {
final var id = quote.getId();
final var address = m.resolveSignalServiceAddress(quote.getAuthor());
final var author = getLegacyIdentifier(address);
final var authorNumber = address.getNumber().orNull();
final var authorUuid = address.getUuid().toString();
final var text = quote.getText();
static JsonQuote from(MessageEnvelope.Data.Quote quote) {
final var id = quote.id();
final var address = quote.author();
final var author = address.getLegacyIdentifier();
final var authorNumber = address.getNumber().orElse(null);
final var authorUuid = address.getUuid().map(UUID::toString).orElse(null);
final var text = quote.text().orElse(null);
final List<JsonMention> mentions;
if (quote.getMentions() != null && quote.getMentions().size() > 0) {
mentions = quote.getMentions()
.stream()
.map(quotedMention -> JsonMention.from(quotedMention, m))
.collect(Collectors.toList());
} else {
mentions = null;
}
final var mentions = quote.mentions().size() > 0 ? quote.mentions()
.stream()
.map(JsonMention::from)
.collect(Collectors.toList()) : null;
final List<JsonQuotedAttachment> attachments;
if (quote.getAttachments().size() > 0) {
attachments = quote.getAttachments().stream().map(JsonQuotedAttachment::from).collect(Collectors.toList());
} else {
attachments = new ArrayList<>();
}
final var attachments = quote.attachments().size() > 0 ? quote.attachments()
.stream()
.map(JsonQuotedAttachment::from)
.collect(Collectors.toList()) : new ArrayList<JsonQuotedAttachment>();
return new JsonQuote(id, author, authorNumber, authorUuid, text, mentions, attachments);
}

View file

@ -2,21 +2,18 @@ package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
import org.asamk.signal.manager.api.MessageEnvelope;
public record JsonQuotedAttachment(
String contentType, String filename, @JsonInclude(JsonInclude.Include.NON_NULL) JsonAttachment thumbnail
) {
static JsonQuotedAttachment from(SignalServiceDataMessage.Quote.QuotedAttachment quotedAttachment) {
final var contentType = quotedAttachment.getContentType();
final var filename = quotedAttachment.getFileName();
final JsonAttachment thumbnail;
if (quotedAttachment.getThumbnail() != null) {
thumbnail = JsonAttachment.from(quotedAttachment.getThumbnail());
} else {
thumbnail = null;
}
static JsonQuotedAttachment from(MessageEnvelope.Data.Attachment quotedAttachment) {
final var contentType = quotedAttachment.contentType();
final var filename = quotedAttachment.fileName().orElse(null);
final var thumbnail = quotedAttachment.thumbnail().isPresent()
? JsonAttachment.from(quotedAttachment.thumbnail().get())
: null;
return new JsonQuotedAttachment(contentType, filename, thumbnail);
}
}

View file

@ -1,9 +1,8 @@
package org.asamk.signal.json;
import org.asamk.signal.manager.Manager;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage.Reaction;
import org.asamk.signal.manager.api.MessageEnvelope;
import static org.asamk.signal.util.Util.getLegacyIdentifier;
import java.util.UUID;
public record JsonReaction(
String emoji,
@ -14,13 +13,13 @@ public record JsonReaction(
boolean isRemove
) {
static JsonReaction from(Reaction reaction, Manager m) {
final var emoji = reaction.getEmoji();
final var address = m.resolveSignalServiceAddress(reaction.getTargetAuthor());
final var targetAuthor = getLegacyIdentifier(address);
final var targetAuthorNumber = address.getNumber().orNull();
final var targetAuthorUuid = address.getUuid().toString();
final var targetSentTimestamp = reaction.getTargetSentTimestamp();
static JsonReaction from(MessageEnvelope.Data.Reaction reaction) {
final var emoji = reaction.emoji();
final var address = reaction.targetAuthor();
final var targetAuthor = address.getLegacyIdentifier();
final var targetAuthorNumber = address.getNumber().orElse(null);
final var targetAuthorUuid = address.getUuid().map(UUID::toString).orElse(null);
final var targetSentTimestamp = reaction.targetSentTimestamp();
final var isRemove = reaction.isRemove();
return new JsonReaction(emoji,
targetAuthor,

View file

@ -1,17 +1,17 @@
package org.asamk.signal.json;
import org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage;
import org.asamk.signal.manager.api.MessageEnvelope;
import java.util.List;
record JsonReceiptMessage(long when, boolean isDelivery, boolean isRead, boolean isViewed, List<Long> timestamps) {
static JsonReceiptMessage from(SignalServiceReceiptMessage receiptMessage) {
final var when = receiptMessage.getWhen();
final var isDelivery = receiptMessage.isDeliveryReceipt();
final var isRead = receiptMessage.isReadReceipt();
final var isViewed = receiptMessage.isViewedReceipt();
final var timestamps = receiptMessage.getTimestamps();
static JsonReceiptMessage from(MessageEnvelope.Receipt receiptMessage) {
final var when = receiptMessage.when();
final var isDelivery = receiptMessage.type() == MessageEnvelope.Receipt.Type.DELIVERY;
final var isRead = receiptMessage.type() == MessageEnvelope.Receipt.Type.READ;
final var isViewed = receiptMessage.type() == MessageEnvelope.Receipt.Type.VIEWED;
final var timestamps = receiptMessage.timestamps();
return new JsonReceiptMessage(when, isDelivery, isRead, isViewed, timestamps);
}

View file

@ -1,10 +1,3 @@
package org.asamk.signal.json;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
record JsonRemoteDelete(long timestamp) {
static JsonRemoteDelete from(SignalServiceDataMessage.RemoteDelete remoteDelete) {
return new JsonRemoteDelete(remoteDelete.getTargetSentTimestamp());
}
}
record JsonRemoteDelete(long timestamp) {}

View file

@ -2,43 +2,40 @@ package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
import org.asamk.signal.manager.api.MessageEnvelope;
import java.util.List;
import java.util.stream.Collectors;
public record JsonSharedContact(
JsonContactName name,
JsonContactAvatar avatar,
@JsonInclude(JsonInclude.Include.NON_NULL) JsonContactAvatar avatar,
@JsonInclude(JsonInclude.Include.NON_NULL) List<JsonContactPhone> phone,
@JsonInclude(JsonInclude.Include.NON_NULL) List<JsonContactEmail> email,
@JsonInclude(JsonInclude.Include.NON_NULL) List<JsonContactAddress> address,
String organization
) {
static JsonSharedContact from(SharedContact contact) {
final var name = JsonContactName.from(contact.getName());
final var avatar = contact.getAvatar().isPresent() ? JsonContactAvatar.from(contact.getAvatar().get()) : null;
static JsonSharedContact from(MessageEnvelope.Data.SharedContact contact) {
final var name = JsonContactName.from(contact.name());
final var avatar = contact.avatar().isPresent() ? JsonContactAvatar.from(contact.avatar().get()) : null;
final var phone = contact.getPhone().isPresent() ? contact.getPhone()
.get()
final var phone = contact.phone().size() > 0 ? contact.phone()
.stream()
.map(JsonContactPhone::from)
.collect(Collectors.toList()) : null;
final var email = contact.getEmail().isPresent() ? contact.getEmail()
.get()
final var email = contact.email().size() > 0 ? contact.email()
.stream()
.map(JsonContactEmail::from)
.collect(Collectors.toList()) : null;
final var address = contact.getAddress().isPresent() ? contact.getAddress()
.get()
final var address = contact.address().size() > 0 ? contact.address()
.stream()
.map(JsonContactAddress::from)
.collect(Collectors.toList()) : null;
final var organization = contact.getOrganization().orNull();
final var organization = contact.organization().orElse(null);
return new JsonSharedContact(name, avatar, phone, email, address, organization);
}

View file

@ -1,15 +1,16 @@
package org.asamk.signal.json;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
import org.asamk.signal.manager.api.MessageEnvelope;
import java.util.Base64;
public record JsonSticker(String packId, String packKey, int stickerId) {
static JsonSticker from(SignalServiceDataMessage.Sticker sticker) {
final var packId = Base64.getEncoder().encodeToString(sticker.getPackId());
final var packKey = Base64.getEncoder().encodeToString(sticker.getPackKey());
final var stickerId = sticker.getStickerId();
static JsonSticker from(MessageEnvelope.Data.Sticker sticker) {
final var encoder = Base64.getEncoder();
final var packId = encoder.encodeToString(sticker.packId());
final var packKey = encoder.encodeToString(sticker.packKey());
final var stickerId = sticker.stickerId();
return new JsonSticker(packId, packKey, stickerId);
}
}

View file

@ -3,10 +3,9 @@ package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import org.asamk.Signal;
import org.asamk.signal.manager.Manager;
import org.whispersystems.signalservice.api.messages.multidevice.SentTranscriptMessage;
import org.asamk.signal.manager.api.MessageEnvelope;
import static org.asamk.signal.util.Util.getLegacyIdentifier;
import java.util.UUID;
record JsonSyncDataMessage(
@Deprecated String destination,
@ -15,16 +14,16 @@ record JsonSyncDataMessage(
@JsonUnwrapped JsonDataMessage dataMessage
) {
static JsonSyncDataMessage from(SentTranscriptMessage transcriptMessage, Manager m) {
if (transcriptMessage.getDestination().isPresent()) {
final var address = transcriptMessage.getDestination().get();
return new JsonSyncDataMessage(getLegacyIdentifier(address),
address.getNumber().orNull(),
address.getUuid().toString(),
JsonDataMessage.from(transcriptMessage.getMessage(), m));
static JsonSyncDataMessage from(MessageEnvelope.Sync.Sent transcriptMessage) {
if (transcriptMessage.destination().isPresent()) {
final var address = transcriptMessage.destination().get();
return new JsonSyncDataMessage(address.getLegacyIdentifier(),
address.getNumber().orElse(null),
address.getUuid().map(UUID::toString).orElse(null),
JsonDataMessage.from(transcriptMessage.message()));
} else {
return new JsonSyncDataMessage(null, null, null, JsonDataMessage.from(transcriptMessage.getMessage(), m));
return new JsonSyncDataMessage(null, null, null, JsonDataMessage.from(transcriptMessage.message()));
}
}

View file

@ -3,11 +3,10 @@ package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.asamk.Signal;
import org.asamk.signal.manager.Manager;
import org.asamk.signal.util.Util;
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
import org.asamk.signal.manager.api.MessageEnvelope;
import org.asamk.signal.manager.groups.GroupId;
import org.asamk.signal.manager.storage.recipients.RecipientAddress;
import java.util.Base64;
import java.util.List;
import java.util.stream.Collectors;
@ -39,43 +38,40 @@ record JsonSyncMessage(
this.type = type;
}
static JsonSyncMessage from(SignalServiceSyncMessage syncMessage, Manager m) {
final var sentMessage = syncMessage.getSent().isPresent() ? JsonSyncDataMessage.from(syncMessage.getSent()
.get(), m) : null;
static JsonSyncMessage from(MessageEnvelope.Sync syncMessage) {
final var sentMessage = syncMessage.sent().isPresent()
? JsonSyncDataMessage.from(syncMessage.sent().get())
: null;
final List<String> blockedNumbers;
final List<String> blockedGroupIds;
if (syncMessage.getBlockedList().isPresent()) {
final var base64 = Base64.getEncoder();
blockedNumbers = syncMessage.getBlockedList()
if (syncMessage.blocked().isPresent()) {
blockedNumbers = syncMessage.blocked()
.get()
.getAddresses()
.recipients()
.stream()
.map(Util::getLegacyIdentifier)
.map(RecipientAddress::getLegacyIdentifier)
.collect(Collectors.toList());
blockedGroupIds = syncMessage.getBlockedList()
blockedGroupIds = syncMessage.blocked()
.get()
.getGroupIds()
.groupIds()
.stream()
.map(base64::encodeToString)
.map(GroupId::toBase64)
.collect(Collectors.toList());
} else {
blockedNumbers = null;
blockedGroupIds = null;
}
final var readMessages = syncMessage.getRead().isPresent() ? syncMessage.getRead()
.get()
final var readMessages = syncMessage.read().size() > 0 ? syncMessage.read()
.stream()
.map(JsonSyncReadMessage::from)
.collect(Collectors.toList()) : null;
final JsonSyncMessageType type;
if (syncMessage.getContacts().isPresent()) {
if (syncMessage.contacts().isPresent()) {
type = JsonSyncMessageType.CONTACTS_SYNC;
} else if (syncMessage.getGroups().isPresent()) {
} else if (syncMessage.groups().isPresent()) {
type = JsonSyncMessageType.GROUPS_SYNC;
} else if (syncMessage.getRequest().isPresent()) {
type = JsonSyncMessageType.REQUEST_SYNC;
} else {
type = null;
}

View file

@ -1,19 +1,19 @@
package org.asamk.signal.json;
import org.whispersystems.signalservice.api.messages.multidevice.ReadMessage;
import org.asamk.signal.manager.api.MessageEnvelope;
import static org.asamk.signal.util.Util.getLegacyIdentifier;
import java.util.UUID;
record JsonSyncReadMessage(
@Deprecated String sender, String senderNumber, String senderUuid, long timestamp
) {
static JsonSyncReadMessage from(final ReadMessage readMessage) {
final var senderAddress = readMessage.getSender();
final var sender = getLegacyIdentifier(senderAddress);
final var senderNumber = senderAddress.getNumber().orNull();
final var senderUuid = senderAddress.getUuid().toString();
final var timestamp = readMessage.getTimestamp();
static JsonSyncReadMessage from(MessageEnvelope.Sync.Read readMessage) {
final var senderAddress = readMessage.sender();
final var sender = senderAddress.getLegacyIdentifier();
final var senderNumber = senderAddress.getNumber().orElse(null);
final var senderUuid = senderAddress.getUuid().map(UUID::toString).orElse(null);
final var timestamp = readMessage.timestamp();
return new JsonSyncReadMessage(sender, senderNumber, senderUuid, timestamp);
}
}

View file

@ -2,25 +2,17 @@ package org.asamk.signal.json;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage;
import java.util.Base64;
import org.asamk.signal.manager.api.MessageEnvelope;
import org.asamk.signal.manager.groups.GroupId;
record JsonTypingMessage(
String action, long timestamp, @JsonInclude(JsonInclude.Include.NON_NULL) String groupId
) {
JsonTypingMessage(final String action, final long timestamp, final String groupId) {
this.action = action;
this.timestamp = timestamp;
this.groupId = groupId;
}
static JsonTypingMessage from(SignalServiceTypingMessage typingMessage) {
final var action = typingMessage.getAction().name();
final var timestamp = typingMessage.getTimestamp();
final var encoder = Base64.getEncoder();
final var groupId = typingMessage.getGroupId().transform(encoder::encodeToString).orNull();
static JsonTypingMessage from(MessageEnvelope.Typing typingMessage) {
final var action = typingMessage.type().name();
final var timestamp = typingMessage.timestamp();
final var groupId = typingMessage.groupId().map(GroupId::toBase64).orElse(null);
return new JsonTypingMessage(action, timestamp, groupId);
}
}