diff --git a/src/messages/messages.gateway.ts b/src/messages/messages.gateway.ts index a236fed..d5fdf93 100644 --- a/src/messages/messages.gateway.ts +++ b/src/messages/messages.gateway.ts @@ -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}`); diff --git a/src/messages/messages.service.ts b/src/messages/messages.service.ts index aacbbc4..79a0a59 100644 --- a/src/messages/messages.service.ts +++ b/src/messages/messages.service.ts @@ -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 */