Добавление мультимедиа в сообщенияAdd media to messages

применимо к: Пакет SDK v4APPLIES TO: SDK v4

Обмен сообщениями между пользователем и ботом может включать вложения мультимедиа, такие как изображения, видео, аудио и файлы.Messages exchanged between user and bot can contain media attachments, such as images, video, audio, and files. Пакет SDK Bot Framework поддерживает задачу отправки пользователю форматированного сообщения.The Bot Framework SDK supports the task of sending rich messages to the user. Чтобы определить, какой тип форматированных сообщений поддерживает канал (Slack, Facebook и др.), см. сведения об ограничениях в документации по этому каналу.To determine the type of rich messages a channel (Facebook, Slack, etc.) supports, consult the channel's documentation for information about limitations.

Предварительные требованияPrerequisites

Отправка вложенийSend attachments

Чтобы отправить пользователю содержимое, например изображение или видео, нужно добавить вложение или список вложений в сообщение.To send the user content like an image or a video, you can add an attachment or list of attachments to a message.

Примеры доступных карточек см. в статье Проектирование взаимодействия с пользователем.See design user experience for examples of available cards.

Свойство Attachments объекта Activity содержит массив объектов Attachment, представляющих вложения в виде форматированных карточек и файлов мультимедиа.The Attachments property of the Activity object contains an array of Attachment objects that represent the media attachments and rich cards attached to the message. Чтобы добавить мультимедийное вложение в сообщение, создайте объект Attachment для действия reply (которое было создано из действия с помощью CreateReply()) и задайте свойства ContentType, ContentUrl и Name.To add a media attachment to a message, create an Attachment object for the reply activity (that was created off the activity with CreateReply()) and set the ContentType, ContentUrl, and Name properties.

Представленный здесь исходный код основан на примере обработки вложений.The source code shown here is based on the Handling Attachments sample.

Чтобы создать ответное сообщение, определите текст и настройте вложения.To create the reply message, define the text and then set up the attachments. Присвоение вложений ответному сообщению выполняется одинаково для всех типов вложений, но настройка и определение разных вложений будут отличаться, как показано в следующих фрагментах.Assigning the attachments to the reply is the same for each attachment type, however the various attachments are set up and defined differently, as seen in the following snippets. Ниже приведен код для настройки ответа со встроенным вложением:The code below is setting up the reply for an inline attachment:

Bots/AttachmentsBot.csBots/AttachmentsBot.cs

reply = MessageFactory.Text("This is an inline attachment.");
reply.Attachments = new List<Attachment>() { GetInlineAttachment() };

Далее мы рассмотрим разные типы вложений.Next, we look at the types of attachments. Во-первых, это встроенные вложения:First is an inline attachment:

Bots/AttachmentsBot.csBots/AttachmentsBot.cs

private static Attachment GetInlineAttachment()
{
    var imagePath = Path.Combine(Environment.CurrentDirectory, @"Resources", "architecture-resize.png");
    var imageData = Convert.ToBase64String(File.ReadAllBytes(imagePath));

    return new Attachment
    {
        Name = @"Resources\architecture-resize.png",
        ContentType = "image/png",
        ContentUrl = $"data:image/png;base64,{imageData}",
    };
}

Во-вторых, отправленные вложения:Then, an uploaded attachment:

Bots/AttachmentsBot.csBots/AttachmentsBot.cs

private static async Task<Attachment> GetUploadedAttachmentAsync(ITurnContext turnContext, string serviceUrl, string conversationId, CancellationToken cancellationToken)
{
    if (string.IsNullOrWhiteSpace(serviceUrl))
    {
        throw new ArgumentNullException(nameof(serviceUrl));
    }

    if (string.IsNullOrWhiteSpace(conversationId))
    {
        throw new ArgumentNullException(nameof(conversationId));
    }

    var imagePath = Path.Combine(Environment.CurrentDirectory, @"Resources", "architecture-resize.png");

    var connector = turnContext.TurnState.Get<IConnectorClient>() as ConnectorClient;
    var attachments = new Attachments(connector);
    var response = await attachments.Client.Conversations.UploadAttachmentAsync(
        conversationId,
        new AttachmentData
        {
            Name = @"Resources\architecture-resize.png",
            OriginalBase64 = File.ReadAllBytes(imagePath),
            Type = "image/png",
        },
        cancellationToken);

    var attachmentUri = attachments.GetAttachmentUri(response.Id);

    return new Attachment
    {
        Name = @"Resources\architecture-resize.png",
        ContentType = "image/png",
        ContentUrl = attachmentUri,
    };
}

