c# - Terminate all dialogs and exit conversation in MS Bot Framework when the user types "exit", "quit" etc -


i can't figure out how simple thing in ms bot framework: allow user break out of conversation, leave current dialogs , return main menu typing "quit", "exit" or "start over".

here's way main conversation set up:

    public async task<httpresponsemessage> post([frombody]activity activity)     {         try         {             if (activity.type == activitytypes.message)             {                 useractivitylogger.loguserbehaviour(activity);                  if (activity.text.tolower() == "start over")                 {                     //do here, don't have idialogcontext here!                 }                 botutils.sendtyping(activity); //send "typing" indicator upon each message received                 await conversation.sendasync(activity, () => new rootdialog());             }             else             {                 handlesystemmessage(activity);             }         } 

i know how terminate dialog context.done<dialogtype>(this);, in method, not have access idialogcontext object, cannot call .done().

is there other way terminate whole dialog stack when user types message, other adding check in each step of dialogs?

posted bounty:

i need way terminate idialogs without using outrageous hack i've posted here (which deletes user data, need, e.g. user settings , preferences).

basically, when user types "quit" or "exit", need exit whatever idialog in progress , return fresh state, if user has initiated conversation.

i need able messagecontroller.cs, still not have access idialogcontext. useful data seem have there activity object. happy if points out other ways that.

another way approach find other way check "exit" , "quit" keywords @ other place of bot, rather in post method.

but shouldn't check done @ every single step of idialog, because that's code , not possible (when using promptdialog, have no access text user typed).

two possible ways didn't explore:

  • instead of terminating current idialogs, start new conversation user (new conversationid)
  • obtain idialogstack object , manage dialog stack.

the microsoft docs silent on object have no idea how it. not use chain object allows .switch() anywhere in bot, if think can rewritten use it, can 1 of ways solve too. however, haven't found how branching between various types of dialogs (formflow , ordinary idialog) in turn call own child dialogs etc.

problem breakdown

from understanding of question, want achieve reset dialog stack without destroy bot state.


facts (from read github repository)

  1. how framework save dialog stack below:

botdatastore > botdata > dialogstack

  1. botframework using autofac di container
  2. dialogmodule autofac module dialog components

how do

knowing facts above, solution be

  1. register dependencies can use in our controller:

// in global.asax.cs var builder = new containerbuilder(); builder.registermodule(new dialogmodule()); builder.registermodule(new reflectionsurrogatemodule()); builder.registermodule(new dialogmodule_makeroot());  var config = globalconfiguration.configuration; builder.registerapicontrollers(assembly.getexecutingassembly()); builder.registerwebapifilterprovider(config); var container = builder.build(); config.dependencyresolver = new autofacwebapidependencyresolver(container); 
  1. get autofac container (feel free put anywhere in code you're comfortable with)

private static ilifetimescope container {         {         var config = globalconfiguration.configuration;         var resolver = (autofacwebapidependencyresolver)config.dependencyresolver;         return resolver.container;     } } 
  1. load botdata in scope
  2. load dialogstack
  3. reset dialogstack
  4. push new botdata botdatastore

using (var scope = dialogmodule.beginlifetimescope(container, activity)) {     var botdata = scope.resolve<ibotdata>();     await botdata.loadasync(default(cancellationtoken));     var stack = scope.resolve<idialogstack>();     stack.reset();     await botdata.flushasync(default(cancellationtoken)); } 

hope helps.


update 1 (27/08/2016)

thanks @ejadib point out, container being exposed in conversation class.

we can remove step 2 in answer above, in end code like

using (var scope = dialogmodule.beginlifetimescope(conversation.container, activity)) {     var botdata = scope.resolve<ibotdata>();     await botdata.loadasync(default(cancellationtoken));     var stack = scope.resolve<idialogstack>();     stack.reset();     await botdata.flushasync(default(cancellationtoken)); } 

Comments

Popular posts from this blog

mysql - Dreamhost PyCharm Django Python 3 Launching a Site -

java - Sending SMS with SMSLib and Web Services -

java - How to resolve The method toString() in the type Object is not applicable for the arguments (InputStream) -