메시지에 미디어 추가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. Bot Framework SDK는 사용자에게 다양한 메시지를 보내는 작업을 지원합니다.The Bot Framework SDK supports the task of sending rich messages to the user. 채널(Facebook, Slack 등)에서 지원하는 다양한 메시지의 유형을 결정하려면 채널 설명서에서 제한 사항에 대한 정보를 참조하세요.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 the user experience for examples of available cards.

FAQ에서 채널을 사용 하 여 전송 되는 파일의 크기 제한은 무엇 인가요? 를 참조 하세요.See also What is the size limit of a file transferred using channels? in the FAQ.

이 섹션에 표시 되는 모든 소스 코드는 첨부 파일 처리 샘플을 기반으로 합니다.All of the source code shown in this section is based on the Handling attachments sample.

Activity 개체의 Attachments 속성에는 메시지에 첨부된 미디어 첨부 파일과 서식 있는 카드를 나타내는 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. 메시지에 미디어 첨부 파일을 추가하려면 reply 작업에 대한 Attachment 개체를 만들고 ContentType, ContentUrlName 속성을 설정합니다.To add a media attachment to a message, create an Attachment object for the reply activity and set the ContentType, ContentUrl, and Name properties.

회신 메시지를 만들려면 텍스트를 정의한 다음, 첨부 파일을 설정합니다.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 object 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 selects a button or taps a section of the card. 각 카드 작업에는 형식 속성이 있습니다.Each card action has a type and value property.

제대로 작동 하려면 주인공 카드의 클릭 가능한 각 항목에 작업 유형을 할당 합니다.To function correctly, assign an action type to each clickable item on a hero card. 이 표에는 사용 가능한 동작 유형 및 관련 값 속성에 필요한 항목과 관련 설명이 나와 있습니다.This table lists and describes the available action types and what should be in the associated value property. messageBack카드 작업은 다른 카드 작업 보다 일반화 된 의미를 가집니다.The messageBack card action has a more generalized meaning than the other card actions. 및 기타 카드 작업 유형에 대 한 자세한 내용은 활동 스키마카드 작업 섹션을 참조 하세요 messageBack .See the Card action section of the Activity schema for more information about the messageBack and other card action types.

형식Type 설명Description Value
callcall 전화 통화를 시작합니다.Initiates a phone call. 전화 통화 대상입니다(tel:123123123123 형식).Destination for the phone call in this format: tel:123123123123.
downloadFiledownloadFile 파일을 다운로드합니다.Downloads a file. 다운로드할 파일의 URL입니다.The URL of the file to download.
imBackimBack 봇에 메시지를 보내고 채팅에 표시 가능한 응답을 게시합니다.Sends a message to the bot, and posts a visible response in the chat. 보낼 메시지의 텍스트입니다.Text of the message to send.
messageBackmessageBack 채팅 시스템을 통해 보낼 텍스트 응답을 나타냅니다.Represents a text response to be sent via the chat system. 생성 된 메시지에 포함할 선택적 프로그래밍 값입니다.An optional programmatic value to include in generated messages.
openUrlopenUrl 기본 제공 브라우저에서 URL이 열립니다.Opens a URL in the built-in browser. 열려는 URL입니다.The URL to open.
playAudioplayAudio 오디오를 재생합니다.Plays audio. 재생할 오디오의 URL입니다.The URL of the audio to play.
playVideoplayVideo 비디오를 재생합니다.Plays a video. 재생할 비디오의 URL입니다.The URL of video to play.
postBackpostBack 봇에 메시지를 보내고 채팅에 표시 가능한 응답을 게시하지 않을 수 있습니다.Sends a message to the bot, and may not post a visible response in the chat. 보낼 메시지의 텍스트입니다.Text of the message to send.
showImageshowImage 이미지를 표시합니다.Displays an image. 표시할 이미지의 URL입니다.The URL of the image to display.
signinsignin OAuth 로그인 프로세스를 시작 합니다.Initiates an OAuth sign-in process. 시작할 OAuth 흐름의 URL입니다.The URL of the OAuth flow to initiate.

다양한 이벤트 유형을 사용하는 영웅 카드Hero card using various event types

다음 코드에서는 다양한 서식이 있는 카드 이벤트를 사용하는 예제를 보여 줍니다.The following code shows examples using various rich card events.

사용 가능한 모든 카드의 예는 카드 사용 샘플을 참조하세요.For examples of all the available cards, see the Using 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

