Documentation

Bot composition

To get started with InterBot, lets understand the operators

Operator Operator Name Definition
@ Dereference

This operator is used to dereference a Bot

Usage : @A where A is Bot.

= assign

This operator is used to compose a composite bot. User's can assign a botname to a concatenated set of bots.

Usage: @C = @A | @B

Here, @C is a composite bot of 2 bots A & B concatenated serially.

| IO

The pipe operator is an input-output operator. This operator is used concatenate bots serially, where the input to the next bot is the output of the previous bot.

Usage: @D = @A | @B | @C

Bot D is a composed of Bot A, B & C.


Let's walkthrough an example of how to use the operators and create a bot on InterBot

Assume you have an existing online pizza bot that understands English input and responds to its customers in English too. If the Bot had to cater to Spanish speaking audience, then you would have to build a separate Spanish pizza bot for your Spanish customer base.

With InterBot, you can connect 2 bots to your pizza bot, one that translates Spanish input to English output and then the reverse, English input to Spanish output, and voila! You have your Spanish Pizza bot. This is a classic InterBot usecase.

Hence, the Spanish pizza bot will comprise of 3 bots:

  1. @pizzabot (Pizza ordering bot) - This bot the takes the pizza orders in english

  2. @eng2spbot (English to spanish translator bot) - This bot translates english text inputs to spanish text output

  3. @sp2engbot (Spanish to English translator bot) - This bot translates spanish text input to english text output

To compose your Spanish pizza Bot, you would connect the pizza bot between them. The English output of the spanish to English bot would go as input to the pizza bot and the English output of the pizza bot will be input to the English to spanish bot. Hence, your construct would be:

Spanishpizzabot = spanishtoenglish bot + pizzabot + englishtospanish bot

In the InterBot Console, you would type

 >  @spanishpizzabot = @sp2engbot | @pizzabot | @eng2spbot

where @spanishpizzabot is ournew Spanish pizza bot, created on InterBot.

Here's how the messages would flow between the bots.

  1. The @spbot sends the Spanish text message to the @sp2engbot. Let's say the user says 'Hola'

  2. The @sp2engbot takes the Spanish input 'Hola' and translates it to english & gives it to the @pizzabot as 'Hello'

  3. The @pizzabot responds in English with "Size of pizza?" & gives this as input to the @eng2spbot.

  4. The @eng2spbot translates the english input to spanish "tamano de la pizza?" and responds back to the @spanishpizzabot

  5. The @spanishpizzabot passes this message to the user


Bot development - Send and receive a message via Interbot

Interbot (IBC) is a messaging channel to bots to communicate with other bots. It is built on a set of public APIs that enable bot to bot communication. This guide will illustrate how you can create a bot on Gupshup and use the Interbot APIs to send and receive a message from another bot. The APIs you will need to use are:

  • POST /bot/{botname}/enableIBC
  • POST /bot/{botname}/refid
  • POST /bot/{botname}/sendmsg

The base URL for Interbot APIs is: https://ibc.interbot.cc/ibc/

In addition you will also need to use the Gupshup Send Message API

  • POST /sm/api/bot/{botname}/msg

The base URL for the Gupshup API is https://api.gupshup.io


1. Create a bot on Gupshup

Creating a bot on Gupshup is covered in extensive details in our documentation here. For this example let's create a bot that translates any text to English using a translation API. We shall name it ‘translateBot’. This the bot that will receive and subsequently reply to messages. For translateBot to talk to other bots it has to be IBC enabled.

Use the enableIBC API on the Interbot API page. Enter the botname as ‘translateBot’ and hit Submit. A HTTP status of 200 indicates that the bot is now IBC enabled.

We shall create another bot to communicate with ‘translateBot’. Go to the Gupshup dashboard and create a new bot named ‘utilityBot’. The user is going to interact with utilityBot which in turns communicates with translateBot. What the user sees is the output of translateBot.


2. The IBC sendmsg API

  • POST /bot/{botname}/sendmsg

Before we start writing code, let’s take a look at the sendmsg API. The API has 4 required parameters and 1 optional parameter:

  • apikey: Your API key on Interbot. It is usually auto-filled but you can find it on the top right corner of the Interbot portal, when you click on your user profile pic.
  • botname: The name of the bot that is sending out the message to another bot. In this case it will be ‘utilityBot’.
  • destbotname: The name of the bot to be communicated with. Here the destbotname is 'translateBot'
  • refid: The reference ID. Each message has a unique refid. We have an API that generates refid for every message.
  • message: The message to be sent to the destination bot.

This API’s response returns a status code of 200 if successful.

In our ‘utilityBot’, we will make a call to the IBC sendmsg API using the above parameters, after generating a refid. To generate a refid, we shall use the refid API:

  • POST /bot/{botname}/refid

