From 0720de8827195a015dfe5a614faa96ca614dff6e Mon Sep 17 00:00:00 2001 From: Merul Dhiman Date: Mon, 8 Dec 2025 22:25:33 +0530 Subject: [PATCH] fix: duplicate chats being created for eCurrency --- .../src/controllers/WebhookController.ts | 21 +++++++ .../src/controllers/WebhookController.ts | 59 +++++++++++++++---- .../pictique-api/src/services/ChatService.ts | 41 +++++++++++++ 3 files changed, 109 insertions(+), 12 deletions(-) diff --git a/platforms/blabsy-w3ds-auth-api/src/controllers/WebhookController.ts b/platforms/blabsy-w3ds-auth-api/src/controllers/WebhookController.ts index d9bb77841..3095b458d 100644 --- a/platforms/blabsy-w3ds-auth-api/src/controllers/WebhookController.ts +++ b/platforms/blabsy-w3ds-auth-api/src/controllers/WebhookController.ts @@ -161,6 +161,27 @@ export class WebhookController { // Check for existing DM (2 participants, no name) before creating const participants = mappedData.participants || []; const isDM = participants.length === 2 && !mappedData.name; + const chatName = mappedData.name; + + // For eCurrency Chat groups, check by name first + if (chatName && (chatName.startsWith("eCurrency Chat") || chatName.includes("eCurrency Chat"))) { + const existingChatsQuery = collection.where('name', '==', chatName); + const existingChatsSnapshot = await existingChatsQuery.get(); + + if (!existingChatsSnapshot.empty) { + // Use existing chat and store mapping + const existingDoc = existingChatsSnapshot.docs[0]; + console.log(`⚠️ eCurrency Chat with name "${chatName}" already exists, using existing: ${existingDoc.id}`); + docRef = collection.doc(existingDoc.id); + adapter.addToLockedIds(docRef.id); + adapter.addToLockedIds(globalId); + await adapter.mappingDb.storeMapping({ + globalId: globalId, + localId: docRef.id, + }); + return; // Exit early, don't create new chat + } + } if (isDM) { // Query for existing chats with these participants diff --git a/platforms/pictique-api/src/controllers/WebhookController.ts b/platforms/pictique-api/src/controllers/WebhookController.ts index f65e4c871..342e04469 100644 --- a/platforms/pictique-api/src/controllers/WebhookController.ts +++ b/platforms/pictique-api/src/controllers/WebhookController.ts @@ -297,18 +297,53 @@ export class WebhookController { }); } } else { - // Group chat - always create new - chat = await this.chatService.createChat( - local.data.name as string, - participantIds - ); - chat.admins = admins; - await this.chatService.chatRepository.save(chat); - this.adapter.addToLockedIds(chat.id); - await this.adapter.mappingDb.storeMapping({ - localId: chat.id, - globalId: req.body.id, - }); + // Group chat - check for eCurrency Chat duplicates by name + const chatName = local.data.name as string; + if (chatName && (chatName.startsWith("eCurrency Chat") || chatName.includes("eCurrency Chat"))) { + // Check if chat with this name already exists + const existingChat = await this.chatService.chatRepository.findOne({ + where: { name: chatName }, + relations: ["participants", "admins"] + }); + + if (existingChat) { + console.log(`⚠️ eCurrency Chat with name "${chatName}" already exists, using existing: ${existingChat.id}`); + chat = existingChat; + chat.admins = admins; + await this.chatService.chatRepository.save(chat); + this.adapter.addToLockedIds(chat.id); + await this.adapter.mappingDb.storeMapping({ + localId: chat.id, + globalId: req.body.id, + }); + } else { + // Create new chat + chat = await this.chatService.createChat( + chatName, + participantIds + ); + chat.admins = admins; + await this.chatService.chatRepository.save(chat); + this.adapter.addToLockedIds(chat.id); + await this.adapter.mappingDb.storeMapping({ + localId: chat.id, + globalId: req.body.id, + }); + } + } else { + // Regular group chat - always create new + chat = await this.chatService.createChat( + chatName, + participantIds + ); + chat.admins = admins; + await this.chatService.chatRepository.save(chat); + this.adapter.addToLockedIds(chat.id); + await this.adapter.mappingDb.storeMapping({ + localId: chat.id, + globalId: req.body.id, + }); + } } } } else if (mapping.tableName === "messages") { diff --git a/platforms/pictique-api/src/services/ChatService.ts b/platforms/pictique-api/src/services/ChatService.ts index 4b6b5b8d4..ff301dd1e 100644 --- a/platforms/pictique-api/src/services/ChatService.ts +++ b/platforms/pictique-api/src/services/ChatService.ts @@ -61,6 +61,47 @@ export class ChatService { participantIds: string[] = [], creatorId?: string ): Promise { + // For eCurrency Chat groups, check if a chat with the same name already exists + // This prevents duplicate chat creation + if (name && (name.startsWith("eCurrency Chat") || name.includes("eCurrency Chat"))) { + return await AppDataSource.transaction(async (transactionalEntityManager) => { + // Check if a chat with this exact name already exists + const existingChat = await transactionalEntityManager.findOne(Chat, { + where: { name }, + relations: ["participants", "admins"] + }); + + if (existingChat) { + console.log(`⚠️ Chat with name "${name}" already exists, returning existing chat: ${existingChat.id}`); + return existingChat; + } + + // No existing chat found, create new one + const participants = await transactionalEntityManager.findBy(User, { + id: In(participantIds), + }); + if (participants.length !== participantIds.length) { + throw new Error("One or more participants not found"); + } + + let admins: User[] = []; + if (creatorId) { + const creator = await transactionalEntityManager.findOneBy(User, { id: creatorId }); + if (creator) { + admins = [creator]; + } + } + + const chat = transactionalEntityManager.create(Chat, { + name: name, + participants, + admins, + }); + return await transactionalEntityManager.save(Chat, chat); + }); + } + + // For non-eCurrency Chat groups, proceed normally const participants = await this.userRepository.findBy({ id: In(participantIds), });