Iniciar ações com extensões de mensagens

Importante

Os artigos nesta seção são baseados no v3 Bot Framework SDK. Se você estiver procurando a documentação atual (versão 4.6 ou versão posterior do SDK), consulte a seção Interações orientadas a tarefas com extensões de mensagem .

As extensões de mensagem baseadas em ações permitem que os seus utilizadores acionem ações em serviços externos no Teams.

A captura de ecrã é um exemplo que mostra a extensão da mensagem card.

Adicionar uma extensão de mensagem à sua aplicação

Uma extensão de mensagem é um serviço alojado na nuvem que ouve os pedidos dos utilizadores e responde com dados estruturados, como uma card. Integra o seu serviço com o Microsoft Teams através dos objetos do Bot Framework Activity . Nossas extensões .NET e Node.js para o SDK do Bot Builder podem ajudá-lo a adicionar funcionalidade de extensão de mensagem ao seu aplicativo.

Captura de ecrã que mostra a extensão de mensagem baseada em ações no Teams.

Registar-se no Bot Framework

Primeiro, você deve registrar 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 aí, são utilizados na extensão da mensagem para receber e responder aos pedidos dos utilizadores. Lembre-se de ativar o canal do Microsoft Teams para o seu bot.

Anote o ID do aplicativo do bot e a senha do aplicativo, você precisa fornecer o ID do aplicativo no manifesto do aplicativo.

Atualizar o manifesto da aplicação

Assim como acontece com bots e guias, você atualiza o manifesto do seu aplicativo para incluir as propriedades de extensão de mensagem. Estas propriedades regem a forma como a extensão da sua mensagem aparece e se comporta no cliente do Microsoft Teams. As extensões de mensagem são suportadas a partir do manifesto v1.0.

Declarar a extensão da sua mensagem

Para adicionar uma extensão de mensagem, inclua uma nova estrutura JSON de nível superior no manifesto com a composeExtensions propriedade. Está limitado a criar uma única extensão de mensagem para a sua aplicação.

Observação

O manifesto refere-se a extensões de mensagem como composeExtensions. Isto serve para manter a retrocompatibilidade.

A definição de extensão é um objeto que tem a seguinte estrutura:

Nome da propriedade Finalidade Obrigatório?
botId O ID exclusivo da aplicação Microsoft para o bot, conforme registado no Bot Framework. Normalmente, este deverá ser o mesmo que o ID da sua aplicação Teams geral. Sim
scopes Matriz que declara se esta extensão pode ser adicionada a personal âmbitos ou team (ou ambos). Sim
canUpdateConfiguration Ativa o item de menu Configurações . Não
commands Matriz de comandos que esta extensão de mensagem suporta. Está limitado a 10 comandos. Sim

Observação

Se definir a canUpdateConfiguration propriedade no true manifesto da aplicação, pode apresentar o item de menu Definições da sua extensão de mensagem. Para habilitar as configurações, você também deve manipular onQuerySettingsUrl e onSettingsUpdate.

Definir comandos

Sua extensão de mensagem deve declarar um comando, que aparece quando o usuário seleciona seu aplicativo a partir do botão Mais opções () na caixa de composição.

A captura de ecrã é um exemplo que mostra uma lista de extensões de mensagem no Teams.

No manifesto do aplicativo, seu item de comando é um objeto com a seguinte estrutura:

Nome da propriedade Finalidade Obrigatório? Versão de manifesto mínimo
id ID exclusivo que atribui a este comando. O pedido do utilizador inclui este ID. Sim 1,0
title Nome do comando. Este valor é apresentado na IU. Sim 1,0
description Texto de Ajuda que indica o que este comando faz. Este valor é apresentado na IU. Sim 1,0
type Defina o tipo de comando. Os valores possíveis incluem query e action. Se não estiver presente, o valor padrão será definido como query. Não 1,4
initialRun Parâmetro opcional, usado com query comandos. Se definido como true, indica que esse comando deve ser executado assim que o usuário escolher esse comando na interface do usuário. Não 1,0
fetchTask Parâmetro opcional, usado com action comandos. Defina como verdadeiro para obter um Cartão Adaptável ou o URL Web para apresentar no módulo de tarefas. Isso é usado quando a entrada para o action comando é dinâmica, em oposição a um conjunto estático de parâmetros. Observe que, se definida como true, a lista de parâmetros estáticos do comando será 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. Este é enviado para o seu serviço no pedido do utilizador. Sim 1,0
parameter.description Descreve as finalidades deste parâmetro e um exemplo do valor que deve ser fornecido. Este valor é apresentado na IU. Sim 1,0
parameter.title Título ou rótulo curto do parâmetro de fácil utilização. Sim 1,0
parameter.inputType Defina o tipo de entrada necessária. Os valores possíveis incluem text, textarea, number, date, time, toggle. O padrão é definido como text. Não 1,4
context Matriz opcional de valores que define o contexto no qual a ação da 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 mensagem de tipo de ação

