Iniciar ações com extensões de mensagensInitiate actions with messaging extensions

Importante

Os artigos desta seção são baseados no SDK do v3 bot Framework.The articles in this section are based on the v3 Bot Framework SDK. Se você estiver procurando a documentação atual (versão 4,6 ou posterior do SDK), confira a seção interações orientadas por tarefas com extensões de mensagens .If you're looking for current documentation (version 4.6 or later version of the SDK) see the Task-oriented interactions with Messaging Extensions section.

As extensões de mensagens baseadas em ação permitem que os usuários acionem ações em serviços externos enquanto estão dentro do Teams.Action-based messaging extensions allow your users to trigger actions in external services while inside of Teams.

Exemplo de cartão de extensão de mensagens

As seções a seguir descrevem como fazer isso.The following sections describe how to do this.

Adicionar uma extensão de mensagem ao seu aplicativoAdd a messaging extension to your app

Uma extensão de mensagens é um serviço hospedado na nuvem que escuta solicitações de usuário e responde com dados estruturados, como um cartão.A messaging extension is a cloud-hosted service that listens to user requests and responds with structured data, such as a card. Você integra seu serviço ao Microsoft Teams via objetos Activity da estrutura de bot.You integrate your service with Microsoft Teams via Bot Framework Activity objects. As extensões .NET e node. js para o SDK do bot Builder podem ajudá-lo a adicionar a funcionalidade de extensão de mensagens ao seu aplicativo.Our .NET and Node.js extensions for the Bot Builder SDK can help you add messaging extension functionality to your app.

Diagrama do fluxo de mensagens para extensões de mensagens

Registrar-se na estrutura de botRegister in the Bot Framework

Se ainda não tiver feito isso, primeiro você deve registrar um bot com a Microsoft bot Framework.If you haven’t done so already, you must first register a bot with the Microsoft Bot Framework. A ID do aplicativo da Microsoft e os pontos de extremidade de retorno de chamada do bot, conforme definido aqui, serão usados em sua extensão de mensagens para receber e responder às solicitações do usuário.The Microsoft app ID and callback endpoints for your bot, as defined there, will be used in your messaging extension to receive and respond to user requests. Lembre-se de habilitar o canal do Microsoft Teams para o bot.Remember to enable the Microsoft Teams channel for your bot.

Registre sua ID de aplicativo do bot e a senha do aplicativo, você precisará fornecer a ID do aplicativo em seu manifesto do aplicativo.Record your bot app ID and app password, you will need to supply the app ID in your app manifest.

Atualizar o manifesto do aplicativoUpdate your app manifest

Como com bots e guias, você atualiza o manifesto do seu aplicativo para incluir as propriedades de extensão de mensagens.As with bots and tabs, you update the manifest of your app to include the messaging extension properties. Essas propriedades controlam como sua extensão de mensagens aparece e se comporta no cliente Microsoft Teams.These properties govern how your messaging extension appears and behaves in the Microsoft Teams client. As extensões de mensagens têm suporte a partir da versão v 1.0 do manifesto.Messaging extensions are supported beginning with v1.0 of the manifest.

Declarar sua extensão de mensagensDeclare your messaging extension

Para adicionar uma extensão de mensagens, inclua uma nova estrutura JSON de nível superior no manifesto com a composeExtensions propriedade.To add a messaging extension, include a new top-level JSON structure in your manifest with the composeExtensions property. Atualmente, você está limitado a criar uma única extensão de mensagens para o seu aplicativo.Currently, you are limited to creating a single messaging extension for your app.

Observação

O manifesto se refere a extensões de composeExtensionsmensagens como.The manifest refers to messaging extensions as composeExtensions. Isso é para manter a compatibilidade com versões anteriores.This is to maintain backward compatibility.

A definição de extensão é um objeto que tem a seguinte estrutura:The extension definition is an object that has the following structure:

Nome da propriedadeProperty name FinalidadePurpose Obrigatório?Required?
botId A ID exclusiva do aplicativo da Microsoft para o bot, conforme registrado na estrutura do bot.The unique Microsoft app ID for the bot as registered with the Bot Framework. Isso deve ser normalmente o mesmo que a ID do aplicativo de suas equipes gerais.This should typically be the same as the ID for your overall Teams app. SimYes
scopes Matriz que declara se essa extensão pode ser adicionada personal a team ou escopos (ou ambos).Array declaring whether this extension can be added to personal or team scopes (or both). SimYes
canUpdateConfiguration Habilita o item de menu configurações .Enables Settings menu item. NãoNo
commands Matriz de comandos que esta extensão de mensagens suporta.Array of commands that this messaging extension supports. Você está limitado a 10 comandos.You are limited to 10 commands. SimYes

