Return product data from Microsoft Entra protected API

Completed

In this unit, you learn how to return data from an API in a search-based message extension response.

Handle search queries

When a user enters a search query, the bot service sends a request to the messaging extension endpoint. The request contains the search query entered by the user. You use the search query to search for data in an external system, which can be used in the search results.

You access the search query entered by the user using the Query property of the MessagingExtensionQuery object in the OnTeamsMessagingExtensionQueryAsync method. The Parameters property of the MessagingExtensionQuery object contains the parameters that were passed to the messaging extension when it was invoked. The Parameters property is a list of key-value pairs that contains the name and value of each parameter.

Adaptive Card templates

An Adaptive Card is a declarative format for creating platform-agnostic UI components, which provide a consistent user experience across different platforms and devices.

Adaptive Card templates are JSON files that define the structure of an Adaptive Card. Using an Adaptive Card templates allows you to define the structure of the card in a separate file and bind data to the card at runtime.

You use Adaptive Card templates to create the content of the search results that are embedded in the message compose area when the user selects a search result.

The following code snippet shows a basic example of an Adaptive Card template:

{
  "type": "AdaptiveCard",
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.5",
  "body": [
    {
      "type": "TextBlock",
      "text": "${name}",
      "wrap": true,
      "style": "heading"
    }
  ]
}

Adaptive Card templates use express bindings to bind data to the card. You use the Expand method of the AdaptiveCardTemplate object to bind data to the card. The Expand method replaces the express bindings in the template with data from an object. The express bindings are enclosed in ${}. For example, ${name} is an express binding that is replaced with the value of the name property when the card is rendered.

The following code snippet shows how to create an AdaptiveCardTemplate object, bind data to the card and deserialize the expanded template to a JSON object:

var cardJson = await File.ReadAllTextAsync(Path.Combine(".", "Resources", "card.json"), cancellationToken);
var template = new AdaptiveCardTemplate(cardJson);
var expandedTemplate = template.Expand({ name: "Product" });
var content = JsonConvert.DeserializeObject(expandedTemplate);

You first read the Adaptive Card template from a file and create an AdaptiveCardTemplate object. You then use the Expand method to bind data to the card. The Expand method replaces the express bindings in the template with the data from the object. Finally, you deserialize the expanded template to a JSON object, which can be used in the Content property of a MessagingExtensionAttachment object.

Message extension response

A message extension must always return a response to a user search query. The MessagingExtensionResponse object is used to return a response to the user. When returning results to the user, you include a composeExtension object in the response. The composeExtension object contains a MessagingExtensionResult object that contains the results to be displayed to the user.

The following code snippet shows how to return a response to the user:

return new MessagingExtensionResponse
{
    ComposeExtension = new MessagingExtensionResult
    {
        Type = "result",
        AttachmentLayout = "list",
        Attachments = attachments
    }
};

The Attachments property of the MessagingExtensionResult object contains a list of MessagingExtensionAttachment objects.

Each MessagingExtensionAttachment object represents a search result that is displayed to the user. A MessagingExtensionAttachment object contains the following properties:

  • ContentType: The content type of the attachment.
  • Content: The content of the attachment that represents the card that is embedded in to the message compose area when the user selects the search result.
  • Preview: The preview of the attachment that represents the card that is displayed in the search results.

The following code snippet shows how to create a list of MessagingExtensionAttachment objects that contains an Adaptive Card and preview card for each search result:

var attachments = products.Select(product =>
{
    var expandedTemplate = template.Expand(product);

    return new MessagingExtensionAttachment
    {
        ContentType = AdaptiveCard.ContentType,
        Content = JsonConvert.DeserializeObject(content),
        Preview = new ThumbnailCard
        {
            Title = product.Name,
            Subtitle = product.Category,
            Images = [new() { Url = product.ImageUrl }]
        }.ToAttachment()
    };
}).ToList();