Skip to content

Don't Panic! Posts

Microsoft Bot Framework Part 2: Build a bot with Bot Framework SDK

The Microsoft Bot Framework is a flexible framework for building conversational bots. A bot can be written once and deployed to multiple channels including webchat, Microsoft Teams, Alexa and SMS. It supports text, speech and rich GUIs with images and controls.

In this three part series, I’ll register a ‘hello world’ bot application as an Azure Bot Resource and then look at how to customise my bot behaviours. Finally I’ll make it available to a chat widget on a web page, SMS and consume it from a Node.js application.

In the first part, we created an Azure Bot registration and connected to a demo bot application. In this part we’ll swap out the demo bot for one we’ve built using the Microsoft Bot Framework SDK.

Microsoft Bot Framework Part 1: Create an Azure Bot Resource

The Microsoft Bot Framework is a flexible framework for building conversational bots. A bot can be written once and deployed to multiple channels including webchat, Microsoft Teams, Alexa and SMS. It supports text, speech and rich GUIs with images and controls.

In this three part series, I’ll register a ‘hello world’ bot application as an Azure Bot Resource and then look at how to customise my bot behaviours. Finally I’ll make it available to a chat widget on a web page, SMS and consume it from a Node.js application.

In this part, I’ll register and configure a bot with Microsoft Azure Bot Service. It might seem odd to start here rather than going straight into the application code. However, getting this step out of the way gives us something simple to play with that works end to end.

Exception handling in ScheduledExecutorService

Java’s ScheduledExecutorService allows you to schedule Runnable tasks without having to worry too much about creating Threads. At its simplest, you can schedule a task like this:

Runnable task = () -> System.out.println("Hello world!");
executor.schedule(task, 10, TimeUnit.SECONDS);
System.out.println("Done!");

The output is:

Done!
Hello world!

That is we schedule the task, then print “Done!”. 10 seconds later the scheduled task executes and prints “Hello world!”.

But what happens if the Runnable throws an Exception?

The epoch was an hour late

The epoch – midnight on 1st January 1970 – is one of the most important moments in computing. Many systems store dates and times as the number of seconds (or milliseconds) since the epoch. When new year’s revellers counted down the seconds before Big Ben struck twelve for the first time in a new decade, who would have known that the moment would be significant fifty years on?

Except, it didn’t. On the moment that is represented as zero in Unix, C, Java and so many other systems, Big Ben did not strike twelve. At midnight on the 1st January 1970, Big Ben struck one.

Execute Around idiom in Java

The Execute Around idiom is a pattern that allows you to wrap an action with some standard setup / tear down steps. Examples might include:

  • Execute within a lock: acquire the lock, do the action, release the lock
  • Resource handling: acquire the resource, do the action, close the resource
  • Execute as a user: switch to the user, do the action, switch back to the original user
  • Exception handling: do the action, handle the exceptions
  • Time an action: start a timer, do the action, stop the timer

The pattern allows you to pass in arbitrary actions and have them run with the same setup / tear down steps.

Private DNS for Native Windows Docker Container

Docker Windows containers have a number of shortcomings, particularly around networking. One showstopper is that it doesn’t use the DNS of its host server. The expected behaviour in (Linux) Docker containers is that the Docker engine creates a virtual DNS for containers. The Docker DNS resolves containers by name (for Docker Swarm / Docker Compose) or delegates to the host DNS configuration. There are options to override this behaviour if necessary.

Native Windows containers don’t do this. Docker for Windows will resolve container names from the Swarm and will then use the default external DNS (Google DNS on 8.8.8.8) to resolve external addresses. It will not use the host machine DNS settings nor can its behaviour be overridden with the --dns flag. This is a serious problem if your container depends on services within a private / corporate network.

This appears to be an issue with the Docker Windows images (nanoserver / windowservercore) rather than with the engine. Microsoft might get round to fixing it but given its half-hearted support for Docker, it might not.