1 package org
.asamk
.signal
.util
;
3 import org
.asamk
.signal
.json
.JsonSendMessageResult
;
4 import org
.asamk
.signal
.manager
.api
.ProofRequiredException
;
5 import org
.asamk
.signal
.manager
.api
.RecipientIdentifier
;
6 import org
.asamk
.signal
.manager
.api
.SendGroupMessageResults
;
7 import org
.asamk
.signal
.manager
.api
.SendMessageResult
;
8 import org
.asamk
.signal
.manager
.api
.SendMessageResults
;
9 import org
.asamk
.signal
.output
.JsonWriter
;
10 import org
.asamk
.signal
.output
.OutputWriter
;
11 import org
.asamk
.signal
.output
.PlainTextWriter
;
13 import java
.util
.Collection
;
14 import java
.util
.List
;
16 import java
.util
.Objects
;
17 import java
.util
.stream
.Collectors
;
19 public class SendMessageResultUtils
{
21 private SendMessageResultUtils() {
24 public static void outputResult(final OutputWriter outputWriter
, final SendGroupMessageResults sendMessageResults
) {
25 if (outputWriter
instanceof PlainTextWriter writer
) {
26 var errors
= getErrorMessagesFromSendMessageResults(sendMessageResults
.results());
27 printSendMessageResultErrors(writer
, errors
);
28 writer
.println("{}", sendMessageResults
.timestamp());
30 final var writer
= (JsonWriter
) outputWriter
;
31 var results
= getJsonSendMessageResults(sendMessageResults
.results());
32 writer
.write(Map
.of("timestamp", sendMessageResults
.timestamp(), "results", results
));
36 public static void outputResult(final OutputWriter outputWriter
, final SendMessageResults sendMessageResults
) {
37 if (outputWriter
instanceof PlainTextWriter writer
) {
38 var errors
= getErrorMessagesFromSendMessageResults(sendMessageResults
.results());
39 printSendMessageResultErrors(writer
, errors
);
40 writer
.println("{}", sendMessageResults
.timestamp());
42 final var writer
= (JsonWriter
) outputWriter
;
43 var results
= getJsonSendMessageResults(sendMessageResults
.results());
44 writer
.write(Map
.of("timestamp", sendMessageResults
.timestamp(), "results", results
));
48 public static List
<String
> getErrorMessagesFromSendMessageResults(final Map
<RecipientIdentifier
, List
<SendMessageResult
>> mapResults
) {
49 return mapResults
.entrySet()
51 .flatMap(entry
-> entry
.getValue()
53 .map(SendMessageResultUtils
::getErrorMessageFromSendMessageResult
)
54 .filter(Objects
::nonNull
)
55 .map(error
-> entry
.getKey().getIdentifier() + ": " + error
))
56 .collect(Collectors
.toList());
59 public static List
<String
> getErrorMessagesFromSendMessageResults(Collection
<SendMessageResult
> results
) {
60 return results
.stream()
61 .map(SendMessageResultUtils
::getErrorMessageFromSendMessageResult
)
62 .filter(Objects
::nonNull
)
63 .collect(Collectors
.toList());
66 public static String
getErrorMessageFromSendMessageResult(SendMessageResult result
) {
67 var identifier
= result
.address().getLegacyIdentifier();
68 if (result
.proofRequiredFailure() != null) {
69 final var failure
= result
.proofRequiredFailure();
71 "CAPTCHA proof required for sending to \"%s\", available options \"%s\" with challenge token \"%s\", or wait \"%d\" seconds.\n"
73 failure
.getOptions().contains(ProofRequiredException
.Option
.RECAPTCHA
)
75 To get the captcha token, go to https://signalcaptchas.org/challenge/generate.html
76 Check the developer tools (F12) console for a failed redirect to signalcaptcha://
77 Everything after signalcaptcha:// is the captcha token.
78 Use the following command to submit the captcha token:
79 signal-cli submitRateLimitChallenge --challenge CHALLENGE_TOKEN --captcha CAPTCHA_TOKEN"""
85 .map(ProofRequiredException
.Option
::toString
)
86 .collect(Collectors
.joining(", ")),
88 failure
.getRetryAfterSeconds());
89 } else if (result
.isNetworkFailure()) {
90 return String
.format("Network failure for \"%s\"", identifier
);
91 } else if (result
.isUnregisteredFailure()) {
92 return String
.format("Unregistered user \"%s\"", identifier
);
93 } else if (result
.isIdentityFailure()) {
94 return String
.format("Untrusted Identity for \"%s\"", identifier
);
99 public static void printSendMessageResultErrors(PlainTextWriter writer
, List
<String
> errors
) {
100 if (errors
.size() == 0) {
103 writer
.println("Failed to send (some) messages:");
104 for (var error
: errors
) {
105 writer
.println(error
);
109 public static List
<JsonSendMessageResult
> getJsonSendMessageResults(final Map
<RecipientIdentifier
, List
<SendMessageResult
>> mapResults
) {
110 return mapResults
.entrySet().stream().flatMap(entry
-> {
111 final var groupId
= entry
.getKey() instanceof RecipientIdentifier
.Group g ? g
.groupId() : null;
112 return entry
.getValue().stream().map(r
-> JsonSendMessageResult
.from(r
, groupId
));
113 }).collect(Collectors
.toList());
116 public static List
<JsonSendMessageResult
> getJsonSendMessageResults(Collection
<SendMessageResult
> results
) {
117 return results
.stream().map(JsonSendMessageResult
::from
).collect(Collectors
.toList());