From d31d6fa554ebc1b9ca51da03d6b94433db2d2e34 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 9 Sep 2025 16:18:05 -0300 Subject: [PATCH] refactor: replace JSON path queries with raw SQL in Baileys and Chatwoot services to improve message retrieval and update logic --- .../whatsapp/whatsapp.baileys.service.ts | 63 ++++++++++--------- .../chatwoot/services/chatwoot.service.ts | 59 ++++++----------- 2 files changed, 55 insertions(+), 67 deletions(-) diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts index e1d2ab30..fffae53c 100644 --- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts +++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts @@ -484,9 +484,13 @@ export class BaileysStartupService extends ChannelStartupService { private async getMessage(key: proto.IMessageKey, full = false) { try { - const webMessageInfo = (await this.prismaRepository.message.findMany({ - where: { instanceId: this.instanceId, key: { path: ['id'], equals: key.id } }, - })) as unknown as proto.IWebMessageInfo[]; + // Use raw SQL to avoid JSON path issues + const webMessageInfo = (await this.prismaRepository.$queryRaw` + SELECT * FROM "Message" + WHERE "instanceId" = ${this.instanceId} + AND "key"->>'id' = ${key.id} + `) as proto.IWebMessageInfo[]; + if (full) { return webMessageInfo[0]; } @@ -1459,9 +1463,14 @@ export class BaileysStartupService extends ChannelStartupService { let findMessage: any; const configDatabaseData = this.configService.get('DATABASE').SAVE_DATA; if (configDatabaseData.HISTORIC || configDatabaseData.NEW_MESSAGE) { - findMessage = await this.prismaRepository.message.findFirst({ - where: { instanceId: this.instanceId, key: { path: ['id'], equals: key.id } }, - }); + // Use raw SQL to avoid JSON path issues + const messages = (await this.prismaRepository.$queryRaw` + SELECT * FROM "Message" + WHERE "instanceId" = ${this.instanceId} + AND "key"->>'id' = ${key.id} + LIMIT 1 + `) as any[]; + findMessage = messages[0] || null; if (findMessage) message.messageId = findMessage.id; } @@ -4427,24 +4436,23 @@ export class BaileysStartupService extends ChannelStartupService { private async updateMessagesReadedByTimestamp(remoteJid: string, timestamp?: number): Promise { if (timestamp === undefined || timestamp === null) return 0; - const result = await this.prismaRepository.message.updateMany({ - where: { - AND: [ - { key: { path: ['remoteJid'], equals: remoteJid } }, - { key: { path: ['fromMe'], equals: false } }, - { messageTimestamp: { lte: timestamp } }, - { OR: [{ status: null }, { status: status[3] }] }, - ], - }, - data: { status: status[4] }, - }); + // Use raw SQL to avoid JSON path issues + const result = await this.prismaRepository.$executeRaw` + UPDATE "Message" + SET "status" = ${status[4]} + WHERE "instanceId" = ${this.instanceId} + AND "key"->>'remoteJid' = ${remoteJid} + AND ("key"->>'fromMe')::boolean = false + AND "messageTimestamp" <= ${timestamp} + AND ("status" IS NULL OR "status" = ${status[3]}) + `; if (result) { - if (result.count > 0) { + if (result > 0) { this.updateChatUnreadMessages(remoteJid); } - return result.count; + return result; } return 0; @@ -4453,15 +4461,14 @@ export class BaileysStartupService extends ChannelStartupService { private async updateChatUnreadMessages(remoteJid: string): Promise { const [chat, unreadMessages] = await Promise.all([ this.prismaRepository.chat.findFirst({ where: { remoteJid } }), - this.prismaRepository.message.count({ - where: { - AND: [ - { key: { path: ['remoteJid'], equals: remoteJid } }, - { key: { path: ['fromMe'], equals: false } }, - { status: { equals: status[3] } }, - ], - }, - }), + // Use raw SQL to avoid JSON path issues + this.prismaRepository.$queryRaw` + SELECT COUNT(*)::int as count FROM "Message" + WHERE "instanceId" = ${this.instanceId} + AND "key"->>'remoteJid' = ${remoteJid} + AND ("key"->>'fromMe')::boolean = false + AND "status" = ${status[3]} + `.then((result: any[]) => result[0]?.count || 0), ]); if (chat && chat.unreadMessages !== unreadMessages) { diff --git a/src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts b/src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts index ccddd0ce..2cf16134 100644 --- a/src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts +++ b/src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts @@ -1561,33 +1561,18 @@ export class ChatwootService { return; } - // Use the message ID directly instead of JSON path query - await this.prismaRepository.message.updateMany({ - where: { - AND: [ - { instanceId: instance.instanceId }, - { - OR: [ - { id: message.id }, // Use the actual message ID if available - // Fallback to raw query if needed - { - key: { - path: ['id'], - equals: key.id, - }, - }, - ], - }, - ], - }, - data: { - chatwootMessageId: chatwootMessageIds.messageId, - chatwootConversationId: chatwootMessageIds.conversationId, - chatwootInboxId: chatwootMessageIds.inboxId, - chatwootContactInboxSourceId: chatwootMessageIds.contactInboxSourceId, - chatwootIsRead: chatwootMessageIds.isRead, - }, - }); + // Use raw SQL to avoid JSON path issues + await this.prismaRepository.$executeRaw` + UPDATE "Message" + SET + "chatwootMessageId" = ${chatwootMessageIds.messageId}, + "chatwootConversationId" = ${chatwootMessageIds.conversationId}, + "chatwootInboxId" = ${chatwootMessageIds.inboxId}, + "chatwootContactInboxSourceId" = ${chatwootMessageIds.contactInboxSourceId}, + "chatwootIsRead" = ${chatwootMessageIds.isRead || false} + WHERE "instanceId" = ${instance.instanceId} + AND "key"->>'id' = ${key.id} + `; if (this.isImportHistoryAvailable()) { chatwootImport.updateMessageSourceID(chatwootMessageIds.messageId, key.id); @@ -1595,19 +1580,15 @@ export class ChatwootService { } private async getMessageByKeyId(instance: InstanceDto, keyId: string): Promise { - // Try to find message using a more compatible approach - const messages = await this.prismaRepository.message.findFirst({ - where: { - instanceId: instance.instanceId, - // Use raw query to avoid JSON path issues - key: { - path: ['id'], - equals: keyId, - }, - }, - }); + // Use raw SQL query to avoid JSON path issues with Prisma + const messages = await this.prismaRepository.$queryRaw` + SELECT * FROM "Message" + WHERE "instanceId" = ${instance.instanceId} + AND "key"->>'id' = ${keyId} + LIMIT 1 + `; - return messages || null; + return (messages as MessageModel[])[0] || null; } private async getReplyToIds(