И, в-третьих, вложения из Интернета:Lastly, an internet attachment:

Bots/AttachmentsBot.csBots/AttachmentsBot.cs

private static Attachment GetInternetAttachment()
{
    // ContentUrl must be HTTPS.
    return new Attachment
    {
        Name = @"Resources\architecture-resize.png",
        ContentType = "image/png",
        ContentUrl = "https://docs.microsoft.com/en-us/bot-framework/media/how-it-works/architecture-resize.png",
    };
}

Если вложение представляет собой изображение, аудиофайл или видео, служба соединителя будет передавать данные вложения каналу так, чтобы позволить каналу обрабатывать это вложение в диалоге.If an attachment is an image, audio, or video, the Connector service will communicate attachment data to the channel in a way that enables the channel to render that attachment within the conversation. Если вложение представляет собой файл, URL-адрес файла будет отображаться в диалоге как гиперссылка.If the attachment is a file, the file URL will be rendered as a hyperlink within the conversation.

Отправка карточки для имиджевого баннераSend a hero card

Помимо изображений или видео, вы можете прикрепить карточку для имиджевого баннера, которая позволяет совмещать изображения и кнопки в один объект и отправлять их в таком виде пользователю.Besides simple image or video attachments, you can attach a hero card, which allows you to combine images and buttons in one object, and send them to the user. Markdown поддерживается для большинства текстовых полей, но особенности поддержки зависят от канала.Markdown is supported for most text fields, but support may vary by channel.

Чтобы составить сообщение с карточкой имиджевого баннера и кнопкой, вложите HeroCard в сообщение.To compose a message with a hero card and button, you can attach a HeroCard to a message.

Представленный здесь исходный код основан на примере обработки вложений.The source code shown here is based on the Handling Attachments sample.

Bots/AttachmentsBot.csBots/AttachmentsBot.cs

private static async Task DisplayOptionsAsync(ITurnContext turnContext, CancellationToken cancellationToken)
{
    // Create a HeroCard with options for the user to interact with the bot.
    var card = new HeroCard
    {
        Text = "You can upload an image or select one of the following choices",
        Buttons = new List<CardAction>
        {
            // Note that some channels require different values to be used in order to get buttons to display text.
            // In this code the emulator is accounted for with the 'title' parameter, but in other channels you may
            // need to provide a value for other parameters like 'text' or 'displayText'.
            new CardAction(ActionTypes.ImBack, title: "1. Inline Attachment", value: "1"),
            new CardAction(ActionTypes.ImBack, title: "2. Internet Attachment", value: "2"),
            new CardAction(ActionTypes.ImBack, title: "3. Uploaded Attachment", value: "3"),
        },
    };

    var reply = MessageFactory.Attachment(card.ToAttachment());
    await turnContext.SendActivityAsync(reply, cancellationToken);
}

Обработка событий в форматированных карточкахProcess events within rich cards

Для обработки событий в форматированных карточках используйте объекты действий карточек, чтобы указать, какие действия должны происходить, когда пользователь нажимает кнопку или щелкает сегмент карточки.To process events within rich cards, use card action objects to specify what should happen when the user clicks a button or taps a section of the card. Каждое действие карточки имеет определенный тип и значение.Each card action has a type and value.

Во избежание ошибок следует назначить тип действия для каждого активного элемента карточки.To function correctly, assign an action type to each clickable item on the card. В этой таблице перечислены и описаны доступные типы действий и требуемый формат для связанного свойства.This table lists and describes the available action types and what should be in the associated value property.

