The Microsoft Bot Framework makes it easy to create a single bot that can run across a variety of messaging channels including Skype, Group.me, Facebook Messenger, Slack, Telegram, Kik, SMS, and email.

Table of Contents

1) Install Botkit more info here

2) Register a developer account with the Bot Framework Developer Portal and follow this guide to register your first bot with the Bot Framework.

3) By default your bot will be configured to support the Skype channel but you'll need to add it as a contact on Skype in order to test it. You can do that from the developer portal by clicking the "Add to Skype" button in your bots profile page.

4) Run the example bot using the App ID & Password you were assigned. If you are not running your bot at a public, SSL-enabled internet address, use the --lt option and update your bots endpoint in the developer portal to use the URL assigned to your bot.

app_id=<MY_APP_ID> app_password=<MY_APP_PASSWORD> node examples/botframework_bot.js [--lt [--ltsubdomain CUSTOM_SUBDOMAIN]]

5) Your bot should be online! Within Skype, find the bot in your contacts list, and send it a message.

Try:

Since the Bot Framework delivers messages via web hook, your application must be available at a public internet address. Additionally, the Bot Framework requires this address to use SSL. Luckily, you can use LocalTunnel to make a process running locally or in your dev environment available in a Bot Framework friendly way.

When you are ready to go live, consider LetsEncrypt.org, a free SSL Certificate Signing Authority which can be used to secure your website very quickly.

To connect Botkit to Bot Framework, use the constructor method, Botkit.facebookbot(). This will create a Botkit controller with all core features as well as some additional methods.

Argument Description
settings Options used to configure the bot. Supports fields from IChatConnectorSettings.

Creates a new instance of the bots controller. The controller will create a new ChatConnector so any options needed to configure the chat connector should be passed in via the settings argument.

Generally speaking your bot needs to be configured with both an appId and appPassword. You can leave these blank but then your bot can only be called by the Bot Framework Emulator.

In addition to the core events that Botkit fires, this connector also fires some platform specific events.

Normal messages will be sent to your bot using the message_received event. In addition, several other events may fire, depending on the channel your bot is configured to support.

Event Description
message_received A message was received by the bot. Passed an IMessage object.
conversationUpdate Your bot was added to a conversation or other conversation metadata changed. Passed an IConversationUpdate object.
contactRelationUpdate The bot was added to or removed from a user's contact list. Passed an IContactRelationUpdate object.
typing The user or bot on the other end of the conversation is typing. Passed an IEvent object.

In addition to the event specific fields, all incoming events will contain both user and channel fields which can be used for things like storage keys. Every event also has an address field. The user field is just a copy of the events address.user.id field and the channel field is a copy of the events address.conversationId.id field.

Other notable fields for incoming messages are the text field which contains the text of the incoming message, the attachments field which would contain an array of any images sent to the bot by the user, the source field which identifies the type of chat platform (facebook, skype, sms, etc.) that the bot is communicating over, and the sourceEvent field containing the original event/message received from the chat platform.

Botkit receives messages from the Bot Framework using webhooks, and sends messages to the Bot Framework using APIs. This means that your bot application must present a web server that is publicly addressable. Everything you need to get started is already included in Botkit.

To connect your bot to the Bot Framework follow the step by step guide outlined in Getting Started.

Here is the complete code for a basic Bot Framework bot:

var Botkit = require('botkit');
var controller = Botkit.botframeworkbot({
});

var bot = controller.spawn({
        appId: process.env.app_id,
        appPassword: process.env.app_password
});

// if you are already using Express, you can use your own server instance...
// see "Use BotKit with an Express web server"
controller.setupWebserver(process.env.port,function(err,webserver) {
  controller.createWebhookEndpoints(controller.webserver, bot, function() {
      console.log('This bot is online!!!');
  });
});

// user said hello
controller.hears(['hello'], 'message_received', function(bot, message) {

    bot.reply(message, 'Hey there.');

});

controller.hears(['cookies'], 'message_received', function(bot, message) {

    bot.startConversation(message, function(err, convo) {

        convo.say('Did someone say cookies!?!!');
        convo.ask('What is your favorite type of cookie?', function(response, convo) {
            convo.say('Golly, I love ' + response.text + ' too!!!');
            convo.next();
        });
    });
});

Argument Description
port port for webserver
callback callback function

Setup an Express webserver for use with createWebhookEndpoints()

If you need more than a simple webserver to receive webhooks, you should by all means create your own Express webserver! Here is a boilerplate demo.

The callback function receives the Express object as a parameter, which may be used to add further web server routes.

This function configures the route https://_your_server_/botframework/receive to receive webhooks from the Bot Framework.

This url should be used when configuring Facebook.

One of the more complicated aspects of building a bot that supports multiple chat platforms is dealing with all the various schemes these platforms support. To help ease this development burden, the Bot Framework supports a cross platform card & attachment schema which lets you use a single JSON schema to express cards and attachments for any platform. The Bot Frameworks channel adapters will do their best to render a card on a given platform which sometimes result in a card being broken up into multiple messages.

The frameworks attachment schema lets you send a single image/file using contentType and contentUrl fields:

    bot.reply(message, {
        attachments: [
            {
                contentType: 'image/png',
                contentUrl: 'https://upload.wikimedia.org/wikipedia/en/a/a6/Bender_Rodriguez.png',
                name: 'Bender_Rodriguez.png'
            }
        ]
    });

Rich cards can be expressed as attachments by changing the contentType and using the content field to pass a JSON object defining the card:

    bot.reply(message, {
        attachments: [
            {
                contentType: 'application/vnd.microsoft.card.hero',
                content: {
                    title: "I'm a hero card",
                    subtitle: "Pig Latin Wikipedia Page",
                    images: [
                        { url: "https://<ImageUrl1>" },
                        { url: "https://<ImageUrl2>" }
                    ],
                    buttons: [
                        {
                            type: "openUrl",
                            title: "WikiPedia Page",
                            value: "https://en.wikipedia.org/wiki/Pig_Latin"
                        }
                    ]
                }
            }
        ]
    });

The full list of supported card types and relevant schema can be found here

There may be times where the Bot Frameworks cross platform attachment schema doesn’t cover your needs. For instance, you may be trying to send a card type not directly supported by the framework. In those cases you can pass a message using the platforms native schema to the sourceEvent field on the message. Examples of this can be found here (note: you should use sourceEvent instead of channelData and you don’t need to worry about the from & to fields, these will be populated for you when you call bot.reply().)

You can easily turn on the typing indicator on platforms that support that behaviour by sending an empty message of type "typing":

    bot.reply(message, { type: "typing" });

Is something missing or out of date?

This file is managed on Github. click here to view the source, and send us a pull request with your improvements!