/*
- Copyright (C) 2015-2021 AsamK and contributors
+ Copyright (C) 2015-2022 AsamK and contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
import org.asamk.signal.manager.api.Identity;
import org.asamk.signal.manager.api.InactiveGroupLinkException;
import org.asamk.signal.manager.api.InvalidDeviceLinkException;
+import org.asamk.signal.manager.api.InvalidStickerException;
import org.asamk.signal.manager.api.Message;
import org.asamk.signal.manager.api.Pair;
import org.asamk.signal.manager.api.RecipientIdentifier;
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.StickerPackId;
+import org.asamk.signal.manager.api.StickerPackUrl;
import org.asamk.signal.manager.api.TypingAction;
import org.asamk.signal.manager.api.UnregisteredRecipientException;
import org.asamk.signal.manager.api.UpdateGroup;
import org.asamk.signal.manager.storage.recipients.RecipientAddress;
import org.asamk.signal.manager.storage.recipients.RecipientId;
import org.asamk.signal.manager.storage.stickers.Sticker;
-import org.asamk.signal.manager.storage.stickers.StickerPackId;
+import org.asamk.signal.manager.util.AttachmentUtils;
import org.asamk.signal.manager.util.KeyUtils;
import org.asamk.signal.manager.util.StickerUtils;
import org.slf4j.Logger;
import java.io.File;
import java.io.IOException;
import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
@Override
public SendMessageResults sendMessage(
Message message, Set<RecipientIdentifier> recipients
- ) throws IOException, AttachmentInvalidException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException, UnregisteredRecipientException {
+ ) throws IOException, AttachmentInvalidException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException, UnregisteredRecipientException, InvalidStickerException {
final var messageBuilder = SignalServiceDataMessage.newBuilder();
applyMessage(messageBuilder, message);
return sendMessage(messageBuilder, recipients);
private void applyMessage(
final SignalServiceDataMessage.Builder messageBuilder, final Message message
- ) throws AttachmentInvalidException, IOException, UnregisteredRecipientException {
+ ) throws AttachmentInvalidException, IOException, UnregisteredRecipientException, InvalidStickerException {
messageBuilder.withBody(message.messageText());
final var attachments = message.attachments();
if (attachments != null) {
List.of(),
resolveMentions(quote.mentions())));
}
+ if (message.sticker().isPresent()) {
+ final var sticker = message.sticker().get();
+ final var packId = StickerPackId.deserialize(sticker.packId());
+ final var stickerId = sticker.stickerId();
+
+ final var stickerPack = context.getAccount().getStickerStore().getStickerPack(packId);
+ if (stickerPack == null) {
+ throw new InvalidStickerException("Sticker pack not found");
+ }
+ final var manifest = context.getStickerHelper().getOrRetrieveStickerPack(packId, stickerPack.getPackKey());
+ if (manifest.stickers().size() <= stickerId) {
+ throw new InvalidStickerException("Sticker id not part of this pack");
+ }
+ final var manifestSticker = manifest.stickers().get(stickerId);
+ final var streamDetails = context.getStickerPackStore().retrieveSticker(packId, stickerId);
+ if (streamDetails == null) {
+ throw new InvalidStickerException("Missing local sticker file");
+ }
+ messageBuilder.withSticker(new SignalServiceDataMessage.Sticker(packId.serialize(),
+ stickerPack.getPackKey(),
+ stickerId,
+ manifestSticker.emoji(),
+ AttachmentUtils.createAttachment(streamDetails, Optional.absent())));
+ }
}
private ArrayList<SignalServiceDataMessage.Mention> resolveMentions(final List<Message.Mention> mentionList) throws IOException, UnregisteredRecipientException {
}
@Override
- public URI uploadStickerPack(File path) throws IOException, StickerPackInvalidException {
+ public StickerPackUrl uploadStickerPack(File path) throws IOException, StickerPackInvalidException {
var manifest = StickerUtils.getSignalServiceStickerManifestUpload(path);
var messageSender = dependencies.getMessageSender();
var sticker = new Sticker(packId, packKey);
account.getStickerStore().updateSticker(sticker);
- try {
- return new URI("https",
- "signal.art",
- "/addstickers/",
- "pack_id="
- + URLEncoder.encode(Hex.toStringCondensed(packId.serialize()), StandardCharsets.UTF_8)
- + "&pack_key="
- + URLEncoder.encode(Hex.toStringCondensed(packKey), StandardCharsets.UTF_8));
- } catch (URISyntaxException e) {
- throw new AssertionError(e);
- }
+ return new StickerPackUrl(packId, packKey);
+ }
+
+ @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(),
+ new StickerPackUrl(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