PromptDialog.Choice()的消息处理不正确?
我注意到,使用PromptDialog.Choice()
主动开始对话并不像预期的那样工作,并想知道我是否做错了什么或者它是否是bot框架中的问题。PromptDialog.Choice()的消息处理不正确?
我使用的提示在我的根对话是这样的:
public async Task StartAsync(IDialogContext context)
{
PromptDialog.Choice(...);
}
的问题是根对话多个消息到达。至少有两个“对话更新”消息,一个用于添加机器人,另一个用于添加用户。
提示对话框将这些解释为答案,当然它们与可用的提示选项不匹配。因此,提示对话框再次尝试并再次显示。因此,我总是会在对话开始时收到多个提示。
我将其追踪到dialog中的消息处理程序,并且看到它不检查消息类型。作为一种变通方法我已经创建了自己的提示对话框而忽略所有的非消息类型的活动,现在它按预期工作:
[Serializable]
public class CustomPromptDialog : PromptChoice<string>
{
public CustomPromptDialog(string title, params string [] buttons) : base(
new PromptOptions<string>(prompt: title, retry: "", tooManyAttempts: "", options: new List<string>(buttons), attempts: 2, promptStyler: null))
{
}
protected async override Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> message)
{
var activity = await message;
// This is what is IMHO missing in the built-in version.
if(activity.Type != ActivityTypes.Message)
{
return;
}
await base.MessageReceivedAsync(context, message);
}
}
我使用提示错误或者是在框架中的错误?
正如评论中所回答的那样,您的案例解决方案仅在您收到user
加入对话时才启动包含PromptChoice
的对话框。
对于这种情况,你可以检查MemberAdded
信息里面conversationUpdate
消息,只有当新增加的成员是不是机器人启动您的对话,也就是会员的ID不等于机器人的ID,这是message.Recipient.Id
:
private Activity HandleSystemMessage(Activity message)
{
if (message.Type == ActivityTypes.ConversationUpdate)
{
if (message.MembersAdded.Any(o => o.Id != message.Recipient.Id))
{
// Your PromptChoiceDialog here
}
}
return message;
}
该问题被标记为重复,为什么添加了答案? –
@EzequielJadib它不在答案的时候,即使我标记了它(我不确定它最终会被标记为重复),我添加了答案,因为与答案相比也有一个小的变化重复的,因为测试必须检查Id是否不同,不相等。 –
你可以添加你的MessageController的代码吗?您不应该将ConversationUpdate消息路由到您的对话框 –
嗯,这是事情:如果我想主动显示选择对话框,我必须对_something_做出反应,这意味着对话更新;我不想等待第一个传入的用户消息。我真的不得不在_last_传入会话更新中显示提示对话框,但我怎么知道有多少人? – Krumelur
您只需通过使用'message.MembersAdded:'上的一个检查来筛选conversationUpdate对话框,该id应该与'message.Recipient.Id'不同以排除机器人。这就是为什么我要求你的MessageController的代码;) –