From 6692b383ef81a7f12de76a407fd54d6d74551091 Mon Sep 17 00:00:00 2001 From: Diego Silva Date: Thu, 23 Jul 2026 15:11:41 -0300 Subject: [PATCH] fix(whatsapp): restore reply/quote contextInfo in prepareMessage prepareMessage sourced the message contextInfo from `message.message.messageContextInfo`, which only carries device-list / encryption metadata (threadId, deviceListMetadata, messageSecret) and never the quote. The reply context (stanzaId, participant, quotedMessage) lives on the content node instead, e.g. `extendedTextMessage.contextInfo`. Because the extendedTextMessage node is then flattened into `conversation` and deleted, the quote was lost entirely: inbound (and outbound) replies reach the `messages.upsert` webhook and the DB as plain `conversation` with no quotedMessage or stanzaId, so no integration can link a reply to the message it quotes. The existing `messageRaw.contextInfo.quotedMessage` handling right below became dead code. This restores the content-node source (`contentMsg?.contextInfo`) with a fallback to `messageContextInfo`, matching the behaviour that shipped through v2.3.7. The extendedTextMessage->conversation normalization is kept unchanged. Refs #2078, #1872. Co-Authored-By: Claude --- .../channel/whatsapp/whatsapp.baileys.service.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts index 22839fd451..7c703fab61 100644 --- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts +++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts @@ -5155,6 +5155,8 @@ export class BaileysStartupService extends ChannelStartupService { private prepareMessage(message: WAMessage): Message { const keyAny = message.key as any; + const contentType = getContentType(message.message); + const contentMsg = contentType ? (message.message?.[contentType] as any) : undefined; const messageRaw: any = { key: { ...message.key, @@ -5167,14 +5169,20 @@ export class BaileysStartupService extends ChannelStartupService { ? 'Você' : message?.participant || (message.key?.participant ? message.key.participant.split('@')[0] : null)), message: this.deserializeMessageBuffers({ ...message.message }), - messageType: getContentType(message.message), + messageType: contentType, messageTimestamp: Long.isLong(message.messageTimestamp) ? message.messageTimestamp.toNumber() : (message.messageTimestamp as number), source: getDevice(keyAny.id), instanceId: this.instanceId, status: status[message.status], - contextInfo: this.deserializeMessageBuffers(message.message?.messageContextInfo), + // The quote/reply context lives on the content node (e.g. + // extendedTextMessage.contextInfo), not on the top-level + // messageContextInfo (which only carries device/encryption metadata). + // Reading it from the content node keeps stanzaId/participant/quotedMessage + // available after the extendedTextMessage node is flattened below — this + // is how it worked through v2.3.7 and what downstream reply handling expects. + contextInfo: this.deserializeMessageBuffers(contentMsg?.contextInfo ?? message.message?.messageContextInfo), }; if (!messageRaw.status && message.key.fromMe === false) {