From e7898536ec67d3e0f7f3c3236092ebe0318b89f3 Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Tue, 7 Apr 2026 19:52:46 +0530 Subject: [PATCH] feat: add message_received socket handler to notify senders of delivery status --- src/messages/messages.gateway.ts | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/messages/messages.gateway.ts b/src/messages/messages.gateway.ts index 0a46753..2273a05 100644 --- a/src/messages/messages.gateway.ts +++ b/src/messages/messages.gateway.ts @@ -323,6 +323,45 @@ export class MessagesGateway implements OnGatewayConnection, OnGatewayDisconnect }); } + /** + * Acknowledge message delivery from receiver client. + * Called by mobile/web when `new_message` is received via socket so the + * sender gets a real-time double-tick regardless of Redis presence state. + */ + @SubscribeMessage('message_received') + async handleMessageReceived( + @ConnectedSocket() client: AuthenticatedSocket, + @MessageBody() data: { messageId: string; conversationId: string }, + ) { + if (!client.userId || !data?.messageId) return { error: 'Invalid request' }; + + try { + // Verify the receiver is actually a participant of this conversation + const message = await this.prisma.message.findUnique({ + where: { id: data.messageId }, + select: { id: true, senderId: true, conversationId: true, status: true }, + }); + + if (!message) return { error: 'Message not found' }; + // Don't mark sender's own message as delivered + if (message.senderId === client.userId) return { success: false }; + // Already delivered or read — no-op + if (message.status !== 'SENT') return { success: true }; + + const updated = await this.messagesService.markMessageDelivered(message.id); + const deliveredEvent = { + messageId: message.id, + conversationId: message.conversationId, + deliveredAt: (updated.deliveredAt ?? new Date()).toISOString(), + }; + this.sendToUser(message.senderId, 'message_delivered', deliveredEvent); + return { success: true }; + } catch (error) { + this.logger.warn(`message_received ack failed for ${client.userId}: ${error.message}`); + return { error: 'Failed to ack delivery' }; + } + } + /** * Mark messages as read */