Extensión de mensaje basada en API
Nota:
Las extensiones de mensaje basadas en API solo admiten comandos de búsqueda.
Las extensiones de mensaje creadas mediante API (basada en API) usan un servicio web para administrar las solicitudes y respuestas de los usuarios y no requieren un registro de bot. Las extensiones de mensajes basadas en API son una funcionalidad de aplicación de Microsoft Teams que integra las API externas directamente en Teams, lo que mejora la facilidad de uso de la aplicación y ofrece una experiencia de usuario sin problemas. Las extensiones de mensajes basadas en API admiten comandos de búsqueda y se pueden usar para capturar y mostrar datos de servicios externos dentro de Teams, lo que simplifica los flujos de trabajo al reducir la necesidad de cambiar entre aplicaciones. Las extensiones de mensajes basadas en API ayudan a las aplicaciones a interactuar directamente con datos, aplicaciones y servicios de terceros, lo que mejora sus funcionalidades. Con la extensión de mensaje basada en API, puede hacer lo siguiente:
- Recupere información en tiempo real, como la cobertura de noticias más reciente en el lanzamiento de un producto.
- Recuperar información basada en conocimientos, por ejemplo, los archivos de diseño de mi equipo en Figma
Vea el vídeo para obtener más información sobre la creación de una extensión de mensaje basada en API mediante el kit de herramientas de Teams:
Extensiones de mensajes tradicionales basadas en bots | Extensiones de mensajes basadas en API |
---|---|
Los desarrolladores deben compilar, implementar y mantener un servicio para controlar comandos de invocación desde el cliente de Teams. | Si las API del servicio final se pueden describir mediante la especificación de OpenAPI, los desarrolladores pueden eliminar la necesidad del servicio de control de nivel intermedio. |
Este servicio procesa la consulta entrante y realiza una llamada al servicio final del desarrollador. | Teams puede usar directamente la especificación de OpenAPI para compilar solicitudes y comunicarse con el servicio final del desarrollador. |
En las imágenes siguientes se muestra el flujo de consultas de usuario a través de extensiones de mensajes tradicionales y extensiones de mensaje de API:
Flujo de consulta de usuario mediante extensiones de mensaje tradicionales. El desarrollador debe mantener un servicio de controlador de bot personalizado, que controla las solicitudes de un bot de Teams. El servicio de controlador envía una solicitud al servicio del desarrollador cuando se invoca una consulta.
Flujo de consulta de usuario mediante extensiones de mensaje de API. No es necesario un servicio de controlador mantenido por el desarrollador siempre y cuando la interacción se describa claramente en la especificación de OpenAPI del paquete de aplicaciones.
Esta es una secuencia de alto nivel de eventos que se producen durante una invocación de comando de consulta:
Cuando un usuario invoca un comando de consulta, el Bot Service de Teams recibe los parámetros del comando de consulta.
El comando de consulta se define dentro del archivo de manifiesto de la aplicación. La definición de comando contiene una referencia a dentro del
operationId
archivo de especificación de OpenAPI junto con los detalles de los parámetros que el cliente de Teams representa para ese comando. Como referencia, dentrooperationId
del archivo de especificación de OpenAPI es único para una operación HTTP determinada.A continuación, teams Bot Service usa los parámetros proporcionados por el usuario junto con la copia de la especificación de OpenAPI para el asociado
operationId
para crear una solicitud HTTP para el punto de conexión del desarrollador.Si se requiere autenticación y se configura en el manifiesto. Se resuelve en el token o la clave adecuados. Este token o clave se usa como parte de la solicitud saliente. [Opcionalmente]
El servicio bot de Teams realiza la solicitud HTTP al servicio del desarrollador.
El servicio del desarrollador debe responder de acuerdo con el esquema descrito en la especificación de OpenAPI. Está en formato JSON.
El cliente de Teams debe mostrar los resultados al usuario. Para convertir los resultados JSON del paso anterior a la interfaz de usuario, el servicio bot de Teams usa la plantilla de representación de respuesta para crear una tarjeta adaptable para cada resultado.
Las tarjetas adaptables se envían al cliente, lo que las representa en la interfaz de usuario.
Requisitos previos
El paquete de definición de aplicación incluye varios artefactos atractivos que admiten la funcionalidad de esta característica. Antes de empezar, asegúrese de que tiene un conocimiento básico de los siguientes archivos:
Descripción de OpenAPI (OAD)
La descripción de OpenAPI documenat es un estándar del sector adoptado para describir las API. Permite abstraer las API de su implementación, proporcionando definiciones independientes del lenguaje que son legibles por el usuario y legibles por máquina. En la descripción de OpenAPI documenat se describen las interacciones que admite la extensión, lo que permite a Teams crear solicitudes y comunicarse directamente con el servicio sin necesidad de un servicio de control de nivel intermedio.
Un documento de descripción de OpenAPI contiene detalles para comunicarse con el servicio del desarrollador. Asegúrese de cumplir las siguientes directrices para el documento de descripción de OpenAPI (OAD):
- Se admiten las versiones 2.0 y 3.0.x de OpenAPI.
- JSON y YAML son los formatos admitidos.
- El cuerpo de la solicitud, si está presente, debe ser application/Json.
- Defina una dirección URL del servidor de protocolo HTTPS para la
servers.url
propiedad . - Solo se admiten los métodos HTTP POST y GET.
- El documento Descripción de OpenAPI debe tener un .
operationId
- Solo se permite un parámetro necesario sin un valor predeterminado.
- Un parámetro obligatorio con un valor predeterminado se considera opcional.
- Los usuarios no deben especificar un parámetro para un encabezado o cookie.
- La operación no debe tener un encabezado o parámetros de cookie necesarios sin valores predeterminados.
- Asegúrese de que no haya referencias remotas en el documento Descripción de OpenAPI.
- No se admite la construcción de matrices para la solicitud; sin embargo, se admiten objetos anidados dentro de un cuerpo de solicitud JSON.
- Teams no admite las
oneOf
construcciones ,anyOf
,allOf
ynot
(swagger.io).
El código siguiente es un ejemplo de un documento de descripción de OpenAPI:
Documento de descripción de OpenAPI de ejemplo
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.
Para obtener más información sobre cómo escribir definiciones de OpenAPI en YAML, consulte Estructura de OpenAPI.
Manifiesto de la aplicación
El manifiesto de aplicación es un plano técnico para la aplicación de Teams, que define cómo y dónde se invoca la extensión de mensaje dentro del cliente de Teams. Incluye los comandos que admite la extensión y las ubicaciones desde las que se puede acceder a ellos, como el área del mensaje de redacción, la barra de comandos y el mensaje. El manifiesto se vincula a la especificación de OpenAPI y a la plantilla de representación de respuesta para garantizar la funcionalidad adecuada.
El manifiesto de la aplicación contiene la definición del comando de consulta. Asegúrese de cumplir las siguientes directrices para el manifiesto de la aplicación:
- Establezca la versión del manifiesto de la aplicación en
1.17
. - Establezca en
composeExtensions.composeExtensionType
apiBased
. - Defina
composeExtensions.apiSpecificationFile
como la ruta de acceso relativa al documento Descripción de OpenAPI dentro de la carpeta. Esto vincula el manifiesto de aplicación a la especificación de API. - Defina
apiResponseRenderingTemplateFile
como la ruta de acceso relativa a la plantilla de representación de respuesta. Esto especifica la ubicación de la plantilla que se usa para representar las respuestas de la API. - Cada comando debe tener un vínculo a la plantilla de representación de respuesta. Esto conecta cada comando a su formato de respuesta correspondiente.
- La
Commands.id
propiedad del manifiesto de la aplicación debe coincidir con enoperationId
el documento Descripción de OpenAPI. - Si un parámetro necesario no tiene un valor predeterminado, el comando
parameters.name
del manifiesto de la aplicación debe coincidir con elparameters.name
del documento de descripción de OpenAPI. - Si no hay ningún parámetro necesario, el comando
parameters.name
del manifiesto de la aplicación debe coincidir con el opcionalparameters.name
del documento Descripción de OpenAPI. - Asegúrese de que el nombre de los parámetros de cada comando del manifiesto de la aplicación coincida exactamente con el nombre correspondiente del parámetro definido para la operación en el documento Descripción de OpenAPI.
- Se debe definir una plantilla de representación de respuesta por comando, que se usa para convertir respuestas desde una API.
- Las descripciones de comandos y parámetros no deben superar los 128 caracteres.
A continuación se muestra un ejemplo de manifiesto de aplicación con definiciones para extensiones de mensajes basadas en API:
Ejemplo de manifiesto de aplicación
{
"$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": []
}
Parameters
Nombre | Descripción |
---|---|
composeExtensions.composeExtensionType |
Compose tipo de extensión. Actualice el valor a apiBased . |
composeExtensions.authorization |
Información relacionada con la autorización para la extensión de mensaje basada en API |
composeExtensions.authorization.authType |
Enumeración de posibles tipos de autorización. Los valores admitidos son none , apiSecretServiceAuth y microsoftEntra . |
composeExtensions.authorization.apiSecretServiceAuthConfiguration |
Detalles de captura de objetos necesarios para realizar la autenticación del servicio. Solo se aplica cuando el tipo de autenticación es apiSecretServiceAuth . |
composeExtensions.authorization.apiSecretServiceAuthConfiguration.apiSecretRegistrationId |
Id. de registro devuelto cuando el desarrollador envía la clave de API a través del Portal para desarrolladores. |
composeExtensions.apiSpecificationFile |
Hace referencia a un archivo de descripción de OpenAPI en el paquete de la aplicación. Incluya cuando el tipo es apiBased . |
composeExtensions.commands.id |
Identificador único que se asigna al comando de búsqueda. La solicitud de usuario incluye este id. El identificador debe coincidir con el operationId disponible en la descripción de OpenAPI. |
composeExtensions.commands.context |
Matriz donde se definen los puntos de entrada de la extensión de mensaje. Los valores predeterminados son compose y commandBox . |
composeExtensions.commands.parameters |
Define una lista estática de parámetros para el comando. El nombre debe asignarse a en parameters.name la descripción de OpenAPI. Si hace referencia a una propiedad en el esquema del cuerpo de la solicitud, el nombre debe asignarse a properties.name los parámetros de consulta o . |
composeExtensions.commands.apiResponseRenderingTemplateFile |
Plantilla usada para dar formato a la respuesta JSON de la API del desarrollador a la respuesta de tarjeta adaptable. [Obligatorio] |
Para obtener más información, vea composeExtensions.
Plantilla de representación de respuesta
Nota:
Teams admite tarjetas adaptables hasta la versión 1.5. Al usar el diseñador de tarjetas adaptables, asegúrese de cambiar la versión de destino a 1.5.
La plantilla de representación de respuesta es un formato predefinido que determina cómo se muestran los resultados de la API en Teams. Usa plantillas para crear tarjetas adaptables u otros elementos de interfaz de usuario a partir de la respuesta de la API, lo que garantiza una experiencia de usuario integrada y sin problemas en Teams. La plantilla define el diseño y el estilo de la información presentada, que puede incluir texto, imágenes y componentes interactivos. Asegúrese de cumplir las siguientes directrices para la plantilla de representación de respuestas:
- Defina la dirección URL de referencia del esquema en la
$schema
propiedad para establecer la estructura de la plantilla en el esquema de la plantilla de representación de respuesta. - Los valores admitidos para
responseLayout
sonlist
ygrid
, que determinan cómo se presenta visualmente la respuesta. Para obtener más información sobre el diseño, vea Responder a solicitudes de usuario. - Se vuelve a solicitar para
jsonPath
las matrices o cuando los datos de la tarjeta adaptable no son el objeto raíz. Por ejemplo, si los datos están anidados enproductDetails
, la ruta de acceso JSON seríaproductDetails
. - Defina
jsonPath
como la ruta de acceso a los datos o matriz pertinentes en la respuesta de la API. Si la ruta de acceso apunta a una matriz, cada entrada de la matriz se enlaza con la plantilla tarjeta adaptable y devuelve como resultado independiente. [Opcional] - Obtenga una respuesta de ejemplo para validar la plantilla de representación de respuesta. Esto sirve como prueba para asegurarse de que la plantilla funciona según lo esperado.
- Use herramientas como Fiddler o Postman para llamar a la API y asegurarse de que la solicitud y la respuesta son válidas. Este paso es fundamental para solucionar problemas y confirmar que la API funciona correctamente.
- Puede usar la tarjeta adaptable Designer para enlazar la respuesta de la API a la plantilla de representación de respuesta y obtener una vista previa de la tarjeta adaptable. Inserte la plantilla tarjeta adaptable en el EDITOR DE CARGA DE TARJETA e inserte la entrada de respuesta de ejemplo en EL EDITOR DE DATOS DE EJEMPLO.
El código siguiente es un ejemplo de una plantilla de representación de respuesta:
Ejemplo de plantilla de representación de respuesta
{
"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}"
}
}
}
Tarjeta de vista previa
Se usa una plantilla de tarjeta de vista previa en el esquema de plantilla de representación de respuesta para asignar respuestas JSON a una tarjeta de vista previa que los usuarios ven cuando seleccionan un resultado de búsqueda. A continuación, la tarjeta de vista previa se expande en una tarjeta adaptable en el cuadro de redacción del mensaje. La plantilla de tarjeta de vista previa forma parte de la plantilla de representación de respuesta, que también incluye una plantilla de tarjeta adaptable y metadatos.
Tarjeta adaptable expandida
Parameters
Propiedad | Tipo | Descripción | Obligatorio |
---|---|---|---|
version |
string |
Versión del esquema de la plantilla de representación de respuesta actual. | Yes |
jsonPath |
string |
Ruta de acceso a la sección pertinente en los resultados a los que se deben aplicar responseCardTemplate y previewCardTemplate. Si no se establece, el objeto raíz se trata como la sección pertinente. Si la sección pertinente es una matriz, cada entrada se asigna a responseCardTemplate y previewCardTemplate. | No |
responseLayout |
responseLayoutType |
Especifica el diseño de los resultados en el control flotante de la extensión de mensaje. Los tipos admitidos son list y grid . |
Yes |
responseCardTemplate |
adaptiveCardTemplate |
Plantilla para crear una tarjeta adaptable a partir de una entrada de resultado. | Yes |
previewCardTemplate |
previewCardTemplate |
Plantilla para crear una tarjeta de vista previa a partir de una entrada de resultado. La tarjeta de vista previa resultante se muestra en el menú desplegable extensión de mensaje. | Yes |
Ruta de acceso json
La ruta de acceso JSON es opcional, pero debe usarse para matrices o donde el objeto que se va a usar como datos de la tarjeta adaptable no es el objeto raíz. La ruta de acceso JSON debe seguir el formato definido por Newtonsoft. Esta herramienta se puede usar. Puede usar la herramienta JSON para validar si una ruta de acceso JSON es correcta. Si la ruta de acceso JSON apunta a una matriz, cada entrada de esa matriz se enlaza con la plantilla tarjeta adaptable y devuelve como resultados independientes.
Ejemplo Supongamos que tiene el siguiente JSON para una lista de productos y desea crear un resultado de tarjeta para cada entrada.
{
"version": "1.0",
"title": "All Products",
"warehouse": {
"products": [
...
]
}
}
Como puede ver, la matriz de resultados está en "products", que está anidada en "warehouse", por lo que la ruta de acceso JSON sería "warehouse.products".
Use https://adaptivecards.io/designer/ para obtener una vista previa de la tarjeta adaptable insertando la plantilla en la carga útil de la tarjeta Editor, tome una entrada de respuesta de ejemplo de la matriz o del objeto e insértelo en el editor Same Data de la derecha. Asegúrese de que la tarjeta se representa correctamente y es a su gusto. Teams admite tarjetas hasta la versión 1.5, mientras que el diseñador admite la versión 1.6.
Conversión de esquema de OpenAPI
Nota:
Enviamos un encabezado accept-language en la solicitud HTTP que se envía al punto de conexión definido en el documento de descripción de OpenAPI. El lenguaje de aceptación se basa en la configuración regional del cliente de Teams y el desarrollador puede usarlo para devolver una respuesta localizada.
Los siguientes tipos de datos del documento de descripción de OpenAPI se convierten en elementos dentro de una tarjeta adaptable como se indica a continuación:
string
,number
,integer
,boolean
los tipos se convierten en textblock.Ejemplo
Esquema de origen:
string
,number
,integer
yboolean
name: type: string example: doggie
Esquema de destino:
Textblock
{ "type": "TextBlock", "text": "name: ${if(name, name, 'N/A')}", "wrap": true }
array
: una matriz se convierte en un contenedor dentro de la tarjeta adaptable.Ejemplo
Esquema de origen:
array
type: array items: required: - name type: object properties: id: type: integer category: type: object properties: name: type: string
Esquema de destino:
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 objeto se convierte en una propiedad anidada en la tarjeta adaptable.Ejemplo
Esquema de origen:
object
components: schemas: Pet: category: type: object properties: id: type: integer name: type: string
Esquema de destino: propiedad anidada en una tarjeta adaptable
{ "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 una propiedad es una dirección URL de imagen, se convierte en un elemento Image de la tarjeta adaptable.Ejemplo
Esquema de origen:
image
image: type: string format: uri description: The URL of the image of the item to be repaired
Esquema de destino:
"Image"
{ "type": "Image", "url": "${image}", "$when": "${image != null}" }