]> nmode's Git Repositories - signal-cli/blob - src/main/java/org/asamk/signal/commands/SendCommand.java
Fix sendReaction to group (#580)
[signal-cli] / src / main / java / org / asamk / signal / commands / SendCommand.java
1 package org.asamk.signal.commands;
2
3 import net.sourceforge.argparse4j.impl.Arguments;
4 import net.sourceforge.argparse4j.inf.Namespace;
5 import net.sourceforge.argparse4j.inf.Subparser;
6
7 import org.asamk.Signal;
8 import org.asamk.signal.PlainTextWriterImpl;
9 import org.asamk.signal.commands.exceptions.CommandException;
10 import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
11 import org.asamk.signal.commands.exceptions.UntrustedKeyErrorException;
12 import org.asamk.signal.commands.exceptions.UserErrorException;
13 import org.asamk.signal.manager.groups.GroupIdFormatException;
14 import org.asamk.signal.util.IOUtils;
15 import org.asamk.signal.util.Util;
16 import org.freedesktop.dbus.errors.UnknownObject;
17 import org.freedesktop.dbus.exceptions.DBusExecutionException;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20
21 import java.io.IOException;
22 import java.nio.charset.Charset;
23 import java.util.List;
24
25 import static org.asamk.signal.util.ErrorUtils.handleAssertionError;
26
27 public class SendCommand implements DbusCommand {
28
29 private final static Logger logger = LoggerFactory.getLogger(SendCommand.class);
30
31 @Override
32 public void attachToSubparser(final Subparser subparser) {
33 subparser.addArgument("recipient").help("Specify the recipients' phone number.").nargs("*");
34 final var mutuallyExclusiveGroup = subparser.addMutuallyExclusiveGroup();
35 mutuallyExclusiveGroup.addArgument("-g", "--group").help("Specify the recipient group ID.");
36 mutuallyExclusiveGroup.addArgument("--note-to-self")
37 .help("Send the message to self without notification.")
38 .action(Arguments.storeTrue());
39
40 subparser.addArgument("-m", "--message").help("Specify the message, if missing standard input is used.");
41 subparser.addArgument("-a", "--attachment").nargs("*").help("Add file as attachment");
42 subparser.addArgument("-e", "--endsession")
43 .help("Clear session state and send end session message.")
44 .action(Arguments.storeTrue());
45 }
46
47 @Override
48 public void handleCommand(final Namespace ns, final Signal signal) throws CommandException {
49 final List<String> recipients = ns.getList("recipient");
50 final var isEndSession = ns.getBoolean("endsession");
51 final var groupIdString = ns.getString("group");
52 final var isNoteToSelf = ns.getBoolean("note_to_self");
53
54 final var noRecipients = recipients == null || recipients.isEmpty();
55 if ((noRecipients && isEndSession) || (noRecipients && groupIdString == null && !isNoteToSelf)) {
56 throw new UserErrorException("No recipients given");
57 }
58 if (!noRecipients && groupIdString != null) {
59 throw new UserErrorException("You cannot specify recipients by phone number and groups at the same time");
60 }
61 if (!noRecipients && isNoteToSelf) {
62 throw new UserErrorException(
63 "You cannot specify recipients by phone number and not to self at the same time");
64 }
65
66 if (isEndSession) {
67 try {
68 signal.sendEndSessionMessage(recipients);
69 return;
70 } catch (AssertionError e) {
71 handleAssertionError(e);
72 throw e;
73 } catch (Signal.Error.UntrustedIdentity e) {
74 throw new UntrustedKeyErrorException("Failed to send message: " + e.getMessage());
75 } catch (DBusExecutionException e) {
76 throw new UnexpectedErrorException("Failed to send message: " + e.getMessage());
77 }
78 }
79
80 var messageText = ns.getString("message");
81 if (messageText == null) {
82 try {
83 messageText = IOUtils.readAll(System.in, Charset.defaultCharset());
84 } catch (IOException e) {
85 throw new UserErrorException("Failed to read message from stdin: " + e.getMessage());
86 }
87 }
88
89 List<String> attachments = ns.getList("attachment");
90 if (attachments == null) {
91 attachments = List.of();
92 }
93
94 final var writer = new PlainTextWriterImpl(System.out);
95
96 if (groupIdString != null) {
97 byte[] groupId;
98 try {
99 groupId = Util.decodeGroupId(groupIdString).serialize();
100 } catch (GroupIdFormatException e) {
101 throw new UserErrorException("Invalid group id:" + e.getMessage());
102 }
103
104 try {
105 var timestamp = signal.sendGroupMessage(messageText, attachments, groupId);
106 writer.println("{}", timestamp);
107 return;
108 } catch (AssertionError e) {
109 handleAssertionError(e);
110 throw e;
111 } catch (DBusExecutionException e) {
112 throw new UnexpectedErrorException("Failed to send group message: " + e.getMessage());
113 }
114 }
115
116 if (isNoteToSelf) {
117 try {
118 var timestamp = signal.sendNoteToSelfMessage(messageText, attachments);
119 writer.println("{}", timestamp);
120 return;
121 } catch (AssertionError e) {
122 handleAssertionError(e);
123 throw e;
124 } catch (Signal.Error.UntrustedIdentity e) {
125 throw new UntrustedKeyErrorException("Failed to send message: " + e.getMessage());
126 } catch (DBusExecutionException e) {
127 throw new UnexpectedErrorException("Failed to send note to self message: " + e.getMessage());
128 }
129 }
130
131 try {
132 var timestamp = signal.sendMessage(messageText, attachments, recipients);
133 writer.println("{}", timestamp);
134 } catch (AssertionError e) {
135 handleAssertionError(e);
136 throw e;
137 } catch (UnknownObject e) {
138 throw new UserErrorException("Failed to find dbus object, maybe missing the -u flag: " + e.getMessage());
139 } catch (Signal.Error.UntrustedIdentity e) {
140 throw new UntrustedKeyErrorException("Failed to send message: " + e.getMessage());
141 } catch (DBusExecutionException e) {
142 throw new UnexpectedErrorException("Failed to send message: " + e.getMessage());
143 }
144 }
145 }