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); 
}