Definir comandosDefine commands

Sua extensão de mensagens deve declarar um comando, que aparece quando o usuário seleciona seu aplicativo no botão mais opções () na caixa de composição.Your messaging extension should declare one command, which appears when the user selects your app from the More options () button in the compose box.

Captura de tela da lista de extensões de mensagens no Microsoft Teams

No manifesto do aplicativo, seu item de comando é um objeto com a seguinte estrutura:In the app manifest, your command item is an object with the following structure:

Nome da propriedadeProperty name FinalidadePurpose Obrigatório?Required? Versão mínima do manifestoMinimum manifest version
id ID exclusiva que você atribui a este comando.Unique ID that you assign to this command. A solicitação do usuário incluirá essa ID.The user request will include this ID. SimYes 1.01.0
title Nome do comando.Command name. Esse valor é exibido na interface do usuário.This value appears in the UI. SimYes 1.01.0
description Texto de ajuda que indica o que esse comando faz.Help text indicating what this command does. Esse valor é exibido na interface do usuário.This value appears in the UI. SimYes 1.01.0
type Defina o tipo de comando.Set the type of command. Os valores possíveis incluem query e action.Possible values include query and action. Se não estiver presente, o valor padrão será definido comoqueryIf not present the default value is set to query NãoNo 1.41.4
initialRun Parâmetro opcional, usado com query comandos.Optional parameter, used with query commands. Se definido como true, indica que este comando deve ser executado assim que o usuário escolhe este comando na interface do usuário.If set to true, indicates this command should be executed as soon as the user chooses this command in the UI. NãoNo 1.01.0
fetchTask Parâmetro opcional, usado com action comandos.Optional parameter, used with action commands. Defina como true para buscar o cartão adaptável ou a URL da Web a serem exibidos no módulo de tarefa.Set to true to fetch the adaptive card or web url to display within the task module. Isso é usado quando as entradas do action comando são dinâmicas, em vez de um conjunto estático de parâmetros.This is used when the inputs to the action command is dynamic as opposed to a static set of parameters. Observe que, se definido como true , a lista de parâmetros estáticos do comando é ignoradaNote that the if set to true the static parameter list for the command is ignored NãoNo 1.41.4
parameters Lista estática de parâmetros para o comando.Static list of parameters for the command. SimYes 1.01.0
parameter.name O nome do parâmetro.The name of the parameter. Isso é enviado para o serviço na solicitação do usuário.This is sent to your service in the user request. SimYes 1.01.0
parameter.description Descreve os fins deste parâmetro ou o exemplo do valor que deve ser fornecido.Describes this parameter’s purposes or example of the value that should be provided. Esse valor é exibido na interface do usuário.This value appears in the UI. SimYes 1.01.0
parameter.title Título ou rótulo curto de parâmetro amigável.Short user-friendly parameter title or label. SimYes 1.01.0
parameter.inputType Defina como o tipo de entrada obrigatória.Set to the type of input required. Os valores possíveis textincluem textarea, number date time,,, toggle.Possible values include text, textarea, number, date, time, toggle. O padrão é definido comotextDefault is set to text NãoNo 1.41.4
context Matriz opcional de valores que define o contexto no qual a ação de mensagem está disponível.Optional array of values that defines the context the message action is available in. Os valores possíveis messagesão compose,, commandBoxou.Possible values are message, compose, or commandBox. O padrão é ["compose", "commandBox"].Default is ["compose", "commandBox"]. NãoNo 1,51.5

Extensões de mensagem de tipo de açãoAction type message extensions

Para iniciar ações de uma extensão de mensagens, de definir o type parâmetro como action .To initiate actions from a messaging extension set the type parameter to action. Veja a seguir um exemplo de um manifesto com uma pesquisa e um comando create.Below is an example of a manifest with a search and a create command. Uma única extensão de mensagens pode ter até 10 comandos diferentes.A single messaging extension can have up to 10 different commands. Isso pode incluir vários comandos baseados em ação e pesquisa.This can include both multiple search and multiple action-based commands.

Exemplo de manifesto completo do aplicativoComplete app manifest example

