Создание чат-ботов используя Bot Builder SDK 4 — часть 3

Привет. Это третий урок из курса «Создание чат-ботов используя Bot Builder SDK» Сегодня мы разберёмся с вопросом использования карточек в чат-ботах и узнаем как с ними работать, используя Bot Builder SDK 4.

Карточки в чат-ботах служат для более удобного и информативного представления некоторой информации. Ведь чат-бот может присылать пользователю не только текст, это могут быть и изображения, и аудио или видео файлы. К тому же в карточки можно добавлять кнопки, для быстрого взаимодействия с пользователем.

Давайте посмотрим какие типы карточек можно использовать, как они выглядят и разберёмся для чего они нужны.

Первой рассмотрим самую сложную и в то же время самую функциональную карточку.

Adaptive Card — настраиваемая карта, которая может содержать любую комбинацию текста, речи, изображений, кнопок и полей ввода. С помощью данной карточки вы можете выводить информацию в любом нужном для вас виде, будь то изображения, поля для ввода, кнопки либо текст, вы можете размещать их на своё усмотрение и добавлять столько элементов, сколько необходимо.

Получить всю информацию о adaptive card можно на сайте http://adaptivecards.io, здесь можно найти примеры уже созданных сложных карточек, посмотреть на их реализацию, узнать какие элементы доступны для использования. Так же вы можете в интерактивном режиме изменять код карточки и просматривать как она будет отображаться на различных платформах, даже без необходимости использовать эмулятор.

Adaptive Card

Animation Card — может воспроизводить анимированные GIF-файлы или короткие видеоролики. Если вы хотите, чтобы в вашем чат-боте можно было просмотреть GIF-изображение либо видео, вы можете воспользоваться данной карточкой.

Animation Card

Audio Card — карта, которая может воспроизводить аудиофайл. Аналогична предыдущей, но используется для воспроизведения аудиофайлов.

Audio Card

Hero Card — обычно содержит одно большое изображение, одну или несколько кнопок и текст. Данная карточка отлично подходит для отображения, например, preview новостей или схожей информации, где в первую очередь стоит обратить внимание на изображение.

Hero Card

Thumbnail Card — обычно содержит одно небольшое изображение, одну или несколько кнопок и текст. Аналогична предыдущей карте, за тем исключением что отображаемое изображение не такое большое.

Thumbnail Card

Receipt Card —данная карта позволяет боту предоставлять пользователю квитанцию. Обычно содержит список предметов для включения в квитанцию, налоговую и общую информацию и прочий текст. Проще говоря, данная карта удобна для отображения информации чеков и квитанций.

Receipt Card

SignIn Card — позволяет боту запрашивать вход пользователя в систему. Обычно содержит текст и одну или несколько кнопок, которые пользователь может щелкнуть, чтобы инициировать процесс входа в систему.

SignIn Card

Video Card — данная карточка может воспроизводить видеофайлы.

Video Card

Сейчас я покажу как можно добавлять карточки в чат-бот, используя Bot Builder SDK.

Откроем наш проект и добавим новый класс CardsCommand. Данный класс наследуем от класса DialogContainer. Добавляем конструктор, затем добавим константу для хранения названия класса по умолчанию. В конструкторе название по умолчанию будет добавлять для параметра dialogId. Добавим новый диалог, в качестве имени которого будет использоваться переменная dialogId. Добавим переменную response, которая будет служить ответом чат-бота пользователю, содержать она будет информацию, полученную от метода Context.Activity.CreateReply(). Далее сделаем инициализацию для свойства Attachments, присвоив список содержащий класс Attachment. Attachments служит для добавления вложений в возвращаемую информацию чат-бота, именно сюда добавляется информация о карточках.

Добавим в Attachments новую карточку типа Animation Card. Заполним для неё Title, Media (media служит для добавления списка изображений либо видеороликов) и Subtitle. Добавим метод ToAttachment, который позволяет добавлять информацию карточки во вложения. Полученную информацию из переменной response будет передавать в Context.SendActivity. Теперь остаётся добавить информацию для вызова данного диалога. В список доступных диалогов добавим его, с именем cards. В методе OnTurn добавим обработку команды cards и вызов данного диалога. Теперь запустим чат-бот, откроем эмулятор и проверим как это всё работает. После заполнения имени и фамилии, мы можем выполнить команду cards, после чего увидим содержимое Animation Card.

