Not an issue per se but a question on how a bot can maintain state between deployment.
For example, if a bot (slack platform) is having a private conversation and during the conversation a deployment is pushed the conversation thread is lost.
When a bot is deployed and new RTM connection is establish and clearly any state the bot has is memory is lost.
Continuous deployment is an important practice so I am wondering how it can be achieved using the very awesome bitkit library.
@srbartlett, I 100% agree. I am facing this problem as well and am wondering if others have already solved it... If not, I was thinking of creating a fork of BotKit where I can store a hash in a db for every user which is associated to a conversation node... so if the server is reset (cough, cough Heroku...) the bot can smartly know where it is in the conversation flow.
Definitely an issue and would be wise to borrow from existing solutions in http cycles
I'm leveraging the filesystem built directly into NODE to resolve this. See docs here.
I'm facing the same problem. Ideally a solution would leverage botkit's custom storage system. Has anyone worked on a solution?
Can anyone help with saving the state of a conversation flow? Has anybody found any solutions?
@alexbudin Not exactly a solution but using the the Slack Events API allows you to be stateless protocol. https://api.slack.com/events
I've found a solution for this 馃憢
When a user has a conversation with my bot, I create (or find an existing) session. In a session, I store "context" variables about the conversation/state which are also saved to my mongo database. I load all these active sessions into memory when restarting the app so I can access them locally.
Not sure if it's the best or the right way, but it works for me 馃槃
any plan to support multi-nodes and maintaining state in database?
going to try @dannyfreed solution at the moment ;)
Hi ! Something new about this point ?
@dannyfreed can you share your solution ?
Thanks !
Hi !
@dannyfreed can you share your solution ? Thanks !
+1
merged this towards this more active thread https://github.com/howdyai/botkit/issues/506
@dannyfreed I was just about implement something similar. Is there a snippet or two you wouldn't mind sharing for where / how you captured and reinitialized the conversations within botkit? Is it just a matter of dumping / loading controller.tasks on every request / response? What other context are you managing?
@rsweetland I didn't implement this using botkit, ended up building my own solution.
The gist of it was I have a sessions table in my database. I make a call to the database onReceivedMessage and search for the user's "session" based on their user id.
Each session row has a user id, and then a "context" which is essentially just a mutable object (key/value).
I update the state onSend and onReceive depending on the business logic.
Hope that helps!
Totally helps, thank you! 馃檶
But one question (if you don't mind): How did you load the stored conversation / context back into botkit's memory? Just curious if you found a way to effectively serialize / deserialize this.
For example (wishful thinking / pseudo code):
const message; //available from earlier
const tasks = controller.tasks;
for (let task of tasks) {
for (let convo of task.convos) {
const userid = convo.source_message.channel;
const serializedConvo = await lookupStoredConversation(userid);
const botkitConvo = magicalDeserialization(serializedConvo); // <-- ?
const botkitConvo.handle(message);
}
}
}
It's been a while since I looked at any Botkit code. But if I remember correctly, I think you can add middleware that will do this. Basically in the middleware, which you'll want to call for each message you receive and/or send, you can make a call to your database and find the user context as I previously described.
Most helpful comment
I've found a solution for this 馃憢
When a user has a conversation with my bot, I create (or find an existing) session. In a session, I store "context" variables about the conversation/state which are also saved to my mongo database. I load all these active sessions into memory when restarting the app so I can access them locally.
Not sure if it's the best or the right way, but it works for me 馃槃