Para iniciar ações de uma extensão de mensagem, defina o type parâmetro como action. Uma única extensão de mensagem pode ter até 10 comandos diferentes e incluir vários comandos baseados em pesquisa e ação.

Exemplo completo de manifesto do aplicativo

O código a seguir é um exemplo de manifesto com um comando de pesquisa e de criação:

{
  "$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://todobotservice.azurewebsites.net/",
    "privacyUrl": "http://todobotservice.azurewebsites.net/privacy",
    "termsOfUseUrl": "http://todobotservice.azurewebsites.net/termsofuse"
  },
  "name": {
    "short": "To Do",
    "full": "To Do"
  },
  "description": {
    "short": "Find or create a new task in To Do",
    "full": "Find or create a new task in To Do"
  },
  "icons": {
    "outline": "todo-outline.jpg",
    "color": "todo-color.jpg"
  },
  "accentColor": "#ff6a00",
  "composeExtensions": [
    {
      "botId": "57a3c29f-1fc5-4d97-a142-35bb662b7b23",
      "canUpdateConfiguration": true,
      "commands": [
        {
          "id": "searchCmd",
          "description": "Search you Todo's",
          "title": "Search",
          "initialRun": true,
          "context": ["commandBox", "compose"],
          "parameters": [
            {
              "name": "searchKeyword",
              "description": "Enter your search keywords",
              "title": "Keywords"
            }
          ]
        },
        {
          "id": "addTodo",
          "description": "Create a To Do item",
          "title": "Create To Do",
          "type": "action",
          "context": ["commandBox", "message", "compose"],
          "parameters": [
            {
              "name": "Name",
              "description": "To Do Title",
              "title": "Title",
              "inputType": "text"
            },
            {
              "name": "Description",
              "description": "Description of the task",
              "title": "Description",
              "inputType": "textarea"
            },
            {
              "name": "Date",
              "description": "Due date for the task",
              "title": "Date",
              "inputType": "date"
            }
          ]
        },
        {
          "id": "reassignTodo",
          "description": "Reassign a todo item",
          "title": "Reassign a todo item",
          "type": "action",
          "fetchTask": false,
          "parameters": [
            {
              "name": "Name",
              "title": "Title"
              "inputType": "text"
            }
          ]
        }
      ]
    }
  ],
  "permissions": [
    "identity",
    "messageTeamMembers"
  ],
  "validDomains": [
    "todobotservice.azurewebsites.net",
    "*.todobotservice.azurewebsites.net"
  ]
}

Iniciar ações a partir de mensagens

Você pode iniciar ações na área de redação de mensagem e também em uma mensagem usando sua extensão de mensagem, o que permite enviar o conteúdo da mensagem ao bot para processamento. Opcionalmente, você pode responder a essa mensagem usando o método descrito em Respondendo para enviar. A resposta é incluída como uma resposta à mensagem, que os usuários podem editar antes de enviar.

Os usuários podem acessar a extensão de mensagem na opção Executar ação do menu estouro ... , conforme mostrado na imagem a seguir:

A captura de tela descreve como iniciar uma ação a partir de uma mensagem.

Para permitir que sua extensão de mensagem funcione a partir de uma mensagem, adicione o context parâmetro ao objeto da extensão de commands mensagem no manifesto do aplicativo como no exemplo a seguir. As cadeias de caracteres válidas para a context matriz são "message", "commandBox", e "compose". O valor padrão é ["compose", "commandBox"]. Consulte a seção definir comandos para obter detalhes completos sobre o context parâmetro:

