]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/Manager.java
Add support for sending stickers
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / Manager.java
1 package org.asamk.signal.manager;
2
3 import org.asamk.signal.manager.api.Configuration;
4 import org.asamk.signal.manager.api.Device;
5 import org.asamk.signal.manager.api.Group;
6 import org.asamk.signal.manager.api.Identity;
7 import org.asamk.signal.manager.api.InactiveGroupLinkException;
8 import org.asamk.signal.manager.api.InvalidDeviceLinkException;
9 import org.asamk.signal.manager.api.InvalidStickerException;
10 import org.asamk.signal.manager.api.Message;
11 import org.asamk.signal.manager.api.MessageEnvelope;
12 import org.asamk.signal.manager.api.Pair;
13 import org.asamk.signal.manager.api.RecipientIdentifier;
14 import org.asamk.signal.manager.api.SendGroupMessageResults;
15 import org.asamk.signal.manager.api.SendMessageResults;
16 import org.asamk.signal.manager.api.TypingAction;
17 import org.asamk.signal.manager.api.UnregisteredRecipientException;
18 import org.asamk.signal.manager.api.UpdateGroup;
19 import org.asamk.signal.manager.config.ServiceConfig;
20 import org.asamk.signal.manager.config.ServiceEnvironment;
21 import org.asamk.signal.manager.groups.GroupId;
22 import org.asamk.signal.manager.groups.GroupInviteLinkUrl;
23 import org.asamk.signal.manager.groups.GroupNotFoundException;
24 import org.asamk.signal.manager.groups.GroupSendingNotAllowedException;
25 import org.asamk.signal.manager.groups.LastGroupAdminException;
26 import org.asamk.signal.manager.groups.NotAGroupMemberException;
27 import org.asamk.signal.manager.storage.SignalAccount;
28 import org.asamk.signal.manager.storage.identities.TrustNewIdentity;
29 import org.asamk.signal.manager.storage.recipients.Contact;
30 import org.asamk.signal.manager.storage.recipients.Profile;
31 import org.asamk.signal.manager.storage.recipients.RecipientAddress;
32 import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
33
34 import java.io.Closeable;
35 import java.io.File;
36 import java.io.IOException;
37 import java.net.URI;
38 import java.time.Duration;
39 import java.util.Arrays;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.Optional;
43 import java.util.Set;
44 import java.util.UUID;
45
46 public interface Manager extends Closeable {
47
48 static Manager init(
49 String number,
50 File settingsPath,
51 ServiceEnvironment serviceEnvironment,
52 String userAgent,
53 TrustNewIdentity trustNewIdentity
54 ) throws IOException, NotRegisteredException {
55 var pathConfig = PathConfig.createDefault(settingsPath);
56
57 if (!SignalAccount.userExists(pathConfig.dataPath(), number)) {
58 throw new NotRegisteredException();
59 }
60
61 var account = SignalAccount.load(pathConfig.dataPath(), number, true, trustNewIdentity);
62
63 if (!account.isRegistered()) {
64 account.close();
65 throw new NotRegisteredException();
66 }
67
68 final var serviceEnvironmentConfig = ServiceConfig.getServiceEnvironmentConfig(serviceEnvironment, userAgent);
69
70 return new ManagerImpl(account, pathConfig, serviceEnvironmentConfig, userAgent);
71 }
72
73 static void initLogger() {
74 LibSignalLogger.initLogger();
75 }
76
77 static boolean isValidNumber(final String e164Number, final String countryCode) {
78 return PhoneNumberFormatter.isValidNumber(e164Number, countryCode);
79 }
80
81 static List<String> getAllLocalAccountNumbers(File settingsPath) {
82 var pathConfig = PathConfig.createDefault(settingsPath);
83 final var dataPath = pathConfig.dataPath();
84 final var files = dataPath.listFiles();
85
86 if (files == null) {
87 return List.of();
88 }
89
90 return Arrays.stream(files)
91 .filter(File::isFile)
92 .map(File::getName)
93 .filter(file -> PhoneNumberFormatter.isValidNumber(file, null))
94 .toList();
95 }
96
97 String getSelfNumber();
98
99 void checkAccountState() throws IOException;
100
101 /**
102 * This is used for checking a set of phone numbers for registration on Signal
103 *
104 * @param numbers The set of phone number in question
105 * @return A map of numbers to canonicalized number and uuid. If a number is not registered the uuid is null.
106 * @throws IOException if it's unable to get the contacts to check if they're registered
107 */
108 Map<String, Pair<String, UUID>> areUsersRegistered(Set<String> numbers) throws IOException;
109
110 void updateAccountAttributes(String deviceName) throws IOException;
111
112 Configuration getConfiguration();
113
114 void updateConfiguration(Configuration configuration) throws IOException, NotMasterDeviceException;
115
116 /**
117 * @param givenName if null, the previous givenName will be kept
118 * @param familyName if null, the previous familyName will be kept
119 * @param about if null, the previous about text will be kept
120 * @param aboutEmoji if null, the previous about emoji will be kept
121 * @param avatar if avatar is null the image from the local avatar store is used (if present),
122 */
123 void setProfile(
124 String givenName, String familyName, String about, String aboutEmoji, Optional<File> avatar
125 ) throws IOException;
126
127 void unregister() throws IOException;
128
129 void deleteAccount() throws IOException;
130
131 void submitRateLimitRecaptchaChallenge(String challenge, String captcha) throws IOException;
132
133 List<Device> getLinkedDevices() throws IOException;
134
135 void removeLinkedDevices(long deviceId) throws IOException;
136
137 void addDeviceLink(URI linkUri) throws IOException, InvalidDeviceLinkException;
138
139 void setRegistrationLockPin(Optional<String> pin) throws IOException, NotMasterDeviceException;
140
141 Profile getRecipientProfile(RecipientIdentifier.Single recipient) throws IOException, UnregisteredRecipientException;
142
143 List<Group> getGroups();
144
145 SendGroupMessageResults quitGroup(
146 GroupId groupId, Set<RecipientIdentifier.Single> groupAdmins
147 ) throws GroupNotFoundException, IOException, NotAGroupMemberException, LastGroupAdminException, UnregisteredRecipientException;
148
149 void deleteGroup(GroupId groupId) throws IOException;
150
151 Pair<GroupId, SendGroupMessageResults> createGroup(
152 String name, Set<RecipientIdentifier.Single> members, File avatarFile
153 ) throws IOException, AttachmentInvalidException, UnregisteredRecipientException;
154
155 SendGroupMessageResults updateGroup(
156 final GroupId groupId, final UpdateGroup updateGroup
157 ) throws IOException, GroupNotFoundException, AttachmentInvalidException, NotAGroupMemberException, GroupSendingNotAllowedException, UnregisteredRecipientException;
158
159 Pair<GroupId, SendGroupMessageResults> joinGroup(
160 GroupInviteLinkUrl inviteLinkUrl
161 ) throws IOException, InactiveGroupLinkException;
162
163 SendMessageResults sendTypingMessage(
164 TypingAction action, Set<RecipientIdentifier> recipients
165 ) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException;
166
167 SendMessageResults sendReadReceipt(
168 RecipientIdentifier.Single sender, List<Long> messageIds
169 ) throws IOException;
170
171 SendMessageResults sendViewedReceipt(
172 RecipientIdentifier.Single sender, List<Long> messageIds
173 ) throws IOException;
174
175 SendMessageResults sendMessage(
176 Message message, Set<RecipientIdentifier> recipients
177 ) throws IOException, AttachmentInvalidException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException, UnregisteredRecipientException, InvalidStickerException;
178
179 SendMessageResults sendRemoteDeleteMessage(
180 long targetSentTimestamp, Set<RecipientIdentifier> recipients
181 ) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException;
182
183 SendMessageResults sendMessageReaction(
184 String emoji,
185 boolean remove,
186 RecipientIdentifier.Single targetAuthor,
187 long targetSentTimestamp,
188 Set<RecipientIdentifier> recipients
189 ) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException, UnregisteredRecipientException;
190
191 SendMessageResults sendEndSessionMessage(Set<RecipientIdentifier.Single> recipients) throws IOException;
192
193 void deleteRecipient(RecipientIdentifier.Single recipient);
194
195 void deleteContact(RecipientIdentifier.Single recipient);
196
197 void setContactName(
198 RecipientIdentifier.Single recipient, String name
199 ) throws NotMasterDeviceException, IOException, UnregisteredRecipientException;
200
201 void setContactBlocked(
202 RecipientIdentifier.Single recipient, boolean blocked
203 ) throws NotMasterDeviceException, IOException, UnregisteredRecipientException;
204
205 void setGroupBlocked(
206 GroupId groupId, boolean blocked
207 ) throws GroupNotFoundException, IOException, NotMasterDeviceException;
208
209 /**
210 * Change the expiration timer for a contact
211 */
212 void setExpirationTimer(
213 RecipientIdentifier.Single recipient, int messageExpirationTimer
214 ) throws IOException, UnregisteredRecipientException;
215
216 /**
217 * Upload the sticker pack from path.
218 *
219 * @param path Path can be a path to a manifest.json file or to a zip file that contains a manifest.json file
220 * @return if successful, returns the URL to install the sticker pack in the signal app
221 */
222 URI uploadStickerPack(File path) throws IOException, StickerPackInvalidException;
223
224 void requestAllSyncData() throws IOException;
225
226 /**
227 * Add a handler to receive new messages.
228 * Will start receiving messages from server, if not already started.
229 */
230 default void addReceiveHandler(ReceiveMessageHandler handler) {
231 addReceiveHandler(handler, false);
232 }
233
234 void addReceiveHandler(ReceiveMessageHandler handler, final boolean isWeakListener);
235
236 /**
237 * Remove a handler to receive new messages.
238 * Will stop receiving messages from server, if this was the last registered receiver.
239 */
240 void removeReceiveHandler(ReceiveMessageHandler handler);
241
242 boolean isReceiving();
243
244 /**
245 * Receive new messages from server, returns if no new message arrive in a timespan of timeout.
246 */
247 void receiveMessages(Duration timeout, ReceiveMessageHandler handler) throws IOException;
248
249 /**
250 * Receive new messages from server, returns only if the thread is interrupted.
251 */
252 void receiveMessages(ReceiveMessageHandler handler) throws IOException;
253
254 void setIgnoreAttachments(boolean ignoreAttachments);
255
256 boolean hasCaughtUpWithOldMessages();
257
258 boolean isContactBlocked(RecipientIdentifier.Single recipient);
259
260 void sendContacts() throws IOException;
261
262 List<Pair<RecipientAddress, Contact>> getContacts();
263
264 String getContactOrProfileName(RecipientIdentifier.Single recipient);
265
266 Group getGroup(GroupId groupId);
267
268 List<Identity> getIdentities();
269
270 List<Identity> getIdentities(RecipientIdentifier.Single recipient);
271
272 /**
273 * Trust this the identity with this fingerprint
274 *
275 * @param recipient account of the identity
276 * @param fingerprint Fingerprint
277 */
278 boolean trustIdentityVerified(
279 RecipientIdentifier.Single recipient, byte[] fingerprint
280 ) throws UnregisteredRecipientException;
281
282 /**
283 * Trust this the identity with this safety number
284 *
285 * @param recipient account of the identity
286 * @param safetyNumber Safety number
287 */
288 boolean trustIdentityVerifiedSafetyNumber(
289 RecipientIdentifier.Single recipient, String safetyNumber
290 ) throws UnregisteredRecipientException;
291
292 /**
293 * Trust this the identity with this scannable safety number
294 *
295 * @param recipient account of the identity
296 * @param safetyNumber Scannable safety number
297 */
298 boolean trustIdentityVerifiedSafetyNumber(
299 RecipientIdentifier.Single recipient, byte[] safetyNumber
300 ) throws UnregisteredRecipientException;
301
302 /**
303 * Trust all keys of this identity without verification
304 *
305 * @param recipient account of the identity
306 */
307 boolean trustIdentityAllKeys(RecipientIdentifier.Single recipient) throws UnregisteredRecipientException;
308
309 void addClosedListener(Runnable listener);
310
311 @Override
312 void close() throws IOException;
313
314 interface ReceiveMessageHandler {
315
316 ReceiveMessageHandler EMPTY = (envelope, e) -> {
317 };
318
319 void handleMessage(MessageEnvelope envelope, Throwable e);
320 }
321 }