diff --git a/src/Utils/messages.ts b/src/Utils/messages.ts index 86a38228..5f974742 100644 --- a/src/Utils/messages.ts +++ b/src/Utils/messages.ts @@ -396,7 +396,89 @@ export const generateWAMessageContent = async ( options: MessageContentGenerationOptions ) => { let m: WAMessageContent = {} - if (hasNonNullishProperty(message, 'text')) { + + // ⚠️ EXPERIMENTAL: Check for interactive messages FIRST (buttons, lists, templates) + if (hasNonNullishProperty(message, 'text') && hasNonNullishProperty(message, 'buttons')) { + // Process buttons for text messages + const buttonsMessage: proto.Message.IButtonsMessage = { + contentText: (message as any).text, + footerText: (message as any).footerText, + headerType: (message as any).headerType || proto.Message.ButtonsMessage.HeaderType.EMPTY + } + + buttonsMessage.buttons = ((message as any).buttons as any[]).map((btn: any, idx: number) => ({ + buttonId: btn.buttonId || `btn_${idx}`, + buttonText: { displayText: btn.buttonText?.displayText || btn.displayText || btn.text }, + type: btn.type || proto.Message.ButtonsMessage.Button.Type.RESPONSE + })) + + m.buttonsMessage = buttonsMessage + options.logger?.warn('[EXPERIMENTAL] Sending buttonsMessage - this may not work and can cause bans') + } else if (hasNonNullishProperty(message, 'text') && hasNonNullishProperty(message, 'templateButtons')) { + // Process templateButtons + const templateMessage: proto.Message.ITemplateMessage = { + hydratedTemplate: { + hydratedContentText: (message as any).text, + hydratedFooterText: (message as any).footer + } + } + + templateMessage.hydratedTemplate!.hydratedButtons = ((message as any).templateButtons as any[]).map((btn: any) => { + if (btn.quickReplyButton) { + return { index: btn.index, quickReplyButton: btn.quickReplyButton } + } else if (btn.urlButton) { + return { index: btn.index, urlButton: btn.urlButton } + } else if (btn.callButton) { + return { index: btn.index, callButton: btn.callButton } + } + return btn + }) + + m.templateMessage = templateMessage + options.logger?.warn('[EXPERIMENTAL] Sending templateMessage - this may not work and can cause bans') + } else if (hasNonNullishProperty(message, 'sections')) { + // Process list messages + const listMessage: proto.Message.IListMessage = { + title: (message as any).title, + description: (message as any).text, + buttonText: (message as any).buttonText || 'View options', + footerText: (message as any).footerText, + listType: proto.Message.ListMessage.ListType.SINGLE_SELECT + } + + listMessage.sections = ((message as any).sections as any[]).map((section: any) => ({ + title: section.title, + rows: section.rows.map((row: any) => ({ + rowId: row.rowId || row.id, + title: row.title, + description: row.description + })) + })) + + m.listMessage = listMessage + options.logger?.warn('[EXPERIMENTAL] Sending listMessage - this may not work and can cause bans') + } else if (hasNonNullishProperty(message, 'carousel')) { + // Process carousel/interactive messages + const carousel = (message as any).carousel + const interactiveMessage: proto.Message.IInteractiveMessage = { + header: carousel.header || { title: carousel.title || 'Carousel', hasMediaAttachment: false }, + body: { text: (message as any).text || carousel.description || '' }, + footer: carousel.footer ? { text: carousel.footer } : undefined, + carouselMessage: { + cards: carousel.cards.map((card: any) => ({ + header: card.header, + body: card.body, + footer: card.footer, + nativeFlowMessage: card.nativeFlowMessage + })), + messageVersion: carousel.messageVersion || 1 + } + } + + m.interactiveMessage = interactiveMessage + options.logger?.warn('[EXPERIMENTAL] Sending carouselMessage - this may not work and can cause bans') + } else if (hasNonNullishProperty(message, 'text')) { + // Normal text message processing const extContent = { text: message.text } as WATextMessage let urlInfo = message.linkPreview @@ -513,108 +595,7 @@ export const generateWAMessageContent = async ( break } } - // ⚠️ EXPERIMENTAL: Interactive messages - may not work and can cause account bans - // Process buttons for text messages - else if (hasNonNullishProperty(message, 'text') && hasNonNullishProperty(message, 'buttons')) { - const buttonsMessage: proto.Message.IButtonsMessage = { - contentText: (message as any).text, - footerText: (message as any).footerText, - headerType: (message as any).headerType || proto.Message.ButtonsMessage.HeaderType.EMPTY - } - - // Add buttons - buttonsMessage.buttons = ((message as any).buttons as any[]).map((btn: any, idx: number) => ({ - buttonId: btn.buttonId || `btn_${idx}`, - buttonText: { displayText: btn.buttonText?.displayText || btn.displayText || btn.text }, - type: btn.type || proto.Message.ButtonsMessage.Button.Type.RESPONSE - })) - - m.buttonsMessage = buttonsMessage - options.logger?.warn('[EXPERIMENTAL] Sending buttonsMessage - this may not work and can cause bans') - } - // Process templateButtons - else if (hasNonNullishProperty(message, 'text') && hasNonNullishProperty(message, 'templateButtons')) { - const templateMessage: proto.Message.ITemplateMessage = { - hydratedTemplate: { - hydratedContentText: (message as any).text, - hydratedFooterText: (message as any).footer - } - } - - // Add template buttons - templateMessage.hydratedTemplate!.hydratedButtons = ((message as any).templateButtons as any[]).map((btn: any) => { - if (btn.quickReplyButton) { - return { - index: btn.index, - quickReplyButton: btn.quickReplyButton - } - } else if (btn.urlButton) { - return { - index: btn.index, - urlButton: btn.urlButton - } - } else if (btn.callButton) { - return { - index: btn.index, - callButton: btn.callButton - } - } - return btn - }) - - m.templateMessage = templateMessage - options.logger?.warn('[EXPERIMENTAL] Sending templateMessage - this may not work and can cause bans') - } - // Process list messages - else if (hasNonNullishProperty(message, 'sections')) { - const listMessage: proto.Message.IListMessage = { - title: (message as any).title, - description: (message as any).text, - buttonText: (message as any).buttonText || 'View options', - footerText: (message as any).footerText, - listType: proto.Message.ListMessage.ListType.SINGLE_SELECT - } - - // Add sections - listMessage.sections = ((message as any).sections as any[]).map((section: any) => ({ - title: section.title, - rows: section.rows.map((row: any) => ({ - rowId: row.rowId || row.id, - title: row.title, - description: row.description - })) - })) - - m.listMessage = listMessage - options.logger?.warn('[EXPERIMENTAL] Sending listMessage - this may not work and can cause bans') - } - // Process carousel/interactive messages - else if (hasNonNullishProperty(message, 'carousel')) { - const carousel = (message as any).carousel - const interactiveMessage: proto.Message.IInteractiveMessage = { - header: carousel.header || { - title: carousel.title || 'Carousel', - hasMediaAttachment: false - }, - body: { - text: (message as any).text || carousel.description || '' - }, - footer: carousel.footer ? { text: carousel.footer } : undefined, - carouselMessage: { - cards: carousel.cards.map((card: any) => ({ - header: card.header, - body: card.body, - footer: card.footer, - nativeFlowMessage: card.nativeFlowMessage - })), - messageVersion: carousel.messageVersion || 1 - } - } - - m.interactiveMessage = interactiveMessage - options.logger?.warn('[EXPERIMENTAL] Sending carouselMessage - this may not work and can cause bans') - } - // Process buttons with media (image/video) + // ⚠️ EXPERIMENTAL: Process buttons with media (image/video) else if ( (hasNonNullishProperty(message, 'image') || hasNonNullishProperty(message, 'video')) && hasNonNullishProperty(message, 'buttons')