Node concept
Every addX() call on AIRich appends one or more internal nodes shaped like{ id, section, submessage }. These nodes become sections for modern clients and submessages for the fallback payload.
{ id: 'greeting', section: {...}, submessage: {...} },
{ id: 'chart', section: {...}, submessage: {...} }
]
addSection() and addSubmessage() accept raw structures when you want to build a payload yourself, for example with AIRich.newLayout().
const rich = new AIRich(sock)
.addText('Hello', { id: 'greeting' })
.addText('World', { id: 'world' })
.addTip('A small note', { id: 'tip' });
rich.getIds(); // ['greeting', 'world', 'tip']
rich.hasId('world'); // true
rich.peek('world'); // { id, section, submessage }
rich.addText('New', { insertAt: ['greeting', 1] });
rich.delete('tip');Targets and offsets
replace and insertAt accept two forms: a direct ID, or an[id, offset] tuple.
| Value | Meaning |
|---|---|
| 'node-a' | The node-a target. For insertAt: insert after it. |
| ['node-a', 0] | At the node-a position. |
| ['node-a', 1] | One position after node-a. |
| ['node-a', -1] | One position before node-a. |
replace and insertAt are mutually exclusive
A single call may use only one of them. When both are provided, the library throws ContentValidationError.
Methods
addSection
chainable.addSection(section, options)Adds a raw section without a submessage, for view_model structures you build yourself.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
sectionrequired | object | Array<object> | — | Raw section. |
options | object | — | id, replace, insertAt. |
thisaddSubmessage
chainable.addSubmessage(submessage, options)Adds a raw submessage without a section, usually for fallback-only content.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
submessagerequired | object | Array<object> | — | Raw submessage. |
options | object | — | id, replace, insertAt. |
this- Throws ContentValidationError when empty.
delete
chainable.delete(target)Deletes a node by id, with an optional relative offset.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
targetrequired | string | [string, number] | — | Node ID or [id, offset]. |
thishasId
.hasId(id)Checks whether an id is already registered.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
idrequired | string | — | ID to check. |
booleangetIds
.getIds()Returns every registered node id in insertion order.
Array<string>peek
.peek(id)Inspects a node by id without removing it.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
idrequired | string | — | Node ID. |
{ id, section, submessage } | nullassignId
chainable.assignId(index, id)Assigns an id to an existing node at the given index.
Parameter
| Parameter | Type | Default | Description |
|---|---|---|---|
indexrequired | number | — | Node position. |
idrequired | string | — | New ID. |
this- Throws InvalidTargetError when the index is out of range, or AIRichError ALREADY_HAS_ID.
sections
get sectionsGetter containing every active section, excluding null values.
Array<object>items
get itemsGetter that flattens every section into a list of individual primitives.
Array<object>Streaming example
A common pattern for progressive answers: send a placeholder with an ID, replace its content, and callsendEdit().
const rich = new AIRich(sock, { dynamic: false })
.addText('Preparing an answer…', { id: 'answer' })
.addMetadata('Please wait', { id: 'status' });
const first = await rich.send(jid);
// Next stage
rich.addText('The full answer is ready.', { replace: 'answer' });
rich.addText('Done', { replace: 'status' });
await rich.sendEdit(jid, first.key.id);IDs must be unique
Use hasId() before assigning an ID, or handle DuplicateIdError. Nodes produced by addImage() with an array cannot receive a single ID.