Builder for richResponseMessage: text, code, tables, images, video, products, posts, sources, widgets, footer actions, and follow-up suggestions. Every block can be assigned an ID and later replaced, inserted, or deleted.
15
primitives
2
payloads
∞
layouts
Here is a short summary with a code example. Rich responses support text, code, tables, and cards in a single message.
const button = new Button(sock)
.setBody("Pick an option")
.addReply("Hello", "hello");
await button.send(jid);| Builder | Purpose |
|---|---|
| Button | Native flow |
| Carousel | Sliding cards |
| AIRich | Rich response |
ⓘ Give blocks an id so you can update them later with sendEdit().
Generated by a MessageBuilder AIRich response
Usage
Every addX() call appends one or more nodes. Give an id to blocks that may change, then use replace or insertAt to mutate them later.
import { AIRich, Enums } from './lib/MessageBuilder.js';
const rich = new AIRich(sock, {
dynamic: true,
unsupportedTypeAlert: true,
});
rich
.setTitle('Assistant')
.addText('Here is a summary of the article.')
.addCode('javascript', 'const total = items.length;')
.addTable([
['Metric', 'Value'],
['Orders', '128'],
['Revenue', '$4.2k'],
])
.addImage('https://example.com/chart.png', {
width: 640,
height: 360,
id: 'chart',
})
.addSuggest(['Explain in more detail', 'Make it shorter']);
await rich.send(jid);Primitives
Fifteen content methods are available. All of them are chainable unless noted otherwise.
| Method | Purpose | Typename |
|---|---|---|
| addText | Markdown text + inline entities | GenAIMarkdownTextUXPrimitive |
| addFOAText | Literal text | FOATextPrimitive |
| addCode | Code block with highlighting | GenAICodeUXPrimitive |
| addTable | Table with a header row | GenATableUXPrimitive |
| addSource | Source list | GenAISearchResultPrimitive |
| addReels | Horizontal reels cards | GenAIReelPrimitive |
| addImage | One or more images | GenAIImaginePrimitive |
| addVideo | Video + automatic metadata | GenAIImaginePrimitive |
| addProduct | Product cards | GenAIProductItemCardPrimitive |
| addPost | Social media post cards | GenAIPostPrimitive |
| addMetadata | Small metadata text | GenAIMetadataTextPrimitive |
| addTip | Tip with a ⓘ prefix | GenAIMetadataTextPrimitive |
| addWidget | Third-party widget | GenAI3PExtWidgetPrimitive |
| addFooterAction | Footer action buttons | GenAIFooterActionPrimitive |
| addSuggest | Follow-up suggestion pills | GenAIFollowUpSuggestionPillPrimitive |
Methods
loadFrom
chainable.loadFrom(msg)Rebuilds the full state from an existing richResponseMessage, including sections, submessages, and extraPayload.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
msgrequired | WAMessage | — | A rich response message. |
this- Supports three structures: botForwardedMessage.message.richResponseMessage, botForwardedMessage.richResponseMessage, and a direct richResponseMessage.
setResponseId
chainable.setResponseId(id)Sets responseId manually.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
idrequired | string | — | Response ID. |
thisrefreshResponseId
chainable.refreshResponseId()Regenerates responseId using crypto.randomUUID().
thissetBotResponseId
chainable.setBotResponseId(id)Sets botResponseId manually.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
idrequired | string | — | Bot response ID. |
thisrefreshBotResponseId
chainable.refreshBotResponseId()Regenerates botResponseId.
thisaddText
chainable.addText(text, options)Adds a markdown text block (GenAIMarkdownTextUXPrimitive) with hyperlink, citation, and LaTeX image support.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
textrequired | string | — | Markdown text. |
options.hyperlink | boolean | true | Parse [label](url). |
options.citation | boolean | true | Parse [](url). |
options.latex | boolean | true | Parse LaTeX images. |
options.id | string | — | Unique node ID. |
options.replace | string | [string, number] | — | Replace a target node. |
options.insertAt | string | [string, number] | — | Insert after a target node. |
thisrich.addText('Hello! This is a **rich response** example.', { id: 'greeting' });addFOAText
chainable.addFOAText(text, options)FOA text variant (FOATextPrimitive) without inline entity parsing.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
textrequired | string | — | Literal text. |
options | object | — | id, replace, insertAt. |
thisaddCode
chainable.addCode(language, code, options)Adds a code block using AIRich.tokenizer() for syntax highlighting.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
languagerequired | string | — | javascript, typescript, python, java, golang, c, cpp, php, rust, html, bash, css, markdown. |
coderequired | string | — | Source code. |
options | object | — | id, replace, insertAt. |
thisrich.addCode('javascript', 'const x = 42;\nconsole.log(x);', { id: 'code-1' });addTable
chainable.addTable(table, options)Adds a table. The first row is the header; rows of different lengths are padded automatically.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
tablerequired | Array<Array<string>> | — | Table rows; the first row is the header. |
options.hyperlink | boolean | true | Parse hyperlinks inside cells. |
options.citation | boolean | true | Parse citations inside cells. |
options.latex | boolean | true | Parse LaTeX images inside cells. |
options | object | — | id, replace, insertAt. |
thisaddSource
chainable.addSource(sources, options)Adds a list of sources or references (GenAISearchResultPrimitive).
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
sourcesrequired | Array<string> | Array<Array<string>> | Array<object> | — | An array of strings is treated as one source [icon, url, title, subtitle]; an array of arrays is multiple sources; objects use { icon|favicon, url, title, subtitle }. |
options | object | — | id, replace, insertAt. |
thisaddReels
chainable.addReels(reelsItems, options)Adds horizontally scrolling Reels cards.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
reelsItemsrequired | object | Array<object> | — | Fields: videoUrl/url, profileIconUrl/profile, thumbnailUrl/thumbnail, username/title, likes_count, shares_count, view_count, reel_source, is_verified. |
options | object | — | id, replace, insertAt. |
thisaddImage
chainable.addImage(imageUrl, options)Adds one or more images (imagine_type IMAGINE). An array produces multiple sliding card sections.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
imageUrlrequired | string | Buffer | Array | — | URL, buffer, base64, or array. |
options.width | number | — | Display width. |
options.height | number | — | Display height. |
options.status | Enums.IMAGINE_STATUS | 3 (READY) | Image render status. |
options.update_text | string | — | Status text, usually for GENERATING. |
options.resolveUrl | boolean | false | Force reupload of the URL to WhatsApp servers. |
options | object | — | id, replace, insertAt. |
this- Do not pass an id when the array contains more than one image.
addVideo
chainable.addVideo(videoUrl, options)Adds a video (imagine_type ANIMATE). With autoFill enabled, size, duration, and thumbnail are computed automatically.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
videoUrlrequired | string | Buffer | object | Array | — | URL, buffer, array, or object { url, mime_type, file_length, duration, thumbnail }. |
options.autoFill | boolean | true | Compute file_length, duration, and thumbnail from the buffer. |
options.status | Enums.IMAGINE_STATUS | 3 (READY) | Video render status. |
options.estimatedTime | number | — | Estimated completion time in milliseconds for GENERATING. |
options | object | — | id, replace, insertAt. |
thisaddProduct
chainable.addProduct(data, options)Adds product cards. A single object uses the Single layout; an array uses HScroll.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
datarequired | object | Array<object> | — | Fields: title, brand, price, sale_price, product_url/url, image_url/image, icon_url/icon. |
options | object | — | id, replace, insertAt. |
thisaddPost
chainable.addPost(data, options)Adds social media post cards using the HScroll layout.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
datarequired | object | Array<object> | — | Fields: title, subtitle, username, profile_picture_url, is_verified, thumbnail_url, post_caption, likes_count, comments_count, shares_count, post_url, post_deeplink, source_app, footer_label, footer_icon, orientation, post_type. |
options | object | — | id, replace, insertAt. |
thisaddMetadata
chainable.addMetadata(text, options)Adds small metadata text (GenAIMetadataTextPrimitive).
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
textrequired | string | — | Metadata text. |
options | object | — | id, replace, insertAt. |
thisaddTip
chainable.addTip(text, options)Like addMetadata, but automatically prefixed with the ⓘ symbol.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
textrequired | string | — | Tip text. |
options | object | — | id, replace, insertAt. |
thisaddWidget
chainable.addWidget(data, options)Adds a third-party extension widget (GenAI3PExtWidgetPrimitive).
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
datarequired | object | Array<object> | — | Fields: title, header, sections, actions [{ label, state, kind, tool_call_id, toast }], body. |
options.layout | string | HScroll / Single | Card layout. |
options | object | — | id, replace, insertAt, plus extra fields for newLayout(). |
thisaddSuggest
chainable.addSuggest(suggestion, options)Adds follow-up prompt suggestion pills.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
suggestionrequired | string | Array<string> | — | One or more suggestions. |
options.scroll | boolean | true | Arrays use HScroll when true and ActionRow when false. |
options.layout | string | — | Override the layout: Single, HScroll, ActionRow. |
options | object | — | id, replace, insertAt. |
thisrich.addSuggest(['Summarize this article', 'Translate it to English']);build
async.build(jid, options)Assembles the complete botForwardedMessage.message.richResponseMessage, including the base64 unifiedResponse and fallback submessages.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
jidrequired | string | — | Destination JID. |
options.forwarded | boolean | true | Mark the message as forwarded from a bot. |
options.notification | boolean | false | Include sessionTransparencyMetadata. |
options.includesUnifiedResponse | boolean | true | Include the base64 rich payload. |
options.includesSubmessages | boolean | true | Include fallback submessages. |
options.quoted | WAMessage | — | Message to quote. |
options.quotedParticipant | string | — | Override the quoted participant in groups. |
options.messageId | string | — | Custom message ID. |
Promise<WAMessage>- A footer set via setFooter is automatically appended as the final metadata section.
buildEdit
async.buildEdit(targetJid, targetId, options)Wraps an edit payload (protocolMessage type 14) to replace the content of an already delivered message.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
targetJidrequired | string | — | Target message JID. |
targetIdrequired | string | — | Target message ID. |
options.msg | object | — | A previously built message; build() is called again when omitted. |
Promise<WAMessage>sendEdit
async.sendEdit(jid, id, options)Builds and sends an edit payload. jid and id default to the last message sent.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
jid | string | — | Defaults to this._lastMessageKey.remoteJid. |
id | string | — | Defaults to this._lastMessageKey.id. |
options.msg | object | — | Message payload to use as the edit content. |
Promise<WAMessage>- Throws an Error when jid or id is unavailable.
send
async.send(jid, options)Builds and sends the rich response. When includesUnifiedResponse and bypassDownload are enabled, it automatically calls sendEdit so the base64 payload syncs on the client immediately.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
jidrequired | string | — | Destination JID. |
options.bypassDownload | boolean | true | Send a sync edit after the main message. |
options.forwarded | boolean | true | Mark as forwarded. |
options.includesUnifiedResponse | boolean | true | Include the rich payload. |
options.additionalNodes | Array | [] | Additional XMPP nodes. |
Promise<WAMessage>await new AIRich(sock)
.setTitle('Assistant')
.addText('Here is a summary of the article.')
.addCode('javascript', 'const total = items.length;')
.addSuggest(['Explain in more detail', 'Make it shorter'])
.send(jid);Static utilities
tokenizer
staticAIRich.tokenizer(code, lang)Built-in syntax highlighting tokenizer for 13 languages. Produces DEFAULT, KEYWORD, METHOD, STR, NUMBER, and COMMENT tokens.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
coderequired | string | — | Source code. |
lang | string | 'javascript' | Target language. |
{ codeBlock: object[], unified_codeBlock: object[] }toTableMetadata
staticAIRich.toTableMetadata(arr, options)Normalizes a table: pads rows, marks the header, and extracts inline entities from every cell.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
arrrequired | Array<Array<string>> | — | Table rows. |
options | object | — | hyperlink, citation, latex (all default to true). |
{ title, rows, unified_rows }generateVerificationMetadata
staticAIRich.generateVerificationMetadata()Generates verificationMetadata with a random signature and certificate chain so the payload is accepted by clients.
objectnewLayout
staticAIRich.newLayout(name, data, extra)Generic view_model helper that wraps primitives into a section.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
namerequired | string | — | Layout name, such as Single, HScroll, or ActionRow. |
datarequired | object | Array<object> | — | A primitive or list of primitives. |
extra | object | {} | Merged into the root result. |
objectNotes
Dual payload
Rich responses carry two representations: base64 sections in unifiedResponse for modern clients, and submessages as a fallback. Both can be disabled through build options when debugging.
Use IDs for updates
Assign an id to blocks that may change. When streaming, call addText with replace: "id" and then sendEdit to update content without sending a new message.
Not an official API
The richResponseMessage structure comes from reverse engineering and may change at any time. Test on your target devices before shipping to production.
Node management
For replace, insertAt, delete, peek, and assignId, see thenode management page.