{
  "$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",
  "packageName": "com.microsoft.teams.samples.Todo",
  "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": true,
          "parameters": [
            {
              "name": "Name",
              "title": "Title"
            }
          ]
        }
      ]
    }
  ],
  "permissions": [
    "identity",
    "messageTeamMembers"
  ],
  "validDomains": [
    "todobotservice.azurewebsites.net",
    "*.todobotservice.azurewebsites.net"
  ]
}

Iniciar ações de mensagensInitiate actions from messages

Além de iniciar ações da área de mensagem de redação, você também pode usar a extensão de mensagens para iniciar uma ação de uma mensagem.In addition to initiating actions from the compose message area, you can also use your messaging extension to initiate an action from a message. Isso permitirá que você envie o conteúdo da mensagem para seu bot para processamento e, opcionalmente, responda a essa mensagem com uma resposta usando o método descrito em Responder para enviar.This will allow you to send the contents of the message to your bot for processing, and optionally reply to that message with a response using the method described in Responding to submit. A resposta será inserida como uma resposta à mensagem que seus usuários podem editar antes de enviar.The response will be inserted as a reply to the message that your users can edit before submitting. Os usuários podem acessar sua extensão de mensagens no menu de ... estouro e, em seguida, selecionar Take action como na imagem abaixo.Your users can access your messaging extension from the overflow ... menu and then selecting Take action as in the image below.

Exemplo de inicialização de uma ação de uma mensagem

Para permitir que sua extensão de mensagens funcione a partir de uma mensagem, você precisará adicionar o parâmetro ao objeto da extensão de mensagens no manifesto do aplicativo, como no exemplo context commands a seguir.To enable your messaging extension to work from a message you'll need to add the context parameter to your messaging extension's commands object in your app manifest as in the example below. Cadeias de caracteres válidas context para a matriz são , e "message" "commandBox" "compose" .Valid strings for the context array are "message", "commandBox", and "compose". O valor padrão é ["compose", "commandBox"].The default value is ["compose", "commandBox"]. Consulte a seção definir comandos para obter detalhes completos sobre o context parâmetro.See the define commands section for complete details on the context parameter.

"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
    }]
    ...

Veja a seguir um exemplo do objeto que contém os detalhes da mensagem que serão enviados como parte da value composeExtension solicitação que será enviada para o bot.Below is an example of the value object containing the message details that will be sent as part of the composeExtension request be sent to your 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
          }
        }
      ]
    }
  ...

Testar por meio do carregamentoTest via uploading

Você pode testar sua extensão de mensagens carregando seu aplicativo.You can test your messaging extension by uploading your app. Consulte Carregando seu aplicativo em uma equipe para obter detalhes.See Uploading your app in a team for details.

Para abrir sua extensão de mensagens, navegue até qualquer um dos seus chats ou canais.To open your messaging extension, navigate to any of your chats or channels. Escolha o botão Mais opções () na caixa de redação e escolha sua extensão de mensagens.Choose the More options () button in the compose box, and choose your messaging extension.

Coletando entradas de usuáriosCollecting input from users

Há três maneiras de coletar informações de um usuário final no Teams.There are three ways to collect information from an end user in Teams.

Lista de parâmetros estáticosStatic parameter list

Neste método, tudo o que você precisa fazer é definir uma lista estática de parâmetros no manifesto, conforme mostrado acima no comando "Criar Para Fazer".In this method, all you need to do is define a static list of parameters in the manifest as shown above in the "Create To Do" command. Para usar esse método, verifique fetchTask se está definido e que você false defina seus parâmetros no manifesto.To use this method ensure fetchTask is set to false and that you define your parameters in the manifest.

Quando um usuário escolhe um comando com parâmetros estáticos, o Teams gerará um formulário em um Módulo de Tarefas com os parâmetros definidos no manifesto.When a user chooses a command with static parameters, Teams will generate a form in a Task Module with the parameters defined in the manifest. Ao atingir Enviar um composeExtension/submitAction é enviado para o bot.On hitting Submit a composeExtension/submitAction is sent to the bot. Consulte o tópico Respondendo para enviar para obter mais informações sobre o conjunto esperado de respostas.See the topic Responding to submit for more information on the expected set of responses.

Entrada dinâmica usando um cartão adaptávelDynamic input using an adaptive card

