Exercice - Retourner des données de produit à partir de Microsoft Entra’API protégée
Dans cet exercice, vous mettez à jour l’extension de message pour récupérer des données à partir d’une API personnalisée. Vous obtenez des données à partir de l’API personnalisée en fonction de la requête de l’utilisateur et retournez des données dans les résultats de recherche à l’utilisateur.
Installer et configurer le proxy de développement
Dans cet exercice, vous utilisez dev Proxy, un outil en ligne de commande qui peut simuler des API. Il est utile lorsque vous souhaitez tester votre application sans avoir à créer une véritable API.
Pour effectuer cet exercice, vous devez installer la dernière version de Dev Proxy et télécharger la présélection dev Proxy pour ce module.
La présélection simule une API CRUD (Create, Read, Update, Delete) avec un magasin de données en mémoire, qui est protégé par Microsoft Entra. Cela signifie que vous pouvez tester votre application comme si elle appelait une API réelle qui nécessite une authentification.
Pour télécharger la présélection, exécutez la commande suivante dans votre terminal :
devproxy preset get learn-copilot-me-plugin
Obtenir la valeur de la requête utilisateur
Créez une méthode qui obtient la valeur de requête utilisateur par le nom du paramètre .
Dans Visual Studio et le projet ProductsPlugin :
Dans le dossier Helpers , créez un fichier nommé MessageExtensionHelpers.cs
Dans le fichier, ajoutez le code suivant :
using Microsoft.Bot.Schema.Teams; internal class MessageExtensionHelpers { internal static string GetQueryParameterValueByName(IList<MessagingExtensionParameter> parameters, string name) => parameters.FirstOrDefault(p => p.Name == name)?.Value as string ?? string.Empty; }
Save your changes
Ensuite, mettez à jour la méthode OnTeamsMessagingExtensionQueryAsync pour utiliser la nouvelle méthode d’assistance.
Dans le dossier Rechercher , ouvrez SearchApp.cs
Dans la méthode OnTeamsMessagingExtensionQueryAsync , remplacez le code suivant :
var text = query?.Parameters?[0]?.Value as string ?? string.Empty;
avec
var text = MessageExtensionHelpers.GetQueryParameterValueByName(query.Parameters, "ProductName");
Déplacez le curseur vers la variable de texte , utilisez
Ctrl + R
,Ctrl + R
et renommez la variable en nomSave your changes
La méthode OnTeamsMessagingExtensionQueryAsync doit maintenant ressembler à ceci :
protected override async Task<MessagingExtensionResponse> OnTeamsMessagingExtensionQueryAsync(ITurnContext<IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken)
{
var userTokenClient = turnContext.TurnState.Get<UserTokenClient>();
var tokenResponse = await AuthHelpers.GetToken(userTokenClient, query.State, turnContext.Activity.From.Id, turnContext.Activity.ChannelId, connectionName, cancellationToken);
if (!AuthHelpers.HasToken(tokenResponse))
{
return await AuthHelpers.CreateAuthResponse(userTokenClient, connectionName, (Activity)turnContext.Activity, cancellationToken);
}
var name = MessageExtensionHelpers.GetQueryParameterValueByName(query.Parameters, "ProductName");
var card = await File.ReadAllTextAsync(Path.Combine(".", "Resources", "card.json"), cancellationToken);
var template = new AdaptiveCardTemplate(card);
return new MessagingExtensionResponse
{
ComposeExtension = new MessagingExtensionResult
{
Type = "result",
AttachmentLayout = "list",
Attachments = [
new MessagingExtensionAttachment
{
ContentType = AdaptiveCard.ContentType,
Content = JsonConvert.DeserializeObject(template.Expand(new { title = name })),
Preview = new ThumbnailCard { Title = name }.ToAttachment()
}
]
}
};
}
Obtenir des données à partir de l’API personnalisée
Pour obtenir des données à partir de l’API personnalisée, vous devez envoyer le jeton d’accès dans l’en-tête Authorization de la demande et désérialiser la réponse dans un modèle qui représente les données du produit.
Tout d’abord, créez un modèle qui représente les données de produit retournées par l’API personnalisée.
Dans Visual Studio et le projet ProductsPlugin :
Créer un dossier nommé Models
Dans le dossier Models , créez un fichier nommé Product.cs
Dans le fichier, ajoutez le code suivant :
using System.Text.Json.Serialization; internal class Product { [JsonPropertyName("productId")] public int Id { get; set; } [JsonPropertyName("imageUrl")] public string ImageUrl { get; set; } [JsonPropertyName("name")] public string Name { get; set; } [JsonPropertyName("category")] public string Category { get; set; } [JsonPropertyName("callVolume")] public int CallVolume { get; set; } [JsonPropertyName("releaseDate")] public string ReleaseDate { get; set; } }
Save your changes
Ensuite, créez une classe de service qui récupère les données de produit à partir de l’API personnalisée.
Créer un dossier nommé Services
Dans le dossier Services , créez un fichier nommé ProductService.cs
Dans le fichier, ajoutez le code suivant :
using System.Net.Http.Headers; internal class ProductsService { private readonly HttpClient _httpClient; private readonly string _baseUri = "https://api.contoso.com/v1/"; internal ProductsService(string token) { _httpClient = new HttpClient(); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); } internal async Task<Product[]> GetProductsByNameAsync(string name) { var response = await _httpClient.GetAsync($"{_baseUri}products?name={name}"); response.EnsureSuccessStatusCode(); var jsonString = await response.Content.ReadAsStringAsync(); return System.Text.Json.JsonSerializer.Deserialize<Product[]>(jsonString); } }
Save your changes
La classe ProductsService contient des méthodes permettant d’obtenir des données de produit à partir de l’API personnalisée. Le constructeur de classe prend un jeton d’accès en tant que paramètre et configure un instance HttpClient avec le jeton d’accès dans l’en-tête Authorization.
Ensuite, mettez à jour la méthode OnTeamsMessagingExtensionQueryAsync pour utiliser la classe ProductsService pour obtenir des données de produit à partir de l’API personnalisée.
Dans le dossier Rechercher , ouvrez SearchApp.cs
Dans la méthode OnTeamsMessagingExtensionQueryAsync , ajoutez le code suivant après la déclaration de variable de nom pour obtenir les données de produit à partir de l’API personnalisée :
var productService = new ProductsService(tokenResponse.Token); var products = await productService.GetProductsByNameAsync(name);
Save your changes
Créer des résultats de recherche
Maintenant que vous disposez des données de produit, vous pouvez les inclure dans les résultats de recherche retournés à l’utilisateur.
Tout d’abord, nous allons mettre à jour le modèle de carte adaptative existant pour afficher les informations sur le produit.
Continuez dans Visual Studio et dans le projet ProductsPlugin :
Dans le dossier Ressources, renommez carte.json en Product.json
Dans le dossier Ressources , créez un fichier nommé Product.data.json. Ce fichier contient des exemples de données que Visual Studio utilise pour générer un aperçu du modèle de carte adaptative.
Dans le fichier , ajoutez le code JSON suivant :
{ "callVolume": 36, "category": "Enterprise", "imageUrl": "https://raw.githubusercontent.com/SharePoint/sp-dev-provisioning-templates/master/tenant/productsupport/source/Product%20Imagery/Contoso4.png", "name": "Contoso Quad", "productId": 1, "releaseDate": "2019-02-09" }
Save your changes
Dans le dossier Ressources , ouvrez Product.json
Dans le fichier, remplacez le contenu par le code JSON suivant :
{ "type": "AdaptiveCard", "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", "version": "1.5", "body": [ { "type": "TextBlock", "text": "${name}", "wrap": true, "style": "heading" }, { "type": "TextBlock", "text": "${category}", "wrap": true }, { "type": "Container", "items": [ { "type": "Image", "url": "${imageUrl}", "altText": "${name}" } ], "minHeight": "350px", "verticalContentAlignment": "Center", "horizontalAlignment": "Center" }, { "type": "FactSet", "facts": [ { "title": "Call Volume", "value": "${formatNumber(callVolume,0)}" }, { "title": "Release Date", "value": "${formatDateTime(releaseDate,'dd/MM/yyyy')}" } ] } ] }
Save your changes
Le modèle de carte adaptative utilise des expressions de liaison pour afficher les informations sur le produit. Les expressions ${name}, ${category}, ${imageUrl}, ${callVolume} et ${releaseDate} sont remplacées par les valeurs correspondantes des données du produit. Les fonctions de modèle formatNumber et formatDateTime sont utilisées pour mettre en forme les valeurs callVolume et releaseDate , respectivement en nombre et date.
Prenez un moment pour explorer la préversion de la carte adaptative dans Visual Studio. L’aperçu montre à quoi ressemble le modèle de carte adaptative lorsque les données du produit sont liées au modèle. Il utilise les exemples de données du fichier Product.data.json pour générer l’aperçu.
Ensuite, mettez à jour la propriété validDomains dans le manifeste de l’application pour inclure le domaine raw.githubusercontent.com , afin que les images du modèle carte adaptative puissent être affichées dans Microsoft Teams.
Dans le projet TeamsApp :
Dans le dossier appPackage , ouvrez manifest.json
Dans le fichier, ajoutez le domaine GitHub à la propriété validDomains :
"validDomains": [ "token.botframework.com", "raw.githubusercontent.com", "${{BOT_DOMAIN}}" ],
Save your changes
Ensuite, mettez à jour la méthode OnTeamsMessagingExtensionQueryAsync pour créer une liste de pièces jointes contenant les informations sur le produit.
Dans le projet ProductsPlugin :
Dans le dossier Rechercher , ouvrez SearchApp.cs
Mettez à jour carte.json sur Product.json pour refléter la modification du nom de fichier. Remplacez le code suivant :
var card = await File.ReadAllTextAsync(Path.Combine(".", "Resources", "card.json"), cancellationToken);
avec
var card = await File.ReadAllTextAsync(Path.Combine(".", "Resources", "Product.json"), cancellationToken);
Ajoutez le code suivant après la déclaration de variable de modèle pour créer une liste de pièces jointes :
var attachments = products.Select(product => { var content = 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();
Mettez à jour l’instruction return pour inclure la variable attachments :
return new MessagingExtensionResponse { ComposeExtension = new MessagingExtensionResult { Type = "result", AttachmentLayout = "list", Attachments = attachments } };
Enregistrer les modifications
Créer et mettre à jour des ressources
Une fois tout ce qui est maintenant en place, exécutez le processus Préparer les dépendances d’application Teams pour créer de nouvelles ressources et mettre à jour celles existantes.
Continuez dans Visual Studio :
- Dans Explorateur de solutions, cliquez avec le bouton droit sur le projet TeamsApp
- Développez le menu Kit de ressources Teams, sélectionnez Préparer les dépendances de l’application Teams.
- Dans la boîte de dialogue Compte Microsoft 365 , sélectionnez Continuer
- Dans la boîte de dialogue Provisionner , sélectionnez Provisionner
- Dans la boîte de dialogue d’avertissement du Kit de ressources Teams , sélectionnez Provisionner
- Dans la boîte de dialogue Informations du Kit de ressources Teams , sélectionnez l’icône en forme de croix pour fermer la boîte de dialogue
Exécuter et déboguer
Une fois les ressources approvisionnées, démarrez une session de débogage pour tester l’extension de message.
Tout d’abord, démarrez Dev Proxy pour simuler l’API personnalisée.
Ouvrir une fenêtre de terminal
Exécutez la commande suivante pour démarrer le proxy de développement :
devproxy --config-file "~appFolder/presets/learn-copilot-me-plugin/products-api-config.json"
Si vous y êtes invité, acceptez l’avertissement de certificat
Remarque
Lorsque le proxy de développement est en cours d’exécution, il agit comme un proxy à l’échelle du système.
Ensuite, démarrez une session de débogage dans Visual Studio :
Pour démarrer une nouvelle session de débogage, appuyez sur F5 ou sélectionnez Démarrer dans la barre d’outils
Attendez qu’une fenêtre de navigateur s’ouvre et que la boîte de dialogue d’installation de l’application s’affiche dans le client web Microsoft Teams. Si vous y êtes invité, entrez les informations d’identification de votre compte Microsoft 365.
Dans la boîte de dialogue d’installation de l’application, sélectionnez Ajouter
Ouvrir une conversation Microsoft Teams nouvelle ou existante
Dans la zone de composition des messages, sélectionnez + pour ouvrir le sélecteur d’application
Dans la liste des applications, sélectionnez Produits Contoso pour ouvrir l’extension de message
Dans la zone de texte, entrez mark8
Attendez que la recherche se termine et que les résultats s’affichent
Dans la liste des résultats, sélectionnez un résultat de recherche pour incorporer un carte dans la zone de message de composition
Revenez à Visual Studio et sélectionnez Arrêter dans la barre d’outils, ou appuyez sur Maj + F5 pour arrêter la session de débogage. En outre, arrêtez le proxy de développement à l’aide de Ctrl + C.