Persisting data within a conversation with botframework’s dialogs

In the previous botframework article I covered the different types of responses available for the botframework. This article is going to touch on the Dialog and persisting information between subsequent messages.

So what’s a Dialog?

Dialogs can call child dialogs or send messages to a user. Dialogs are suspended when waiting for a message from the user to the bot. Dialogs are resumed when the bot receives a message from the user.

To create a Dialog, you must implement the IDialog<T> interface and make your dialog class serializable, something like this:

[Serializable]
public class HelloDialog : IDialog<object>
{
    protected int count = 1;

    public async Task StartAsync(IDialogContext context)
    {
        await context.PostAsync($"You're new!");
        context.Wait(MessageReceivedAsync);
    }

    public async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument)
    {
        var message = await argument;
        await context.PostAsync($"I've seen you {count++} times now, {message.From.Name}");
        context.Wait(MessageReceivedAsync);
    }
}

What I’m trying to show here is how the dialog handles an initial message from a new user, versus the continuation of a conversation with that same user.

In order to wire the dialog up to the MessagesController you need to reference Microsoft.Bot.Builder.Dialogs and use the Conversation.SendAsync() method:

public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
    if (activity.Type == ActivityTypes.Message)
    {
        // needs a reference to Microsoft.Bot.Builder.Dialogs
        await Conversation.SendAsync(activity, () => new HelloDialog());
    }
    else
    {
        HandleSystemMessage(activity);
    }
    var response = Request.CreateResponse(HttpStatusCode.OK);
    return response;
}

With this implemented you should see something similar to the following conversation if you use the bot framework channel emulator:

dialog with basic state

The magic is in context.Wait:

context wait tooltip

Suspend the current dialog until the user has sent a message to the bot

So what we’ve done here is implement IDialog<T>’s StartAsync method, then tell the bot to hang around, waiting for another message in the same conversation from the same user using context.Wait.

Well, that sounds like stateful communication, right? Which sucks, since it inhibits scaling by requiring sticky sessions.

A-ha! But not quite, in this case; in something that hopefully doesn’t end up looking like viewstate, we have DialogState encoded in the context’s PrivateConversationData’s Bag:

dialogstate in the context's privateconversationdata

This will allow state to be carried around and the conversation continued without the user needing to be tied to a single instance of the bot. Nice.

Let’s play with that a bit:

public async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument)
{
    int heresavalue = 1;
    if (!context.PrivateConversationData.TryGetValue<int>("countthingy", out heresavalue)) { heresavalue = 1; }

    var message = await argument;
    await context.PostAsync($"I've seen you {count++} times now, {message.From.Name} and also {heresavalue}");
    context.Wait(MessageReceivedAsync);

    context.PrivateConversationData.SetValue<int>("countthingy", heresavalue * 2);
}

Now we’re setting a variable heresavalue and doubling it for each message in the same conversation, just to show that the value is being persisted; after a few messages, it looks like this:

UDC in privateconversationdata

context.PrivateConversationData.SetValue<T> and context.PrivateConversationData.TryGetValue<T> mean we can push info into the databag and get it back again within the context of a one on one chat.

The same is also true for context.ConversationData, where the conversation is a group (i.e., the bot and more than one other user), instead of one-to-one.

Skype

What’s quite cool is how your Skype name is pulled out from message.From.Name when the bot is deployed to Skype

skype name being passed in the message

Summary

Hopefully this short article gave you an idea of how to implement a Dialog and how you can persist state within a conversation.

Rate-Limiting, Powershell, Pester, and the ZenDesk API

Have you ever had to utterly hammer an API via a little Powershell script, only to find you’re getting rate limited, and lose all that previously downloaded data before you could persist it somewhere?

I have. I’ve recently put together a script to query a customer support ticketing system’s API, get a list of all tickets within a given time period, then query again to get to get the full content for each ticket.

All of this data is being added to a custom Powershell object (as opposed to churning out to a file as I go) since I convert it all to Json right at the end.

I’d rather not get half way through a few thousand calls and then have the process fail due to being throttled, so I’ve chosen to create a little function that will check for – in my case – an HTTP 429 response (“Too Many Requests”), get the value of the “Retry-After” header, then wait that many seconds before trying again.

This particular implementation is all quite specific to the ZenDesk API, but could easily be adapted to other APIs which rate limit/throttle and return the appropriate headers.

I’ve called the function CalmlyCall as a nod to Twitter’s original throttling implementation when they used HTTP 420 – “Enhance Your Calm” – back in the day.

function CalmlyCall($uri, $headers) {
    $enhanceyourcalm = 0

    do {
        if ($enhanceyourcalm -gt 0) {
            Write-Host -Object "Throttled; calming down for $enhanceyourcalm seconds..."
            Start-Sleep -Seconds $enhanceyourcalm
            $headers.Calm = $true
        }

        $response = Invoke-WebRequest -Uri $uri -Headers $headers -UseBasicParsing
        $ratelimit = $response.Headers['X-Rate-Limit-Remaining']

        if ([int]$ratelimit -lt 50) {
            Write-Host -Object "Calm may be needed: rate limit remaining - $($ratelimit)"
        }

        $enhanceyourcalm = $response.Headers["Retry-After"]
    } while ($response.StatusCode -eq 429)

    return ConvertFrom-Json $response.Content
}

You’ll see that I’m just using a do .. while loop to call the specified endpoint, check the headers for throttling information, and patiently (using Start-Sleep) until I’m allowed to continue. Simple stuff.

I’m only adding a Calm header when I’m throttled to make it more easily testable. I’m sure there’s a better solution to this, but it works well enough for me.

And since I’m a fan of testing my powershell, here’s the associated Pester script – it’s not great, since I’m mocking against Write-Host, for example:

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
. "$here\$sut"

Describe "CalmlyCall" {
    Context "if no rate limiting exists" {
        It "should call the endpoint" {
            Mock Write-Host {}
            Mock Invoke-WebRequest -ParameterFilter { $Uri.ToString().EndsWith("test.here") } {        
                [PSCustomObject] `
                @{
                    Headers = @{};
                    StatusCode = 200;
                    Content = "{'result':'mycontent'}"
                }
            }

            $actual = CalmlyCall -uri "test.here" -headers @{}

            Assert-MockCalled Invoke-WebRequest
            $actual.result | Should be "mycontent"
        }
    }


    Context "if rate limiting exists" {
        It "should check limit remaining" {
            Mock Invoke-WebRequest -ParameterFilter { $Uri.ToString().EndsWith("test.here") } {        
                [PSCustomObject] `
                @{
                    Headers = @{'X-Rate-Limit-Remaining' = '20';'Retry-After' = '0'};
                    StatusCode = 200;
                    Content = "{'result':'mycontent'}"
                }
            }

            Mock Write-Host -ParameterFilter { $Object.ToString().EndsWith("rate limit remaining - 20")}

            $actual = CalmlyCall -uri "test.here" -headers @{}

            Assert-MockCalled Invoke-WebRequest
            Assert-MockCalled Write-Host -Times 1 -Exactly
            $actual.result | Should be "mycontent"
        }
    }


    Context "if initial request is throttled" {
        It "should respect throttling" {
            Mock Invoke-WebRequest -ParameterFilter { $Uri.ToString().EndsWith("test.here") } {        
                [PSCustomObject] `
                @{
                    Headers = @{'X-Rate-Limit-Remaining' = '0';'Retry-After' = '10'};
                    StatusCode = 429;
                    Content = "{'result':'mycontent'}"
                }
            }

            Mock Invoke-WebRequest -ParameterFilter { $Uri.ToString().EndsWith("test.here") -and $Headers -ne $null -and $Headers.Calm} {        
                [PSCustomObject] `
                @{
                    Headers = @{'X-Rate-Limit-Remaining' = '100';'Retry-After' = '0'};
                    StatusCode = 200;
                    Content = "{'result':'mycontent'}"
                }
            }

            Mock Start-Sleep -ParameterFilter { $Seconds -eq 10 }
            Mock Write-Host -ParameterFilter { $Object.ToString().EndsWith("rate limit remaining - 0") -or
                                               $Object.ToString().StartsWith("Throttled; calming down for 10 seconds")}

            $actual = CalmlyCall -uri "test.here" -headers @{}

            Assert-MockCalled Invoke-WebRequest -Times 2 -Exactly
            Assert-MockCalled Start-Sleep -Times 1 -Exactly
            Assert-MockCalled Write-Host -Times 2 -Exactly
            $actual.result | Should be "mycontent"
        }
    }
}

Feel free to suggest improvements!

Botframework Web Chat Embedding

The past two articles have been about setting up a botframework bot in Skype and comparing the various Skype clients to see how it’s rendered. In this short article we’ll have a look at configuring the Web Chat client.

Web Chat client is enabled by default when you register your bot:
enabled clients

If you click “edit” next to Web Chat, you’re taken to the configuration page:

configure within botframework dev portal

Click “Regenerate Web Chat secret” and those textboxes will be populated
regenerate web chat secret

You can now embed the web chat client on your webpage using an iframe

