feat: Automatically mark messages as delivered when recipients come online or receive new messages.

This commit is contained in:
pradeepkumar
2026-03-28 02:02:49 +05:30
parent 0abfa51ed9
commit 1697d638b6
2 changed files with 78 additions and 0 deletions

View File

@@ -99,6 +99,26 @@ export class MessagesGateway implements OnGatewayConnection, OnGatewayDisconnect
.catch((err) => {
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.userId;
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) {
this.logger.warn(`Failed to get participants for direct delivery in ${data.conversationId}: ${participantError.message}`);

View File

@@ -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
*/