Extension de message basée sur l’API
Remarque
Les extensions de message basées sur l’API prennent uniquement en charge les commandes de recherche.
Les extensions de message générées à l’aide de l’API (basées sur l’API) utilisent un service web pour gérer les demandes et les réponses des utilisateurs et ne nécessitent pas d’inscription de bot. Les extensions de message basées sur l’API sont une fonctionnalité d’application Microsoft Teams qui intègre des API externes directement dans Teams, ce qui améliore la facilité d’utilisation de votre application et offre une expérience utilisateur transparente. Les extensions de message basées sur l’API prennent en charge les commandes de recherche et peuvent être utilisées pour extraire et afficher des données à partir de services externes dans Teams, ce qui simplifie les flux de travail en réduisant le besoin de basculer entre les applications. Les extensions de message basées sur l’API aident vos applications à interagir directement avec des données, des applications et des services tiers, ce qui améliore leurs fonctionnalités. Avec l’extension de message basée sur l’API, vous pouvez :
- Récupérer des informations en temps réel, telles que la couverture des dernières actualités sur le lancement d’un produit.
- Récupérer des informations basées sur les connaissances, par exemple les fichiers de conception de mon équipe dans Figma
Regardez la vidéo pour en savoir plus sur la création d’une extension de message basée sur l’API à l’aide de Teams Toolkit :
Extensions de message traditionnelles basées sur un bot | Extensions de message basées sur l’API |
---|---|
Les développeurs doivent créer, déployer et gérer un service pour gérer les commandes d’appel à partir du client Teams. | Si les API du service final peuvent être décrites à l’aide de la spécification OpenAPI, les développeurs peuvent éliminer le besoin du service de gestion de couche intermédiaire. |
Ce service traite la requête entrante et effectue un appel au service final du développeur. | Teams peut utiliser directement la spécification OpenAPI pour générer des demandes et communiquer avec le service final du développeur. |
Les images suivantes montrent le flux des requêtes utilisateur via les extensions de message traditionnelles et les extensions de message d’API :
Flux de requête utilisateur utilisant des extensions de message traditionnelles. Le développeur doit gérer un service de gestionnaire de bot personnalisé, qui gère les demandes d’un bot Teams. Le service gestionnaire envoie une requête au service du développeur lorsqu’une requête est appelée.
Flux de requête utilisateur à l’aide d’extensions de message d’API. Il n’est pas nécessaire d’utiliser un service de gestionnaire géré par le développeur tant que l’interaction est clairement décrite dans la spécification OpenAPI du package d’application.
Voici une séquence d’événements de haut niveau qui se produisent lors d’un appel de commande de requête :
Lorsqu’un utilisateur appelle une commande de requête, les paramètres de la commande de requête sont reçus par le Bot Service Teams.
La commande de requête est définie dans le fichier manifeste de l’application. La définition de commande contient une référence à l’intérieur
operationId
du fichier de spécification OpenAPI, ainsi que les détails des paramètres rendus par le client Teams pour cette commande. À titre de référence, leoperationId
à l’intérieur du fichier de spécification OpenAPI est unique à une opération HTTP particulière.Le Bot Service Teams utilise ensuite les paramètres fournis par l’utilisateur ainsi que la copie de la spécification OpenAPI pour le associé
operationId
afin de générer une requête HTTP pour le point de terminaison du développeur.Si l’authentification est requise et est configurée dans le manifeste. Il est résolu en jeton ou clé approprié. Ce jeton ou cette clé est utilisé dans le cadre de la demande sortante. [Facultatif]
Le service de bot Teams effectue la requête HTTP au service du développeur.
Le service du développeur doit répondre conformément au schéma décrit dans la spécification OpenAPI. Il est au format JSON.
Le client Teams doit afficher les résultats à l’utilisateur. Pour convertir les résultats JSON de l’étape précédente en interface utilisateur, le service de bot Teams utilise le modèle de rendu de réponse pour générer une carte adaptative pour chaque résultat.
Les cartes adaptatives sont envoyées au client, qui les affiche dans l’interface utilisateur.
Configuration requise
Le package de définition d’application inclut divers artefacts attrayants qui prennent en charge les fonctionnalités de cette fonctionnalité. Avant de commencer, assurez-vous d’avoir une compréhension de base des fichiers suivants :
Description OpenAPI (OAD)
Le documenat de description OpenAPI est une norme industrielle adoptée pour décrire les API. Il vous permet d’extraire vos API de leur implémentation, en fournissant des définitions indépendantes du langage qui sont à la fois lisibles par l’utilisateur et lisibles par machine. Le documenat de description OpenAPI décrit les interactions que votre extension prend en charge, ce qui permet à Teams de générer des demandes et de communiquer directement avec votre service sans avoir besoin d’un service de gestion de couche intermédiaire.
Un document de description OpenAPI contient des détails pour communiquer avec le service du développeur. Vérifiez que vous respectez les instructions suivantes pour le document De description OpenAPI (OAD) :
- Les versions 2.0 et 3.0.x d’OpenAPI sont prises en charge.
- JSON et YAML sont les formats pris en charge.
- Le corps de la demande, s’il est présent, doit être application/Json.
- Définissez une URL de serveur de protocole HTTPS pour la
servers.url
propriété . - Seules les méthodes POST et GET HTTP sont prises en charge.
- Le document De description OpenAPI doit avoir un
operationId
. - Un seul paramètre obligatoire sans valeur par défaut est autorisé.
- Un paramètre obligatoire avec une valeur par défaut est considéré comme facultatif.
- Les utilisateurs ne doivent pas entrer de paramètre pour un en-tête ou un cookie.
- L’opération ne doit pas avoir d’en-tête ou de paramètres de cookie requis sans valeurs par défaut.
- Vérifiez qu’il n’existe aucune référence distante dans le document Description OpenAPI.
- La construction de tableaux pour la requête n’est pas prise en charge ; toutefois, les objets imbriqués dans un corps de requête JSON sont pris en charge.
- Teams ne prend pas en charge les
oneOf
constructions ,anyOf
allOf
, etnot
(swagger.io).
Le code suivant est un exemple de document de description OpenAPI :
Exemple de document de description OpenAPI
openapi: 3.0.1
info:
title: OpenTools Plugin
description: A plugin that allows the user to find the most appropriate AI tools for their use cases, with their pricing information.
version: 'v1'
servers:
- url: https://gptplugin.opentools.ai
paths:
/tools:
get:
operationId: searchTools
summary: Search for AI Tools
parameters:
- in: query
name: search
required: true
schema:
type: string
description: Used to search for AI tools by their category based on the keywords. For example, ?search="tool to create music" will give tools that can create music.
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/searchToolsResponse'
"400":
description: Search Error
content:
application/json:
schema:
$ref: '#/components/schemas/searchToolsError'
components:
schemas:
searchToolsResponse:
required:
- search
type: object
properties:
tools:
type: array
items:
type: object
properties:
name:
type: string
description: The name of the tool.
opentools_url:
type: string
description: The URL to access the tool.
main_summary:
type: string
description: A summary of what the tool is.
pricing_summary:
type: string
description: A summary of the pricing of the tool.
categories:
type: array
items:
type: string
description: The categories assigned to the tool.
platforms:
type: array
items:
type: string
description: The platforms that this tool is available on.
description: The list of AI tools.
searchToolsError:
type: object
properties:
message:
type: string
description: Message of the error.
Pour plus d’informations sur l’écriture de définitions OpenAPI dans YAML, consultez Structure OpenAPI.
Manifeste d'application
Le manifeste d’application est un blueprint pour votre application Teams, qui définit comment et où l’extension de message est appelée dans le client Teams. Il inclut les commandes que votre extension prend en charge et les emplacements à partir desquels elles sont accessibles, tels que la zone de rédaction des messages, la barre de commandes et le message. Le manifeste est lié à la spécification OpenAPI et au modèle de rendu de réponse pour garantir les fonctionnalités appropriées.
Le manifeste d’application contient la définition de commande de requête. Veillez à respecter les instructions suivantes pour le manifeste de l’application :
- Définissez la version du manifeste de l’application sur
1.17
. - Définissez sur
composeExtensions.composeExtensionType
apiBased
. - Définissez
composeExtensions.apiSpecificationFile
comme chemin d’accès relatif au document De description OpenAPI dans le dossier . Cela lie le manifeste de l’application à la spécification de l’API. - Définissez
apiResponseRenderingTemplateFile
comme chemin d’accès relatif au modèle de rendu de réponse. Cela spécifie l’emplacement du modèle utilisé pour le rendu des réponses de l’API. - Chaque commande doit avoir un lien vers le modèle de rendu de réponse. Cela connecte chaque commande à son format de réponse correspondant.
- La
Commands.id
propriété dans le manifeste de l’application doit correspondre auoperationId
dans le document Description OpenAPI. - Si un paramètre requis est sans valeur par défaut, la commande
parameters.name
dans le manifeste de l’application doit correspondre à dansparameters.name
le document de description OpenAPI. - Si aucun paramètre n’est requis, la commande
parameters.name
dans le manifeste de l’application doit correspondre au facultatifparameters.name
dans le document Description OpenAPI. - Vérifiez que le nom des paramètres de chaque commande dans le manifeste de l’application correspond exactement au nom correspondant du paramètre défini pour l’opération dans le document Description OpenAPI.
- Un modèle de rendu de réponse doit être défini par commande, qui est utilisée pour convertir des réponses à partir d’une API.
- Les descriptions des commandes et des paramètres ne doivent pas dépasser 128 caractères.
Voici un exemple de manifeste d’application avec des définitions pour les extensions de message basées sur l’API :
Exemple de manifeste d’application
{
"$schema": "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.schema.json",
+ "manifestVersion": "devPreview",
"version": "1.0.0",
"id": "04805b4b-xxxx-xxxx-xxxx-4dbc1cac8f89",
"packageName": "com.microsoft.teams.extension",
"developer": {
"name": "Teams App, Inc.",
"websiteUrl": "https://www.example.com",
"privacyUrl": "https://www.example.com/termofuse",
"termsOfUseUrl": "https://www.example.com/privacy"
},
"icons": {
"color": "color.png",
"outline": "outline.png"
},
"name": {
"short": "AI tools",
"full": "AI tools"
},
"description": {
"short": "AI tools",
"full": "AI tools"
},
"accentColor": "#FFFFFF",
"composeExtensions": [
{
+ "composeExtensionType": "apiBased",
+ "authorization": {
+ "authType": "apiSecretServiceAuth ",
+ "apiSecretServiceAuthConfiguration": {
+ "apiSecretRegistrationId": "96270b0f-7298-40cc-b333-152f84321813"
+ }
+ },
+ "apiSpecificationFile": "aitools-openapi.yml",
"commands": [
{
"id": "searchTools",
"type": "query",
"context": [
"compose",
"commandBox"
],
"title": "search for AI tools",
"description": "search for AI tools",
"parameters": [
{
"name": "search",
"title": "search query",
"description": "e.g. search='tool to create music'"
}
],
+ "apiResponseRenderingTemplateFile": "response-template.json"
}
]
}
],
"validDomains": []
}
Paramètres
Nom | Description |
---|---|
composeExtensions.composeExtensionType |
Compose type d’extension. Mettez à jour la valeur sur apiBased . |
composeExtensions.authorization |
Informations relatives à l’autorisation pour l’extension de message basé sur l’API |
composeExtensions.authorization.authType |
Énumération des types d’autorisation possibles. Les valeurs prises en charge sont none , apiSecretServiceAuth et microsoftEntra . |
composeExtensions.authorization.apiSecretServiceAuthConfiguration |
Détails de capture d’objet nécessaires pour effectuer l’authentification de service. Applicable uniquement lorsque le type d’authentification est apiSecretServiceAuth . |
composeExtensions.authorization.apiSecretServiceAuthConfiguration.apiSecretRegistrationId |
ID d’inscription retourné lorsque le développeur envoie la clé API via le portail des développeurs. |
composeExtensions.apiSpecificationFile |
Fait référence à un fichier de description OpenAPI dans le package d’application. Incluez lorsque type est apiBased . |
composeExtensions.commands.id |
ID unique que vous affectez à la commande de recherche. La demande de l’utilisateur inclut cet ID. L’ID doit correspondre au operationId disponible dans la description OpenAPI. |
composeExtensions.commands.context |
Tableau où les points d’entrée pour l’extension de message sont définis. Les valeurs par défaut sont compose et commandBox . |
composeExtensions.commands.parameters |
Définit une liste statique de paramètres pour la commande . Le nom doit être mappé au parameters.name dans la description OpenAPI. Si vous référencez une propriété dans le schéma du corps de la demande, le nom doit être mappé aux properties.name paramètres de requête ou . |
composeExtensions.commands.apiResponseRenderingTemplateFile |
Modèle utilisé pour mettre en forme la réponse JSON de l’API du développeur à la réponse de carte adaptative. [Obligatoire] |
Pour plus d’informations, consultez composeExtensions.
Modèle de rendu de réponse
Remarque
Teams prend en charge les cartes adaptatives jusqu’à la version 1.5. Lorsque vous utilisez le concepteur de cartes adaptatives, veillez à remplacer la version cible par la version 1.5.
Le modèle de rendu de réponse est un format prédéfini qui détermine la façon dont les résultats de votre API sont affichés dans Teams. Il utilise des modèles pour créer des cartes adaptatives ou d’autres éléments d’interface utilisateur à partir de la réponse de l’API, garantissant ainsi une expérience utilisateur transparente et intégrée dans Teams. Le modèle définit la disposition et le style des informations présentées, qui peuvent inclure du texte, des images et des composants interactifs. Veillez à respecter les instructions suivantes pour le modèle de rendu de réponse :
- Définissez l’URL de référence de schéma dans la
$schema
propriété pour établir la structure de votre modèle dans le schéma du modèle de rendu de réponse. - Les valeurs prises en charge pour
responseLayout
sontlist
etgrid
, qui déterminent la façon dont la réponse est visuellement présentée. Pour plus d’informations sur la disposition, consultez Répondre aux demandes des utilisateurs. - Un
jsonPath
est demandé de nouveau pour les tableaux ou lorsque les données de la carte adaptative ne sont pas l’objet racine. Par exemple, si vos données sont imbriquées sousproductDetails
, votre chemin JSON estproductDetails
. - Définissez
jsonPath
comme chemin d’accès aux données ou au tableau appropriés dans la réponse de l’API. Si le chemin pointe vers un tableau, chaque entrée du tableau est liée au modèle de carte adaptative et retourne un résultat distinct. [Facultatif] - Obtenez un exemple de réponse pour valider le modèle de rendu de réponse. Cela sert de test pour vous assurer que votre modèle fonctionne comme prévu.
- Utilisez des outils tels que Fiddler ou Postman pour appeler l’API et vous assurer que la demande et la réponse sont valides. Cette étape est cruciale pour résoudre les problèmes et confirmer que votre API fonctionne correctement.
- Vous pouvez utiliser la carte adaptative Designer pour lier la réponse de l’API au modèle de rendu de réponse et afficher un aperçu de la carte adaptative. Insérez le modèle De carte adaptative dans l’ÉDITEUR DE CHARGE UTILE CARD et insérez l’exemple d’entrée de réponse dans l’ÉDITEUR DE DONNÉES ÉCHANTILLON.
Le code suivant est un exemple de modèle de rendu de réponse :
Exemple de modèle de rendu de réponse
{
"version": "1.0",
"$schema": "developer.microsoft.com/json-schemas/teams/v1.17/MicrosoftTeams.ResponseRenderingTemplate.schema.json",
"jsonPath": "repairs",
"responseLayout": "grid",
"responseCardTemplate": {
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.4",
"body": [
{
"type": "Container",
"items": [
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "Title: ${if(title, title, 'N/A')}",
"wrap": true
},
{
"type": "TextBlock",
"text": "Description: ${if(description, description, 'N/A')}",
"wrap": true
},
{
"type": "TextBlock",
"text": "Assigned To: ${if(assignedTo, assignedTo, 'N/A')}",
"wrap": true
},
{
"type": "Image",
"url": "${image}",
"size": "Medium",
"$when": "${image != null}"
}
]
},
{
"type": "Column",
"width": "auto",
"items": [
{
"type": "Image",
"url": "${if(image, image, '')}",
"size": "Medium"
}
]
}
]
},
{
"type": "FactSet",
"facts": [
{
"title": "Repair ID:",
"value": "${if(id, id, 'N/A')}"
},
{
"title": "Date:",
"value": "${if(date, date, 'N/A')}"
}
]
}
]
}
]
},
"previewCardTemplate": {
"title": "Title: ${if(title, title, 'N/A')}",
"subtitle": "Description: ${if(description, description, 'N/A')}",
"text": "Assigned To: ${if(assignedTo, assignedTo, 'N/A')}",
"image": {
"url": "${image}",
"$when": "${image != null}"
}
}
}
Carte d’aperçu
Un aperçu carte modèle dans le schéma du modèle de rendu de réponse est utilisé pour mapper les réponses JSON à un aperçu carte que les utilisateurs voient lorsqu’ils sélectionnent un résultat de recherche. L’aperçu carte développe ensuite une carte adaptative dans la zone de composition de message. La préversion carte modèle fait partie du modèle de rendu de réponse, qui inclut également un modèle de carte adaptative et des métadonnées.
Carte adaptative développée
Paramètres
Propriété | Type | Description | Obligatoire |
---|---|---|---|
version |
string |
Version de schéma du modèle de rendu de réponse actuel. | Oui |
jsonPath |
string |
Chemin d’accès à la section appropriée dans les résultats auxquels responseCardTemplate et previewCardTemplate doivent être appliqués. S’il n’est pas défini, l’objet racine est traité comme la section appropriée. Si la section appropriée est un tableau, chaque entrée est mappée au responseCardTemplate et au previewCardTemplate. | Non |
responseLayout |
responseLayoutType |
Spécifie la disposition des résultats dans le menu volant d’extension de message. Les types pris en charge sont list et grid . |
Oui |
responseCardTemplate |
adaptiveCardTemplate |
Modèle permettant de créer une carte adaptative à partir d’une entrée de résultat. | Oui |
previewCardTemplate |
previewCardTemplate |
Modèle permettant de créer un aperçu carte à partir d’une entrée de résultat. L’aperçu obtenu carte s’affiche dans le menu volant de l’extension de message. | Oui |
Chemin d’accès Json
Le chemin JSON est facultatif, mais doit être utilisé pour les tableaux ou lorsque l’objet à utiliser comme données de la carte adaptative n’est pas l’objet racine. Le chemin JSON doit suivre le format défini par Newtonsoft. Cet outil peut être utilisé. Vous pouvez utiliser l’outil JSON pour vérifier si un chemin JSON est correct. Si le chemin JSON pointe vers un tableau, chaque entrée de ce tableau est liée au modèle carte adaptative et retourne des résultats distincts.
Exemple Supposons que vous disposez du code JSON suivant pour une liste de produits et que vous souhaitez créer un résultat carte pour chaque entrée.
{
"version": "1.0",
"title": "All Products",
"warehouse": {
"products": [
...
]
}
}
Comme vous pouvez le voir, le tableau de résultats se trouve sous « products », qui est imbriqué sous « warehouse », de sorte que le chemin JSON serait « warehouse.products ».
Utilisez https://adaptivecards.io/designer/ pour afficher un aperçu de la carte adaptative en insérant le modèle dans la charge utile de la carte Rédacteur, puis prenez un exemple d’entrée de réponse à partir de votre tableau ou de votre objet et insérez-le dans l’éditeur de données identiques à droite. Assurez-vous que le carte s’affiche correctement et est à votre convenance. Teams prend en charge les cartes jusqu’à la version 1.5, tandis que le concepteur prend en charge la version 1.6.
Conversion de schéma OpenAPI
Remarque
Nous envoyons un en-tête accept-language dans la requête HTTP qui est envoyé au point de terminaison défini dans le document de description OpenAPI. La langue d’acceptation est basée sur les paramètres régionaux du client Teams et peut être utilisée par le développeur pour retourner une réponse localisée.
Les types de données suivants dans le document de description OpenAPI sont convertis en éléments au sein d’une carte adaptative comme suit :
string
,number
,integer
, lesboolean
types sont convertis en TextBlock.Exemple
Schéma source :
string
,number
,integer
etboolean
name: type: string example: doggie
Schéma cible :
Textblock
{ "type": "TextBlock", "text": "name: ${if(name, name, 'N/A')}", "wrap": true }
array
: un tableau est converti en conteneur à l’intérieur de la carte adaptative.Exemple
Schéma source :
array
type: array items: required: - name type: object properties: id: type: integer category: type: object properties: name: type: string
Schéma cible :
Container
{ "type": "Container", "$data": "${$root}", "items": [ { "type": "TextBlock", "text": "id: ${if(id, id, 'N/A')}", "wrap": true }, { "type": "TextBlock", "text": "category.name: ${if(category.name, category.name, 'N/A')}", "wrap": true } ] }
object
: un objet est converti en propriété imbriquée dans la carte adaptative.Exemple
Schéma source :
object
components: schemas: Pet: category: type: object properties: id: type: integer name: type: string
Schéma cible : propriété imbriquée dans une carte adaptative
{ "type": "TextBlock", "text": "category.id: ${if(category.id, category.id, 'N/A')}", "wrap": true }, { "type": "TextBlock", "text": "category.name: ${if(category.name, category.name, 'N/A')}", "wrap": true }
image
: si une propriété est une URL d’image, elle est convertie en élément Image dans la carte adaptative.Exemple
Schéma source :
image
image: type: string format: uri description: The URL of the image of the item to be repaired
Schéma cible :
"Image"
{ "type": "Image", "url": "${image}", "$when": "${image != null}" }