c# - LUIS Bot framework won't call Intent from external call -


i implemented external login bot. when external site calls bot callback method need set token , username in privateconversationdata , resume chat message "welcome [username]!".

to display message send messageactivity activity never connects chat , won't fire appropriate [luisintent("userisauthenticated")].

other intents, out of login-flow, works expected.

this callback method:

public class oauthcallbackcontroller : apicontroller {     [httpget]     [route("api/oauthcallback")]     public async task oauthcallback([fromuri] string userid, [fromuri] string botid, [fromuri] string conversationid,         [fromuri] string channelid, [fromuri] string serviceurl, [fromuri] string locale,         [fromuri] cancellationtoken cancellationtoken, [fromuri] string accesstoken, [fromuri] string username)     {         var resumptioncookie = new resumptioncookie(tokendecoder(userid), tokendecoder(botid),             tokendecoder(conversationid), channelid, tokendecoder(serviceurl), locale);              var container = webapiapplication.findcontainer();              var message = resumptioncookie.getmessage();             message.text = "userisauthenticated";              using (var scope = dialogmodule.beginlifetimescope(container, message))             {                 var botdata = scope.resolve<ibotdata>();                 await botdata.loadasync(cancellationtoken);                  botdata.privateconversationdata.setvalue("accesstoken", accesstoken);                 botdata.privateconversationdata.setvalue("username", username);                  resumptioncookie pending;                 if (botdata.privateconversationdata.trygetvalue("persistedcookie", out pending))                 {                     botdata.privateconversationdata.removevalue("persistedcookie");                     await botdata.flushasync(cancellationtoken);                 }                  var stack = scope.resolve<idialogstack>();                 var child = scope.resolve<maindialog>(typedparameter.from(message));                 var interruption = child.void<object, imessageactivity>();                  try                 {                     stack.call(interruption, null);                      await stack.pollasync(cancellationtoken);                 }                                 {                     await botdata.flushasync(cancellationtoken);                 }             }         }     }         public static string tokendecoder(string token)     {         return encoding.utf8.getstring(httpserverutility.urltokendecode(token));     } } 

this controller:

public class messagescontroller : apicontroller {     private readonly ilifetimescope scope;      public messagescontroller(ilifetimescope scope)     {         setfield.notnull(out this.scope, nameof(scope), scope);     }      public async task<httpresponsemessage> post([frombody] activity activity, cancellationtoken token)     {         if (activity != null)         {             switch (activity.getactivitytype())             {                 case activitytypes.message:                     using (var scope = dialogmodule.beginlifetimescope(this.scope, activity))                     {                         var posttobot = scope.resolve<iposttobot>();                         await posttobot.postasync(activity, token);                     }                     break;             }         }          return new httpresponsemessage(httpstatuscode.accepted);     } } 

this how registered components:

protected override void load(containerbuilder builder)     {         base.load(builder);          builder.register(             c => new luismodelattribute("myid", "subscriptionkey"))             .asself()             .asimplementedinterfaces()             .singleinstance();          builder.registertype<maindialog>().asself().as<idialog<object>>().instanceperdependency();          builder.registertype<luisservice>()             .keyed<iluisservice>(fibermodule.key_donotserialize)             .asimplementedinterfaces()             .singleinstance();     } 

this dialog:

[serializable] public sealed class maindialog : luisdialog<object> {     public static readonly string authtokenkey = "testtoken";     public readonly resumptioncookie resumptioncookie;     public static readonly uri cloudocoauthcallback = new uri("http://localhost:3980/api/oauthcallback");      public maindialog(imessageactivity activity, iluisservice luis)         : base(luis)     {         resumptioncookie = new resumptioncookie(activity);     }      [luisintent("")]     public async task none(idialogcontext context, luisresult result)     {         await context.postasync("sorry cannot understand!");         context.wait(messagereceived);     }      [luisintent("userauthenticated")]     public async task userauthenticated(idialogcontext context, luisresult result)     {         string username;         context.privateconversationdata.trygetvalue("username", out username);          await context.postasync($"welcome {username}!");         context.wait(messagereceived);     }      [luisintent("login")]     private async task login(idialogcontext context, luisresult result)     {         string token;         if (!context.privateconversationdata.trygetvalue(authtokenkey, out token))         {             context.privateconversationdata.setvalue("persistedcookie", resumptioncookie);              var loginurl = cloudochelpers.getloginurl(resumptioncookie, oauthcallback.tostring());              var reply = context.makemessage();              var cardbuttons = new list<cardaction>();             var plbutton = new cardaction             {                 value = loginurl,                 type = actiontypes.signin,                 title = "connetti cloudoc"             };             cardbuttons.add(plbutton);             var plcard = new signincard("connect", cardbuttons);              reply.attachments = new list<attachment>             {                 plcard.toattachment()             };              await context.postasync(reply);             context.wait(messagereceived);         }         else         {             context.done(token);         }     } } 

what miss?

update

also tried resumeasync in callback method:

var container = webapiapplication.findcontainer();  var message = resumptioncookie.getmessage(); message.text = "userisauthenticated";  using (var scope = dialogmodule.beginlifetimescope(container, message)) {      var botdata = scope.resolve<ibotdata>();      await botdata.loadasync(cancellationtoken);       botdata.privateconversationdata.setvalue("accesstoken", accesstoken);      botdata.privateconversationdata.setvalue("username", username);       resumptioncookie pending;      if (botdata.privateconversationdata.trygetvalue("persistedcookie", out pending))      {          botdata.privateconversationdata.removevalue("persistedcookie");          await botdata.flushasync(cancellationtoken);      }       await conversation.resumeasync(resumptioncookie, message, cancellationtoken);  } 

but give me error operation not valid due current state of object.

update 2

following ezequiel idea changed code way:

    [httpget]     [route("api/oauthcallback")]     public async task oauthcallback(string state, [fromuri] string accesstoken, [fromuri] string username)     {         var resumptioncookie = resumptioncookie.gzipdeserialize(state);         var message = resumptioncookie.getmessage();         message.text = "userisauthenticated";          await conversation.resumeasync(resumptioncookie, message);     } 

resumptioncookie seems ok:

enter image description here

but await conversation.resumeasync(resumptioncookie, message); continue give me error operation not valid due current state of object.

you need resume conversation bot that's why message not arriving.

instead of using dialog stack, try using

await conversation.resumeasync(resumptioncookie, message); 

depending on auth needs, might want consider authbot. can take logic on oauthcallback controller of library idea of how resuming conversation bot after auth.

the contosoflowers example, using resume conversation mechanism. not auth purposes, showing how handle hypotethical credit card payment.


Comments

Popular posts from this blog

php - How to add and update images or image url in Volusion using Volusion API -

javascript - jQuery UI Splitter/Resizable for unlimited amount of columns -

javascript - IE9 error '$'is not defined -