fix: suppress libsignal session logs + add carousel media warning

1. Suppress verbose "Closing session: SessionEntry {...}" logs from
   libsignal that dump cryptographic keys/ratchets to console.log

2. Add warning when carousel cards don't have media attachments -
   WhatsApp Web requires every card to have hasMediaAttachment:true
   with actual image/video (per ckptw reference implementation)

3. Add carousel structure summary log for debugging card composition

https://claude.ai/code/session_018DkDxsjWzM131jy3ivWjZp
This commit is contained in:
Claude
2026-02-07 02:40:43 +00:00
parent 479f53a8bc
commit 52b8e8b4ff
2 changed files with 39 additions and 0 deletions
+11
View File
@@ -22,6 +22,17 @@ import { SenderKeyRecord } from './Group/sender-key-record'
import { GroupCipher, GroupSessionBuilder, SenderKeyDistributionMessage } from './Group'
import { LIDMappingStore } from './lid-mapping'
// Suppress verbose "Closing session: SessionEntry {...}" logs from libsignal
// These are raw console.log calls from the native Signal library that dump
// cryptographic session details (keys, ratchets, etc.) on every encrypt/decrypt
const _origConsoleLog = console.log
console.log = function(...args: unknown[]) {
if (args.length > 0 && typeof args[0] === 'string' && args[0].startsWith('Closing session')) {
return // suppress libsignal session dump
}
_origConsoleLog.apply(console, args)
}
// ============================================
// Identity Key Detection Constants
// ============================================
+28
View File
@@ -610,6 +610,16 @@ export const generateCarouselMessage = async (
throw new Boom('mediaOptions required for processing card media', { statusCode: 400 })
}
// WhatsApp requires ALL carousel cards to have media attachments (image or video)
// Cards without media will not render on WhatsApp Web/Desktop
const cardsWithoutMedia = cards.filter(card => !card.image && !card.video)
if (cardsWithoutMedia.length > 0) {
mediaOptions?.logger?.warn(
{ cardsWithoutMedia: cardsWithoutMedia.length, totalCards: cards.length },
'[CAROUSEL] WARNING: Cards without media will NOT render on WhatsApp Web. Every card MUST have an image or video.'
)
}
// Map cards to the carousel format (processing media)
const carouselCards = await Promise.all(cards.map(async (card) => {
const hasMedia = !!(card.image || card.video)
@@ -653,6 +663,24 @@ export const generateCarouselMessage = async (
}
}
// Log carousel structure summary for debugging
mediaOptions?.logger?.info(
{
totalCards: carouselCards.length,
cards: carouselCards.map((c: any, i: number) => ({
index: i,
hasMedia: c.header?.hasMediaAttachment,
mediaType: c.header?.imageMessage ? 'image' : c.header?.videoMessage ? 'video' : 'none',
hasBody: !!c.body?.text,
hasFooter: !!c.footer?.text,
buttonsCount: c.nativeFlowMessage?.buttons?.length || 0
})),
rootHeader: !!interactiveMessage.header?.title,
rootBody: !!interactiveMessage.body?.text
},
'[CAROUSEL] Structure summary'
)
// Wrap in viewOnceMessageV2 (NOT V1!) for WhatsApp Web/Desktop rendering
// V2 (field 55) is the stable wrapper for interactive messages from non-Cloud API accounts
// V1 (field 37) caused error 479 - V2 is the correct approach (confirmed by Z-API)