This API's response body contains the refid that you will use. Here's the code to generate a refid:

var botName = "utilityBot"; 
var envurl = "https://ibc.interbot.cc/ibc/bot/";
var apikey = "790o50cf98f646b1c6d5985xx2d1d446";

function generateRefid(cb){
    var url = envurl+botName+'/refid';
    var headers = {
        'content-type': 'application/x-www-form-urlencoded',
        'apikey': apikey
    }
    context.simplehttp.makePost(url, "", headers,cb);
}

Whenever a user sends a message, it has to be passed on to the destination bot. Thus in the messageHandler() method, we shall first generate a refid and then make a call to the sendmsg API. Once that is done, we will store the refid (for use later) and then make a call to the IBC sendmsg API. Here'’'s how the messageHandler() function will look:

function MessageHandler(context, event) {
    var _event = event;
    var _context = context;
    generateRefid(function(context,event){
        var refid = String(event.getresp);
        context.simpledb.botleveldata[refid] = JSON.stringify(_event.contextobj);
        context.simpledb.saveData(sendIBCMessage(context,destbotname,refid,_event.message));
    }); 
}
function generateRefid(cb){
    var url = envurl+botName+'/refid';
    var headers = {
        'content-type': 'application/x-www-form-urlencoded',
        'apikey': apikey
    }
    context.simplehttp.makePost(url, "", headers,cb);
}

function sendIBCMessage(context,recipientName,refid,message) {
    context.console.log("Inside sendIBCMessage : message : "+message);
    var url = envurl+botName+'/sendmsg';
    var headers = {
        'content-type': 'application/x-www-form-urlencoded',
        'apikey': apikey
    }
    var formData = 'refid=' + refid + '&message=' + message+'&destbotname='+recipientName;
    context.simplehttp.makePost(url, formData, headers);
}

3. Receive messages from a bot

Assume the user sent 'utilityBot' a message with the words 'Hola Amigo'. In the above code, this message is then sent from 'utilityBot' to 'translateBot' which is programmed to reply with an English translation. This message is relayed back to 'utilityBot' through the messageHandler() function. Any message that is a reply to an IBC message will have the event.contextobj.channeltype = 'ibc'. Also, the refid and the event.contextobj will be unique. The refid and the contextobj has to be verified before the Gupshup Send Message API is used.

var channelName = event.contextobj.channeltype;
    var senderName = event.senderobj.channelid;
    if(channelName == "ibc"){
        var refid = event.contextobj.refid;
        var userContextStr = context.simpledb.botleveldata[refid];
        var userContext = JSON.parse(userContextStr);
        delete context.simpledb.botleveldata[refid];
        context.simpledb.saveData(sendMsg(context,userContextStr,event.message));
}

[Do note that the Gupshup Send Message API is different from the IBC sendMsg API]

Here are the details of the Gupshup Send Message API:

  • POST /sm/api/bot/{botname}/msg

The API has 3 parameters which are all required. Here are the details:

  • botname: The name of the bot that you are sending a message to.
  • context: The context object
  • message: The message to be sent
function sendMsg(context,userContext,message){
    var url = botenvurl+botName+'/msg';
    var headers = {
        'content-type': 'application/x-www-form-urlencoded',
        'apikey': apikey
    }
    var formData = 'context=' + userContext + '&message=' + message+"&bypass=false";
    context.simplehttp.makePost(url, formData, headers);
}

4. Putting it all together

Now that we have seen how you can send and receive messages from another bot, we can put all this code together. You can of course communicate to different bots based on your requirement. Below is the entire code for the processes described above:

/** This is a sample code for your bot**/
var apikey = "798ae0cf98f646b1c6dxxxx446";
var botName = "utilityBot"; 
var envurl = "https://ibc.interbot.cc/ibc/bot/";
var botenvurl = "https://api.gupshup.io/sm/api/v1/bot/";
var destbotname = "translateBot";

function MessageHandler(context, event) {
    var channelName = event.contextobj.channeltype;
    var senderName = event.senderobj.channelid;

    if(channelName == "ibc"){
        var refid = event.contextobj.refid;
        var userContextStr = context.simpledb.botleveldata[refid];

        var userContext = JSON.parse(userContextStr);
        delete context.simpledb.botleveldata[refid];
        context.simpledb.saveData(sendMsg(context,userContextStr,event.message));

    }else{
        var _event = event;
        var _context = context;
        generateRefid(function(context,event){
            var refid = String(event.getresp);
            context.simpledb.botleveldata[refid] = JSON.stringify(_event.contextobj);
            context.simpledb.saveData(sendIBCMessage(context,destbotname,refid,_event.message));
        }); 
    }
}

function generateRefid(cb){
    var url = envurl+botName+'/refid';
    var headers = {
        'content-type': 'application/x-www-form-urlencoded',
        'apikey': apikey
    }
    context.simplehttp.makePost(url, "", headers,cb);
}