public CardsCommand(string dialogId = DefaultName, DialogSet dialogs = null) : base(dialogId, dialogs)
{
    Dialogs.Add(dialogId, new WaterfallStep[]
    {
        async (dc, args, next) =>
        {
            var message = dc.Context.Activity.Text;
            if (!string.IsNullOrEmpty(message))
            {
                await next.Invoke();
                return;
            }

            await dc.Prompt("cardPrompt", "Выберите тип нужной карточки", GenerateOptions());
        },
        async (dc, args, next) =>
        {
            var selectedCard = (args as Microsoft.Bot.Builder.Prompts.ChoiceResult)?.Value.Value;
            var message = dc.Context.Activity.Text;
            if (selectedCard == null && !string.IsNullOrEmpty(message))
            {
                var foundResult  = GenerateOptions().Choices.FirstOrDefault(x => x.Synonyms.Contains(message.ToLower()));
                if (foundResult != null)
                {
                    selectedCard = foundResult.Value;
                }
            }

            var activity = dc.Context.Activity;
            switch (selectedCard)
            {
                case "Adaptive card":
                    await dc.Context.SendActivity(CreateResponse(activity, CreateAdaptiveCardAttachment()));
                    break;
                case "Animation card":
                    await dc.Context.SendActivity(CreateResponse(activity, CreateAnimationCardAttachment()));
                    break;
                case "Audio card":
                    await dc.Context.SendActivity(CreateResponse(activity, CreateAudioCardAttachment()));
                    break;
                case "Hero card":
                    await dc.Context.SendActivity(CreateResponse(activity, CreateHeroCardAttachment()));
                    break;
                case "Receipt card":
                    await dc.Context.SendActivity(CreateResponse(activity, CreateReceiptCardAttachment()));
                    break;
                case "Signin card":
                    await dc.Context.SendActivity(CreateResponse(activity, CreateSignInCardAttachment()));
                    break;
                case "Thumbnail card":
                    await dc.Context.SendActivity(CreateResponse(activity, CreateThumbnailCardAttachment()));
                    break;
                case "Video card":
                    await dc.Context.SendActivity(CreateResponse(activity, CreateVideoCardAttacment()));
                    break;
            }
            await dc.End();
        }
    });
    var cardPrompt = new ChoicePrompt(Culture.English)
    {
        Style = Microsoft.Bot.Builder.Prompts.ListStyle.List
    };
    Dialogs.Add("cardPrompt", cardPrompt);
}
private Activity CreateResponse(Activity activity, Attachment attachment)
{
    var response = activity.CreateReply();
    response.Attachments = new List<Attachment>() { attachment };
    return response;
}

private ChoicePromptOptions GenerateOptions()
{
    return new ChoicePromptOptions()
    {
        Choices = new List<Choice>()
        {
            new Choice()
            {
                Value = "Adaptive card",
                Synonyms = new List<string>() { "1", "adaptive" }
            },
            new Choice()
            {
                Value = "Animation card",
                Synonyms = new List<string>() { "2", "animation" }
            },
            new Choice()
            {
                Value = "Audio card",
                Synonyms = new List<string>() { "3", "audio" }
            },
            new Choice()
            {
                Value = "Hero card",
                Synonyms = new List<string>() { "4", "hero" }
            },
            new Choice()
            {
                Value = "Receipt card",
                Synonyms = new List<string>() { "5", "receipt" }
            },
            new Choice()
            {
                Value = "Signin card",
                Synonyms = new List<string>() { "6", "signin" }
            },
            new Choice()
            {
                Value = "Thumbnail card",
                Synonyms = new List<string>() { "7", "thumbnail" }
            },
            new Choice()
            {
                Value = "Video card",
                Synonyms = new List<string>() { "8", "video" }
            }
        }
    };
}
private Attachment CreateAdaptiveCardAttachment()
{
    var adaptiveCard = File.ReadAllText(@".\adaptiveCard.json");
    return new Attachment()
    {
        ContentType = "application/vnd.microsoft.card.adaptive",
        Content = JsonConvert.DeserializeObject(adaptiveCard)
    };
}

private Attachment CreateAnimationCardAttachment()
{
    return new AnimationCard()
    {
        Title = "Microsoft Bot Framework",
        Media = new List<MediaUrl>()
            {
                new MediaUrl("http://i.giphy.com/Ki55RUbOV5njy.gif")
            },
        Subtitle = "Animation Card"
    }.ToAttachment();
}

private Attachment CreateAudioCardAttachment()
{
    return new AudioCard()
    {
        Title = "I am your father",
        Media = new List<MediaUrl>()
        {
            new MediaUrl("http://www.wavlist.com/movies/004/father.wav")
        },
        Buttons = new List<CardAction>()
        {
            new CardAction()
            {
                Type = ActionTypes.OpenUrl,
                Title = "Read more",
                Value = "https://en.wikipedia.org/wiki/The_Empire_Strikes_Back"
            }
        },
        Subtitle = "Star Wars: Episode V - The Empire Strikes Back",
        Text = "The Empire Strikes Back (also known as Star Wars: Episode V – The Empire Strikes Back) is a 1980 American epic space opera film directed by Irvin Kershner. Leigh Brackett and Lawrence Kasdan wrote the screenplay, with George Lucas writing the film\'s story and serving as executive producer. The second installment in the original Star Wars trilogy, it was produced by Gary Kurtz for Lucasfilm Ltd. and stars Mark Hamill, Harrison Ford, Carrie Fisher, Billy Dee Williams, Anthony Daniels, David Prowse, Kenny Baker, Peter Mayhew and Frank Oz.",
        Image = new ThumbnailUrl("https://upload.wikimedia.org/wikipedia/en/3/3c/SW_-_Empire_Strikes_Back.jpg")
    }.ToAttachment();
}

