mirror of
https://github.com/AsamK/signal-cli
synced 2025-09-03 20:50:38 +00:00
Merge branch 'AsamK:master' into master
This commit is contained in:
commit
e3e7c87f2a
7 changed files with 361 additions and 7 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -11,3 +11,4 @@ local.properties
|
||||||
.settings/
|
.settings/
|
||||||
out/
|
out/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
/bin/
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
liberapay: asamk
|
liberapay: asamk
|
||||||
|
ko_fi: asamk
|
||||||
bitcoin: bc1qykae53fry8a8ycgdzgv0rlxfc959hmmllvz698
|
bitcoin: bc1qykae53fry8a8ycgdzgv0rlxfc959hmmllvz698
|
||||||
|
|
|
@ -81,15 +81,15 @@ dependencies. If you have a recent gradle version installed, you can replace `./
|
||||||
|
|
||||||
./gradlew build
|
./gradlew build
|
||||||
|
|
||||||
3. Create shell wrapper in *build/install/signal-cli/bin*:
|
3a. Create shell wrapper in *build/install/signal-cli/bin*:
|
||||||
|
|
||||||
./gradlew installDist
|
./gradlew installDist
|
||||||
|
|
||||||
4. Create tar file in *build/distributions*:
|
3b. Create tar file in *build/distributions*:
|
||||||
|
|
||||||
./gradlew distTar
|
./gradlew distTar
|
||||||
|
|
||||||
5. Compile and run signal-cli:
|
3c. Compile and run signal-cli:
|
||||||
|
|
||||||
./gradlew run --args="--help"
|
./gradlew run --args="--help"
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class RegistrationManager implements Closeable {
|
||||||
private final SignalServiceAccountManager accountManager;
|
private final SignalServiceAccountManager accountManager;
|
||||||
private final PinHelper pinHelper;
|
private final PinHelper pinHelper;
|
||||||
|
|
||||||
public RegistrationManager(
|
private RegistrationManager(
|
||||||
SignalAccount account,
|
SignalAccount account,
|
||||||
PathConfig pathConfig,
|
PathConfig pathConfig,
|
||||||
ServiceEnvironmentConfig serviceEnvironmentConfig,
|
ServiceEnvironmentConfig serviceEnvironmentConfig,
|
||||||
|
|
|
@ -33,6 +33,7 @@ Where <type> is according to DBus specification:
|
||||||
* <ay> : Byte Array
|
* <ay> : Byte Array
|
||||||
* <aay> : Array of Byte Arrays
|
* <aay> : Array of Byte Arrays
|
||||||
* <as> : String Array
|
* <as> : String Array
|
||||||
|
* <ax> : Array of signed 64 bit integer
|
||||||
* <b> : Boolean (0|1)
|
* <b> : Boolean (0|1)
|
||||||
* <x> : Signed 64 bit integer
|
* <x> : Signed 64 bit integer
|
||||||
* <> : no return value
|
* <> : no return value
|
||||||
|
@ -43,6 +44,64 @@ Phone numbers always have the format +<countrycode><regional number>
|
||||||
|
|
||||||
== Methods
|
== Methods
|
||||||
|
|
||||||
|
=== Control methods
|
||||||
|
These methods are available if the daemon is started anonymously (without an explicit `-u USERNAME`).
|
||||||
|
Requests are sent to `/org/asamk/Signal`; requests related to individual accounts are sent to
|
||||||
|
`/org/asamk/Signal/_441234567890` where the + dialing code is replaced by an underscore (_).
|
||||||
|
Only `version()` is activated in single-user mode; the rest are disabled.
|
||||||
|
|
||||||
|
link() -> deviceLinkUri<s>::
|
||||||
|
link(newDeviceName<s>) -> deviceLinkUri<s>::
|
||||||
|
* newDeviceName : Name to give new device (defaults to "cli" if no name is given)
|
||||||
|
* deviceLinkUri : URI of newly linked device
|
||||||
|
|
||||||
|
Returns a URI of the form "tsdevice:/?uuid=...". This can be piped to a QR encoder to create a display that
|
||||||
|
can be captured by a Signal smartphone client. For example:
|
||||||
|
|
||||||
|
`dbus-send --session --dest=org.asamk.Signal --type=method_call --print-reply /org/asamk/Signal org.asamk.Signal.link string:"My secondary client"|tr '\n' '\0'|sed 's/.*string //g'|sed 's/\"//g'|qrencode -s10 -tANSI256`
|
||||||
|
|
||||||
|
Exception: Failure
|
||||||
|
|
||||||
|
listAccounts() -> accountList<as>::
|
||||||
|
* accountList : Array of all attached accounts in DBus object path form
|
||||||
|
|
||||||
|
Exceptions: None
|
||||||
|
|
||||||
|
register(number<s>, voiceVerification<b>) -> <>::
|
||||||
|
* number : Phone number
|
||||||
|
* voiceVerification : true = use voice verification; false = use SMS verification
|
||||||
|
|
||||||
|
Exceptions: Failure, InvalidNumber, RequiresCaptcha
|
||||||
|
|
||||||
|
registerWithCaptcha(number<s>, voiceVerification<b>, captcha<s>) -> <>::
|
||||||
|
* number : Phone number
|
||||||
|
* voiceVerification : true = use voice verification; false = use SMS verification
|
||||||
|
* captcha : Captcha string
|
||||||
|
|
||||||
|
Exceptions: Failure, InvalidNumber, RequiresCaptcha
|
||||||
|
|
||||||
|
verify(number<s>, verificationCode<s>) -> <>::
|
||||||
|
* number : Phone number
|
||||||
|
* verificationCode : Code received from Signal after successful registration request
|
||||||
|
|
||||||
|
Command fails if PIN was set after previous registration; use verifyWithPin instead.
|
||||||
|
|
||||||
|
Exception: Failure, InvalidNumber
|
||||||
|
|
||||||
|
verifyWithPin(number<s>, verificationCode<s>, pin<s>) -> <>::
|
||||||
|
* number : Phone number
|
||||||
|
* verificationCode : Code received from Signal after successful registration request
|
||||||
|
* pin : PIN you set with setPin command after verifying previous registration
|
||||||
|
|
||||||
|
Exception: Failure, InvalidNumber
|
||||||
|
|
||||||
|
version() -> version<s>::
|
||||||
|
* version : Version string of signal-cli
|
||||||
|
|
||||||
|
Exceptions: None
|
||||||
|
|
||||||
|
=== Other methods
|
||||||
|
|
||||||
updateGroup(groupId<ay>, newName<s>, members<as>, avatar<s>) -> groupId<ay>::
|
updateGroup(groupId<ay>, newName<s>, members<as>, avatar<s>) -> groupId<ay>::
|
||||||
* groupId : Byte array representing the internal group identifier
|
* groupId : Byte array representing the internal group identifier
|
||||||
* newName : New name of group (empty if unchanged)
|
* newName : New name of group (empty if unchanged)
|
||||||
|
@ -60,6 +119,13 @@ updateProfile(newName<s>, about <s>, aboutEmoji <s>, avatar<s>, remove<b>) -> <>
|
||||||
|
|
||||||
Exceptions: Failure
|
Exceptions: Failure
|
||||||
|
|
||||||
|
|
||||||
|
setExpirationTimer(number<s>, expiration<i>) -> <>::
|
||||||
|
* number : Phone number of recipient
|
||||||
|
* expiration : int32 for the number of seconds before messages to this recipient disappear. Set to 0 to disable expiration.
|
||||||
|
|
||||||
|
Exceptions: Failure
|
||||||
|
|
||||||
setContactBlocked(number<s>, block<b>) -> <>::
|
setContactBlocked(number<s>, block<b>) -> <>::
|
||||||
* number : Phone number affected by method
|
* number : Phone number affected by method
|
||||||
* block : 0=remove block , 1=blocked
|
* block : 0=remove block , 1=blocked
|
||||||
|
@ -106,6 +172,18 @@ sendGroupMessage(message<s>, attachments<as>, groupId<ay>) -> timestamp<x>::
|
||||||
|
|
||||||
Exceptions: GroupNotFound, Failure, AttachmentInvalid
|
Exceptions: GroupNotFound, Failure, AttachmentInvalid
|
||||||
|
|
||||||
|
sendContacts() -> <>::
|
||||||
|
|
||||||
|
Sends a synchronization message with the local contacts list to all linked devices. This command should only be used if this is the primary device.
|
||||||
|
|
||||||
|
Exceptions: Failure
|
||||||
|
|
||||||
|
sendSyncRequest() -> <>::
|
||||||
|
|
||||||
|
Sends a synchronization request to the primary device (for group, contacts, ...). Only works if sent from a secondary device.
|
||||||
|
|
||||||
|
Exception: Failure
|
||||||
|
|
||||||
sendNoteToSelfMessage(message<s>, attachments<as>) -> timestamp<x>::
|
sendNoteToSelfMessage(message<s>, attachments<as>) -> timestamp<x>::
|
||||||
* message : Text to send (can be UTF8)
|
* message : Text to send (can be UTF8)
|
||||||
* attachments : String array of filenames to send as attachments (passed as filename, so need to be readable by the user signal-cli is running under)
|
* attachments : String array of filenames to send as attachments (passed as filename, so need to be readable by the user signal-cli is running under)
|
||||||
|
@ -125,6 +203,19 @@ Depending on the type of the recipient field this sends a message to one or mult
|
||||||
|
|
||||||
Exceptions: AttachmentInvalid, Failure, InvalidNumber, UntrustedIdentity
|
Exceptions: AttachmentInvalid, Failure, InvalidNumber, UntrustedIdentity
|
||||||
|
|
||||||
|
sendTyping(recipient<s>, stop<b>) -> <>::
|
||||||
|
* recipient : Phone number of a single recipient
|
||||||
|
* targetSentTimestamp : True, if typing state should be stopped
|
||||||
|
|
||||||
|
Exceptions: Failure, GroupNotFound, UntrustedIdentity
|
||||||
|
|
||||||
|
|
||||||
|
sendReadReceipt(recipient<s>, targetSentTimestamp<ax>) -> <>::
|
||||||
|
* recipient : Phone number of a single recipient
|
||||||
|
* targetSentTimestamp : Array of Longs to identify the corresponding signal messages
|
||||||
|
|
||||||
|
Exceptions: Failure, UntrustedIdentity
|
||||||
|
|
||||||
sendGroupMessageReaction(emoji<s>, remove<b>, targetAuthor<s>, targetSentTimestamp<x>, groupId<ay>) -> timestamp<x>::
|
sendGroupMessageReaction(emoji<s>, remove<b>, targetAuthor<s>, targetSentTimestamp<x>, groupId<ay>) -> timestamp<x>::
|
||||||
* emoji : Unicode grapheme cluster of the emoji
|
* emoji : Unicode grapheme cluster of the emoji
|
||||||
* remove : Boolean, whether a previously sent reaction (emoji) should be removed
|
* remove : Boolean, whether a previously sent reaction (emoji) should be removed
|
||||||
|
@ -215,11 +306,59 @@ isGroupBlocked(groupId<ay>) -> state<b>::
|
||||||
|
|
||||||
Exceptions: None, for unknown groups 0 (false) is returned
|
Exceptions: None, for unknown groups 0 (false) is returned
|
||||||
|
|
||||||
|
removePin() -> <>::
|
||||||
|
|
||||||
|
Removes registration PIN protection.
|
||||||
|
|
||||||
|
Exception: Failure
|
||||||
|
|
||||||
|
setPin(pin<s>) -> <>::
|
||||||
|
* pin : PIN you set after registration (resets after 7 days of inactivity)
|
||||||
|
|
||||||
|
Sets a registration lock PIN, to prevent others from registering your number.
|
||||||
|
|
||||||
|
Exception: Failure
|
||||||
|
|
||||||
version() -> version<s>::
|
version() -> version<s>::
|
||||||
* version : Version string of signal-cli
|
* version : Version string of signal-cli
|
||||||
|
|
||||||
isRegistred -> result<b>::
|
isRegistered() -> result<b>::
|
||||||
* result : Currently always returns 1=true
|
isRegistered(number<s>) -> result<b>::
|
||||||
|
isRegistered(numbers<as>) -> results<ab>::
|
||||||
|
* number : Phone number
|
||||||
|
* numbers : String array of phone numbers
|
||||||
|
* result : true=number is registered, false=number is not registered
|
||||||
|
* results : Boolean array of results
|
||||||
|
|
||||||
|
Exception: InvalidNumber for an incorrectly formatted phone number. For unknown numbers, false is returned, but no exception is raised. If no number is given, returns whether you are registered (presumably true).
|
||||||
|
|
||||||
|
addDevice(deviceUri<s>) -> <>::
|
||||||
|
* deviceUri : URI in the form of tsdevice:/?uuid=... Normally received from Signal desktop or smartphone app
|
||||||
|
|
||||||
|
Exception: InvalidUri
|
||||||
|
|
||||||
|
listDevices() -> devices<as>::
|
||||||
|
* devices : String array of linked devices
|
||||||
|
|
||||||
|
Exception: Failure
|
||||||
|
|
||||||
|
removeDevice(deviceId<i>) -> <>::
|
||||||
|
* deviceId : Device ID to remove, obtained from listDevices() command
|
||||||
|
|
||||||
|
Exception: Failure
|
||||||
|
|
||||||
|
updateDeviceName(deviceName<s>) -> <>::
|
||||||
|
* deviceName : New name
|
||||||
|
|
||||||
|
Set a new name for this device (main or linked).
|
||||||
|
|
||||||
|
Exception: Failure
|
||||||
|
|
||||||
|
uploadStickerPack(stickerPackPath<s>) -> url<s>::
|
||||||
|
* stickerPackPath : Path to the manifest.json file or a zip file in the same directory
|
||||||
|
* url : URL of sticker pack after successful upload
|
||||||
|
|
||||||
|
Exception: Failure
|
||||||
|
|
||||||
== Signals
|
== Signals
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,14 @@ public interface Signal extends DBusInterface {
|
||||||
String message, List<String> attachments, List<String> recipients
|
String message, List<String> attachments, List<String> recipients
|
||||||
) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.UntrustedIdentity;
|
) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.UntrustedIdentity;
|
||||||
|
|
||||||
|
void sendTyping(
|
||||||
|
String recipient, boolean stop
|
||||||
|
) throws Error.Failure, Error.GroupNotFound, Error.UntrustedIdentity;
|
||||||
|
|
||||||
|
void sendReadReceipt(
|
||||||
|
String recipient, List<Long> targetSentTimestamp
|
||||||
|
) throws Error.Failure, Error.UntrustedIdentity;
|
||||||
|
|
||||||
long sendRemoteDeleteMessage(
|
long sendRemoteDeleteMessage(
|
||||||
long targetSentTimestamp, String recipient
|
long targetSentTimestamp, String recipient
|
||||||
) throws Error.Failure, Error.InvalidNumber;
|
) throws Error.Failure, Error.InvalidNumber;
|
||||||
|
@ -41,6 +49,10 @@ public interface Signal extends DBusInterface {
|
||||||
String emoji, boolean remove, String targetAuthor, long targetSentTimestamp, List<String> recipients
|
String emoji, boolean remove, String targetAuthor, long targetSentTimestamp, List<String> recipients
|
||||||
) throws Error.InvalidNumber, Error.Failure;
|
) throws Error.InvalidNumber, Error.Failure;
|
||||||
|
|
||||||
|
void sendContacts() throws Error.Failure;
|
||||||
|
|
||||||
|
void sendSyncRequest() throws Error.Failure;
|
||||||
|
|
||||||
long sendNoteToSelfMessage(
|
long sendNoteToSelfMessage(
|
||||||
String message, List<String> attachments
|
String message, List<String> attachments
|
||||||
) throws Error.AttachmentInvalid, Error.Failure;
|
) throws Error.AttachmentInvalid, Error.Failure;
|
||||||
|
@ -59,6 +71,8 @@ public interface Signal extends DBusInterface {
|
||||||
|
|
||||||
void setContactName(String number, String name) throws Error.InvalidNumber;
|
void setContactName(String number, String name) throws Error.InvalidNumber;
|
||||||
|
|
||||||
|
void setExpirationTimer(final String number, final int expiration) throws Error.Failure;
|
||||||
|
|
||||||
void setContactBlocked(String number, boolean blocked) throws Error.InvalidNumber;
|
void setContactBlocked(String number, boolean blocked) throws Error.InvalidNumber;
|
||||||
|
|
||||||
void setGroupBlocked(byte[] groupId, boolean blocked) throws Error.GroupNotFound, Error.InvalidGroupId;
|
void setGroupBlocked(byte[] groupId, boolean blocked) throws Error.GroupNotFound, Error.InvalidGroupId;
|
||||||
|
@ -73,12 +87,28 @@ public interface Signal extends DBusInterface {
|
||||||
byte[] groupId, String name, List<String> members, String avatar
|
byte[] groupId, String name, List<String> members, String avatar
|
||||||
) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.GroupNotFound, Error.InvalidGroupId;
|
) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.GroupNotFound, Error.InvalidGroupId;
|
||||||
|
|
||||||
boolean isRegistered();
|
boolean isRegistered() throws Error.Failure, Error.InvalidNumber;
|
||||||
|
|
||||||
|
boolean isRegistered(String number) throws Error.Failure, Error.InvalidNumber;
|
||||||
|
|
||||||
|
List<Boolean> isRegistered(List<String> numbers) throws Error.Failure, Error.InvalidNumber;
|
||||||
|
|
||||||
|
void addDevice(String uri) throws Error.InvalidUri;
|
||||||
|
|
||||||
|
void removeDevice(int deviceId) throws Error.Failure;
|
||||||
|
|
||||||
|
List<String> listDevices() throws Error.Failure;
|
||||||
|
|
||||||
|
void updateDeviceName(String deviceName) throws Error.Failure;
|
||||||
|
|
||||||
void updateProfile(
|
void updateProfile(
|
||||||
String name, String about, String aboutEmoji, String avatarPath, boolean removeAvatar
|
String name, String about, String aboutEmoji, String avatarPath, boolean removeAvatar
|
||||||
) throws Error.Failure;
|
) throws Error.Failure;
|
||||||
|
|
||||||
|
void removePin();
|
||||||
|
|
||||||
|
void setPin(String registrationLockPin);
|
||||||
|
|
||||||
String version();
|
String version();
|
||||||
|
|
||||||
List<String> listNumbers();
|
List<String> listNumbers();
|
||||||
|
@ -97,6 +127,8 @@ public interface Signal extends DBusInterface {
|
||||||
|
|
||||||
byte[] joinGroup(final String groupLink) throws Error.Failure;
|
byte[] joinGroup(final String groupLink) throws Error.Failure;
|
||||||
|
|
||||||
|
String uploadStickerPack(String stickerPackPath) throws Error.Failure;
|
||||||
|
|
||||||
class MessageReceived extends DBusSignal {
|
class MessageReceived extends DBusSignal {
|
||||||
|
|
||||||
private final long timestamp;
|
private final long timestamp;
|
||||||
|
@ -223,6 +255,13 @@ public interface Signal extends DBusInterface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class InvalidUri extends DBusExecutionException {
|
||||||
|
|
||||||
|
public InvalidUri(final String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Failure extends DBusExecutionException {
|
class Failure extends DBusExecutionException {
|
||||||
|
|
||||||
public Failure(final String message) {
|
public Failure(final String message) {
|
||||||
|
|
|
@ -5,8 +5,12 @@ import org.asamk.signal.BaseConfig;
|
||||||
import org.asamk.signal.manager.AttachmentInvalidException;
|
import org.asamk.signal.manager.AttachmentInvalidException;
|
||||||
import org.asamk.signal.manager.Manager;
|
import org.asamk.signal.manager.Manager;
|
||||||
import org.asamk.signal.manager.NotMasterDeviceException;
|
import org.asamk.signal.manager.NotMasterDeviceException;
|
||||||
|
import org.asamk.signal.manager.StickerPackInvalidException;
|
||||||
|
import org.asamk.signal.manager.UntrustedIdentityException;
|
||||||
|
import org.asamk.signal.manager.api.Device;
|
||||||
import org.asamk.signal.manager.api.Message;
|
import org.asamk.signal.manager.api.Message;
|
||||||
import org.asamk.signal.manager.api.RecipientIdentifier;
|
import org.asamk.signal.manager.api.RecipientIdentifier;
|
||||||
|
import org.asamk.signal.manager.api.TypingAction;
|
||||||
import org.asamk.signal.manager.groups.GroupId;
|
import org.asamk.signal.manager.groups.GroupId;
|
||||||
import org.asamk.signal.manager.groups.GroupInviteLinkUrl;
|
import org.asamk.signal.manager.groups.GroupInviteLinkUrl;
|
||||||
import org.asamk.signal.manager.groups.GroupNotFoundException;
|
import org.asamk.signal.manager.groups.GroupNotFoundException;
|
||||||
|
@ -17,15 +21,19 @@ import org.asamk.signal.manager.storage.identities.IdentityInfo;
|
||||||
import org.asamk.signal.util.ErrorUtils;
|
import org.asamk.signal.util.ErrorUtils;
|
||||||
import org.asamk.signal.util.Util;
|
import org.asamk.signal.util.Util;
|
||||||
import org.freedesktop.dbus.exceptions.DBusExecutionException;
|
import org.freedesktop.dbus.exceptions.DBusExecutionException;
|
||||||
|
import org.whispersystems.libsignal.InvalidKeyException;
|
||||||
import org.whispersystems.libsignal.util.Pair;
|
import org.whispersystems.libsignal.util.Pair;
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
import org.whispersystems.signalservice.api.groupsv2.GroupLinkNotActiveException;
|
import org.whispersystems.signalservice.api.groupsv2.GroupLinkNotActiveException;
|
||||||
import org.whispersystems.signalservice.api.messages.SendMessageResult;
|
import org.whispersystems.signalservice.api.messages.SendMessageResult;
|
||||||
import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException;
|
import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException;
|
||||||
import org.whispersystems.signalservice.api.util.InvalidNumberException;
|
import org.whispersystems.signalservice.api.util.InvalidNumberException;
|
||||||
|
import org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedResponseException;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -33,6 +41,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@ -58,6 +67,51 @@ public class DbusSignalImpl implements Signal {
|
||||||
return objectPath;
|
return objectPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addDevice(String uri) {
|
||||||
|
try {
|
||||||
|
m.addDeviceLink(new URI(uri));
|
||||||
|
} catch (IOException | InvalidKeyException e) {
|
||||||
|
throw new Error.Failure(e.getClass().getSimpleName() + " Add device link failed. " + e.getMessage());
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
throw new Error.InvalidUri(e.getClass().getSimpleName()
|
||||||
|
+ " Device link uri has invalid format: "
|
||||||
|
+ e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeDevice(int deviceId) {
|
||||||
|
try {
|
||||||
|
m.removeLinkedDevices(deviceId);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error.Failure(e.getClass().getSimpleName() + ": Error while removing device: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> listDevices() {
|
||||||
|
List<Device> devices;
|
||||||
|
List<String> results = new ArrayList<String>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
devices = m.getLinkedDevices();
|
||||||
|
} catch (IOException | Error.Failure e) {
|
||||||
|
throw new Error.Failure("Failed to get linked devices: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return devices.stream().map(d -> d.getName() == null ? "" : d.getName()).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateDeviceName(String deviceName) {
|
||||||
|
try {
|
||||||
|
m.updateAccountAttributes(deviceName);
|
||||||
|
} catch (IOException | Signal.Error.Failure e) {
|
||||||
|
throw new Error.Failure("UpdateAccount error: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long sendMessage(final String message, final List<String> attachments, final String recipient) {
|
public long sendMessage(final String message, final List<String> attachments, final String recipient) {
|
||||||
var recipients = new ArrayList<String>(1);
|
var recipients = new ArrayList<String>(1);
|
||||||
|
@ -165,6 +219,57 @@ public class DbusSignalImpl implements Signal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendTyping(
|
||||||
|
final String recipient, final boolean stop
|
||||||
|
) throws Error.Failure, Error.GroupNotFound, Error.UntrustedIdentity {
|
||||||
|
try {
|
||||||
|
var recipients = new ArrayList<String>(1);
|
||||||
|
recipients.add(recipient);
|
||||||
|
m.sendTypingMessage(stop ? TypingAction.STOP : TypingAction.START,
|
||||||
|
getSingleRecipientIdentifiers(recipients, m.getUsername()).stream()
|
||||||
|
.map(RecipientIdentifier.class::cast)
|
||||||
|
.collect(Collectors.toSet()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error.Failure(e.getMessage());
|
||||||
|
} catch (GroupNotFoundException | NotAGroupMemberException | GroupSendingNotAllowedException e) {
|
||||||
|
throw new Error.GroupNotFound(e.getMessage());
|
||||||
|
} catch (UntrustedIdentityException e) {
|
||||||
|
throw new Error.UntrustedIdentity(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendReadReceipt(
|
||||||
|
final String recipient, final List<Long> timestamps
|
||||||
|
) throws Error.Failure, Error.UntrustedIdentity {
|
||||||
|
try {
|
||||||
|
m.sendReadReceipt(getSingleRecipientIdentifier(recipient, m.getUsername()), timestamps);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error.Failure(e.getMessage());
|
||||||
|
} catch (UntrustedIdentityException e) {
|
||||||
|
throw new Error.UntrustedIdentity(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendContacts() {
|
||||||
|
try {
|
||||||
|
m.sendContacts();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error.Failure("SendContacts error: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendSyncRequest() {
|
||||||
|
try {
|
||||||
|
m.requestAllSyncData();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error.Failure("Request sync data error: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long sendNoteToSelfMessage(
|
public long sendNoteToSelfMessage(
|
||||||
final String message, final List<String> attachments
|
final String message, final List<String> attachments
|
||||||
|
@ -250,6 +355,15 @@ public class DbusSignalImpl implements Signal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setExpirationTimer(final String number, final int expiration) {
|
||||||
|
try {
|
||||||
|
m.setExpirationTimer(getSingleRecipientIdentifier(number, m.getUsername()), expiration);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error.Failure(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setContactBlocked(final String number, final boolean blocked) {
|
public void setContactBlocked(final String number, final boolean blocked) {
|
||||||
try {
|
try {
|
||||||
|
@ -357,6 +471,32 @@ public class DbusSignalImpl implements Signal {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRegistered(String number) {
|
||||||
|
var result = isRegistered(List.of(number));
|
||||||
|
return result.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Boolean> isRegistered(List<String> numbers) {
|
||||||
|
var results = new ArrayList<Boolean>();
|
||||||
|
if (numbers.isEmpty()) {
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Pair<String, UUID>> registered;
|
||||||
|
try {
|
||||||
|
registered = m.areUsersRegistered(new HashSet<>(numbers));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error.Failure(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return numbers.stream().map(number -> {
|
||||||
|
var uuid = registered.get(number).second();
|
||||||
|
return uuid != null;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateProfile(
|
public void updateProfile(
|
||||||
final String name,
|
final String name,
|
||||||
|
@ -378,6 +518,28 @@ public class DbusSignalImpl implements Signal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removePin() {
|
||||||
|
try {
|
||||||
|
m.setRegistrationLockPin(Optional.absent());
|
||||||
|
} catch (UnauthenticatedResponseException e) {
|
||||||
|
throw new Error.Failure("Remove pin failed with unauthenticated response: " + e.getMessage());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error.Failure("Remove pin error: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPin(String registrationLockPin) {
|
||||||
|
try {
|
||||||
|
m.setRegistrationLockPin(Optional.of(registrationLockPin));
|
||||||
|
} catch (UnauthenticatedResponseException e) {
|
||||||
|
throw new Error.Failure("Set pin error failed with unauthenticated response: " + e.getMessage());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error.Failure("Set pin error: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Provide option to query a version string in order to react on potential
|
// Provide option to query a version string in order to react on potential
|
||||||
// future interface changes
|
// future interface changes
|
||||||
@Override
|
@Override
|
||||||
|
@ -483,6 +645,18 @@ public class DbusSignalImpl implements Signal {
|
||||||
return m.getUsername();
|
return m.getUsername();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String uploadStickerPack(String stickerPackPath) {
|
||||||
|
File path = new File(stickerPackPath);
|
||||||
|
try {
|
||||||
|
return m.uploadStickerPack(path).toString();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error.Failure("Upload error (maybe image size is too large):" + e.getMessage());
|
||||||
|
} catch (StickerPackInvalidException e) {
|
||||||
|
throw new Error.Failure("Invalid sticker pack: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void checkSendMessageResult(long timestamp, SendMessageResult result) throws DBusExecutionException {
|
private static void checkSendMessageResult(long timestamp, SendMessageResult result) throws DBusExecutionException {
|
||||||
var error = ErrorUtils.getErrorMessageFromSendMessageResult(result);
|
var error = ErrorUtils.getErrorMessageFromSendMessageResult(result);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue