diff --git a/CHANGELOG.md b/CHANGELOG.md index 711d6e9b7..329af4351 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,10 @@ -# Unreleased +# 2.3.2 (2025-09-02) -### Fixed +### Widget Works Modification +* [WIDGET-WORKS] Fix `PrismaClientValidationError` in `messages.update` (missing `Message` relation) by guarding `messageUpdate.create` calls. * [WIDGET-WORKS] Guard `messages.update` cache cleanup with a derived key and optional `MESSAGE_UPDATE_CACHE_DELETE_DISABLED` flag to prevent cache.delete crash-loops. -# 2.3.2 (2025-09-02) ### Features diff --git a/src/api/integrations/channel/whatsapp/baileysMessage.processor.ts b/src/api/integrations/channel/whatsapp/baileysMessage.processor.ts index 1b0202fbf..d46c347ad 100644 --- a/src/api/integrations/channel/whatsapp/baileysMessage.processor.ts +++ b/src/api/integrations/channel/whatsapp/baileysMessage.processor.ts @@ -1,5 +1,5 @@ import { Logger } from '@config/logger.config'; -import { BaileysEventMap, MessageUpsertType, proto } from 'baileys'; +import { BaileysEventMap, MessageUpsertType } from 'baileys'; import { catchError, concatMap, delay, EMPTY, from, retryWhen, Subject, Subscription, take, tap } from 'rxjs'; type MessageUpsertPayload = BaileysEventMap['messages.upsert']; diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts index 03be7876c..eea479af8 100644 --- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts +++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts @@ -151,7 +151,8 @@ import { BaileysMessageProcessor } from './baileysMessage.processor'; import { useVoiceCallsBaileys } from './voiceCalls/useVoiceCallsBaileys'; // [WIDGET-WORKS] Local helper because isJidUser is absent from current Baileys typings. -const isJidUser = (jid?: string) => !!jid && jid.includes('@s.whatsapp.net') && !isJidGroup(jid) && !isJidBroadcast(jid); +const isJidUser = (jid?: string) => + !!jid && jid.includes('@s.whatsapp.net') && !isJidGroup(jid) && !isJidBroadcast(jid); // [WIDGET-WORKS] Gracefully access non-typed Baileys senderPn on keys. const getSenderPn = (key: WAMessageKey | proto.IMessageKey) => (key as any)?.senderPn; @@ -1478,9 +1479,16 @@ export class BaileysStartupService extends ChannelStartupService { if (update.message === null && update.status === undefined) { this.sendDataWebhook(Events.MESSAGES_DELETE, key); - if (this.configService.get('DATABASE').SAVE_DATA.MESSAGE_UPDATE) - await this.prismaRepository.messageUpdate.create({ data: message }); - + if (this.configService.get('DATABASE').SAVE_DATA.MESSAGE_UPDATE) { + // [WIDGET-WORKS] Guard against missing parent message to prevent PrismaClientValidationError + if (message.messageId) { + await this.prismaRepository.messageUpdate.create({ data: message }); + } else { + this.logger.warn( + `[WIDGET-WORKS] Skipping messageUpdate.create for key ${key.id}: Parent message not found.`, + ); + } + } if (this.configService.get('CHATWOOT').ENABLED && this.localChatwoot?.enabled) { this.chatwootService.eventWhatsapp( Events.MESSAGES_DELETE, @@ -1524,8 +1532,16 @@ export class BaileysStartupService extends ChannelStartupService { this.sendDataWebhook(Events.MESSAGES_UPDATE, message); - if (this.configService.get('DATABASE').SAVE_DATA.MESSAGE_UPDATE) - await this.prismaRepository.messageUpdate.create({ data: message }); + if (this.configService.get('DATABASE').SAVE_DATA.MESSAGE_UPDATE) { + // [WIDGET-WORKS] Guard against missing parent message to prevent PrismaClientValidationError + if (message.messageId) { + await this.prismaRepository.messageUpdate.create({ data: message }); + } else { + this.logger.warn( + `[WIDGET-WORKS] Skipping messageUpdate.create for key ${key.id}: Parent message not found.`, + ); + } + } if (!skipMessageUpdateCacheDelete) { const cacheDeleteKey = `${this.instanceId}:${message.remoteJid}:${message.keyId}`;