jsonchatbotdialogflow-esfacebook-chatbotgupshup

Maintaining session in Gupshup bot calls to Api.ai


I am building a bot in Gupshup with Api.ai integration. I have an agent in Api.ai with several intents and each of them linked through contexts(input & output contexts). When I use the following code to call Api.ai, the first intent is called and I get the reply. However when the second message is given, the bot takes it as a completely new message, without identifying its relation with first. How can I solve this issue? Kindly help

function MessageHandler(context, event) {
    // var nlpToken = "xxxxxxxxxxxxxxxxxxxxxxx";//Your API.ai token
    // context.sendResponse(JSON.stringify(event));
    sendMessageToApiAi({
        message : event.message,
        sessionId : new Date().getTime() +'api',
        nlpToken : "3626fe2d46b64cf8a9c0d3bee99a9sb3",
        callback : function(res){
            //Sample response from apiai here.
            context.sendResponse(JSON.parse(res).result.fulfillment.speech);
        }
    },context)
}

function sendMessageToApiAi(options,botcontext) {
    var message = options.message; // Mandatory
    var sessionId = options.sessionId || ""; // optinal
    var callback = options.callback;
    if (!(callback && typeof callback == 'function')) {
       return botcontext.sendResponse("ERROR : type of options.callback should be function and its Mandatory");
    }
    var nlpToken = options.nlpToken;

    if (!nlpToken) {
       if (!botcontext.simpledb.botleveldata.config || !botcontext.simpledb.botleveldata.config.nlpToken) {
           return botcontext.sendResponse("ERROR : token not set. Please set Api.ai Token to options.nlpToken or context.simpledb.botleveldata.config.nlpToken");
       } else {
           nlpToken = botcontext.simpledb.botleveldata.config.nlpToken;
       }
    }
    var query = '?v=20150910&query='+ encodeURIComponent(message) +'&sessionId='+sessionId+'&timezone=Asia/Calcutta&lang=en    '
    var apiurl = "https://api.api.ai/api/query"+query;
    var headers = { "Authorization": "Bearer " + nlpToken};
    botcontext.simplehttp.makeGet(apiurl, headers, function(context, event) {
       if (event.getresp) {
           callback(event.getresp);
       } else {
           callback({})
       }
    });
}

/** Functions declared below are required **/
function EventHandler(context, event) {
    if (!context.simpledb.botleveldata.numinstance)
        context.simpledb.botleveldata.numinstance = 0;
    numinstances = parseInt(context.simpledb.botleveldata.numinstance) + 1;
    context.simpledb.botleveldata.numinstance = numinstances;
    context.sendResponse("Thanks for adding me. You are:" + numinstances);
}

function HttpResponseHandler(context, event) {
    // if(event.geturl === "http://ip-api.com/json")
    context.sendResponse(event.getresp);
}

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);
}

Solution

  • The sessionId has to be fixed for a user. There are two ways you can do this in the Gupshup bot code -

    1. Use the unique userID which is sent to the bot for every user. To get this value you can use -

      event.senderobj.channelid

      But this value is dependent on how different messaging channels provides it and api.ai has a limit of 36 characters.

      Sample code -

      function MessageHandler(context, event) {
      sendMessageToApiAi({
          message : event.message,
          sessionId : event.senderobj.channelid,
          nlpToken : "3626fe2d46b64cf8a9c0d3bee99a9sb3",
          callback : function(res){
              //Sample response from apiai here.
              context.sendResponse(JSON.parse(res).result.fulfillment.speech);
           }
         },context)
      }
      
    2. Generate a unique sessionId for each user and store it in the database to utilise it. In the below sample , I am storing the sessionId at roomleveldata which is the default persistance provided by Gupshup, to know more check this guide.

      Sample code -

      function MessageHandler(context, event) {
      sendMessageToApiAi({
          message : event.message,
          sessionId : sessionId(context),
          nlpToken : "84c813598fb34dc5b1f3e1c695e49811",
          callback : function(res){
              //Sample response from apiai here.
              context.sendResponse(JSON.stringify(res));
          }
         },context)
      }
      function sessionId(context){
       var userSession = context.simpledb.roomleveldata.sessionID;
       if(!userSession){
         userSession = new Date().getTime() +'api';
          context.simpledb.roomleveldata.sessionID = userSession;
         return userSession;
       }else{
          return userSession;
       }
      }
      

    Remember that sessionId should not exceed 36 characters.