"allDeclaredMethods":true,
"allDeclaredConstructors":true}
,
+{
+ "name":"org.asamk.signal.commands.ListStickerPacksCommand$JsonStickerPack",
+ "allDeclaredFields":true,
+ "queryAllDeclaredMethods":true,
+ "queryAllDeclaredConstructors":true,
+ "methods":[
+ {"name":"author","parameterTypes":[] },
+ {"name":"cover","parameterTypes":[] },
+ {"name":"installed","parameterTypes":[] },
+ {"name":"packId","parameterTypes":[] },
+ {"name":"stickers","parameterTypes":[] },
+ {"name":"title","parameterTypes":[] }
+ ]}
+,
+{
+ "name":"org.asamk.signal.commands.ListStickerPacksCommand$JsonStickerPack$JsonSticker",
+ "allDeclaredFields":true,
+ "queryAllDeclaredMethods":true,
+ "queryAllDeclaredConstructors":true,
+ "methods":[
+ {"name":"contentType","parameterTypes":[] },
+ {"name":"emoji","parameterTypes":[] },
+ {"name":"id","parameterTypes":[] }
+ ]}
+,
{
"name":"org.asamk.signal.commands.RegisterCommand$RegistrationParams",
"allDeclaredFields":true,
"queryAllDeclaredMethods":true,
"queryAllDeclaredConstructors":true,
"methods":[
+ {"name":"<init>","parameterTypes":["java.lang.Integer","java.lang.String","java.lang.String","java.lang.String"] },
{"name":"<init>","parameterTypes":["java.lang.String","java.lang.String","java.lang.String"] },
{"name":"contentType","parameterTypes":[] },
{"name":"emoji","parameterTypes":[] },
package org.asamk.signal.manager;
+import org.asamk.signal.manager.api.StickerPack;
+
import java.util.List;
public record JsonStickerPack(String title, String author, JsonSticker cover, List<JsonSticker> stickers) {
- public record JsonSticker(String emoji, String file, String contentType) {}
+ public record JsonSticker(Integer id, String emoji, String file, String contentType) {
+
+ public StickerPack.Sticker toApi() {
+ return new StickerPack.Sticker(id == null ? Integer.parseInt(file) : id, emoji, contentType);
+ }
+ }
}
import org.asamk.signal.manager.api.RecipientIdentifier;
import org.asamk.signal.manager.api.SendGroupMessageResults;
import org.asamk.signal.manager.api.SendMessageResults;
+import org.asamk.signal.manager.api.StickerPack;
import org.asamk.signal.manager.api.TypingAction;
import org.asamk.signal.manager.api.UnregisteredRecipientException;
import org.asamk.signal.manager.api.UpdateGroup;
*/
URI uploadStickerPack(File path) throws IOException, StickerPackInvalidException;
+ List<StickerPack> getStickerPacks();
+
void requestAllSyncData() throws IOException;
/**
import org.asamk.signal.manager.api.SendGroupMessageResults;
import org.asamk.signal.manager.api.SendMessageResult;
import org.asamk.signal.manager.api.SendMessageResults;
+import org.asamk.signal.manager.api.StickerPack;
import org.asamk.signal.manager.api.TypingAction;
import org.asamk.signal.manager.api.UnregisteredRecipientException;
import org.asamk.signal.manager.api.UpdateGroup;
}
}
+ @Override
+ public List<StickerPack> getStickerPacks() {
+ final var stickerPackStore = context.getStickerPackStore();
+ return account.getStickerStore().getStickerPacks().stream().map(pack -> {
+ if (stickerPackStore.existsStickerPack(pack.getPackId())) {
+ try {
+ final var manifest = stickerPackStore.retrieveManifest(pack.getPackId());
+ return new StickerPack(pack.getPackId(),
+ pack.getPackKey(),
+ pack.isInstalled(),
+ manifest.title(),
+ manifest.author(),
+ java.util.Optional.ofNullable(manifest.cover() == null ? null : manifest.cover().toApi()),
+ manifest.stickers().stream().map(JsonStickerPack.JsonSticker::toApi).toList());
+ } catch (Exception e) {
+ logger.warn("Failed to read local sticker pack manifest: {}", e.getMessage(), e);
+ }
+ }
+
+ return new StickerPack(pack.getPackId(), pack.getPackKey(), pack.isInstalled());
+ }).toList();
+ }
+
@Override
public void requestAllSyncData() throws IOException {
context.getSyncHelper().requestAllSyncData();
--- /dev/null
+package org.asamk.signal.manager.api;
+
+import org.asamk.signal.manager.storage.stickers.StickerPackId;
+
+import java.util.List;
+import java.util.Optional;
+
+public record StickerPack(
+ StickerPackId packId,
+ byte[] packKey,
+ boolean installed,
+ String title,
+ String author,
+ Optional<Sticker> cover,
+ List<Sticker> stickers
+) {
+
+ public StickerPack(final StickerPackId packId, final byte[] packKey, final boolean installed) {
+ this(packId, packKey, installed, "", "", Optional.empty(), List.of());
+ }
+
+ public record Sticker(int id, String emoji, String contentType) {}
+}
final var jsonManifest = new JsonStickerPack(manifest.getTitle().orNull(),
manifest.getAuthor().orNull(),
manifest.getCover()
- .transform(c -> new JsonStickerPack.JsonSticker(c.getEmoji(),
+ .transform(c -> new JsonStickerPack.JsonSticker(c.getId(),
+ c.getEmoji(),
String.valueOf(c.getId()),
c.getContentType()))
.orNull(),
manifest.getStickers()
.stream()
- .map(c -> new JsonStickerPack.JsonSticker(c.getEmoji(),
+ .map(c -> new JsonStickerPack.JsonSticker(c.getId(),
+ c.getEmoji(),
String.valueOf(c.getId()),
c.getContentType()))
.toList());
package org.asamk.signal.manager.storage.stickers;
import java.util.Base64;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
return new StickerStore(stickers, saver);
}
+ public Collection<Sticker> getStickerPacks() {
+ return stickers.values();
+ }
+
public Sticker getStickerPack(StickerPackId packId) {
synchronized (stickers) {
return stickers.get(packId);
addCommand(new ListDevicesCommand());
addCommand(new ListGroupsCommand());
addCommand(new ListIdentitiesCommand());
+ addCommand(new ListStickerPacksCommand());
addCommand(new QuitGroupCommand());
addCommand(new ReceiveCommand());
addCommand(new RegisterCommand());
--- /dev/null
+package org.asamk.signal.commands;
+
+import net.sourceforge.argparse4j.inf.Namespace;
+import net.sourceforge.argparse4j.inf.Subparser;
+
+import org.asamk.signal.commands.exceptions.CommandException;
+import org.asamk.signal.manager.Manager;
+import org.asamk.signal.manager.api.StickerPack;
+import org.asamk.signal.output.JsonWriter;
+import org.asamk.signal.output.OutputWriter;
+import org.asamk.signal.output.PlainTextWriter;
+import org.asamk.signal.util.Hex;
+
+import java.util.List;
+
+public class ListStickerPacksCommand implements JsonRpcLocalCommand {
+
+ @Override
+ public String getName() {
+ return "listStickerPacks";
+ }
+
+ @Override
+ public void attachToSubparser(final Subparser subparser) {
+ subparser.help("Show a list of known sticker packs.");
+ }
+
+ @Override
+ public void handleCommand(
+ final Namespace ns, final Manager c, final OutputWriter outputWriter
+ ) throws CommandException {
+ final var stickerPacks = c.getStickerPacks();
+ if (outputWriter instanceof JsonWriter jsonWriter) {
+ final var jsonStickerPacks = stickerPacks.stream().map(JsonStickerPack::new).toList();
+ jsonWriter.write(jsonStickerPacks);
+ } else if (outputWriter instanceof PlainTextWriter plainTextWriter) {
+ for (final var sticker : stickerPacks) {
+ plainTextWriter.println("Pack {}: “{}” by “{}” has {} stickers",
+ Hex.toStringCondensed(sticker.packId().serialize()),
+ sticker.title(),
+ sticker.author(),
+ sticker.stickers().size());
+ }
+ }
+ }
+
+ private record JsonStickerPack(
+ String packId, boolean installed, String title, String author, JsonSticker cover, List<JsonSticker> stickers
+ ) {
+
+ JsonStickerPack(StickerPack stickerPack) {
+ this(Hex.toStringCondensed(stickerPack.packId().serialize()),
+ stickerPack.installed(),
+ stickerPack.title(),
+ stickerPack.author(),
+ stickerPack.cover().map(JsonSticker::new).orElse(null),
+ stickerPack.stickers().stream().map(JsonSticker::new).toList());
+ }
+
+ private record JsonSticker(int id, String emoji, String contentType) {
+
+ JsonSticker(StickerPack.Sticker sticker) {
+ this(sticker.id(), sticker.emoji(), sticker.contentType());
+ }
+ }
+ }
+}
import org.asamk.signal.manager.api.RecipientIdentifier;
import org.asamk.signal.manager.api.SendGroupMessageResults;
import org.asamk.signal.manager.api.SendMessageResults;
+import org.asamk.signal.manager.api.StickerPack;
import org.asamk.signal.manager.api.TypingAction;
import org.asamk.signal.manager.api.UpdateGroup;
import org.asamk.signal.manager.groups.GroupId;
}
}
+ @Override
+ public List<StickerPack> getStickerPacks() {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public void requestAllSyncData() throws IOException {
signal.sendSyncRequest();