.net - 机器人对话框不等待
问题描述
机器人信息
- SDK平台:.NET
- SDK版本:3.15.3
- 活跃频道:不适用
- 部署环境:使用模拟器进行本地开发
问题描述
使用模拟器进行测试时,程序不会等待用户在上下文中输入。等待,也不会在将对话框转发到另一个对话框时。
代码示例
当连接新用户时,我的 MessagesController 会触发问候语:
if(activity.Type == ActivityTypes.ConversationUpdate)
{
if (activity.MembersAdded.Count == 1)
{
await Conversation.SendAsync(activity, () => new Dialogs.GreetDialog());
}
}
然后我的 Greet Dialog 输出“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 应该提示用户输入用户名,然后连接到 db 并使用所述用户名获取用户:
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/
推荐阅读
- dynamics-crm - 这个 "IsValidODataAttribute": true 在 /api/data/v 中是什么意思...?
- android - 如何用android代码解决这个NullPointerException?
- javascript - 我需要为轮播创建标题,因此每当我单击图像时,都会显示属于该图像的标题
- javascript - 更改滑块时,html 视频的调整速度不够快
- python - Python 的 msvcrt.getch() 行为异常:从标准输入中获取并存储了多个字符;结果值甚至不是字符串或字符类型
- javascript - Javascript从对象数组中的搜索结果返回对象
- c# - NServiceBus - 处理同一消息的多个端点
- python - 关于 OpenCV resize 的 INTER_AREA 工作域的问题(func != 0 && cn <= 4 in function 'cv::hal::resize' failure)
- r - 如何在 R 中弹出函数的描述和输入?
- ios - IOS 13 UIWindow 实例在应用程序启动期间为零