Refactor target message for delivery receipt processing

This commit is contained in:
trevor-signal 2023-12-08 15:35:31 -05:00 committed by GitHub
parent e724f36b79
commit c2b1d76e6d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 82 additions and 40 deletions

View file

@ -15,6 +15,7 @@ import * as Errors from '../types/errors';
import {
SendActionType,
SendStatus,
UNDELIVERED_SEND_STATUSES,
sendStateReducer,
} from '../messages/MessageSendState';
import type { DeleteSentProtoRecipientOptionsType } from '../sql/Interface';
@ -25,6 +26,7 @@ import { queueUpdateMessage } from '../util/messageBatcher';
import { getMessageSentTimestamp } from '../util/getMessageSentTimestamp';
import { getMessageIdForLogging } from '../util/idForLogging';
import { generateCacheKey } from './generateCacheKey';
import { getPropForTimestamp } from '../util/editHelpers';
const { deleteSentProtoRecipient } = dataInterface;
@ -38,7 +40,7 @@ export type MessageReceiptAttributesType = {
envelopeId: string;
messageSentAt: number;
receiptTimestamp: number;
removeFromMessageReceiverCache: () => unknown;
removeFromMessageReceiverCache: () => void;
sourceConversationId: string;
sourceDevice: number;
sourceServiceId: ServiceIdString;
@ -89,45 +91,74 @@ function remove(receipt: MessageReceiptAttributesType): void {
receipt.removeFromMessageReceiverCache();
}
async function getTargetMessage(
sourceId: string,
serviceId: ServiceIdString,
messages: ReadonlyArray<MessageAttributesType>
): Promise<MessageModel | null> {
function getTargetMessage({
sourceConversationId,
messages,
targetTimestamp,
}: {
sourceConversationId: string;
messages: ReadonlyArray<MessageAttributesType>;
targetTimestamp: number;
}): MessageModel | null {
if (messages.length === 0) {
return null;
}
const message = messages.find(
item =>
(isOutgoing(item) || isStory(item)) && sourceId === item.conversationId
);
if (message) {
return window.MessageCache.__DEPRECATED$register(
message.id,
message,
'MessageReceipts.getTargetMessage 1'
);
}
const groups = await window.Signal.Data.getAllGroupsInvolvingServiceId(
serviceId
);
const matchingMessages = messages
.filter(msg => isOutgoing(msg) || isStory(msg))
.filter(msg => {
const sendStateByConversationId = getPropForTimestamp({
message: msg,
prop: 'sendStateByConversationId',
targetTimestamp,
log,
});
const ids = groups.map(item => item.id);
ids.push(sourceId);
const isRecipient = Object.hasOwn(
sendStateByConversationId ?? {},
sourceConversationId
);
if (!isRecipient) {
return false;
}
const target = messages.find(
item =>
(isOutgoing(item) || isStory(item)) && ids.includes(item.conversationId)
);
if (!target) {
const sendStatus =
sendStateByConversationId?.[sourceConversationId]?.status;
if (
sendStatus === undefined ||
UNDELIVERED_SEND_STATUSES.includes(sendStatus)
) {
log.warn(`
MessageReceipts.getTargetMessage: received receipt for undelivered message,
status: ${sendStatus},
sourceConversationId: ${sourceConversationId},
message: ${getMessageIdForLogging(message)}.
`);
return false;
}
return true;
});
if (matchingMessages.length === 0) {
return null;
}
if (matchingMessages.length > 1) {
log.warn(`
MessageReceipts.getTargetMessage: multiple (${matchingMessages.length})
matching messages for receipt,
sentAt=${targetTimestamp},
sourceConversationId=${sourceConversationId}
`);
}
const message = matchingMessages[0];
return window.MessageCache.__DEPRECATED$register(
target.id,
target,
'MessageReceipts.getTargetMessage 2'
message.id,
message,
'MessageReceipts.getTargetMessage'
);
}
@ -367,11 +398,11 @@ export async function onReceipt(
messageSentAt
);
const message = await getTargetMessage(
const message = getTargetMessage({
sourceConversationId,
sourceServiceId,
messages
);
messages,
targetTimestamp: receipt.messageSentAt,
});
if (message) {
await updateMessageSendState(receipt, message);