1 package org
.asamk
.signal
.commands
;
3 import com
.fasterxml
.jackson
.annotation
.JsonInclude
;
5 import net
.sourceforge
.argparse4j
.inf
.Namespace
;
6 import net
.sourceforge
.argparse4j
.inf
.Subparser
;
8 import org
.asamk
.signal
.commands
.exceptions
.CommandException
;
9 import org
.asamk
.signal
.commands
.exceptions
.IOErrorException
;
10 import org
.asamk
.signal
.commands
.exceptions
.RateLimitErrorException
;
11 import org
.asamk
.signal
.manager
.Manager
;
12 import org
.asamk
.signal
.manager
.api
.RateLimitException
;
13 import org
.asamk
.signal
.manager
.api
.UserStatus
;
14 import org
.asamk
.signal
.manager
.api
.UsernameStatus
;
15 import org
.asamk
.signal
.output
.JsonWriter
;
16 import org
.asamk
.signal
.output
.OutputWriter
;
17 import org
.asamk
.signal
.output
.PlainTextWriter
;
18 import org
.asamk
.signal
.util
.CommandUtil
;
19 import org
.slf4j
.Logger
;
20 import org
.slf4j
.LoggerFactory
;
22 import java
.io
.IOException
;
23 import java
.util
.HashSet
;
25 import java
.util
.stream
.Stream
;
27 public class GetUserStatusCommand
implements JsonRpcLocalCommand
{
29 private static final Logger logger
= LoggerFactory
.getLogger(GetUserStatusCommand
.class);
32 public String
getName() {
33 return "getUserStatus";
37 public void attachToSubparser(final Subparser subparser
) {
38 subparser
.help("Check if the specified phone number/s have been registered");
39 subparser
.addArgument("recipient").help("Phone number").nargs("*");
40 subparser
.addArgument("--username").help("Specify the recipient username or username link.").nargs("*");
44 public void handleCommand(
45 final Namespace ns
, final Manager m
, final OutputWriter outputWriter
46 ) throws CommandException
{
47 // Get a map of registration statuses
48 Map
<String
, UserStatus
> registered
;
50 registered
= m
.getUserStatus(new HashSet
<>(ns
.getList("recipient")));
51 } catch (RateLimitException e
) {
52 final var message
= CommandUtil
.getRateLimitMessage(e
);
53 throw new RateLimitErrorException(message
, e
);
54 } catch (IOException e
) {
55 throw new IOErrorException("Unable to check if users are registered: "
58 + e
.getClass().getSimpleName()
62 final var usernames
= ns
.<String
>getList("username");
63 final var registeredUsernames
= usernames
== null
64 ? Map
.<String
, UsernameStatus
>of()
65 : m
.getUsernameStatus(new HashSet
<>(usernames
));
68 switch (outputWriter
) {
69 case JsonWriter writer
-> {
70 var jsonUserStatuses
= Stream
.concat(registered
.entrySet().stream().map(entry
-> {
71 final var number
= entry
.getValue().number();
72 final var uuid
= entry
.getValue().uuid();
73 return new JsonUserStatus(entry
.getKey(),
76 uuid
== null ?
null : uuid
.toString(),
78 }), registeredUsernames
.entrySet().stream().map(entry
-> {
79 final var username
= entry
.getValue().username();
80 final var uuid
= entry
.getValue().uuid();
81 return new JsonUserStatus(entry
.getKey(),
84 uuid
== null ?
null : uuid
.toString(),
87 writer
.write(jsonUserStatuses
);
89 case PlainTextWriter writer
-> {
90 for (var entry
: registered
.entrySet()) {
91 final var userStatus
= entry
.getValue();
92 writer
.println("{}: {}{}",
94 userStatus
.uuid() != null,
95 userStatus
.unrestrictedUnidentifiedAccess() ?
" (unrestricted sealed sender)" : "");
97 for (var entry
: registeredUsernames
.entrySet()) {
98 final var userStatus
= entry
.getValue();
99 writer
.println("{}: {}{}",
101 userStatus
.uuid() != null,
102 userStatus
.unrestrictedUnidentifiedAccess() ?
" (unrestricted sealed sender)" : "");
108 private record JsonUserStatus(
110 @JsonInclude(JsonInclude
.Include
.NON_NULL
) String number
,
111 @JsonInclude(JsonInclude
.Include
.NON_NULL
) String username
,