Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Observação
- As extensões de mensagem baseadas em API dão suporte apenas a comandos de pesquisa.
- Não há suporte para extensões de mensagem baseadas em API no Microsoft 365 Copilot. Se você quiser criar extensões de mensagem baseadas em API compatíveis com o Microsoft 365 Copilot, confira Agentes de API do Microsoft 365 Copilot.
As extensões de mensagem criadas usando API (baseadas em API) usam um serviço Web para gerenciar solicitações e respostas do usuário e não exigem um registro de bot. As extensões de mensagem baseadas em API são um recurso do aplicativo Microsoft Teams que integra APIs externas diretamente ao Teams, aprimorando a usabilidade do aplicativo e oferecendo uma experiência de usuário perfeita. As extensões de mensagem baseadas em API oferecem suporte a comandos de pesquisa e podem ser usadas para buscar e exibir dados de serviços externos no Teams, simplificando os fluxos de trabalho ao reduzir a necessidade de alternar entre aplicativos. As extensões de mensagem baseadas em API ajudam seus aplicativos a interagir diretamente com dados, aplicativos e serviços de terceiros, aprimorando seus recursos. Com a extensão de mensagem baseada em API, você pode:
- Recupere informações em tempo real, como a cobertura de notícias mais recente sobre o lançamento de um produto.
- Recupere informações baseadas em conhecimento, por exemplo, os arquivos de design da equipe no Figma.
Observação
Os agentes fornecem uma experiência mais flexível, inteligente e pronta para o futuro que permite um raciocínio mais avançado, um desenvolvimento mais simples e um melhor alinhamento com o Teams em evolução e a plataforma Microsoft 365. Recomendamos que você explore e crie agentes.
Para obter mais informações, confira Criar agentes declarativos e Criar agentes no Teams.
Se você tiver uma extensão de mensagem baseada em bot existente, também poderá estendê-la como um agente .
Confira o vídeo para saber mais sobre como criar uma extensão de mensagem baseada em API usando o Microsoft 365 Agents Toolkit (anteriormente conhecido como Teams Toolkit):
| Extensões de mensagem tradicionais baseadas em bot | Extensões de mensagem baseadas em API |
|---|---|
| Os desenvolvedores precisam criar, implantar e manter um serviço para lidar com comandos de invocação do cliente do Teams. | Se as APIs do serviço final puderem ser descritas usando a Especificação OpenAPI, os desenvolvedores poderão eliminar a necessidade do serviço de manipulação da camada intermediária. |
| Esse serviço processa a consulta de entrada e faz uma chamada para o serviço final do desenvolvedor. | As equipes podem usar diretamente a especificação OpenAPI para criar solicitações e se comunicar com o serviço final do desenvolvedor. |
As imagens a seguir mostram o fluxo de consultas de usuário por meio de extensões de mensagem tradicionais e extensões de mensagem de API:
Fluxo de consulta do usuário usando Extensões de Mensagem Tradicionais. O desenvolvedor deve manter um serviço de manipulador de bot personalizado, que lida com as solicitações de um bot do Teams. O serviço do manipulador envia uma solicitação ao serviço do desenvolvedor quando uma consulta é invocada.
Fluxo de consulta do usuário usando extensões de mensagem de API. Não há necessidade de um serviço de manipulador mantido pelo desenvolvedor, desde que a interação esteja claramente descrita na Especificação OpenAPI no Pacote do Aplicativo.
Aqui está uma sequência de eventos de alto nível que ocorrem durante uma invocação de comando de consulta:
Quando um usuário invoca um comando de consulta, os parâmetros do comando de consulta são recebidos pelo Serviço de Bot do Teams.
O comando de consulta é definido dentro do arquivo de manifesto do aplicativo. A definição de comando contém uma referência ao interior do arquivo de especificação OpenAPI,
operationIdjuntamente com os detalhes dos parâmetros que o cliente do Teams renderiza para esse comando. Para referência, ooperationIdinterior do arquivo de especificação OpenAPI é exclusivo para uma operação HTTP específica.O Serviço de Bot do Teams usa os parâmetros fornecidos pelo usuário junto com a cópia da Especificação OpenAPI para o associado
operationIdpara criar uma solicitação HTTP para o ponto de extremidade do desenvolvedor.Se a autenticação é necessária e está configurada no manifesto. É resolvido para o token ou chave apropriado. Esse token ou chave é usado como parte da solicitação de saída. [Opcionalmente]
O serviço de bot do Teams executa a solicitação HTTP para o serviço do desenvolvedor.
O serviço do desenvolvedor deve responder de acordo com o esquema descrito na Especificação OpenAPI. Está no formato JSON.
O cliente do Teams deve mostrar os resultados de volta para o usuário. Para converter os resultados JSON da etapa anterior em interface do usuário, o serviço de bot do Teams usa o modelo de Renderização de resposta para criar um Cartão Adaptável para cada resultado.
Os Cartões Adaptáveis são enviados para o cliente, que os renderiza na interface do usuário.
Pré-requisitos
O pacote de definição de aplicativo inclui vários artefatos atraentes que dão suporte à funcionalidade desse recurso. Antes de começar, verifique se você tem uma compreensão básica dos seguintes arquivos:
Descrição do OpenAPI (OAD)
O documento de descrição do OpenAPI é um padrão do setor adotado para descrever APIs. Ele permite que você abstraia suas APIs de sua implementação, fornecendo definições independentes de linguagem que são legíveis por humanos e por máquina. O documento de descrição do OpenAPI descreve as interações que sua extensão suporta, permitindo que o Teams crie solicitações e se comunique diretamente com seu serviço sem a necessidade de um serviço de manipulação de camada intermediária.
Um documento de descrição do OpenAPI contém detalhes para se comunicar com o serviço do desenvolvedor. Certifique-se de seguir as seguintes diretrizes para o documento Descrição do OpenAPI (OAD):
- As versões 2.0 e 3.0.x do OpenAPI são suportadas.
- JSON e YAML são os formatos com suporte.
- O corpo da solicitação, se presente, deve ser application/Json.
- Defina uma URL do servidor de protocolo HTTPS para a
servers.urlpropriedade. - Há suporte apenas para os métodos POST e GET HTTP.
- O documento de descrição do OpenAPI deve ter um
operationIdarquivo . - Somente um parâmetro necessário sem um valor padrão é permitido.
- Um parâmetro necessário com um valor padrão é considerado opcional.
- Os usuários não devem inserir um parâmetro para um cabeçalho ou cookie.
- A operação não deve ter um cabeçalho obrigatório ou parâmetros de cookie sem valores padrão.
- Certifique-se de que não haja referências remotas no documento Descrição do OpenAPI.
- Não há suporte para a construção de matrizes para a solicitação; no entanto, há suporte para objetos aninhados em um corpo de solicitação JSON.
- O Teams não dá suporte às
oneOfconstruções ,anyOf,allOf, enot(swagger.io).
O código a seguir é um exemplo de documento de descrição do OpenAPI:
Documento de descrição do 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 de OpenAPI no YAML, consulte Estrutura do OpenAPI.
Manifesto do aplicativo
O manifesto do aplicativo é um plano para o aplicativo Teams, definindo como e onde a extensão de mensagem é invocada no cliente do Teams. Ele inclui os comandos aos quais sua extensão dá suporte e os locais dos quais eles podem ser acessados, como a área de redação de mensagem, a barra de comandos e a mensagem. O manifesto é vinculado à Especificação OpenAPI e ao Modelo de Renderização de Resposta para garantir a funcionalidade adequada.
O manifesto do aplicativo contém a definição de comando de consulta. Certifique-se de seguir as seguintes diretrizes para o manifesto do aplicativo:
- Defina a versão do manifesto do aplicativo como
1.17. - Defina
composeExtensions.composeExtensionTypecomoapiBased. - Defina
composeExtensions.apiSpecificationFilecomo o caminho relativo para o documento de descrição do OpenAPI dentro da pasta. Isso vincula o manifesto do aplicativo à especificação da API. - Defina
apiResponseRenderingTemplateFilecomo o caminho relativo para o modelo de renderização de resposta. Isso especifica o local do modelo usado para renderizar respostas da API. - Cada comando deve ter um link para o modelo de renderização de resposta. Isso conecta cada comando ao seu formato de resposta correspondente.
- A
Commands.idpropriedade no manifesto do aplicativo deve corresponder ao documento de descrição dooperationIdOpenAPI. - Se um parâmetro necessário não tiver um valor padrão, o comando
parameters.nameno manifesto do aplicativo deverá corresponder ao no documento de descrição doparameters.nameOpenAPI. - Se não houver nenhum parâmetro necessário, o comando
parameters.nameno manifesto do aplicativo deverá corresponder ao opcionalparameters.nameno documento Descrição do OpenAPI. - Certifique-se de que o nome dos parâmetros de cada comando no manifesto do aplicativo corresponda exatamente ao nome correspondente do parâmetro definido para a operação no documento Descrição do OpenAPI.
- Um modelo de renderização de resposta deve ser definido por comando, que é usado para converter respostas de uma API.
- As descrições de comando e parâmetro não devem exceder 128 caracteres.
Veja a seguir um exemplo de manifesto do aplicativo com definições para extensões de mensagem baseadas em API:
Exemplo de manifesto de aplicativo
{
"$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 à autorização para a extensão de mensagem baseada em API |
composeExtensions.authorization.authType |
Enumeração de possíveis tipos de autorização. Os valores com suporte são none, apiSecretServiceAuthe microsoftEntra. |
composeExtensions.authorization.apiSecretServiceAuthConfiguration |
Detalhes de captura de objeto necessários para fazer a autenticação de serviço. Aplicável somente quando o tipo de autenticação é apiSecretServiceAuth. |
composeExtensions.authorization.apiSecretServiceAuthConfiguration.apiSecretRegistrationId |
ID de registro retornada quando o desenvolvedor envia a chave de API por meio do Portal do desenvolvedor. |
composeExtensions.apiSpecificationFile |
Faz referência a um arquivo de Descrição do OpenAPI no pacote do aplicativo. Incluir quando o tipo é apiBased. |
composeExtensions.commands.id |
ID exclusiva que você atribui ao comando de pesquisa. A solicitação do usuário inclui essa ID. A ID deve corresponder ao operationId disponível na descrição do OpenAPI. |
composeExtensions.commands.context |
Matriz em que os pontos de entrada para extensão de mensagem estão definidos. Os valores padrão são compose e commandBox. |
composeExtensions.commands.parameters |
Define uma lista estática de parâmetros para o comando. O nome deve ser mapeado para o na descrição do parameters.name OpenAPI. Se você estiver fazendo referência a uma propriedade no esquema do corpo da solicitação, o nome deverá ser mapeado para properties.name ou consultar parâmetros. |
composeExtensions.commands.apiResponseRenderingTemplateFile |
Modelo usado para formatar a resposta JSON da API do desenvolvedor para a resposta do Cartão Adaptável. [Obrigatório] |
Para obter mais informações, consulte composeExtensions.
Modelo de renderização de resposta
O modelo de renderização de respostas é um formato predefinido que determina como os resultados da sua API são exibidos no Teams. Ele usa modelos para criar Cartões Adaptáveis ou outros elementos da interface do usuário com base na resposta da API, garantindo uma experiência do usuário integrada e perfeita no Teams. O modelo define o layout e o estilo das informações apresentadas, que podem incluir texto, imagens e componentes interativos. Siga as seguintes diretrizes para o modelo de renderização de respostas:
- Defina a URL de referência de esquema na
$schemapropriedade para estabelecer a estrutura do seu modelo para o esquema do modelo de renderização de resposta. - Os valores com suporte para
responseLayoutsãolistegrid, que determinam como a resposta é apresentada visualmente. Para obter mais informações sobre o layout, consulte responder às solicitações do usuário. - A
jsonPathé reexigido para matrizes ou quando os dados do Cartão Adaptável não são o objeto raiz. Por exemplo, se os dados estiverem aninhados emproductDetails, o caminho JSON seriaproductDetails. - Defina
jsonPathcomo o caminho para os dados ou matrizes relevantes na resposta da API. Se o caminho apontar para uma matriz, cada entrada na matriz será associada ao modelo de Cartão Adaptável e retornará como um resultado separado. [Opcional] - Obtenha uma resposta de exemplo para validar o modelo de renderização de resposta. Isso serve como um teste para garantir que seu modelo funcione conforme o esperado.
- Use ferramentas como Fiddler ou Postman para chamar a API e garantir que a solicitação e a resposta sejam válidas. Esta etapa é crucial para solucionar problemas e confirmar se sua API está funcionando corretamente.
- Você pode usar o Adaptive Card Designer para vincular a resposta da API ao modelo de renderização de resposta e visualizar o Cartão Adaptável. Insira o modelo de Cartão Adaptável no EDITOR DE CONTEÚDO DO CARTÃO e insira a entrada de resposta de exemplo no EDITOR DE DADOS DE EXEMPLO.
O código a seguir é um exemplo de um modelo de renderização de resposta:
Exemplo de modelo de renderizaçã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 visualização
Um modelo de card de visualização no esquema de modelo de renderização de resposta é usado para mapear respostas JSON para um card de visualização que os usuários veem quando selecionam um resultado de pesquisa. Em seguida, o card de visualização se expande para um Cartão Adaptável na caixa de redação de mensagem. O modelo de card de visualização faz parte do modelo de renderização de resposta, que também inclui um modelo de Cartão Adaptável e metadados.
Cartão Adaptável Expandido
Parâmetros
| Propriedade | Tipo | Descrição | Obrigatório |
|---|---|---|---|
version |
string |
A versão do esquema do modelo de renderização de resposta atual. | Sim |
jsonPath |
string |
O caminho para a seção relevante nos resultados ao qual o responseCardTemplate e o previewCardTemplate devem ser aplicados. Se não for definido, o objeto raiz será tratado como a seção relevante. Se a seção relevante for uma matriz, cada entrada será mapeada para responseCardTemplate e previewCardTemplate. | Não |
responseLayout |
responseLayoutType |
Especifica o layout dos resultados no submenu da extensão de mensagem. Os tipos com suporte são list e grid. |
Sim |
responseCardTemplate |
adaptiveCardTemplate |
Um modelo para criar um Cartão Adaptável a partir de uma entrada de resultado. | Sim |
previewCardTemplate |
previewCardTemplate |
Um modelo para criar um card de visualização a partir de uma entrada de resultado. O card de visualização resultante é exibido no menu de submenu da extensão de mensagem. | Sim |
Caminho JSON
O caminho JSON é opcional, mas deve ser usado para matrizes ou em que o objeto a ser usado como dados para o Cartão Adaptável não é o objeto raiz. O caminho JSON deve seguir o formato definido pela Newtonsoft. Esta ferramenta pode ser usada. Você pode usar a ferramenta JSON para validar se um caminho JSON está correto. Se o caminho JSON apontar para uma matriz, cada entrada nessa matriz será associada ao modelo de Cartão Adaptável e retornará como resultados separados.
Exemplo Digamos que você tenha o JSON a seguir para uma lista de produtos e queira criar um resultado de card para cada entrada.
{
"version": "1.0",
"title": "All Products",
"warehouse": {
"products": [
...
]
}
}
Como você pode ver, a matriz de resultados está em "produtos", que está aninhada em "warehouse", portanto, o caminho JSON seria "warehouse.products".
Use o Adaptive Card Designer para visualizar um Cartão Adaptável inserindo o modelo no Editor de Carga de Cartão. Pegue uma entrada de resposta de amostra de sua matriz ou para seu objeto e insira-a no Editor de Dados de Amostra. Certifique-se de que o card seja renderizado corretamente e seja do seu agrado.
Conversão de esquema OpenAPI
Observação
Enviamos um cabeçalho accept-language na solicitação HTTP que é enviada para o endpoint definido no documento de descrição do OpenAPI. O accept-language é baseado na localidade do cliente do Teams e pode ser usado pelo desenvolvedor para retornar uma resposta localizada.
Os seguintes tipos de dados no documento de descrição do OpenAPI são convertidos em elementos em um Cartão Adaptável da seguinte maneira:
string,number,integerboolean, tipos são convertidos em um TextBlock.Exemplo
Esquema de origem:
string,number,integerebooleanname: type: string example: doggieEsquema de destino:
Textblock{ "type": "TextBlock", "text": "name: ${if(name, name, 'N/A')}", "wrap": true }
array: uma matriz é convertida em um contêiner dentro do Cartão Adaptável.Exemplo
Esquema de origem:
arraytype: array items: required: - name type: object properties: id: type: integer category: type: object properties: name: type: stringEsquema 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 em uma propriedade aninhada no Cartão Adaptável.Exemplo
Esquema de origem:
objectcomponents: schemas: Pet: category: type: object properties: id: type: integer name: type: stringEsquema de destino: propriedade aninhada em um Cartão Adaptá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 uma URL de imagem, ela será convertida em um elemento Image no Cartão Adaptável.Exemplo
Esquema de origem:
imageimage: type: string format: uri description: The URL of the image of the item to be repairedEsquema de destino:
"Image"{ "type": "Image", "url": "${image}", "$when": "${image != null}" }