Procurar com extensões de mensagens
Importante
Os artigos nesta secção baseiam-se no SDK v3 do Bot Framework. Se estiver à procura da documentação atual (versão 4.6 ou versão posterior do SDK), veja a secção Interações orientadas para tarefas com Extensões de Mensagens .
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 cartão, 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 cartão. 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 o cartão ajustável ou o 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 , compose ou 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.
Exemplo de manifesto de aplicação completo
{
"$schema": "https://developer.microsoft.com/json-schemas/teams/v1.8/MicrosoftTeams.schema.json",
"manifestVersion": "1.5",
"version": "1.0",
"id": "57a3c29f-1fc5-4d97-a142-35bb662b7b23",
"developer": {
"name": "John Developer",
"websiteUrl": "http://bingbotservice.azurewebsites.net/",
"privacyUrl": "http://bingbotservice.azurewebsites.net/privacy",
"termsOfUseUrl": "http://bingbotservice.azurewebsites.net/termsofuse"
},
"name": {
"short": "Bing",
"full": "Bing"
},
"description": {
"short": "Find Bing search results",
"full": "Find Bing search results and share them with your team members."
},
"icons": {
"outline": "bing-outline.jpg",
"color": "bing-color.jpg"
},
"accentColor": "#ff6a00",
"composeExtensions": [
{
"botId": "57a3c29f-1fc5-4d97-a142-35bb662b7b23",
"canUpdateConfiguration": true,
"commands": [{
"id": "searchCmd",
"description": "Search Bing for information on the web",
"title": "Search",
"initialRun": true,
"parameters": [{
"name": "searchKeyword",
"description": "Enter your search keywords",
"title": "Keywords"
}]
}
]
}
],
"permissions": [
"identity",
"messageTeamMembers"
],
"validDomains": [
"bingbotservice.azurewebsites.net",
"*.bingbotservice.azurewebsites.net"
]
}
Testar através do carregamento
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 verificar primeiro se existem informações de configuração armazenadas; se a extensão da 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 mensagem exigir autenticação, verifique 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, verifique 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 cartão 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 onQuery
nã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 |
ID de objeto do Microsoft Entra do utilizador que enviou o pedido. |
channelData.tenant.id |
ID do inquilino do Microsoft Entra. |
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 consultacount : número de elementos a devolver |
Exemplo de solicitação
{
"name": "composeExtension/query",
"value": {
"commandId": "searchCmd",
"parameters": [
{
"name": "searchKeywords",
"value": "Toronto"
}
],
"queryOptions": {
"skip": 0,
"count": 25
}
},
"type": "invoke",
"timestamp": "2017-05-01T15:45:51.876Z",
"localTimestamp": "2017-05-01T08:45:51.876-07:00",
"id": "f:622749630322482883",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
"from": {
"id": "29:1C7dbRrC_5yzN1RGtZIrcWT0xz88KPGP9sxdpVpV8sODlgPHeQE9RqQ02hnpuKzy6zZ-AaZx6swUOMj_Dsdse3TQ4sIaeebbFBF-VgjJy_nY",
"name": "Larry Jin",
"aadObjectId": "cd723fa0-0591-416a-9290-e93ecf3a9b92"
},
"conversation": {
"id": "19:skypespaces_8198cfe0dd2647ae91930f0974768a40@thread.skype"
},
"recipient": {
"id": "28:b4922ea1-5315-4fd0-9b21-d941ab06e39f",
"name": "TheComposeExtensionDev"
},
"entities": [
{
"type": "clientInfo",
"country": "US",
"platform": "Windows"
}
]
}
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 cartão. 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 cartão.
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:
"composeExtensions": [
{
"botId": "abc123456-ab12-ab12-ab12-abcdef123456",
"messageHandlers": [
{
"type": "link",
"value": {
"domains": [
"*.trackeddomain.com"
]
}
}
]
}
]
Depois de adicionar o domínio para escutar o manifesto da aplicação, tem de alterar o código do bot para responder ao pedido de invocação abaixo.
{
"type": "invoke",
"name": "composeExtension/queryLink",
"value": {
"url": "https://theurlsubmittedbyyouruser.trackeddomain.com/id/1234"
}
}
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 de estado HTTP 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 pesquisaauth : pede ao utilizador para se autenticarconfig : pede ao utilizador para configurar a extensão da mensagemmessage : 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 objetos de cartão que contêm campos de miniatura, título e textogrid : 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 . |
Tipos e pré-visualizações de cartões de resposta
Suportamos os seguintes tipos de anexo:
Para obter mais informações, consulte Cartões para obter uma descrição geral.
Para saber como utilizar os tipos de cartões de miniatura e de destaque, consulte Adicionar cartões e ações de cartão.
Para obter mais informações sobre o cartão de conector dos Grupos do Microsoft 365, consulte Utilizar o cartão de conector para Grupos do Microsoft 365.
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 doattachment
objeto. Opreview
anexo só pode ser um cartão Hero ou Thumbnail. - Extraído das propriedades básicas
title
,text
eimage
do anexo. Estes são utilizados apenas se apreview
propriedade não estiver definida e estas propriedades estiverem disponíveis.
Pode apresentar uma pré-visualização de um cartão 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 cartão Hero ou Miniatura. Se não for especificada nenhuma propriedade de pré-visualização, a pré-visualização do cartão falha e nada é apresentado.
Exemplo de resposta
Este exemplo mostra uma resposta com dois resultados, combinando diferentes formatos de cartão: Conector para Grupos do Microsoft 365 e Adaptável. Embora provavelmente queira manter um formato de cartão 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.
{
"composeExtension": {
"type": "result",
"attachmentLayout": "list",
"attachments": [
{
"contentType": "application/vnd.microsoft.teams.card.o365connector",
"content": {
"sections": [
{
"activityTitle": "[85069]: Create a cool app",
"activityImage": "https://placekitten.com/200/200"
},
{
"title": "Details",
"facts": [
{
"name": "Assigned to:",
"value": "[Larry Brown](mailto:larryb@example.com)"
},
{
"name": "State:",
"value": "Active"
}
]
}
]
},
"preview": {
"contentType": "application/vnd.microsoft.card.thumbnail",
"content": {
"title": "85069: Create a cool app",
"images": [
{
"url": "https://placekitten.com/200/200"
}
]
}
}
},
{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"type": "AdaptiveCard",
"body": [
{
"type": "Container",
"items": [
{
"type": "TextBlock",
"text": "Microsoft Corp (NASDAQ: MSFT)",
"size": "medium",
"isSubtle": true
},
{
"type": "TextBlock",
"text": "September 19, 4:00 PM EST",
"isSubtle": true
}
]
},
{
"type": "Container",
"spacing": "none",
"items": [
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "75.30",
"size": "extraLarge"
},
{
"type": "TextBlock",
"text": "▼ 0.20 (0.32%)",
"size": "small",
"color": "attention",
"spacing": "none"
}
]
},
{
"type": "Column",
"width": "auto",
"items": [
{
"type": "FactSet",
"facts": [
{
"title": "Open",
"value": "62.24"
},
{
"title": "High",
"value": "62.98"
},
{
"title": "Low",
"value": "62.20"
}
]
}
]
}
]
}
]
}
],
"version": "1.0"
},
"preview": {
"contentType": "application/vnd.microsoft.card.thumbnail",
"content": {
"title": "Microsoft Corp (NASDAQ: MSFT)",
"text": "75.30 ▼ 0.20 (0.32%)"
}
}
}
]
}
}
Consulta predefinida
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
.
Exemplo de pedido para uma consulta predefinida
{
"type": "invoke",
"name": "composeExtension/query",
"value": {
"commandId": "searchCmd",
"parameters": [
{
"name": "initialRun",
"value": "true"
}
],
"queryOptions": {
"skip": 0,
"count": 25
}
},
⋮
}
Identifique o usuário
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 o ID de objeto do Microsoft Entra.
"from": {
"id": "29:1C7dbRrC_5yzN1RGtZIrcWT0xz88KPGP9sxdpVpV8sODlgPHeQE9RqQ02hnpuKzy6zZ-AaZx6swUOMj_Dsdse3TQ4sIaeebbFBF-VgjJy_nY",
"name": "Larry Jin",
"aadObjectId": "cd723fa0-0591-416a-9290-e93ecf3a9b92"
},
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 do 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 umaopenUrl
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.
Exemplo de solicitação reemitida
{
"name": "composeExtension/query",
"value": {
"commandId": "insertWiki",
"parameters": [{
"name": "searchKeyword",
"value": "lakers"
}],
"state": "12345",
"queryOptions": {
"skip": 0,
"count": 25
}
},
"type": "invoke",
"timestamp": "2017-04-26T05:18:25.629Z",
"localTimestamp": "2017-04-25T22:18:25.629-07:00",
"entities": [{
"type": "clientInfo",
"country": "US",
"platform": "Web",
}],
"text": "",
"attachments": [],
"address": {
"id": "f:7638210432489287768",
"channelId": "msteams",
"user": {
"id": "29:1A5TJWHkbOwSyu_L9Ktk9QFI1d_kBOEPeNEeO1INscpKHzHTvWfiau5AX_6y3SuiOby-r73dzHJ17HipUWqGPgw",
"aadObjectId": "fc8ca1c0-d043-4af6-b09f-141536207403"
},
"conversation": {
"id": "19:7705841b240044b297123ad7f9c99217@thread.skype"
},
"bot": {
"id": "28:c073afa8-7e77-4f92-b3e7-aa589e952a3e",
"name": "maotestbot2"
},
"serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
"useAuth": true
},
"source": "msteams"
}
Suporte do SDK
.NET
Para receber e processar consultas com o SDK do Bot Builder para .NET, pode verificar 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();