"composeExtensions": [
  {
    "botId": "57a3c29f-1fc5-4d97-a142-35bb662b7b23",
    "canUpdateConfiguration": true,
    "commands": [
      {
        "id": "reassignTodo",
        "description": "Reassign a todo item",
        "title": "Create To Do",
        "type": "Action",
        "context": ["message"],
        "fetchTask": true
    }]
    ...

O código a value seguir é um exemplo do objeto que contém os detalhes da mensagem enviados como parte da composeExtensions solicitação ao bot:

{
  "name": "composeExtension/submitAction",
  "type": "invoke",
...
  "value": {
    "commandId": "setReminder",
    "commandContext": "message",
    "messagePayload": {
      "id": "1111111111",
      "replyToId": null,
      "createdDateTime": "2019-02-25T21:29:36.065Z",
      "lastModifiedDateTime": null,
      "deleted": false,
      "subject": "Message subject",
      "summary": null,
      "importance": "normal",
      "locale": "en-us",
      "body": {
        "contentType": "html",
        "content": "this is the message"
    },
      "from": {
        "device": null,
        "conversation": null,
        "user": {
          "userIdentityType": "aadUser",
          "id": "wxyz12ab8-ab12-cd34-ef56-098abc123876",
          "displayName": "Jamie Smythe"
        },
        "application": null
      },
      "reactions": [
        {
          "reactionType": "like",
          "createdDateTime": "2019-02-25T22:40:40.806Z",
          "user": {
            "device": null,
            "conversation": null,
            "user": {
              "userIdentityType": "aadUser",
              "id": "qrst12346-ab12-cd34-ef56-098abc123876",
              "displayName": "Jim Brown"
            },
            "application": null
          }
        }
      ],
      "mentions": [
        {
          "id": 0,
          "mentionText": "Sarah",
          "mentioned": {
            "device": null,
            "conversation": null,
            "user": {
              "userIdentityType": "aadUser",
              "id": "ab12345678-ab12-cd34-ef56-098abc123876",
              "displayName": "Sarah"
            },
            "application": null
          }
        }
      ]
    }
  ...

Teste via upload

Você pode testar sua extensão de mensagem carregando seu aplicativo. Para obter mais informações, consulte Carregando seu aplicativo em uma equipe.

Para abrir sua extensão de mensagem, vá para qualquer um dos seus chats ou canais. Selecione o botão Mais opções () na caixa de redação e escolha a extensão da mensagem.

Coletando informações de usuários

Há três maneiras de coletar informações de um usuário no Teams.

Lista de parâmetros estáticos

Nesse método, tudo o que você precisa fazer é definir uma lista estática de parâmetros no manifesto, conforme mostrado no comando "Create To Do". Para usar esse método, verifique se fetchTask está definido como false e que você define seus parâmetros no manifesto.

Quando um usuário escolhe um comando com parâmetros estáticos, o Teams gera um formulário em um módulo de tarefa com os parâmetros definidos no manifesto. Ao pressionar Enviar, um composeExtensions/submitAction é enviado para o bot. Para obter mais informações sobre o conjunto esperado de respostas, consulte Respondendo ao enviar.

Entrada dinâmica usando um Cartão Adaptável

Nesse método, seu serviço pode definir um Cartão Adaptável personalizado para coletar a entrada do usuário. Para essa abordagem, defina o fetchTask parâmetro como true no manifesto. Se você definir fetchTask como true, todos os parâmetros estáticos definidos para o comando serão ignorados.

Nesse método, seu serviço recebe um composeExtensions/fetchTask evento e responde com uma resposta do módulo de tarefa baseada em Cartão Adaptável. A seguir está um exemplo de resposta com um Cartão Adaptável:

{
    "task": {
        "type": "continue",
        "value": {
            "card": {
                "contentType": "application/vnd.microsoft.card.adaptive",
                "content": {
                    "body": [
                        {
                            "type": "TextBlock",
                            "text": "Please enter the following information:"
                        },
                        {
                            "type": "TextBlock",
                            "text": "Name"
                        },
                        {
                            "type": "Input.Text",
                            "spacing": "None",
                            "title": "New Input.Toggle",
                            "placeholder": "Placeholder text"
                        },
                        {
                            "type": "TextBlock",
                            "text": "Date of birth"
                        },
                        {
                            "type": "Input.Date",
                            "spacing": "None",
                            "title": "New Input.Toggle"
                        }
                    ],
                    "type": "AdaptiveCard",
                    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
                    "version": "1.0"
                }
            }
        }
    }
}

O bot também pode responder com uma resposta de autenticação/configuração se o usuário precisar autenticar ou configurar a extensão antes de obter a entrada do usuário.

Entrada dinâmica usando um modo de exibição da Web

Nesse método, seu serviço pode mostrar um <iframe> widget baseado para mostrar qualquer interface do usuário personalizada e coletar a entrada do usuário. Para essa abordagem, defina o fetchTask parâmetro como true no manifesto.

Assim como no fluxo do Cartão Adaptável, seu serviço envia um fetchTask evento e responde com uma resposta do módulo de tarefa baseada em URL. A seguir está um exemplo de resposta com um Cartão Adaptável:

{
    "task": {
        "value": {
            "url": "http://mywebapp.com/input"
        },
        "type": "continue"
    }
}

Solicitação para instalar seu bot de conversa

Se seu aplicativo contiver um bot de conversa, verifique se ele está instalado na conversa antes de carregar seu módulo de tarefa para obter mais contexto para seu módulo de tarefa. Por exemplo, talvez seja necessário buscar a lista para preencher um controle do seletor de pessoas ou a lista de canais em uma equipe.

Para facilitar esse fluxo, quando sua extensão de mensagem receber a composeExtensions/fetchTask invocação pela primeira vez, marque se o bot está instalado no contexto atual. Você pode obter isso, tentando obter chamada de lista. Por exemplo, se o bot não estiver instalado, você retornará um Cartão Adaptável com uma ação que solicita que o usuário instale o bot. O usuário precisa ter permissão para instalar aplicativos nesse local. Se não for possível instalar, a mensagem solicitará que você contate o administrador.

Veja um exemplo da resposta:

{
  "type": "AdaptiveCard",
  "body": [
    {
      "type": "TextBlock",
      "text": "Looks like you haven't used Disco in this team/chat"
    }
  ],
  "actions": [
    {
      "type": "Action.Submit",
      "title": "Continue",
      "data": {
        "msteams": {
          "justInTimeInstall": true
        }
      }
    }
  ],
  "version": "1.0"
}

Depois que o usuário concluir a instalação, seu bot receberá outra mensagem de invocação com name = composeExtensions/submitAction e value.data.msteams.justInTimeInstall = true.

Aqui está um exemplo da invocação:

{
  "value": {
    "commandId": "giveKudos",
    "commandContext": "compose",
    "context": {
      "theme": "default"
    },
    "data": {
      "msteams": {
        "justInTimeInstall": true
      }
    }
  },
  "conversation": {
    "id": "19:7705841b240044b297123ad7f9c99217@thread.skype"
  },
  "name": "composeExtension/submitAction",
  "imdisplayname": "Bob Smith"
}

Responda à invocação com a mesma resposta de tarefa com a qual você respondeu, se o bot foi instalado.

Respondendo ao envio

Quando um usuário conclui a inserção de sua entrada, o bot recebe um composeExtensions/submitAction evento com a ID do comando e os valores de parâmetro definidos.

Estas são as diferentes respostas esperadas para um submitAction.

Resposta do módulo de tarefa

A resposta do módulo de tarefa é usada quando sua extensão precisa encadear caixas de diálogo para obter mais informações. A resposta é a fetchTask mesma mencionada anteriormente.

Compose extensions auth/config response

Compose extensions A resposta auth/config é usada quando sua extensão precisa autenticar ou configurar para continuar. Para obter mais informações, consulte a seção autenticação na seção de pesquisa.

Compose extensions result response

A resposta de resultado das extensões do Compose é usada para inserir um card na caixa de composição como resultado do comando. É a mesma resposta usada no comando de pesquisa, mas está limitada a um card ou um resultado na matriz.

{
  "composeExtension": {
    "type": "result",
    "attachmentLayout": "list",
    "preview": {
          "contentType": "application/vnd.microsoft.card.thumbnail",
          "content": {
            "title": "85069: Create a cool app",
            "images": [
              {
                "url": "https://placekitten.com/200/200"
              }
            ]
          }
        },
    "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"
                }
              ]
            }
          ]
        }
      }
    ]
  }
}

