如何在身份验证上转发用户的消息

时间:2017-04-30 17:08:46

标签: c# botframework

我使用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的字段中保存用户的消息,但这看起来太难看了。还有另一种方式吗?

2 个答案:

答案 0 :(得分:1)

ResumeAfterAuth 方法中的 IAwaitable 是您调用的对话框( AzureAuthDialog )的结果,而不是初始用户的消息。< / p>

如果您不拥有 AzureAuthDialog ,则需要保留原始消息并将其传递给回调( ResumeAfterAuth )。您可以将它保存为对话框类的成员变量或通过lambda函数的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 ,我猜您最好在完成后将原始用户文本返回给您。

编辑:您需要配置BotFramework以允许它序列化闭包,如果您还没有,则described here。您可以通过将其添加到服务的启动方法来实现:

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

答案 1 :(得分:0)

@andre提到的是一种方法,另一种方法是将用户消息存储在本地变量中,然后在认证后将存储的用户消息传递给它时调用base.MessageReceived函数。代码通常是这样的:

IndustryName    Country A   Country B   Country C
Industry A      2           1           NULL
Industry B      3           NULL        NULL