microsoft bot 框架输入指示器表单流程(Form Builder)
microsoft bot framework typing indicator form flow(Form Builder)
我需要在表单流中添加输入指示器 activity,我使用了以下代码,但它只在表单流之外工作,一旦用户进入表单构建器,输入指示器就不会出现.
Activity replytyping1 = activity.CreateReply();
replytyping1.Type = ActivityTypes.Typing;
replytyping1.Text = null;
ConnectorClient connector2 = new ConnectorClient(new Uri(activity.ServiceUrl));
await connector2.Conversations.ReplyToActivityAsync(replytyping1);
我在对话框中使用以下代码来调用表单生成器:
var myform = new FormDialog<TrainingForm>(new TrainingForm(), TrainingForm.MYBuildForm, FormOptions.PromptInStart, null);
context.Call<TrainingForm>(myform, AfterChildDialog);
我的表单生成器代码:
public enum MoreHelp { Yes, No };
public enum Helpfull { Yes, No };
[Serializable]
public class TrainingForm
{
public string More = string.Empty;
public string usefull = string.Empty;
[Prompt("Is there anything else I can help you with today? {||}")]
[Template(TemplateUsage.NotUnderstood, "What does \"{0}\" mean?", ChoiceStyle = ChoiceStyleOptions.Auto)]
public MoreHelp? needMoreHelp { get; set; }
[Prompt("Was this helpful? {||}")]
[Template(TemplateUsage.NotUnderstood, "What does \"{0}\" mean?", ChoiceStyle = ChoiceStyleOptions.Auto)]
public Helpfull? WasHelpful { get; set; }
public static IForm<TrainingForm> MYBuildForm()
{
return new FormBuilder<TrainingForm>()
.Field(new FieldReflector<TrainingForm>(nameof(needMoreHelp))
.SetActive(state => true)
.SetNext(SetNext2).SetIsNullable(false))
.Field(new FieldReflector<TrainingForm>(nameof(WasHelpful))
.SetActive(state => state.More.Contains("No"))
.SetNext(SetNext).SetIsNullable(false)).OnCompletion(async (context, state) =>
{
if (state.usefull == "No")
{
await context.PostAsync("Sorry I could not help you");
}
else if (state.usefull == "Yes")
{
await context.PostAsync("Glad I could help");
}
if(state.More == "Yes")
{
await context.PostAsync("Ok! How can I help?");
}
context.Done<object>(new object());
})
.Build();
}
如果您尝试从加载 FormFlow 对话框的对话框中发送输入 activity,它将无法工作,因为父对话框中的代码不会在每次加载 FormFlow 对话框时执行。
但是,您可以修改 MessagesController 并检查对话框堆栈。如果 FormFlow 对话框是堆栈中的最后一个对话框,则发送输入:
public async Task<HttpResponseMessage> Post([FromBody]Activity activity) {
if (activity.Type == ActivityTypes.Message)
{
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
{
var botData = scope.Resolve<IBotData>();
await botData.LoadAsync(default(CancellationToken));
var stack = scope.Resolve<IDialogTask>();
if (stack.Frames != null && stack.Frames.Count > 0)
{
var lastFrame = stack.Frames[stack.Frames.Count - 1];
var frameValue = lastFrame.Target.GetType().GetFields()[0].GetValue(lastFrame.Target);
if(frameValue is FormDialog<TrainingForm>)
{
var typingReply = activity.CreateReply();
typingReply.Type = ActivityTypes.Typing;
var connector = new ConnectorClient(new Uri(activity.ServiceUrl));
await connector.Conversations.ReplyToActivityAsync(typingReply);
}
}
}
await Conversation.SendAsync(activity, () => FormDialog.FromForm(TrainingForm.MYBuildForm));
}
else
{
this.HandleSystemMessage(activity);
}
return Request.CreateResponse(HttpStatusCode.OK);
}
我需要在表单流中添加输入指示器 activity,我使用了以下代码,但它只在表单流之外工作,一旦用户进入表单构建器,输入指示器就不会出现.
Activity replytyping1 = activity.CreateReply();
replytyping1.Type = ActivityTypes.Typing;
replytyping1.Text = null;
ConnectorClient connector2 = new ConnectorClient(new Uri(activity.ServiceUrl));
await connector2.Conversations.ReplyToActivityAsync(replytyping1);
我在对话框中使用以下代码来调用表单生成器:
var myform = new FormDialog<TrainingForm>(new TrainingForm(), TrainingForm.MYBuildForm, FormOptions.PromptInStart, null);
context.Call<TrainingForm>(myform, AfterChildDialog);
我的表单生成器代码:
public enum MoreHelp { Yes, No };
public enum Helpfull { Yes, No };
[Serializable]
public class TrainingForm
{
public string More = string.Empty;
public string usefull = string.Empty;
[Prompt("Is there anything else I can help you with today? {||}")]
[Template(TemplateUsage.NotUnderstood, "What does \"{0}\" mean?", ChoiceStyle = ChoiceStyleOptions.Auto)]
public MoreHelp? needMoreHelp { get; set; }
[Prompt("Was this helpful? {||}")]
[Template(TemplateUsage.NotUnderstood, "What does \"{0}\" mean?", ChoiceStyle = ChoiceStyleOptions.Auto)]
public Helpfull? WasHelpful { get; set; }
public static IForm<TrainingForm> MYBuildForm()
{
return new FormBuilder<TrainingForm>()
.Field(new FieldReflector<TrainingForm>(nameof(needMoreHelp))
.SetActive(state => true)
.SetNext(SetNext2).SetIsNullable(false))
.Field(new FieldReflector<TrainingForm>(nameof(WasHelpful))
.SetActive(state => state.More.Contains("No"))
.SetNext(SetNext).SetIsNullable(false)).OnCompletion(async (context, state) =>
{
if (state.usefull == "No")
{
await context.PostAsync("Sorry I could not help you");
}
else if (state.usefull == "Yes")
{
await context.PostAsync("Glad I could help");
}
if(state.More == "Yes")
{
await context.PostAsync("Ok! How can I help?");
}
context.Done<object>(new object());
})
.Build();
}
如果您尝试从加载 FormFlow 对话框的对话框中发送输入 activity,它将无法工作,因为父对话框中的代码不会在每次加载 FormFlow 对话框时执行。
但是,您可以修改 MessagesController 并检查对话框堆栈。如果 FormFlow 对话框是堆栈中的最后一个对话框,则发送输入:
public async Task<HttpResponseMessage> Post([FromBody]Activity activity) {
if (activity.Type == ActivityTypes.Message)
{
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
{
var botData = scope.Resolve<IBotData>();
await botData.LoadAsync(default(CancellationToken));
var stack = scope.Resolve<IDialogTask>();
if (stack.Frames != null && stack.Frames.Count > 0)
{
var lastFrame = stack.Frames[stack.Frames.Count - 1];
var frameValue = lastFrame.Target.GetType().GetFields()[0].GetValue(lastFrame.Target);
if(frameValue is FormDialog<TrainingForm>)
{
var typingReply = activity.CreateReply();
typingReply.Type = ActivityTypes.Typing;
var connector = new ConnectorClient(new Uri(activity.ServiceUrl));
await connector.Conversations.ReplyToActivityAsync(typingReply);
}
}
}
await Conversation.SendAsync(activity, () => FormDialog.FromForm(TrainingForm.MYBuildForm));
}
else
{
this.HandleSystemMessage(activity);
}
return Request.CreateResponse(HttpStatusCode.OK);
}