Envoyer des pièces jointes multimédias avec le kit de développement logiciel (SDK) Bot Framework

S'APPLIQUE À : SDK v4

Les messages échangés entre l’utilisateur et le bot peuvent contenir des pièces jointes multimédia, comme des images, des vidéos, des pistes audio et des fichiers. Le kit SDK Bot Framework prend en charge l’envoi de messages enrichis à l’utilisateur. Pour déterminer le type de messages enrichis pris en charge par un canal (Facebook, Slack, etc.), consultez la documentation du canal pour obtenir des informations sur les limitations.

Remarque

Les kits SDK JavaScript, C# et Python Bot Framework continueront d’être pris en charge. Toutefois, le kit de développement logiciel (SDK) Java est mis hors service avec une prise en charge finale à long terme se terminant en novembre 2023.

Les bots existants créés avec le kit de développement logiciel (SDK) Java continueront de fonctionner.

Pour la nouvelle génération de bots, envisagez d’utiliser Microsoft Copilot Studio et lisez-en plus sur le choix de la solution copilote appropriée.

Pour plus d’informations, consultez Les futures versions de bot.

Prérequis

Envoyer des pièces jointes

Pour envoyer le contenu de l’utilisateur comme une image ou une vidéo, vous pouvez ajouter une pièce jointe ou une liste de pièces jointes à un message.

Consultez Concevoir l'expérience utilisateur pour obtenir des exemples de cartes disponibles.

Consultez également Quelle est la limite de taille d'un fichier transféré à l'aide des canaux ? dans la FAQ.

L'ensemble du code source présenté dans cette section est basé sur l'exemple Gestion des pièces jointes.

La propriété Attachments de l’objet Activity contient un tableau d’objets Attachment qui représentent les pièces jointes multimédias et cartes enrichies attachées au message. Pour ajouter une pièce jointe multimédia à un message, créez un objet Attachment pour l’activité reply et définissez les propriétés ContentType, ContentUrl et Name.

Pour créer le message de réponse, définissez le texte, puis configurez les pièces jointes. L’affectation des pièces jointes à la réponse est identique pour chaque type de pièce jointe, cependant les pièces jointes diverses sont configurées et définies différemment, comme illustré dans les extraits de code suivants. Le code ci-dessous configure la réponse pour une pièce jointe insérée :

Bots/AttachmentsBot.cs

{
    reply = MessageFactory.Text("This is an inline attachment.");

Il nous faut ensuite regarder les types de pièces jointes. Tout d’abord, la pièce jointe insérée :

Bots/AttachmentsBot.cs

{
    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}",
    };
}

Ensuite, en pièce jointe chargée :

Bots/AttachmentsBot.cs

{
    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,
    };
}

Enfin, la pièce jointe internet :

Bots/AttachmentsBot.cs

    {
        // 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",
        };
    }
}

Si la pièce jointe est une image, un contenu audio ou une vidéo, le service Connector communique les données de pièce jointe au canal de manière à permettre au canal d’afficher cette pièce jointe dans la conversation. Si la pièce jointe est un fichier, l’URL du fichier s’affiche sous la forme d’un lien hypertexte dans la conversation.

Envoyer une carte de héros

Outre les simples pièces jointes image ou vidéo, vous pouvez attacher une carte de héros, qui vous permet de combiner des images et des boutons dans un seul objet à envoyer à l’utilisateur. Markdown est pris en charge pour la plupart des champs de texte, mais sa prise en charge varie selon le canal.

Pour composer un message avec un bouton et une carte de héros, vous pouvez joindre un objet HeroCard à un message.

Le code source suivant provient de l'exemple Gestion des pièces jointes.

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

Traiter des événements dans les cartes enrichies

Pour traiter les événements dans les cartes enrichies, utilisez les objets d'action de carte pour spécifier ce qui doit se produire quand l'utilisateur sélectionne un bouton ou appuie sur une section de la carte. Chaque action de carte possède une propriété de type et de valeur.

Pour bien fonctionner, il faut attribuer un type d'action à chaque élément interactif sur une carte de héros. Ce tableau liste et décrit les types d’actions disponibles, et ce qui doit se trouver dans la propriété de valeur associée.

L'action de carte messageBack a une signification plus généralisée que les autres. Consultez la section Action de carte du schéma d'activité pour plus d'informations sur le messageBack et les autres types d'action de carte.

