Deploy SUSI.AI to a Messenger

Integration of SUSI AI to messenger platform has become a vital step as to enhance the popularity of this chatbot and to target a large base of users. For example – Viber claims that it has a user base of 800 million. So just integrating SUSI AI to Viber can increase its user base exponentially. This integration also proves to be a big boon, if the chat bot learns with the number and variations in the questions being asked. Like in the case of the web chat client (Susi AI).

This blog post will walk you through on how to deploy SUSI.AI to a messenger platform (Viber and Line messengers are used as an example in this post). We will be using Node.js and REST API technology in our example integrations. The repository of deployment of Susi AI to Viber can be found at susi_viberbot, and to Line messenger at susi_linebot. The SUSI AI Viberbot can be followed from here and Linebot by scanning this QR code.

The diagram below will give you an overview on what flow is followed to deploy SUSI AI chatbot to various messenger platforms.

Fig: Integration of Susi AI to chat messengers.

Let’s walk through each of the steps mentioned in the above diagram.

  1. To get familiar with SUSI.AI chatbot.

We have an API from where we fetch answers. To get a reply for the query ‘hi’, we can visit the API link with the query ‘hi’ appended to it (http://api.susi.ai/susi/chat.json?q=hi). You can chat with SUSI AI here.

  1. To set up a private SUSI AI chatbot account.

A account must be set up in the messenger platform, so that the user can message in that account to get a reply by the chatbot. Steps to set up the chatbot account is dependent on the messenger platform.

  1. To set up a webhook url.

The message sent to the chatbot account, must somehow connect to the chatbot. This message can be fed as a query to the chatbot, so that accordingly chatbot can think of a reply. To achieve this we need a url referred to as the webhook url.

The messages sent by the user, to the SUSI AI chatbot account on the messenger, can then be redirected to this url.

(Heroku platform allows 5 apps to be hosted on its platform for free, so you can check this documentation on how to host a node js app there.)

Now we need to think on how to handle these messages.

  1. To host code on our webhook url

As said earlier, we will be using Node js technology.

Generally, the messages from our SUSI AI chatbot account on the messenger will travel as requests to our webhook url. These come as POST requests to our url. To handle that we can use this piece of code:

app.post('/', function(request, response) {
    response.writeHead(200);

    // first step here, getting the message string from the request body

    // second step, calling the chatbot to get the reply to this message

    // third step, to send this reply back to our messenger's API
    
    response.end();
}

Let’s go through the three steps:

  • Getting the message string from the request body:

Request body is in JSON in case of REST API. To be extra sure, we use:

var reqBody = JSON.parse(request.body);

What property of this reqBody has our message string is dependent on the messenger platform. Suppose we have our message in the actions property of the reqBody, we can access that by:

var message = reqBody.actions;

For example in Viber, we need to use this piece of code:

app.post('/', function(req, response) {
    response.writeHead(200);

    // If user sends a message in 1-on-1 chat to the susi public account
    if(req.body.event === 'message'){
        // call chatbot or it’s API with event.message.text as the message string.
    }
}

In Line messenger, we accept the request at ‘/webhook’:

// register a webhook handler with middleware
app.post('/webhook', line.middleware(config), (req, res) => {
  // here events property has our message string somewhere nested in it.
  Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

// event handler
function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
      // ignore non-text-message event
      return Promise.resolve(null);
  }
  // call chatbot API with event.message.text as the query string.
}

So the code is dependent on the messenger platform.

  • Calling the SUSI AI chatbot API to get the reply to this message(‘hi susi’ in this case).

This part of our code will remain constant, for any messenger platform.

Let’s first see SUSI API’s answer to query “hi susi” and get familiar with it. Visit http://api.asksusi.com/susi/chat.json?q=hi susi from the browser and get familiar with the JSON object returned.

We get a JSON object as follows:

The answer can be found as the value of the key named expression. In this case it is “Hi, I’m Susi”.

To fetch the answer through coding, we can use this code snippet in Node js:

// including request module
var request = require(‘request’);

// setting options to make a successful call to Susi API.
var options = {
    method: 'GET',          
    url:'http://api.asksusi.com/susi/chat.json',
    qs:
    {
        timezoneOffset: '-330',
        q:'hi susi'
    }
};

// A request to the Susi bot
request(options, function (error, response, body) {
    if (error)
        throw new Error(error);
    // answer fetched from susi
    ans = (JSON.parse(body)).answers[0].actions[0].expression;
}

The properties required for the call are set up through a json object (i.e. options). Pass the options object to our request function as its first parameter. The response by the API will be stored in ‘body’ variable. We need to parse this body, to be able to access the properties of that body object. Hence, fetching the answer from Susi API.

  • To send the answer fetched from our SUSI API, back to our messenger.

This feature too is dependent on the messenger platform. Initially as the messenger platform requests us with a request which has the user message string. Now, it’s our time to send a request back to our messenger platform with a reply(i.e. the answer we will fetch from our chat bot’s API).

Generally, it is sent as a POST request.

The basic code to send a message to the messenger API:

// Assuming ans variable has the reply by our chatbot.
// setting options to request the chat api of viber.
var options1 = {
    method: 'POST',
    url: MESSENGER_API_URL,
    headers: headerBody,
    body:
    {
        // other properties dependent to the messenger
        text: ans
        // the property name can be different from 'text'
    },
    json: true
};

// request to the api of messenger.
request(options1, function (error1, res, body1) {
    if (error1) 
        throw new Error(error1);
    console.log(body1);
});

In case of Viber, we set up an options variable and request Viber’s chat API:

// setting options to request the chat api of viber.
var options1 = {
    method: 'POST',
    url: 'https://chatapi.viber.com/pa/send_message',
    headers: headerBody,
    body:
    {
        receiver: req.body.sender.id,
        min_api_version: 1,
        sender:
        {
            name: 'Susi',
            avatar: ''
        },
        tracking_data: 'tracking data',
        type: 'text',
        text: ans
    },
    json: true
};

// request to the chat api of viber.
request(options1, function (error1, res, body1) {
    if (error1) throw new Error(error1);
        console.log(body1);
});

In case of Line messenger, we use it’s reply API:

const answer = {
    type: 'text',
    text: ans
};

// use reply API
return client.replyMessage(event.replyToken, answer);