PRODUCT_LIST type requires WhatsApp Business catalog data and causes
error 479 for regular menu lists. SINGLE_SELECT is the correct type
for interactive menu lists with sections/rows.
https://claude.ai/code/session_01SJdSHiUxtwzV8bb5dedodb
Error 479 was still occurring even with legacy listMessage format.
The issue is that listType must be PRODUCT_LIST (not SINGLE_SELECT)
to match the biz node type="product_list" v="2" that we're injecting.
This matches pastorini's working implementation exactly:
- listMessage with listType: PRODUCT_LIST
- biz node with type="product_list" v="2"
https://claude.ai/code/session_01Vgu4xrsj8aUVCHWb4pmQPF
The modern interactiveMessage format was causing error 479 (message rejection).
Switched to legacy listMessage format that matches pastorini's working implementation.
Changes:
1. **messages.ts**: Changed nativeList to use generateListMessageLegacy()
- Creates listMessage directly (not viewOnceMessage wrapper)
- Uses SINGLE_SELECT type (standard list)
2. **messages-send.ts**: Inject correct biz node for listMessage
- For buttonType === 'list': <biz><list type="product_list" v="2">
- Matches pastorini's working structure
- Removed checks that skipped biz node for listMessage
Why this works:
- Legacy listMessage + product_list biz node = accepted by WhatsApp
- Modern interactiveMessage + native_flow biz node = error 479
- This matches the pastorini implementation that works on Web/iOS/Android
https://claude.ai/code/session_01Vgu4xrsj8aUVCHWb4pmQPF
- Fix ProductCarouselMessageOptions import indentation
- Fix productList comment indentation to align with else-if chain
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace catalogId with businessOwnerJid (required for catalog reference)
- Fix cards structure to use proper IInteractiveMessage[] format
- Each card now uses collectionMessage with bizJid and id
- Fix body reading from productCarousel.body (was reading from message.body)
- Remove 'as any' type casting by using correct proto types
- Update examples in types and function documentation
Addresses:
- Schema mismatch in carousel cards
- Body text being silently ignored when nested in productCarousel
- Improper type casting masking validation errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes based on code review:
1. Fix sections vs productSections mismatch
- Changed `productMsg.productList.sections` to `productMsg.productList.productSections`
- Ensures consistency with ProductListMessageOptions type
2. Add section title validation
- Each section must have a non-empty title string
3. Add productId validation for each product
- Each product in a section must have a non-empty productId string
4. Add headerImage.productId validation
- When headerImage is provided, productId must be a non-empty string
5. Remove fallback values (|| '')
- Removed fallbacks for title and description
- Let generateProductListMessage handle validation consistently
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add generateProductListMessage function for sending multiple products
from the WhatsApp Business catalog in a single message.
Features:
- ProductListMessageOptions type with full validation
- Support for product sections (categories)
- Optional header image from catalog
- Integration with sendMessage via 'productList' property
- Maximum 30 products limit per WhatsApp specs
Usage:
```typescript
const msg = generateProductListMessage({
title: 'Our Best Sellers',
description: 'Check out our products!',
buttonText: 'View Products',
businessOwnerJid: '5511999999999@s.whatsapp.net',
productSections: [
{ title: 'Electronics', products: [{ productId: 'prod_001' }] }
]
})
await sock.sendMessage(jid, msg)
```
Note: Requires WhatsApp Business account with catalog configured.
Does NOT require Meta Business Manager integration.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes all 9 issues identified in PR #49 review:
## 1. Input Validation (formatNativeFlowButton)
- Added validateNonEmptyString helper function
- Validates required fields: text, url, copyText, id, phoneNumber
- Throws Boom error with descriptive message for empty/whitespace values
## 2-3. Async Media Processing (generateButtonMessage)
- Function is now async, returns Promise<WAMessageContent>
- Accepts optional MessageContentGenerationOptions parameter
- Calls prepareWAMessageMedia() for headerImage/headerVideo
- Throws error if media provided without mediaOptions
## 4-7. Async Media Processing (generateCarouselMessage)
- Function is now async, returns Promise<WAMessageContent>
- Uses Promise.all to process all card media in parallel
- Properly converts WAMediaUpload to IImageMessage/IVideoMessage
## 5. Mutual Exclusivity Validation
- generateButtonMessage: Throws if both headerImage AND headerVideo provided
- generateCarouselMessage: Throws if card has both image AND video
## 6. Empty Button Array Validation
- Each carousel card must have at least one button
- Throws descriptive error with card index
## 8. Updated Async Calls
- generateWAMessageContent now awaits generateButtonMessage
- generateWAMessageContent now awaits generateCarouselMessage
- Both pass MessageContentGenerationOptions for media processing
## 9. Type Support
- Functions accept MessageContentGenerationOptions as optional param
- Enables access to upload, mediaCache, logger options
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extends the Native Flow implementation with additional features:
## New Button Type
- `CallButton` - `cta_call` type for initiating phone calls
```typescript
{ type: 'call', text: 'Call Us', phoneNumber: '+5511999999999' }
```
## New List Message Support
- `generateListMessage()` - Creates interactive list with single_select
- `nativeList` type for sendMessage integration
```typescript
await sock.sendMessage(jid, {
text: 'Choose:',
nativeList: {
buttonText: 'View Options',
sections: [{ title: 'Section', rows: [...] }]
}
})
```
## Legacy Functions (for backward compatibility)
- `generateButtonMessageLegacy()` - Old buttonsMessage format
- `generateListMessageLegacy()` - Old listMessage format
⚠️ These are deprecated and may not work on all devices
## Other Improvements
- Added `merchantUrl` support for URL buttons
- Added `messageVersion` parameter (default: 2)
- Added `messageParamsJson` to nativeFlowMessage
- Created `NativeListSection` type to avoid conflict with legacy `ListSection`
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix TS2345 errors where array element access (medias[i]) was inferred as
`AlbumMediaItem | undefined` instead of `AlbumMediaItem`.
Changes:
- Add non-null assertion (!) after array access in for loops
- Add explicit cast to AnyMessageContent for hasNonNullishProperty calls
The non-null assertion is safe here because we iterate with `i < medias.length`,
guaranteeing the index is valid.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements WhatsApp album messages (grouped media) with the following features:
- Send 2-10 images/videos grouped as a single album message
- Adaptive delay between sends based on media type (videos get 2x delay)
- Intelligent retry with exponential backoff for failed items
- parentMessageKey reference to album root (as suggested by maintainer)
- Complete result structure with success/failure tracking per item
- Validation for min (2) and max (10) media items
Types added:
- AlbumMediaItem: Single image/video with caption, mentions, dimensions
- AlbumMessageOptions: Configuration for delay, retry, continueOnFailure
- AlbumMediaResult: Per-item result with latency and retry attempts
- AlbumSendResult: Complete result with albumKey and statistics
Based on PR #2058 from WhiskeySockets/Baileys with improvements.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Critical bug fix: Interactive message blocks were never being executed because
they were placed AFTER the normal text message processing block. Messages with
text+buttons were processed as plain text, ignoring the interactive features.
Changes:
- Move all interactive message processing (buttons, lists, templates, carousel)
to BEFORE the normal text processing block
- Remove duplicate interactive message blocks that were unreachable
- Ensure correct execution order: check for interactive features first, then
fallback to normal text processing
This fixes the runtime error where interactive message functions were not
being called properly when sending messages with buttons/lists.
Structure now:
1. Check text + buttons → buttonsMessage
2. Check text + templateButtons → templateMessage
3. Check sections → listMessage
4. Check carousel → interactiveMessage
5. Check text (normal) → extendedTextMessage
6. Other message types...
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixes type incompatibility error when processing buttons with media:
- Extract only media properties before passing to prepareWAMessageMedia
- Remove problematic interactiveMessage type from AnyRegularMessageContent
- Move Carouselable to text message type as Partial
This resolves the compilation error:
error TS2345: Argument of type '...' is not assignable to parameter
of type 'AnyMediaMessageContent'
Changes:
- src/Utils/messages.ts: Extract media content explicitly for type safety
- src/Types/Message.ts: Simplify type definitions, add Carouselable to text messages
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
⚠️ EXPERIMENTAL FEATURE - Use only for testing with disposable accounts
Implements full support for WhatsApp interactive messages including:
- Simple text buttons (up to 3 buttons)
- Buttons with images/videos
- List messages (up to 10 items in sections)
- Template buttons (quick reply, URL, call actions)
- Carousel messages (up to 10 scrollable cards)
Features:
- Feature flag 'enableInteractiveMessages' (default: true for dev/testing)
- Prometheus metrics for tracking sends, successes, failures, and latency
- Comprehensive TypeScript types for all interactive message formats
- Extensive logging with warnings about potential account bans
- Automatic 'biz' node injection when feature is enabled
CRITICAL WARNINGS:
- These features may NOT work on non-business WhatsApp accounts
- Can cause temporary or permanent account BANS
- WhatsApp actively blocks this functionality since April 2022
- Messages may be rejected or fail silently
- Use ONLY in dev environment with test accounts
Architecture:
- Added ButtonInfo, Templatable, Listable, Carouselable types to Message.ts
- Extended AnyMediaMessageContent and AnyRegularMessageContent
- Implemented message generation in messages.ts
- Added getButtonType() and getButtonArgs() helpers in messages-send.ts
- Injected 'biz' node in stanza construction with metrics tracking
- Added 4 new Prometheus metrics: interactiveMessagesSent, Success, Failures, Latency
Documentation:
- Complete usage guide in INTERACTIVE_MESSAGES.md
- Examples for all interactive message types
- Metrics monitoring queries
- Troubleshooting guide
- Migration path to WhatsApp Business API
Related issues:
- https://github.com/WhiskeySockets/Baileys/issues/56
- https://github.com/WhiskeySockets/Baileys/issues/25
- https://github.com/WhiskeySockets/Baileys/pull/2291
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* refactor: reorganize browser utility functions and improve buffer handling
* fix: harden protobuf deserialization and clean up code
* refactor: simplify data handling in GroupCipher and SenderKey classes
* fix: Ensure consistent Buffer hydration and remove redundant code
* refactor: update decodeAndHydrate calls to use proto types for improved type safety
* fix: handle invalid signatureKeyPublic types in sender-key-state
- added extra check to ensure signatureKeyPublic is either a base64 string or a Buffer
- fallback to empty buffer when unexpected object type is received
- prevents ERR_INVALID_ARG_TYPE error in Buffer.from
* adjusted based on @jlucaso1 recommmendation
* fix: handle chain key objects for skmsg group message decryption
previously, some sender chain keys were stored or retrieved as plain objects
(e.g. { '0': 85, '1': 100, ... }) instead of Buffers. this caused
"ERR_INVALID_ARG_TYPE" during initial decryption of skmsg group messages.
this fixes any chain key object is converted to a proper Buffer
before being passed to SenderChainKey.
* fix: add more robust checks and fallbacks
* feat: async cache
feat: async caching
* fix: linting issues
* fix: mget logic
---------
Co-authored-by: αѕтяσχ11 <devastro0010@gmail.com>
* chore: remove comments and veirfy from generated proto files (improve size)
* refactor: replace fromObject with create for proto message instantiation and flag no beautiful
* chore: lint issues
* feat: implement basic newsletter functionality with socket integration and event handling
* feat: enhance media handling for newsletters with raw media upload support
* feat: working updatePicture, removePicure, adminCount, mute, Unmute
* fix: fetchMessages
* chore: cleanup
* fix: update newsletter metadata path and query ID for consistency. newsletterMetadata works now
* chore: enhance newsletter metadata parsing and error handling
* fix: correct DELETE QueryId value in Newsletter.ts
* chore: split mex stuffs to own file
* chore: remove as any
* feat: interface "ILogger" created
feat: interface "ILogger" used instead of pino logger
feat: "PinoLoggerAdapter" created to implement "ILogger" interface
* feat: PinoLoggerAdapter removed
feat: ILogger mapping the features we're using from pino
* fix: sort imports
---------
Co-authored-by: Mateus Franchini de Freitas <contato.mateusfr@outlook.com>
Co-authored-by: Mateus Franchini de Freitas <mfranchini@domtec.com.br>
Co-authored-by: Rajeh Taher <rajeh@reforward.dev>
* feat: add Id support for desktop
This commit adjusts the ID length check for desktop, fixing the issue where some desktop IDs were incorrectly classified as "unknown."
Baileys stopped identifying if a message was from WA Desktop (Based on my observations last Year).
This adjustment addresses this issue.
* redundancy removed
* fix: linting