Formflow提示时显示自适应卡 [英] Adaptive Cards as Formflow prompts

查看:104
本文介绍了Formflow提示时显示自适应卡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I made a bot in C# using BotFramework, Adaptive Cards, LUIS and FormFlow. It/he is responsible for managing meetings in a team.

return new FormBuilder<MeetingRequestInput>()

    ...

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

    ...

    .Build();

在测试过程中,我们发现用户应该键入所需的会议日期/时间时出现问题(人们会键入dd/mm/yymm/dd/yydd-mm-yy,仅dd等),因此我们想使用某种带有格式化输入的表单",以避免解析问题并保持可用性.

During tests we noticed problems when a user was supposed to type the desired meeting date/time (people would type dd/mm/yy, mm/dd/yy, dd-mm-yy, only dd, etcetra) so we would like to use some kind of "Form" with formatted inputs to avoid parsing problems and retaining usability.

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

I think we can't change the desired keyboard type (kinda like in mobile, where sometimes the keyboard only shows numbers, or shows a DateTime Picker), nor apply a pattern auto-complete, at least using BotFramework.

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

To solve this, I'd like to use an AdaptiveCard with Date and Time pickers in my FormFlow prompt, at least when the user is asked to type the requested date, like so:

使用自适应卡的输入示例

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

In this example, the user would fill the AdaptiveDateInput and the AdaptiveTimeInput, then press the Confirm button. Doing so, it would grab the values inside the inputs, then "type and send" for the user the desired DateTime in a specific template, avoiding the previous parsing problems.

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

Problem is, I can't replace the "normal" FormFlow Card (who's expecting a simple string as a prompt parameter) with an entire Adaptive Card. How do I solve this problem? Are AdaptiveCards the best answer or are there alternatives?

现在我像这样手动显示卡:

Right now I'm displaying the card manually like so:

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解析"February 2th",但我们没有相同的结果幸运的是"2 de Fevereiro"或"2 Fevralya".

I've read this question, but I don't know if we have the exact same problem. And their solution does not apply to me: even though I made the examples above in english, the bot will actually expect inputs in other languages, so yeah we can parse "February 2th" using a Recognizer, but we don't have the same luck with "2 de Fevereiro" nor "2 Fevralya".

推荐答案

使用 FormBuilder.Prompter ,您可以根据需要自定义 FormFlow 消息.但是,由于 AdaptiveCards 在.Value中发送响应,因此代码需要在验证之前将.Value传输到.Text属性.

Using the FormBuilder.Prompter, you can customize FormFlow messages any way you like. However, since AdaptiveCards send responses in the .Value, the code will need to transfer .Value to .Text property before validation.

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

Here is an example of a FormFlow form that sends an AdaptiveCard for a RequestedDate field:

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

然后,在Messages Controller中,将Adaptive Card的返回值添加到活动的.Text属性中:

Then, in the Messages Controller, add the Adaptive Card's return value to the .Text property of the activity:

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

这篇关于Formflow提示时显示自适应卡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