From a593051512b716ed3cc42a1a7b69d49a459352ed Mon Sep 17 00:00:00 2001 From: AsamK Date: Mon, 8 Aug 2022 18:12:30 +0200 Subject: [PATCH] Implement receive handling for story messages --- graalvm-config-dir/reflect-config.json | 82 ++++++++++++++ .../org/asamk/signal/manager/api/Color.java | 24 ++++ .../signal/manager/api/MessageEnvelope.java | 103 +++++++++++++++++- .../helper/IncomingMessageHandler.java | 103 ++++++++++++++---- .../asamk/signal/ReceiveMessageHandler.java | 42 +++++++ .../asamk/signal/dbus/DbusManagerImpl.java | 8 +- .../asamk/signal/json/JsonDataMessage.java | 9 +- .../signal/json/JsonMessageEnvelope.java | 3 + .../asamk/signal/json/JsonStoryContext.java | 16 +++ .../asamk/signal/json/JsonStoryMessage.java | 52 +++++++++ .../asamk/signal/json/JsonSyncMessage.java | 22 +--- .../signal/json/JsonSyncStoryMessage.java | 26 +++++ 12 files changed, 443 insertions(+), 47 deletions(-) create mode 100644 lib/src/main/java/org/asamk/signal/manager/api/Color.java create mode 100644 src/main/java/org/asamk/signal/json/JsonStoryContext.java create mode 100644 src/main/java/org/asamk/signal/json/JsonStoryMessage.java create mode 100644 src/main/java/org/asamk/signal/json/JsonSyncStoryMessage.java diff --git a/graalvm-config-dir/reflect-config.json b/graalvm-config-dir/reflect-config.json index c223851b..389c947c 100644 --- a/graalvm-config-dir/reflect-config.json +++ b/graalvm-config-dir/reflect-config.json @@ -837,6 +837,55 @@ "allDeclaredMethods":true, "allDeclaredConstructors":true }, +{ + "name":"org.asamk.signal.json.JsonStoryContext", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[ + {"name":"authorNumber","parameterTypes":[] }, + {"name":"authorUuid","parameterTypes":[] }, + {"name":"sentTimestamp","parameterTypes":[] } + ] +}, +{ + "name":"org.asamk.signal.json.JsonStoryMessage", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[ + {"name":"allowsReplies","parameterTypes":[] }, + {"name":"fileAttachment","parameterTypes":[] }, + {"name":"groupId","parameterTypes":[] }, + {"name":"textAttachment","parameterTypes":[] } + ] +}, +{ + "name":"org.asamk.signal.json.JsonStoryMessage$TextAttachment", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[ + {"name":"backgroundColor","parameterTypes":[] }, + {"name":"backgroundGradient","parameterTypes":[] }, + {"name":"preview","parameterTypes":[] }, + {"name":"style","parameterTypes":[] }, + {"name":"text","parameterTypes":[] }, + {"name":"textBackgroundColor","parameterTypes":[] }, + {"name":"textForegroundColor","parameterTypes":[] } + ] +}, +{ + "name":"org.asamk.signal.json.JsonStoryMessage$TextAttachment$Gradient", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[ + {"name":"angle","parameterTypes":[] }, + {"name":"endColor","parameterTypes":[] }, + {"name":"startColor","parameterTypes":[] } + ] +}, { "name":"org.asamk.signal.json.JsonSyncDataMessage", "allDeclaredFields":true, @@ -860,6 +909,17 @@ "allDeclaredMethods":true, "allDeclaredConstructors":true }, +{ + "name":"org.asamk.signal.json.JsonSyncStoryMessage", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[ + {"name":"dataMessage","parameterTypes":[] }, + {"name":"destinationNumber","parameterTypes":[] }, + {"name":"destinationUuid","parameterTypes":[] } + ] +}, { "name":"org.asamk.signal.json.JsonTypingMessage", "allDeclaredFields":true, @@ -3106,6 +3166,28 @@ {"name":"timestamp_"} ] }, +{ + "name":"org.whispersystems.signalservice.internal.push.SignalServiceProtos$TextAttachment", + "fields":[ + {"name":"backgroundCase_"}, + {"name":"background_"}, + {"name":"bitField0_"}, + {"name":"preview_"}, + {"name":"textBackgroundColor_"}, + {"name":"textForegroundColor_"}, + {"name":"textStyle_"}, + {"name":"text_"} + ] +}, +{ + "name":"org.whispersystems.signalservice.internal.push.SignalServiceProtos$TextAttachment$Gradient", + "fields":[ + {"name":"angle_"}, + {"name":"bitField0_"}, + {"name":"endColor_"}, + {"name":"startColor_"} + ] +}, { "name":"org.whispersystems.signalservice.internal.push.SignalServiceProtos$TypingMessage", "fields":[ diff --git a/lib/src/main/java/org/asamk/signal/manager/api/Color.java b/lib/src/main/java/org/asamk/signal/manager/api/Color.java new file mode 100644 index 00000000..11f7deb0 --- /dev/null +++ b/lib/src/main/java/org/asamk/signal/manager/api/Color.java @@ -0,0 +1,24 @@ +package org.asamk.signal.manager.api; + +public record Color(int color) { + + public int alpha() { + return color >>> 24; + } + + public int red() { + return (color >> 16) & 0xFF; + } + + public int green() { + return (color >> 8) & 0xFF; + } + + public int blue() { + return color & 0xFF; + } + + public String toHexColor() { + return String.format("#%08x", color); + } +} diff --git a/lib/src/main/java/org/asamk/signal/manager/api/MessageEnvelope.java b/lib/src/main/java/org/asamk/signal/manager/api/MessageEnvelope.java index d2164e91..a3546a4b 100644 --- a/lib/src/main/java/org/asamk/signal/manager/api/MessageEnvelope.java +++ b/lib/src/main/java/org/asamk/signal/manager/api/MessageEnvelope.java @@ -15,6 +15,8 @@ import org.whispersystems.signalservice.api.messages.SignalServiceGroup; import org.whispersystems.signalservice.api.messages.SignalServiceGroupContext; import org.whispersystems.signalservice.api.messages.SignalServicePreview; import org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage; +import org.whispersystems.signalservice.api.messages.SignalServiceStoryMessage; +import org.whispersystems.signalservice.api.messages.SignalServiceTextAttachment; import org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage; import org.whispersystems.signalservice.api.messages.calls.AnswerMessage; import org.whispersystems.signalservice.api.messages.calls.BusyMessage; @@ -49,7 +51,8 @@ public record MessageEnvelope( Optional typing, Optional data, Optional sync, - Optional call + Optional call, + Optional story ) { public record Receipt(long when, Type type, List timestamps) { @@ -94,6 +97,7 @@ public record MessageEnvelope( public record Data( long timestamp, Optional groupContext, + Optional storyContext, Optional groupCallUpdate, Optional body, int expiresInSeconds, @@ -121,6 +125,10 @@ public record MessageEnvelope( ) { return new Data(dataMessage.getTimestamp(), dataMessage.getGroupContext().map(GroupContext::from), + dataMessage.getStoryContext() + .map((SignalServiceDataMessage.StoryContext storyContext) -> StoryContext.from(storyContext, + recipientResolver, + addressResolver)), dataMessage.getGroupCallUpdate().map(GroupCallUpdate::from), dataMessage.getBody(), dataMessage.getExpiresInSeconds(), @@ -168,6 +176,18 @@ public record MessageEnvelope( } } + public record StoryContext(RecipientAddress author, long sentTimestamp) { + + static StoryContext from( + SignalServiceDataMessage.StoryContext storyContext, + RecipientResolver recipientResolver, + RecipientAddressResolver addressResolver + ) { + return new StoryContext(addressResolver.resolveRecipientAddress(recipientResolver.resolveRecipient( + storyContext.getAuthorServiceId())), storyContext.getSentTimestamp()); + } + } + public record GroupCallUpdate(String eraId) { static GroupCallUpdate from(SignalServiceDataMessage.GroupCallUpdate groupCallUpdate) { @@ -519,7 +539,8 @@ public record MessageEnvelope( long expirationStartTimestamp, Optional destination, Set recipients, - Optional message + Optional message, + Optional story ) { static Sent from( @@ -537,7 +558,8 @@ public record MessageEnvelope( .map(d -> addressResolver.resolveRecipientAddress(recipientResolver.resolveRecipient(d))) .collect(Collectors.toSet()), sentMessage.getDataMessage() - .map(message -> Data.from(message, recipientResolver, addressResolver, fileProvider))); + .map(message -> Data.from(message, recipientResolver, addressResolver, fileProvider)), + sentMessage.getStoryMessage().map(s -> Story.from(s, fileProvider))); } } @@ -757,6 +779,75 @@ public record MessageEnvelope( } } + public record Story( + boolean allowsReplies, + Optional groupId, + Optional fileAttachment, + Optional textAttachment + ) { + + public static Story from( + SignalServiceStoryMessage storyMessage, final AttachmentFileProvider fileProvider + ) { + return new Story(storyMessage.getAllowsReplies().orElse(false), + storyMessage.getGroupContext().map(c -> GroupUtils.getGroupIdV2(c.getMasterKey())), + storyMessage.getFileAttachment().map(f -> Data.Attachment.from(f, fileProvider)), + storyMessage.getTextAttachment().map(t -> TextAttachment.from(t, fileProvider))); + } + + public record TextAttachment( + Optional text, + Optional