fix(carousel): hasSubtitle + relayMessage direto + proto atualizado
Implementação completa baseada na análise ponto-a-ponto de 5 diferenças: 1. hasSubtitle adicionado ao proto schema (field 10, bool em Header) - Adicionado ao WAProto.proto, index.js (encode/decode/fromObject/toObject) - Adicionado ao index.d.ts (IHeader, Header class) - Usado no root header e em cada card do carousel 2. relayMessage direto para carousel em sendMessage - Detecta nativeCarousel no content e bypassa generateWAMessage inteiro - Chama generateWAMessageContent (que usa fromObject) diretamente - Depois relayMessage sem passar por generateWAMessageFromContent - Elimina: segundo WAProto.Message.create(), contextInfo.expiration, etc. 3. Pipeline final do carousel agora: sendMessage → generateWAMessageContent(fromObject) → relayMessage Sem: generateWAMessageFromContent, WAProto.Message.create, ephemeral Commits anteriores já incluem: - viewOnceMessage wrapper - fromObject no generateWAMessageContent - Skip tctoken no stanza https://claude.ai/code/session_01EK9NpViRCtda1WAvFd8ptR
This commit is contained in:
@@ -30,6 +30,7 @@ import {
|
||||
generateMessageIDV2,
|
||||
generateParticipantHashV2,
|
||||
generateWAMessage,
|
||||
generateWAMessageContent,
|
||||
getStatusCodeForMediaRetry,
|
||||
getUrlFromDirectPath,
|
||||
getWAUploadToServer,
|
||||
@@ -1964,6 +1965,52 @@ 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
|
||||
if (typeof content === 'object' && 'nativeCarousel' in content && (content as any).nativeCarousel) {
|
||||
const messageId = generateMessageIDV2(sock.user?.id)
|
||||
const msgContent = await generateWAMessageContent(content, {
|
||||
logger,
|
||||
upload: waUploadToServer,
|
||||
mediaCache: config.mediaCache,
|
||||
options: config.options,
|
||||
jid,
|
||||
})
|
||||
|
||||
const timestamp = unixTimestampSeconds()
|
||||
const fullMsg = proto.WebMessageInfo.fromObject({
|
||||
key: {
|
||||
remoteJid: jid,
|
||||
fromMe: true,
|
||||
id: messageId
|
||||
},
|
||||
message: msgContent,
|
||||
messageTimestamp: timestamp,
|
||||
messageStubParameters: [],
|
||||
participant: isJidGroup(jid) ? userJid : undefined,
|
||||
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'
|
||||
await messageMutex.mutex(mutexKey, () => upsertMessage(fullMsg, 'append'))
|
||||
})
|
||||
}
|
||||
|
||||
return fullMsg
|
||||
}
|
||||
|
||||
if (
|
||||
typeof content === 'object' &&
|
||||
'disappearingMessagesInChat' in content &&
|
||||
|
||||
@@ -616,7 +616,8 @@ export const generateCarouselMessage = async (
|
||||
|
||||
const header: any = {
|
||||
title: card.title || '',
|
||||
hasMediaAttachment: hasMedia
|
||||
hasMediaAttachment: hasMedia,
|
||||
hasSubtitle: !!card.title
|
||||
}
|
||||
|
||||
// Process media if present
|
||||
@@ -642,7 +643,7 @@ export const generateCarouselMessage = async (
|
||||
|
||||
// Build the interactive message with carousel
|
||||
const interactiveMessage: proto.Message.IInteractiveMessage = {
|
||||
header: text ? { title: text } : undefined,
|
||||
header: text ? { title: text, hasSubtitle: true } : undefined,
|
||||
body: { text: text || '' },
|
||||
footer: footer ? { text: footer } : undefined,
|
||||
carouselMessage: {
|
||||
|
||||
Reference in New Issue
Block a user