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
Post a Comment