1 package org
.asamk
.signal
.commands
;
3 import net
.sourceforge
.argparse4j
.impl
.Arguments
;
4 import net
.sourceforge
.argparse4j
.inf
.Namespace
;
5 import net
.sourceforge
.argparse4j
.inf
.Subparser
;
7 import org
.asamk
.Signal
;
8 import org
.asamk
.signal
.JsonReceiveMessageHandler
;
9 import org
.asamk
.signal
.JsonWriter
;
10 import org
.asamk
.signal
.OutputType
;
11 import org
.asamk
.signal
.OutputWriter
;
12 import org
.asamk
.signal
.PlainTextWriter
;
13 import org
.asamk
.signal
.ReceiveMessageHandler
;
14 import org
.asamk
.signal
.commands
.exceptions
.CommandException
;
15 import org
.asamk
.signal
.commands
.exceptions
.IOErrorException
;
16 import org
.asamk
.signal
.commands
.exceptions
.UnexpectedErrorException
;
17 import org
.asamk
.signal
.json
.JsonMessageEnvelope
;
18 import org
.asamk
.signal
.manager
.Manager
;
19 import org
.asamk
.signal
.util
.DateUtils
;
20 import org
.freedesktop
.dbus
.DBusMap
;
21 import org
.freedesktop
.dbus
.connections
.impl
.DBusConnection
;
22 import org
.freedesktop
.dbus
.exceptions
.DBusException
;
23 import org
.freedesktop
.dbus
.types
.Variant
;
24 import org
.slf4j
.Logger
;
25 import org
.slf4j
.LoggerFactory
;
27 import java
.io
.IOException
;
28 import java
.util
.Base64
;
29 import java
.util
.List
;
31 import java
.util
.concurrent
.TimeUnit
;
33 public class ReceiveCommand
implements ExtendedDbusCommand
, LocalCommand
{
35 private final static Logger logger
= LoggerFactory
.getLogger(ReceiveCommand
.class);
38 public String
getName() {
43 public void attachToSubparser(final Subparser subparser
) {
44 subparser
.help("Query the server for new messages.");
45 subparser
.addArgument("-t", "--timeout")
48 .help("Number of seconds to wait for new messages (negative values disable timeout)");
49 subparser
.addArgument("--ignore-attachments")
50 .help("Don’t download attachments of received messages.")
51 .action(Arguments
.storeTrue());
55 public List
<OutputType
> getSupportedOutputTypes() {
56 return List
.of(OutputType
.PLAIN_TEXT
, OutputType
.JSON
);
59 public void handleCommand(
60 final Namespace ns
, final Signal signal
, DBusConnection dbusconnection
, final OutputWriter outputWriter
61 ) throws CommandException
{
63 if (outputWriter
instanceof JsonWriter jsonWriter
) {
65 dbusconnection
.addSigHandler(Signal
.MessageReceived
.class, signal
, messageReceived
-> {
66 var envelope
= JsonMessageEnvelope
.from(messageReceived
);
67 final var object
= Map
.of("envelope", envelope
);
68 jsonWriter
.write(object
);
71 dbusconnection
.addSigHandler(Signal
.ReceiptReceived
.class, signal
, receiptReceived
-> {
72 var envelope
= JsonMessageEnvelope
.from(receiptReceived
);
73 final var object
= Map
.of("envelope", envelope
);
74 jsonWriter
.write(object
);
77 dbusconnection
.addSigHandler(Signal
.SyncMessageReceived
.class, signal
, syncReceived
-> {
78 var envelope
= JsonMessageEnvelope
.from(syncReceived
);
79 final var object
= Map
.of("envelope", envelope
);
80 jsonWriter
.write(object
);
83 final var writer
= (PlainTextWriter
) outputWriter
;
85 dbusconnection
.addSigHandler(Signal
.MessageReceivedV2
.class, signal
, messageReceived
-> {
86 writer
.println("Envelope from: {}", messageReceived
.getSender());
87 writer
.println("Timestamp: {}", DateUtils
.formatTimestamp(messageReceived
.getTimestamp()));
88 writer
.println("Body: {}", messageReceived
.getMessage());
89 if (messageReceived
.getGroupId().length
> 0) {
90 writer
.println("Group info:");
91 writer
.indentedWriter()
92 .println("Id: {}", Base64
.getEncoder().encodeToString(messageReceived
.getGroupId()));
94 final var extras
= messageReceived
.getExtras();
95 printMessageExtras(writer
, extras
);
99 dbusconnection
.addSigHandler(Signal
.ReceiptReceivedV2
.class, signal
, receiptReceived
-> {
100 writer
.println("Receipt from: {}", receiptReceived
.getSender());
101 writer
.println("Timestamp: {}", DateUtils
.formatTimestamp(receiptReceived
.getTimestamp()));
102 writer
.println("Type: {}", receiptReceived
.getReceiptType());
105 dbusconnection
.addSigHandler(Signal
.SyncMessageReceivedV2
.class, signal
, syncReceived
-> {
106 writer
.println("Sync Envelope from: {} to: {}",
107 syncReceived
.getSource(),
108 syncReceived
.getDestination());
109 writer
.println("Timestamp: {}", DateUtils
.formatTimestamp(syncReceived
.getTimestamp()));
110 writer
.println("Body: {}", syncReceived
.getMessage());
111 if (syncReceived
.getGroupId().length
> 0) {
112 writer
.println("Group info:");
113 writer
.indentedWriter()
114 .println("Id: {}", Base64
.getEncoder().encodeToString(syncReceived
.getGroupId()));
116 final var extras
= syncReceived
.getExtras();
117 printMessageExtras(writer
, extras
);
121 } catch (DBusException e
) {
122 logger
.error("Dbus client failed", e
);
123 throw new UnexpectedErrorException("Dbus client failed", e
);
126 double timeout
= ns
.getDouble("timeout");
127 long timeoutMilliseconds
= timeout
< 0 ?
10000 : (long) (timeout
* 1000);
131 Thread
.sleep(timeoutMilliseconds
);
132 } catch (InterruptedException ignored
) {
141 private void printMessageExtras(final PlainTextWriter writer
, final Map
<String
, Variant
<?
>> extras
) {
142 if (extras
.containsKey("attachments")) {
143 final List
<DBusMap
<String
, Variant
<?
>>> attachments
= getValue(extras
, "attachments");
144 if (attachments
.size() > 0) {
145 writer
.println("Attachments:");
146 for (var attachment
: attachments
) {
147 final String value
= getValue(attachment
, "file");
148 writer
.println("- Stored plaintext in: {}", value
);
154 @SuppressWarnings("unchecked")
155 private <T
> T
getValue(final Map
<String
, Variant
<?
>> stringVariantMap
, final String field
) {
156 return (T
) stringVariantMap
.get(field
).getValue();
160 public void handleCommand(
161 final Namespace ns
, final Manager m
, final OutputWriter outputWriter
162 ) throws CommandException
{
163 double timeout
= ns
.getDouble("timeout");
164 boolean ignoreAttachments
= Boolean
.TRUE
.equals(ns
.getBoolean("ignore-attachments"));
165 m
.setIgnoreAttachments(ignoreAttachments
);
167 final var handler
= outputWriter
instanceof JsonWriter ?
new JsonReceiveMessageHandler(m
,
168 (JsonWriter
) outputWriter
) : new ReceiveMessageHandler(m
, (PlainTextWriter
) outputWriter
);
170 m
.receiveMessages(handler
);
172 m
.receiveMessages((long) (timeout
* 1000), TimeUnit
.MILLISECONDS
, handler
);
174 } catch (IOException e
) {
175 throw new IOErrorException("Error while receiving messages: " + e
.getMessage(), e
);