Add support for sending stickers

This commit is contained in:
AsamK 2022-01-03 13:24:13 +01:00
parent 5d83e149b3
commit 404063a080
11 changed files with 141 additions and 35 deletions

View file

@ -9,6 +9,7 @@ import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
import org.asamk.signal.commands.exceptions.UserErrorException;
import org.asamk.signal.manager.AttachmentInvalidException;
import org.asamk.signal.manager.Manager;
import org.asamk.signal.manager.api.InvalidStickerException;
import org.asamk.signal.manager.api.Message;
import org.asamk.signal.manager.api.RecipientIdentifier;
import org.asamk.signal.manager.api.UnregisteredRecipientException;
@ -17,6 +18,7 @@ import org.asamk.signal.manager.groups.GroupSendingNotAllowedException;
import org.asamk.signal.manager.groups.NotAGroupMemberException;
import org.asamk.signal.output.OutputWriter;
import org.asamk.signal.util.CommandUtil;
import org.asamk.signal.util.Hex;
import org.asamk.signal.util.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -65,6 +67,7 @@ public class SendCommand implements JsonRpcLocalCommand {
subparser.addArgument("--quote-mention")
.nargs("*")
.help("Quote with mention of another group member (syntax: start:length:recipientNumber)");
subparser.addArgument("--sticker").help("Send a sticker (syntax: stickerPackId:stickerId)");
}
@Override
@ -100,13 +103,20 @@ public class SendCommand implements JsonRpcLocalCommand {
}
}
final var stickerString = ns.getString("sticker");
final var sticker = stickerString == null ? null : parseSticker(stickerString);
var messageText = ns.getString("message");
if (messageText == null) {
logger.debug("Reading message from stdin...");
try {
messageText = IOUtils.readAll(System.in, Charset.defaultCharset());
} catch (IOException e) {
throw new UserErrorException("Failed to read message from stdin: " + e.getMessage());
if (sticker != null) {
messageText = "";
} else {
logger.debug("Reading message from stdin...");
try {
messageText = IOUtils.readAll(System.in, Charset.defaultCharset());
} catch (IOException e) {
throw new UserErrorException("Failed to read message from stdin: " + e.getMessage());
}
}
}
@ -129,15 +139,18 @@ public class SendCommand implements JsonRpcLocalCommand {
: parseMentions(m, quoteMentionStrings);
quote = new Message.Quote(quoteTimestamp,
CommandUtil.getSingleRecipientIdentifier(quoteAuthor, m.getSelfNumber()),
quoteMessage,
quoteMessage == null ? "" : quoteMessage,
quoteMentions);
} else {
quote = null;
}
try {
var results = m.sendMessage(new Message(messageText, attachments, mentions, Optional.ofNullable(quote)),
recipientIdentifiers);
var results = m.sendMessage(new Message(messageText,
attachments,
mentions,
Optional.ofNullable(quote),
Optional.ofNullable(sticker)), recipientIdentifiers);
outputResult(outputWriter, results);
} catch (AttachmentInvalidException | IOException e) {
throw new UnexpectedErrorException("Failed to send message: " + e.getMessage() + " (" + e.getClass()
@ -146,6 +159,8 @@ public class SendCommand implements JsonRpcLocalCommand {
throw new UserErrorException(e.getMessage());
} catch (UnregisteredRecipientException e) {
throw new UserErrorException("The user " + e.getSender().getIdentifier() + " is not registered.");
} catch (InvalidStickerException e) {
throw new UserErrorException("Failed to send sticker: " + e.getMessage(), e);
}
}
@ -167,4 +182,15 @@ public class SendCommand implements JsonRpcLocalCommand {
}
return mentions;
}
private Message.Sticker parseSticker(final String stickerString) throws UserErrorException {
final Pattern stickerPattern = Pattern.compile("([0-9a-f]+):([0-9]+)");
final var matcher = stickerPattern.matcher(stickerString);
if (!matcher.matches() || matcher.group(1).length() % 2 != 0) {
throw new UserErrorException("Invalid sticker syntax ("
+ stickerString
+ ") expected 'stickerPackId:stickerId'");
}
return new Message.Sticker(Hex.toByteArray(matcher.group(1)), Integer.parseInt(matcher.group(2)));
}
}

View file

@ -10,6 +10,7 @@ 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.InvalidNumberException;
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;
@ -199,7 +200,11 @@ public class DbusSignalImpl implements Signal {
@Override
public long sendMessage(final String message, final List<String> attachments, final List<String> recipients) {
try {
final var results = m.sendMessage(new Message(message, attachments, List.of(), Optional.empty()),
final var results = m.sendMessage(new Message(message,
attachments,
List.of(),
Optional.empty(),
Optional.empty()),
getSingleRecipientIdentifiers(recipients, m.getSelfNumber()).stream()
.map(RecipientIdentifier.class::cast)
.collect(Collectors.toSet()));
@ -208,7 +213,7 @@ public class DbusSignalImpl implements Signal {
return results.timestamp();
} catch (AttachmentInvalidException e) {
throw new Error.AttachmentInvalid(e.getMessage());
} catch (IOException e) {
} catch (IOException | InvalidStickerException e) {
throw new Error.Failure(e);
} catch (GroupNotFoundException | NotAGroupMemberException | GroupSendingNotAllowedException e) {
throw new Error.GroupNotFound(e.getMessage());
@ -346,13 +351,16 @@ public class DbusSignalImpl implements Signal {
final String message, final List<String> attachments
) throws Error.AttachmentInvalid, Error.Failure, Error.UntrustedIdentity {
try {
final var results = m.sendMessage(new Message(message, attachments, List.of(), Optional.empty()),
Set.of(RecipientIdentifier.NoteToSelf.INSTANCE));
final var results = m.sendMessage(new Message(message,
attachments,
List.of(),
Optional.empty(),
Optional.empty()), Set.of(RecipientIdentifier.NoteToSelf.INSTANCE));
checkSendMessageResults(results);
return results.timestamp();
} catch (AttachmentInvalidException e) {
throw new Error.AttachmentInvalid(e.getMessage());
} catch (IOException e) {
} catch (IOException | InvalidStickerException e) {
throw new Error.Failure(e.getMessage());
} catch (GroupNotFoundException | NotAGroupMemberException | GroupSendingNotAllowedException e) {
throw new Error.GroupNotFound(e.getMessage());
@ -384,11 +392,14 @@ public class DbusSignalImpl implements Signal {
@Override
public long sendGroupMessage(final String message, final List<String> attachments, final byte[] groupId) {
try {
var results = m.sendMessage(new Message(message, attachments, List.of(), Optional.empty()),
Set.of(getGroupRecipientIdentifier(groupId)));
var results = m.sendMessage(new Message(message,
attachments,
List.of(),
Optional.empty(),
Optional.empty()), Set.of(getGroupRecipientIdentifier(groupId)));
checkSendMessageResults(results);
return results.timestamp();
} catch (IOException e) {
} catch (IOException | InvalidStickerException e) {
throw new Error.Failure(e.getMessage());
} catch (GroupNotFoundException | NotAGroupMemberException | GroupSendingNotAllowedException e) {
throw new Error.GroupNotFound(e.getMessage());