From 5ed9db4f08e52ed0c42cb42740f85d2ad346e13c Mon Sep 17 00:00:00 2001 From: AsamK Date: Sun, 30 Oct 2022 18:18:21 +0100 Subject: [PATCH] Implement replying to stories --- client/src/cli.rs | 6 ++++++ client/src/jsonrpc.rs | 2 ++ client/src/main.rs | 4 ++++ .../org/asamk/signal/manager/ManagerImpl.java | 8 ++++++++ .../org/asamk/signal/manager/api/Message.java | 5 ++++- man/signal-cli.1.adoc | 6 ++++++ .../asamk/signal/commands/SendCommand.java | 20 +++++++++++++++++-- .../org/asamk/signal/dbus/DbusSignalImpl.java | 9 ++++++--- 8 files changed, 54 insertions(+), 6 deletions(-) diff --git a/client/src/cli.rs b/client/src/cli.rs index 23d9e914..ca809290 100644 --- a/client/src/cli.rs +++ b/client/src/cli.rs @@ -162,6 +162,12 @@ pub enum CliCommands { #[arg(long)] sticker: Option, + + #[arg(long)] + story_timestamp: Option, + + #[arg(long)] + story_author: Option, }, SendContacts, SendPaymentNotification { diff --git a/client/src/jsonrpc.rs b/client/src/jsonrpc.rs index 5881a1ac..51e41c19 100644 --- a/client/src/jsonrpc.rs +++ b/client/src/jsonrpc.rs @@ -130,6 +130,8 @@ pub trait Rpc { #[allow(non_snake_case)] quoteMessage: Option, #[allow(non_snake_case)] quoteMention: Vec, sticker: Option, + #[allow(non_snake_case)] storyTimestamp: Option, + #[allow(non_snake_case)] storyAuthor: Option, ) -> Result; #[rpc(name = "sendContacts", params = "named")] diff --git a/client/src/main.rs b/client/src/main.rs index 29512953..ea9cb9c8 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -127,6 +127,8 @@ async fn main() -> Result<(), anyhow::Error> { quote_message, quote_mention, sticker, + story_timestamp, + story_author, } => { client .send( @@ -143,6 +145,8 @@ async fn main() -> Result<(), anyhow::Error> { quote_message, quote_mention, sticker, + story_timestamp, + story_author, ) .await } diff --git a/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java index 95aba4c4..4ffeb99f 100644 --- a/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java @@ -624,6 +624,14 @@ class ManagerImpl implements Manager { } messageBuilder.withPreviews(previews); } + if (message.storyReply().isPresent()) { + final var storyReply = message.storyReply().get(); + final var authorServiceId = context.getRecipientHelper() + .resolveSignalServiceAddress(context.getRecipientHelper().resolveRecipient(storyReply.author())) + .getServiceId(); + messageBuilder.withStoryContext(new SignalServiceDataMessage.StoryContext(authorServiceId, + storyReply.timestamp())); + } } private ArrayList resolveMentions(final List mentionList) throws UnregisteredRecipientException { diff --git a/lib/src/main/java/org/asamk/signal/manager/api/Message.java b/lib/src/main/java/org/asamk/signal/manager/api/Message.java index 1e76faea..aba79cc5 100644 --- a/lib/src/main/java/org/asamk/signal/manager/api/Message.java +++ b/lib/src/main/java/org/asamk/signal/manager/api/Message.java @@ -9,7 +9,8 @@ public record Message( List mentions, Optional quote, Optional sticker, - List previews + List previews, + Optional storyReply ) { public record Mention(RecipientIdentifier.Single recipient, int start, int length) {} @@ -19,4 +20,6 @@ public record Message( public record Sticker(byte[] packId, int stickerId) {} public record Preview(String url, String title, String description, Optional image) {} + + public record StoryReply(long timestamp, RecipientIdentifier.Single author) {} } diff --git a/man/signal-cli.1.adoc b/man/signal-cli.1.adoc index 4509f08f..5b3af7c1 100644 --- a/man/signal-cli.1.adoc +++ b/man/signal-cli.1.adoc @@ -275,6 +275,12 @@ Specify the description for the link preview (optional). *--preview-image*:: Specify the image file for the link preview (optional). +*--story-timestamp*:: +Specify the timestamp of a story to reply to. + +*--story-author*:: +Specify the number of the author of the story. + *-e*, *--end-session*:: Clear session state and send end session message. diff --git a/src/main/java/org/asamk/signal/commands/SendCommand.java b/src/main/java/org/asamk/signal/commands/SendCommand.java index 3fd00eaf..2a47ab8d 100644 --- a/src/main/java/org/asamk/signal/commands/SendCommand.java +++ b/src/main/java/org/asamk/signal/commands/SendCommand.java @@ -80,6 +80,10 @@ public class SendCommand implements JsonRpcLocalCommand { subparser.addArgument("--preview-title").help("Specify the title for the link preview (mandatory)."); subparser.addArgument("--preview-description").help("Specify the description for the link preview (optional)."); subparser.addArgument("--preview-image").help("Specify the image file for the link preview (optional)."); + subparser.addArgument("--story-timestamp") + .type(long.class) + .help("Specify the timestamp of a story to reply to."); + subparser.addArgument("--story-author").help("Specify the number of the author of the story."); } @Override @@ -170,18 +174,30 @@ public class SendCommand implements JsonRpcLocalCommand { previews = List.of(); } + final Message.StoryReply storyReply; + final var storyReplyTimestamp = ns.getLong("story-timestamp"); + if (storyReplyTimestamp != null) { + final var storyAuthor = ns.getString("story-author"); + storyReply = new Message.StoryReply(storyReplyTimestamp, + CommandUtil.getSingleRecipientIdentifier(storyAuthor, m.getSelfNumber())); + } else { + storyReply = null; + } + if (messageText.isEmpty() && attachments.isEmpty() && sticker == null && quote == null) { throw new UserErrorException( "Sending empty message is not allowed, either a message, attachment or sticker must be given."); } try { - var results = m.sendMessage(new Message(messageText, + final var message = new Message(messageText, attachments, mentions, Optional.ofNullable(quote), Optional.ofNullable(sticker), - previews), recipientIdentifiers); + previews, + Optional.ofNullable((storyReply))); + var results = m.sendMessage(message, recipientIdentifiers); outputResult(outputWriter, results); } catch (AttachmentInvalidException | IOException e) { throw new UnexpectedErrorException("Failed to send message: " + e.getMessage() + " (" + e.getClass() diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index c19daadf..1a9118be 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -218,7 +218,8 @@ public class DbusSignalImpl implements Signal { List.of(), Optional.empty(), Optional.empty(), - List.of()), + List.of(), + Optional.empty()), getSingleRecipientIdentifiers(recipients, m.getSelfNumber()).stream() .map(RecipientIdentifier.class::cast) .collect(Collectors.toSet())); @@ -386,7 +387,8 @@ public class DbusSignalImpl implements Signal { List.of(), Optional.empty(), Optional.empty(), - List.of()), Set.of(RecipientIdentifier.NoteToSelf.INSTANCE)); + List.of(), + Optional.empty()), Set.of(RecipientIdentifier.NoteToSelf.INSTANCE)); checkSendMessageResults(results); return results.timestamp(); } catch (AttachmentInvalidException e) { @@ -428,7 +430,8 @@ public class DbusSignalImpl implements Signal { List.of(), Optional.empty(), Optional.empty(), - List.of()), Set.of(getGroupRecipientIdentifier(groupId))); + List.of(), + Optional.empty()), Set.of(getGroupRecipientIdentifier(groupId))); checkSendMessageResults(results); return results.timestamp(); } catch (IOException | InvalidStickerException e) { -- 2.50.1