<iframe src='https://webchat.botframework.com/embed/rposbo_demo_bot?s=YOUR_SECRET_HERE'></iframe>

Which looks like this – have a play!

Rich botframework conversation cards

In the last article about bots I covered creating a basic bot using Microsoft’s botframework, setting up Azure, deploying the bot into Azure, and configuring it to work within Skype.

In this article we’re going to investigate the various response types available to us in the botframework to develop a more rich conversational experience.

Markdown

Luckily you’re not limited to plain text in a bot conversation; we’re able to embed images, add attachments, give headers and subheaders, add a button or link, tap events for various areas, as well as use markdown to format the main text content.

If you’re not already familiar with Markdown, then get on the case! It means you can very easily write HTML by using a shorthand syntax which can easily be converted to HTML.

I’ve been using it for many years for blogging and general documentation; using pandoc you can even convert markdown to PDF or a Word Doc. Using remark.js or the more recent Marp you can use it to easily create PowerPoint-like presentations

markdown example

Botframework messages support using this syntax to make the responses more rich. Of course, for this to work, the attached service needs to know how to render the response (and I’ll get on to this later)

Response Types

If you go and read the first article in my botframework series, you’ll recognise this as the default reply logic within the boilerplate MessagesController:

// return our reply to the user
Activity reply = 
   activity.CreateReply($"You sent {activity.Text} which was {length} characters");

For each of the following response type examples just replace this line from the default MessagesController with the example code.

