fix: normalize wrapped WhatsApp messages before reading content (#628)
WhatsApp wraps certain message types in container objects: - viewOnceMessageV2 (listen-once voice, view-once media) - ephemeralMessage (disappearing messages) - editedMessage (edited messages) Without calling Baileys' normalizeMessageContent(), the fields conversation, extendedTextMessage, imageMessage, etc. are nested inside the wrapper and invisible to our direct field access. This causes these messages to be silently dropped with no error. - Import and call normalizeMessageContent() early in messages.upsert - Use the normalized content object for all field reads - Add mock to test suite Co-authored-by: Ethan M <ethan@nanoclaw.local> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -87,6 +87,7 @@ vi.mock('@whiskeysockets/baileys', () => {
|
|||||||
fetchLatestWaWebVersion: vi
|
fetchLatestWaWebVersion: vi
|
||||||
.fn()
|
.fn()
|
||||||
.mockResolvedValue({ version: [2, 3000, 0] }),
|
.mockResolvedValue({ version: [2, 3000, 0] }),
|
||||||
|
normalizeMessageContent: vi.fn((content: unknown) => content),
|
||||||
makeCacheableSignalKeyStore: vi.fn((keys: unknown) => keys),
|
makeCacheableSignalKeyStore: vi.fn((keys: unknown) => keys),
|
||||||
useMultiFileAuthState: vi.fn().mockResolvedValue({
|
useMultiFileAuthState: vi.fn().mockResolvedValue({
|
||||||
state: {
|
state: {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import makeWASocket, {
|
|||||||
WASocket,
|
WASocket,
|
||||||
fetchLatestWaWebVersion,
|
fetchLatestWaWebVersion,
|
||||||
makeCacheableSignalKeyStore,
|
makeCacheableSignalKeyStore,
|
||||||
|
normalizeMessageContent,
|
||||||
useMultiFileAuthState,
|
useMultiFileAuthState,
|
||||||
} from '@whiskeysockets/baileys';
|
} from '@whiskeysockets/baileys';
|
||||||
|
|
||||||
@@ -172,6 +173,11 @@ export class WhatsAppChannel implements Channel {
|
|||||||
this.sock.ev.on('messages.upsert', async ({ messages }) => {
|
this.sock.ev.on('messages.upsert', async ({ messages }) => {
|
||||||
for (const msg of messages) {
|
for (const msg of messages) {
|
||||||
if (!msg.message) continue;
|
if (!msg.message) continue;
|
||||||
|
// Unwrap container types (viewOnceMessageV2, ephemeralMessage,
|
||||||
|
// editedMessage, etc.) so that conversation, extendedTextMessage,
|
||||||
|
// imageMessage, etc. are accessible at the top level.
|
||||||
|
const normalized = normalizeMessageContent(msg.message);
|
||||||
|
if (!normalized) continue;
|
||||||
const rawJid = msg.key.remoteJid;
|
const rawJid = msg.key.remoteJid;
|
||||||
if (!rawJid || rawJid === 'status@broadcast') continue;
|
if (!rawJid || rawJid === 'status@broadcast') continue;
|
||||||
|
|
||||||
@@ -196,10 +202,10 @@ export class WhatsAppChannel implements Channel {
|
|||||||
const groups = this.opts.registeredGroups();
|
const groups = this.opts.registeredGroups();
|
||||||
if (groups[chatJid]) {
|
if (groups[chatJid]) {
|
||||||
const content =
|
const content =
|
||||||
msg.message?.conversation ||
|
normalized.conversation ||
|
||||||
msg.message?.extendedTextMessage?.text ||
|
normalized.extendedTextMessage?.text ||
|
||||||
msg.message?.imageMessage?.caption ||
|
normalized.imageMessage?.caption ||
|
||||||
msg.message?.videoMessage?.caption ||
|
normalized.videoMessage?.caption ||
|
||||||
'';
|
'';
|
||||||
|
|
||||||
// Skip protocol messages with no text content (encryption keys, read receipts, etc.)
|
// Skip protocol messages with no text content (encryption keys, read receipts, etc.)
|
||||||
|
|||||||
Reference in New Issue
Block a user