]> nmode's Git Repositories - signal-cli/commitdiff
Implement replying to stories
authorAsamK <asamk@gmx.de>
Sun, 30 Oct 2022 17:18:21 +0000 (18:18 +0100)
committerAsamK <asamk@gmx.de>
Sun, 30 Oct 2022 17:18:21 +0000 (18:18 +0100)
client/src/cli.rs
client/src/jsonrpc.rs
client/src/main.rs
lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java
lib/src/main/java/org/asamk/signal/manager/api/Message.java
man/signal-cli.1.adoc
src/main/java/org/asamk/signal/commands/SendCommand.java
src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java

index 23d9e9142611f2f61c0a588e9b26a6cf472868c4..ca80929017b31558083407009926afea4b928ec9 100644 (file)
@@ -162,6 +162,12 @@ pub enum CliCommands {
 
         #[arg(long)]
         sticker: Option<String>,
+
+        #[arg(long)]
+        story_timestamp: Option<u64>,
+
+        #[arg(long)]
+        story_author: Option<String>,
     },
     SendContacts,
     SendPaymentNotification {
index 5881a1ac5358fd99f1e6519ae05cbc261340ced1..51e41c198b68fa2eee10e6f65ea2e34d24a88bc4 100644 (file)
@@ -130,6 +130,8 @@ pub trait Rpc {
         #[allow(non_snake_case)] quoteMessage: Option<String>,
         #[allow(non_snake_case)] quoteMention: Vec<String>,
         sticker: Option<String>,
+        #[allow(non_snake_case)] storyTimestamp: Option<u64>,
+        #[allow(non_snake_case)] storyAuthor: Option<String>,
     ) -> Result<Value>;
 
     #[rpc(name = "sendContacts", params = "named")]
index 2951295314ff79a3cf5ff224495c8f0bb3f58caa..ea9cb9c83c1087a6b8d0553d945f9c9acefec87a 100644 (file)
@@ -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
         }
index 95aba4c4d862d5a9e46a1c53ffe818ea180b3652..4ffeb99fdd10a278f8ccef1a7e4f250397cca2a7 100644 (file)
@@ -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<SignalServiceDataMessage.Mention> resolveMentions(final List<Message.Mention> mentionList) throws UnregisteredRecipientException {
index 1e76faeaa041b8b3795c94dd5ef8537fda7cc120..aba79cc56325a88983826fca984ef87a5d962b73 100644 (file)
@@ -9,7 +9,8 @@ public record Message(
         List<Mention> mentions,
         Optional<Quote> quote,
         Optional<Sticker> sticker,
-        List<Preview> previews
+        List<Preview> previews,
+        Optional<StoryReply> 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<String> image) {}
+
+    public record StoryReply(long timestamp, RecipientIdentifier.Single author) {}
 }
index 4509f08f1a72e314ee5342469b57dae763223425..5b3af7c1df12deea2f20184ba17cc82142c03387 100644 (file)
@@ -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.
 
index 3fd00eaf0d07b27b40b9fdd172372b4f6997deeb..2a47ab8d0794d4d9e5212f56536290fdbad8f305 100644 (file)
@@ -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()
index c19daadffd670198006e303ce304cbebb2a7ba7b..1a9118be1f2065ce82134dca21908d81efa4fda1 100644 (file)
@@ -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) {