.net - 机器人对话框不等待

标签 .net botframework

机器人信息

  • SDK 平台:.NET
  • SDK 版本:3.15.3
  • 活跃 channel :不适用
  • 部署环境:使用模拟器进行本地开发

问题描述

使用模拟器进行测试时,程序不会等待上下文中的用户输入。将对话框转发到另一个对话框时也不等待。

代码示例

当新用户连接时,我的 MessagesController 会发出问候语:

if(activity.Type == ActivityTypes.ConversationUpdate)
{
    if (activity.MembersAdded.Count == 1)
    {
        await Conversation.SendAsync(activity, () => new Dialogs.GreetDialog());
    }
}

然后我的问候对话框输出“Hello”并转发到 GatherUserDialog:

public async Task StartAsync(IDialogContext context)
{
       context.UserData.Clear();
       context.Wait(GatherInfoAsync);
}

private async Task GatherInfoAsync(IDialogContext context, IAwaitable<object> args)
{
     var activity = await args as Activity;

     if (!(context.UserData.ContainsKey("askedname")))
     {
           await context.PostAsync("Hello!");
           await context.Forward(new GatherUserDialog(), this.MessageReceivedAsync, activity);
     }

}

我的 GatherUserDialog 应提示用户输入用户名,然后连接到数据库并获取具有所述用户名的用户:

Object person;

public async Task StartAsync(IDialogContext context)
{
    await context.PostAsync("May I please have your username?");
    context.UserData.SetValue("askedname", true);
    context.Wait(MessageReceivedAsync);
}

private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
    var activity = await result as Activity;
    await result;
    using (SoCoDirectoryModel model = new SoCoDirectoryModel())
    {
        var ents = model.Entities;
        var text = activity.Text;
        this.person = (from e in model.Entities
                               where e.EmployeeId == activity.Text
                               select e).SingleOrDefault();
    }
    if (this.person == null)
    {
        await context.PostAsync("Could not find that user. Please try again.");
        context.Wait(MessageReceivedAsync);
    }
    else
    {
        this.person = person as Ent;
        await context.PostAsync($"Hello {(this.person as Ent).FirstName}, what can I do for you?");
        context.Wait(MessageReceivedAsync);

    }
    context.Wait(MessageReceivedAsync);
}

```

复制步骤

我不知道要放在这里什么,除了上面的代码和更新 NuGet 包以使用最新的稳定版本的包之外,我没有做任何特殊的事情。

预期行为

预期的行为应该是问候语,然后提示输入用户名,然后传递用户名用于获取帐户信息。

实际结果

模拟器似乎在启动时发送了 2 个帖子, state.getConversationData 和 state.getPrivateConversationData,两者同时运行,并继续完成机器人应保留的输入等待。到达 GatherUserDialog 后,程序无法停止以接受用户输入,并尝试使用空字符串执行 linq 代码。 我相信这会导致超时异常,并且“抱歉,我的机器人代码有问题。”

显然我不能发布图片,所以这里是聊天图片的链接: https://user-images.githubusercontent.com/18318261/42243397-0a373820-7ec6-11e8-99c4-5fefced6a06c.png

最佳答案

这是一个已知问题。当机器人连接到对话时以及当用户连接到对话时,ConversationUpdate 由 Direct Line 连接器发送。当 Direct Line 连接器发送 ConversationUpdate 时,它​​不会发送正确的 User.Id,因此机器人无法构造对话堆栈。模拟器的行为有所不同(它立即发送机器人和用户 ConversationUpdate 事件,并且确实发送正确的 user.id。)

解决方法是不使用 ConversationUpdate,并从客户端发送事件,然后通过对话框响应该事件。

客户端 JavaScript:

 var user = {
            id: 'user-id',
            name: 'user name'
        };

        var botConnection = new BotChat.DirectLine({
            token: '[DirectLineSecretHere]',
            user: user
        });

        BotChat.App({
            user: user,
            botConnection: botConnection,
            bot: { id: 'bot-id', name: 'bot name' },
            resize: 'detect'
        }, document.getElementById("bot"));

        botConnection
            .postActivity({
                from: user,
                name: 'requestWelcomeDialog',
                type: 'event',
                value: ''
            })
            .subscribe(function (id) {
                console.log('"trigger requestWelcomeDialog" sent');
            });

响应事件:

if (activity.Type == ActivityTypes.Event)
{
    var eventActivity = activity.AsEventActivity();

    if (eventActivity.Name == "requestWelcomeDialog")
    {
         await Conversation.SendAsync(activity, () => new Dialogs.GreetDialog());
    }
}

更多信息可以在这里找到:https://github.com/Microsoft/BotBuilder/issues/4245#issuecomment-369311452

更新(关于此的博客文章):https://blog.botframework.com/2018/07/12/how-to-properly-send-a-greeting-message-and-common-issues-from-customers/

关于.net - 机器人对话框不等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51163544/

相关文章:

c# - Microsoft Bot Framework 的自动测试

javascript - 延迟加载 javascript 文件

botframework - 如何通过 REST API 为连接到 Microsoft Teams channel 的机器人获取机器人 ID 和用户 ID

javascript - kendo grid发送json到 Controller

.NET PInvoke 异常处理

c# - 在这种情况下,一般异常处理不是那么糟糕吗?

c# - C#中使用字符串连接时创建了多少个字符串对象

botframework - 覆盖网络聊天中的时间戳格式

.net - .Net 3.5 中通过字符串名称调用方法的最快方法是什么?