Compartilhar via


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 oneOfconstruções , anyOf, allOfe not (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 como apiBased.

  • 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 ao parameters.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 opcional parameters.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, apiSecretServiceAuthe 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ão list e grid, 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 em productDetails, o caminho JSON seria productDetails.
  • 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

Captura de ecrã a mostrar um exemplo de extensão de composição que apresenta uma matriz de cartões de pré-visualização ao procurar uma palavra específica. Neste caso, a pesquisa de

Cartão Ajustável Expandido

Exemplo de como o Cartão Ajustável parece expandido quando um utilizador seleciona uma pré-visualização card. O Cartão Ajustável mostra os valores Título, Descrição completa, Atribuído A, RepairId e Data.

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:

  • stringos tipos , number, integerboolean são convertidos num TextBlock.

    Exemplo
    • Esquema de Origem: string, , numberintegereboolean

       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.

Para criar uma extensão de mensagem baseada em API com o Portal do Programador para Teams, siga estes passos:

  1. Aceda ao Portal do Programador do Teams.

  2. Aceda a Aplicações.

  3. Selecione + Novas aplicações.

  4. Introduza um nome da aplicação e selecione a Versão do manifesto como Pré-visualização do programador público (devPreview).

  5. Selecione Adicionar.

    Captura de ecrã a mostrar o nome da aplicação e a versão do manifesto selecionada como Pré-lançamento mais recente (devPreview) no Portal do Programador.

  6. No painel esquerdo, em Configurar, atualize as seguintes informações Básicas:

    1. Nome completo
    2. Descrição curta
    3. Descrição longa
    4. Nome do programador ou da empresa
    5. Site (tem de ser um URL HTTPS válido)
    6. Política de privacidade
    7. Termos de uso
  7. Selecione Salvar.

  8. Selecione Funcionalidades da aplicação.

  9. Selecione Extensão de mensagens.

    Captura de ecrã a mostrar a opção de extensão de mensagem no Portal do Programador do Teams.

  10. Em Tipo de extensão de mensagem, selecione API.

    1. 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.
  11. Em Especificação OpenAPI, selecione Carregar agora.

    Captura de ecrã a mostrar a opção Carregar agora no Portal do Programador do Teams.

  12. Selecione o documento Descrição de OpenAPI no formato JSON ou YAML e selecione Abrir.

  13. Selecione Salvar. É apresentado um pop-up com a mensagem Especificação da API guardada com êxito.

  14. Selecione A receber.

    Captura de ecrã a mostrar um exemplo das especificações da API guardadas com êxito e o botão Obter.

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:

  1. Em Tipo de extensão de mensagem, selecione Adicionar.

    Captura de ecrã a mostrar a opção adicionar para adicionar comandos no Portal do Programador do Teams.

    É apresentado um pop-up adicionar comando com uma lista de todas as APIs disponíveis no documento Descrição de OpenAPI.

  2. Selecione uma API na lista e selecione Seguinte.

    Captura de ecrã a mostrar a lista de APIs do Documento de Descrição de OpenAPI na janela de pop-up Adicionar um comando.

    São apresentados os detalhes do Comando .

  3. Em Detalhes do comando, aceda a Modelo de card adaptável e selecione Carregar agora.

    Captura de ecrã a mostrar a opção Carregar agora para adicionar o modelo de Cartão Ajustável no para o comando .

    Observação

    Se tiver mais do que uma API, certifique-se de que carrega o modelo de card Adaptável para cada API.

  4. 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

    Captura de ecrã a mostrar os campos disponíveis na página de detalhes do comando.

  5. Em Detalhes, atualize a Descrição do comando.

    1. 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.
  6. Selecione Adicionar. O comando é adicionado com êxito.

  7. Selecione Salvar.

  8. 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.

Captura de ecrã a mostrar o plug-in para Microsoft 365 Copilot criado na página de funcionalidades da aplicação no Portal do Programador do Teams.

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:

Confira também

Autenticação para extensões de mensagens baseadas em API