Testing Events in the Bot Framework Emulator

The Bot Framework emulator is great at testing basic message events, which probably represents the majority of the work. It also supports a few addition ‘system events’ namely; conversation updates, contact updates, ping, typing, delete user data. All good news. However, there is nothing stopping the Bot from supporting all sorts of other events. For example, perhaps the host system wants to invoke a language change, request a transcript, etc. The emulator isn’t so great at supporting these. My quick solution was to write a console app that will send any message, including events, to your Bot site.

static void Main(string[] args)
{
    /*
        hostAddress:=
        conversationId:=
        authToken:=

        Example of a message type
        json:={\"type\":\"message\",\"text\":\"look\",\"from\":{\"id\":\"default-user\",\"name\":\"User\"},\"locale\":\"en-US\",\"textFormat\":\"plain\",\"timestamp\":\"2018-10-08T08:39:19.622Z\",\"channelData\":{}}

        Example of an event type
        json:={\"from\":{\"id\":\"SomeId\",\"name\":\"Paulio\"},\"type\":\"event\",\"name\":\"MyCommand\",\"value\":{\"command\":\"ResetFlags\"}}
    */

    var commands = CommandsFromArgs(args);

    string botEndpoint, authorizationHeader, method, contentType;
    byte[] body;
    ParseCommands(commands, out botEndpoint, out authorizationHeader, out method, out contentType, out body);

    var webClient = new WebClient();
    webClient.Headers.Add("Authorization", authorizationHeader);
    webClient.Headers.Add("Content-Type", contentType);
    var result = webClient.UploadData(botEndpoint, method, body);

    var response = Encoding.ASCII.GetString(result);
}

private static void ParseCommands(Dictionary commands, out string botEndpoint, out string authorizationHeader, out string method, out string contentType, out byte[] body)
{
    var botHostAddress = commands["hostAddress"];
    var conversationId = commands["conversationId"];
    botEndpoint = $"{botHostAddress}/v3/directline/conversations/{conversationId}%7Clivechat/activities";
    var authToken = commands["authToken"];
    authorizationHeader = $"Bearer {authToken}";
    method = "POST";
    contentType = "application/json";
    var requestBody = commands["json"];
    body = Encoding.ASCII.GetBytes(requestBody);
}

private static Dictionary CommandsFromArgs(string[] args)
{
    var commands = new Dictionary();
    var splitter = new string[] { ":=" };
    foreach (var arg in args)
    {
        if (arg.Contains(":="))
        {
            var pair = arg.Split(splitter, StringSplitOptions.None);
            if (pair.Length == 2)
            {
                commands.Add(pair[0], pair[1]);
            }
        }
    }

    return commands;
}

To invoke the sender you must supply;

  1. hostAddress – the Service URL address of your dev or actual site. This is a property of an Activity
  2. conversationId – the id of the conversation, you can see this by setting a break point in your code, although it’s a good idea to get your Bot to have a diagnostic message/command so it will display this for you
  3. authToken- another one you’ll need to glean from your code or diagnostics
  4. json – the payload you wish to send to the Bot. In the code you can see two examples, one is a basic message activity, the other is an event.

Hope this helps.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s