mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 18:40:39 +00:00
parent
3f315df6c8
commit
23845eab47
6 changed files with 228 additions and 0 deletions
|
@ -16,10 +16,14 @@
|
|||
*/
|
||||
package org.asamk.signal.manager;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import org.asamk.Signal;
|
||||
import org.asamk.signal.AttachmentInvalidException;
|
||||
import org.asamk.signal.GroupNotFoundException;
|
||||
import org.asamk.signal.JsonStickerPack;
|
||||
import org.asamk.signal.NotAGroupMemberException;
|
||||
import org.asamk.signal.StickerPackInvalidException;
|
||||
import org.asamk.signal.TrustLevel;
|
||||
import org.asamk.signal.UserAlreadyExists;
|
||||
import org.asamk.signal.storage.SignalAccount;
|
||||
|
@ -77,6 +81,8 @@ import org.whispersystems.signalservice.api.messages.SignalServiceContent;
|
|||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceStickerManifest;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceStickerManifest.StickerInfo;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.BlockedListMessage;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.ContactsMessage;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContact;
|
||||
|
@ -102,9 +108,13 @@ import org.whispersystems.signalservice.api.util.SleepTimer;
|
|||
import org.whispersystems.signalservice.api.util.StreamDetails;
|
||||
import org.whispersystems.signalservice.api.util.UptimeSleepTimer;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
|
||||
import org.whispersystems.signalservice.internal.push.StickerUploadAttributes;
|
||||
import org.whispersystems.signalservice.internal.push.StickerUploadAttributesResponse;
|
||||
import org.whispersystems.signalservice.internal.push.UnsupportedDataMessageException;
|
||||
import org.whispersystems.signalservice.internal.util.Hex;
|
||||
import org.whispersystems.util.Base64;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
|
@ -121,6 +131,7 @@ import java.util.Arrays;
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
@ -130,6 +141,8 @@ import java.util.Objects;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class Manager implements Signal {
|
||||
|
||||
|
@ -857,6 +870,138 @@ public class Manager implements Signal {
|
|||
account.getThreadStore().updateThread(thread);
|
||||
}
|
||||
|
||||
public String uploadStickerPack(String path) throws IOException, StickerPackInvalidException {
|
||||
JsonStickerPack pack = parseStickerPack(path);
|
||||
|
||||
if (pack.stickers == null) {
|
||||
throw new StickerPackInvalidException("Must set a 'stickers' field.");
|
||||
}
|
||||
|
||||
if (pack.stickers.isEmpty()) {
|
||||
throw new StickerPackInvalidException("Must include stickers.");
|
||||
}
|
||||
|
||||
List<StickerInfo> stickers = new ArrayList<>(pack.stickers.size());
|
||||
for (int i = 0; i < pack.stickers.size(); i++) {
|
||||
if (pack.stickers.get(i).file == null) {
|
||||
throw new StickerPackInvalidException("Must set a 'file' field on each sticker.");
|
||||
}
|
||||
if (!stickerDataContainsPath(path, pack.stickers.get(i).file)) {
|
||||
throw new StickerPackInvalidException("Could not find find " + pack.stickers.get(i).file);
|
||||
}
|
||||
|
||||
StickerInfo stickerInfo = new StickerInfo(i, Optional.fromNullable(pack.stickers.get(i).emoji).or(""));
|
||||
stickers.add(stickerInfo);
|
||||
}
|
||||
|
||||
boolean uniqueCover = false;
|
||||
StickerInfo cover = stickers.get(0);
|
||||
if (pack.cover != null) {
|
||||
if (pack.cover.file == null) {
|
||||
throw new StickerPackInvalidException("Must set a 'file' field on the cover.");
|
||||
}
|
||||
if (!stickerDataContainsPath(path, pack.cover.file)) {
|
||||
throw new StickerPackInvalidException("Could not find find cover " + pack.cover.file);
|
||||
}
|
||||
|
||||
uniqueCover = true;
|
||||
cover = new StickerInfo(pack.stickers.size(), Optional.fromNullable(pack.cover.emoji).or(""));
|
||||
}
|
||||
|
||||
SignalServiceStickerManifest manifest = new SignalServiceStickerManifest(
|
||||
Optional.fromNullable(pack.title).or(""),
|
||||
Optional.fromNullable(pack.author).or(""),
|
||||
cover,
|
||||
stickers);
|
||||
|
||||
SignalServiceMessageSender messageSender = new SignalServiceMessageSender(
|
||||
BaseConfig.serviceConfiguration,
|
||||
null,
|
||||
username,
|
||||
account.getPassword(),
|
||||
account.getDeviceId(),
|
||||
account.getSignalProtocolStore(),
|
||||
BaseConfig.USER_AGENT,
|
||||
account.isMultiDevice(),
|
||||
Optional.fromNullable(messagePipe),
|
||||
Optional.fromNullable(unidentifiedMessagePipe),
|
||||
Optional.<SignalServiceMessageSender.EventListener>absent());
|
||||
|
||||
System.out.println("Starting upload process...");
|
||||
Pair<byte[], StickerUploadAttributesResponse> responsePair = messageSender.getStickerUploadAttributes(stickers.size() + (uniqueCover ? 1 : 0));
|
||||
byte[] packKey = responsePair.first();
|
||||
StickerUploadAttributesResponse response = responsePair.second();
|
||||
|
||||
System.out.println("Uploading manifest...");
|
||||
messageSender.uploadStickerManifest(manifest, packKey, response.getManifest());
|
||||
|
||||
Map<Integer, StickerUploadAttributes> attrById = new HashMap<>();
|
||||
|
||||
for (StickerUploadAttributes attr : response.getStickers()) {
|
||||
attrById.put(attr.getId(), attr);
|
||||
}
|
||||
|
||||
for (int i = 0; i < pack.stickers.size(); i++) {
|
||||
System.out.println("Uploading sticker " + (i+1) + "/" + pack.stickers.size() + "...");
|
||||
StickerUploadAttributes attr = attrById.get(i);
|
||||
if (attr == null) {
|
||||
throw new StickerPackInvalidException("Upload attributes missing for id " + i);
|
||||
}
|
||||
|
||||
byte[] data = readStickerDataFromPath(path, pack.stickers.get(i).file);
|
||||
messageSender.uploadSticker(new ByteArrayInputStream(data), data.length, packKey, attr);
|
||||
}
|
||||
|
||||
if (uniqueCover) {
|
||||
System.out.println("Uploading unique cover...");
|
||||
StickerUploadAttributes attr = attrById.get(pack.stickers.size());
|
||||
if (attr == null) {
|
||||
throw new StickerPackInvalidException("Upload attributes missing for cover with id " + pack.stickers.size());
|
||||
}
|
||||
|
||||
byte[] data = readStickerDataFromPath(path, pack.cover.file);
|
||||
messageSender.uploadSticker(new ByteArrayInputStream(data), data.length, packKey, attr);
|
||||
}
|
||||
|
||||
return "https://signal.art/addstickers/#pack_id=" + response.getPackId() + "&pack_key=" + Hex.toStringCondensed(packKey).replaceAll(" ", "");
|
||||
}
|
||||
|
||||
private static byte[] readStickerDataFromPath(String rootPath, String subFile) throws IOException, StickerPackInvalidException {
|
||||
if (rootPath.endsWith(".zip")) {
|
||||
ZipFile zip = new ZipFile(rootPath);
|
||||
ZipEntry entry = zip.getEntry(subFile);
|
||||
return IOUtils.readFully(zip.getInputStream(entry));
|
||||
} else if (rootPath.endsWith(".json")) {
|
||||
String dir = new File(rootPath).getParent();
|
||||
FileInputStream fis = new FileInputStream(new File(dir, subFile));
|
||||
return IOUtils.readFully(fis);
|
||||
} else {
|
||||
throw new StickerPackInvalidException("Must point to either a ZIP or JSON file.");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean stickerDataContainsPath(String rootPath, String subFile) throws IOException {
|
||||
if (rootPath.endsWith(".zip")) {
|
||||
ZipFile zip = new ZipFile(rootPath);
|
||||
return zip.getEntry(subFile) != null;
|
||||
} else if (rootPath.endsWith(".json")) {
|
||||
String dir = new File(rootPath).getParent();
|
||||
return new File(dir, subFile).exists();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static JsonStickerPack parseStickerPack(String rootPath) throws IOException, StickerPackInvalidException {
|
||||
if (!stickerDataContainsPath(rootPath, "manifest.json")) {
|
||||
throw new StickerPackInvalidException("Could not find manifest.json");
|
||||
}
|
||||
|
||||
String json = new String(readStickerDataFromPath(rootPath, "manifest.json"));
|
||||
|
||||
return new ObjectMapper().readValue(json, JsonStickerPack.class);
|
||||
}
|
||||
|
||||
private void requestSyncGroups() throws IOException {
|
||||
SignalServiceProtos.SyncMessage.Request r = SignalServiceProtos.SyncMessage.Request.newBuilder().setType(SignalServiceProtos.SyncMessage.Request.Type.GROUPS).build();
|
||||
SignalServiceSyncMessage message = SignalServiceSyncMessage.forRequest(new RequestMessage(r));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue