diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index a77161f4..e8cbdfa7 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -1443,8 +1443,11 @@ export const makeMessagesSocket = (config: SocketConfig) => { } } + // Skip tctoken for carousel messages - not present in working implementations + // and may cause error 479 on linked devices + const isCarouselForTcToken = isCarouselMessage(message) const contactTcTokenData = - !isGroup && !isRetryResend && !isStatus ? await authState.keys.get('tctoken', [destinationJid]) : {} + !isGroup && !isRetryResend && !isStatus && !isCarouselForTcToken ? await authState.keys.get('tctoken', [destinationJid]) : {} const tcTokenBuffer = contactTcTokenData[destinationJid]?.token diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 277f98db..27507070 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -1712,6 +1712,10 @@ export const generateWAMessageFromContent = ( } } + // Skip ephemeral contextInfo for carousel messages - carousel was already + // processed with fromObject and adding contextInfo.expiration may cause + // error 479 on linked devices (Web/Desktop) + const isCarouselEphemeral = !!(message as any)?.viewOnceMessage?.message?.interactiveMessage?.carouselMessage if ( // if we want to send a disappearing message !!options?.ephemeralExpiration && @@ -1720,7 +1724,9 @@ export const generateWAMessageFromContent = ( // already not converted to disappearing message key !== 'ephemeralMessage' && // newsletters don't support ephemeral messages - !isJidNewsletter(jid) + !isJidNewsletter(jid) && + // carousel messages should not have ephemeral contextInfo + !isCarouselEphemeral ) { /* @ts-ignore */ innerMessage[key].contextInfo = { @@ -1730,7 +1736,13 @@ export const generateWAMessageFromContent = ( } } - message = WAProto.Message.create(message) + // For carousel messages already processed with fromObject, skip create() to + // preserve the deep protobuf conversion. create() does shallow assignment which + // may not properly handle deeply nested carousel structures (cards > headers > media) + const isCarouselVOM = !!(message as any)?.viewOnceMessage?.message?.interactiveMessage?.carouselMessage + if (!isCarouselVOM) { + message = WAProto.Message.create(message) + } const messageJSON = { key: {