feat(experimental): add interactive messages support (buttons, lists, templates, carousel)

⚠️ 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>
This commit is contained in:
Renato Alcara
2026-01-23 00:51:33 -03:00
parent fe2563d509
commit 90db2512d9
7 changed files with 837 additions and 4 deletions
+79 -2
View File
@@ -195,7 +195,7 @@ export type AnyMediaMessageContent = (
fileName?: string
caption?: string
} & Contextable)
) & { mimetype?: string } & Editable
) & { mimetype?: string } & Editable & Partial<Buttonable> & Partial<Templatable>
export type ButtonReplyInfo = {
displayText: string
@@ -215,14 +215,91 @@ export type WASendableProduct = Omit<proto.Message.ProductMessage.IProductSnapsh
productImage: WAMediaUpload
}
// ⚠️ EXPERIMENTAL: Interactive message types
// These features may not work and can cause account bans
// Use only for testing with disposable accounts
export type ButtonInfo = {
buttonId: string
buttonText: { displayText: string }
type?: proto.Message.ButtonsMessage.Button.Type
}
export type Buttonable = {
buttons: ButtonInfo[]
headerType?: proto.Message.ButtonsMessage.HeaderType
footerText?: string
}
export type TemplateButton =
| { index: number; quickReplyButton: { displayText: string; id: string } }
| { index: number; urlButton: { displayText: string; url: string } }
| { index: number; callButton: { displayText: string; phoneNumber: string } }
export type Templatable = {
templateButtons: TemplateButton[]
footer?: string
}
export type ListSection = {
title: string
rows: Array<{
rowId: string
title: string
description?: string
}>
}
export type Listable = {
sections: ListSection[]
title?: string
buttonText?: string
}
export type CarouselCard = {
header: {
title: string
imageMessage?: {
url: string
mimetype: string
}
videoMessage?: {
url: string
mimetype: string
}
hasMediaAttachment: boolean
}
body: { text: string }
footer?: { text: string }
nativeFlowMessage?: {
buttons: Array<{
name: string
buttonParamsJson: string
}>
}
}
export type Carouselable = {
carousel: {
cards: CarouselCard[]
messageVersion?: number
}
}
export type AnyRegularMessageContent = (
| ({
text: string
linkPreview?: WAUrlInfo | null
} & Mentionable &
Contextable &
Editable)
Editable &
Partial<Buttonable> &
Partial<Templatable> &
Partial<Listable>)
| AnyMediaMessageContent
| ({
interactiveMessage: proto.Message.IInteractiveMessage
} & Partial<Carouselable>)
| { event: EventMessageOptions }
| ({
poll: PollMessageOptions
+22
View File
@@ -133,6 +133,28 @@ export type SocketConfig = {
*/
enableCTWARecovery: boolean
/**
* ⚠️ EXPERIMENTAL: Enable interactive messages (buttons, lists, templates, carousel).
*
* **WARNING**: These features MAY NOT WORK and can cause ACCOUNT BANS.
*
* WhatsApp actively blocks non-business accounts from sending interactive messages.
* Using this feature can result in:
* - Messages not being delivered
* - Temporary account restrictions
* - Permanent account bans
*
* Use ONLY for:
* - Testing in DEV environment
* - DISPOSABLE test accounts
* - Experimental research
*
* @default true (for dev/testing)
* @see https://github.com/WhiskeySockets/Baileys/issues/56
* @see https://github.com/WhiskeySockets/Baileys/issues/25
*/
enableInteractiveMessages: boolean
/**
* Returns if a jid should be ignored,
* no event for that jid will be triggered.