fix(whatsapp): peel nested envelopes and restore immediate payload return
A quoted message can carry its own envelope stack (ephemeral wrapping viewOnce wrapping the payload), and a reply itself can be enveloped: both layers now unwrap iteratively (bounded) before quote extraction. Peeled top-level envelopes return their inner message immediately, as before — the template/buttons/list branches only apply to unenveloped messages.
This commit is contained in:
committed by
Teknium
parent
5de769956f
commit
7ecd4d14a5
@@ -468,4 +468,43 @@ import {
|
||||
console.log(' ✓ quoted message text survives ephemeral/view-once/document envelopes');
|
||||
}
|
||||
|
||||
{
|
||||
// Nested envelopes (ephemeral wrapping viewOnce wrapping the payload) and
|
||||
// the second envelope position: quoted text must resolve there as well.
|
||||
const quotedMessage = {
|
||||
ephemeralMessage: {
|
||||
message: {
|
||||
viewOnceMessageV2: {
|
||||
message: { extendedTextMessage: { text: 'Example appointment at 11:40' } },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const event = await extractBridgeEvent({
|
||||
msg: {
|
||||
key: { id: 'reply-nested', remoteJid: '15551234567@s.whatsapp.net', fromMe: false },
|
||||
messageTimestamp: 123,
|
||||
message: {
|
||||
ephemeralMessage: {
|
||||
message: {
|
||||
extendedTextMessage: {
|
||||
text: 'confirmed',
|
||||
contextInfo: { stanzaId: 'original-id', participant: '15559998888@s.whatsapp.net', quotedMessage },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
chatId: '15551234567@s.whatsapp.net',
|
||||
senderId: '15550001111@s.whatsapp.net',
|
||||
senderNumber: '15550001111',
|
||||
botIds: ['15559998888@s.whatsapp.net'],
|
||||
downloadMedia: async () => Buffer.from(''),
|
||||
});
|
||||
assert.equal(event.quotedMessageId, 'original-id');
|
||||
assert.equal(event.hasQuotedMessage, true);
|
||||
assert.equal(event.quotedText, 'Example appointment at 11:40');
|
||||
console.log(' ✓ nested envelopes: quote text resolves through both layers');
|
||||
}
|
||||
|
||||
console.log('\n✅ All WhatsApp native bridge helper tests passed.');
|
||||
|
||||
@@ -19,15 +19,26 @@ export function normalizeWhatsAppId(value) {
|
||||
}
|
||||
|
||||
function unwrapMessageEnvelopes(content) {
|
||||
if (content?.ephemeralMessage?.message) return content.ephemeralMessage.message;
|
||||
if (content?.viewOnceMessage?.message) return content.viewOnceMessage.message;
|
||||
if (content?.viewOnceMessageV2?.message) return content.viewOnceMessageV2.message;
|
||||
if (content?.documentWithCaptionMessage?.message) return content.documentWithCaptionMessage.message;
|
||||
return content;
|
||||
let cur = content;
|
||||
// Envelopes nest (ephemeral wrapping viewOnce wrapping the payload); peel
|
||||
// until an inner message is reached so nested quotes resolve too.
|
||||
for (let i = 0; i < 8 && cur; i++) {
|
||||
const next =
|
||||
cur.ephemeralMessage?.message ??
|
||||
cur.viewOnceMessage?.message ??
|
||||
cur.viewOnceMessageV2?.message ??
|
||||
cur.documentWithCaptionMessage?.message;
|
||||
if (next === undefined) break;
|
||||
cur = next;
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
export function getMessageContent(msg) {
|
||||
const content = unwrapMessageEnvelopes(msg?.message || {});
|
||||
// A peeled envelope returns its inner message immediately: the payload
|
||||
// shape (template/buttons/list/etc.) applies to unenveloped messages.
|
||||
if (content !== (msg?.message || {})) return content;
|
||||
if (content.templateMessage?.hydratedTemplate) return content.templateMessage.hydratedTemplate;
|
||||
if (content.buttonsMessage) return content.buttonsMessage;
|
||||
if (content.listMessage) return content.listMessage;
|
||||
|
||||
Reference in New Issue
Block a user