Skip to content
MessageBuilder
Documentation menu
Carousel

Carousel

Builder for carouselMessage: horizontal cards that require an image or video on every card.

Builders
v4.8/Baileys runtime
On this page

Builder for interactiveMessage.carouselMessage. Every card requires an image or video in its header and can carry its own native flow buttons.

  • Each card has its own header, body, footer, and nativeFlowMessage.
  • Header media is mandatory: an image or a video.
  • A good fit for catalogs, recommendations, and visual choices.
carouselMessage

Card structure

The library does not provide field-level helpers for cards. Build an object that follows theinteractiveMessage.carouselMessage.cards[] schema, then pass it to addCard().

FieldRequiredDescription
header.hasMediaAttachmentYesMust be true. Without it, addCard() throws an error.
header.imageMessage / videoMessageYes*Uploaded media or a Baileys media object.
body.textNoMain card text.
footer.textNoFooter text, usually a price or label.
nativeFlowMessage.buttonsNoNative flow buttons for this card.
carousel.js
javascript
import { Carousel, Toolkit } from './lib/MessageBuilder.js';

const imageUrl = await Toolkit.toUrl(sock, imageBuffer, 'image');

const card = {
  header: {
    hasMediaAttachment: true,
    imageMessage: { url: imageUrl },
  },
  body: { text: 'Arabica coffee 250g' },
  footer: { text: '$12' },
  nativeFlowMessage: {
    buttons: [
      {
        name: 'quick_reply',
        buttonParamsJson: JSON.stringify({
          display_text: 'Order',
          id: 'arabica-coffee',
        }),
      },
    ],
  },
};

await new Carousel(sock)
  .setBody('Featured products')
  .setFooter('Prices may change')
  .addCard(card)
  .send(jid);

Methods

loadFrom

chainable
.loadFrom(msg)

Rebuilds the state from an existing interactiveMessage.carouselMessage.

Parameter

ParameterTypeDefaultDescription
msgrequiredWAMessage—A message containing carouselMessage.
Returnthis

addCard

chainable
.addCard(card)

Adds one card or an array of cards. Every card must have header.hasMediaAttachment = true.

Parameter

ParameterTypeDefaultDescription
cardrequiredobject | Array<object>—A card with header, body, footer, and nativeFlowMessage following the Baileys schema.
Returnthis
  • Throws Error("Card [index] must include an image or video in header") when header media is missing.
example
const card = {
  header: {
    hasMediaAttachment: true,
    imageMessage: { url: 'https://example.com/product.jpg' },
  },
  body: { text: 'Arabica coffee 250g' },
  footer: { text: '$12' },
  nativeFlowMessage: {
    buttons: [
      {
        name: 'quick_reply',
        buttonParamsJson: JSON.stringify({ display_text: 'Order', id: 'arabica-coffee' }),
      },
    ],
  },
};

await new Carousel(sock)
  .setBody('Featured products')
  .addCard(card)
  .send(jid);

build

.build(jid, options)

Assembles the full carousel message. Unlike the other builders, this method is not async even though it returns the result of generateWAMessageFromContent.

Parameter

ParameterTypeDefaultDescription
jidrequiredstring—Destination JID.
options.messageIdstring—Custom message ID.
ReturnWAMessage

send

async
.send(jid, options)

Builds and sends through relayMessage with the standard native flow node.

Parameter

ParameterTypeDefaultDescription
jidrequiredstring—Destination JID.
options.messageIdstring—Custom message ID.
options.additionalNodesArray[]Additional XMPP nodes.
ReturnPromise<WAMessage>

Notes

Media is not optional

A carousel without media is rejected before it is sent. If you need text-only cards, use AIRich or a Button list instead.

Media must be uploaded

ImageMessage.url should come from prepareWAMessageMedia or Toolkit.toUrl so WhatsApp servers can access it.