Creación de una extensión de mensaje basada en API
Nota:
Las extensiones de mensaje basadas en API solo admiten comandos de búsqueda.
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.
Antes de empezar, asegúrese de cumplir los siguientes requisitos:
1. Descripción de OpenAPI (OAD)
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:
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, consulte Estructura de OpenAPI.
2. Manifiesto de aplicación
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 archivo de 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
la 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 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
en la descripción de OpenAPI.Asegúrese de que los parámetros de cada comando coinciden exactamente con los nombres de los parámetros definidos para la operación en la especificación de OpenAPI.
Se debe definir una plantilla de representación de respuesta por comando, que se usa para convertir respuestas desde una API.
La descripción completa no debe superar los 128 caracteres.
{ "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.17/MicrosoftTeams.schema.json", + "manifestVersion": "1.17", "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": "9xxxxxxx-7xxx-4xxx-bxxx-1xxxxxxxxxxx" + } + }, + "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.
3. Plantilla de representación de respuesta
Nota:
Teams admite tarjetas adaptables hasta la versión 1.5 y las tarjetas adaptables Designer admiten hasta la versión 1.6.
-
Defina la dirección URL de referencia del esquema en la
$schema
propiedad para establecer la estructura de la plantilla. -
Los valores admitidos para
responseLayout
sonlist
ygrid
, que determinan cómo se presenta visualmente la respuesta. -
Se recomienda para
jsonPath
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 en el EDITOR DE CARGA ÚTIL 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",
"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
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. Si la ruta de acceso JSON apunta a una matriz, cada entrada de esa matriz se enlaza con la plantilla de tarjeta adaptable y devuelve como resultados independientes.
Ejemplo Supongamos que tiene el código JSON siguiente 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 De los mismos datos de la derecha. Asegúrese de que la tarjeta se representa correctamente y es a su gusto. Tenga en cuenta que Teams admite tarjetas hasta la versión 1.5, mientras que el diseñador admite la versión 1.6.
Asignación de esquemas
Las propiedades del documento Descripción de OpenAPI se asignan a la plantilla 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}" }
Puede crear una extensión de mensaje basada en API mediante el Portal para desarrolladores para Teams y teams Toolkit para Visual Studio Code, la interfaz de línea de comandos (CLI) o Visual Studio.
- Portal para desarrolladores de Teams
- Visual Studio Code
- CLI del kit de herramientas de Teams
- Visual Studio
Para crear una extensión de mensaje basada en API mediante el Portal para desarrolladores para Teams, siga estos pasos:
Vaya al Portal para desarrolladores de Teams.
Vaya a Aplicaciones.
Seleccione + Nuevas aplicaciones.
Escriba un nombre de la aplicación y seleccione la versión del manifiesto como Versión preliminar del desarrollador público (devPreview).
Seleccione Agregar.
En el panel izquierdo, en Configurar, actualice la siguiente información básica:
- Nombre completo
- Descripción breve
- Descripción larga
- Nombre del desarrollador o de la empresa
- Sitio web (debe ser una dirección URL HTTPS válida)
- Directiva de privacidad
- Términos de uso
Haga clic en Guardar.
Seleccione Características de la aplicación.
Seleccione Extensión de mensajería.
En Tipo de extensión de mensaje, seleccione API.
- Si recibe una declinación de responsabilidades, que lee La extensión de mensaje del bot ya está en uso por parte de los usuarios. ¿Desea cambiar el tipo de extensión de mensaje a API?. Seleccione Sí, cambie.
En Especificación de OpenAPI, seleccione Cargar ahora.
Seleccione el documento Descripción de OpenAPI en formato JSON o YAML y seleccione Abrir.
Haga clic en Guardar. Aparece un elemento emergente con la especificación de API de mensaje guardada correctamente.
Seleccione Got it (Lo tengo).
Agregar comandos
Nota:
Las extensiones de mensaje creadas a partir de una API solo admiten un único parámetro.
Puede agregar comandos y parámetros a la extensión de mensaje para agregar comandos:
En Tipo de extensión de mensaje, seleccione Agregar.
Aparece un elemento emergente Agregar comando con una lista de todas las API disponibles en el documento Descripción de OpenAPI.
Seleccione una API en la lista y seleccione Siguiente.
Aparece un elemento Command details (Detalles del comando ).
En Detalles del comando, vaya a Plantilla de tarjeta adaptable y seleccione Cargar ahora.
Nota:
Si tiene más de una API, asegúrese de cargar la plantilla de tarjeta adaptable para cada API.
Seleccione el archivo de plantilla tarjeta adaptable en formato JSON y seleccione Abrir.
Los siguientes atributos se actualizan automáticamente desde la plantilla tarjeta adaptable:
- Tipo de comando
- Identificador de comando
- Título del comando
- Nombre del parámetro
- Descripción del parámetro
En Detalles, actualice la descripción del comando.
- Si desea iniciar un comando con un desencadenador en Microsoft 365 Copilot, active ejecutar automáticamente el comando cuando un usuario abra el botón de alternancia de extensión.
Seleccione Agregar. El comando se agrega correctamente.
Haga clic en Guardar.
En Autenticación, seleccione cualquiera de las opciones siguientes:
- Sin autenticación
- Clave de API
Se crea una extensión de mensaje basada en API.
Para probar la extensión de mensaje basada en API creada en el Portal para desarrolladores de Teams, puede usar los métodos siguientes:
Versión preliminar en Teams: en el Portal para desarrolladores, abra la extensión de mensaje y seleccione Vista previa en Teams en la esquina superior derecha. Se le redirigirá a Teams, donde puede agregar la aplicación a Teams para obtener una vista previa de la aplicación.
Descargar paquete de aplicación: en la página de extensión del mensaje, seleccione Paquete de aplicación en el panel izquierdo y, a continuación, en la esquina superior izquierda de la ventana, seleccione Descargar paquete de aplicación. El paquete de la aplicación se descarga en la máquina local en un archivo .zip. Puede cargar el paquete de la aplicación en los equipos y probar la extensión del mensaje.
Guías paso a paso
Para compilar una extensión de mensaje basada en API, siga estas guías paso a paso:
- Para principiantes: cree una extensión de mensaje basada en API con Teams Toolkit.
- Para usuarios avanzados: cree una extensión de mensaje basada en API desde cero.