ТипType ОписаниеDescription ЗначениеValue
openUrlopenUrl Открывает URL-адрес в окне встроенного браузера.Opens a URL in the built-in browser. URL-адрес, который нужно открыть.The URL to open.
imBackimBack Отправляет боту сообщение и отображает полученный ответ в чате.Sends a message to the bot, and posts a visible response in the chat. Текст отправляемого сообщения.Text of the message to send.
postBackpostBack Отправляет боту сообщение, но не всегда отображает полученный ответ в чате.Sends a message to the bot, and may not post a visible response in the chat. Текст отправляемого сообщения.Text of the message to send.
вызываетcall Инициирует телефонный звонок.Initiates a phone call. Целевое назначение телефонного звонка в следующем формате: tel:123123123123.Destination for the phone call in this format: tel:123123123123.
playAudioplayAudio Воспроизводит звук.Plays audio. URL-адрес для воспроизведения звука.The URL of the audio to play.
playVideoplayVideo Воспроизводит видео.Plays a video. URL-адрес для воспроизведения видео.The URL of video to play.
showImageshowImage Отображает изображение.Displays an image. URL-адрес для отображения изображения.The URL of the image to display.
downloadFiledownloadFile Скачивает файл.Downloads a file. URL-адрес для скачивания файла.The URL of the file to download.
signinsignin Инициирует процесс входа OAuth.Initiates an OAuth signin process. URL-адрес потока OAuth, который нужно запустить.The URL of the OAuth flow to initiate.

Карточка для имиджевого баннера с различными типами событийHero card using various event types

В следующем коде показаны примеры использования различных событий форматированных карточек.The following code shows examples using various rich card events.

Примеры для всех доступных типов карточек представлены в этом примере на C#.For examples of all the available cards, see the C# cards sample.

Cards.csCards.cs

public static HeroCard GetHeroCard()
{
    var heroCard = new HeroCard
    {
        Title = "BotFramework Hero Card",
        Subtitle = "Microsoft Bot Framework",
        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.",
        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(ActionTypes.OpenUrl, "Get Started", value: "https://docs.microsoft.com/bot-framework") },
    };

    return heroCard;
}

Cards.csCards.cs

public static SigninCard GetSigninCard()
{
    var signinCard = new SigninCard
    {
        Text = "BotFramework Sign-in Card",
        Buttons = new List<CardAction> { new CardAction(ActionTypes.Signin, "Sign-in", value: "https://login.microsoftonline.com/") },
    };

    return signinCard;
}

Отправка адаптивной карточкиSend an Adaptive Card

Адаптивные карточки и MessageFactory используются для отправки форматированных сообщений, включая тексты, изображения, видео, аудио и файлы для взаимодействия с пользователями.Adaptive Card and MessageFactory are used to send rich messages including texts, images, video, audio and files to communicate with users. Но между ними существуют некоторые отличия.However, there are some differences between them.

Во-первых, только некоторые каналы поддерживают адаптивные карточки и среди таких каналов есть те, которые могут поддерживать их частично.First, only some channels support Adaptive Cards, and channels that do support it might partially support Adaptive Cards. Например, при отправке адаптивной карточки в Facebook, кнопки не будут работать, а тексты и изображения будут отображаться.For example, if you send an Adaptive Card in Facebook, the buttons won't work while texts and images work well. MessageFactory — это просто вспомогательный класс в пакете SDK Bot Framework. Он позволяет автоматизировать действия по созданию и поддерживается большинством каналов.MessageFactory is just a helper class within the Bot Framework SDK to automate creation steps for you, and supported by most channels.

Во-вторых, адаптивная карточка отправляет сообщения в формате карточки и канал определяет макет карточки.Second, Adaptive Card delivers messages in the card format, and the channel determines the layout of the card. Формат сообщений, предоставляемый MessageFactory, зависит от канала, и это необязательно формат карточек, если только адаптивная карточка не является частью вложения.The format of messages MessageFactory delivers depends on the channel, and is not necessarily in the card format unless Adaptive Card is part of the attachment.

Последние сведения о поддержке каналов адаптивных карточек см. на странице конструктора адаптивных карточек.To find the latest information on Adaptive Card channel support, see the Adaptive Cards Designer.

Примечание

