Extensão de mensagem baseada em API
Observação
As extensões de mensagens baseadas em API só suportam comandos de pesquisa.
As extensões de mensagens criadas com a API (baseada em API) utilizam um serviço Web para gerir pedidos e respostas de utilizadores e não necessitam de um registo de bot. As extensões de mensagens baseadas em API são uma capacidade de aplicação do Microsoft Teams que integra APIs externas diretamente no Teams, melhorando a usabilidade da sua aplicação e oferecendo uma experiência de utilizador totalmente integrada. As extensões de mensagens baseadas em API suportam comandos de pesquisa e podem ser utilizadas para obter e apresentar dados de serviços externos no Teams, simplificando os fluxos de trabalho ao reduzir a necessidade de alternar entre aplicações. As extensões de mensagens baseadas em API ajudam as suas aplicações a interagir diretamente com dados, aplicações e serviços de terceiros, melhorando as suas capacidades. Com a extensão de mensagens baseada em API, pode:
- Obtenha informações em tempo real, como a cobertura de notícias mais recente num lançamento de produto.
- Obter informações baseadas em conhecimento, por exemplo, os ficheiros de design da minha equipa no Figma
Veja o vídeo para saber mais sobre a criação de uma extensão de mensagem baseada em API com o Teams Toolkit:
Extensões de mensagens tradicionais baseadas em bots | Extensões de mensagens baseadas em API |
---|---|
Os programadores precisam de criar, implementar e manter um serviço para processar comandos de invocação do cliente do Teams. | Se as APIs do serviço final puderem ser descritas com a Especificação openAPI, os programadores podem eliminar a necessidade do serviço de processamento de camada média. |
Este serviço processa a consulta recebida e faz uma chamada para o serviço final do programador. | O Teams pode utilizar diretamente a Especificação openAPI para criar pedidos e comunicar com o serviço final do programador. |
As imagens seguintes mostram o fluxo de consultas do utilizador através de extensões de mensagens tradicionais e extensões de mensagens da API:
Fluxo de consulta do utilizador com extensões de mensagens tradicionais. O programador tem de manter um serviço de processador de bots personalizado, que processa os pedidos de um bot do Teams. O serviço de processador envia um pedido ao serviço do programador quando uma consulta é invocada.
Fluxo de consulta de utilizador com Extensões de Mensagens de API. Não é necessário um serviço de processador mantido pelo programador, desde que a interação esteja claramente descrita na Especificação OpenAPI no Pacote de Aplicações.
Eis uma sequência de eventos de alto nível que ocorre durante uma invocação de comandos de consulta:
Quando um utilizador invoca um comando de consulta, os parâmetros do comando de consulta são recebidos pela Serviço de Bot do Teams.
O comando de consulta é definido dentro do ficheiro de manifesto da aplicação. A definição de comando contém uma referência ao
operationId
ficheiro OpenAPI Specification, juntamente com os detalhes dos parâmetros que o cliente do Teams compõe para esse comando. Para referência, ooperationId
ficheiro OpenAPI Specification no interior é exclusivo de uma determinada operação HTTP.O Teams Serviço de Bot, em seguida, utiliza os parâmetros fornecidos pelo utilizador juntamente com a cópia da Especificação openAPI para o associado
operationId
para criar um pedido HTTP para o ponto final do programador.Se a autenticação for necessária e estiver configurada no manifesto. É resolvido para o token ou chave adequado. Este token ou chave é utilizado como parte do pedido de saída. [Opcionalmente]
O serviço de bot do Teams efetua o pedido HTTP ao serviço do programador.
O serviço do programador deve responder de acordo com o esquema descrito na Especificação openAPI. Isto está no formato JSON.
O cliente do Teams tem de mostrar os resultados ao utilizador. Para converter os resultados JSON do passo anterior para a IU, o serviço de bot do Teams utiliza o modelo de Composição de resposta para criar um Cartão Ajustável para cada resultado.
Os Cartões Ajustáveis são enviados para o cliente, o que os compõe na IU.
Pré-requisitos
O pacote de definição de aplicação inclui vários artefactos apelativos que suportam a funcionalidade desta funcionalidade. Antes de começar, certifique-se de que tem uma compreensão básica dos seguintes ficheiros:
Descrição de OpenAPI (OAD)
O documenat de descrição de OpenAPI é um padrão da indústria adotado para descrever as APIs. Permite-lhe abstrair as SUAS APIs da respetiva implementação, fornecendo definições agnósticas de linguagem que são legíveis por humanos e legíveis por computador. A descrição openAPI descreve as interações que a sua extensão suporta, permitindo ao Teams criar pedidos e comunicar diretamente com o seu serviço sem a necessidade de um serviço de processamento de camada média.
Um documento de descrição openAPI contém detalhes para comunicar com o serviço do programador. Certifique-se de que cumpre as seguintes diretrizes para o documento de Descrição de OpenAPI (OAD):
- As versões OpenAPI 2.0 e 3.0.x são suportadas.
- JSON e YAML são os formatos suportados.
- O corpo do pedido, se estiver presente, tem de ser application/Json.
- Defina um URL de servidor de protocolo HTTPS para a
servers.url
propriedade . - Apenas os métodos POST e GET HTTP são suportados.
- O documento Descrição de OpenAPI tem de ter um
operationId
. - Só é permitido um parâmetro necessário sem um valor predefinido.
- Um parâmetro necessário com um valor predefinido é considerado opcional.
- Os utilizadores não podem introduzir um parâmetro para um cabeçalho ou cookie.
- A operação não pode ter um cabeçalho ou parâmetros de cookie necessários sem valores predefinidos.
- Certifique-se de que não existem referências remotas no documento Descrição de OpenAPI.
- A construção de matrizes para o pedido não é suportada; no entanto, os objetos aninhados dentro de um corpo de pedido JSON são suportados.
- O Teams não suporta as
oneOf
construções ,anyOf
,allOf
enot
(swagger.io).
O código seguinte é um exemplo de um documento de Descrição de OpenAPI:
Documento de Descrição de OpenAPI de Exemplo
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 obter mais informações sobre como escrever definições openAPI no YAML, veja Estrutura openAPI.
Manifesto do aplicativo
O manifesto de aplicação é um esquema para a sua aplicação Teams, que define como e onde a extensão de mensagem é invocada no cliente do Teams. Inclui os comandos suportados pela extensão e as localizações a partir das quais podem ser acedidos, como a área de composição de mensagens, a barra de comandos e a mensagem. O manifesto liga à Especificação OpenAPI e ao Modelo de Composição de Resposta para garantir a funcionalidade adequada.
O manifesto da aplicação contém a definição do comando de consulta. Certifique-se de que cumpre as seguintes diretrizes para o manifesto da aplicação:
- Defina a versão do manifesto da aplicação como
1.17
. - Defina
composeExtensions.composeExtensionType
comoapiBased
. - Defina
composeExtensions.apiSpecificationFile
como o caminho relativo para o documento Descrição de OpenAPI na pasta. Isto liga o manifesto da aplicação à especificação da API. - Defina
apiResponseRenderingTemplateFile
como o caminho relativo para o modelo de composição de resposta. Isto especifica a localização do modelo utilizado para compor respostas da API. - Cada comando tem de ter uma ligação para o modelo de composição de resposta. Esta ação liga cada comando ao respetivo formato de resposta correspondente.
- A
Commands.id
propriedade no manifesto da aplicação tem de corresponder aooperationId
no documento Descrição de OpenAPI. - Se um parâmetro necessário não tiver um valor predefinido, o comando
parameters.name
no manifesto da aplicação tem de corresponder aoparameters.name
no documento de descrição OpenAPI. - Se não existir nenhum parâmetro necessário, o comando
parameters.name
no manifesto da aplicação tem de corresponder ao opcionalparameters.name
no documento Descrição de OpenAPI. - Certifique-se de que o nome dos parâmetros para cada comando no manifesto da aplicação corresponde exatamente ao nome correspondente do parâmetro definido para a operação no documento Descrição de OpenAPI.
- Um modelo de composição de resposta tem de ser definido por comando, que é utilizado para converter respostas de uma API.
- As descrições do comando e dos parâmetros não podem exceder os 128 carateres.
Segue-se um exemplo de manifesto de aplicação com definições para extensões de mensagens baseadas em API:
Exemplo de manifesto de aplicação
{
"$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": []
}
Parâmetros
Nome | Descrição |
---|---|
composeExtensions.composeExtensionType |
Compose tipo de extensão. Atualize o valor para apiBased . |
composeExtensions.authorization |
Informações relacionadas com autorização para a extensão de mensagens baseada em API |
composeExtensions.authorization.authType |
Enumeração de possíveis tipos de autorização. Os valores suportados são none , apiSecretServiceAuth e microsoftEntra . |
composeExtensions.authorization.apiSecretServiceAuthConfiguration |
Objeto que captura os detalhes necessários para realizar a autenticação do serviço. Aplicável apenas quando o tipo de autenticação for apiSecretServiceAuth . |
composeExtensions.authorization.apiSecretServiceAuthConfiguration.apiSecretRegistrationId |
ID de registo devolvido quando o programador submete a chave de API através do Portal do Programador. |
composeExtensions.apiSpecificationFile |
Referencia um ficheiro de Descrição de OpenAPI no pacote de aplicação. Incluir quando o tipo for apiBased . |
composeExtensions.commands.id |
ID exclusivo que atribui ao comando de pesquisa. A solicitação do usuário inclui essa ID. O ID tem de corresponder ao operationId disponível na Descrição de OpenAPI. |
composeExtensions.commands.context |
Matriz onde os pontos de entrada para a extensão de mensagem estão definidos. Os valores predefinidos são compose e commandBox . |
composeExtensions.commands.parameters |
Define uma lista estática de parâmetros para o comando . O nome tem de ser mapeado para na parameters.name Descrição de OpenAPI. Se estiver a referenciar uma propriedade no esquema do corpo do pedido, o nome tem de mapear para properties.name ou consultar parâmetros. |
composeExtensions.commands.apiResponseRenderingTemplateFile |
Modelo utilizado para formatar a resposta JSON da API do programador para a resposta do Cartão Ajustável. [Obrigatório] |
Para obter mais informações, veja composeExtensions.
Modelo de composição de resposta
Observação
O Teams suporta Cartões Ajustáveis até à versão 1.5. Ao utilizar o Estruturador de Cartões Ajustáveis, certifique-se de que altera a versão de destino para 1.5.
O modelo de composição de respostas é um formato predefinido que dita a forma como os resultados da sua API são apresentados no Teams. Utiliza modelos para criar Cartões Ajustáveis ou outros elementos de IU a partir da resposta da API, garantindo uma experiência de utilizador integrada e integrada no Teams. O modelo define o esquema e o estilo das informações apresentadas, que podem incluir texto, imagens e componentes interativos. Certifique-se de que cumpre as seguintes diretrizes para o modelo de composição de respostas:
- Defina o URL de referência de esquema na
$schema
propriedade para estabelecer a estrutura do modelo para o esquema do modelo de composição de resposta. - Os valores suportados para
responseLayout
sãolist
egrid
, que determinam como a resposta é apresentada visualmente. Para obter mais informações sobre o esquema, veja Responder a pedidos de utilizador. - A
jsonPath
é necessário para matrizes ou quando os dados do Cartão Ajustável não são o objeto raiz. Por exemplo, se os seus dados estiverem aninhados emproductDetails
, o caminho JSON seriaproductDetails
. - Defina
jsonPath
como o caminho para os dados ou matriz relevantes na resposta da API. Se o caminho apontar para uma matriz, cada entrada na matriz vincula-se ao modelo Cartão Ajustável e devolve como um resultado separado. [Opcional] - Obtenha uma resposta de exemplo para validar o modelo de composição de resposta. Isto serve como um teste para garantir que o seu modelo funciona conforme esperado.
- Utilize ferramentas como o Fiddler ou o Postman para chamar a API e garantir que o pedido e a resposta são válidos. Este passo é crucial para resolver problemas e confirmar que a API está a funcionar corretamente.
- Pode utilizar o cartão ajustável Designer para vincular a resposta da API ao modelo de composição de resposta e pré-visualizar o Cartão Ajustável. Insira o modelo Cartão Ajustável no EDITOR DE PAYLOAD CARTÃO e insira a entrada de resposta de exemplo no EDITOR DE DADOS DE EXEMPLO.
O código seguinte é um exemplo de um modelo de composição de Resposta:
Exemplo de modelo de composição de resposta
{
"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}"
}
}
}
Cartão de Pré-visualização
Um modelo de card de pré-visualização no esquema de modelo de composição de resposta é utilizado para mapear respostas JSON para uma pré-visualização card que os utilizadores veem quando selecionam um resultado de pesquisa. A pré-visualização card, em seguida, expande-se para um Cartão Ajustável na caixa de composição de mensagens. O modelo de card de pré-visualização faz parte do modelo de composição de resposta, que também inclui um modelo de Cartão Ajustável e metadados.
Cartão Ajustável Expandido
Parâmetros
Propriedade | Tipo | Descrição | Obrigatório |
---|---|---|---|
version |
string |
A versão de esquema do modelo de composição de resposta atual. | Sim |
jsonPath |
string |
O caminho para a secção relevante nos resultados aos quais o responseCardTemplate e previewCardTemplate devem ser aplicados. Se não estiver definido, o objeto raiz é tratado como a secção relevante. Se a secção relevante for uma matriz, cada entrada é mapeada para responseCardTemplate e previewCardTemplate. | Não |
responseLayout |
responseLayoutType |
Especifica o esquema dos resultados na lista de opções da extensão de mensagem. Os tipos suportados são list e grid . |
Sim |
responseCardTemplate |
adaptiveCardTemplate |
Um modelo para criar um Cartão Ajustável a partir de uma entrada de resultado. | Sim |
previewCardTemplate |
previewCardTemplate |
Um modelo para criar uma pré-visualização card a partir de uma entrada de resultados. O card de pré-visualização resultante é apresentado no menu de lista de opções da extensão de mensagem. | Sim |
Caminho Json
O caminho JSON é opcional, mas deve ser utilizado para matrizes ou onde o objeto a ser utilizado como dados para o Cartão Ajustável não é o objeto raiz. O caminho JSON deve seguir o formato definido pela Newtonsoft. Esta ferramenta pode ser utilizada. Pode utilizar a ferramenta JSON para validar se um caminho JSON está correto. Se o caminho JSON apontar para uma matriz, cada entrada nessa matriz está vinculada ao modelo Cartão Ajustável e devolve como resultados separados.
Exemplo Suponhamos que tem o seguinte JSON para uma lista de produtos e quer criar um resultado card para cada entrada.
{
"version": "1.0",
"title": "All Products",
"warehouse": {
"products": [
...
]
}
}
Como pode ver, a matriz de resultados está em "produtos", que está aninhada em "armazém", pelo que o caminho JSON seria "warehouse.products".
Utilize https://adaptivecards.io/designer/ para pré-visualizar o Cartão Ajustável ao inserir o modelo no cartão Payload Editor e obter uma entrada de resposta de exemplo da sua matriz ou do seu objeto e inseri-lo no editor de Dados Idênticos à direita. Certifique-se de que o card é composto corretamente e é do seu agrado. O Teams suporta cartões até à versão 1.5, enquanto o estruturador suporta a versão 1.6.
Conversão de esquema OpenAPI
Observação
Enviamos um cabeçalho accept-language no pedido HTTP que é enviado para o ponto final definido no documento de descrição openAPI. A linguagem accept-language baseia-se na região do cliente do Teams e pode ser utilizada pelo programador para devolver uma resposta localizada.
Os seguintes tipos de dados no documento de descrição openAPI são convertidos em elementos dentro de um Cartão Ajustável da seguinte forma:
string
os tipos ,number
,integer
boolean
são convertidos num TextBlock.Exemplo
Esquema de Origem:
string
, ,number
integer
eboolean
name: type: string example: doggie
Esquema de Destino:
Textblock
{ "type": "TextBlock", "text": "name: ${if(name, name, 'N/A')}", "wrap": true }
array
: uma matriz é convertida num contentor dentro do Cartão Ajustável.Exemplo
Esquema de origem:
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
: um objeto é convertido numa propriedade aninhada no Cartão Ajustável.Exemplo
Esquema de Origem:
object
components: schemas: Pet: category: type: object properties: id: type: integer name: type: string
Esquema de Destino: propriedade aninhada num Cartão Ajustável
{ "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
: se uma propriedade for um URL de imagem, é convertida num elemento Imagem no Cartão Ajustável.Exemplo
Esquema de origem:
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}" }