Skip to content

The Dynamic Content Toolkit allows bot creators to populate bot elements with dynamic content pulled from an organization's owned resources and databases at runtime.

It can be installed via NPM or Yarn, and details of its usage can be found on NPM.

npm install @stackchat/dynamic-content-toolkit
yarn add @stackchat/dynamic-content-toolkit

This is useful in situations where you wish to populate a message, action sequence, navigation, postback button or Dynamic User Input Group with live data. For example, in a shopping application, a user could ask about black shoes that are on sale. Using the Dynamic Content Toolkit, you can fetch products that meet that description and send them to a user in a carousel.

Messages

MessageThread is a top level class that allows you to display a collection of messages of various types, such as text, images and carousels.

The MessageThread is defined as messages: An array of messages to display to the user

MessageThread's messages property is a container for individual message objects. You can add as many or as few messages you like. The only requirement is that there should be at least one message in a MessageThread. Below are all of the different types of messages you can use.

TextMessage

// Import required classes
import { TextMessage } from "@stackchat/dynamic-content-toolkit";

const textMessage = new TextMessage();
textMessage.text = "Hello, world!";

ImageMessage

// Import required classes
import { ImageMessage } from "@stackchat/dynamic-content-toolkit";

const imageMessage = new ImageMessage();
imageMessage.imageUrl = "https://placekitten.com/320/320";

ListMessage

// Import required classes
import {
  LinkButton,
  WebviewButton,
  PostbackButton
} from "@stackchat/dynamic-content-toolkit";

// Create a LinkButton
const linkButton = new LinkButton();
linkButton.text = "Link Button";
linkButton.uri = "https://stackchat.com";

// Create a WebviewButton
const webviewButton = new WebviewButton();
webviewButton.text = "Webview Button";
webviewButton.uri = "https://stackchat.com";

// Create a PostbackButton
const postbackButton = new PostbackButton();
postbackButton.text = "Postback Button";
postbackButton.payload = {
  /**
   * This is the name any of the exported functions from your
   * cloud functions code. The `data` object is sent to the
   * specified function when the user clicks or taps on the
   * button.
   */
  handler: "myCloudFunction",
  /**
   * An object with key-value pairs
   */
  data: {
    ...
  }
}
// Import required classes
import {
  ListMessage,
  MessageCard
} from "@stackchat/dynamic-content-toolkit";

// Create message cards
const itemOne = new MessageCard();
itemOne.imageUrl = "https://placekitten.com/320/320";
itemOne.title = "Item 1";
itemOne.description = "This is a description for item 1";
itemOne.size = MessageCardImageSize.Compact
itemOne.buttons = [ linkButton, webviewButton, postbackButton ];

// Create a ListMessage
const listMessage = new ListMessage();
listMessage.items = [ itemOne ];

CarouselMessage

// Import required classes
import {
  CarouselMessage,
  MessageCard
} from "@stackchat/dynamic-content-toolkit";

// Create message cards
const itemOne = new MessageCard();
itemOne.imageUrl = "https://placekitten.com/320/320";
itemOne.title = "Item 1";
itemOne.description = "This is a description for item 1";
itemOne.size = MessageCardImageSize.Compact;
itemOne.buttons = [ linkButton, webviewButton, postbackButton ];

// Create a CarouselMessage
const listMessage = new CarouselMessage();
listMessage.items = [ itemOne ];

MessageThread

// Import required classes
import { MessageThread } from "@stackchat/dynamic-content-toolkit";

// Create a MessageThread
const messageThread = new MessageThread();
messageThread.messages = [
  textMessage,
  imageMessage,
  listMessage,
  carouselMessage
];

While it is not currently possible to create User Input Groups via the Dynamic Content Toolkit, it is still possible to do so manually.

Action Sequences

ActionSequence is a top level class that allows you to sequentially execute a collection of ActionItems. This allows you to do things like clearing/setting slot values or triggering analytics events from your Cloud Function.

An ActionSequence is defined as actions: The collection of actions to execute.

ActionSequence's actions property is a container for individual actions. You can add as many or as few actions depending on your needs. The only requirement is that there should be at least one action in an ActionSequence. Below are all of the different types of actions you can use.

SetSlotsAction

// Import required classes
import { SetSlotsAction } from "@stackchat/dynamic-content-toolkit";

const setSlotsAction = new SetSlotsAction();
/**
 * The `slots` property is an object of slots in your bot
 * and the values you would like to set them to. In the example
 * below, `Slot1`, `Slot2` and `Slot3` are slot names as they
 * appear in your bot in Stackchat Studio. The desired values
 * for each slot goes against each of the slots.
 */
