As extensões de mensagens baseadas em pesquisa permitem-lhe consultar o seu serviço e publicar essas informações sob a forma de um card diretamente na sua mensagem.
As secções seguintes descrevem como fazê-lo:
Adicionar uma extensão de mensagem à sua aplicação
Uma extensão de mensagem é um serviço alojado na cloud que escuta os pedidos dos utilizadores e responde com dados estruturados, como um card. Integra o seu serviço no Microsoft Teams através de objetos do Bot Framework Activity . As nossas extensões .NET e Node.js para o SDK do Bot Builder podem ajudá-lo a adicionar a funcionalidade de extensão de mensagens à sua aplicação.
Registar no Bot Framework
Primeiro, tem de registar um bot no Microsoft Bot Framework. O ID da aplicação Microsoft e os pontos finais de chamada de retorno para o bot, conforme definido aqui, são utilizados na extensão da sua mensagem para receber e responder a pedidos de utilizador. Lembre-se de ativar o canal do Microsoft Teams para o seu bot.
Tome nota do ID da aplicação do bot e da palavra-passe da aplicação. Tem de fornecer o ID da aplicação no manifesto da aplicação.
Atualizar seu manifesto do aplicativo
Tal como acontece com bots e separadores, atualiza o manifesto da sua aplicação para incluir as propriedades da extensão da mensagem. Estas propriedades regem a forma como a extensão de mensagem é apresentada e comporta-se no cliente do Microsoft Teams. As extensões de mensagens são suportadas a partir do manifesto v1.0.
Declarar a extensão da mensagem
Para adicionar uma extensão de mensagem, inclua uma nova estrutura JSON de nível superior no seu manifesto com a composeExtensions propriedade . Está limitado à criação de uma extensão de mensagem única para a sua aplicação.
Observação
O manifesto refere-se às extensões de mensagens como composeExtensions. Isto é para manter a retrocompatibilidade.
A definição da extensão é um objeto que tem a seguinte estrutura:
Nome da propriedade
Objetivo
Obrigatório?
botId
O ID exclusivo do aplicativo Microsoft para o bot conforme registrado na estrutura do bot. Normalmente, deve ser igual ao ID da sua aplicação geral do Teams.
Sim
scopes
Matriz a declarar se esta extensão pode ser adicionada a personal ou team âmbitos (ou ambos).
Sim
canUpdateConfiguration
Ativa o item de menu Definições .
Não
commands
Matriz de comandos suportados por esta extensão de mensagem. Está limitado a 10 comandos.
Sim
Observação
Se definir a canUpdateConfiguration propriedade como true no manifesto da aplicação, pode apresentar o item de menu Definições da sua extensão de mensagem. Para ativar as Definições, também tem de processar onQuerySettingsUrl e onSettingsUpdate.
Definir comandos
A extensão da sua mensagem deve declarar um comando, que é apresentado quando o utilizador seleciona a sua aplicação a partir do botão Mais opções (⋯) na caixa de composição.
No manifesto da aplicação, o item de comando é um objeto com a seguinte estrutura:
Nome da propriedade
Objetivo
Obrigatório?
Versão mínima do manifesto
id
ID exclusivo que atribui a este comando. A solicitação do usuário inclui essa ID.
Sim
1.0
title
Nome do comando. Esse valor aparece na interface do usuário.
Sim
1.0
description
Texto de ajuda que indica o que este comando faz. Esse valor aparece na interface do usuário.
Sim
1.0
type
Defina o tipo de comando. Os valores possíveis incluem query e action. Se não estiver presente, o valor predefinido está definido como query.
Não
1.4
initialRun
Parâmetro opcional, utilizado com query comandos. Se definido como verdadeiro, indica que este comando deve ser executado assim que o utilizador escolher este comando na IU.
Não
1.0
fetchTask
Parâmetro opcional, utilizado com action comandos. Defina como verdadeiro para obter um Cartão Ajustável ou UM URL da Web a apresentar no módulo de tarefa. Isto é utilizado quando a entrada para o action comando é dinâmica em oposição a um conjunto estático de parâmetros. Tenha em atenção que, se definido como verdadeiro, a lista de parâmetros estáticos do comando é ignorada.
Não
1.4
parameters
Lista estática de parâmetros para o comando .
Sim
1.0
parameter.name
O nome do parâmetro. Isso é enviado ao seu serviço na solicitação do usuário.
Sim
1.0
parameter.description
Descreve os objetivos deste parâmetro e o exemplo do valor que deve ser fornecido. Esse valor aparece na interface do usuário.
Sim
1.0
parameter.title
Título ou etiqueta abreviado do parâmetro amigável do utilizador.
Sim
1.0
parameter.inputType
Defina para o tipo de entrada necessário. Os valores possíveis incluem text, textarea, number, date, time, . toggle A predefinição está definida como text.
Não
1.4
context
Matriz opcional de valores que define o contexto em que a ação de mensagem está disponível. Os valores possíveis são message, composeou commandBox. O padrão é ["compose", "commandBox"].
Não
1,5
Extensões de mensagens de tipo de pesquisa
Para a extensão de mensagem baseada em pesquisa, defina o type parâmetro como query. Segue-se um exemplo de um manifesto com um único comando de pesquisa. Uma extensão de mensagem única pode ter até 10 comandos diferentes associados à mesma. Isto pode incluir múltiplas pesquisas e vários comandos baseados em ações.
Pode testar a extensão da mensagem ao carregar a sua aplicação.
Para abrir a extensão da sua mensagem, aceda a qualquer uma das suas conversas ou canais. Selecione o botão Mais opções (⋯) na caixa de composição e selecione a extensão da sua mensagem.
Adicionar processadores de eventos
A maior parte do seu trabalho envolve o onQuery evento, que processa todas as interações na janela da extensão da mensagem.
Se definir canUpdateConfiguration como true no manifesto, ative o item de menu Definições para a extensão da sua mensagem e também tem de processar onQuerySettingsUrl e onSettingsUpdate.
Processar eventos onQuery
Uma extensão de mensagem recebe um onQuery evento quando algo acontece na janela da extensão da mensagem ou é enviada para a janela.
Se a extensão da sua mensagem utilizar uma página de configuração, o processador de onQuery deve marcar primeiro para quaisquer informações de configuração armazenadas; se a extensão de mensagem não estiver configurada, devolva uma config resposta com uma ligação para a sua página de configuração. A resposta da página de configuração também é processada pelo onQuery. A única exceção é quando a página de configuração é chamada pelo processador para onQuerySettingsUrl; consulte a secção seguinte:
Se a extensão da sua mensagem exigir autenticação, marcar as informações de estado do utilizador. Se o utilizador não tiver sessão iniciada, siga as instruções na secção Autenticação mais à frente neste artigo.
Em seguida, marcar se initialRun está definido; se for o caso, tome as medidas adequadas, como fornecer instruções ou uma lista de respostas.
O resto do processador pede onQuery informações ao utilizador, apresenta uma lista de cartões de pré-visualização e devolve o card selecionado pelo utilizador.
Processar eventos onQuerySettingsUrl e onSettingsUpdate
Os onQuerySettingsUrl eventos e onSettingsUpdate funcionam em conjunto para ativar o item de menu Definições .
O processador de onQuerySettingsUrl devolve o URL da página de configuração; depois de a página de configuração fechar, o processador de onSettingsUpdate aceita e guarda o estado devolvido. Este é o único caso em que onQuerynão recebe a resposta da página de configuração.
Receber e responder a consultas
Cada pedido à extensão da mensagem é feito através de um Activity objeto que é publicado no URL de chamada de retorno. O pedido contém informações sobre o comando do utilizador, como o ID e os valores dos parâmetros. O pedido também fornece metadados sobre o contexto em que a extensão foi invocada, incluindo o ID de utilizador e inquilino, juntamente com o ID do chat ou o canal e os IDs de equipa.
Receber pedidos de utilizador
Quando um utilizador efetua uma consulta, o Microsoft Teams envia ao seu serviço um objeto padrão do Bot Framework Activity . O serviço deve efetuar a respetiva lógica para um Activity que tenha type definido invoke como e name definido como um tipo suportado composeExtensions , conforme mostrado na tabela seguinte.
Além das propriedades de atividade do bot padrão, o payload contém os seguintes metadados de pedido:
Nome da propriedade
Objetivo
type
Tipo de pedido; tem de ser invoke.
name
Tipo de comando que é emitido para o serviço. São suportados os seguintes tipos: composeExtension/query composeExtension/querySettingUrl composeExtension/setting composeExtension/selectItem composeExtension/queryLink
from.id
ID do usuário que enviou a solicitação.
from.name
Nome do usuário que enviou a solicitação.
from.aadObjectId
Microsoft Entra ID de objeto do utilizador que enviou o pedido.
channelData.tenant.id
Microsoft Entra ID do inquilino.
channelData.channel.id
ID do canal (se a solicitação foi feita em um canal).
channelData.team.id
ID da equipe (se a solicitação foi feita em um canal).
clientInfo
Metadados opcionais sobre o software de cliente utilizado para enviar a mensagem de um utilizador. A entidade pode conter duas propriedades: O country campo contém a localização detetada pelo utilizador. O platform campo descreve a plataforma de cliente de mensagens. Para obter mais informações, vejaTipos de entidade não IRI — clientInfo.
Os parâmetros do pedido encontram-se no objeto de valor, que inclui as seguintes propriedades:
Nome da propriedade
Objetivo
commandId
O nome do comando invocado pelo utilizador, que corresponde a um dos comandos declarados no manifesto da aplicação.
parameters
Matriz de parâmetros: cada objeto de parâmetro contém o nome do parâmetro, juntamente com o valor do parâmetro fornecido pelo utilizador.
queryOptions
Parâmetros de paginação: skip: ignorar contagem para esta consulta count: número de elementos a devolver
Receber pedidos de ligações inseridas na caixa de mensagem de composição
Como alternativa (ou além disso) à pesquisa no seu serviço externo, pode utilizar um URL inserido na caixa de mensagem de composição para consultar o seu serviço e devolver um card. Na captura de ecrã abaixo, um utilizador colou um URL para um item de trabalho no Azure DevOps, que a extensão da mensagem resolveu num card.
Para permitir que a extensão de mensagem interaja com ligações desta forma, primeiro tem de adicionar a messageHandlers matriz ao manifesto da aplicação, tal como no exemplo:
Se a sua aplicação devolver vários itens, apenas o primeiro é utilizado.
Responder a pedidos de utilizador
Quando o utilizador efetua uma consulta, o Teams emite um pedido HTTP síncrono ao seu serviço. Durante este período, o código tem 5 segundos para fornecer uma resposta HTTP ao pedido. Durante este período, o serviço pode efetuar outra pesquisa ou qualquer outra lógica de negócio necessária para servir o pedido.
O seu serviço deve responder com os resultados correspondentes à consulta do utilizador. A resposta tem de indicar um código http status de 200 OK e um objeto application/json válido com o seguinte corpo:
Nome da propriedade
Objetivo
composeExtension
Envelope de resposta de nível superior.
composeExtension.type
Tipo de resposta. São suportados os seguintes tipos: result: apresenta uma lista de resultados da pesquisa auth: Solicitações o utilizador a autenticar config: Solicitações o utilizador para configurar a extensão da mensagem message: exibe uma mensagem de texto simples
composeExtension.attachmentLayout
Especifica o esquema dos anexos. Utilizado para respostas do tipo result. São suportados os seguintes tipos: list: uma lista de card objetos que contêm miniaturas, título e campos de texto grid: uma grelha de imagens em miniatura
composeExtension.attachments
Matriz de objetos de anexo válidos. Utilizado para respostas do tipo result. São suportados os seguintes tipos: application/vnd.microsoft.card.thumbnail application/vnd.microsoft.card.hero application/vnd.microsoft.teams.card.o365connector application/vnd.microsoft.card.adaptive
composeExtension.suggestedActions
Ações sugeridas. Utilizado para respostas do tipo auth ou config.
composeExtension.text
Mensagem a apresentar. Utilizado para respostas do tipo message.
A lista de resultados é apresentada na IU do Microsoft Teams com uma pré-visualização de cada item. A pré-visualização é gerada de uma de duas formas:
Utilizar a preview propriedade dentro do attachment objeto. O preview anexo só pode ser um Card de Destaques ou Miniaturas.
Extraído das propriedades básicas title, texte image do anexo. Estes são utilizados apenas se a preview propriedade não estiver definida e estas propriedades estiverem disponíveis.
Pode apresentar uma pré-visualização de uma card adaptável ou de conector para Grupos do Microsoft 365 na lista de resultados, bastando definir a respetiva propriedade de pré-visualização. Isto não é necessário se os resultados já forem cartões de destaque ou miniaturas. Se utilizar o anexo de pré-visualização, este tem de ser um destaque ou um card de Miniaturas. Se não for especificada nenhuma propriedade de pré-visualização, a pré-visualização do card falha e nada é apresentado.
Exemplo de resposta
Este exemplo mostra uma resposta com dois resultados, combinando diferentes formatos de card: Conector para Grupos do Microsoft 365 e Adaptável. Embora provavelmente queira manter um formato de card na sua resposta, mostra como a preview propriedade de cada elemento na attachments coleção tem de definir explicitamente uma pré-visualização no formato de destaque ou miniatura, conforme descrito acima.
Se definir initialRun como true no manifesto, o Microsoft Teams emite uma consulta "predefinida" quando o utilizador abre pela primeira vez a extensão da mensagem. O seu serviço pode responder a esta consulta com um conjunto de resultados pré-preenchidos. Isto pode ser útil para apresentar, por exemplo, itens visualizados recentemente, favoritos ou qualquer outra informação que não dependa da entrada do utilizador.
A consulta predefinida tem a mesma estrutura que qualquer consulta de utilizador normal, exceto com um parâmetro initialRun cujo valor de cadeia é true.
Todos os pedidos aos seus serviços incluem o ID oculto do utilizador que efetuou o pedido e o nome a apresentar do utilizador e Microsoft Entra ID de objeto.
Os id valores e aadObjectId são garantidos como o do utilizador autenticado do Teams. Podem ser utilizadas como chaves para procurar credenciais ou qualquer estado em cache no seu serviço. Além disso, cada pedido contém o ID de inquilino Microsoft Entra do utilizador, que pode ser utilizado para identificar a organização do utilizador. Se aplicável, o pedido também contém os IDs da equipa e do canal a partir dos quais o pedido teve origem.
Autenticação
Se o seu serviço necessitar de autenticação de utilizador, tem de iniciar sessão no utilizador antes de o utilizador poder utilizar a extensão de mensagem. Se escreveu um bot ou um separador que inicia sessão no utilizador, esta secção deverá ser familiar.
A sequência é a seguinte:
O utilizador emite uma consulta ou a consulta predefinida é enviada automaticamente para o seu serviço.
O seu serviço verifica se o utilizador se autenticou primeiro ao inspecionar o ID de utilizador do Teams.
Se o utilizador não se tiver autenticado, envie uma auth resposta com uma openUrl ação sugerida, incluindo o URL de autenticação.
O cliente do Microsoft Teams inicia uma janela de pop-up que aloja a sua página Web com o URL de autenticação especificado.
Depois de o utilizador iniciar sessão, deve fechar a janela e enviar um "código de autenticação" para o cliente do Teams.
Em seguida, o cliente do Teams reedita a consulta para o seu serviço, que inclui o código de autenticação transmitido no passo 5.
O seu serviço tem de verificar se o código de autenticação recebido no passo 6 corresponde ao do passo 5, o que garante que um utilizador malicioso não tenta falsificar ou comprometer o fluxo de início de sessão. Isso efetivamente "fecha o loop" para concluir a sequência de autenticação segura.
Responder com uma ação de início de sessão
Para solicitar que um usuário não autenticado entre, responda com uma ação sugerida do tipo openUrl que inclui a URL de autenticação.
Exemplo de resposta para uma ação de início de sessão
{
"composeExtension":{
"type":"auth",
"suggestedActions":{
"actions":[
{
"type": "openUrl",
"value": "https://example.com/auth",
"title": "Sign in to this app"
}
]
}
}
}
Observação
Para que a experiência de início de sessão seja alojada num pop-up do Teams, a parte do domínio do URL tem de estar na lista de domínios válidos da sua aplicação. Para obter mais informações, confira validDomains no esquema de manifesto.
Iniciar o fluxo de início de sessão
O seu início de sessão tem de ser reativo e estar dentro de uma janela de pop-up. Ela deve se integrar ao SDK do cliente JavaScript do Microsoft Teams, que usa a passagem de mensagens.
Tal como acontece com outras experiências incorporadas em execução no Teams, o seu código dentro da janela tem de chamar microsoftTeams.initialize()primeiro . Se o seu código executar um fluxo OAuth, pode transmitir o ID de utilizador do Teams para a janela, que, em seguida, pode passá-lo para o URL do URL de início de sessão do OAuth.
Concluir o fluxo de início de sessão
Quando o pedido de início de sessão for concluído e redirecionar novamente para a sua página, deverá executar os seguintes passos:
Gerar um código de segurança. (Pode ser um número aleatório.) Tem de colocar este código em cache no seu serviço, juntamente com as credenciais obtidas através do início de sessão, como tokens OAuth 2.0.
Chamar microsoftTeams.authentication.notifySuccess e passar o código de segurança.
Neste momento, a janela é fechada e o controlo é passado para o cliente do Teams. O cliente pode agora reeditar a consulta original do utilizador, juntamente com o código de segurança na state propriedade . Seu código pode usar o código de segurança para pesquisar as credenciais armazenadas anteriormente para concluir a sequência de autenticação e, em seguida, concluir a solicitação do usuário.
Para receber e processar consultas com o SDK do Bot Builder para .NET, pode marcar para o invoke tipo de ação na atividade de entrada e, em seguida, utilizar o método auxiliar no pacote NuGet Microsoft.Bot.Connector.Teams para determinar se é uma atividade de extensão de mensagens.
Código de exemplo no .NET
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Invoke) // Received an invoke
{
if (activity.IsComposeExtensionQuery())
{
// This is the response object that will get sent back to the messaging extension request.
ComposeExtensionResponse invokeResponse = null;
// This helper method gets the query as an object.
var query = activity.GetComposeExtensionQueryData();
if (query.CommandId != null && query.Parameters != null && query.Parameters.Count > 0)
{
// query.Parameters has the parameters sent by client
var results = new ComposeExtensionResult()
{
AttachmentLayout = "list",
Type = "result",
Attachments = new List<ComposeExtensionAttachment>(),
};
invokeResponse.ComposeExtension = results;
}
// Return the response
return Request.CreateResponse<ComposeExtensionResponse>(HttpStatusCode.OK, invokeResponse);
} else
{
// Handle other types of Invoke activities here.
}
} else {
// Failure case catch-all.
var response = Request.CreateResponse(HttpStatusCode.BadRequest);
response.Content = new StringContent("Invalid request! This API supports only messaging extension requests. Check your query and try again");
return response;
}
}
Node.js
Código de exemplo no Node.js
require('dotenv').config();
import * as restify from 'restify';
import * as builder from 'botbuilder';
import * as teamBuilder from 'botbuilder-teams';
class App {
run() {
const server = restify.createServer();
let teamChatConnector = new teamBuilder.TeamsChatConnector({
appId: process.env.MICROSOFT_APP_ID,
appPassword: process.env.MICROSOFT_APP_PASSWORD
});
// Command ID must match what's defined in manifest
teamChatConnector.onQuery('<%= commandId %>',
(event: builder.IEvent,
query: teamBuilder.ComposeExtensionQuery,
callback: (err: Error, result: teamBuilder.IComposeExtensionResponse, statusCode: number) => void) => {
// Check for initialRun; i.e., when you should return default results
// if (query.parameters[0].name === 'initialRun') {}
// Check query.queryOptions.count and query.queryOptions.skip for paging
// Return auth response
// let response = teamBuilder.ComposeExtensionResponse.auth().actions([
// builder.CardAction.openUrl(null, 'https://authUrl', 'Please sign in')
// ]).toResponse();
// Return config response
// let response = teamBuilder.ComposeExtensionResponse.config().actions([
// builder.CardAction.openUrl(null, 'https://configUrl', 'Please sign in')
// ]).toResponse();
// Return result response
let response = teamBuilder.ComposeExtensionResponse.result('list').attachments([
new builder.ThumbnailCard()
.title('Test thumbnail card')
.text('This is a test thumbnail card')
.images([new builder.CardImage().url('https://bot-framework.azureedge.net/bot-icons-v1/bot-framework-default-9.png')])
.toAttachment()
]).toResponse();
callback(null, response, 200);
});
server.post('/api/composeExtension', teamChatConnector.listen());
server.listen(process.env.PORT, () => console.log(`listening to port:` + process.env.PORT));
}
}
const app = new App();
app.run();
A fonte deste conteúdo pode ser encontrada no GitHub, onde você também pode criar e revisar problemas e solicitações de pull. Para obter mais informações, confira o nosso guia para colaboradores.
Comentários do Platform Docs
O Platform Docs é um projeto código aberto. Selecione um link para fornecer comentários:
Learn how to build message extensions that allow users to interact with external services within their flow of work in Microsoft Teams and Microsoft 365 Copilot.
Saiba como criar e configurar extensões de mensagens baseadas em ações para o Microsoft Teams com o SDK do Bot Framework para permitir que os utilizadores acionem serviços externos.
Saiba como criar extensões de mensagens e os cenários em que são utilizadas. Explore exemplos sobre extensões de mensagens baseadas em ações e pesquisas.
Saiba como criar uma extensão de mensagem a partir do documento de descrição openAPI (OAD) com o Portal do Programador para Teams, Visual Studio Code, a CLI do Teams Toolkit ou o Visual Studio.
Saiba como criar e enviar caixas de diálogo (módulos de tarefas). Processe a ação de invocação inicial e responda com uma caixa de diálogo (módulo de tarefa) a partir de um comando de extensão de mensagem de ação.
Saiba como criar ou criar uma extensão de mensagem baseada em API com o Portal do Programador para Teams, o Teams Toolkit para Visual Studio, Visual Studio Code e a CLI.
Saiba mais sobre os comandos de pesquisa de extensões de mensagens para aplicações do Teams, para criar um comando de pesquisa através do manifesto da aplicação e manualmente.