Esercizio - Restituire i dati del prodotto da Microsoft Entra'API protetta
In questo esercizio si aggiorna l'estensione del messaggio per recuperare i dati da un'API personalizzata. I dati vengono ottenuti dall'API personalizzata in base alla query dell'utente e vengono restituiti all'utente nei risultati della ricerca.
Installare e configurare Dev Proxy
In questo esercizio si usa Dev Proxy, uno strumento da riga di comando in grado di simulare le API. È utile quando si vuole testare l'app senza dover creare un'API reale.
Per completare questo esercizio, è necessario installare la versione più recente di Dev Proxy e scaricare il set di impostazioni di Dev Proxy per questo modulo.
Il set di impostazioni simula un'API CRUD (Create, Read, Update, Delete) con un archivio dati in memoria protetto da Microsoft Entra. Ciò significa che è possibile testare l'app come se chiamasse un'API reale che richiede l'autenticazione.
Per scaricare il set di impostazioni, eseguire il comando seguente nel terminale:
devproxy preset get learn-copilot-me-plugin
Ottenere il valore della query utente
Creare un metodo che ottiene il valore della query utente in base al nome del parametro.
In Visual Studio e nel progetto ProductsPlugin:
Nella cartella Helpers creare un nuovo file denominato MessageExtensionHelpers.cs
Nel file aggiungere il codice seguente:
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
Aggiornare quindi il metodo OnTeamsMessagingExtensionQueryAsync per usare il nuovo metodo helper.
Nella cartella Cerca aprire SearchApp.cs
Nel metodo OnTeamsMessagingExtensionQueryAsync sostituire il codice seguente:
var text = query?.Parameters?[0]?.Value as string ?? string.Empty;
con
var text = MessageExtensionHelpers.GetQueryParameterValueByName(query.Parameters, "ProductName");
Spostare il cursore nella variabile di testo , usare
Ctrl + R
,Ctrl + R
e rinominare la variabile in nomeSave your changes
Il metodo OnTeamsMessagingExtensionQueryAsync dovrebbe ora essere simile al seguente:
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()
}
]
}
};
}
Ottenere dati dall'API personalizzata
Per ottenere dati dall'API personalizzata, è necessario inviare il token di accesso nell'intestazione Authorization della richiesta e deserializzare la risposta in un modello che rappresenta i dati del prodotto.
Creare innanzitutto un modello che rappresenta i dati del prodotto restituiti dall'API personalizzata.
In Visual Studio e nel progetto ProductsPlugin:
Creare una cartella denominata Models
Nella cartella Models (Modelli) creare un nuovo file denominato Product.cs
Nel file aggiungere il codice seguente:
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
Creare quindi una classe di servizio che recupera i dati del prodotto dall'API personalizzata.
Creare una cartella denominata Services
Nella cartella Servizi creare un nuovo file denominato ProductService.cs
Nel file aggiungere il codice seguente:
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 contiene metodi per ottenere i dati di prodotto dall'API personalizzata. Il costruttore della classe accetta un token di accesso come parametro e configura un'istanza HttpClient con il token di accesso nell'intestazione Authorization.
Aggiornare quindi il metodo OnTeamsMessagingExtensionQueryAsync per usare la classe ProductsService per ottenere i dati del prodotto dall'API personalizzata.
Nella cartella Cerca aprire SearchApp.cs
Nel metodo OnTeamsMessagingExtensionQueryAsync aggiungere la dichiarazione della variabile code after name seguente per ottenere i dati del prodotto dall'API personalizzata:
var productService = new ProductsService(tokenResponse.Token); var products = await productService.GetProductsByNameAsync(name);
Save your changes
Creare i risultati della ricerca
Ora che sono disponibili i dati del prodotto, è possibile includerli nei risultati della ricerca restituiti all'utente.
Per prima cosa, aggiornare il modello di scheda adattiva esistente per visualizzare le informazioni sul prodotto.
Continuare in Visual Studio e nel progetto ProductsPlugin:
Nella cartella Risorse rinominare card.json in Product.json
Nella cartella Risorse creare un nuovo file denominato Product.data.json. Questo file contiene dati di esempio usati da Visual Studio per generare un'anteprima del modello di scheda adattiva.
Nel file aggiungere il codice JSON seguente:
{ "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
Nella cartella Risorse aprire Product.json
Nel file sostituire il contenuto con il codice JSON seguente:
{ "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
Il modello Scheda adattiva usa espressioni di associazione per visualizzare le informazioni sul prodotto. Le espressioni ${name}, ${category}, ${imageUrl}, ${callVolume}e ${releaseDate} vengono sostituite con i valori corrispondenti dai dati del prodotto. Le funzioni modello formatNumber e formatDateTime vengono usate per formattare rispettivamente i valori callVolume e releaseDate in un numero e una data.
Dedicare un momento all'esplorazione dell'anteprima della scheda adattiva in Visual Studio. L'anteprima mostra l'aspetto del modello di scheda adattiva quando i dati del prodotto sono associati al modello. Usa i dati di esempio del file Product.data.json per generare l'anteprima.
Aggiornare quindi la proprietà validDomains nel manifesto dell'app per includere il dominio raw.githubusercontent.com , in modo che le immagini nel modello di scheda adattiva possano essere visualizzate in Microsoft Teams.
Nel progetto TeamsApp:
Nella cartella appPackage aprire manifest.json
Nel file aggiungere il dominio GitHub alla proprietà validDomains :
"validDomains": [ "token.botframework.com", "raw.githubusercontent.com", "${{BOT_DOMAIN}}" ],
Save your changes
Aggiornare quindi il metodo OnTeamsMessagingExtensionQueryAsync per creare un elenco di allegati contenenti le informazioni sul prodotto.
Nel progetto ProductsPlugin:
Nella cartella Cerca aprire SearchApp.cs
Aggiornare card.json a Product.json, in modo da riflettere la modifica nel nome del file. Sostituire il codice seguente:
var card = await File.ReadAllTextAsync(Path.Combine(".", "Resources", "card.json"), cancellationToken);
con
var card = await File.ReadAllTextAsync(Path.Combine(".", "Resources", "Product.json"), cancellationToken);
Aggiungere il codice seguente dopo la dichiarazione della variabile di modello per creare un elenco di allegati:
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();
Aggiornare l'istruzione return per includere la variabile attachments :
return new MessagingExtensionResponse { ComposeExtension = new MessagingExtensionResult { Type = "result", AttachmentLayout = "list", Attachments = attachments } };
Salvare le modifiche
Creare e aggiornare le risorse
Con tutto ciò che è ora disponibile, eseguire il processo Preparare le dipendenze delle app di Teams per creare nuove risorse e aggiornarne di quelle esistenti.
Continuare in Visual Studio:
- In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto TeamsApp
- Espandere il menu Teams Toolkit, selezionare Prepare Teams App Dependencies (Preparare le dipendenze delle app di Teams)
- Nella finestra di dialogo Account Microsoft 365 selezionare Continua
- Nella finestra di dialogo Provision (Provision ) selezionare Provisioning (Provisioning)
- Nella finestra di dialogo di avviso di Teams Toolkit selezionare Provisioning
- Nella finestra di dialogo Informazioni di Teams Toolkit selezionare l'icona a croce per chiudere la finestra di dialogo
Eseguire ed eseguire il debug
Con il provisioning delle risorse, avviare una sessione di debug per testare l'estensione del messaggio.
Avviare innanzitutto Dev Proxy per simulare l'API personalizzata.
Aprire una finestra del terminale
Eseguire il comando seguente per avviare Dev Proxy:
devproxy --config-file "~appFolder/presets/learn-copilot-me-plugin/products-api-config.json"
Se richiesto, accettare l'avviso del certificato
Nota
Quando Dev Proxy è in esecuzione, funge da proxy a livello di sistema.
Avviare quindi una sessione di debug in Visual Studio:
Per avviare una nuova sessione di debug, premere F5 o selezionare Avvia dalla barra degli strumenti
Attendere l'apertura di una finestra del browser e la finestra di dialogo di installazione dell'app viene visualizzata nel client Web di Microsoft Teams. Se richiesto, immettere le credenziali dell'account Microsoft 365.
Nella finestra di dialogo di installazione dell'app selezionare Aggiungi
Aprire una chat di Microsoft Teams nuova o esistente
Nell'area di composizione dei messaggi selezionare + per aprire la selezione app
Nell'elenco delle app selezionare Prodotti Contoso per aprire l'estensione del messaggio
Nella casella di testo immettere mark8
Attendere il completamento della ricerca e visualizzare i risultati
Nell'elenco dei risultati selezionare un risultato di ricerca per incorporare una scheda nella finestra di messaggio compose
Tornare a Visual Studio e selezionare Arresta dalla barra degli strumenti oppure premere MAIUSC + F5 per arrestare la sessione di debug. Inoltre, arrestare Dev Proxy usando CTRL + C.