繁体   English   中英

Formflow提示时显示自适应卡

[英]Adaptive Cards as Formflow prompts

我使用BotFramework,自适应卡,LUIS和FormFlow在C#中创建了一个机器人。 他/他负责管理团队中的会议。

return new FormBuilder<MeetingRequestInput>()

    ...

    .Field(
        nameof(MeetingRequestInput.RequestedDate),
        "What date would you like to meet?"
    )

    ...

    .Build();

在测试期间,我们注意到当用户应该键入所需的会议日期/时间时出现的问题(人们会键入dd/mm/yymm/dd/yydd-mm-yy ,仅dd等),因此我们想使用带有格式输入的某种“表单”来避免解析问题并保持可用性。

我认为我们无法更改所需的键盘类型(有点像在移动设备中那样,有时键盘仅显示数字或显示DateTime Picker),也不能应用自动完成模式,至少使用BotFramework可以。

为了解决这个问题,我想至少在要求用户键入请求的日期时,在FormFlow提示符中使用带有日期和时间选择器的AdaptiveCard,如下所示:

使用自适应卡的输入示例

在此示例中,用户将填充AdaptiveDateInput和AdaptiveTimeInput,然后按“确认”按钮。 这样做,它将获取输入中的值,然后在特定模板中为用户“键入并发送”所需的DateTime,避免了先前的解析问题。

问题是,我无法用整个自适应卡替换“正常”的FormFlow卡(期望将简单的字符串作为提示参数)。 我该如何解决这个问题? AdaptiveCard是最好的答案还是有其他选择?

现在,我手动显示卡,如下所示:

AdaptiveCard card = new AdaptiveCard();
    card.Body = new List<AdaptiveElement>()
    {
        new AdaptiveTextBlock()
        {
            Text = "What date would you like to meet?"
        },
        new AdaptiveDateInput()
        {
            Value = DateTime.Now.ToShortDateString(),
            Id = "dateInp"
        },
        new AdaptiveTimeInput()
        {
            Value = DateTime.Now.ToShortTimeString(),
            Id = "timeInp"
        }
    };
    card.Actions = new List<AdaptiveAction>()
    {
        new AdaptiveSubmitAction()
        {
            Type = "Action.Submit",
            Title = "Confirm"
        }
    };
    var msg = context.MakeMessage();
    msg.Attachments.Add(
        new Attachment()
        {
            Content = card,
            ContentType = "application/vnd.microsoft.card.adaptive",
            Name = "Requested Date Adaptive Card"
        }
    );
    await context.PostAsync(msg);

我已经读过这个问题 ,但是我不知道我们是否有完全相同的问题。 而且它们的解决方案不适用于我:即使我上面用英语制作了示例,该机器人实际上也会期望使用其他语言输入,因此,是的,我们可以使用Recognizer解析“ 2月2日”,但我们没有相同的结果“ 2 de Fevereiro”或“ 2 Fevralya”的运气不错。

使用FormBuilder.Prompter ,您可以按照自己的方式自定义FormFlow消息。 但是,由于AdaptiveCard在.Value中发送响应,因此代码需要在验证之前将.Value传输到.Text属性。

这是一个FormFlow表单的示例,该表单为RequestedDate字段发送AdaptiveCard:

[Serializable]
public class AdaptiveCardsFormFlow
{
    public string Name { get; set; }
    public DateTime? RequestedDate { get; set; }

    public static IForm<AdaptiveCardsFormFlow> BuildForm()
    {
        IFormBuilder<AdaptiveCardsFormFlow> formBuilder = GetFormbuilder();

        var built = formBuilder
            .Field(nameof(Name), "What is your name?")
            .Field(nameof(RequestedDate))
            .Confirm("Is this information correct? {*}")
            .Build();

        return built;
    }

    private static AdaptiveCard GetDateCard()
    {
        AdaptiveCard card = new AdaptiveCard();
        card.Body = new List<AdaptiveElement>()
        {
            new AdaptiveTextBlock()
            {
                Text = "What date would you like to meet?"
            },
            new AdaptiveDateInput()
            {
                Value = DateTime.Now.ToShortDateString(),
                Id = "dateInp"
            },
            new AdaptiveTimeInput()
            {
                Value = DateTime.Now.ToShortTimeString(),
                Id = "timeInp"
            }
        };
        card.Actions = new List<AdaptiveAction>()
        {
            new AdaptiveSubmitAction()
            {
                Type = "Action.Submit",
                Title = "Confirm"
            }
        };
        return card;
    }

    private static IFormBuilder<AdaptiveCardsFormFlow> GetFormbuilder()
    {

        IFormBuilder<AdaptiveCardsFormFlow> formBuilder = new FormBuilder<AdaptiveCardsFormFlow>()
            .Prompter(async (context, prompt, state, field) =>
            {
                var preamble = context.MakeMessage();
                var promptMessage = context.MakeMessage();
                if (prompt.GenerateMessages(preamble, promptMessage))
                {
                    await context.PostAsync(preamble);
                }

                if (field != null && field.Name == nameof(AdaptiveCardsFormFlow.RequestedDate))
                {
                    var attachment = new Attachment()
                    {
                        Content = GetDateCard(),
                        ContentType = AdaptiveCard.ContentType,
                        Name = "Requested Date Adaptive Card"
                    };

                    promptMessage.Attachments.Add(attachment);
                }

                await context.PostAsync(promptMessage);

                return prompt;
            }).Message("Please enter your information to schedule a callback.");

        return formBuilder;
    }
}

使用此类:

 private class DateTimeInp
    {
        public string dateInp { get; set; }
        public string timeInp { get; set; }

        public DateTime? ToDateTime()
        {
            string fullDateTime = dateInp + " " + timeInp;
            DateTime toDateTime;
            if(DateTime.TryParse(fullDateTime, out toDateTime))
            {
                return toDateTime;
            }
            return null;
        }
    }

然后,在消息控制器中,将自适应卡的返回值添加到活动的.Text属性中:

if(activity.Value != null)
{
    DateTimeInp input = JsonConvert.DeserializeObject<DateTimeInp>(activity.Value.ToString());
    var toDateTime = input.ToDateTime();
    if(toDateTime != null)
    {
        activity.Text = toDateTime.ToString();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM