From 019ac36a787003035c1f7957e660d8466796d838 Mon Sep 17 00:00:00 2001 From: Renato Alcara Date: Tue, 27 Jan 2026 21:14:38 -0300 Subject: [PATCH] =?UTF-8?q?fix:=20n=C3=A3o=20injetar=20biz=20node=20para?= =?UTF-8?q?=20mensagens=20de=20cat=C3=A1logo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adicionada função isCatalogMessage() para detectar mensagens de catálogo (catalog_message, single_product, product_list). Mensagens de catálogo funcionam apenas com o formato proto viewOnceMessage > interactiveMessage > nativeFlowMessage, sem necessidade de injeção de biz node. Isso corrige o error 405 ao enviar lista de produtos. Co-Authored-By: Claude Opus 4.5 --- src/Socket/messages-send.ts | 38 ++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 8680661d..d4478456 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -763,6 +763,27 @@ export const makeMessagesSocket = (config: SocketConfig) => { return false } + /** + * Checks if the message is a catalog/product message (catalog_message, single_product) + * These messages may need different biz node handling or no biz node at all + */ + const isCatalogMessage = (message: proto.IMessage): boolean => { + const interactiveMsg = message.interactiveMessage || + message.viewOnceMessage?.message?.interactiveMessage + + const nativeFlow = interactiveMsg?.nativeFlowMessage + if (nativeFlow?.buttons?.length) { + // Check if any button is a catalog-type button + return nativeFlow.buttons.some( + (btn: any) => btn?.name === 'catalog_message' || + btn?.name === 'single_product' || + btn?.name === 'product_list' + ) + } + + return false + } + /** * Checks if the nativeFlowMessage is a list (single_select button) * Lists need type='list' in the biz node instead of type='native_flow' @@ -1147,7 +1168,12 @@ export const makeMessagesSocket = (config: SocketConfig) => { // ⚠️ EXPERIMENTAL: Inject 'biz' node for interactive messages // This may not work and can cause account bans const buttonType = getButtonType(message) - if (buttonType && enableInteractiveMessages) { + const isCatalog = isCatalogMessage(message) + const isCarousel = isCarouselMessage(message) + + // Catalog messages (catalog_message, single_product) don't need biz node injection + // They work with just the viewOnceMessage > interactiveMessage > nativeFlowMessage format + if (buttonType && enableInteractiveMessages && !isCatalog) { const startTime = Date.now() // Debug: Log message structure to diagnose list detection @@ -1222,8 +1248,6 @@ export const makeMessagesSocket = (config: SocketConfig) => { destinationJid?.endsWith('@c.us') ) && !isJidBot(destinationJid) - const isCarousel = isCarouselMessage(message) - if (isPrivateUserChat && !isCarousel) { ;(stanza.content as BinaryNode[]).push({ tag: 'bot', @@ -1250,6 +1274,14 @@ export const makeMessagesSocket = (config: SocketConfig) => { ) metrics.interactiveMessagesFailures.inc({ type: buttonType, reason: 'injection_failed' }) } + } else if (buttonType && isCatalog) { + // Catalog messages (catalog_message, single_product, product_list) work without biz node + // The viewOnceMessage > interactiveMessage > nativeFlowMessage format is sufficient + logger.info( + { msgId, buttonType, to: destinationJid }, + '[CATALOG] Sending catalog/product message without biz node injection' + ) + metrics.interactiveMessagesSent.inc({ type: 'catalog' }) } else if (buttonType && !enableInteractiveMessages) { logger.warn( { msgId, buttonType },