Вы должны протестировать эту функцию, выбрав каналы, которые будут использоваться ботом, чтобы определить, поддерживают ли они адаптивные карточки.You should test this feature with the channels your bot will use to determine whether those channels support adaptive cards.

Чтобы использовать адаптивные карточки, обязательно добавьте пакет NuGet AdaptiveCards.To use Adaptive Cards, be sure to add the AdaptiveCards NuGet package.

Представленный здесь исходный код основан на примере использования карточек.The source code shown here is based on the Using cards sample.

Cards.csCards.cs

Этот пример считывает файл JSON с адаптивной картой из файла и добавляет его в качестве вложения.This example reads the Adaptive Card JSON from a file and adds it as an attachment.

public static Attachment CreateAdaptiveCardAttachment()
{
    // combine path for cross platform support
    var paths = new[] { ".", "Resources", "adaptiveCard.json" };
    var adaptiveCardJson = File.ReadAllText(Path.Combine(paths));

    var adaptiveCardAttachment = new Attachment()
    {
        ContentType = "application/vnd.microsoft.card.adaptive",
        Content = JsonConvert.DeserializeObject(adaptiveCardJson),
    };

    return adaptiveCardAttachment;
}

Сообщения также могут включать несколько вложений в макете карусели, где вложения помещаются одно за другим и пользователь может их прокручивать.Messages can also include multiple attachments in a carousel layout, which places the attachments side by side and allows the user to scroll across.

Исходный код, показанный здесь, основан на образце карточек.The source code shown here is based on the cards sample.

Dialogs/MainDialog.csDialogs/MainDialog.cs

Сначала создайте ответ и определите вложения в виде списка.First, create the reply and define the attachments as a list.

// Cards are sent as Attachments in the Bot Framework.
// So we need to create a list of attachments for the reply activity.
var attachments = new List<Attachment>();

// Reply to the activity we received with an activity.
var reply = MessageFactory.Attachment(attachments);

Затем добавьте вложения и задайте для типа макета значение « _обойма_».Then add the attachments and set the layout type to carousel. Здесь мы добавляем их по одному, но вы можете управлять этим списком и добавлять в него карточки любым удобным методом.Here we're adding them one at a time, but feel free to manipulate the list to add the cards however you prefer.

// Display a carousel of all the rich card types.
reply.AttachmentLayout = AttachmentLayoutTypes.Carousel;
reply.Attachments.Add(Cards.CreateAdaptiveCardAttachment());
reply.Attachments.Add(Cards.GetAnimationCard().ToAttachment());
reply.Attachments.Add(Cards.GetAudioCard().ToAttachment());
reply.Attachments.Add(Cards.GetHeroCard().ToAttachment());
reply.Attachments.Add(Cards.GetOAuthCard().ToAttachment());
reply.Attachments.Add(Cards.GetReceiptCard().ToAttachment());
reply.Attachments.Add(Cards.GetSigninCard().ToAttachment());
reply.Attachments.Add(Cards.GetThumbnailCard().ToAttachment());
reply.Attachments.Add(Cards.GetVideoCard().ToAttachment());

Завершив добавление вложений, вы можете отправить этот ответ так же, как и любой другой.Once the attachments are added, you can send the reply just like any other.

// Send the card(s) to the user as an attachment to the activity
await stepContext.Context.SendActivityAsync(reply, cancellationToken);

Дополнительные ресурсыAdditional resources

Примеры доступных карточек см. в статье Проектирование взаимодействия с пользователем.See design user experience for examples of available cards.

См. дополнительные сведения о схеме карточек Bot Framework и действиях в беседах.For detailed information on the schema, see the Bot Framework card schema and the message activity section of the Bot Framework Activity schema.

Пример кода для обработки входных данных адаптивной карточкиCode sample for processing Adaptive Card input

В этом примере кода показан один из способов использования входных данных адаптивной карточки в пределах класса диалога бота.This sample code shows one way to use Adaptive Card inputs within a bot dialog class. Он расширяет текущий пример 06.using-cards, включая проверку входных данных, полученных в текстовом поле отвечающего клиента.It extends the current sample 06.using-cards by validating the input received in the text field from the responding client. Сначала мы добавили функцию ввода текста и кнопку к имеющейся адаптивной карточке, добавив следующий код перед последней скобкой adaptiveCard.json в папке ресурсов:We first added text input and button functionality to the existing adaptive card by adding the following code just before the final bracket of adaptiveCard.json, found in the resources folder:

"actions": [
  {
    "type": "Action.ShowCard",
    "title": "Text",
    "card": {
      "type": "AdaptiveCard",
      "body": [
        {
          "type": "Input.Text",
          "id": "text",
          "isMultiline": true,
          "placeholder": "Enter your comment"
        }
      ],
      "actions": [
        {
          "type": "Action.Submit",
          "title": "OK"
        }
      ]
    }
  }
]

Обратите внимание, что поле ввода называется "text", поэтому наша адаптивная карточка присоединит данные текста комментария как Value.[text.]Note that the input field is labeled "text" so our adaptive card will attach comment text data as Value.[text.]

Наш проверяющий элемент управления использует Newtonsoft.json, чтобы сначала преобразовать его в JObject, а затем создать обрезанную текстовую строку для сравнения.Our validator uses Newtonsoft.json to first convert this to a JObject, and then create a trimmed text string for comparison. Поэтому добавьте:So add:

using System;
using System.Linq;
using Newtonsoft.Json.Linq;

в MainDialog.cs и установите последнюю стабильную версию пакета nuget из Newtonsoft.Json.to MainDialog.cs and install the latest stable nuget package of Newtonsoft.Json. В коде проверяющего элемента управления мы добавили поток логики в комментариях в коде.In the validator code we added the logic flow into the code comments. Этот код ChoiceValidator() помещается в пример 06.using-cards, открытом для объявления MainDialog, сразу после закрытой фигурной скобки:This ChoiceValidator() code is placed into the 06.using-cards sample just after the closed brace public for declaration of MainDialog:

private async Task ChoiceValidator(
    PromptValidatorContext promptContext,
    CancellationToken cancellationToken)
{
    // Retrieves Adaptive Card comment text as JObject.
    // looks for JObject field "text" and converts that input into a trimmed text string.
    var jobject = promptContext.Context.Activity.Value as JObject;
    var jtoken = jobject?["text"];
    var text = jtoken?.Value().Trim();

    // Logic: 1. if succeeded = true, just return promptContext
    //        2. if false, see if JObject contained Adaptive Card input.
    //               No = (bad input) return promptContext
    //               Yes = update Value field with JObject text string, return "true".
    if (!promptContext.Recognized.Succeeded && text != null)
    {
        var choice = promptContext.Options.Choices.FirstOrDefault(
        c => c.Value.Equals(text, StringComparison.InvariantCultureIgnoreCase));
        if (choice != null)
        {
            promptContext.Recognized.Value = new FoundChoice
            {
                Value = choice.Value,
            };
            return true;
        }
    }
    return promptContext.Recognized.Succeeded;
}

Теперь выше в объявлении MainDialog измените:Now above in the MainDialog declaration change:

// Define the main dialog and its related components.
AddDialog(new ChoicePrompt(nameof(ChoicePrompt)));

на:to:

// Define the main dialog and its related components.
AddDialog(new ChoicePrompt(nameof(ChoicePrompt), ChoiceValidator));

При этом будет вызван проверяющий элемент управления для поиска входных данных адаптивной карточки каждый раз, когда создается ChoicePrompt.This will invoke your validator to look for Adaptive Card input each time a new ChoicePrompt is created.

Чтобы протестировать код, после отображения адаптивной карточки нажмите кнопку Text (Текст), введите допустимый вариант, например "Карточка имиджевого баннера", и нажмите кнопку OK.To test your code, once an Adaptive Card has been displayed, Click the "Text" button, Enter a valid selection such as "Hero Card" and click the "OK" button.

Проверка адаптивной карточки

  1. Первые входные данные будут использоваться для запуска нового диалога.The first input will be used to start a new dialog.
  2. Снова нажмите кнопку OK, и эти входные данные будут использоваться для выбора новой карточки.Click the "OK" button again and this input will be used to select a new card.

Дальнейшие действияNext steps