botmasterai / botmaster-socket.io

The socket.io Botmaster integration
MIT License
8 stars 8 forks source link

Watson conversation context is lost if the client disconnects and reconnects even if botmasterUserId is the same #2

Closed vivekpd15 closed 7 years ago

vivekpd15 commented 7 years ago

Watson conversation context is lost if the client disconnects and reconnects even if botmasterUserId is the same.

I have checked on the server that the botmasterUserId is the same in all cases.

Any idea, what could be going wrong?

jdwuarin commented 7 years ago

That is quite weird. Am I to assume that you are using both botmaster-session-ware and botmaster-watson-conversation-ware?

vivekpd15 commented 7 years ago

Yes. That is exactly my setup. I am using both these modules.

jdwuarin commented 7 years ago

Got it. I'll need some minimal code you've got to replicate the bug as I can't manage to replicate here

vivekpd15 commented 7 years ago
const express = require('express');
var app = express();
const fs = require('fs');
const Botmaster = require('botmaster');
const SocketIoBot = require('botmaster-socket.io');
const SessionWare = require('botmaster-session-ware');
const WatsonConversationWare = require('botmaster-watson-conversation-ware');
const https = require('https');
const bodyParser = require('body-parser');
const cors = require('cors');

app.disable('x-powered-by');
app.use(bodyParser.urlencoded({
  extended: false
}));
app.use(bodyParser.json());
app.use(cors());
const options = {
  key: fs.readFileSync('/usr/local/ssl/key/private.key', 'utf8'),
  cert: fs.readFileSync('/usr/local/ssl/crt/public.crt', 'utf8'),
  ca: fs.readFileSync('/usr/local/ssl/crt/intermediate.crt', 'utf8')
};

const httpsServer = https.createServer(options, app);
httpsServer.listen(8001, function () {
  console.log("SERVER RUNNING AT 8001");
});

const botmasterSettings = {
  // by default botmaster will start an express server that listens on port 3000
  // you can pass in a port argument here to change this default setting:
  server: httpsServer,
  //port: 8001
}

const botmaster = new Botmaster(botmasterSettings);

botmaster.addBot(new SocketIoBot({
  id: 'app-bot',
  server: botmaster.server,
}));

const watsonConversationWareOptions = {
  settings: {
    username: '',
    password: '',
    version: '', // as of this writing (01 Apr 2017), only v1 is available
    version_date: '', // latest version-date as of this writing
  },
  workspaceId: '' // As provided by Watson Conversation
}

// declaring middleware
const watsonConversationWare = WatsonConversationWare(watsonConversationWareOptions);
botmaster.use(watsonConversationWare);

botmaster.on('error', (bot, err) => { // added
  console.log(err.stack); // added
}); // added

botmaster.use({
  type: 'incoming',
  name: 'watson-middleware',
  controller: (bot, update) => {
    if (!(update.hasOwnProperty('watsonUpdate'))) {
      return;
    }
    return bot.sendTextCascadeTo(update.watsonUpdate.output.text, update.sender.id);
  }
});

// This will make our context persist throughout different messages from the
// same user
const sessionWare = SessionWare();
botmaster.useWrapped(sessionWare.incoming, sessionWare.outgoing);
jdwuarin commented 7 years ago

That code works for me when I test it and reconnect. I haven't tried using https however (I'm using http). It could be because of that.

But in general, as long as when in your middleware, you can assess that update.sender.id is the same even after a reconnection, there is no way that the session will be lost.

This means that you're either hitting (independent of your reconnection) a node in your Watson Conversation that resets the context. Or maybe your server is restarting. If you are using a simple MemoryStore that comes in with botmaster-session-ware restarting your server will clear all sessions, as they are stored in memory. One way around that would be to write your own store adapter that stores data in redis or persists it to a database. The general way to write such an adapter is as in the MemoryStore example: https://github.com/botmasterai/botmaster-session-ware/blob/master/src/adapters/MemoryStore.js. Once your adapter class is written, you would create your sessionWare object by doing something like this:

const sessionWare = SessionWare(new YourStoreAdapterClass());

Hope that helps