setSlotsAction.slots = {
  Slot1: "Value 1",
  Slot2: "Value 2",
  Slot3: "Value 3"
};

ClearSlotsAction

// Import required classes
import { ClearSlotsAction } from "@stackchat/dynamic-content-toolkit";

const clearSlotsAction = new ClearSlotsAction();
/**
 * The `slotNames` property is an array of slots in your bot.
 * In the example below, `Slot1`, `Slot2` and `Slot3` are slot
 * names as they appear in your bot in Stackchat Studio. All
 * of the slots mentioned will have their values cleared once
 * this action is executed.
 */
clearSlotsAction.slotNames = [ "Slot1", "Slot2", "Slot3" ];

AnalyticsEventAction

// Import required classes
import { AnalyticsEventAction } from "@stackchat/dynamic-content-toolkit";

const analyticsEventAction = new AnalyticsEventAction();

// The `eventName` property is required, but this value is ignored by Adobe Analytics.
analyticsEventAction.eventName = "Event 1";
/**
 * The `eventData` property is an optional object that is sent as a straight
 * pass-through to your configured analytics provider. It is an object with
 * arbitary key-value mappings that should map to the values expected by your
 * analytics provider. For example, if you're using Adobe Analytics,
 * `eventData` might look something like this:
 * {
 *    prop1: 'value1',
 *    prop3: 'value2',
 *    events: 'event3,event4'
 * }
 */
analyticsEventAction.eventData = {
  ...
}

ActionSequence

// Import required classes
import { ActionSequence } from "@stackchat/dynamic-content-toolkit";

// Create an ActionSequence
const actionSequence = new ActionSequence();
actionSequence.actions = [
  setSlotsAction,
  clearSlotsAction,
  analyticsEventAction
];

Navigation

When a Cloud Function is defined in Stackchat Studio, a Continue To navigation target may be defined, which will navigate the user accordingly once execution is complete. However, you may want to override this value if certain conditions are met, so the Navigation class is made available to you. This a top level class that will trigger navigation to another flow or flow element in your bot.

Navigation is defined as continueTo: The flow or flow element to navigate to once your cloud function completes execution. Expects a string containing two tokens in the format of flow_name:flow_element_name. flow_name can be replaced by _ to indicate the current flow, while flow_element_name can be replaced by * to indicate the default entry element for the flow referenced in the first token. Otherwise these values should be the actual names of the flow or flow element you wish to navigate to.

Navigation

// Import required classes
import { Navigation } from "@stackchat/dynamic-content-toolkit";

// Create an ActionSequence
const navigation = new Navigation();
navigation.continueTo = "Flow One: *";

The continueTo property accepts a flow, a flow element or both in the following syntax:

Flow:Flow Element

/**
 * For demonstration purpose, let us assume we have a bot
 * with flows as `Flow One`, `Flow Two` and `Flow Three`. Further
 * more, let us assume each of the above flows have three elements
 * therein named as `Element One`, `Element Two` and `Element Three`.
 *
 * The structure would be as follows:
 * {
 *      'Flow One': [ `Element One`, `Element Two`, `Element Three ~ default` ],
 *      'Flow Two': [ `Element One`, `Element Two ~ default`, `Element Three` ],
 *      'Flow Three': [ `Element One ~ default`, `Element Two`, `Element Three` ]
 * }
 *
 * We are assuming that `Element 2` inside `Flow 2` is the element
 * that triggered our cloud function execution.
 *
 * On the above basis, the following are valid `continueTo` values:
 */
const possibleValues = [
  "Flow One:*", // Continue to the default element of `Flow One`, i.e `Element Three`,
  "_:*", // Continue to the default element of the current flow i.e. `Flow Two, Element Two`,
  "_:Element Three", // Continue to the `Element Three` of current flow, i.e. `Flow Two`,
    "Flow One:Element Three", // Continue to `Element Three` in `Flow One`
];

Postback Buttons

The Web Messenger can also use Postback buttons by adding delegates.

This can also function in a carousel, where postback buttons can contain payloads. Those Postbacks can then be configured to trigger a specific Cloud Function.

From the example above, the Dynamic Content carousel showing sales on black shoes can include a Postback "Buy" button where each result has a payload that is the product ID for the given pair of shoes. When the user clicks the button, the product ID payload can be returned and instructed to execute a PurchaseItem Cloud Function using that product ID.