Skip to content

Rich Content

The OmniBots widget supports 15 rich content element types that bots can send within messages. These elements render below or instead of plain text and provide interactive, structured experiences directly in the chat window.

Rich content elements are delivered in the rich_content array of a message. Multiple elements can be included in a single message, and they render in order.

imageGallery showing all 15 rich content element types rendered in the widget: text with Markdown, button stack, product card, horizontal carousel, inline image, video player, audio waveform, file download card, vertical list, location map, multi-field form, star rating, chip pills, info alert box, and horizontal divider
Complete gallery of all 15 rich content element types

Button Action Types

Many rich content elements use buttons. All buttons share a common set of action types:

ActionDescriptionProperties
postbackSends a payload to the bot as if the user typed itpayload: string
urlOpens a link in a new tab (or same window)url: string, target?: '_blank' | '_self'
phoneInitiates a phone callnumber: string
copyCopies text to the clipboardtext: string
ts
type ButtonAction = PostbackAction | UrlAction | PhoneAction | CopyAction;

Each button also supports a style property ('primary', 'secondary', 'outline', 'danger') and an optional Material icon via the icon property.

Element Types

1. Text

Renders formatted text. Supports Markdown when markdown: true.

ts
interface TextElement {
  type: 'text';
  text: string;
  markdown?: boolean;
}

2. Buttons

A vertical stack of action buttons with an optional header.

ts
interface ButtonsElement {
  type: 'buttons';
  text?: string;      // Optional header text above the buttons
  buttons: Button[];
}
Button PropertyTypeDescription
titlestringButton label
style'primary' | 'secondary' | 'outline' | 'danger'Visual style
iconstringMaterial icon name
actionButtonActionAction to perform on click

3. Card

A structured card with an optional image, title, subtitle, description, and action buttons.

ts
interface CardElement {
  type: 'card';
  image_url?: string;
  image_alt?: string;
  title: string;
  subtitle?: string;
  description?: string;
  buttons?: Button[];
}

Cards render with a vertical layout: image at the top, text content below, and buttons at the bottom. The image has a configurable image_alt text for accessibility.

A horizontally scrollable collection of cards. Users can swipe or use scroll to browse.

ts
interface CarouselElement {
  type: 'carousel';
  cards: CardElement[];  // Array of card objects (without the type field)
}

Each card in the carousel follows the same structure as the standalone Card element. The carousel tracks scroll interactions for analytics (carousel_scroll, carousel_card_view events).

5. Image

Displays an image with optional caption and click action.

ts
interface ImageElement {
  type: 'image';
  url: string;
  alt?: string;
  caption?: string;
  action?: ButtonAction;
}

The alt text is used for the image's alt attribute. When an action is specified, the image becomes clickable.

6. Video

Embeds a video player with playback controls.

ts
interface VideoElement {
  type: 'video';
  url: string;           // MP4 or WebM URL
  poster?: string;       // Thumbnail image URL
  title?: string;
  autoplay?: boolean;    // Default: false
  controls?: boolean;    // Default: true
  loop?: boolean;        // Default: false
  muted?: boolean;       // Default: false (required for autoplay)
  aspect_ratio?: '16:9' | '4:3' | '1:1' | '9:16';  // Default: '16:9'
}

Autoplay Requirement

Browsers require muted: true for autoplay to work. If autoplay is true and muted is false, the browser will block autoplay.

Video analytics track play, pause, completion, and progress milestones (25%, 50%, 75%).

7. Audio

Renders an audio player with playback controls, optional waveform visualization, and duration display.

ts
interface AudioElement {
  type: 'audio';
  url: string;
  title?: string;
  duration?: number;     // Duration in seconds (for display before loading)
  waveform?: number[];   // Waveform data array for visualization
}

8. File

A downloadable file attachment with type icon and size information.

ts
interface FileElement {
  type: 'file';
  url: string;
  filename: string;
  file_type?: string;    // pdf, doc, xlsx, etc.
  file_size?: number;    // Size in bytes
  icon?: string;         // Custom icon (defaults based on file_type)
}

The file element displays a type-specific icon (PDF, Word, etc.), the filename, and a human-readable file size. Clicking downloads the file.

9. List

A vertical list of items, each with an optional image, title, subtitle, and click action.

ts
interface ListElement {
  type: 'list';
  title?: string;
  items: ListItem[];
}

interface ListItem {
  title: string;
  subtitle?: string;
  image_url?: string;
  action?: ButtonAction;
}

List items are interactive when an action is specified. Each item can have a small image or icon alongside the text content.

10. Location

Embeds a Google Maps view with a marker at the specified coordinates.

ts
interface LocationElement {
  type: 'location';
  latitude: number;
  longitude: number;
  title?: string;        // Location name
  address?: string;      // Full address text
  zoom?: number;         // Map zoom level (default: 15)
  action?: ButtonAction; // Click action (default: open in maps)
}

The map displays the location name and address below the embedded map. Clicking the map opens it in Google Maps by default.

11. Form

An embedded data collection form rendered directly in the chat. More capable than the pre-chat form, supporting additional field types and validation rules.

ts
interface FormElement {
  type: 'form';
  title?: string;
  description?: string;
  fields: FormField[];
  submit_button?: {
    title: string;
    style?: 'primary' | 'secondary';
  };
  submit_action: {
    type: 'postback';
    payload: string;   // Template with {{field_name}} placeholders
  };
}

Form Field Types

TypeDescription
textSingle-line text input
emailEmail input with validation
phonePhone number input
numberNumeric input
dateDate picker
timeTime picker
datetimeDate and time picker
selectDropdown with predefined options
textareaMulti-line text input

Each field supports optional validation rules:

ts
interface FormFieldValidation {
  pattern?: string;   // Regex pattern
  min?: number;       // Min value/length
  max?: number;       // Max value/length
  message?: string;   // Custom error message
}

When the form is submitted, the payload template is filled with the field values (e.g., "order_form:{{name}}:{{email}}") and sent as a postback action.

12. Rating

A rating input that allows the user to rate on a scale. Supports multiple visual styles.

ts
interface RatingElement {
  type: 'rating';
  title?: string;
  max_rating?: number;   // Default: 5
  style?: 'stars' | 'thumbs' | 'emoji' | 'numbers';
  submit_action: {
    type: 'postback';
    payload: string;     // Template with {{rating}} placeholder
  };
}
StyleDisplay
stars1 to 5 star icons (default)
thumbsThumbs up / thumbs down
emojiEmoji scale
numbersNumeric scale

When the user selects a rating, the payload template is filled with the selected value and sent as a postback.

13. Chips

Clickable pill-shaped buttons, similar to quick replies but rendered as a rich content element. Supports multi-select.

ts
interface ChipsElement {
  type: 'chips';
  chips: ChipItem[];
  style?: 'default' | 'outline' | 'pill';
  wrap?: boolean;   // Wrap to multiple lines (default: true)
}

interface ChipItem {
  title: string;
  icon?: string;        // Material icon name
  action: ButtonAction;
}

Chips wrap to multiple lines by default. Each chip can have an optional icon and supports any button action type.

14. Divider

A horizontal separator line within a message. Used to visually separate sections of content.

ts
interface DividerElement {
  type: 'divider';
}

15. Info

An alert or information box with a colored accent based on its severity level.

ts
interface InfoElement {
  type: 'info';
  style: 'info' | 'success' | 'warning' | 'error';
  title?: string;
  text: string;
  icon?: string;
}
StyleColorUse Case
infoBlueGeneral information
successGreenConfirmation or success messages
warningYellow/amberCautions or important notices
errorRedError messages or failures

Analytics

All rich content interactions are tracked as analytics events. The widget sends rich_content_interaction events via WebSocket when users interact with elements.

EventTriggered By
button_clickClicking a button in a ButtonsElement
card_clickClicking a Card body
card_button_clickClicking a button within a Card
carousel_scrollScrolling the Carousel
carousel_card_viewA Carousel card entering the viewport
carousel_card_clickClicking a card within a Carousel
list_item_clickClicking a List item
image_clickClicking an Image
link_clickClicking a URL action
copy_clickClicking a copy action
phone_clickClicking a phone action
video_play / video_pause / video_completeVideo playback events
video_progressVideo reaching 25%, 50%, or 75%
audio_play / audio_pause / audio_completeAudio playback events
file_downloadDownloading a File element
location_click / location_directionsInteracting with a Location map
form_start / form_submitStarting and submitting a Form
rating_submitSubmitting a Rating
chip_clickClicking a Chip

Each event includes the message_id, element_type, element_id, element_index, action_type, and action_value for detailed analytics.

Multiple Elements

A single message can contain multiple rich content elements. They render in the order they appear in the rich_content array. Combine elements creatively -- for example, a Text element followed by a Carousel, followed by Chips for navigation.

OmniBots AI Bot Platform