Let’s make an example response just using some basic markdown to give a heading (a single “#” at the start of a line is an “H1”, two “##” is an “H2”, etc), bold, italic, a link, an image, a blockquote, and a code block:

var markdownContent = "#A heading\n";
markdownContent += "##A subheading\n";
markdownContent += "**something bold**\n\n";
markdownContent += "*something italic*\n\n";
markdownContent += "[a link!](http://robinosborne.co.uk/?s=bot)\n\n";
markdownContent += "![AN IMAGE!](http://robinosborne.co.uk/wp-content/uploads/2016/07/robinosborne.jpg)\n";
markdownContent += "> A quote of something interesting\n\n";
markdownContent += "```\nvar this = \"code\";\n```\n";

Activity reply = activity.CreateReply(markdownContent);

Now here’s the the rub: as I mentioned at the start, in order to use these rich responses the service to which your bot is talking needs to know how to render the content. The JSON response will just contain a block of markdown, not a pre-rendered chunk of HTML for example. As such, the services (such as Skype or Slack) need to know how to render markdown.

The case in point; here is the above message being rendered in different services:

Markdown: in the Bot Channel Emulator

markdown response rendered in bot channel emulator

Alright, that’s pretty awesome! The H1 and H2 came out nicely, as did the bold and italic text. The image was embedded and the alt/title was even rendered underneath, but the image has been stretched to look much bigger than the original; and there’s the link. The blockquote looks great and there’s even a nicely formatted code block! Aces! This is great, right?..

Markdown: in the Skype Desktop App

markdown response in Skype desktop app

Uh, okayyy.. H1 and H2 are just underlined, bold and italic are good as is the link; the image isn’t embedded and the quote is certainly rendering as a quote, but needs a cite perhaps. The code block seems to have been ignored.

Markdown: in the Skype Web App

markdown response in Skype web app

The quote is ignored, and the image doesn’t even link to the image, like it did in the desktop app.

Markdown: in the Skype Android App

markdown response in Skype android app

Now we’ve got an embedded image (sort of), the quote just has an empty (null) cite and the code block is ignored.

Mixed Results for markdown rendering in Skype vs the emulator, for sure. And these all use the same JSON response:

"text": "#A heading\n##A subheading\n**something bold**\n\n*something italic*\n\n[a link!](http://robinosborne.co.uk/?s=bot)\n\n![AN IMAGE!](http://robinosborne.co.uk/wp-content/uploads/2016/07/robinosborne.jpg)\n> A quote of something interesting\n\n```\nvar this = \"code\";\n```\n"

Attachments

As well as plain old text and funky markdown messages, we can add simple media attachments – images, audio, video, or generic “files”

Let’s try to send a couple of images:

Activity reply = activity.CreateReply("Here's an **image attachment**");
reply.Attachments = new List<Attachment> {
   new Attachment()
   {
       ContentUrl = "http://robinosborne.co.uk/wp-content/uploads/2016/07/image-attachment-tachikoma.jpg",
       ContentType = "image/jpg",
       Name = "Tachikoma - jpg"
   },
   new Attachment()
   {
       ContentUrl = "http://robinosborne.co.uk/wp-content/uploads/2016/07/image-attachment-gypsy-danger.png",
       ContentType = "image/png",
       Name = "Gypsy Danger - png"
   }
};

Image Attachments: in the Emulator

image attachments response in bot channel emulator

Great stuff; that’s a jpg and a png with their alt appearing as a caption.

Image Attachments: in Skype Desktop

image attachments response in skype desktop

Image Attachments: in Skype Web App

image attachments response in skype web

Image Attachments: in Skype Android App

image attachments response in skype  android app

Some subtle differences there, but overall a pretty standard response.

Rich Attachments: Hero Card

As well as plain old media attachments, we can also attach “cards”. These cards can have some extra functionality, like buttons and tap events.

The hero card contains a single large image, a button, and a “tap action”, along with text content.

Activity reply = activity.CreateReply("Here's a **hero**");

var heroCard = new HeroCard()
{
    Title = "I'm a hero card",
    Subtitle = "Robin hearts Tachikoma",
    Images = new List<CardImage> {
        new CardImage(url: "http://robinosborne.co.uk/wp-content/uploads/2016/07/robinosborne.jpg")
    },
    Buttons = new List<CardAction> {
     new CardAction()
        {
            Value = "https://robinosborne.co.uk/?s=bot",
            Type = "openUrl",
            Title = "Rob's bots"
        } 
    }
};

reply.Attachments = new List<Attachment> {
    heroCard.ToAttachment()
};

Hero: in Emulator

hero attachments response in emulator

Awesome – like it said in the description; a heading, a button, and an image.

Hero: in Skype

botframework hero attachment in skype android app

Looking good

Rich Attachments: Thumbnail Card

The thumbnail card can have a single small image, a button, and a “tap action”, along with text content to display on the card.

Activity reply = activity.CreateReply("Here's a **thumbnail**");

var thumbnailCard = new ThumbnailCard()
{
    Title = "I'm a thumbnail card",
    Subtitle = "Tachikoma hearts Robin",
    Images = new List<CardImage> {
        new CardImage(url: "http://robinosborne.co.uk/wp-content/uploads/2016/07/image-attachment-tachikoma.jpg")
    },
    Buttons = new List<CardAction> {
     new CardAction()
        {
            Value = "https://robinosborne.co.uk/?s=bot",
            Type = "openUrl",
            Title = "Rob's bots"
        }
    }
};

reply.Attachments = new List<Attachment> {
    thumbnailCard.ToAttachment()
};

Thumbnail: in Emulator

thumbnail attachments response in emulator

Does as expected, but the text content doesn’t look perfect – the justified alignment is odd in the emulator. Maybe Skype can do better?…

Thumbnail: in Skype

botframework thumbnail attachment in skype android app

The Android app is looking nice.

Rich Attachments: Receipt Card

The concept of this is kinda cool; a card to – presumably – summarise a purchase, which implies it should be possible to complete a transaction all within the scope of a conversation.

The receipt card can contain a title, “facts”, line items, tax, VAT, total value, and one or more buttons. It’s a beefy one – are you ready?..

Activity reply = activity.CreateReply("Here's a **receipt**");
var receiptCard = new ReceiptCard()
{
    Title = "I'm a receipt card",
    Buttons = new List<CardAction> {
        new CardAction()
        {
            Value = "https://robinosborne.co.uk/?s=bot",
            Type = "openUrl",
            Title = "Pay with rposbo bucks",
            Image = "http://robinosborne.co.uk/wp-content/uploads/2016/07/robinosborne.jpg"
        },
        new CardAction()
        {
            Value = "https://robinosborne.co.uk/?s=bot",
            Type = "openUrl",
            Title = "Paypal"
        }
    },
    Facts = new List<Fact> {
        new Fact("You shopped at", "Epic Shop"),
        new Fact("We love you", "THIS MUCH")
    },
    Items = new List<ReceiptItem> {
        new ReceiptItem
        {
             Title = "Building Great Startup Teams",
             Image = new CardImage("https://images-na.ssl-images-amazon.com/images/I/41xkMlpjRuL._AC_SX60_CR,0,0,60,60_.jpg"),
             Price = "9.99",
             Quantity = "1",
             Subtitle = "A Guide to Attracting, Hiring, and Retaining Employees",
             Text = "Dean Hume"
        },
        new ReceiptItem
        {
             Title = "Fast ASP.NET Websites",
             Image = new CardImage("https://images-na.ssl-images-amazon.com/images/I/51S6zPA2TYL._AC_SX60_CR,0,0,60,60_.jpg"),
             Price = "20.99",
             Quantity = "1",
             Subtitle = "Practical, hands-on guidance to create faster, more efficient ASP.NET sites",
             Text = "Dean Hume"
        }
    },
    Total = "30.98",
    Tax = "9.68",
    Vat = "10"
};

reply.Attachments = new List<Attachment> {
    receiptCard.ToAttachment()
};

Receipt: in Emulator

receipt attachment response in emulator

Woah. Yeah, you can seriously pack a load of information into this one card. It even renders quite nicely in the emulator, except notice that it’s using the main receipt’s title for each line item instead of the item’s title, but the correct title per line item is returned in the JSON, so this is just an issue with the emulator.

Still cool though. Having multiple buttons is interesting, and being able to add an image to a button could be handy for, say, payment method logos.

Receipt: in Skype

botframework receipt attachment in skype android app

This is a really slick looking card.

Rich Attachments: Sign In Card

The sign in card may not look like much (and it doesn’t), but when the card action is set to the type of “signin”, it can initiate an oauth flow; the user can be made to leave the conversation to authenticate with a third party system.

Activity reply = activity.CreateReply("Here's a **signin**");

var signinCard = new SigninCard()
{
    Text = "Authorisation needed",    
    Buttons = new List<CardAction> {
     new CardAction()
        {
            Value = "https://robinosborne.co.uk/?s=bot",
            Type = "signin",
            Title = "Facebook OAuth",
            Image = "https://cdn1.iconfinder.com/data/icons/logotypes/32/square-facebook-128.png"
        },
     new CardAction()
        {
            Value = "https://robinosborne.co.uk/?s=bot",
            Type = "signin",
            Title = "Google",
            Image = "http://images.dailytech.com/nimage/G_is_For_Google_New_Logo_Thumb.png"
        }
    }
};

reply.Attachments = new List<Attachment> {
    signinCard.ToAttachment()
};

SignIn: in Emulator

sign in attachment response in emulator

Ha – the smiley isn’t on the message at all; this is just how the emulator is rendering a “sign in” card!

SignIn: in Skype

botframework signin attachment in skype android app

Very cute! It hasn’t taken my content, nor my custom buttons; looks like the “sign in” card may use default content only.

it’s possible to use the AttachmentLayout property to return a response containing several different rich content cards, and combine them into a carousel display; by default these are displayed as a list, as you can see from the image attachments screenshot.

Currently this only works for hero and thumbnail cards, and the emulator just renders a horizontal scrollbar which flips between each card (i.e., as opposed to a smooth scroll).

Summary

In this article I’ve shown you the various response types available to developers in the botframework with an example implementation for each type.

The possibilities for this are already numerous; you could implement a bot which could have a simple “conversation” with a user, create a carousel of products (hero/thumbnail) with click or tap actions which could add products to a cart (maybe..), give the user a receipt, and have them authenticate via a sign in card.

The concepts are there, and it’s certainly promising.

Have a play, let me know how you get on!

Create your first botframework bot in Azure!

At //Build 2016 Microsoft unleashed something known as the Bot Framework; a set of three products to help you build conversational bots and connect them with services, like Slack, Skype, and even Email and SMS.

The Bot Framework has a number of components including the Developer Portal, Bot Builder, and the Bot Directory:

  • Developer Portal is where you wire your bot up to existing services like Skype and Slack
  • Bot Directory is where you publish your bot to so that others can search for and connect it to their Skype and Slack
  • Bot Builder is what you use to implement a more complex and intelligent conversational flow, optionally leveraging the awesome power of some of the Microsoft Research’s Cognitive Services for language interpretation, image recognition, and much more.

In this article I’m going to take you through the process of creating, deploying, and configuring your own Skype bot.

Bots

As far as some people are concerned, “bots” are the new “apps”; before too long every company will have to offer their own bot for some reason or another.

Concept of conversational bots is not new; nerds of my age or similar will no doubt be aware of ELIZA, a conversational bot with no intelligence as such, just giving semi-canned responses to input such as a cheap psychotherapist might do. Great fun though.

This sort of bot paved the way for significantly more complex human language-based interaction, having possibly been the first computer to “pass” the Turing Test!

ChatOps

The term ChatOps has been credited to GitHub following them unleashing Hubot on the tech world; a conversational bot which allowed members of github to interrogate and even update their various systems without leaving their chatroom.

The benefits of this are numerous, such as avoiding a second class citizen “admin” web interface for “backoffice” tasks. These “admin” sites never get as much development and refactoring time as your core product might, falling behind and eventually becoming a hindrance to the team.

Another key feature is the log of the conversation between the team and the bot, allowing for a simple audit log should the conversation include deployment or outage investigations.

Hubot

hubot

Hubot is a nodejs project from GitHub – open source, naturally – with coffeescript (“a little language that compiles into JavaScript”) “commands”, making it extremely simple to extend with your own commands.

I’ve previously deployed a hubot instance (called MrBot..) to heroku, with coffeescript commands to hook into a TeamCity instance’s API to trigger and report on builds and kick off deployments to Azure, through to querying an API in Azure to inspect diagnostic logs and report on system performance.

Being able to implement this all within the context of a conversation in hipchat or Slack was extremely natural and gave a cohesive experience.

botframework

This brings me back to the newly unleashed botframework. Now it’s even easier than ever to create your own conversational bot, deploy it, and connect it to various services.

So that’s what we’re going to do. Get comfy.

Install prerequisite software

In order to use the botframework you’re going to need to make sure you’re running an up to date Visual Studio with all the latest bells and whistles:

  • Visual Studio 2015 Update 3 (if you use Community edition, like me, you may find the Update 3 download actually tries to install Update 2; instead, just go to “Add or Remove Programs”, select Visual Studio > Modify and you’ll be able to install Update 3 from there)
  • Update all VS extensions to their latest versions:
    • Open Visual Studio > Tools > Extensions and Updates > Updates > the lot.
  • Download and install the Bot Application template; this gives you a new project type in Visual Studio:
    • http://aka.ms/bf-bc-vstemplate
    • Save the zip file to your VS templates directory, usually something like: “%USERPROFILE%\Documents\Visual Studio 2015\Templates\ProjectTemplates\Visual C#\”

Create your first bot

Exciting stuff, eh?

  • Open Visual Studio
  • Make sure you have “Create new git repository” selected, since we’ll be deploying to Azure using git
  • Create a new C# project using the new Bot Application template:

bot framework visual studio new project

Take a moment to check out what’s been created in Visual Studio from that new project template. There’s very little code; just a few config files, a mainly blank default.htm page, and a MessagesController class with an interesting using at the top:

using Microsoft.Bot.Connector;

And a nice auth attribute on the controller class:

[BotAuthentication]

Inside that MessagesController class is an interesting method:

public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
    if (activity.Type == ActivityTypes.Message)
    {
        ConnectorClient connector = 
            new ConnectorClient(new Uri(activity.ServiceUrl));

        // calculate something for us to return
        int length = (activity.Text ?? string.Empty).Length;

        // return our reply to the user
        Activity reply = 
            activity.CreateReply($"You sent {activity.Text} which was {length} characters");
        await connector.Conversations.ReplyToActivityAsync(reply);
    }
    else
    {
        HandleSystemMessage(activity);
    }
    var response = Request.CreateResponse(HttpStatusCode.OK);
    return response;
}

