| 
									
										
										
										
											2023-01-03 11:55:46 -08:00
										 |  |  | // Copyright 2016 Signal Messenger, LLC
 | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  | // SPDX-License-Identifier: AGPL-3.0-only
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* eslint-disable max-classes-per-file */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import { isEqual } from 'lodash'; | 
					
						
							|  |  |  | import { Collection, Model } from 'backbone'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-26 14:15:33 -05:00
										 |  |  | import type { MessageModel } from '../models/messages'; | 
					
						
							| 
									
										
										
										
											2021-12-10 14:51:54 -08:00
										 |  |  | import type { MessageAttributesType } from '../model-types.d'; | 
					
						
							| 
									
										
										
										
											2022-04-20 20:29:37 -04:00
										 |  |  | import { isOutgoing, isStory } from '../state/selectors/message'; | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  | import { getOwn } from '../util/getOwn'; | 
					
						
							|  |  |  | import { missingCaseError } from '../util/missingCaseError'; | 
					
						
							| 
									
										
										
										
											2021-08-31 14:35:01 -07:00
										 |  |  | import { createWaitBatcher } from '../util/waitBatcher'; | 
					
						
							| 
									
										
										
										
											2021-10-26 15:59:08 -07:00
										 |  |  | import type { UUIDStringType } from '../types/UUID'; | 
					
						
							| 
									
										
										
										
											2022-11-22 10:43:43 -08:00
										 |  |  | import * as Errors from '../types/errors'; | 
					
						
							| 
									
										
										
										
											2021-07-28 13:53:18 -05:00
										 |  |  | import { | 
					
						
							|  |  |  |   SendActionType, | 
					
						
							|  |  |  |   SendStatus, | 
					
						
							|  |  |  |   sendStateReducer, | 
					
						
							|  |  |  | } from '../messages/MessageSendState'; | 
					
						
							| 
									
										
										
										
											2021-08-31 14:35:01 -07:00
										 |  |  | import type { DeleteSentProtoRecipientOptionsType } from '../sql/Interface'; | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  | import dataInterface from '../sql/Client'; | 
					
						
							| 
									
										
										
										
											2021-09-17 14:27:53 -04:00
										 |  |  | import * as log from '../logging/log'; | 
					
						
							| 
									
										
										
										
											2023-01-11 14:54:06 -08:00
										 |  |  | import { getSourceUuid } from '../messages/helpers'; | 
					
						
							| 
									
										
										
										
											2023-04-10 20:54:43 -07:00
										 |  |  | import { queueUpdateMessage } from '../util/messageBatcher'; | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | const { deleteSentProtoRecipient } = dataInterface; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export enum MessageReceiptType { | 
					
						
							|  |  |  |   Delivery = 'Delivery', | 
					
						
							|  |  |  |   Read = 'Read', | 
					
						
							| 
									
										
										
										
											2021-07-27 10:42:25 -05:00
										 |  |  |   View = 'View', | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-04 07:27:16 -08:00
										 |  |  | export type MessageReceiptAttributesType = { | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  |   messageSentAt: number; | 
					
						
							|  |  |  |   receiptTimestamp: number; | 
					
						
							| 
									
										
										
										
											2021-10-26 15:59:08 -07:00
										 |  |  |   sourceUuid: UUIDStringType; | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  |   sourceConversationId: string; | 
					
						
							|  |  |  |   sourceDevice: number; | 
					
						
							|  |  |  |   type: MessageReceiptType; | 
					
						
							| 
									
										
										
										
											2022-08-15 14:53:33 -07:00
										 |  |  |   wasSentEncrypted: boolean; | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MessageReceiptModel extends Model<MessageReceiptAttributesType> {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let singleton: MessageReceipts | undefined; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-31 14:35:01 -07:00
										 |  |  | const deleteSentProtoBatcher = createWaitBatcher({ | 
					
						
							|  |  |  |   name: 'deleteSentProtoBatcher', | 
					
						
							|  |  |  |   wait: 250, | 
					
						
							|  |  |  |   maxSize: 30, | 
					
						
							|  |  |  |   async processBatch(items: Array<DeleteSentProtoRecipientOptionsType>) { | 
					
						
							| 
									
										
										
										
											2021-09-17 14:27:53 -04:00
										 |  |  |     log.info( | 
					
						
							| 
									
										
										
										
											2021-08-31 14:35:01 -07:00
										 |  |  |       `MessageReceipts: Batching ${items.length} sent proto recipients deletes` | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2022-08-15 14:53:33 -07:00
										 |  |  |     const { successfulPhoneNumberShares } = await deleteSentProtoRecipient( | 
					
						
							|  |  |  |       items | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (const uuid of successfulPhoneNumberShares) { | 
					
						
							|  |  |  |       const convo = window.ConversationController.get(uuid); | 
					
						
							|  |  |  |       if (!convo) { | 
					
						
							|  |  |  |         continue; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       log.info( | 
					
						
							|  |  |  |         'MessageReceipts: unsetting shareMyPhoneNumber ' + | 
					
						
							|  |  |  |           `for ${convo.idForLogging()}` | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // `deleteSentProtoRecipient` has already updated the database so there
 | 
					
						
							|  |  |  |       // is no need in calling `updateConversation`
 | 
					
						
							|  |  |  |       convo.unset('shareMyPhoneNumber'); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-31 14:35:01 -07:00
										 |  |  |   }, | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  | async function getTargetMessage( | 
					
						
							|  |  |  |   sourceId: string, | 
					
						
							| 
									
										
										
										
											2021-10-26 15:59:08 -07:00
										 |  |  |   sourceUuid: UUIDStringType, | 
					
						
							| 
									
										
										
										
											2021-12-10 14:51:54 -08:00
										 |  |  |   messages: ReadonlyArray<MessageAttributesType> | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  | ): Promise<MessageModel | null> { | 
					
						
							|  |  |  |   if (messages.length === 0) { | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   const message = messages.find( | 
					
						
							| 
									
										
										
										
											2022-04-20 20:29:37 -04:00
										 |  |  |     item => | 
					
						
							|  |  |  |       (isOutgoing(item) || isStory(item)) && sourceId === item.conversationId | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  |   ); | 
					
						
							|  |  |  |   if (message) { | 
					
						
							|  |  |  |     return window.MessageController.register(message.id, message); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-10 14:51:54 -08:00
										 |  |  |   const groups = await window.Signal.Data.getAllGroupsInvolvingUuid(sourceUuid); | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-10 14:51:54 -08:00
										 |  |  |   const ids = groups.map(item => item.id); | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  |   ids.push(sourceId); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const target = messages.find( | 
					
						
							| 
									
										
										
										
											2022-04-20 20:29:37 -04:00
										 |  |  |     item => | 
					
						
							|  |  |  |       (isOutgoing(item) || isStory(item)) && ids.includes(item.conversationId) | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  |   ); | 
					
						
							|  |  |  |   if (!target) { | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return window.MessageController.register(target.id, target); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const wasDeliveredWithSealedSender = ( | 
					
						
							|  |  |  |   conversationId: string, | 
					
						
							|  |  |  |   message: MessageModel | 
					
						
							|  |  |  | ): boolean => | 
					
						
							|  |  |  |   (message.get('unidentifiedDeliveries') || []).some( | 
					
						
							|  |  |  |     identifier => | 
					
						
							|  |  |  |       window.ConversationController.getConversationId(identifier) === | 
					
						
							|  |  |  |       conversationId | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:18:42 -07:00
										 |  |  | const shouldDropReceipt = ( | 
					
						
							|  |  |  |   receipt: MessageReceiptModel, | 
					
						
							|  |  |  |   message: MessageModel | 
					
						
							|  |  |  | ): boolean => { | 
					
						
							|  |  |  |   const type = receipt.get('type'); | 
					
						
							|  |  |  |   switch (type) { | 
					
						
							|  |  |  |     case MessageReceiptType.Delivery: | 
					
						
							|  |  |  |       return false; | 
					
						
							|  |  |  |     case MessageReceiptType.Read: | 
					
						
							|  |  |  |       return !window.storage.get('read-receipt-setting'); | 
					
						
							|  |  |  |     case MessageReceiptType.View: | 
					
						
							|  |  |  |       if (isStory(message.attributes)) { | 
					
						
							|  |  |  |         return !window.Events.getStoryViewReceiptsEnabled(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return !window.storage.get('read-receipt-setting'); | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       throw missingCaseError(type); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  | export class MessageReceipts extends Collection<MessageReceiptModel> { | 
					
						
							|  |  |  |   static getSingleton(): MessageReceipts { | 
					
						
							|  |  |  |     if (!singleton) { | 
					
						
							|  |  |  |       singleton = new MessageReceipts(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return singleton; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-11 14:54:06 -08:00
										 |  |  |   forMessage(message: MessageModel): Array<MessageReceiptModel> { | 
					
						
							|  |  |  |     if (!isOutgoing(message.attributes) && !isStory(message.attributes)) { | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  |       return []; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-01-11 14:54:06 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     const ourUuid = window.textsecure.storage.user.getCheckedUuid().toString(); | 
					
						
							|  |  |  |     const sourceUuid = getSourceUuid(message.attributes); | 
					
						
							|  |  |  |     if (ourUuid !== sourceUuid) { | 
					
						
							|  |  |  |       return []; | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-01-11 14:54:06 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:18:42 -07:00
										 |  |  |     const sentAt = message.get('sent_at'); | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  |     const receipts = this.filter( | 
					
						
							| 
									
										
										
										
											2023-01-11 14:54:06 -08:00
										 |  |  |       receipt => receipt.get('messageSentAt') === sentAt | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  |     ); | 
					
						
							|  |  |  |     if (receipts.length) { | 
					
						
							| 
									
										
										
										
											2022-10-25 15:18:42 -07:00
										 |  |  |       log.info(`MessageReceipts: found early receipts for message ${sentAt}`); | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  |       this.remove(receipts); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-10-25 15:18:42 -07:00
										 |  |  |     return receipts.filter(receipt => { | 
					
						
							|  |  |  |       if (shouldDropReceipt(receipt, message)) { | 
					
						
							|  |  |  |         log.info( | 
					
						
							|  |  |  |           `MessageReceipts: Dropping an early receipt ${receipt.get('type')} ` + | 
					
						
							|  |  |  |             `for message ${sentAt}` | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-30 20:52:03 -04:00
										 |  |  |   private async updateMessageSendState( | 
					
						
							|  |  |  |     receipt: MessageReceiptModel, | 
					
						
							|  |  |  |     message: MessageModel | 
					
						
							|  |  |  |   ): Promise<void> { | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  |     const messageSentAt = receipt.get('messageSentAt'); | 
					
						
							| 
									
										
										
										
											2022-10-25 15:18:42 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (shouldDropReceipt(receipt, message)) { | 
					
						
							|  |  |  |       log.info( | 
					
						
							|  |  |  |         `MessageReceipts: Dropping a receipt ${receipt.get('type')} ` + | 
					
						
							|  |  |  |           `for message ${messageSentAt}` | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 15:49:38 -05:00
										 |  |  |     const receiptTimestamp = receipt.get('receiptTimestamp'); | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  |     const sourceConversationId = receipt.get('sourceConversationId'); | 
					
						
							| 
									
										
										
										
											2022-06-30 20:52:03 -04:00
										 |  |  |     const type = receipt.get('type'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const oldSendStateByConversationId = | 
					
						
							|  |  |  |       message.get('sendStateByConversationId') || {}; | 
					
						
							|  |  |  |     const oldSendState = getOwn( | 
					
						
							|  |  |  |       oldSendStateByConversationId, | 
					
						
							|  |  |  |       sourceConversationId | 
					
						
							|  |  |  |     ) ?? { status: SendStatus.Sent, updatedAt: undefined }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     let sendActionType: SendActionType; | 
					
						
							|  |  |  |     switch (type) { | 
					
						
							|  |  |  |       case MessageReceiptType.Delivery: | 
					
						
							|  |  |  |         sendActionType = SendActionType.GotDeliveryReceipt; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case MessageReceiptType.Read: | 
					
						
							|  |  |  |         sendActionType = SendActionType.GotReadReceipt; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case MessageReceiptType.View: | 
					
						
							|  |  |  |         sendActionType = SendActionType.GotViewedReceipt; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  |         throw missingCaseError(type); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const newSendState = sendStateReducer(oldSendState, { | 
					
						
							|  |  |  |       type: sendActionType, | 
					
						
							|  |  |  |       updatedAt: receiptTimestamp, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // The send state may not change. For example, this can happen if we get a read
 | 
					
						
							|  |  |  |     //   receipt before a delivery receipt.
 | 
					
						
							|  |  |  |     if (!isEqual(oldSendState, newSendState)) { | 
					
						
							|  |  |  |       message.set('sendStateByConversationId', { | 
					
						
							|  |  |  |         ...oldSendStateByConversationId, | 
					
						
							|  |  |  |         [sourceConversationId]: newSendState, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 20:54:43 -07:00
										 |  |  |       queueUpdateMessage(message.attributes); | 
					
						
							| 
									
										
										
										
											2022-06-30 20:52:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |       // notify frontend listeners
 | 
					
						
							|  |  |  |       const conversation = window.ConversationController.get( | 
					
						
							|  |  |  |         message.get('conversationId') | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |       const updateLeftPane = conversation | 
					
						
							|  |  |  |         ? conversation.debouncedUpdateLastMessage | 
					
						
							|  |  |  |         : undefined; | 
					
						
							|  |  |  |       if (updateLeftPane) { | 
					
						
							|  |  |  |         updateLeftPane(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ( | 
					
						
							|  |  |  |       (type === MessageReceiptType.Delivery && | 
					
						
							| 
									
										
										
										
											2022-08-15 14:53:33 -07:00
										 |  |  |         wasDeliveredWithSealedSender(sourceConversationId, message) && | 
					
						
							|  |  |  |         receipt.get('wasSentEncrypted')) || | 
					
						
							| 
									
										
										
										
											2022-06-30 20:52:03 -04:00
										 |  |  |       type === MessageReceiptType.Read | 
					
						
							|  |  |  |     ) { | 
					
						
							|  |  |  |       const recipient = window.ConversationController.get(sourceConversationId); | 
					
						
							|  |  |  |       const recipientUuid = recipient?.get('uuid'); | 
					
						
							|  |  |  |       const deviceId = receipt.get('sourceDevice'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (recipientUuid && deviceId) { | 
					
						
							| 
									
										
										
										
											2022-08-15 14:53:33 -07:00
										 |  |  |         await Promise.all([ | 
					
						
							|  |  |  |           deleteSentProtoBatcher.add({ | 
					
						
							|  |  |  |             timestamp: messageSentAt, | 
					
						
							|  |  |  |             recipientUuid, | 
					
						
							|  |  |  |             deviceId, | 
					
						
							|  |  |  |           }), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           // We want the above call to not be delayed when testing with
 | 
					
						
							|  |  |  |           // CI.
 | 
					
						
							| 
									
										
										
										
											2023-01-18 19:02:03 -05:00
										 |  |  |           window.SignalCI | 
					
						
							| 
									
										
										
										
											2023-01-12 19:24:59 -05:00
										 |  |  |             ? deleteSentProtoBatcher.flushAndWait() | 
					
						
							|  |  |  |             : Promise.resolve(), | 
					
						
							| 
									
										
										
										
											2022-08-15 14:53:33 -07:00
										 |  |  |         ]); | 
					
						
							| 
									
										
										
										
											2022-06-30 20:52:03 -04:00
										 |  |  |       } else { | 
					
						
							|  |  |  |         log.warn( | 
					
						
							|  |  |  |           `MessageReceipts.onReceipt: Missing uuid or deviceId for deliveredTo ${sourceConversationId}` | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async onReceipt(receipt: MessageReceiptModel): Promise<void> { | 
					
						
							|  |  |  |     const messageSentAt = receipt.get('messageSentAt'); | 
					
						
							|  |  |  |     const sourceConversationId = receipt.get('sourceConversationId'); | 
					
						
							| 
									
										
										
										
											2021-10-26 15:59:08 -07:00
										 |  |  |     const sourceUuid = receipt.get('sourceUuid'); | 
					
						
							| 
									
										
										
										
											2022-06-30 20:52:03 -04:00
										 |  |  |     const type = receipt.get('type'); | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     try { | 
					
						
							| 
									
										
										
										
											2023-03-27 19:48:57 -04:00
										 |  |  |       const messages = | 
					
						
							|  |  |  |         await window.Signal.Data.getMessagesIncludingEditedBySentAt( | 
					
						
							|  |  |  |           messageSentAt | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-26 15:59:08 -07:00
										 |  |  |       const message = await getTargetMessage( | 
					
						
							|  |  |  |         sourceConversationId, | 
					
						
							|  |  |  |         sourceUuid, | 
					
						
							|  |  |  |         messages | 
					
						
							|  |  |  |       ); | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-30 20:52:03 -04:00
										 |  |  |       if (message) { | 
					
						
							|  |  |  |         await this.updateMessageSendState(receipt, message); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         // We didn't find any messages but maybe it's a story sent message
 | 
					
						
							|  |  |  |         const targetMessages = messages.filter( | 
					
						
							|  |  |  |           item => | 
					
						
							|  |  |  |             item.storyDistributionListId && | 
					
						
							|  |  |  |             item.sendStateByConversationId && | 
					
						
							|  |  |  |             !item.deletedForEveryone && | 
					
						
							|  |  |  |             Boolean(item.sendStateByConversationId[sourceConversationId]) | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  |         ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-30 20:52:03 -04:00
										 |  |  |         // Nope, no target message was found
 | 
					
						
							|  |  |  |         if (!targetMessages.length) { | 
					
						
							|  |  |  |           log.info( | 
					
						
							| 
									
										
										
										
											2022-10-25 15:18:42 -07:00
										 |  |  |             'MessageReceipts: No message for receipt', | 
					
						
							| 
									
										
										
										
											2022-06-30 20:52:03 -04:00
										 |  |  |             type, | 
					
						
							|  |  |  |             sourceConversationId, | 
					
						
							| 
									
										
										
										
											2022-08-15 14:53:33 -07:00
										 |  |  |             sourceUuid, | 
					
						
							| 
									
										
										
										
											2022-06-30 20:52:03 -04:00
										 |  |  |             messageSentAt | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  |           ); | 
					
						
							| 
									
										
										
										
											2022-06-30 20:52:03 -04:00
										 |  |  |           return; | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-06-30 20:52:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         await Promise.all( | 
					
						
							|  |  |  |           targetMessages.map(msg => { | 
					
						
							|  |  |  |             const model = window.MessageController.register(msg.id, msg); | 
					
						
							|  |  |  |             return this.updateMessageSendState(receipt, model); | 
					
						
							|  |  |  |           }) | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       this.remove(receipt); | 
					
						
							|  |  |  |     } catch (error) { | 
					
						
							| 
									
										
										
										
											2022-11-22 10:43:43 -08:00
										 |  |  |       log.error('MessageReceipts.onReceipt error:', Errors.toLogFormat(error)); | 
					
						
							| 
									
										
										
										
											2021-07-20 15:17:25 -05:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |