June 1st, 2017

Deploying bots using the Serverless framework

Introduction

Microsoft recently partnered with the makers of the Whim service to experiment with conversational user interfaces. Whim is a Mobility-as-a-Service (MaaS) solution that allows people to leverage multiple kinds of transportation options with a single monthly fee. The makers of Whim found conversational interfaces interesting in the context of everyday mobility and as an additional interaction channel with their service.

After exploring a few potential end-user scenarios, we decided to start building one of them using the Microsoft Bot Framework. You can see the end result from this video, which shows the basic features of the bot in action within Facebook Messenger.

One of the goals was to integrate the development and deployment of the related components with the existing tools and practices of the company. The implementation of the Whim service is heavily based on serverless computing and leveraging the Serverless framework.

In this code story, we’ll talk about how we made it possible to deploy a Node.js-based bot using the Serverless framework and some challenges we had along the way.

If you’d rather jump directly into the code, the Whim bot can be found on GitHub.

Deployment with Serverless framework

The Serverless framework is a set of tools that make it easier to manage projects targeting serverless runtimes. It supports providers like Azure Functions, AWS Lamba, and Apache OpenWhisk by implementing abstractions and helpers for things like configuration, deployment, and debugging. At a high level, the steps to deploy a serverless project would be something like:

$ npm install -g serverless
$ cd <your-serverless-project>
// edit serverless.yml with your configurations
$ serverless deploy

For more about using the Serverless framework, check out the documentation.

Since the Whim backend was already using the AWS Lambda provider, the initial deployment targeted it. While the Microsoft Bot Framework is agnostic as to where a bot is hosted, we ran into two issues that needed to be fixed before the bot was functioning properly.

The first issue related to the way authorization headers were passed between the systems. You can read more about the issue and our fix on GitHub. Afterward, the requests were properly authenticated and reached the bot code from the Facebook Messenger channel as expected.

The second challenge was the differences between the request and response formats expected by the Serverless framework provider vs. the Microsoft Bot Framework. The basic usage is as follows:

// Setup Restify Server
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function () {
   console.log('%s listening to %s', server.name, server.url); 
});
  
// Create chat connector for communicating with the Bot Framework Service
var connector = new builder.ChatConnector({
    appId: process.env.MICROSOFT_APP_ID,
    appPassword: process.env.MICROSOFT_APP_PASSWORD
});

// Listen for messages from users 
server.post('/api/messages', connector.listen());

You can see that what connector.listen() returns above is directly given as a handler for the server created with the Restify framework. There is an assumption about what kind of request is passed to the bot framework code and how the bot framework code indicates when processing of the request has completed.

Restify uses common request and response APIs that, for example, the popular Express framework supports. However, this format isn’t what serverless providers like AWS Lambda use.

Even though the format is not exactly the same, the concept is. As a result, it is possible to implement a small “glue code” in between the components to achieve the desired functionality. You can see this solution in an example from the AWS Lambda case.

Other challenges

User authentication

The Whim API requires two-factor authentication before the bot can interact with it. The goal was to make the authentication as easy as possible and make it feel well integrated into the overall Facebook Messenger experience.

For that, we leveraged the Facebook Messenger Account Linking API through the Microsoft Bot Framework by using channel-specific messages. You can read full details in this blog post.

Determining location

User location is at the core of the Whim service, so we paid specific attention to how we could provide the best location picking experience within Facebook Messenger. We achieved it by combining the suggested location from the service with the native location picker found within Facebook Messenger. You can see the implementation of this custom dialog on GitHub.

Conclusion

As you can see, we were able to use the Serverless framework to manage a Node.js bot project based on the Microsoft Bot Framework. In addition to managing the core bot project, the same tooling can be used to manage other serverless programs. For example, a bot project could also include an image-processing component that is implemented as a separate “microservice.” The Serverless framework can help in managing all these various pieces and how they are tied together.

To get started deploying your simple bot using the knowledge and mechanisms from this code story, please take a look at the related GitHub repository.


Cover image from Whim.

Author

0 comments

Discussion are closed.