botframework - Nested dialogs: message being sent twice -


i have bot doing this:

1) new activity (message) arrives.

2) dispatch message rootdialog.

3) depending on logic, rootdialog can:

 a) call luisdialog (handling natural language)   b) call customdialog (handles business logic). 

but when user state reset, , flow leads intention inside luisdialog, calls intention method twice. first time state empty, works fine.

let me show code:

messagescontroller:

   public async task<httpresponsemessage> post([frombody]activity activity)     {         if (activity.type == activitytypes.message)         {             connectorclient connector = new connectorclient(new uri(activity.serviceurl));             try             {                 await conversation.sendasync(activity, () => new rootdialog());             }             catch (httprequestexception e)             {              ...             }      } 

rootdialog:

 public class rootdialog : idialog<object>  {     public async task startasync(idialogcontext context)     {         await messagereceivedasync(context, awaitable.fromitem(context.activity.asmessageactivity()));     }      private async task messagereceivedasync(idialogcontext context, iawaitable<imessageactivity> awaitable)     {         bool value = dosomecustomlogic();         if (value)          {             string message = dosomething();             await context.postasync(message);         } else {             bool value2 = dosomecustomlogic2();             if (value2)              {                 var answervalidationdialog = new validateanswerwithuserdialog();                 context.call(answervalidationdialog, validateanswerwithuserdialogcompletedcallback);             } else {                 var luisdialog = new luisdialog();                 await context.forward(luisdialog,luisdialogcompletedcallback, context.activity, cancellationtoken.none);             }         }     } 

callbacks context.done(true);

and luisdialog has intention goes this:

  [luisintent(luisutils.intent_menu_salute)]     public async task saluteormenu(idialogcontext context, luisresult result)     {         if (luisutils.intentscoreishighenough(result))         {             string username = context.activity.from.name;             contexthelper helper = new contexthelper(messagereceived);             await helper.askusertodosomeinitialaction(context, saluteword, username);             context.done(true);         }         else         {             await none(context, result);         }     } 

and class contexthelper:

public class contexthelper {     private func<idialogcontext, iawaitable<imessageactivity>, task> messagereceived;      public contexthelper(func<idialogcontext, iawaitable<imessageactivity>, task> messagereceived)     {         messagereceived = messagereceived;     }      public async task askusertodosomeinitialaction(idialogcontext context, string saluteword, string username)     {         var reply = context.makemessage();         list<cardaction> buttons = buildinitialoptionactions();         list<cardimage> images = buildinitialoptionimages();         string initialtext = $"hi stranger!"         var card = new herocard         {             title = "hello!"             text = initialtext,             buttons = buttons,             images = images         };         reply.attachments = new list<attachment> { card.toattachment() };         await context.postasync(reply);         context.wait(afteruserchoseoptioninsalute);     }      private async task afteruserchoseoptioninsalute(idialogcontext context, iawaitable<imessageactivity> result)     {         await redispatchmessagereceivedtodialog(context);     }      private async task redispatchmessagereceivedtodialog(idialogcontext context)     {         await messagereceived(context, awaitable.fromitem(context.activity.asmessageactivity()));     }  } 

the saluteormenu intention gets called twice (only first time interact bot or when delete state. after debugging saw after doing context.wait(afteruserchoseoptioninsalute);, bot calls function (instead of waiting event call it)

any ideas?

thanks in advance.

i found line wrong. on first dialog (the rootdialog):

public async task startasync(idialogcontext context) {    await messagereceivedasync(context, awaitable.fromitem(context.activity.asmessageactivity())); } 

that line re dispatches message incoming activity. had somewhere in chunk of code , (don't know why), thought idea use on startasync. so, because of that, 2 calls occurring.

dumb me.

i changed , worked:

public async task startasync(idialogcontext context) {     context.wait(messagereceivedasync); } 

Comments

Popular posts from this blog

How to understand 2 main() functions after using uftrace to profile the C++ program? -

c# - Update a combobox from a presenter (MVP) -

How to put a lock and transaction on table using spring 4 or above using jdbcTemplate and annotations like @Transactional? -