feat: Automatically mark messages as delivered when recipients come online or receive new messages.
This commit is contained in:
@@ -99,6 +99,26 @@ export class MessagesGateway implements OnGatewayConnection, OnGatewayDisconnect
|
|||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
this.logger.warn(`Failed to update online status for ${userId}: ${err.message}`);
|
this.logger.warn(`Failed to update online status for ${userId}: ${err.message}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Mark pending SENT messages as DELIVERED now that this user is online
|
||||||
|
this.messagesService.markPendingMessagesAsDelivered(userId)
|
||||||
|
.then((results) => {
|
||||||
|
for (const result of results) {
|
||||||
|
// Notify each sender that their messages were delivered
|
||||||
|
const deliveredEvent = {
|
||||||
|
messageIds: result.messageIds,
|
||||||
|
conversationId: result.conversationId,
|
||||||
|
deliveredAt: result.deliveredAt,
|
||||||
|
};
|
||||||
|
this.sendToUser(result.senderId, 'message_delivered', deliveredEvent);
|
||||||
|
}
|
||||||
|
if (results.length > 0) {
|
||||||
|
this.logger.log(`Marked pending messages as delivered for ${userId} across ${results.length} conversation(s)`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
this.logger.warn(`Failed to mark pending messages as delivered for ${userId}: ${err.message}`);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -190,6 +210,18 @@ export class MessagesGateway implements OnGatewayConnection, OnGatewayDisconnect
|
|||||||
? participants.agentUserId
|
? participants.agentUserId
|
||||||
: participants.userId;
|
: participants.userId;
|
||||||
this.sendToUser(otherUserId, 'new_message', message);
|
this.sendToUser(otherUserId, 'new_message', message);
|
||||||
|
|
||||||
|
// Auto-mark as DELIVERED if recipient is online
|
||||||
|
if (this.isUserOnline(otherUserId)) {
|
||||||
|
await this.messagesService.markMessageDelivered(message.id);
|
||||||
|
const deliveredEvent = {
|
||||||
|
messageId: message.id,
|
||||||
|
conversationId: data.conversationId,
|
||||||
|
deliveredAt: new Date(),
|
||||||
|
};
|
||||||
|
// Notify sender that message was delivered
|
||||||
|
this.sendToUser(client.userId, 'message_delivered', deliveredEvent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (participantError) {
|
} catch (participantError) {
|
||||||
this.logger.warn(`Failed to get participants for direct delivery in ${data.conversationId}: ${participantError.message}`);
|
this.logger.warn(`Failed to get participants for direct delivery in ${data.conversationId}: ${participantError.message}`);
|
||||||
|
|||||||
@@ -528,6 +528,52 @@ export class MessagesService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark all SENT messages addressed to a user as DELIVERED (when they come online)
|
||||||
|
* Returns the updated messages grouped by conversation for notification purposes
|
||||||
|
*/
|
||||||
|
async markPendingMessagesAsDelivered(userId: string): Promise<{ conversationId: string; senderId: string; messageIds: string[]; deliveredAt: Date }[]> {
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
// Find all conversations where this user is a participant
|
||||||
|
const conversations = await this.prisma.conversation.findMany({
|
||||||
|
where: {
|
||||||
|
OR: [
|
||||||
|
{ userId },
|
||||||
|
{ agentProfile: { userId } },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
select: { id: true, userId: true, agentProfile: { select: { userId: true } } },
|
||||||
|
});
|
||||||
|
|
||||||
|
const results: { conversationId: string; senderId: string; messageIds: string[]; deliveredAt: Date }[] = [];
|
||||||
|
|
||||||
|
for (const conv of conversations) {
|
||||||
|
const otherUserId = conv.userId === userId ? conv.agentProfile.userId : conv.userId;
|
||||||
|
|
||||||
|
// Find SENT messages from the other user in this conversation
|
||||||
|
const sentMessages = await this.prisma.message.findMany({
|
||||||
|
where: {
|
||||||
|
conversationId: conv.id,
|
||||||
|
senderId: otherUserId,
|
||||||
|
status: MessageStatus.SENT,
|
||||||
|
},
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (sentMessages.length > 0) {
|
||||||
|
const messageIds = sentMessages.map((m) => m.id);
|
||||||
|
await this.prisma.message.updateMany({
|
||||||
|
where: { id: { in: messageIds } },
|
||||||
|
data: { status: MessageStatus.DELIVERED, deliveredAt: now },
|
||||||
|
});
|
||||||
|
results.push({ conversationId: conv.id, senderId: otherUserId, messageIds, deliveredAt: now });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get conversation by ID with full details
|
* Get conversation by ID with full details
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user