mirror of
https://github.com/AsamK/signal-cli.git
synced 2026-03-14 02:30:15 +00:00
Add --ignore-avatars and --ignore-stickers CLI flags
Implement two new CLI flags to disable downloading avatars and sticker packs during message reception, following the existing pattern of --ignore-attachments and --ignore-stories flags. Changes: - Add --ignore-avatars and --ignore-stickers flags to ReceiveCommand, DaemonCommand, and JsonRpcDispatcherCommand - Extend ReceiveConfig record with ignoreAvatars and ignoreStickers fields - Pass ignoreAvatars as explicit boolean parameter to ProfileHelper, SyncHelper, and GroupHelper methods (per maintainer feedback) - Gate avatar downloads in ProfileHelper (profile avatars), SyncHelper (contact avatars), and GroupHelper (group avatars for V1 and V2) - Gate sticker pack downloads in IncomingMessageHandler for both direct sticker messages and sync sticker pack operations - Update handleSignalServiceDataMessage and handleSyncMessage to pass full ReceiveConfig instead of individual boolean flags - Update man page (signal-cli.1.adoc) with flag documentation - Add entries to CHANGELOG.md When these flags are set, the respective content is not downloaded during message reception. Metadata (avatar paths, sticker pack IDs) is still stored, and existing FileNotFoundException handling will surface if content is later requested but wasn't downloaded. Fixes #1903 Closes #1904
This commit is contained in:
parent
d9f5a573cd
commit
fefca7d837
@ -27,6 +27,8 @@ Requires libsignal-client version 0.86.12.
|
||||
|
||||
- Add sendPollCreate, sendPollVote, sendPollTerminate commands for polls
|
||||
- Add updateDevice command to set device name of linked devices
|
||||
- Add --ignore-avatars flag to prevent downloading avatars
|
||||
- Add --ignore-stickers flag to prevent downloading sticker packs
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
package org.asamk.signal.manager.api;
|
||||
|
||||
public record ReceiveConfig(boolean ignoreAttachments, boolean ignoreStories, boolean sendReadReceipts) {}
|
||||
public record ReceiveConfig(boolean ignoreAttachments, boolean ignoreStories, boolean ignoreAvatars, boolean ignoreStickers, boolean sendReadReceipts) {}
|
||||
|
||||
@ -107,7 +107,10 @@ public class GroupHelper {
|
||||
return group != null && group.isBlocked();
|
||||
}
|
||||
|
||||
public void downloadGroupAvatar(GroupIdV1 groupId, SignalServiceAttachment avatar) {
|
||||
public void downloadGroupAvatar(GroupIdV1 groupId, SignalServiceAttachment avatar, boolean ignoreAvatars) {
|
||||
if (ignoreAvatars) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
context.getAvatarStore()
|
||||
.storeGroupAvatar(groupId,
|
||||
@ -167,7 +170,7 @@ public class GroupHelper {
|
||||
storeProfileKeysFromMembers(group);
|
||||
final var avatar = group.avatar;
|
||||
if (!avatar.isEmpty()) {
|
||||
downloadGroupAvatar(groupId, groupSecretParams, avatar);
|
||||
downloadGroupAvatar(groupId, groupSecretParams, avatar, false);
|
||||
}
|
||||
}
|
||||
groupInfoV2.setGroup(group);
|
||||
@ -506,13 +509,16 @@ public class GroupHelper {
|
||||
storeProfileKeysFromMembers(decryptedGroup);
|
||||
final var avatar = decryptedGroup.avatar;
|
||||
if (!avatar.isEmpty()) {
|
||||
downloadGroupAvatar(groupInfoV2.getGroupId(), groupSecretParams, avatar);
|
||||
downloadGroupAvatar(groupInfoV2.getGroupId(), groupSecretParams, avatar, false);
|
||||
}
|
||||
groupInfoV2.setGroup(decryptedGroup);
|
||||
account.getGroupStore().updateGroup(group);
|
||||
}
|
||||
|
||||
private void downloadGroupAvatar(GroupIdV2 groupId, GroupSecretParams groupSecretParams, String cdnKey) {
|
||||
private void downloadGroupAvatar(GroupIdV2 groupId, GroupSecretParams groupSecretParams, String cdnKey, boolean ignoreAvatars) {
|
||||
if (ignoreAvatars) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
context.getAvatarStore()
|
||||
.storeGroupAvatar(groupId,
|
||||
|
||||
@ -372,7 +372,7 @@ public final class IncomingMessageHandler {
|
||||
false,
|
||||
senderDeviceAddress,
|
||||
destination,
|
||||
receiveConfig.ignoreAttachments()));
|
||||
receiveConfig));
|
||||
}
|
||||
|
||||
if (content.getStoryMessage().isPresent()) {
|
||||
@ -385,7 +385,7 @@ public final class IncomingMessageHandler {
|
||||
actions.addAll(handleSyncMessage(envelope,
|
||||
syncMessage,
|
||||
senderDeviceAddress,
|
||||
receiveConfig.ignoreAttachments()));
|
||||
receiveConfig));
|
||||
}
|
||||
|
||||
return actions;
|
||||
@ -478,7 +478,7 @@ public final class IncomingMessageHandler {
|
||||
final SignalServiceEnvelope envelope,
|
||||
final SignalServiceSyncMessage syncMessage,
|
||||
final DeviceAddress sender,
|
||||
final boolean ignoreAttachments
|
||||
final ReceiveConfig receiveConfig
|
||||
) {
|
||||
var actions = new ArrayList<HandleAction>();
|
||||
account.setMultiDevice(true);
|
||||
@ -494,12 +494,12 @@ public final class IncomingMessageHandler {
|
||||
: new DeviceAddress(account.getRecipientResolver().resolveRecipient(destination),
|
||||
destination.getServiceId(),
|
||||
0),
|
||||
ignoreAttachments));
|
||||
receiveConfig));
|
||||
}
|
||||
if (message.getStoryMessage().isPresent()) {
|
||||
actions.addAll(handleSignalServiceStoryMessage(message.getStoryMessage().get(),
|
||||
sender.recipientId(),
|
||||
ignoreAttachments));
|
||||
receiveConfig.ignoreAttachments()));
|
||||
}
|
||||
}
|
||||
if (syncMessage.getRequest().isPresent() && account.isPrimaryDevice()) {
|
||||
@ -525,7 +525,7 @@ public final class IncomingMessageHandler {
|
||||
try {
|
||||
final var groupsMessage = syncMessage.getGroups().get();
|
||||
context.getAttachmentHelper()
|
||||
.retrieveAttachment(groupsMessage, context.getSyncHelper()::handleSyncDeviceGroups);
|
||||
.retrieveAttachment(groupsMessage, input -> context.getSyncHelper().handleSyncDeviceGroups(input, receiveConfig.ignoreAvatars()));
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed to handle received sync groups, ignoring: {}", e.getMessage());
|
||||
}
|
||||
@ -553,7 +553,7 @@ public final class IncomingMessageHandler {
|
||||
final var contactsMessage = syncMessage.getContacts().get();
|
||||
context.getAttachmentHelper()
|
||||
.retrieveAttachment(contactsMessage.getContactsStream(),
|
||||
context.getSyncHelper()::handleSyncDeviceContacts);
|
||||
input -> context.getSyncHelper().handleSyncDeviceContacts(input, receiveConfig.ignoreAvatars()));
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed to handle received sync contacts, ignoring: {}", e.getMessage());
|
||||
}
|
||||
@ -579,7 +579,7 @@ public final class IncomingMessageHandler {
|
||||
final var sticker = context.getStickerHelper()
|
||||
.addOrUpdateStickerPack(stickerPackId, stickerPackKey, installed);
|
||||
|
||||
if (sticker != null && installed) {
|
||||
if (sticker != null && installed && !receiveConfig.ignoreStickers()) {
|
||||
context.getJobExecutor().enqueueJob(new RetrieveStickerPackJob(stickerPackId, sticker.packKey()));
|
||||
}
|
||||
}
|
||||
@ -741,7 +741,7 @@ public final class IncomingMessageHandler {
|
||||
boolean isSync,
|
||||
DeviceAddress source,
|
||||
DeviceAddress destination,
|
||||
boolean ignoreAttachments
|
||||
ReceiveConfig receiveConfig
|
||||
) {
|
||||
var actions = new ArrayList<HandleAction>();
|
||||
if (message.getGroupContext().isPresent()) {
|
||||
@ -760,7 +760,7 @@ public final class IncomingMessageHandler {
|
||||
|
||||
if (groupInfo.getAvatar().isPresent()) {
|
||||
var avatar = groupInfo.getAvatar().get();
|
||||
context.getGroupHelper().downloadGroupAvatar(groupV1.getGroupId(), avatar);
|
||||
context.getGroupHelper().downloadGroupAvatar(groupV1.getGroupId(), avatar, receiveConfig.ignoreAvatars());
|
||||
}
|
||||
|
||||
if (groupInfo.getName().isPresent()) {
|
||||
@ -833,7 +833,7 @@ public final class IncomingMessageHandler {
|
||||
message.getExpireTimerVersion());
|
||||
}
|
||||
}
|
||||
if (!ignoreAttachments) {
|
||||
if (!receiveConfig.ignoreAttachments()) {
|
||||
if (message.getAttachments().isPresent()) {
|
||||
for (var attachment : message.getAttachments().get()) {
|
||||
context.getAttachmentHelper().downloadAttachment(attachment);
|
||||
@ -881,7 +881,9 @@ public final class IncomingMessageHandler {
|
||||
sticker = new StickerPack(stickerPackId, messageSticker.getPackKey());
|
||||
account.getStickerStore().addStickerPack(sticker);
|
||||
}
|
||||
context.getJobExecutor().enqueueJob(new RetrieveStickerPackJob(stickerPackId, messageSticker.getPackKey()));
|
||||
if (!receiveConfig.ignoreStickers()) {
|
||||
context.getJobExecutor().enqueueJob(new RetrieveStickerPackJob(stickerPackId, messageSticker.getPackKey()));
|
||||
}
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
|
||||
@ -275,10 +275,13 @@ public final class ProfileHelper {
|
||||
private Profile decryptProfileAndDownloadAvatar(
|
||||
final RecipientId recipientId,
|
||||
final ProfileKey profileKey,
|
||||
final SignalServiceProfile encryptedProfile
|
||||
final SignalServiceProfile encryptedProfile,
|
||||
final boolean ignoreAvatars
|
||||
) {
|
||||
final var avatarPath = encryptedProfile.getAvatar();
|
||||
downloadProfileAvatar(recipientId, avatarPath, profileKey);
|
||||
if (!ignoreAvatars) {
|
||||
downloadProfileAvatar(recipientId, avatarPath, profileKey, ignoreAvatars);
|
||||
}
|
||||
|
||||
return ProfileUtils.decryptProfile(profileKey, encryptedProfile);
|
||||
}
|
||||
@ -286,8 +289,12 @@ public final class ProfileHelper {
|
||||
public void downloadProfileAvatar(
|
||||
final RecipientId recipientId,
|
||||
final String avatarPath,
|
||||
final ProfileKey profileKey
|
||||
final ProfileKey profileKey,
|
||||
final boolean ignoreAvatars
|
||||
) {
|
||||
if (ignoreAvatars) {
|
||||
return;
|
||||
}
|
||||
var profile = account.getProfileStore().getProfile(recipientId);
|
||||
if (profile == null || !Objects.equals(avatarPath, profile.getAvatarUrlPath())) {
|
||||
logger.trace("Downloading profile avatar for {}", recipientId);
|
||||
@ -341,7 +348,7 @@ public final class ProfileHelper {
|
||||
Profile newProfile = null;
|
||||
if (profileKey.isPresent()) {
|
||||
logger.trace("Decrypting profile");
|
||||
newProfile = decryptProfileAndDownloadAvatar(recipientId, profileKey.get(), encryptedProfile);
|
||||
newProfile = decryptProfileAndDownloadAvatar(recipientId, profileKey.get(), encryptedProfile, false);
|
||||
}
|
||||
|
||||
if (newProfile == null) {
|
||||
|
||||
@ -40,7 +40,7 @@ public class ReceiveHelper {
|
||||
private final SignalDependencies dependencies;
|
||||
private final Context context;
|
||||
|
||||
private ReceiveConfig receiveConfig = new ReceiveConfig(false, false, false);
|
||||
private ReceiveConfig receiveConfig = new ReceiveConfig(false, false, false, false, false);
|
||||
private boolean hasCaughtUpWithOldMessages = false;
|
||||
private boolean isWaitingForMessage = false;
|
||||
private boolean shouldStop = false;
|
||||
|
||||
@ -293,7 +293,7 @@ public class SyncHelper {
|
||||
return context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forConfiguration(configurationMessage));
|
||||
}
|
||||
|
||||
public void handleSyncDeviceGroups(final InputStream input) {
|
||||
public void handleSyncDeviceGroups(final InputStream input, final boolean ignoreAvatars) {
|
||||
final var s = new DeviceGroupsInputStream(input);
|
||||
DeviceGroup g;
|
||||
while (true) {
|
||||
@ -327,7 +327,7 @@ public class SyncHelper {
|
||||
}
|
||||
|
||||
if (g.getAvatar().isPresent()) {
|
||||
context.getGroupHelper().downloadGroupAvatar(syncGroup.getGroupId(), g.getAvatar().get());
|
||||
context.getGroupHelper().downloadGroupAvatar(syncGroup.getGroupId(), g.getAvatar().get(), ignoreAvatars);
|
||||
}
|
||||
syncGroup.archived = g.isArchived();
|
||||
account.getGroupStore().updateGroup(syncGroup);
|
||||
@ -335,7 +335,7 @@ public class SyncHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public void handleSyncDeviceContacts(final InputStream input) throws IOException {
|
||||
public void handleSyncDeviceContacts(final InputStream input, final boolean ignoreAvatars) throws IOException {
|
||||
final var s = new DeviceContactsInputStream(input);
|
||||
DeviceContact c;
|
||||
while (true) {
|
||||
@ -381,7 +381,7 @@ public class SyncHelper {
|
||||
account.getContactStore().storeContact(recipientId, builder.build());
|
||||
|
||||
if (c.getAvatar().isPresent()) {
|
||||
storeContactAvatar(c.getAvatar().get(), address);
|
||||
storeContactAvatar(c.getAvatar().get(), address, ignoreAvatars);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -430,7 +430,10 @@ public class SyncHelper {
|
||||
streamDetails.getContentType()));
|
||||
}
|
||||
|
||||
private void storeContactAvatar(DeviceContactAvatar avatar, RecipientAddress address) {
|
||||
private void storeContactAvatar(DeviceContactAvatar avatar, RecipientAddress address, boolean ignoreAvatars) {
|
||||
if (ignoreAvatars) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
context.getAvatarStore()
|
||||
.storeContactAvatar(address,
|
||||
|
||||
@ -18,6 +18,6 @@ public class DownloadProfileAvatarJob implements Job {
|
||||
logger.trace("Downloading profile avatar {}", avatarPath);
|
||||
final var account = context.getAccount();
|
||||
context.getProfileHelper()
|
||||
.downloadProfileAvatar(account.getSelfRecipientId(), avatarPath, account.getProfileKey());
|
||||
.downloadProfileAvatar(account.getSelfRecipientId(), avatarPath, account.getProfileKey(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -587,6 +587,12 @@ Don’t download attachments of received messages.
|
||||
*--ignore-stories*::
|
||||
Don’t receive story messages from the server.
|
||||
|
||||
*--ignore-avatars*::
|
||||
Don't download avatars of received messages.
|
||||
|
||||
*--ignore-stickers*::
|
||||
Don't download sticker packs of received messages.
|
||||
|
||||
|
||||
*--send-read-receipts*::
|
||||
Send read receipts for all incoming data messages (in addition to the default delivery receipts)
|
||||
@ -950,6 +956,12 @@ Don’t download attachments of received messages.
|
||||
*--ignore-stories*::
|
||||
Don’t receive story messages from the server.
|
||||
|
||||
*--ignore-avatars*::
|
||||
Don't download avatars of received messages.
|
||||
|
||||
*--ignore-stickers*::
|
||||
Don't download sticker packs of received messages.
|
||||
|
||||
*--send-read-receipts*::
|
||||
Send read receipts for all incoming data messages (in addition to the default delivery receipts)
|
||||
|
||||
@ -971,6 +983,12 @@ Don’t download attachments of received messages.
|
||||
*--ignore-stories*::
|
||||
Don’t receive story messages from the server.
|
||||
|
||||
*--ignore-avatars*::
|
||||
Don't download avatars of received messages.
|
||||
|
||||
*--ignore-stickers*::
|
||||
Don't download sticker packs of received messages.
|
||||
|
||||
*--send-read-receipts*::
|
||||
Send read receipts for all incoming data messages (in addition to the default delivery receipts)
|
||||
|
||||
|
||||
@ -82,6 +82,12 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand {
|
||||
subparser.addArgument("--ignore-stories")
|
||||
.help("Don’t receive story messages from the server.")
|
||||
.action(Arguments.storeTrue());
|
||||
subparser.addArgument("--ignore-avatars")
|
||||
.help("Don't download avatars of received messages.")
|
||||
.action(Arguments.storeTrue());
|
||||
subparser.addArgument("--ignore-stickers")
|
||||
.help("Don't download sticker packs of received messages.")
|
||||
.action(Arguments.storeTrue());
|
||||
subparser.addArgument("--send-read-receipts")
|
||||
.help("Send read receipts for all incoming data messages (in addition to the default delivery receipts)")
|
||||
.action(Arguments.storeTrue());
|
||||
|
||||
@ -44,6 +44,12 @@ public class JsonRpcDispatcherCommand implements LocalCommand, MultiLocalCommand
|
||||
subparser.addArgument("--ignore-stories")
|
||||
.help("Don’t receive story messages from the server.")
|
||||
.action(Arguments.storeTrue());
|
||||
subparser.addArgument("--ignore-avatars")
|
||||
.help("Don't download avatars of received messages.")
|
||||
.action(Arguments.storeTrue());
|
||||
subparser.addArgument("--ignore-stickers")
|
||||
.help("Don't download sticker packs of received messages.")
|
||||
.action(Arguments.storeTrue());
|
||||
subparser.addArgument("--send-read-receipts")
|
||||
.help("Send read receipts for all incoming data messages (in addition to the default delivery receipts)")
|
||||
.action(Arguments.storeTrue());
|
||||
|
||||
@ -55,6 +55,12 @@ public class ReceiveCommand implements LocalCommand, JsonRpcSingleCommand<Receiv
|
||||
subparser.addArgument("--ignore-stories")
|
||||
.help("Don’t receive story messages from the server.")
|
||||
.action(Arguments.storeTrue());
|
||||
subparser.addArgument("--ignore-avatars")
|
||||
.help("Don't download avatars of received messages.")
|
||||
.action(Arguments.storeTrue());
|
||||
subparser.addArgument("--ignore-stickers")
|
||||
.help("Don't download sticker packs of received messages.")
|
||||
.action(Arguments.storeTrue());
|
||||
subparser.addArgument("--send-read-receipts")
|
||||
.help("Send read receipts for all incoming data messages (in addition to the default delivery receipts)")
|
||||
.action(Arguments.storeTrue());
|
||||
@ -76,8 +82,10 @@ public class ReceiveCommand implements LocalCommand, JsonRpcSingleCommand<Receiv
|
||||
final var maxMessagesRaw = ns.getInt("max-messages");
|
||||
final var ignoreAttachments = Boolean.TRUE.equals(ns.getBoolean("ignore-attachments"));
|
||||
final var ignoreStories = Boolean.TRUE.equals(ns.getBoolean("ignore-stories"));
|
||||
final var ignoreAvatars = Boolean.TRUE.equals(ns.getBoolean("ignore-avatars"));
|
||||
final var ignoreStickers = Boolean.TRUE.equals(ns.getBoolean("ignore-stickers"));
|
||||
final var sendReadReceipts = Boolean.TRUE.equals(ns.getBoolean("send-read-receipts"));
|
||||
m.setReceiveConfig(new ReceiveConfig(ignoreAttachments, ignoreStories, sendReadReceipts));
|
||||
m.setReceiveConfig(new ReceiveConfig(ignoreAttachments, ignoreStories, ignoreAvatars, ignoreStickers, sendReadReceipts));
|
||||
try {
|
||||
final var handler = switch (outputWriter) {
|
||||
case JsonWriter writer -> new JsonReceiveMessageHandler(m, writer);
|
||||
|
||||
@ -146,8 +146,10 @@ public class CommandUtil {
|
||||
public static ReceiveConfig getReceiveConfig(final Namespace ns) {
|
||||
final var ignoreAttachments = Boolean.TRUE.equals(ns.getBoolean("ignore-attachments"));
|
||||
final var ignoreStories = Boolean.TRUE.equals(ns.getBoolean("ignore-stories"));
|
||||
final var ignoreAvatars = Boolean.TRUE.equals(ns.getBoolean("ignore-avatars"));
|
||||
final var ignoreStickers = Boolean.TRUE.equals(ns.getBoolean("ignore-stickers"));
|
||||
final var sendReadReceipts = Boolean.TRUE.equals(ns.getBoolean("send-read-receipts"));
|
||||
|
||||
return new ReceiveConfig(ignoreAttachments, ignoreStories, sendReadReceipts);
|
||||
return new ReceiveConfig(ignoreAttachments, ignoreStories, ignoreAvatars, ignoreStickers, sendReadReceipts);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user