Type Description active
call Procède à un appel téléphonique. Destination d’un appel téléphonique au format suivant : tel:123123123123.
downloadFile Télécharge un fichier. URL du fichier à télécharger.
imBack Envoie un message au bot et publie une réponse visible dans la conversation. Texte du message à envoyer.
messageBack Représente une réponse textuelle à envoyer par le biais du système de conversation. Valeur programmatique facultative à inclure dans les messages générés.
openUrl Ouvre une URL dans le navigateur intégré. URL à ouvrir.
playAudio Lit le contenu audio. URL du contenu audio à lire.
playVideo Lit une vidéo. URL de la vidéo à lire.
postBack Envoie un message au bot et ne publie pas une réponse visible dans la conversation. Texte du message à envoyer.
showImage Affiche une image. URL de l’image à afficher.
signin Lance un processus de connexion OAuth. URL du flux OAuth à lancer.

Carte de héros utilisant différents types d’événements

Le code suivant montre des exemples d’utilisation de différents événements de carte enrichie.

Pour des exemples de toutes les cartes disponibles, consultez l'exemple Utilisation des cartes.

Cards.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.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;
}

Envoyer une carte adaptative

Bien que vous puissiez utiliser la fabrique de messages pour créer un message qui contient une pièce jointe (de n'importe quel type), une carte adaptative est un type spécifique de pièce jointe. Tous les canaux ne prennent pas en charge les cartes adaptatives, et certains canaux ne le font que partiellement. Par exemple, si vous envoyez une carte adaptative dans Facebook, les boutons sont inopérants, alors que les textes et images fonctionnent parfaitement. La fabrique de messages est une classe d'aide du Kit de développement logiciel (SDK) Bot Framework utilisée pour automatiser les étapes de création.

Les cartes adaptatives sont un format d’échange de cartes ouvert permettant aux développeurs d’échanger du contenu d’interface utilisateur de manière commune et cohérente. Cependant, les canaux ne prennent pas tous en charge les cartes adaptatives.

Le concepteur de cartes adaptatives offre une expérience de conception riche et interactive pour la création de cartes adaptatives.

Remarque

Vous devez tester cette fonctionnalité avec les canaux que votre bot utilise pour déterminer s’ils prennent en charge les cartes adaptatives.

Pour utiliser des cartes adaptatives, veillez à ajouter le package NuGet AdaptiveCards.

Le code source suivant provient de l'exemple Utilisation de cartes.

Cards.cs

Cet exemple lit le JSON de la carte adaptative à partir d'un fichier et l'ajoute en tant que pièce jointe.

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

Les messages peuvent également inclure plusieurs pièces jointes dans une disposition carrousel, qui place les pièces jointes côte à côte et permet à l’utilisateur de faire défiler latéralement.

Le code source suivant provient de l'exemple Utilisation de cartes.

Dialogs/MainDialog.cs

En premier lieu, créez la réponse et définissez les pièces jointes sous forme de liste.

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

Ajoutez ensuite les pièces jointes et définissez le type de disposition sur carrousel. Nous les ajoutons une à une ici, mais n’hésitez pas à arranger la liste pour ajouter les cartes à votre convenance.

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

Une fois les pièces jointes ajoutées, vous pouvez envoyer la réponse comme n’importe quelle autre réponse.

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

Exemple de code pour le traitement d’une entrée de carte adaptative

L'exemple suivant illustre une façon d'utiliser les entrées de la carte adaptative dans une classe de dialogue de bot. Il élargit l'exemple des cartes de héros en validant l'entrée reçue dans le champ de texte du client qui répond. Vous devez d'abord ajouter la fonctionnalité de saisie de texte et de bouton à la carte adaptative existante en ajoutant le code suivant juste avant le crochet final de adaptiveCard.json, qui se trouve dans le dossier des ressources :

"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"
        }
      ]
    }
  }
]

L'ID du champ d'entrée de texte est défini sur « texte ». Lorsque l'utilisateur sélectionne OK, le message généré par la carte adaptative a une propriété de valeur nommée text qui contient les informations entrées par l'utilisateur dans le champ d'entrée de texte de la carte.

Notre validateur utilise Newtonsoft.json pour le convertir en JObject, puis pour créer une chaîne de texte tronquée à des fins de comparaison. Par conséquent, ajoutez :

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

à MainDialog.cs et installez le dernier package NuGet stable de Newtonsoft.Json. Dans le code du validateur, nous avons ajouté le flux logique dans les commentaires du code. Cette méthode ChoiceValidator est placée dans l'exemple Utilisation de cartes juste après l'accolade fermée publique pour la déclaration de 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;
}

À présent, ci-dessus, dans la déclaration MainDialog, changez :

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

le validateur recherchera ainsi les données de la carte adaptative chaque fois qu'une nouvelle invite de choix sera créée.

Tester le bot Utilisation de cartes

  1. Exécutez l'exemple Utilisation de cartes localement et ouvrez le bot dans Bot Framework Emulator.
  2. Suivez les invites du bot pour afficher un type de carte, par exemple une carte adaptative.

Étapes suivantes