Chatdown for the Bot Framework - Introduction and Processing Multiple Files
Did you hear all of the great news that came out of Microsoft's Build conference? The Bot Framework team has been on fire, which is a sure sign that chatbots are still high on Microsoft's priority list. I was able to sit in on a few sessions back in March at the MVP Summit that dealt with the Bot Framework, so I received a sneak preview of the new Bot Emulator, the command line tools, the newer cognitive services, and the roadmap for SDK 4. Unfortunately, I was under an NDA, so I wasn't able to share any of it. Now that Build is over, all of this stuff is out in the open, and I've been queuing up some blog posts and video tutorials on some of the new functionality.
The biggest addition is simply knowing that a new version of the Bot Emulator is coming--one that is clearly working its way towards being a full tool rather than just an emulator. I took it for a spin as soon as it was released, and even with the bugs, I like where its going.
One of the things that the emulator works well with right now is Chatdown. Chatdown is a markdown-ish language with modified syntax that lets you quickly build conversations for later transcription.
A very simple chat file (usually signified with a *.chat
extension) could look something like this:
user=Angel
bot=Ginny
bot: Hello, Angel. What are looking for today?
user: I need to schedule with a master assessor this week.
You name the user, you name the bot, and then you write out the dialog prefixed with the appropriate party. From the command line, you would process this file with the chatdown CLI:
chatdown dialog.chat > dialog.transcript
Note that you are sending the processed text of dialog.chat into the dialog.transcript file (which will be created for you). If you leave off the arrow and transcript file, it will print to standard output. Conversely, you can type chatdown syntax directly into a terminal window, and have chatdown process that, and push it to a transcript file, but I really don't see many people doing this.
The output of the above would be:
[
{
"conversation": {
"id": "1"
},
"id": "6d0bfe25-82fc-402a-857a-1297e2465104",
"recipient": {
"id": "b1719f61-7d0d-3785-80ff-a394ee526ba6",
"name": "Angel",
"role": "user"
},
"from": {
"id": "caa38425-65b6-3bf9-aece-4f2d87453b10",
"name": "Ginny",
"role": "bot"
},
"text": "Hello, Angel. What are looking for today?",
"timestamp": "2018-05-13T13:54:47.000Z",
"type": "message",
"channelId": "chatdown"
},
{
"conversation": {
"id": "1"
},
"id": "29fd9bd5-de80-4a31-be9a-0577b883fd22",
"recipient": {
"id": "caa38425-65b6-3bf9-aece-4f2d87453b10",
"name": "Ginny",
"role": "bot"
},
"from": {
"id": "b1719f61-7d0d-3785-80ff-a394ee526ba6",
"name": "Angel",
"role": "user"
},
"text": "I need to schedule with a master assessor this week.\n",
"timestamp": "2018-05-13T13:54:49.000Z",
"type": "message",
"channelId": "chatdown"
}
]
This is a JSON object that represents an array of conversation components. In the new Bot Emulator, you then can select "File" => "Open Transcript Fileā¦", and select your brand new transcript file. The Bot Emulator will then display the conversation as it would look if it were actually a conversation that occurred in the bot.
You can do more than just standard text though. Chatdown can simulate typing, as well as a brief delay:
bot: [Typing][Delay=2000]
Currently this doesn't affect the Bot Emulator display of the transcript, but it does offer additional context in the inspector pain of the emulator.
The beauty of chatbots though is in the ability to provide a richer experience with rich card formats and Adaptive Cards. Chatdown supports this since conversations are JSON schemas (as you've seen above), and both rich cards and Adaptive Cards are described with JSON.
Documentation is sparse on adding rich cards, but you can grab the formatting from the documentation for the REST APIs.
For attaching rich cards and Adaptive Cards, you're going to want to reference an external JSON file.
{
"title": "Dr. John Jane",
"images": [
{
"url": "https://www.example.com/images/jane.jpg",
"alt": "Dr. John Jane",
"tap": {
"type": "openUrl",
"value": "https://www.example.com"
}
}
],
"buttons": [
{
"type": "openUrl",
"title": "More...",
"value": "https://www.example.com/doctors/jane/"
}
]
}
You can then add this to a chatdown file with the following syntax:
[Attachment=cards/hero.json hero]
Notice the Attachment
directive is set to the path to the JSON file. There is also a content type attribute at the end of the directive. In this case, "hero" is a shortcut to the "application/vnd.microsoft.card.hero" content type. Chatdown offers content type shortcuts for all the rich card formats as well as Adaptive Cards, so you can save some typing.
If you wanted to add an Adaptive Card to a conversation, you do it much the same way:
[Attachment=cards/adaptive-1.json adaptivecard]
In this example, adaptive-1.json
could look something like this:
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "Container",
"items": [
{
"type": "TextBlock",
"text": "Meet with Coach",
"weight": "bolder",
"size": "medium"
},
{
"type": "TextBlock",
"text": "May 24th"
}
]
}
],
"actions": [
{
"type": "Action.Submit",
"title": "1:00pm-2:00pm"
},
{
"type": "Action.Submit",
"title": "2:00pm-3:00pm"
}
]
}
By default, multiple rich cards will show up in a list--one on top of the other. If you wanted to change that to be presented horizontally, you could use the AttachmentLayout
directive.
[AttachmentLayout=carousel]
[Attachment=cards/adaptive-1.json adaptivecard]
[Attachment=cards/adaptive-2.json adaptivecard]
Currently, you can only process one chatdown file at a time. What if you wanted to process multiple ones? The Chatdown documentation recommends using the Chokidar CLI, which also acts as a file watcher, but if you don't want to run a file watcher, you can use a PowerShell snippet like this:
Get-ChildItem **/*.chat | ForEach-Object { chatdown "$(Split-Path $_.FullName)/$($_.Name )" > "$(Split-Path $_.FullName)/$($_.BaseName).transcript" }
If that's too verbose for you, just give it some time. I'm sure the Chatdown team will incorporate multiple file processing soon.
One tool that bears mentioning: If you are using a lot of Adaptive Cards in your chatdown files, and you program in Visual Studio Code, you'll want the Adaptive Card Viewer extension. This extension will allow you to maintain a preview window that will update in real time as you edit your Adaptive Cards.
So what's the point of Chatdown, and why should you use it? It's much easier to prototype chatbots with mock conversations than it is to build out chatbots and then iterate over the design and conversation flow. Chatdown will allow the chatbot developer and the usability design team to work together to storyboard conversations for stakeholder approval. For single developers or hobbyists, it'll allow you to quickly mock-up a conversation in order to see where the pain points might be in the conversational workflow--eliminating them in advance, and then coding to the solution. Chatdown is simply one more tool in the arsenal to build useful applications.