Neste método, seu serviço pode definir um cartão adaptável personalizado para coletar a entrada do usuário final.In this method, your service can define a custom adaptive card to collect the end user input. Para essa abordagem, de fetchTask definir o parâmetro como no true manifesto.For this approach, set the fetchTask parameter to true in the manifest. Observe que se você definir fetchTask para true quaisquer parâmetros estáticos definidos para o comando será ignorado.Note that if you set fetchTask to true any static parameters defined for the command will be ignored.

Neste método, seu serviço receberá um evento e precisará responder com uma resposta de módulo de tarefa baseada em cartão composeExtension/fetchTask adaptável.In this method your service will receive a composeExtension/fetchTask event and needs to respond with an adaptive card based task module response. Abaixo está uma resposta de exemplo com um cartão adaptável:Below is an sample response with an adaptive card:

{
    "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 auth/config se o usuário precisar autenticar ou configurar a extensão antes de obter a entrada do usuário.The bot can also respond with an auth/config response if the user needs to authenticate or configure the extension before getting the user input.

Entrada dinâmica usando um modo de exibição da WebDynamic input using a web view

Neste método, seu serviço pode mostrar um widget baseado para mostrar qualquer interface do usuário <iframe> personalizada e coletar a entrada do usuário.In this method your service can show an <iframe> based widget to show any custom UI and collect user input. Para essa abordagem, de fetchTask definir o parâmetro como no true manifesto.For this approach, set the fetchTask parameter to true in the manifest.

Assim como no fluxo de cartão adaptável, seu serviço enviará um evento e precisará responder com uma resposta de módulo de tarefa fetchTask baseada emURL.Just like in the adaptive card flow your service will be send a fetchTask event and needs to respond with a URL based task module response. Abaixo está uma resposta de exemplo com um cartão Adaptável:Below is an sample response with an Adaptive card:

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

Solicitar a instalação do bot de conversaRequest to install your conversational bot

Se seu aplicativo também contiver um bot de conversa, talvez seja necessário garantir que o bot está instalado na conversa antes de carregar o módulo de tarefa.If your app also contains a conversational bot, it may be necessary to ensure that your bot is installed in the conversation before loading your task module. Isso pode ser útil em situações em que você precisa obter contexto adicional para o módulo de tarefas.This can be useful in situations where you need to get additional context for you task module. Por exemplo, talvez seja necessário buscar a lista para preencher um controle de selador de pessoas ou a lista de canais em uma equipe.For example, you may need to fetch the roster to populate a people picker control, or the list of channels in a team.

Para facilitar esse fluxo, quando sua extensão de mensagens recebe pela primeira vez a verificação de invocação para ver se o bot está instalado no contexto atual (você pode fazer isso ao tentar a chamada de lista de composeExtension/fetchTask recebimento, por exemplo).To facilitate this flow, when your messaging extension first receives the composeExtension/fetchTask invoke check to see if your bot is installed in the current context (you could accomplish this by attempting the get roster call, for example). 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 seu bot Consulte o exemplo abaixo.If your bot is not installed, you return an Adaptive Card with an action that requests the user to install your bot See the example below. Observe que isso exige que o usuário tenha permissão para instalar aplicativos nesse local; se não puderem, eles receberão uma mensagem solicitando que contatem o administrador.Note that this requires the user to have permission to install apps in that location; if they cannot they will be presented with a message asking them to contact their administrator.

Veja um exemplo da resposta:Here's an example of the response:

{
  "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 name = composeExtension/submitAction com e value.data.msteams.justInTimeInstall = true .Once the user completes the installation, your bot will receive another invoke message with name = composeExtension/submitAction, and value.data.msteams.justInTimeInstall = true.

Veja um exemplo da invocação:Here's an example of the invoke:

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

Você deve responder a essa invocação com a mesma resposta de tarefa com a que teria respondido se o bot já estivesse instalado.You should respond to this invoke with the same task response you would have responded with if the bot was already installed.

Respondendo ao envioResponding to submit

Depois que um usuário concluir a entrada, o bot receberá um evento com a id de comando composeExtension/submitAction e os valores de parâmetro definidos.Once a user completes entering their input your bot will receive a composeExtension/submitAction event with the command id and parameter values set.

Estas são as diferentes respostas esperadas para um submitAction .These are the different expected responses to a submitAction.

Resposta do Módulo de TarefaTask Module response

Isso é usado quando sua extensão precisa encadear as caixas de diálogo juntas para obter mais informações.This is used when your extension needs to chain dialogs together to get more information. A resposta é exatamente a mesma fetchTask mencionada anteriormente.The response is exactly the same as fetchTask mentioned earlier.

Resposta de auth/config de extensão de composiçãoCompose extension auth/config response

Isso é usado quando sua extensão precisa ser autenticada ou configurada para continuar.This is used when your extension needs to either authenticate or configure in order to continue. Consulte a seção autenticação na seção de pesquisa para obter mais detalhes.See authentication section in the search section for more details.

Resposta de resultado da extensão de composiçãoCompose extension result response

Isso usado para inserir um cartão na caixa de composição como resultado de um comando.This used to insert a card into the compose box as a result of a the command. É a mesma resposta usada no comando de pesquisa, mas está limitada a um cartão ou a um resultado na matriz.It's the same response that's used in the search command, but it's limited to one card or one result in the array.

{
  "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&quot;: &quot;https://placekitten.com/200/200"
            },
            {
              "title": "Details",
              "facts": [
                {
                  "name": "Assigned to:",
                  "value&quot;: &quot;[Larry Brown](mailto:larryb@example.com)"
                },
                {
                  "name": "State:",
                  "value": "Active"
                }
              ]
            }
          ]
        }
      }
    ]
  }
}