Responder com uma mensagem de Cartão Adaptável enviada de um bot

Responda à ação de envio inserindo uma mensagem com um Cartão Adaptável no canal com um bot. O usuário pode visualizar a mensagem antes de enviá-la e, possivelmente, também editar/interagir com ela. Isso pode ser útil em cenários em que você precisa coletar informações de seus usuários antes de criar uma resposta do Cartão Adaptável. O cenário a seguir mostra como você pode usar esse fluxo para configurar uma votação sem incluir as etapas de configuração na mensagem do canal.

  1. O usuário seleciona a extensão de mensagem para disparar o módulo de tarefa.
  2. O usuário usa o módulo de tarefa para configurar a sondagem.
  3. Depois de enviar o módulo de tarefa de configuração, o aplicativo usa as informações fornecidas no módulo de tarefa para criar um Cartão Adaptável e o envia como uma botMessagePreview resposta ao cliente.
  4. Em seguida, o usuário pode visualizar a mensagem do Cartão Adaptável antes que o bot a insira no canal. Se o bot ainda não for membro do canal, clicar em Send adiciona o bot.
  5. A interação com o Cartão Adaptável altera a mensagem antes de enviá-la.
  6. Depois que o usuário seleciona Send, o bot posta a mensagem no canal.

Observação

  • O activityPreview deve conter uma message atividade com exatamente um anexo de Cartão Adaptável.
  • O Outlook não oferece suporte para responder com uma mensagem de Cartão Adaptável enviada de um bot.

