refactor: replace JSON path queries with raw SQL in Baileys and Chatwoot services to improve message retrieval and update logic
Some checks are pending
Build Docker image / Build and Deploy (push) Waiting to run

This commit is contained in:
Davidson Gomes 2025-09-09 16:18:05 -03:00
parent edbf36019e
commit d31d6fa554
2 changed files with 55 additions and 67 deletions

View File

@ -484,9 +484,13 @@ export class BaileysStartupService extends ChannelStartupService {
private async getMessage(key: proto.IMessageKey, full = false) { private async getMessage(key: proto.IMessageKey, full = false) {
try { try {
const webMessageInfo = (await this.prismaRepository.message.findMany({ // Use raw SQL to avoid JSON path issues
where: { instanceId: this.instanceId, key: { path: ['id'], equals: key.id } }, const webMessageInfo = (await this.prismaRepository.$queryRaw`
})) as unknown as proto.IWebMessageInfo[]; SELECT * FROM "Message"
WHERE "instanceId" = ${this.instanceId}
AND "key"->>'id' = ${key.id}
`) as proto.IWebMessageInfo[];
if (full) { if (full) {
return webMessageInfo[0]; return webMessageInfo[0];
} }
@ -1459,9 +1463,14 @@ export class BaileysStartupService extends ChannelStartupService {
let findMessage: any; let findMessage: any;
const configDatabaseData = this.configService.get<Database>('DATABASE').SAVE_DATA; const configDatabaseData = this.configService.get<Database>('DATABASE').SAVE_DATA;
if (configDatabaseData.HISTORIC || configDatabaseData.NEW_MESSAGE) { if (configDatabaseData.HISTORIC || configDatabaseData.NEW_MESSAGE) {
findMessage = await this.prismaRepository.message.findFirst({ // Use raw SQL to avoid JSON path issues
where: { instanceId: this.instanceId, key: { path: ['id'], equals: key.id } }, 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; if (findMessage) message.messageId = findMessage.id;
} }
@ -4427,24 +4436,23 @@ export class BaileysStartupService extends ChannelStartupService {
private async updateMessagesReadedByTimestamp(remoteJid: string, timestamp?: number): Promise<number> { private async updateMessagesReadedByTimestamp(remoteJid: string, timestamp?: number): Promise<number> {
if (timestamp === undefined || timestamp === null) return 0; if (timestamp === undefined || timestamp === null) return 0;
const result = await this.prismaRepository.message.updateMany({ // Use raw SQL to avoid JSON path issues
where: { const result = await this.prismaRepository.$executeRaw`
AND: [ UPDATE "Message"
{ key: { path: ['remoteJid'], equals: remoteJid } }, SET "status" = ${status[4]}
{ key: { path: ['fromMe'], equals: false } }, WHERE "instanceId" = ${this.instanceId}
{ messageTimestamp: { lte: timestamp } }, AND "key"->>'remoteJid' = ${remoteJid}
{ OR: [{ status: null }, { status: status[3] }] }, AND ("key"->>'fromMe')::boolean = false
], AND "messageTimestamp" <= ${timestamp}
}, AND ("status" IS NULL OR "status" = ${status[3]})
data: { status: status[4] }, `;
});
if (result) { if (result) {
if (result.count > 0) { if (result > 0) {
this.updateChatUnreadMessages(remoteJid); this.updateChatUnreadMessages(remoteJid);
} }
return result.count; return result;
} }
return 0; return 0;
@ -4453,15 +4461,14 @@ export class BaileysStartupService extends ChannelStartupService {
private async updateChatUnreadMessages(remoteJid: string): Promise<number> { private async updateChatUnreadMessages(remoteJid: string): Promise<number> {
const [chat, unreadMessages] = await Promise.all([ const [chat, unreadMessages] = await Promise.all([
this.prismaRepository.chat.findFirst({ where: { remoteJid } }), this.prismaRepository.chat.findFirst({ where: { remoteJid } }),
this.prismaRepository.message.count({ // Use raw SQL to avoid JSON path issues
where: { this.prismaRepository.$queryRaw`
AND: [ SELECT COUNT(*)::int as count FROM "Message"
{ key: { path: ['remoteJid'], equals: remoteJid } }, WHERE "instanceId" = ${this.instanceId}
{ key: { path: ['fromMe'], equals: false } }, AND "key"->>'remoteJid' = ${remoteJid}
{ status: { equals: status[3] } }, AND ("key"->>'fromMe')::boolean = false
], AND "status" = ${status[3]}
}, `.then((result: any[]) => result[0]?.count || 0),
}),
]); ]);
if (chat && chat.unreadMessages !== unreadMessages) { if (chat && chat.unreadMessages !== unreadMessages) {

View File

@ -1561,33 +1561,18 @@ export class ChatwootService {
return; return;
} }
// Use the message ID directly instead of JSON path query // Use raw SQL to avoid JSON path issues
await this.prismaRepository.message.updateMany({ await this.prismaRepository.$executeRaw`
where: { UPDATE "Message"
AND: [ SET
{ instanceId: instance.instanceId }, "chatwootMessageId" = ${chatwootMessageIds.messageId},
{ "chatwootConversationId" = ${chatwootMessageIds.conversationId},
OR: [ "chatwootInboxId" = ${chatwootMessageIds.inboxId},
{ id: message.id }, // Use the actual message ID if available "chatwootContactInboxSourceId" = ${chatwootMessageIds.contactInboxSourceId},
// Fallback to raw query if needed "chatwootIsRead" = ${chatwootMessageIds.isRead || false}
{ WHERE "instanceId" = ${instance.instanceId}
key: { AND "key"->>'id' = ${key.id}
path: ['id'], `;
equals: key.id,
},
},
],
},
],
},
data: {
chatwootMessageId: chatwootMessageIds.messageId,
chatwootConversationId: chatwootMessageIds.conversationId,
chatwootInboxId: chatwootMessageIds.inboxId,
chatwootContactInboxSourceId: chatwootMessageIds.contactInboxSourceId,
chatwootIsRead: chatwootMessageIds.isRead,
},
});
if (this.isImportHistoryAvailable()) { if (this.isImportHistoryAvailable()) {
chatwootImport.updateMessageSourceID(chatwootMessageIds.messageId, key.id); chatwootImport.updateMessageSourceID(chatwootMessageIds.messageId, key.id);
@ -1595,19 +1580,15 @@ export class ChatwootService {
} }
private async getMessageByKeyId(instance: InstanceDto, keyId: string): Promise<MessageModel> { private async getMessageByKeyId(instance: InstanceDto, keyId: string): Promise<MessageModel> {
// Try to find message using a more compatible approach // Use raw SQL query to avoid JSON path issues with Prisma
const messages = await this.prismaRepository.message.findFirst({ const messages = await this.prismaRepository.$queryRaw`
where: { SELECT * FROM "Message"
instanceId: instance.instanceId, WHERE "instanceId" = ${instance.instanceId}
// Use raw query to avoid JSON path issues AND "key"->>'id' = ${keyId}
key: { LIMIT 1
path: ['id'], `;
equals: keyId,
},
},
});
return messages || null; return (messages as MessageModel[])[0] || null;
} }
private async getReplyToIds( private async getReplyToIds(