2017-04-30 12 views
2

私はBot FrameworkとAzureAuthDialogを使用してユーザーを認証しています。認証時にユーザーのメッセージを転送する方法

ボットはまず、ユーザーに何を求めているかを尋ねます。ユーザーがメッセージを書くたびに、彼は認証されているかどうかをチェックします。彼が認証されていないとわかったら、彼に認証を求めてください。認証が完了したら、認証前にリクエストを処理し続けたいと思います。

一方、現在のところ、ユーザーが認証すると、ユーザーメッセージが失われます。ここでは、コードですが、より多くを理解することは、インラインコメントを参照してください:

public class IntentHandler : LuisDialog<object> 
    { 
protected override async Task MessageReceived(IDialogContext context, IAwaitable<IMessageActivity> item) 
     { 
      if (!await context.IsUserAuthenticated(m_resourceId)) 
      { 
// this has the user's message 
       var message = await item; 
// The next thing that is called here is ResumeAfterAuth function, but it does not have the user's message anymore 
       await context.Forward(new AzureAuthDialog(m_resourceId), ResumeAfterAuth, message, CancellationToken.None); 
      } 
      else 
      { 
       await base.MessageReceived(context, item); 
      } 
     } 

     private async Task ResumeAfterAuth(IDialogContext context, IAwaitable<string> item) 
     { 
// this does not have the users's message, it only includes "User is loged in" 
       var message = await item; 
       await context.PostAsync(message); 
       PrivateTracer.Tracer.TraceInformation($"User {context.GetUserMail()} signed in"); 
       await context.PostAsync(c_welcomeQuestion); 
      } 
    } 

認証前からユーザーのメッセージを渡す方法任意のアイデアを? 私はMessageReceived enter code hereのフィールドにユーザーのメッセージを保存することができますが、それはあまりにも醜いようです。別の方法がありますか?あなたのResumeAfterAuth方法で

+0

AuthBotのAzureAuthDialogは、あなたが作成したものですか? –

+0

これはauth botのものです –

答えて

1

IAwaitableは、あなたが(AzureAuthDialog)と呼ばれるダイアログではなく、最初のユーザーのメッセージの結果です。

あなたはAzureAuthDialogを所有していない場合、あなたは自分の周りの元のメッセージを維持し、あなたのコールバック(ResumeAfterAuth)にそれを渡す必要があります。あなたはこのような何か、ラムダ関数にダイアログクラスのメンバ変数として、またはclousureを通してそれを保つことができる:

if (!await context.IsUserAuthenticated(m_resourceId)) 
{  
    var initialUserText = (await item).Text; 
    await context.Forward(new AzureAuthDialog(m_resourceId), (_context, _item) => ResumeAfterAuth(_context, _item, initialUserText), message, CancellationToken.None); 
} 

そして、あなたのコールバックメソッドのシグネチャは次のようになります。

private async Task ResumeAfterAuth(IDialogContext context, IAwaitable<string> item, string initialUserText) 

あなたの場合自分自身AzureAuthDialog、私はあなたがそれが完了したら元のユーザーのテキストをあなたに戻すことによってより良いと思います。

EDIT:閉鎖をシリアル化できるようにBotFrameworkを設定する必要があります(完了していない場合はdescribed here)。あなたは、サービスの起動方法にこれを追加することによってそれを行うことができます。

var builder = new ContainerBuilder(); 
builder.RegisterModule(new ReflectionSurrogateModule()); 
builder.Update(Conversation.Container); 
0

それを行うための一つの方法、他の最良の方法は何@andre述べたように、ローカル変数にユーザメッセージを保存し、呼び出すことです認証後にbase.MessageReceived関数が格納されたユーザーメッセージを渡します。コードは通常次のようなものになります。

class IntentHandler : LuisDialog<object> 
{ 

    private string userToBot; 

    protected override async Task MessageReceived(IDialogContext context, IAwaitable<IMessageActivity> item) 
    { 
     var message = await item; 
     //No way to get the message in the LuisIntent methods so saving it here 
     userToBot = message.Text.ToLowerInvariant(); 

     if (message.Type != ActivityTypes.Message) 
     { 
      await base.MessageReceived(context, item); 

      return; 
     } 

     if (!await context.IsUserAuthenticated(m_resourceId)) 
     { 
      await context.Forward(new AzureAuthDialog(m_resourceId), ResumeAfterAuth, message, CancellationToken.None); 
     } 
     else 
     { 
      await base.MessageReceived(context, item); 
     } 

    } 

    private async Task ResumeAfterAuth(IDialogContext context, IAwaitable<string> result) 
    { 
     var message = await 
     await context.PostAsync(message); 

     Activity activity = (Activity)context.Activity; 

     //Store the saved message back to the activity 
     activity.Text = userToBot; 

     //Reset the saved message 
     userToBot = string.Empty; 

     //Call the base.MessageReceived to trigger the LUIS intenet 
     await base.MessageReceived(context, Awaitable.FromItem(activity)); 

    } 

} 
関連する問題