function sendIBCMessage(context,recipientName,refid,message) {
    context.console.log("Inside sendIBCMessage : message : "+message);
    var url = envurl+botName+'/sendmsg';
    var headers = {
        'content-type': 'application/x-www-form-urlencoded',
        'apikey': apikey
    }
    var formData = 'refid=' + refid + '&message=' + message+'&destbotname='+recipientName;
    context.simplehttp.makePost(url, formData, headers);
}

function sendMsg(context,userContext,message){
    context.console.log("Inside sendMsg : message : "+message);

    var url = botenvurl+botName+'/msg';
    var headers = {
        'content-type': 'application/x-www-form-urlencoded',
        'apikey': apikey
    }
    var formData = 'context=' + userContext + '&message=' + message+"&bypass=false";
    context.simplehttp.makePost(url, formData, headers);
}


/** Functions declared below are required **/
function EventHandler(context, event) {

}

function HttpResponseHandler(context, event) {

}

function DbGetHandler(context, event) {
    //context.sendResponse("testdbput keyword was last get by:" + event.dbval);
}

function DbPutHandler(context, event) {
    //context.sendResponse("testdbput keyword was last put by:" + event.dbval);
}

We've hosted some use cases & Bot code snippets on Github. This will help developers to quickly get started with building their first InterBot bots. Check it out at https://github.com/GupshupBot/InterBot


Error messages (Displayed in the shell)

  1. Not Bot Owner - This message is displayed when user is trying to compose a bot with name that is already exists on InterBot

  2. Botname should be more than 5 characters - This message is displayed when Botname is less than 5 characters

  3. Mapped bot <botname> does not exist - This message is displayed when the bot being used in composing a new bot, does not exist)

  4. Invalid Format - Message displayed when the compose syntax is incorrect.



function MessageHandler(context, event) { } function EventHandler(context, event) { } function HttpResponseHandler(context, event) { } function DbGetHandler(context, event) { } function DbPutHandler(context, event) { }
function MessageHandler(context, event) { var channelName = event.contextobj.channeltype; var senderName = event.senderobj.channelid; context.console.log("refid : "+refid+" ; senderName : "+senderName); var ibcbots = botmap.split("|"); var position = ibcbots.indexOf("@"+senderName); var nextBot = ibcbots[position+1] var lastBot = ibcbots[ibcbots.length-1].replace(/@/g,""); context.console.log("nextBot : "+nextBot); if(channelName == "ibc"){ var refid = event.contextobj.refid; if(position < 0 && senderName!=botName){ //IBC Init Point if(!context.simpledb.botleveldata[refid]){ context.simpledb.botleveldata[refid]=senderName; context.simpledb.saveData(sendIBCMessage(context,ibcbots[0].replace(/@/g,""),refid,event.message)); }else{ delete(context.simpledb.botleveldata[refid]) return; } }else if(nextBot){ sendIBCMessage(context,nextBot.replace(/@/g,""),refid,event.message); }else{ recBotname = context.simpledb.botleveldata[refid]; try{ var userContext = JSON.parse(recBotname); delete context.simpledb.botleveldata[refid]; context.simpledb.saveData(sendMsg(context,recBotname,event.message)); }catch(err){ delete context.simpledb.botleveldata[refid]; context.simpledb.saveData(sendIBCMessage(context,recBotname,refid,event.message)); } } }else{ var _event = event; var _context = context; generateRefid(function(context,event){ var refid = String(event.getresp); context.simpledb.botleveldata[refid] = JSON.stringify(_event.contextobj); context.simpledb.saveData(sendIBCMessage(context,ibcbots[0].replace(/@/g,""),refid,_event.message)); }); } } function generateRefid(cb){ var url = envurl+botName+'/refid'; var headers = { 'content-type': 'application/x-www-form-urlencoded', 'apikey': apikey } context.simplehttp.makePost(url, "", headers,cb); } function sendIBCMessage(context,recipientName,refid,message) { var url = envurl+botName+'/sendmsg'; var headers = { 'content-type': 'application/x-www-form-urlencoded', 'apikey': apikey } var formData = 'refid=' + refid + '&message=' + message+'&destbotname='+recipientName; context.simplehttp.makePost(url, formData, headers); } function sendMsg(context,userContext,message){ var url = botenvurl+botName+'/msg'; var headers = { 'content-type': 'application/x-www-form-urlencoded', 'apikey': apikey } var formData = 'context=' + userContext + '&message=' + message+"&bypass=true"; context.simplehttp.makePost(url, formData, headers); } /** Functions declared below are required **/ function EventHandler(context, event) {} function HttpResponseHandler(context, event) {} function DbGetHandler(context, event) {} function DbPutHandler(context, event) {}