Java Code Examples for org.whispersystems.signalservice.api.messages.SignalServiceDataMessage#Builder
The following examples show how to use
org.whispersystems.signalservice.api.messages.SignalServiceDataMessage#Builder .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: GroupUtil.java From mollyim-android with GNU General Public License v3.0 | 6 votes |
@WorkerThread public static void setDataMessageGroupContext(@NonNull Context context, @NonNull SignalServiceDataMessage.Builder dataMessageBuilder, @NonNull GroupId.Push groupId) { if (groupId.isV2()) { GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); GroupDatabase.GroupRecord groupRecord = groupDatabase.requireGroup(groupId); GroupDatabase.V2GroupProperties v2GroupProperties = groupRecord.requireV2GroupProperties(); SignalServiceGroupV2 group = SignalServiceGroupV2.newBuilder(v2GroupProperties.getGroupMasterKey()) .withRevision(v2GroupProperties.getGroupRevision()) .build(); dataMessageBuilder.asGroupMessage(group); } else { dataMessageBuilder.asGroupMessage(new SignalServiceGroup(groupId.getDecodedId())); } }
Example 2
Source File: Manager.java From signal-cli with GNU General Public License v3.0 | 6 votes |
/** * This method throws an EncapsulatedExceptions exception instead of returning a list of SendMessageResult. */ private long sendMessageLegacy(SignalServiceDataMessage.Builder messageBuilder, Collection<SignalServiceAddress> recipients) throws EncapsulatedExceptions, IOException { final long timestamp = System.currentTimeMillis(); messageBuilder.withTimestamp(timestamp); List<SendMessageResult> results = sendMessage(messageBuilder, recipients); List<UntrustedIdentityException> untrustedIdentities = new LinkedList<>(); List<UnregisteredUserException> unregisteredUsers = new LinkedList<>(); List<NetworkFailureException> networkExceptions = new LinkedList<>(); for (SendMessageResult result : results) { if (result.isUnregisteredFailure()) { unregisteredUsers.add(new UnregisteredUserException(result.getAddress().getLegacyIdentifier(), null)); } else if (result.isNetworkFailure()) { networkExceptions.add(new NetworkFailureException(result.getAddress().getLegacyIdentifier(), null)); } else if (result.getIdentityFailure() != null) { untrustedIdentities.add(new UntrustedIdentityException("Untrusted", result.getAddress().getLegacyIdentifier(), result.getIdentityFailure().getIdentityKey())); } } if (!untrustedIdentities.isEmpty() || !unregisteredUsers.isEmpty() || !networkExceptions.isEmpty()) { throw new EncapsulatedExceptions(untrustedIdentities, unregisteredUsers, networkExceptions); } return timestamp; }
Example 3
Source File: Manager.java From signal-cli with GNU General Public License v3.0 | 6 votes |
public long sendMessage(String messageText, List<String> attachments, List<String> recipients) throws IOException, EncapsulatedExceptions, AttachmentInvalidException, InvalidNumberException { final SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder().withBody(messageText); if (attachments != null) { List<SignalServiceAttachment> attachmentStreams = Utils.getSignalServiceAttachments(attachments); // Upload attachments here, so we only upload once even for multiple recipients SignalServiceMessageSender messageSender = getMessageSender(); List<SignalServiceAttachment> attachmentPointers = new ArrayList<>(attachmentStreams.size()); for (SignalServiceAttachment attachment : attachmentStreams) { if (attachment.isStream()) { attachmentPointers.add(messageSender.uploadAttachment(attachment.asStream())); } else if (attachment.isPointer()) { attachmentPointers.add(attachment.asPointer()); } } messageBuilder.withAttachments(attachmentPointers); } return sendMessageLegacy(messageBuilder, getSignalServiceAddresses(recipients)); }
Example 4
Source File: Manager.java From signal-cli with GNU General Public License v3.0 | 6 votes |
private SignalServiceDataMessage.Builder getGroupUpdateMessageBuilder(GroupInfo g) throws AttachmentInvalidException { SignalServiceGroup.Builder group = SignalServiceGroup.newBuilder(SignalServiceGroup.Type.UPDATE) .withId(g.groupId) .withName(g.name) .withMembers(new ArrayList<>(g.getMembers())); File aFile = getGroupAvatarFile(g.groupId); if (aFile.exists()) { try { group.withAvatar(Utils.createAttachment(aFile)); } catch (IOException e) { throw new AttachmentInvalidException(aFile.toString(), e); } } return SignalServiceDataMessage.newBuilder() .asGroupMessage(group.build()) .withExpiration(g.messageExpirationTime); }
Example 5
Source File: Manager.java From signal-cli with GNU General Public License v3.0 | 6 votes |
public long sendGroupMessage(String messageText, List<String> attachments, byte[] groupId) throws IOException, EncapsulatedExceptions, GroupNotFoundException, AttachmentInvalidException, NotAGroupMemberException { final SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder().withBody(messageText); if (attachments != null) { messageBuilder.withAttachments(Utils.getSignalServiceAttachments(attachments)); } if (groupId != null) { SignalServiceGroup group = SignalServiceGroup.newBuilder(SignalServiceGroup.Type.DELIVER) .withId(groupId) .build(); messageBuilder.asGroupMessage(group); } final GroupInfo g = getGroupForSending(groupId); messageBuilder.withExpiration(g.messageExpirationTime); return sendMessageLegacy(messageBuilder, g.getMembersWithout(account.getSelfAddress())); }
Example 6
Source File: LeaveGroupJob.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
private static @NonNull List<Recipient> deliver(@NonNull Context context, @NonNull GroupId.Push groupId, @NonNull String name, @NonNull List<RecipientId> members, @NonNull List<RecipientId> destinations) throws IOException, UntrustedIdentityException { SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender(); List<SignalServiceAddress> addresses = Stream.of(destinations).map(Recipient::resolved).map(t -> RecipientUtil.toSignalServiceAddress(context, t)).toList(); List<SignalServiceAddress> memberAddresses = Stream.of(members).map(Recipient::resolved).map(t -> RecipientUtil.toSignalServiceAddress(context, t)).toList(); List<Optional<UnidentifiedAccessPair>> unidentifiedAccess = Stream.of(destinations).map(Recipient::resolved).map(recipient -> UnidentifiedAccessUtil.getAccessFor(context, recipient)).toList(); SignalServiceGroup serviceGroup = new SignalServiceGroup(SignalServiceGroup.Type.QUIT, groupId.getDecodedId(), name, memberAddresses, null); SignalServiceDataMessage.Builder dataMessage = SignalServiceDataMessage.newBuilder() .withTimestamp(System.currentTimeMillis()) .asGroupMessage(serviceGroup); List<SendMessageResult> results = messageSender.sendMessage(addresses, unidentifiedAccess, false, dataMessage.build()); Stream.of(results) .filter(r -> r.getIdentityFailure() != null) .map(SendMessageResult::getAddress) .map(a -> Recipient.externalPush(context, a)) .forEach(r -> Log.w(TAG, "Identity failure for " + r.getId())); Stream.of(results) .filter(SendMessageResult::isUnregisteredFailure) .map(SendMessageResult::getAddress) .map(a -> Recipient.externalPush(context, a)) .forEach(r -> Log.w(TAG, "Unregistered failure for " + r.getId())); return Stream.of(results) .filter(r -> r.getSuccess() != null || r.getIdentityFailure() != null || r.isUnregisteredFailure()) .map(SendMessageResult::getAddress) .map(a -> Recipient.externalPush(context, a)) .toList(); }
Example 7
Source File: Manager.java From signal-cli with GNU General Public License v3.0 | 5 votes |
public void sendEndSessionMessage(List<String> recipients) throws IOException, EncapsulatedExceptions, InvalidNumberException { SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder() .asEndSessionMessage(); final Collection<SignalServiceAddress> signalServiceAddresses = getSignalServiceAddresses(recipients); try { sendMessageLegacy(messageBuilder, signalServiceAddresses); } catch (Exception e) { for (SignalServiceAddress address : signalServiceAddresses) { handleEndSession(address); } account.save(); throw e; } }
Example 8
Source File: Manager.java From signal-cli with GNU General Public License v3.0 | 5 votes |
public void sendMessageReaction(String emoji, boolean remove, String targetAuthor, long targetSentTimestamp, List<String> recipients) throws IOException, EncapsulatedExceptions, InvalidNumberException { SignalServiceDataMessage.Reaction reaction = new SignalServiceDataMessage.Reaction(emoji, remove, canonicalizeAndResolveSignalServiceAddress(targetAuthor), targetSentTimestamp); final SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder() .withReaction(reaction); sendMessageLegacy(messageBuilder, getSignalServiceAddresses(recipients)); }
Example 9
Source File: Manager.java From signal-cli with GNU General Public License v3.0 | 5 votes |
void sendGroupInfoRequest(byte[] groupId, SignalServiceAddress recipient) throws IOException, EncapsulatedExceptions { if (groupId == null) { return; } SignalServiceGroup.Builder group = SignalServiceGroup.newBuilder(SignalServiceGroup.Type.REQUEST_INFO) .withId(groupId); SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder() .asGroupMessage(group.build()); // Send group info request message to the recipient who sent us a message with this groupId sendMessageLegacy(messageBuilder, Collections.singleton(recipient)); }
Example 10
Source File: Manager.java From signal-cli with GNU General Public License v3.0 | 5 votes |
void sendUpdateGroupMessage(byte[] groupId, SignalServiceAddress recipient) throws IOException, EncapsulatedExceptions, NotAGroupMemberException, GroupNotFoundException, AttachmentInvalidException { if (groupId == null) { return; } GroupInfo g = getGroupForSending(groupId); if (!g.isMember(recipient)) { return; } SignalServiceDataMessage.Builder messageBuilder = getGroupUpdateMessageBuilder(g); // Send group message only to the recipient who requested it sendMessageLegacy(messageBuilder, Collections.singleton(recipient)); }
Example 11
Source File: Manager.java From signal-cli with GNU General Public License v3.0 | 5 votes |
public void sendGroupMessageReaction(String emoji, boolean remove, String targetAuthor, long targetSentTimestamp, byte[] groupId) throws IOException, EncapsulatedExceptions, InvalidNumberException, NotAGroupMemberException, GroupNotFoundException { SignalServiceDataMessage.Reaction reaction = new SignalServiceDataMessage.Reaction(emoji, remove, canonicalizeAndResolveSignalServiceAddress(targetAuthor), targetSentTimestamp); final SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder() .withReaction(reaction); if (groupId != null) { SignalServiceGroup group = SignalServiceGroup.newBuilder(SignalServiceGroup.Type.DELIVER) .withId(groupId) .build(); messageBuilder.asGroupMessage(group); } final GroupInfo g = getGroupForSending(groupId); sendMessageLegacy(messageBuilder, g.getMembersWithout(account.getSelfAddress())); }
Example 12
Source File: Signal.java From signal-bot with GNU Affero General Public License v3.0 | 5 votes |
public void sendMessage(User sender, Group group, SignalServiceDataMessage.Builder messageBuilder) throws IOException { messageBuilder.withTimestamp(System.currentTimeMillis()); if(group != null) { messageBuilder.asGroupMessage(SignalServiceGroup.newBuilder(Type.DELIVER).withId(group.getId().getId()).build()); sendMessage(group.getMembers(), messageBuilder.build()); } else { sendMessage(sender.getNumber(), messageBuilder.build()); } }
Example 13
Source File: Xkcd.java From signal-bot with GNU Affero General Public License v3.0 | 5 votes |
private void sendXkcd(User sender, Group group, String id) throws IOException { Map<String, Object> info = getData(id + "/info.0.json"); File image = toFile(info.get("img").toString()); SignalServiceDataMessage.Builder message = SignalServiceDataMessage.newBuilder() .withBody(info.get("title").toString()) .withAttachment(SignalServiceAttachment.newStreamBuilder() .withContentType("image/png") .withLength(image.length()) .withStream(new FileInputStream(image)) .build()); Signal.getInstance().sendMessage(sender, group, message); image.delete(); }
Example 14
Source File: RemoteDeleteSendJob.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
private @NonNull List<Recipient> deliver(@NonNull Recipient conversationRecipient, @NonNull List<Recipient> destinations, long targetSentTimestamp) throws IOException, UntrustedIdentityException { SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender(); List<SignalServiceAddress> addresses = Stream.of(destinations).map(t -> RecipientUtil.toSignalServiceAddress(context, t)).toList(); List<Optional<UnidentifiedAccessPair>> unidentifiedAccess = Stream.of(destinations).map(recipient -> UnidentifiedAccessUtil.getAccessFor(context, recipient)).toList(); SignalServiceDataMessage.Builder dataMessage = SignalServiceDataMessage.newBuilder() .withTimestamp(System.currentTimeMillis()) .withRemoteDelete(new SignalServiceDataMessage.RemoteDelete(targetSentTimestamp)); if (conversationRecipient.isGroup()) { GroupUtil.setDataMessageGroupContext(context, dataMessage, conversationRecipient.requireGroupId().requirePush()); } List<SendMessageResult> results = messageSender.sendMessage(addresses, unidentifiedAccess, false, dataMessage.build()); Stream.of(results) .filter(r -> r.getIdentityFailure() != null) .map(SendMessageResult::getAddress) .map(a -> Recipient.externalPush(context, a)) .forEach(r -> Log.w(TAG, "Identity failure for " + r.getId())); Stream.of(results) .filter(SendMessageResult::isUnregisteredFailure) .map(SendMessageResult::getAddress) .map(a -> Recipient.externalPush(context, a)) .forEach(r -> Log.w(TAG, "Unregistered failure for " + r.getId())); return Stream.of(results) .filter(r -> r.getSuccess() != null || r.getIdentityFailure() != null || r.isUnregisteredFailure()) .map(SendMessageResult::getAddress) .map(a -> Recipient.externalPush(context, a)) .toList(); }
Example 15
Source File: ReactionSendJob.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
private @NonNull List<Recipient> deliver(@NonNull Recipient conversationRecipient, @NonNull List<Recipient> destinations, @NonNull Recipient targetAuthor, long targetSentTimestamp) throws IOException, UntrustedIdentityException { SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender(); List<SignalServiceAddress> addresses = Stream.of(destinations).map(t -> RecipientUtil.toSignalServiceAddress(context, t)).toList(); List<Optional<UnidentifiedAccessPair>> unidentifiedAccess = Stream.of(destinations).map(recipient -> UnidentifiedAccessUtil.getAccessFor(context, recipient)).toList(); SignalServiceDataMessage.Builder dataMessage = SignalServiceDataMessage.newBuilder() .withTimestamp(System.currentTimeMillis()) .withReaction(buildReaction(context, reaction, remove, targetAuthor, targetSentTimestamp)); if (conversationRecipient.isGroup()) { GroupUtil.setDataMessageGroupContext(context, dataMessage, conversationRecipient.requireGroupId().requirePush()); } List<SendMessageResult> results = messageSender.sendMessage(addresses, unidentifiedAccess, false, dataMessage.build()); Stream.of(results) .filter(r -> r.getIdentityFailure() != null) .map(SendMessageResult::getAddress) .map(a -> Recipient.externalPush(context, a)) .forEach(r -> Log.w(TAG, "Identity failure for " + r.getId())); Stream.of(results) .filter(SendMessageResult::isUnregisteredFailure) .map(SendMessageResult::getAddress) .map(a -> Recipient.externalPush(context, a)) .forEach(r -> Log.w(TAG, "Unregistered failure for " + r.getId())); return Stream.of(results) .filter(r -> r.getSuccess() != null || r.getIdentityFailure() != null || r.isUnregisteredFailure()) .map(SendMessageResult::getAddress) .map(a -> Recipient.externalPush(context, a)) .toList(); }
Example 16
Source File: ProfileKeySendJob.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
private List<Recipient> deliver(@NonNull Recipient conversationRecipient, @NonNull List<Recipient> destinations) throws IOException, UntrustedIdentityException { SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender(); List<SignalServiceAddress> addresses = Stream.of(destinations).map(t -> RecipientUtil.toSignalServiceAddress(context, t)).toList(); List<Optional<UnidentifiedAccessPair>> unidentifiedAccess = Stream.of(destinations).map(recipient -> UnidentifiedAccessUtil.getAccessFor(context, recipient)).toList(); SignalServiceDataMessage.Builder dataMessage = SignalServiceDataMessage.newBuilder() .asProfileKeyUpdate(true) .withTimestamp(System.currentTimeMillis()) .withProfileKey(Recipient.self().resolve().getProfileKey()); if (conversationRecipient.isGroup()) { dataMessage.asGroupMessage(new SignalServiceGroup(conversationRecipient.requireGroupId().getDecodedId())); } List<SendMessageResult> results = messageSender.sendMessage(addresses, unidentifiedAccess, false, dataMessage.build()); Stream.of(results) .filter(r -> r.getIdentityFailure() != null) .map(SendMessageResult::getAddress) .map(a -> Recipient.externalPush(context, a)) .forEach(r -> Log.w(TAG, "Identity failure for " + r.getId())); Stream.of(results) .filter(SendMessageResult::isUnregisteredFailure) .map(SendMessageResult::getAddress) .map(a -> Recipient.externalPush(context, a)) .forEach(r -> Log.w(TAG, "Unregistered failure for " + r.getId())); return Stream.of(results) .filter(r -> r.getSuccess() != null || r.getIdentityFailure() != null || r.isUnregisteredFailure()) .map(SendMessageResult::getAddress) .map(a -> Recipient.externalPush(context, a)) .toList(); }
Example 17
Source File: Manager.java From signal-cli with GNU General Public License v3.0 | 4 votes |
private List<SendMessageResult> sendMessage(SignalServiceDataMessage.Builder messageBuilder, Collection<SignalServiceAddress> recipients) throws IOException { if (messagePipe == null) { messagePipe = getMessageReceiver().createMessagePipe(); } if (unidentifiedMessagePipe == null) { unidentifiedMessagePipe = getMessageReceiver().createUnidentifiedMessagePipe(); } SignalServiceDataMessage message = null; try { message = messageBuilder.build(); if (message.getGroupContext().isPresent()) { try { SignalServiceMessageSender messageSender = getMessageSender(); final boolean isRecipientUpdate = false; List<SendMessageResult> result = messageSender.sendMessage(new ArrayList<>(recipients), getAccessFor(recipients), isRecipientUpdate, message); for (SendMessageResult r : result) { if (r.getIdentityFailure() != null) { account.getSignalProtocolStore().saveIdentity(r.getAddress(), r.getIdentityFailure().getIdentityKey(), TrustLevel.UNTRUSTED); } } return result; } catch (UntrustedIdentityException e) { account.getSignalProtocolStore().saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), e.getIdentityKey(), TrustLevel.UNTRUSTED); return Collections.emptyList(); } } else { // Send to all individually, so sync messages are sent correctly List<SendMessageResult> results = new ArrayList<>(recipients.size()); for (SignalServiceAddress address : recipients) { ContactInfo contact = account.getContactStore().getContact(address); if (contact != null) { messageBuilder.withExpiration(contact.messageExpirationTime); messageBuilder.withProfileKey(account.getProfileKey().serialize()); } else { messageBuilder.withExpiration(0); messageBuilder.withProfileKey(null); } message = messageBuilder.build(); if (address.matches(account.getSelfAddress())) { results.add(sendSelfMessage(message)); } else { results.add(sendMessage(address, message)); } } return results; } } finally { if (message != null && message.isEndSession()) { for (SignalServiceAddress recipient : recipients) { handleEndSession(recipient); } } account.save(); } }
Example 18
Source File: Manager.java From signal-cli with GNU General Public License v3.0 | 4 votes |
private byte[] sendUpdateGroupMessage(byte[] groupId, String name, Collection<SignalServiceAddress> members, String avatarFile) throws IOException, EncapsulatedExceptions, GroupNotFoundException, AttachmentInvalidException, NotAGroupMemberException { GroupInfo g; if (groupId == null) { // Create new group g = new GroupInfo(KeyUtils.createGroupId()); g.addMembers(Collections.singleton(account.getSelfAddress())); } else { g = getGroupForSending(groupId); } if (name != null) { g.name = name; } if (members != null) { final Set<String> newE164Members = new HashSet<>(); for (SignalServiceAddress member : members) { if (g.isMember(member) || !member.getNumber().isPresent()) { continue; } newE164Members.add(member.getNumber().get()); } final List<ContactTokenDetails> contacts = accountManager.getContacts(newE164Members); if (contacts.size() != newE164Members.size()) { // Some of the new members are not registered on Signal for (ContactTokenDetails contact : contacts) { newE164Members.remove(contact.getNumber()); } System.err.println("Failed to add members " + Util.join(", ", newE164Members) + " to group: Not registered on Signal"); System.err.println("Aborting…"); System.exit(1); } g.addMembers(members); } if (avatarFile != null) { IOUtils.createPrivateDirectories(pathConfig.getAvatarsPath()); File aFile = getGroupAvatarFile(g.groupId); Files.copy(Paths.get(avatarFile), aFile.toPath(), StandardCopyOption.REPLACE_EXISTING); } account.getGroupStore().updateGroup(g); SignalServiceDataMessage.Builder messageBuilder = getGroupUpdateMessageBuilder(g); sendMessageLegacy(messageBuilder, g.getMembersWithout(account.getSelfAddress())); return g.groupId; }
Example 19
Source File: Tex.java From signal-bot with GNU Affero General Public License v3.0 | 4 votes |
@Override public void onMessage(User sender, Group group, SignalServiceDataMessage message) throws IOException { String body = stripPrefix(message.getBody().get()); if(body.isEmpty()) { Signal.getInstance().sendMessage(sender, group, "Usage: !tex [tex source]"); return; } String url = URL + URLEncoder.encode(body, "utf-8").replace("+", "%20"); try { // Download response File file = toFile(url); // Test for PNG header and interpret as string otherwise FileInputStream in = new FileInputStream(file); byte[] buf = new byte[8]; if(in.read(buf) != 8 || !Arrays.equals(buf, PNG_HEADER)) { String beginning = new String(buf, "utf-8"); Scanner scanner = new Scanner(in); scanner.useDelimiter("\\A"); String end = scanner.next(); scanner.close(); Signal.getInstance().sendMessage(sender, group, beginning + end); in.close(); file.delete(); return; } in.close(); // Remove alpha channel BufferedImage imgWithAlpha = ImageIO.read(file); BufferedImage imgWithoutAlpha = new BufferedImage(imgWithAlpha.getWidth() + PADDING, imgWithAlpha.getHeight() + PADDING, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = imgWithoutAlpha.createGraphics(); g2d.setColor(Color.WHITE); g2d.fillRect(0, 0, imgWithoutAlpha.getWidth(), imgWithoutAlpha.getHeight()); g2d.drawImage(imgWithAlpha, PADDING / 2, PADDING / 2, null); g2d.dispose(); ImageIO.write(imgWithoutAlpha, "PNG", file); // Send PNG SignalServiceDataMessage.Builder reply = SignalServiceDataMessage.newBuilder() .withAttachment(SignalServiceAttachment.newStreamBuilder() .withContentType("image/png") .withLength(file.length()) .withStream(new FileInputStream(file)) .build()); Signal.getInstance().sendMessage(sender, group, reply); file.delete(); } catch(IOException e) { e.printStackTrace(); Signal.getInstance().sendMessage(sender, group, "Error: " + e.getMessage()); } }
Example 20
Source File: Manager.java From signal-cli with GNU General Public License v3.0 | 4 votes |
private void sendExpirationTimerUpdate(SignalServiceAddress address) throws IOException { final SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder() .asExpirationUpdate(); sendMessage(messageBuilder, Collections.singleton(address)); }