Send remote delete (#593)
* Implementation of remoteDelete command, iteration 1 * Implementation of remoteDelete command, iteration 2 * Implementation of remoteDelete command, iteration 3 * Implementation of remoteDelete command, iteration 4 * Implementation of remoteDelete command, iteration 5 * Implementation of remoteDelete command, iteration 6 * Renaming dbus methods remoteGroupDelete -> sendGroupRemoteDeleteMessage, remoteDelete -> sendRemoteDeleteMessage
This commit is contained in:
		
							parent
							
								
									2ad18342a8
								
							
						
					
					
						commit
						05abb3f9f6
					
				@ -992,6 +992,22 @@ public class Manager implements Closeable {
 | 
			
		||||
        return sendSelfMessage(messageBuilder);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Pair<Long, List<SendMessageResult>> sendRemoteDeleteMessage(
 | 
			
		||||
            long targetSentTimestamp, List<String> recipients
 | 
			
		||||
    ) throws IOException, InvalidNumberException {
 | 
			
		||||
        var delete = new SignalServiceDataMessage.RemoteDelete(targetSentTimestamp);
 | 
			
		||||
        final var messageBuilder = SignalServiceDataMessage.newBuilder().withRemoteDelete(delete);
 | 
			
		||||
        return sendMessage(messageBuilder, getSignalServiceAddresses(recipients));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Pair<Long, List<SendMessageResult>> sendGroupRemoteDeleteMessage(
 | 
			
		||||
            long targetSentTimestamp, GroupId groupId
 | 
			
		||||
    ) throws IOException, NotAGroupMemberException, GroupNotFoundException {
 | 
			
		||||
        var delete = new SignalServiceDataMessage.RemoteDelete(targetSentTimestamp);
 | 
			
		||||
        final var messageBuilder = SignalServiceDataMessage.newBuilder().withRemoteDelete(delete);
 | 
			
		||||
        return sendGroupMessage(messageBuilder, groupId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Pair<Long, List<SendMessageResult>> sendMessageReaction(
 | 
			
		||||
            String emoji, boolean remove, String targetAuthor, long targetSentTimestamp, List<String> recipients
 | 
			
		||||
    ) throws IOException, InvalidNumberException {
 | 
			
		||||
 | 
			
		||||
@ -149,6 +149,24 @@ Depending on the type of the recipient(s) field this sends a reaction to one or
 | 
			
		||||
 | 
			
		||||
Exceptions: Failure, InvalidNumber
 | 
			
		||||
 | 
			
		||||
sendGroupRemoteDeleteMessage(targetSentTimestamp<x>, groupId<ay>) -> timestamp<x>::
 | 
			
		||||
* targetSentTimestamp : Long representing timestamp of the message to delete
 | 
			
		||||
* groupId             : Byte array with base64 encoded group identifier
 | 
			
		||||
* timestamp           : Long, can be used to identify the corresponding signal reply
 | 
			
		||||
 | 
			
		||||
Exceptions: Failure, GroupNotFound
 | 
			
		||||
 | 
			
		||||
sendRemoteDeleteMessage(targetSentTimestamp<x>, recipient<s>) -> timestamp<x>::
 | 
			
		||||
sendRemoteDeleteMessage(targetSentTimestamp<x>, recipients<as>) -> timestamp<x>::
 | 
			
		||||
* targetSentTimestamp : Long representing timestamp of the message to delete
 | 
			
		||||
* recipient           : String with the phone number of a single recipient
 | 
			
		||||
* recipients          : Array of strings with phone numbers, should there be more recipients
 | 
			
		||||
* timestamp           : Long, can be used to identify the corresponding signal reply
 | 
			
		||||
 | 
			
		||||
Depending on the type of the recipient(s) field this deletes a message with one or multiple recipients.
 | 
			
		||||
 | 
			
		||||
Exceptions: Failure, InvalidNumber
 | 
			
		||||
 | 
			
		||||
getContactName(number<s>) -> name<s>::
 | 
			
		||||
* number  : Phone number
 | 
			
		||||
* name    : Contact's name in local storage (from the master device for a linked account, or the one set with setContactName); if not set, contact's profile name is used
 | 
			
		||||
 | 
			
		||||
@ -193,6 +193,19 @@ Specify the timestamp of the message to which to react.
 | 
			
		||||
*-r*, *--remove*::
 | 
			
		||||
Remove a reaction.
 | 
			
		||||
 | 
			
		||||
=== remoteDelete
 | 
			
		||||
 | 
			
		||||
Remotely delete a previously sent message.
 | 
			
		||||
 | 
			
		||||
RECIPIENT::
 | 
			
		||||
Specify the recipients’ phone number.
 | 
			
		||||
 | 
			
		||||
*-g* GROUP, *--group* GROUP::
 | 
			
		||||
Specify the recipient group ID in base64 encoding.
 | 
			
		||||
 | 
			
		||||
*-t* TIMESTAMP, *--target-timestamp* TIMESTAMP::
 | 
			
		||||
Specify the timestamp of the message to delete.
 | 
			
		||||
 | 
			
		||||
=== receive
 | 
			
		||||
 | 
			
		||||
Query the server for new messages.
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,18 @@ public interface Signal extends DBusInterface {
 | 
			
		||||
            String message, List<String> attachments, List<String> recipients
 | 
			
		||||
    ) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.UntrustedIdentity;
 | 
			
		||||
 | 
			
		||||
    long sendRemoteDeleteMessage(
 | 
			
		||||
            long targetSentTimestamp, String recipient
 | 
			
		||||
    ) throws Error.Failure, Error.InvalidNumber;
 | 
			
		||||
 | 
			
		||||
    long sendRemoteDeleteMessage(
 | 
			
		||||
            long targetSentTimestamp, List<String> recipients
 | 
			
		||||
    ) throws Error.Failure, Error.InvalidNumber;
 | 
			
		||||
 | 
			
		||||
    long sendGroupRemoteDeleteMessage(
 | 
			
		||||
            long targetSentTimestamp, byte[] groupId
 | 
			
		||||
    ) throws Error.Failure, Error.GroupNotFound;
 | 
			
		||||
 | 
			
		||||
    long sendMessageReaction(
 | 
			
		||||
            String emoji, boolean remove, String targetAuthor, long targetSentTimestamp, String recipient
 | 
			
		||||
    ) throws Error.InvalidNumber, Error.Failure;
 | 
			
		||||
 | 
			
		||||
@ -22,20 +22,21 @@ public class Commands {
 | 
			
		||||
        addCommand("receive", new ReceiveCommand());
 | 
			
		||||
        addCommand("register", new RegisterCommand());
 | 
			
		||||
        addCommand("removeDevice", new RemoveDeviceCommand());
 | 
			
		||||
        addCommand("remoteDelete", new RemoteDeleteCommand());
 | 
			
		||||
        addCommand("removePin", new RemovePinCommand());
 | 
			
		||||
        addCommand("send", new SendCommand());
 | 
			
		||||
        addCommand("sendReaction", new SendReactionCommand());
 | 
			
		||||
        addCommand("sendContacts", new SendContactsCommand());
 | 
			
		||||
        addCommand("updateContact", new UpdateContactCommand());
 | 
			
		||||
        addCommand("sendReaction", new SendReactionCommand());
 | 
			
		||||
        addCommand("setPin", new SetPinCommand());
 | 
			
		||||
        addCommand("trust", new TrustCommand());
 | 
			
		||||
        addCommand("unblock", new UnblockCommand());
 | 
			
		||||
        addCommand("unregister", new UnregisterCommand());
 | 
			
		||||
        addCommand("updateAccount", new UpdateAccountCommand());
 | 
			
		||||
        addCommand("updateContact", new UpdateContactCommand());
 | 
			
		||||
        addCommand("updateGroup", new UpdateGroupCommand());
 | 
			
		||||
        addCommand("updateProfile", new UpdateProfileCommand());
 | 
			
		||||
        addCommand("verify", new VerifyCommand());
 | 
			
		||||
        addCommand("uploadStickerPack", new UploadStickerPackCommand());
 | 
			
		||||
        addCommand("verify", new VerifyCommand());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Map<String, Command> getCommands() {
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,82 @@
 | 
			
		||||
package org.asamk.signal.commands;
 | 
			
		||||
 | 
			
		||||
import net.sourceforge.argparse4j.inf.Namespace;
 | 
			
		||||
import net.sourceforge.argparse4j.inf.Subparser;
 | 
			
		||||
 | 
			
		||||
import org.asamk.Signal;
 | 
			
		||||
import org.asamk.signal.PlainTextWriterImpl;
 | 
			
		||||
import org.asamk.signal.commands.exceptions.CommandException;
 | 
			
		||||
import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
 | 
			
		||||
import org.asamk.signal.commands.exceptions.UserErrorException;
 | 
			
		||||
import org.asamk.signal.manager.groups.GroupIdFormatException;
 | 
			
		||||
import org.asamk.signal.util.Util;
 | 
			
		||||
import org.freedesktop.dbus.errors.UnknownObject;
 | 
			
		||||
import org.freedesktop.dbus.exceptions.DBusExecutionException;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import static org.asamk.signal.util.ErrorUtils.handleAssertionError;
 | 
			
		||||
 | 
			
		||||
public class RemoteDeleteCommand implements DbusCommand {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void attachToSubparser(final Subparser subparser) {
 | 
			
		||||
        subparser.help("Remotely delete a previously sent message.");
 | 
			
		||||
        subparser.addArgument("-t", "--target-timestamp")
 | 
			
		||||
                .required(true)
 | 
			
		||||
                .type(long.class)
 | 
			
		||||
                .help("Specify the timestamp of the message to delete.");
 | 
			
		||||
        subparser.addArgument("-g", "--group")
 | 
			
		||||
                .help("Specify the recipient group ID.");
 | 
			
		||||
        subparser.addArgument("recipient")
 | 
			
		||||
                .help("Specify the recipients' phone number.").nargs("*");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void handleCommand(final Namespace ns, final Signal signal) throws CommandException {
 | 
			
		||||
        final List<String> recipients = ns.getList("recipient");
 | 
			
		||||
        final var groupIdString = ns.getString("group");
 | 
			
		||||
 | 
			
		||||
        final var noRecipients = recipients == null || recipients.isEmpty();
 | 
			
		||||
        if (noRecipients && groupIdString == null) {
 | 
			
		||||
            throw new UserErrorException("No recipients given");
 | 
			
		||||
        }
 | 
			
		||||
        if (!noRecipients && groupIdString != null) {
 | 
			
		||||
            throw new UserErrorException("You cannot specify recipients by phone number and groups at the same time");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final long targetTimestamp = ns.getLong("target_timestamp");
 | 
			
		||||
 | 
			
		||||
        final var writer = new PlainTextWriterImpl(System.out);
 | 
			
		||||
 | 
			
		||||
        byte[] groupId = null;
 | 
			
		||||
        if (groupIdString != null) {
 | 
			
		||||
            try {
 | 
			
		||||
                groupId = Util.decodeGroupId(groupIdString).serialize();
 | 
			
		||||
            } catch (GroupIdFormatException e) {
 | 
			
		||||
                throw new UserErrorException("Invalid group id: " + e.getMessage());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            long timestamp;
 | 
			
		||||
            if (groupId != null) {
 | 
			
		||||
                timestamp = signal.sendGroupRemoteDeleteMessage(targetTimestamp, groupId);
 | 
			
		||||
            } else {
 | 
			
		||||
                timestamp = signal.sendRemoteDeleteMessage(targetTimestamp, recipients);
 | 
			
		||||
            }
 | 
			
		||||
            writer.println("{}", timestamp);
 | 
			
		||||
        } catch (AssertionError e) {
 | 
			
		||||
            handleAssertionError(e);
 | 
			
		||||
            throw e;
 | 
			
		||||
        } catch (UnknownObject e) {
 | 
			
		||||
            throw new UserErrorException("Failed to find dbus object, maybe missing the -u flag: " + e.getMessage());
 | 
			
		||||
        } catch (Signal.Error.InvalidNumber e) {
 | 
			
		||||
            throw new UserErrorException("Invalid number: " + e.getMessage());
 | 
			
		||||
        } catch (Signal.Error.GroupNotFound e) {
 | 
			
		||||
            throw new UserErrorException("Failed to send to group: " + e.getMessage());
 | 
			
		||||
        } catch (DBusExecutionException e) {
 | 
			
		||||
            throw new UnexpectedErrorException("Failed to send message: " + e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -103,6 +103,45 @@ public class DbusSignalImpl implements Signal {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public long sendRemoteDeleteMessage(
 | 
			
		||||
            final long targetSentTimestamp, final String recipient
 | 
			
		||||
    ) {
 | 
			
		||||
        var recipients = new ArrayList<String>(1);
 | 
			
		||||
        recipients.add(recipient);
 | 
			
		||||
        return sendRemoteDeleteMessage(targetSentTimestamp, recipients);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public long sendRemoteDeleteMessage(
 | 
			
		||||
            final long targetSentTimestamp, final List<String> recipients
 | 
			
		||||
    ) {
 | 
			
		||||
        try {
 | 
			
		||||
            final var results = m.sendRemoteDeleteMessage(targetSentTimestamp, recipients);
 | 
			
		||||
            checkSendMessageResults(results.first(), results.second());
 | 
			
		||||
            return results.first();
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            throw new Error.Failure(e.getMessage());
 | 
			
		||||
        } catch (InvalidNumberException e) {
 | 
			
		||||
            throw new Error.InvalidNumber(e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public long sendGroupRemoteDeleteMessage(
 | 
			
		||||
            final long targetSentTimestamp, final byte[] groupId
 | 
			
		||||
    ) {
 | 
			
		||||
        try {
 | 
			
		||||
            final var results = m.sendGroupRemoteDeleteMessage(targetSentTimestamp, GroupId.unknownVersion(groupId));
 | 
			
		||||
            checkSendMessageResults(results.first(), results.second());
 | 
			
		||||
            return results.first();
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            throw new Error.Failure(e.getMessage());
 | 
			
		||||
        } catch (GroupNotFoundException | NotAGroupMemberException e) {
 | 
			
		||||
            throw new Error.GroupNotFound(e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public long sendMessageReaction(
 | 
			
		||||
            final String emoji, final boolean remove, final String targetAuthor, final long targetSentTimestamp, final String recipient
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user