메시지 팩터리 를 사용하여 첨부 파일이 포함된 메시지를 만들 수 있지만 적응형 카드는 특정 유형의 첨부 파일입니다.While you can use the message factory to create a message that contains an attachment (of any sort), an Adaptive Card is one specific type of attachment. 일부 채널은 적응형 카드 지원하지 않으며, 이 채널은 부분적으로만 지원할 수 있습니다.Note that some channels don't support Adaptive Cards, and channels that do may only partially support them. 예를 들어, Facebook에서 적응형 카드를 보내면 텍스트와 이미지가 제대로 작동하는 동안 단추가 작동하지 않습니다.For example, if you send an Adaptive Card in Facebook, the buttons won't work while texts and images work well. 메시지 팩터리 는 만들기 단계를 자동화하는 데 사용되는 Bot Framework SDK 도우미 클래스입니다.The message factory is a Bot Framework SDK helper class used to automate creation steps for you.

적응형 카드는 개발자가 일반적이고 일관된 방법으로 UI 콘텐츠를 교환할 수 있는 개방형 카드 교환 형식입니다.Adaptive Cards are an open card exchange format enabling developers to exchange UI content in a common and consistent way. 그러나 모든 채널이 적응형 카드 지원하지는 않습니다.However, not all channels support Adaptive Cards.

적응형 카드 디자이너는 적응형 카드를 작성하기 위한 풍부한 대화형 디자인 타임 환경을 제공합니다.The Adaptive Cards Designer provides a rich, interactive design-time experience for authoring adaptive cards.

참고

해당 채널이 적응형 카드를 지원하는지 여부를 확인하려면 봇이 사용할 채널을 통해 이 기능을 테스트해야 합니다.You should test this feature with the channels your bot will use to determine whether those channels support adaptive cards.

적응형 카드를 사용하려면 AdaptiveCards NuGet 패키지를 추가해야 합니다.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 Using 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 the Design the user experience article for examples of available cards.

스키마에 대한 자세한 내용은 Bot Framework 작업 스키마의 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

다음 샘플에서는 봇 대화 상자 클래스 내에서 적응 카드 입력을 사용 하는 한 가지 방법을 보여 줍니다.The following sample shows one way to use Adaptive Card inputs within a bot dialog class. 응답 하는 클라이언트에서 텍스트 필드에 받은 입력의 유효성을 검사 하 여 주인공 카드 샘플을 확장 합니다.It extends the hero cards sample by validating the input received in the text field from the responding client. 먼저 resources 폴더에 있는 adaptiveCard.js 의 마지막 대괄호 바로 앞에 다음 코드를 추가 하 여 텍스트 입력 및 단추 기능을 기존 적응 카드에 추가 해야 합니다.You first need to add the text input and button functionality to the existing adaptive card by adding the following code just before the final bracket of adaptiveCard.json, located 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"
        }
      ]
    }
  }
]

텍스트 입력 필드의 ID는로 설정 됩니다 "text" .Note that the ID of the text input field is set to "text". 사용자가 확인 을 선택 하면 선택 카드에서 생성 하는 메시지에는 "text" 사용자가 카드의 텍스트 입력 필드에 입력 한 정보가 포함 된 속성이 있는 속성 값이 포함 됩니다.When the user selects OK, the message the Adaptive Card generates will have a value property that has a property named "text" which contains the information the user entered in the text input field of the card.

이 유효성 검사기는 의Newtonsoft.js 사용 하 여 먼저이를로 변환 하 JObject 고, 비교를 위해 잘린 텍스트 문자열을 만듭니다.Our validator uses Newtonsoft.json to first convert this to a JObject, and then create a trimmed text string for comparison. 따라서 MainDialog.cs에 다음을 추가합니다.So add:

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

Maindialog. csNewtonsoft.Js 의 안정적인 최신 NuGet 패키지를 설치 합니다.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 메서드는 MainDialog 선언에 대해 폐쇄형 중괄호 public 바로 다음에 카드 사용 샘플에 배치 됩니다.This ChoiceValidator method is placed into the 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));

그러면 새 선택 프롬프트가 생성 될 때마다 적응 카드 입력을 찾기 위해 유효성 검사기가 호출 됩니다.This will invoke your validator to look for Adaptive Card input each time a new choice prompt is created.

코드를 테스트하려면 적응형 카드가 표시되면 텍스트 단추를 선택하고, Hero Card와 같은 유효한 선택 항목을 입력한 다음, 확인 단추를 선택합니다.To test your code, once an Adaptive Card has been displayed, select the Text button, Enter a valid selection such as Hero Card then select the OK button.

적응형 카드 테스트

  1. 첫 번째 입력은 새 대화 상자를 시작하는 데 사용됩니다.The first input will be used to start a new dialog.
  2. 확인 단추를 다시 선택하면 이 입력이 새 카드를 선택하는 데 사용됩니다.Select the OK button again and this input will be used to select a new card.

다음 단계Next steps