The ServiceUrl is the system that’s currently calling the bot endpoint; e.g., Skype or Slack.

Other than that, it’s pretty sparse:

vs new bot framework project

So we’ve created a .Net Web API with some special authorisation implementation, and an endpoint to which all messages (Activitys) are sent.

There are various activity Types, for events such as your bot or another user joining or leaving a conversation, your bot or another user joining or leaving a group conversation (all of which are grouped under the ActivityTypes.ConversationUpdate type, the bot being added to or removed from a user’s contacts list (ActivityTypes.ContactRelationUpdate), knowing that the user is typing (ActivityTypes.Typing – now come on; this is cool!), and a couple of others.

This is where we’ll do all our cleverness; we’ll implement some message parsing logic in a new class and call it in here – we could even have this call a completely different API, using the “bot” merely as a basic web host with authorisation, and single entry point; we could potentially deploy this bot only once and leave it alone.

The botframework SDK allows for some complex conversation models, and I’ll go into this in another article.

Let’s come back to this concept shortly. First up, I’m going to show how to run, test, deploy, and connect to services. Which is really cool.

Locally running and debugging

You’re still in Visual Studio, so let’s hit F5 to run and debug:

Run and debug the bot framework in Visual Studio

Bot Framework Channel Emulator

It’s easy to test this endpoint by using the Bot Framework Channel Emulator; a simple “Click Once” application from Microsoft. Since it’s a Click Once app, it will auto update when necessary. Very handy.

Once your bot/web api is running locally, open up the Bot Framework Emulator, and enter the following details:

  1. Bot Url: this will be localhost:<port>/api/messages – just grab the port from the browser window you launched when F5-ing the project
  2. Microsoft App Id: when testing locally, leave this blank; when testing a remote endpoint, use the Mirosoft App Id you’re given (we’ll get on to this shortly)
  3. Microsoft App Password: same as above; leave blank for local testing, or use the value you’re given from your bot dashboard (later)

If you’ve not made any code changes to the default project you should be able to type in a message at the box at bottom of the emulator and see a response letting you know the length of the message you just entered, along with the JSON for that response in the window on the right of the emulator.

testing locally with the bot emulator

Notice the full JSON response in the right side window; lots of interesting data in there…

Deploying to Azure

Now that we’ve got a “working” bot, it’s time to set it free into the big wide world so we can connect it to other services and start to see the real potential; once this step is done, updating with new functionality will be extremely easy.

The tutorial on the botframework website shows you how to use Visual Studio’s “Publish” functionality to deploy to Azure; I really don’t like this since it’s not supporting anything other than a single developer, with no support for collaboration and no “gates” to deployment – i.e., automated tests.

I’m going to implement a basic separation of these concerns (which I’ll expand on in a subsequent article by introducing a CI server to run tests before allowing us to deploy) using git.

git commit -am “It’s ALIVE!”

I love git. Git git git yum yum yum in my tum. Or something. So I’m going to use this as the deployment initialisation mechanism.

Given .Net Core runs on pretty much OS these days, we could deploy this anywhere; however, the bot requires HTTPS – as any web-based system should – and Azure gives this to you for free (unlike Appharbor, for example), so that’s my host of choice.

Aside: if you try to run your bot over HTTP from a remote endpoint you’ll get an error:

bot running over http gives a warning

Set up Azure

Create the new web app/app service (same thing)

  1. Go to portal.azure.com
  2. If you don’t already have an account, create one; I’ll not go into the detail of doing that here
  3. Select “New Web App” and click “Create”:
    Azure new web app

Configure deployment from git

  1. Once that’s finished creating it, select “Deployment Source” (under Settings > Publishing > Deployment Source) and choose “local git”
  2. Once that’s done, go to the “Essentials” view of your web app, get the git repo endpoint, and set a password for your deployment user (if you haven’t already)
  3. Set up a new git remote either from within Visual Studio’s Team Explorer window, or the command prompt, like:
    • git remote add azure <paste in your azure git repo url here>
    • git push azure master
    • Enter the deployment user’s password and away you go:
remote:   Copying all files to temporary location below for package/publish:
remote:   D:\local\Temp\8d3a8421b0c42a4.
remote: KuduSync.NET from: 'D:\local\Temp\8d3a8421b0c42a4' to: 'D:\home\site\wwwroot'
remote: Copying file: 'Web.config'
remote: Finished successfully.
remote: Running post deployment command(s)...
remote: Deployment successful.
To https:[email protected]:443/rposbo-botframework-demobot.git
   e16b753..9dac446  master -> master

Notice how the git push command is reporting on the actual deployment into Azure? How cool is that?

Testing in Azure
You can’t! At least, you can’t yet. We currently don’t have a valid MicrosoftAppId and MicrosoftAppPassword, remember? They’re still blank in our web.config! Before we can actually use this remotely deployed bot we need to get some valid credentials by registering it with the Microsoft Bot Framework.

Registering with the Microsoft Bot Framework

Head over to https://dev.botframework.com/, click Register a Bot.

Fill in a name and a “bot handle” – this will be your BotId in your web.config – and paste in your Azure endpoint + “/api/messages/” for the “Messaging endpoint” section.

Then click “Create Microsoft App ID and Password” to open up a new tab and log in with your Microsoft (Live/whatever it’s called now) details to see your already configured apps.

Click “Add an app”, give it a name, and on the next screen you’ll see your Microsoft App ID; paste this back in the bot registration page AND in your web.config as the MicrosoftAppId.

Click “Generate new password” and paste this in your web.config as the MicrosoftAppPassword

Finish the rest of this form, click “Register” and whilst you’re waiting for that to finish you can git push your new web.config up to Azure – make sure you’ve filled in your BotId, MicrosoftAppId, and MicrosoftAppPassword! Go on then.. get git pushing!

Say hello to your new friend!

You should now be back in your dev portal with your new bot listed and showing as already being connected to Skype!

Click that “Add to Skype” link..

And have a “chat”:

When you send your first message it may take a few seconds to get a response, but subsequent ones should be quicker.

You just had a chat with your very own Skype Conversational Bot! How cool is that?

Summary

Where do we go from here? You could connect your bot to other services if you have the prerequisites for that service, such as Facebook Messenger, SMS (Twilio) or Slack.

You could start to develop cleverness around parsing the content of the message, and responding appropriately.

You could investigate the various types of responses that are available, such as:

  • attachment – have an inline file or image with your message
  • hero – a “card” with header, subheader, image, and button
  • thumbnail – like a hero, but the image is smaller and to one side
  • receipt – a product listing with images, descriptions, and prices, with a subtotal and total!

You could check out carousels of response cards and combine everything into one giant reply!

Pretty cool, right? Have a go and let me know how you get along.

Unit Testing Powershell with Pester

I write a lot of Powershell these days; it’s my go-to language for quick jobs that need to interact with external systems, like an API, a DB, or the file system for example.

Nothing to configure, nothing to deploy, nothing to set up really; just hack a script together and run it. Perfect for one-off little tasks.

I’ve used it for all manner of things in my career so far, most notably for Azure automation back before Azure had decent automation in place. We’re talking pre-Resource Manager environment creation stuff.

I would tie together a suite of separate scripts which would individually:

  • create a Storage account,
  • get the key for the Storage account,
  • create a DB instance,
  • execute a DB initialisation script,
  • create a Service Bus,
  • execute a Service Bus initialisation script,
  • deploy Cloud Services,
  • start/stop/restart those services

Tie that lot together and I could spin up an entire environment easily.

powershell_azure_createdb

Continue reading

Save 24% With The Last Frontier of Minification: HTML!

As a web developer, front end developer, or web performance enthusiast (or all of those), it’s likely that you’re already minifying your JavaScript (or uglifying it) and most likely your css too.

Why do we do this?

We minify specifically to reduce the bytes going over the wire; trying to get our websites as tiny as possible in order to shoot them through the internet faster than our competitor’s.

We obsess over optimising our images, carefully choosing the appropriate format and tweaking the quality percentage, hoping to achieve the balance between clarity and file size.

So we have teeny tiny JavaScript; we have clean, minified, uncssed css; we have perfectly small images (being lazy loaded, no doubt).

So what’s left?…

The ever-overlooked … HTML minification!

Thats right! HTML! BOOM!

Seriously though; HTML may be the one remaining frontier for optimisation. If you’ve covered off all the other static files – the css, js, and images – then not optimising html seems like a wasted opportunity.

If you view the source of most websites you visit you’ll probably find line after line of white space, acres of indents, reams of padding, novels in the forms of comments.

Every single one of these is a wasted opportunity to save bytes; to squeeze the last few bits out of your HTTP response, turning it from a hulking oil tanker into a zippy land speeder.

Continue reading

Getting Browser Location in Chrome and Deprecating Powerful Features on Insecure Origins

A while ago I created the most useful web page I’ve ever written; an extremely basic page to list the bus arrival times, based on your current location anywhere in London!

I have used this page several times a day on an almost daily basis since I created it, as does my wife; every morning we need to know when the next bus will arrive near our house in order to know when to rush out with our children to take them to school.

I used it every morning to check if I needed to rush out the door to catch the rare “express” bus that would get me to the tube much quicker than the usual one.

I discovered just how useful it is whilst in a pub, deciding whether I had time for another drink before heading home; a quick glance at my phone and I could find out that the next bus home wasn’t for 20 minutes – plenty of time!

However, recently it stopped working for me. It still worked just fine on my wife’s iPhone (and hence Safari), but not on my Nexus (Chrome). It works on my laptop too, or at least appeared to.

So what’s going on?

Continue reading

Lazy Loading Images? Don’t Rely On JavaScript!

So much of the internet is now made up of pages containing loads of images; just visit your favourite shopping site and scroll through a product listing page for an example of this.

As you can probably imagine, bringing in all of these images when the page loads can add unnecessary bloat, causing the user to download lots of data they may not see. It can also make the page slow to interact with, due to the page layout constantly changing as new images load in, causing the browser to reprocess the page.

One popular method to deal with this is to “Lazy Load” the images; that is, to only load the images just before the user will need to see them.

If this technique is applied to the “above the fold” content – i.e., the first average viewport-sized section of the page – then the user can get a significantly faster first view experience.

So everyone should always do this, right?

Before we get on to that, let’s look at how this is usually achieved. It’s so easy to find a suitable jQuery plugin or angularjs module that a simple install command later and you’re almost done; just add a new attribute to image tags or JavaScript method to process the images you want to delay loading for.

So surely this is a no-brainer?

Continue reading

Client Hints in Action

Following along from my recent post about responsive images using pure HTML, this post is about the more server-centric option. It doesn’t answer the art direction question, but it can help reduce the amount of HTML required to implement fully responsive images.

Client hint example site

If you are aware of responsive images and the <picture> element, you’ll know that the code required to give the browser enough choices and information in order to have it request the correct image can be somewhat verbose.

This article will cover the other side of the story, allowing the server to help with the decision of which image to show and ultimately greatly reducing the HTML required to achieve responsive images

Continue reading