Builder for interactiveMessage with native flow buttons: quick reply, CTA URL, copy code, call, reminder, address, location, and nested lists. This is the primary choice for modern interactive menus.
quick_replycta_urlcta_copycta_callsingle_selectaddress_messagesend_locationAll native flow types
Each button below is produced by a different addX() method.
Try tapping one
Basic usage
Chain setters and adders, then call send(). Every method returns the same instance.
import { Button } from './lib/MessageBuilder.js';
const button = new Button(sock)
.setBody('Pick an option below.')
.setFooter('MessageBuilder v4.8')
.addReply('Hello', 'hello')
.addUrl('Open website', 'https://example.com', true)
.addCopy('Copy code', 'MB-4.8');
await button.send(jid);Methods
loadFrom
chainable.loadFrom(msg)Rebuilds the builder state from an existing interactiveMessage, such as an incoming message you want to edit or resend.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
msgrequired | WAMessage | — | A message containing interactiveMessage. |
this- Throws an Error when interactiveMessage is missing.
setImage
chainable.setImage(path, options)Sets an image on the message header.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
pathrequired | string | Buffer | — | Image URL or raw buffer. |
options | object | {} | Merged into the media object, for example caption or jpegThumbnail. |
thisbutton.setImage('https://example.com/banner.jpg', { caption: 'Today’s menu' });setDocument
chainable.setDocument(path, options)Sets a document on the message header.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
pathrequired | string | Buffer | — | Document URL or buffer. |
options | object | {} | Additional media options. |
thissetMedia
chainable.setMedia(obj)Fully overrides the header media object. Useful for media types without a dedicated helper.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
objrequired | object | — | A Baileys media object such as videoMessage or productMessage. |
this- Must be a plain object; arrays or null throw a TypeError.
clearButtons
chainable.clearButtons()Removes every button already added without touching the body, footer, or media.
thissetParams
chainable.setParams(obj)Fully overrides messageParamsJson on nativeFlowMessage. Normally populated by addSelection and similar methods.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
objrequired | object | — | Native flow parameter object. |
thisaddButton
chainable.addButton(name, params)Generic method for adding any native flow button manually. Every addX helper is built on top of it.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
namerequired | string | — | Native flow name, such as 'quick_reply' or 'cta_url'. |
paramsrequired | object | string | — | Parameter object; automatically JSON.stringify’d when an object is passed. |
thisbutton.addButton('quick_reply', { display_text: 'Hello', id: 'hello' });addSelection
chainable.addSelection(title, options)Adds a list button (single_select) and makes it the active selection for the following makeSection and makeRow calls.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
titlerequired | string | — | List button label. |
options | object | {} | Merged into buttonParamsJson, for example initial sections. |
thisbutton
.addSelection('View menu')
.makeSection('Food')
.makeRow('Fried rice', '$8', 'Spice level adjustable', 'fried-rice');makeSection
chainable.makeSection(title, highlight_label)Adds a new section to the active list and makes it the target for the next makeRow calls.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
title | string | '' | Section title. |
highlight_label | string | '' | Small label shown next to the section title. |
this- Throws an Error when no selection is active.
makeRow
chainable.makeRow(header, title, description, id)Adds one row to the active list section.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
header | string | '' | Row header text. |
title | string | '' | Primary row title. |
description | string | '' | Secondary description. |
id | string | '' | ID returned when the row is selected. |
this- Throws an Error when no selection and section are active.
addReply
chainable.addReply(display_text, id, options)Adds a quick reply button.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
display_textrequired | string | — | Text shown on the button. |
idrequired | string | — | ID returned when the button is pressed. |
options | object | {} | Additional fields for buttonParamsJson. |
thisaddCall
chainable.addCall(display_text, id, options)Adds a call button (cta_call).
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
display_textrequired | string | — | Button text. |
idrequired | string | — | Action ID. |
options | object | {} | Additional fields. |
thisaddReminder
chainable.addReminder(display_text, id, options)Adds a reminder button (cta_reminder).
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
display_textrequired | string | — | Button text. |
idrequired | string | — | Action ID. |
options | object | {} | Additional fields. |
thisaddCancelReminder
chainable.addCancelReminder(display_text, id, options)Adds a cancel-reminder button (cta_cancel_reminder).
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
display_textrequired | string | — | Button text. |
idrequired | string | — | Action ID. |
options | object | {} | Additional fields. |
thisaddAddress
chainable.addAddress(display_text, id, options)Adds an address request button (address_message).
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
display_textrequired | string | — | Button text. |
idrequired | string | — | Action ID. |
options | object | {} | Additional fields. |
thisaddLocation
chainable.addLocation(options)Adds a send-location button (send_location).
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
options | object | {} | Location button parameters. |
thisaddUrl
chainable.addUrl(display_text, url, webview_interaction, options)Adds a link button (cta_url).
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
display_textrequired | string | — | Button text. |
urlrequired | string | — | Link destination. |
webview_interaction | boolean | false | Open in an in-app webview when true. |
options | object | {} | Additional fields, also merged into the button object. |
thisbutton.addUrl('Open documentation', 'https://example.com/docs', true);addCopy
chainable.addCopy(display_text, copy_code, options)Adds a copy-code button (cta_copy).
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
display_textrequired | string | — | Button text. |
copy_coderequired | string | — | Text copied to the clipboard. |
options | object | {} | Additional fields. |
thistoCard
async.toCard()Assembles the card object (body, footer, header with media, nativeFlowMessage) without wrapping it in a full WhatsApp message.
Promise<object>build
async.build(jid, options)Assembles a complete WAMessage from the current builder state. The message is not sent.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
jidrequired | string | — | Destination JID. |
options.messageId | string | — | Custom message ID. |
options | object | — | Other options passed to generateWAMessageFromContent. |
Promise<WAMessage>send
async.send(jid, options)Builds and sends through client.relayMessage(), adding the biz > interactive > native_flow XMPP node required by WhatsApp.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
jidrequired | string | — | Destination JID. |
options.messageId | string | — | Custom message ID. |
options.additionalNodes | Array | [] | Additional XMPP nodes. |
options | object | — | Other options passed to relayMessage. |
Promise<WAMessage>const msg = await new Button(sock)
.setBody('Pick an option below.')
.setFooter('MessageBuilder v4.8')
.addReply('Hello', 'hello')
.addUrl('Open website', 'https://example.com')
.send(jid);
console.log(msg.key.id);paramsList
Button.paramsList is a static object, not a method. It documents the advanced parameter schemas for a few button types.
| Type | Fields |
|---|---|
| limited_time_offer | text: stringurl: stringcopy_code: stringexpiration_time: number |
| bottom_sheet | in_thread_buttons_limit: numberdivider_indices: number[]list_title: stringbutton_title: string |
| tap_target_configuration | title: stringdescription: stringcanonical_url: stringdomain: stringbuttonIndex: number |
Notes
The native flow node is required
Without the biz > interactive > native_flow node, a message may send successfully but WhatsApp will not render the buttons. send() adds this node automatically.
Practical limits
WhatsApp limits how many buttons render cleanly. When you have many options, use single_select (a list) instead of stacking quick replies.
See the animation
Open the playground to edit button text, add list sections, and copy the generated code.