The Bot Framework SDK team is happy to announce the General Availability of the consolidated bot framework CLI tool bf-cli. The new BF CLI tool will replace legacy standalone tools to manage Bot Framework bots and related services. The old tools will be ported over in phases and all new features, bug fixes, and further investments will focus on the new BF CLI. Old tools will still work for the time being, but they are going to be deprecated in future releases.
Upon the release of Bot Framework SDK version 4.6 the following legacy tools have been ported: Chatdown, QnAMaker, LuisGen, and LuDown.
To learn more about the BF CLI please visit the BF CLI github repository.
The following page is about a legacy tool.
Chatdown is a transcript generator which consumes a .chat file to generate mock transcripts. Generated mock transcript files are output to stdout.
A good bot, just like any successful application or a website, starts with clarity on supported scenarios. Creating mockups of conversations between bot and user is useful for:
- Framing the scenarios supported by the bot.
- Business decision makers to review, provide feedback.
- Defining a "happy path" (as well as other paths) through conversational flows between a user and a bot
.chat
file format helps you create mockups of conversations between a user and a bot. Chatdown CLI tool converts .chat
files into conversation transcripts (.transcript
files) that can be viewed in the Bot Framework Emulator.
- Node.js version 8.5 or higher
npm i -g chatdown
Usage:
chatdown <chat> --help
Argument | Description |
---|---|
<chat> |
The path of the chat file to be parsed. If omitted, stdin will be used. |
-v, --version |
show version |
--help |
Output the help to the console |
--static |
use static timestamps when generating timestamps on activities. |
Here's an example .chat
file:
user=Joe
bot=LulaBot
bot: Hi!
user: yo!
bot: [Typing][Delay=3000]
Greetings!
What would you like to do?
* update - You can update your account
* List - You can list your data
* help - you can get help
user: I need the bot framework logo.
bot:
Here you go.
[Attachment=bot-framework.png]
[Attachment=http://yahoo.com/bot-framework.png]
[AttachmentLayout=carousel]
user: thanks
bot:
Here's a form for you
[Attachment=card.json adaptivecard]
See the Examples folder for more samples.
Chat files are markdown files that contain 2 parts:
- Header that defines who the participants are in the conversation
- Back and forth conversation between a user and a bot
The header defines who the participants are in the conversation and defines other options.
Option | Description |
---|---|
user=<user> |
This option tells chatdown that a user message will begin with <user> followed by a colon. For example, user=Joe instructs chatdown that lines beginning with Joe: or user: are the start of a message from the user Joe. |
users=<user1>,<user2>,<user3> |
This option tells chatdown that there are multiple users in the conversation. |
bot=<bot> |
This options tells chatdown that a bot message will begin with <bot> followed by a colon. For example, bot=LulaBot instructs chadown that lines beginning with LulaBot: or bot: are the start of a message from the bot Lulabot. |
channelId=<channelID> |
This option tells chatdown to use the specified channelID for each activity. |
Once the configuration options for users
and bot
are defined, the rest of the conversation can use the alias prefixes user:
and bot:
or the names directly. Chatdown will correctly make the associations to the specified names for you.
The Bot will default to sending to the first user in the users list or the last user it received a message from, unless you directly specify a target user by using the bot->user: syntax.
For example:
users=Joe,Fred
bot: This will go to Joe, because he's first in the list
Fred: What about me?
bot: This will go to Fred, because he's the latest user to talk to the bot
bot->Joe: This will always go to Joe
bot->Fred: This will always go to Fred
The conversation between the user and the bot with markdown support for bot's responses. Every time a user:
or bot:
is found at the beginning of the line, a new activity will be inserted into the transcript. Inside the markdown, you can insert commands to generate richer transcripts:
Command | Description |
---|---|
[Typing] |
Inserts a typing activity into the transcript to signify that a user or a bot is typing. |
[Delay=<milliseconds>] |
Delays the transcript by <milliseconds> . |
[ConversationUpdate=] |
Sends a conversationUpdate, with membersAdded= and membersRemoved= values |
Example ConversationUpdate message
[ConversationUpdate=
MembersAdded=Joe,Susan]
bot->Joe: Hi Joe!
bot->Susan: Hi Susan!
When sending a message there are a number of commands for controlling layout.
Command | Description |
---|---|
[Suggestions=<Option 1>|<Option 2>|<Option 3>] |
Add suggested action buttons, delimited by | |
[AttachmentLayout=LayoutType] |
Specify how multiple attachments would be displayed. Layout types are carousel or list |
You can add cards using simple commands as well. Currently we support a number of cards:
description | card name |
---|---|
HeroCard | A simple card with single large image, title, subtitle, text and buttons |
ThumbnailCard | Same as herocard, but image is much smaller |
AudioCard | send audio card for playing back an audio url |
VideoCard | send an video player card for playing back a video file |
AnimationCard | send a animated gif card |
MediaCard | send arbitrary media with transport control |
SigninCard | send a signin card |
OauthCard | send an oauth card which uses azure bot service oauth flow |
Bot:
[Herocard
title=Cheese gromit!
subtitle=Hero Card
text=This is some text describing the card, it's cool because it's cool
image=https://memegenerator.net/img/instances/500x/73055378/cheese-gromit.jpg
buttons=Option 1| Option 2| Option 3]
Bot:
[ThumbnailCard
title=Cheese gromit!
subtitle=Thumbnail Card
text=This is some text describing the card, it's cool because it's cool
image=https://memegenerator.net/img/instances/500x/73055378/cheese-gromit.jpg
buttons=Option 1| Option 2| Option 3]
The properties that are supported are
property | description |
---|---|
title | The title of the card |
subtitle | a subtitle for the card with less emphasis |
text | a generic text property which can contain longer text describing the card |
image | image url to use for the card |
buttons | a set of button labels separated by ` |
To add an attachment, you use [Attachment=path contentPath]
. The path can be a URL or a local path (either absolute or relative to .chat
file). The content type is optional and if not passed, will be inferred from the file extension. You can also pass it using a shortcut or full mime type.
[Attachment=path contentType]
The following examples illustrates sending a carousel of photos:
Enjoy these pictures!
[AttachmentLayout=carousel]
[Attachment=http://4.bp.blogspot.com/--cFa6t-x4qY/UAqEgUvPd2I/AAAAAAAANIg/pMLE080Zjh4/s1600/turtle.jpg]
[Attachment=http://viagemempauta.com.br/wp-content/uploads/2015/09/2_All-Angle-By-Andreza-dos-Santos_FTS_2914-344-620x415.jpg]
[Attachment=http://images.fineartamerica.com/images-medium-large/good-morning-turtles-freund-gloria.jpg]
[Attachment=http://4.bp.blogspot.com/--cFa6t-x4qY/UAqEgUvPd2I/AAAAAAAANIg/pMLE080Zjh4/s1600/turtle.jpg]
[Attachment=image.png]
This example sends a local adaptive card using a content type shortcut:
[Attachment=folder/sample.json "adaptivecard"]
Some of the content types have shortcuts:
ContentType Shortcuts | Description |
---|---|
animation | application/vnd.microsoft.card.animation |
audio | application/vnd.microsoft.card.audio |
hero | application/vnd.microsoft.card.hero |
receipt | application/vnd.microsoft.card.receipt |
thumbnail | application/vnd.microsoft.card.thumbnail |
signin | application/vnd.microsoft.card.signin |
video | application/vnd.microsoft.card.video |
adaptivecard | application/vnd.microsoft.card.adaptive |
application/custom | application/custom |
In the simplest form, a chatdown command looks like the following:
chatdown sample.chat > sample.transcript
This will consume sample.chat
and output sample.transcript
.
stdin can be used as an alternative to specifying an input file.
(echo user=Joe && echo bot=LulaBot && echo Joe: 'Hi!' && echo LulaBot: 'Hi there!') | chatdown > sample.transcript
stdout can be used as an alternative to specifying the output file.
chatdown sample.chat
or
chatdown sample.chat > joe.transcript
The transcript will be piped to stdout.
Chatdown can be used within a Node.js application as an imported library. Install locally:
npm i -s chatdown
In your node project:
const chatdown = require('chatdown');
const conversation = `
user=Joe
bot=LulaBot
user: Hello!
bot: Hello, can I help you?
user: I need an image
bot: here you go! [Attachments:bot-framework.png]
`;
chatdown(conversation, config)
.then(activities => {
// do stuff with the resulting activities.
})
.catch(e =>{
// oops! Something went wrong
});
If you are dealing strictly with files, and not standard input/output, you can process all Chatdown files at once:
chatdown -f **/*.chat -o ./transcripts
The above command will process all *.chat
files in the current directory and all subdirectories, and put the output in the "transcripts" folder of the current directory. If an output directory is not present, it will default to the current working directory.
Chokidar-cli is a great utility to do this.
To install:
npm install -g chokidar-cli
To run as a watcher:
chokidar "**/*.chat" -c "chatdown {path} > {path}.transcript"
Now, any time a .chat file is created or saved, chatdown will automatically create the transcript file beside it.
Nightly builds are based on the latest development code which means they may or may not be stable and probably won't be documented. These builds are better suited for more experienced users and developers although everyone is welcome to give them a shot and provide feedback.
You can get the latest nightly build of Chatdown from the BotBuilder MyGet feed. To install the nightly -
npm config set registry https://botbuilder.myget.org/F/botbuilder-tools-daily/npm/
Install using npm:
npm i -g chatdown
To reset registry:
npm config set registry https://registry.npmjs.org/