Para habilitar esse fluxo, seu módulo de tarefa deve responder como no exemplo a seguir, que apresenta a mensagem de visualização ao usuário:

{
  "composeExtension": {
    "type": "botMessagePreview",
    "activityPreview": {
      "type": "message",
      "attachments":  [
        {
          "contentType": "application/vnd.microsoft.card.adaptive",
          "content": << Card Payload >>
        }
      ]
    }
  }
}

Sua extensão de mensagem precisa responder a dois novos tipos de interações value.botMessagePreviewAction = "send" e value.botMessagePreviewAction = "edit". O código a value seguir é um exemplo do objeto que você precisa processar:

{
  "name": "composeExtension/submitAction",
  "type": "invoke",
  "conversation": { "id": "19:c366b75791784100b6e8b515fd55b063@thread.skype" },
  "imdisplayname": "Pranav Smith",
  ...
  "value": {
    "botMessagePreviewAction": "send" | "edit",
    "botActivityPreview": [
      {
        "type": "message/card",
        "attachments": [
          {
            "content":
              {
                "type": "AdaptiveCard",
                "body": [{<<card payload>>}]
              },
            "contentType" : "application/vnd.microsoft.card.adaptive"
          }
        ],
        "context": { "theme": "default" }
      }
    ],
  }
}

Ao responder à edit solicitação, você deve responder com uma task resposta com os valores preenchidos com as informações que o usuário enviou. Ao responder à send solicitação, você deve enviar uma mensagem para o canal contendo o Cartão Adaptável finalizado.

teamChatConnector.onComposeExtensionSubmitAction((
    event: builder.IEvent,
    request: teamBuilder.IComposeExtensionActionCommandRequest,
    callback: (err: Error, result: any, statusCode: number) => void) => {
        let invokeValue = (<any> event).value;

        if (invokeValue.botMessagePreviewAction ) {
            let attachment = invokeValue.botActivityPreview[0].attachments[0];

            if (invokeValue.botMessagePreviewAction === 'send') {
                let msg = new builder.Message()
                    .address(event.address)
                    .addAttachment(attachment);
                teamChatConnector.send([msg.toMessage()],
                    (error) => {
                        if(error){
                            // TODO: Handle error and callback.
                        }
                        else {
                            callback(null, null, 200);
                        }
                    }
                );
            }

            else if (invokeValue.botMessagePreviewAction === 'edit') {
              // Create the card and populate with user-inputted information.
              let card = { ... }

              let taskResponse = {
                task: {
                  type: "continue",
                  value: {
                    title: "Card Preview",
                    card: {
                      contentType: 'application/vnd.microsoft.card.adaptive',
                      content: card
                    }
                  }
                }
              }
              callback(null, taskResponse, 200);
            }

        else {
            let attachment = {
                  // Create Adaptive Card.
                };
            let activity = new builder.Message().addAttachment(attachment).toMessage();
            let response = teamBuilder.ComposeExtensionResponse.messagePreview()
                .preview(activity)
                .toResponse();
            callback(null, response, 200);
        }
    });

Confira também

Exemplos do Bot Framework