Criar uma 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 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.
Antes de começar, certifique-se de que cumpre os seguintes requisitos:
1. Descrição de OpenAPI (OAD)
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:
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, veja Estrutura openAPI.
2. Manifesto da aplicação
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 ficheiro 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 àoperationId
na 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 Descrição de 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
na Descrição de OpenAPI.Confirme que os parâmetros de cada comando correspondem exatamente aos nomes dos parâmetros definidos para a operação na especificação OpenAPI.
Um modelo de composição de resposta tem de ser definido por comando, que é utilizado para converter respostas de uma API.
A descrição completa não pode exceder os 128 carateres.
{ "$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": [] }
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.
3. Modelo de composição de resposta
Observação
O Teams suporta Cartões Ajustáveis até à versão 1.5 e os Cartões Ajustáveis Designer suportam até à versão 1.6.
-
Defina o URL de referência de esquema na
$schema
propriedade para estabelecer a estrutura do modelo. -
Os valores suportados para
responseLayout
sãolist
egrid
, que determinam como a resposta é apresentada visualmente. -
É recomendado um
jsonPath
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 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",
"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
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 a card adaptável não é o objeto raiz. O caminho JSON deve seguir o formato definido pela Newtonsoft. Se o caminho JSON apontar para uma matriz, cada entrada nessa matriz está vinculada ao modelo de card adaptável e devolve como resultados separados.
Exemplo Suponhamos que tem o JSON abaixo para uma lista de produtos e quer criar uma card resultado 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 a card adaptá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 Mesmos Dados à direita. Certifique-se de que o card é composto corretamente e é do seu agrado. Tenha em atenção que o Teams suporta cartões até à versão 1.5, enquanto o estruturador suporta a versão 1.6.
Mapeamento de esquemas
As propriedades no documento Descrição de OpenAPI são mapeadas para o modelo 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}" }
Pode criar uma extensão de mensagem baseada em API com o Portal do Programador para Teams e o Teams Toolkit para Visual Studio Code, interface de linha de comandos (CLI) ou Visual Studio.
- Portal do Desenvolvedor do Teams
- Visual Studio Code
- CLI do Kit de Ferramentas do Teams
- Visual Studio
Para criar uma extensão de mensagem baseada em API com o Portal do Programador para Teams, siga estes passos:
Aceda ao Portal do Programador do Teams.
Aceda a Aplicações.
Selecione + Novas aplicações.
Introduza um nome da aplicação e selecione a Versão do manifesto como Pré-visualização do programador público (devPreview).
Selecione Adicionar.
No painel esquerdo, em Configurar, atualize as seguintes informações Básicas:
- Nome completo
- Descrição curta
- Descrição longa
- Nome do programador ou da empresa
- Site (tem de ser um URL HTTPS válido)
- Política de privacidade
- Termos de uso
Selecione Salvar.
Selecione Funcionalidades da aplicação.
Selecione Extensão de mensagens.
Em Tipo de extensão de mensagem, selecione API.
- Se receber uma exclusão de responsabilidade, que indica que a extensão de mensagem do Bot já está a ser utilizada pelos utilizadores. Pretende alterar o tipo de extensão de mensagem para API?. Selecione Sim, alterar.
Em Especificação OpenAPI, selecione Carregar agora.
Selecione o documento Descrição de OpenAPI no formato JSON ou YAML e selecione Abrir.
Selecione Salvar. É apresentado um pop-up com a mensagem Especificação da API guardada com êxito.
Selecione A receber.
Adicionar comandos
Observação
As extensões de mensagens criadas a partir de uma API só suportam um único parâmetro.
Pode adicionar comandos e parâmetros à sua extensão de mensagem para adicionar comandos:
Em Tipo de extensão de mensagem, selecione Adicionar.
É apresentado um pop-up adicionar comando com uma lista de todas as APIs disponíveis no documento Descrição de OpenAPI.
Selecione uma API na lista e selecione Seguinte.
São apresentados os detalhes do Comando .
Em Detalhes do comando, aceda a Modelo de card adaptável e selecione Carregar agora.
Observação
Se tiver mais do que uma API, certifique-se de que carrega o modelo de card Adaptável para cada API.
Selecione o ficheiro de modelo Cartão Ajustável no formato JSON e selecione Abrir.
Os seguintes atributos são atualizados automaticamente a partir do modelo cartão ajustável:
- Tipo de Comando
- ID do Comando
- Título do comando
- Nome do parâmetro
- Descrição do parâmetro
Em Detalhes, atualize a Descrição do comando.
- Se quiser iniciar um comando com um acionador no Microsoft 365 Copilot, ative o botão Executar automaticamente o comando quando um utilizador abrir o botão de alternar da extensão.
Selecione Adicionar. O comando é adicionado com êxito.
Selecione Salvar.
Em Autenticação, selecione qualquer uma das seguintes opções:
- Sem Autenticação
- Chave de API
É criada uma extensão de mensagem baseada em API.
Para testar a extensão de mensagem baseada em API criada no Portal do Programador para Teams, pode utilizar os seguintes métodos:
Pré-visualização no Teams: no Portal do Programador, abra a extensão da sua mensagem e selecione Pré-visualização no Teams no canto superior direito. É redirecionado para o Teams, onde pode adicionar a aplicação ao Teams para pré-visualizar a aplicação.
Transferir pacote de aplicação: na página da extensão da mensagem, selecione Pacote de aplicação no painel esquerdo e, em seguida, no canto superior esquerdo da janela, selecione Transferir pacote de aplicação. O pacote de aplicação é transferido para o seu computador local num ficheiro .zip. Pode carregar o pacote de aplicações para as equipas e testar a extensão da mensagem.
Guias passo a passo
Para criar uma extensão de mensagem baseada em API, siga estes guias passo a passo:
- Para principiantes: crie uma extensão de mensagem baseada em API com o Teams Toolkit.
- Para utilizadores avançados: crie uma extensão de mensagem baseada em API desde o início.