Make send behavior more deterministic if there are unregistered recipients

Fixes #803
This commit is contained in:
AsamK 2021-11-14 14:42:17 +01:00
parent fa5c09d23b
commit 382d8d22d0
10 changed files with 192 additions and 136 deletions

View file

@ -83,7 +83,9 @@ public class SendCommand implements JsonRpcLocalCommand {
}
try {
m.sendEndSessionMessage(singleRecipients);
final var results = m.sendEndSessionMessage(singleRecipients);
outputResult(outputWriter, results.timestamp());
ErrorUtils.handleSendMessageResults(results.results());
return;
} catch (IOException e) {
throw new UnexpectedErrorException("Failed to send message: " + e.getMessage() + " (" + e.getClass()

View file

@ -3,14 +3,18 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.JsonWriter;
import org.asamk.signal.OutputWriter;
import org.asamk.signal.PlainTextWriter;
import org.asamk.signal.commands.exceptions.CommandException;
import org.asamk.signal.commands.exceptions.UserErrorException;
import org.asamk.signal.manager.Manager;
import org.asamk.signal.manager.UntrustedIdentityException;
import org.asamk.signal.manager.api.SendMessageResults;
import org.asamk.signal.util.CommandUtil;
import org.asamk.signal.util.ErrorUtils;
import java.io.IOException;
import java.util.Map;
public class SendReceiptCommand implements JsonRpcLocalCommand {
@ -43,16 +47,28 @@ public class SendReceiptCommand implements JsonRpcLocalCommand {
final var type = ns.getString("type");
try {
final SendMessageResults results;
if (type == null || "read".equals(type)) {
m.sendReadReceipt(recipient, targetTimestamps);
results = m.sendReadReceipt(recipient, targetTimestamps);
} else if ("viewed".equals(type)) {
m.sendViewedReceipt(recipient, targetTimestamps);
results = m.sendViewedReceipt(recipient, targetTimestamps);
} else {
throw new UserErrorException("Unknown receipt type: " + type);
}
} catch (IOException | UntrustedIdentityException e) {
outputResult(outputWriter, results.timestamp());
ErrorUtils.handleSendMessageResults(results.results());
} catch (IOException e) {
throw new UserErrorException("Failed to send message: " + e.getMessage() + " (" + e.getClass()
.getSimpleName() + ")");
}
}
private void outputResult(final OutputWriter outputWriter, final long timestamp) {
if (outputWriter instanceof PlainTextWriter writer) {
writer.println("{}", timestamp);
} else {
final var writer = (JsonWriter) outputWriter;
writer.write(Map.of("timestamp", timestamp));
}
}
}

View file

@ -4,20 +4,23 @@ import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.JsonWriter;
import org.asamk.signal.OutputWriter;
import org.asamk.signal.PlainTextWriter;
import org.asamk.signal.commands.exceptions.CommandException;
import org.asamk.signal.commands.exceptions.UserErrorException;
import org.asamk.signal.manager.Manager;
import org.asamk.signal.manager.UntrustedIdentityException;
import org.asamk.signal.manager.api.RecipientIdentifier;
import org.asamk.signal.manager.api.TypingAction;
import org.asamk.signal.manager.groups.GroupNotFoundException;
import org.asamk.signal.manager.groups.GroupSendingNotAllowedException;
import org.asamk.signal.manager.groups.NotAGroupMemberException;
import org.asamk.signal.util.CommandUtil;
import org.asamk.signal.util.ErrorUtils;
import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
public class SendTypingCommand implements JsonRpcLocalCommand {
@ -57,12 +60,23 @@ public class SendTypingCommand implements JsonRpcLocalCommand {
}
try {
m.sendTypingMessage(action, recipientIdentifiers);
} catch (IOException | UntrustedIdentityException e) {
final var results = m.sendTypingMessage(action, recipientIdentifiers);
outputResult(outputWriter, results.timestamp());
ErrorUtils.handleSendMessageResults(results.results());
} catch (IOException e) {
throw new UserErrorException("Failed to send message: " + e.getMessage() + " (" + e.getClass()
.getSimpleName() + ")");
} catch (GroupNotFoundException | NotAGroupMemberException | GroupSendingNotAllowedException e) {
throw new UserErrorException("Failed to send to group: " + e.getMessage());
}
}
private void outputResult(final OutputWriter outputWriter, final long timestamp) {
if (outputWriter instanceof PlainTextWriter writer) {
writer.println("{}", timestamp);
} else {
final var writer = (JsonWriter) outputWriter;
writer.write(Map.of("timestamp", timestamp));
}
}
}

View file

@ -6,7 +6,6 @@ import org.asamk.signal.manager.AttachmentInvalidException;
import org.asamk.signal.manager.Manager;
import org.asamk.signal.manager.NotMasterDeviceException;
import org.asamk.signal.manager.StickerPackInvalidException;
import org.asamk.signal.manager.UntrustedIdentityException;
import org.asamk.signal.manager.api.Configuration;
import org.asamk.signal.manager.api.Device;
import org.asamk.signal.manager.api.Group;
@ -298,31 +297,34 @@ public class DbusManagerImpl implements Manager {
}
@Override
public void sendTypingMessage(
public SendMessageResults sendTypingMessage(
final TypingAction action, final Set<RecipientIdentifier> recipients
) throws IOException, UntrustedIdentityException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException {
for (final var recipient : recipients) {
if (recipient instanceof RecipientIdentifier.Single) {
signal.sendTyping(((RecipientIdentifier.Single) recipient).getIdentifier(),
action == TypingAction.STOP);
} else if (recipient instanceof RecipientIdentifier.Group) {
throw new UnsupportedOperationException();
}
}
) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException {
return handleMessage(recipients, numbers -> {
numbers.forEach(n -> signal.sendTyping(n, action == TypingAction.STOP));
return 0L;
}, () -> {
signal.sendTyping(signal.getSelfNumber(), action == TypingAction.STOP);
return 0L;
}, groupId -> {
throw new UnsupportedOperationException();
});
}
@Override
public void sendReadReceipt(
public SendMessageResults sendReadReceipt(
final RecipientIdentifier.Single sender, final List<Long> messageIds
) throws IOException, UntrustedIdentityException {
) {
signal.sendReadReceipt(sender.getIdentifier(), messageIds);
return new SendMessageResults(0, Map.of());
}
@Override
public void sendViewedReceipt(
public SendMessageResults sendViewedReceipt(
final RecipientIdentifier.Single sender, final List<Long> messageIds
) throws IOException, UntrustedIdentityException {
) {
signal.sendViewedReceipt(sender.getIdentifier(), messageIds);
return new SendMessageResults(0, Map.of());
}
@Override

View file

@ -7,7 +7,6 @@ import org.asamk.signal.manager.AttachmentInvalidException;
import org.asamk.signal.manager.Manager;
import org.asamk.signal.manager.NotMasterDeviceException;
import org.asamk.signal.manager.StickerPackInvalidException;
import org.asamk.signal.manager.UntrustedIdentityException;
import org.asamk.signal.manager.api.Identity;
import org.asamk.signal.manager.api.InactiveGroupLinkException;
import org.asamk.signal.manager.api.InvalidDeviceLinkException;
@ -305,16 +304,15 @@ public class DbusSignalImpl implements Signal {
try {
var recipients = new ArrayList<String>(1);
recipients.add(recipient);
m.sendTypingMessage(stop ? TypingAction.STOP : TypingAction.START,
final var results = m.sendTypingMessage(stop ? TypingAction.STOP : TypingAction.START,
getSingleRecipientIdentifiers(recipients, m.getSelfNumber()).stream()
.map(RecipientIdentifier.class::cast)
.collect(Collectors.toSet()));
checkSendMessageResults(results.timestamp(), results.results());
} catch (IOException e) {
throw new Error.Failure(e.getMessage());
} catch (GroupNotFoundException | NotAGroupMemberException | GroupSendingNotAllowedException e) {
throw new Error.GroupNotFound(e.getMessage());
} catch (UntrustedIdentityException e) {
throw new Error.UntrustedIdentity(e.getMessage());
}
}
@ -323,11 +321,11 @@ public class DbusSignalImpl implements Signal {
final String recipient, final List<Long> messageIds
) throws Error.Failure, Error.UntrustedIdentity {
try {
m.sendReadReceipt(getSingleRecipientIdentifier(recipient, m.getSelfNumber()), messageIds);
final var results = m.sendReadReceipt(getSingleRecipientIdentifier(recipient, m.getSelfNumber()),
messageIds);
checkSendMessageResults(results.timestamp(), results.results());
} catch (IOException e) {
throw new Error.Failure(e.getMessage());
} catch (UntrustedIdentityException e) {
throw new Error.UntrustedIdentity(e.getMessage());
}
}
@ -336,11 +334,11 @@ public class DbusSignalImpl implements Signal {
final String recipient, final List<Long> messageIds
) throws Error.Failure, Error.UntrustedIdentity {
try {
m.sendViewedReceipt(getSingleRecipientIdentifier(recipient, m.getSelfNumber()), messageIds);
final var results = m.sendViewedReceipt(getSingleRecipientIdentifier(recipient, m.getSelfNumber()),
messageIds);
checkSendMessageResults(results.timestamp(), results.results());
} catch (IOException e) {
throw new Error.Failure(e.getMessage());
} catch (UntrustedIdentityException e) {
throw new Error.UntrustedIdentity(e.getMessage());
}
}