One of the many benefits of the Microsoft Bot Framework is that it allows the creation of bots capable of running on a multitude of channels (Skype, Facebook Messenger, Slack, etc.). However, due to the subtle differences between these platforms, it is impractical for the framework to cover all possible message types for each one. Even though Bot Builder SDK allows for all sorts of rich message templates, there are still some types of messages, such as a Facebook Messenger Share button, that require you to set the custom channel data of the outgoing message.
What is channel data?
Before understanding how to modify channel data, it helps to first know what it is and why it is important.
When a message is sent between the user and the bot, there is internal data within the message that is specific to each channel, which allows the bot to properly communicate on that channel. This information is called channel data.
For example, when communicating over the Office 365 email channel, the channel data might contain information about the email’s body, subject, and recipients. The channel data for a message via Facebook Messenger might contain extra details about an attachment which specify a special button.
On most channels, modifying the channel data is unnecessary, but if the need arises, the Bot Builder SDK allows the freedom to adapt the underlying message structure.
Now that we have familiarized you with channel data, let’s see how to use it in code!
NOTE: All the code used for this section is available in a GitHub repository.
Changing channel data with the NodeJS SDK is as easy as instantiating a class and calling one function.
First, make sure you have instantiated your instance of the Bot Builder SDK:
Now, in order to get access to channel data, you must be inside one of your bot’s dialog handlers:
For this example, we will use channel data to structure a generic template with a Facebook Messenger Share button.
From the documentation, Facebook requires our channel data to look like this:
In order to mimic this format, we will use the
Message class of the SDK, and the
.sourceEvent() function (see documentation).
When calling the
Message class, you can pass the context of the current dialog session into the constructor, which automatically populates the message’s address information with details such as…
- user ID
- bot ID
- channel ID
- conversation ID (optional)
…so that you don’t have to. Knowing that, our updated code will look like this:
new botbuilder.Message(session) to create a new instance of the
Message class that will represent our outgoing message. We then call
sourceEvent() to modify and customize the channel data to our specifications.
It is also important to note that whenever you use
sourceEvent() to modify channel data, you must specify the name of the channel the message is intended for. In our example, we did this here:
That’s all you have to do in order to use custom channel data in NodeJS. See the Channels documentation for further details on the capabilities of each channel. You can also take a look at the sample code on Github with a working example of the code in this article.
NOTE: All the code used for this section is available in a Github repository.
We will go into more detail about this later. For now we need to construct a new message to expose the
ChannelData object. This is done in the
ShareButtonDialog.cs file (in the Github repo).
The above code will be called from our messages controller (in the Github repo) when our bot receives a message from Facebook.
Now that we have access to the
ChannelData object of our message, can add our own custom JSON data. To do so, we need to use the
Newtonsoft.Json assembly that we mentioned at the beginning of this section.
Creating JSON Objects in C#
To create a proper JSON object, we need to define a class for each of the nested objects within our required format. For example, according to the documentation this the format required by Facebook to create a Share Button:
Ultimately, this breaks down into several objects:
- channelData (outermost wrapper)
- generic template (inside of payload)
- generic template content (inside of elements)
- facebook share button (inside of buttons)
After this section, we will end up with the following C# classes:
We will now create a file for each class. (It is useful to create a folder in your solution explorer called “Models” or something similar to store these files in.) Let’s start from the top, outermost layer of our JSON structure, and work our way inward. This file is in the Github repository.)
At the very top of each of these class files, we make sure to include the
Newtonsoft.Json assembly, as we will be assigning attributes to the members of each class that will define their JSON representation. For example, with this class, we want to create a C# object,
FacebookChannelData, that will house the first object in our notation.
The desired JSON representation for this object is:
In C#, we define this by creating an object,
FacebookChannelData, with an
Attachment member. We then assign an attribute to this property,
that will be used to convert it to its desired JSON representation:
attachment. So essentially,
is converted to:
Now, if we go a level lower, to define our
FacebookAttachment object (in the Github repo) that will be nested inside
we follow the same pattern:
This C# object will convert to the following JSON:
This is done for each level of our desired JSON structure until it is completely filled out. Then, we just have to connect it all together in the
ShareButtonDialog.cs file (in the Github repo).
This will produce a Generic Template containing a Share Button in Facebook Messenger! See the documentation for further details on the capabilities of each channel.
You can also take a look at the Github repository containing a working example of the code above.
Tony Anziano from the Bot Framework team