diff --git a/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.h b/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.h index abbeeff41..016c47ef9 100644 --- a/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.h +++ b/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.h @@ -5,6 +5,7 @@ NS_ASSUME_NONNULL_BEGIN @class OWSIncomingSentMessageTranscript; +@class SSKProtoSyncMessageSentUpdate; @class TSAttachmentStream; @class YapDatabaseReadWriteTransaction; @@ -18,6 +19,11 @@ NS_ASSUME_NONNULL_BEGIN NSArray *attachmentStreams))attachmentHandler transaction:(YapDatabaseReadWriteTransaction *)transaction; ++ (BOOL)areSentUpdatesEnabled; + ++ (void)processSentUpdateTranscript:(SSKProtoSyncMessageSentUpdate *)sentUpdate + transaction:(YapDatabaseReadWriteTransaction *)transaction; + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m b/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m index 801bdcf47..0be9fefc7 100644 --- a/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m +++ b/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m @@ -10,11 +10,13 @@ #import "OWSReadReceiptManager.h" #import "SSKEnvironment.h" #import "TSAttachmentPointer.h" +#import "TSGroupThread.h" #import "TSInfoMessage.h" #import "TSNetworkManager.h" #import "TSOutgoingMessage.h" #import "TSQuotedMessage.h" #import "TSThread.h" +#import NS_ASSUME_NONNULL_BEGIN @@ -65,6 +67,13 @@ NS_ASSUME_NONNULL_BEGIN OWSAssertDebug(transcript); OWSAssertDebug(transaction); + if (self.dataMessage.group) { + _thread = [TSGroupThread getOrCreateThreadWithGroupId:_dataMessage.group.id transaction:transaction]; + } else { + _thread = [TSContactThread getOrCreateThreadWithContactId:_recipientId transaction:transaction]; + } + + OWSLogInfo(@"Recording transcript in thread: %@ timestamp: %llu", transcript.thread.uniqueId, transcript.timestamp); if (transcript.isEndSessionMessage) { @@ -171,6 +180,93 @@ NS_ASSUME_NONNULL_BEGIN } } +#pragma mark - + ++ (BOOL)areSentUpdatesEnabled +{ + return NO; +} + ++ (void)processSentUpdateTranscript:(SSKProtoSyncMessageSentUpdate *)sentUpdate + transaction:(YapDatabaseReadWriteTransaction *)transaction +{ + OWSAssertDebug(sentUpdate); + OWSAssertDebug(transaction); + + if (!self.areSentUpdatesEnabled) { + OWSFailDebug(@"Ignoring 'sent update' transcript; disabled."); + return; + } + + uint64_t timestamp = sentUpdate.timestamp; + if (timestamp < 1) { + OWSFailDebug(@"'Sent update' transcript has invalid timestamp."); + return; + } + + NSData *groupId = sentUpdate.groupID; + if (groupId.length < 1) { + OWSFailDebug(@"'Sent update' transcript has invalid groupId."); + return; + } + + NSArray *statusProtos = sentUpdate.unidentifiedStatus; + if (statusProtos.count < 1) { + OWSFailDebug(@"'Sent update' transcript is missing statusProtos."); + return; + } + + NSMutableArray *nonUdRecipientIds = [NSMutableArray new]; + NSMutableArray *udRecipientIds = [NSMutableArray new]; + for (SSKProtoSyncMessageSentUpdateUnidentifiedDeliveryStatus *statusProto in statusProtos) { + NSString *recipientId = statusProto.destination; + if (statusProto.unidentified) { + [udRecipientIds addObject:recipientId]; + } else { + [nonUdRecipientIds addObject:recipientId]; + } + } + + NSArray *messages + = (NSArray *)[TSInteraction interactionsWithTimestamp:timestamp + ofClass:[TSOutgoingMessage class] + withTransaction:transaction]; + if (messages.count < 1) { + // This message may have disappeared. + OWSLogError(@"No matching message with timestamp: %llu.", timestamp); + return; + } + + BOOL messageFound = NO; + for (TSOutgoingMessage *message in messages) { + TSThread *thread = [message threadWithTransaction:transaction]; + if (!thread.isGroupThread) { + continue; + } + TSGroupThread *groupThread = (TSGroupThread *)thread; + if (![groupThread.groupModel.groupId isEqual:groupId]) { + continue; + } + + OWSLogInfo(@"Processing 'sent update' transcript in thread: %@, timestamp: %llu, nonUdRecipientIds: %d, " + @"udRecipientIds: %d.", + thread.uniqueId, + timestamp, + (int)nonUdRecipientIds.count, + (int)udRecipientIds.count); + + [message updateWithWasSentFromLinkedDeviceWithUDRecipientIds:udRecipientIds + nonUdRecipientIds:nonUdRecipientIds + transaction:transaction]; + messageFound = YES; + } + + if (!messageFound) { + // This message may have disappeared. + OWSLogError(@"No matching message with timestamp: %llu.", timestamp); + } +} + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index 094768123..b20b21ce7 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -860,8 +860,7 @@ NS_ASSUME_NONNULL_BEGIN if (syncMessage.sent) { OWSIncomingSentMessageTranscript *transcript = - [[OWSIncomingSentMessageTranscript alloc] initWithProto:syncMessage.sent - transaction:transaction]; + [[OWSIncomingSentMessageTranscript alloc] initWithProto:syncMessage.sent transaction:transaction]; SSKProtoDataMessage *_Nullable dataMessage = syncMessage.sent.message; if (!dataMessage) { @@ -909,6 +908,8 @@ NS_ASSUME_NONNULL_BEGIN } transaction:transaction]; } + } else if (syncMessage.sentUpdate) { + [OWSRecordTranscriptJob processSentUpdateTranscript:syncMessage.sentUpdate transaction:transaction]; } else if (syncMessage.request) { if (syncMessage.request.type == SSKProtoSyncMessageRequestTypeContacts) { // We respond asynchronously because populating the sync message will