Responder com uma mensagem de cartão adaptável enviada de um botRespond with an adaptive card message sent from a bot

Você também pode responder à ação enviar inserindo uma mensagem com um Cartão Adaptável no canal com um bot.You can also respond to the submit action by inserting a message with an Adaptive Card into the channel with a bot. O usuário poderá visualizar a mensagem antes de enviar e também pode editar/interagir com ela.Your user will be able to preview the message before submitting it, and potentially edit/interact with it as well. Isso pode ser muito útil em cenários em que você precisa coletar informações de seus usuários antes de criar uma resposta de cartão adaptável.This can be very useful in scenarios where you need to gather information from your users before creating an adaptive card response. O cenário a seguir mostra como você pode usar esse fluxo para configurar uma sondagem sem incluir as etapas de configuração na mensagem do canal.The following scenario shows how you can use this flow to configure a poll without including the configuration steps in the channel message.

  1. O usuário clica na extensão de mensagens para disparar o módulo de tarefa.The user clicks the messaging extension to trigger the task module.
  2. O usuário usa o módulo de tarefa para configurar a sondagem.The user uses the task module to configure the poll.
  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 envia-o como uma resposta botMessagePreview ao cliente.After submitting the configuration task module the app uses the information provided in the task module to craft an adaptive card and sends it as a botMessagePreview response to the client.
  4. Em seguida, o usuário pode visualizar a mensagem de cartão adaptável antes que o bot a insere no canal.The user can then preview the adaptive card message before the bot will inserts it into the channel. Se o bot ainda não for membro do canal, clicar Send adicionará o bot.If the bot is not already a member of the channel, clicking Send will add the bot.
  5. Interagir com o cartão adaptável alterará a mensagem antes de enviá-la.Interacting with the adaptive card will change the message before sending it.
  6. Depois que o usuário Send clicar, o bot postará a mensagem no canal.Once the user clicks Send the bot will post the message to the channel.

Para habilitar esse fluxo, seu módulo de tarefa deve responder como no exemplo abaixo, que apresentará a mensagem de visualização ao usuário.To enable this flow your task module should respond as in the example below, which will present the preview message to the user.

Observação

O activityPreview deve conter uma atividade com exatamente message 1 anexo de cartão adaptável.The activityPreview must contain a message activity with exactly 1 adaptive card attachment.

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

Sua extensão de mensagem agora precisará responder a dois novos tipos de interações value.botMessagePreviewAction = "send" e value.botMessagePreviewAction = "edit" .Your message extension will now need to respond to two new types of interactions, value.botMessagePreviewAction = "send" and value.botMessagePreviewAction = "edit". Veja a seguir um exemplo do value objeto que você precisará processar:Below is an example of the value object you will need to process:

{
  "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 à solicitação, você deve responder com uma resposta com os valores preenchidos com as informações que o usuário edit task já enviou.When responding to the edit request you should respond with a task response with the values populated with the information the user has already submitted. Ao responder à send solicitação, você deve enviar uma mensagem para o canal que contém o cartão adaptável finalizado.When responding to the send request you should send a message to the channel containing the finalized adaptive card.

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);
        }
    });

Consulte também Exemplos da Estrutura de Bot.See also Bot Framework samples.