1 package org
.asamk
.signal
.commands
;
3 import com
.fasterxml
.jackson
.core
.type
.TypeReference
;
5 import net
.sourceforge
.argparse4j
.impl
.Arguments
;
6 import net
.sourceforge
.argparse4j
.inf
.Namespace
;
7 import net
.sourceforge
.argparse4j
.inf
.Subparser
;
9 import org
.asamk
.signal
.OutputType
;
10 import org
.asamk
.signal
.ReceiveMessageHandler
;
11 import org
.asamk
.signal
.Shutdown
;
12 import org
.asamk
.signal
.commands
.exceptions
.CommandException
;
13 import org
.asamk
.signal
.commands
.exceptions
.IOErrorException
;
14 import org
.asamk
.signal
.commands
.exceptions
.UserErrorException
;
15 import org
.asamk
.signal
.json
.JsonReceiveMessageHandler
;
16 import org
.asamk
.signal
.manager
.Manager
;
17 import org
.asamk
.signal
.manager
.api
.AlreadyReceivingException
;
18 import org
.asamk
.signal
.manager
.api
.ReceiveConfig
;
19 import org
.asamk
.signal
.output
.JsonWriter
;
20 import org
.asamk
.signal
.output
.OutputWriter
;
21 import org
.asamk
.signal
.output
.PlainTextWriter
;
22 import org
.slf4j
.Logger
;
23 import org
.slf4j
.LoggerFactory
;
25 import java
.io
.IOException
;
26 import java
.time
.Duration
;
27 import java
.util
.ArrayList
;
28 import java
.util
.List
;
29 import java
.util
.Optional
;
31 public class ReceiveCommand
implements LocalCommand
, JsonRpcSingleCommand
<ReceiveCommand
.ReceiveParams
> {
33 private static final Logger logger
= LoggerFactory
.getLogger(ReceiveCommand
.class);
36 public String
getName() {
41 public void attachToSubparser(final Subparser subparser
) {
42 subparser
.help("Query the server for new messages.");
43 subparser
.addArgument("-t", "--timeout")
46 .help("Number of seconds to wait for new messages (negative values disable timeout)");
47 subparser
.addArgument("--max-messages")
50 .help("Maximum number of messages to receive, before returning.");
51 subparser
.addArgument("--ignore-attachments")
52 .help("Don’t download attachments of received messages.")
53 .action(Arguments
.storeTrue());
54 subparser
.addArgument("--ignore-stories")
55 .help("Don’t receive story messages from the server.")
56 .action(Arguments
.storeTrue());
57 subparser
.addArgument("--send-read-receipts")
58 .help("Send read receipts for all incoming data messages (in addition to the default delivery receipts)")
59 .action(Arguments
.storeTrue());
63 public List
<OutputType
> getSupportedOutputTypes() {
64 return List
.of(OutputType
.PLAIN_TEXT
, OutputType
.JSON
);
68 public void handleCommand(
69 final Namespace ns
, final Manager m
, final OutputWriter outputWriter
70 ) throws CommandException
{
71 Shutdown
.installHandler();
72 final var timeout
= ns
.getDouble("timeout");
73 final var maxMessagesRaw
= ns
.getInt("max-messages");
74 final var ignoreAttachments
= Boolean
.TRUE
.equals(ns
.getBoolean("ignore-attachments"));
75 final var ignoreStories
= Boolean
.TRUE
.equals(ns
.getBoolean("ignore-stories"));
76 final var sendReadReceipts
= Boolean
.TRUE
.equals(ns
.getBoolean("send-read-receipts"));
77 m
.setReceiveConfig(new ReceiveConfig(ignoreAttachments
, ignoreStories
, sendReadReceipts
));
79 final var handler
= switch (outputWriter
) {
80 case JsonWriter writer
-> new JsonReceiveMessageHandler(m
, writer
);
81 case PlainTextWriter writer
-> new ReceiveMessageHandler(m
, writer
);
83 final var duration
= timeout
< 0 ?
null : Duration
.ofMillis((long) (timeout
* 1000));
84 final var maxMessages
= maxMessagesRaw
< 0 ?
null : maxMessagesRaw
;
85 Shutdown
.registerShutdownListener(m
::stopReceiveMessages
);
86 m
.receiveMessages(Optional
.ofNullable(duration
), Optional
.ofNullable(maxMessages
), handler
);
87 } catch (IOException e
) {
88 throw new IOErrorException("Error while receiving messages: " + e
.getMessage(), e
);
89 } catch (AlreadyReceivingException e
) {
90 throw new UserErrorException("Receive command cannot be used if messages are already being received.", e
);
95 public TypeReference
<ReceiveParams
> getRequestType() {
96 return new TypeReference
<>() {};
100 public void handleCommand(
101 final ReceiveParams request
, final Manager m
, final JsonWriter jsonWriter
102 ) throws CommandException
{
103 final var timeout
= request
.timeout() == null ?
3.0 : request
.timeout();
104 final var maxMessagesRaw
= request
.maxMessages() == null ?
-1 : request
.maxMessages();
107 final var messages
= new ArrayList
<>();
108 final var handler
= new JsonReceiveMessageHandler(m
, messages
::add
);
109 final var duration
= timeout
< 0 ?
null : Duration
.ofMillis((long) (timeout
* 1000));
110 final var maxMessages
= maxMessagesRaw
< 0 ?
null : maxMessagesRaw
;
111 m
.receiveMessages(Optional
.ofNullable(duration
), Optional
.ofNullable(maxMessages
), handler
);
112 jsonWriter
.write(messages
);
113 } catch (IOException e
) {
114 throw new IOErrorException("Error while receiving messages: " + e
.getMessage(), e
);
115 } catch (AlreadyReceivingException e
) {
116 throw new UserErrorException("Receive command cannot be used if messages are already being received.", e
);
120 public record ReceiveParams(Double timeout
, Integer maxMessages
) {}