fix(carousel): bypass proto fromObject for carousel messages to fix
fix(carousel): bypass proto fromObject for carousel messages to fix
This commit is contained in:
+19
-11
@@ -2020,12 +2020,16 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
|
||||
const userJid = authState.creds.me!.id
|
||||
|
||||
// Special path for carousel: call relayMessage directly
|
||||
// This bypasses generateWAMessageFromContent (which adds contextInfo.expiration
|
||||
// and calls WAProto.Message.create that may corrupt nested carousel structures)
|
||||
// Matches the working implementation's approach: generateWAMessageContent → relayMessage
|
||||
// Special path for carousel: call relayMessage directly with plain JS object
|
||||
// This matches Pastorini's working approach:
|
||||
// 1. Build message as plain JS object (not proto instance)
|
||||
// 2. Pass directly to relayMessage (no WAProto.Message.fromObject/create)
|
||||
// 3. protobuf encode() handles plain objects correctly during serialization
|
||||
// Going through fromObject() can corrupt nested carousel InteractiveMessage oneOf fields
|
||||
if (typeof content === 'object' && 'nativeCarousel' in content && (content as any).nativeCarousel) {
|
||||
const messageId = generateMessageIDV2(sock.user?.id)
|
||||
// generateWAMessageContent returns a plain JS object for carousel
|
||||
// (not a proto instance) to preserve nested structure integrity
|
||||
const msgContent = await generateWAMessageContent(content, {
|
||||
logger,
|
||||
upload: waUploadToServer,
|
||||
@@ -2034,6 +2038,17 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
jid,
|
||||
})
|
||||
|
||||
// Pass the plain JS object directly to relayMessage
|
||||
// This avoids proto.WebMessageInfo.fromObject() which would call
|
||||
// Message.fromObject() on the nested message, potentially corrupting it
|
||||
await relayMessage(jid, msgContent, {
|
||||
messageId,
|
||||
useCachedGroupMetadata: options.useCachedGroupMetadata,
|
||||
additionalAttributes: {},
|
||||
statusJidList: options.statusJidList,
|
||||
})
|
||||
|
||||
// Build WebMessageInfo only for event emission and return value
|
||||
const timestamp = unixTimestampSeconds()
|
||||
const fullMsg = proto.WebMessageInfo.fromObject({
|
||||
key: {
|
||||
@@ -2048,13 +2063,6 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
status: proto.WebMessageInfo.Status.PENDING
|
||||
}) as WAMessage
|
||||
|
||||
await relayMessage(jid, fullMsg.message!, {
|
||||
messageId: fullMsg.key.id!,
|
||||
useCachedGroupMetadata: options.useCachedGroupMetadata,
|
||||
additionalAttributes: {},
|
||||
statusJidList: options.statusJidList,
|
||||
})
|
||||
|
||||
if (config.emitOwnEvents) {
|
||||
process.nextTick(async () => {
|
||||
const mutexKey = fullMsg.key.remoteJid || fullMsg.key.id || 'unknown'
|
||||
|
||||
+10
-7
@@ -641,8 +641,10 @@ export const generateCarouselMessage = async (
|
||||
}))
|
||||
|
||||
// Build the interactive message with carousel
|
||||
// Root header MUST always be present for carousel messages (WhatsApp MD requirement)
|
||||
// Missing root header causes error 479 on some devices
|
||||
const interactiveMessage: proto.Message.IInteractiveMessage = {
|
||||
header: text ? { title: text } : undefined,
|
||||
header: { title: text || '', hasMediaAttachment: false },
|
||||
body: { text: text || '' },
|
||||
footer: footer ? { text: footer } : undefined,
|
||||
carouselMessage: {
|
||||
@@ -1156,12 +1158,13 @@ export const generateWAMessageContent = async (
|
||||
// Pass options for media processing if cards have images/videos
|
||||
const generated = await generateCarouselMessage(carouselOptions, options)
|
||||
m.viewOnceMessage = generated.viewOnceMessage
|
||||
options.logger?.info('Sending carousel with viewOnceMessage wrapper + fromObject encoding')
|
||||
// Return early with fromObject for proper deep conversion of nested carousel structure
|
||||
// fromObject recursively converts nested plain objects to protobuf message instances
|
||||
// whereas create() does shallow property copy which may not properly encode deep structures
|
||||
// This matches the working implementation's encoding approach
|
||||
return WAProto.Message.fromObject(m)
|
||||
options.logger?.info('Sending carousel with viewOnceMessage wrapper (plain object, no proto conversion)')
|
||||
// Return the plain JS object directly WITHOUT calling WAProto.Message.fromObject()
|
||||
// This matches Pastorini's working approach where plain objects are passed directly
|
||||
// to relayMessage. The fromObject() conversion can corrupt nested carousel structures
|
||||
// by incorrectly handling oneOf fields in deeply nested InteractiveMessage cards.
|
||||
// The protobuf encode() method handles plain objects correctly when serializing.
|
||||
return m as WAMessageContent
|
||||
}
|
||||
// Check for nativeList
|
||||
else if (hasNonNullishProperty(message, 'nativeList')) {
|
||||
|
||||
Reference in New Issue
Block a user