Адаптивные карты как подсказки Formflow - PullRequest
0 голосов
/ 17 сентября 2018

Я создал бота на C #, используя BotFramework, Adaptive Cards, LUIS и FormFlow. Он / она отвечает за организацию встреч в команде.

return new FormBuilder<MeetingRequestInput>()

    ...

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

    ...

    .Build();

Во время тестов мы заметили проблемы, когда пользователь должен был ввести желаемую дату / время встречи (люди набрали бы dd/mm/yy, mm/dd/yy, dd-mm-yy, только dd, и так далее), поэтому мы хотели бы использовать какая-то «форма» с отформатированными входами, чтобы избежать проблем с синтаксическим анализом и сохранить удобство использования.

Я думаю, что мы не можем изменить желаемый тип клавиатуры (вроде как на мобильном телефоне, где иногда клавиатура показывает только цифры или показывает DateTime Picker), или применить автозаполнение шаблона, по крайней мере, с помощью BotFramework.

Чтобы решить эту проблему, я хотел бы использовать AdaptiveCard со средствами выбора даты и времени в моем приглашении FormFlow, по крайней мере, когда пользователю предлагается ввести запрошенную дату, например так:

Пример ввода с использованием адаптивных карт

В этом примере пользователь должен заполнить AdaptiveDateInput и AdaptiveTimeInput, а затем нажать кнопку «Подтвердить». При этом он будет захватывать значения внутри входных данных, а затем «печатать и отправлять» пользователю требуемый DateTime в конкретном шаблоне, избегая предыдущих проблем с синтаксическим анализом.

Проблема в том, что я не могу заменить «обычную» карту FormFlow (которая ожидает в качестве параметра подсказки простую строку) всей адаптивной картой. Как мне решить эту проблему? Являются ли AdaptiveCards лучшим ответом или есть альтернативы?

Прямо сейчас я показываю карту вручную, вот так:

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

Я прочитал этот вопрос , но я не знаю, есть ли у нас точно такая же проблема. И их решение не относится ко мне: хотя я и сделал приведенные выше примеры на английском языке, бот фактически ожидает ввод данных на других языках, так что да, мы можем проанализировать «2 февраля» с помощью Recognizer, но у нас нет того же самого удачи с "2 de Fevereiro" или "2 Fevralya".

1 Ответ

0 голосов
/ 26 сентября 2018

Используя FormBuilder.Prompter , вы можете настроить FormFlow сообщения любым удобным вам способом. Однако, поскольку AdaptiveCards отправляет ответы в .Value, перед проверкой код должен будет передать свойство .Value в свойство .Text.

Вот пример формы FormFlow, которая отправляет AdaptiveCard для поля RequestedDate:

[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();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...