private Attachment CreateHeroCardAttachment()
{
    return new HeroCard()
    {
        Title = "",
        Images = new List<CardImage>()
        {
            new CardImage("https://sec.ch9.ms/ch9/7ff5/e07cfef0-aa3b-40bb-9baa-7c9ef8ff7ff5/buildreactionbotframework_960.jpg")
        },
        Buttons = new List<CardAction>()
        {
            new CardAction()
            {
                Type = ActionTypes.OpenUrl,
                Title = "Get Started",
                Value = "https://docs.microsoft.com/en-us/azure/bot-service/"
            }
        }
    }.ToAttachment();
}

private Attachment CreateReceiptCardAttachment()
{
    return new ReceiptCard()
    {
        Title = "John Doe",
        Facts = new List<Fact>()
        {
            new Fact(key: "Order Number", value: "1234"),
            new Fact(key: "Payment Method", value: "VISA 5555-****")
        },
        Items = new List<ReceiptItem>()
        {
            new ReceiptItem()
            {
                Title = "Data Transfer",
                Price = "$38.45",
                Quantity = "368",
                Image = new CardImage("https://github.com/amido/azure-vector-icons/raw/master/renders/traffic-manager.png")
            },
            new ReceiptItem()
            {
                Title = "App Service",
                Price = "$45.00",
                Quantity = "720",
                Image = new CardImage("https://github.com/amido/azure-vector-icons/raw/master/renders/cloud-service.png")
            }
        },
        Tax = "$7.50",
        Total = "$90.95",
        Buttons = new List<CardAction>()
        {
            new CardAction()
            {
                Type = ActionTypes.OpenUrl,
                Title = "More Information",
                Value = "https://azure.microsoft.com/en-us/pricing/details/bot-service/"
            }
        }
    }.ToAttachment();
}

private Attachment CreateSignInCardAttachment()
{
    return new SigninCard()
    {
        Text = "BotFramework Sign-in Card",
        Buttons = new List<CardAction>()
        {
            new CardAction()
            {
                Type = ActionTypes.Signin,
                Title = "Sign-in",
                Value = "https://login.microsoftonline.com"
            }
        }
    }.ToAttachment();
}

private Attachment CreateThumbnailCardAttachment()
{
    return new ThumbnailCard()
    {
        Title = "BotFramework Thumbnail Card",
        Images = new List<CardImage>()
        {
            new CardImage()
            {
                Url = "https://sec.ch9.ms/ch9/7ff5/e07cfef0-aa3b-40bb-9baa-7c9ef8ff7ff5/buildreactionbotframework_960.jpg"
            }
        },
        Buttons = new List<CardAction>()
        {
            new CardAction()
            {
                Type = ActionTypes.OpenUrl,
                Title = "Get Started",
                Value = "https://docs.microsoft.com/en-us/azure/bot-service/"
            }
        },
        Subtitle = "Your bots — wherever your users are talking",
        Text = "Build and connect intelligent bots to interact with your users naturally wherever they are, from text/sms to Skype, Slack, Office 365 mail and other popular services."
    }.ToAttachment();
}

private Attachment CreateVideoCardAttacment()
{
    return new VideoCard()
    {
        Title = "Big Buck Bunny",
        Media = new List<MediaUrl>()
        {
            new MediaUrl("http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4")
        },
        Buttons = new List<CardAction>()
        {
            new CardAction()
            {
                Type = ActionTypes.OpenUrl,
                Title = "Learn More",
                Value = "https://peach.blender.org/"
            }
        },
        Subtitle = "by the Blender Institute",
        Text = "Big Buck Bunny (code-named Peach) is a short computer-animated comedy film by the Blender Institute, part of the Blender Foundation. Like the foundation\'s previous film Elephants Dream, the film was made using Blender, a free software application for animation made by the same foundation. It was released as an open-source film under Creative Commons License Attribution 3.0."
    }.ToAttachment();
}
case "cards":
    context.Activity.Text = indexOfSpace >= 0
        ? context.Activity.Text.Substring(indexOfSpace + 1, message.Length - indexOfSpace - 1)
        : String.Empty;
    await dialogCtx.Begin("cards");
break;

В код чат-бота я добавил обработку команды cards по аналогии с предыдущими, а также добавил возможность отображения информации обо всех карточках и вывод списка доступных, процесс изменений отображать я не буду, так как все действия схожи с тем, что было ранее. Ссылка на исходники урока.

Выполняя команду cards мы можем увидеть список карточек, внешний вид и информацию о которых мы можем получить. Сразу введём 1 и увидим пример adaptive card. Далее будем выполнять команды cards и добавлять наименование нужной карточки либо её номер.

Карточки могут добавить вашим чат-ботам не только привлекательности, но и сделать их гораздо удобными в использовании, в зависимости от ваших целей выбирайте наиболее подходящий вам вариант для использования.

А на следующем уроке мы наконец-то узнаем, как происходит публикация чат-бота и его подключение к различным мессенджерам.

На этом всё, с Вами был Амельченя Андрей, приятного программирования.

Добавить комментарий