Compartir a través de


Iniciar acciones con extensiones de mensajería

Importante

Los artículos de esta sección se basan en el SDK de Bot Framework v3. Si busca documentación actual (versión 4.6 o posterior del SDK), consulte la sección Interacciones orientadas a tareas con extensiones de mensaje .

Las extensiones de mensajes basadas en acciones permiten a los usuarios desencadenar acciones en servicios externos mientras están en Teams.

La captura de pantalla es un ejemplo que muestra la tarjeta de extensión de mensaje.

Agregar una extensión de mensaje a la aplicación

Una extensión de mensaje es un servicio hospedado en la nube que escucha las solicitudes del usuario y responde con datos estructurados, como una tarjeta. Integre el servicio con Microsoft Teams a través de objetos de Bot Framework Activity . Nuestras extensiones .NET y Node.js del SDK de Bot Builder pueden ayudarle a agregar la funcionalidad de extensión de mensaje a la aplicación.

Captura de pantalla que muestra la extensión de mensaje basada en acciones en Teams.

Registro en Bot Framework

Primero debe registrar un bot con Microsoft Bot Framework. El identificador de aplicación de Microsoft y los puntos de conexión de devolución de llamada del bot, tal como se define allí, se usan en la extensión de mensaje para recibir y responder a las solicitudes del usuario. No olvide habilitar el canal de Microsoft Teams para el bot.

Tome nota del identificador de la aplicación de bot y la contraseña de la aplicación; debe proporcionar el identificador de la aplicación en el manifiesto de la aplicación.

Actualizar el manifiesto de la aplicación

Al igual que con los bots y las pestañas, se actualiza el manifiesto de la aplicación para incluir las propiedades de la extensión de mensaje. Estas propiedades rigen cómo aparece y se comporta la extensión de mensaje en el cliente de Microsoft Teams. Las extensiones de mensaje se admiten a partir del manifiesto v1.0.

Declaración de la extensión de mensaje

Para agregar una extensión de mensaje, incluya una nueva estructura JSON de nivel superior en el manifiesto con la composeExtensions propiedad . Está limitado a crear una sola extensión de mensaje para la aplicación.

Nota:

El manifiesto hace referencia a las extensiones de mensaje como composeExtensions. Esto es para mantener la compatibilidad con versiones anteriores.

La definición de extensión es un objeto que tiene la estructura siguiente:

Nombre de propiedad Objetivo ¿Necesario?
botId El ID. de aplicación de Microsoft único para el bot, registrado con Bot Framework. Normalmente, debe ser el mismo que el identificador de la aplicación general de Teams. Yes
scopes Matriz que declara si esta extensión se puede agregar a personal o team ámbitos (o ambos). Yes
canUpdateConfiguration Habilita el elemento de menú Configuración . No
commands Matriz de comandos que admite esta extensión de mensaje. Está limitado a 10 comandos. Yes

Nota:

Si establece la canUpdateConfiguration propiedad true en en el manifiesto de la aplicación, puede mostrar el elemento de menú Configuración de la extensión de mensaje. Para habilitar La configuración, también debe controlar onQuerySettingsUrl y onSettingsUpdate.

Definición de comandos

La extensión de mensaje debe declarar un comando, que aparece cuando el usuario selecciona la aplicación en el botón Más opciones () del cuadro de redacción.

Captura de pantalla de un ejemplo que muestra una lista de extensiones de mensaje en Teams.

En el manifiesto de la aplicación, el elemento de comando es un objeto con la siguiente estructura:

Nombre de propiedad Objetivo ¿Necesario? Versión mínima del manifiesto
id Identificador único que se asigna a este comando. La solicitud de usuario incluye este id. 1.0
title Nombre del comando. Este valor aparece en la interfaz de usuario. 1.0
description Texto de ayuda que indica lo que hace este comando. Este valor aparece en la interfaz de usuario. 1.0
type Establezca el tipo de comando. Los valores posibles incluyen query y action. Si no está presente, el valor predeterminado se establece en query. No 1.4
initialRun Parámetro opcional, que se usa con query comandos. Si se establece en true, indica que este comando debe ejecutarse en cuanto el usuario elija este comando en la interfaz de usuario. No 1.0
fetchTask Parámetro opcional, que se usa con action comandos. Establézcalo en true para capturar la tarjeta adaptable o la dirección URL web que se mostrará en el módulo de tareas. Esto se usa cuando la entrada al action comando es dinámica en lugar de un conjunto estático de parámetros. Tenga en cuenta que si se establece en true, se omite la lista de parámetros estáticos para el comando. No 1.4
parameters Lista estática de parámetros para el comando. 1.0
parameter.name Nombre del parámetro. Esto se envía al servicio en la solicitud del usuario. 1.0
parameter.description Describe los propósitos de este parámetro y el ejemplo del valor que se debe proporcionar. Este valor aparece en la interfaz de usuario. 1.0
parameter.title Título o etiqueta de parámetros breves fáciles de usar. 1.0
parameter.inputType Establezca en el tipo de entrada necesaria. Entre los valores posibles se incluyen , , , , , toggletime. datenumbertextareatext El valor predeterminado está establecido en text. No 1.4
context Matriz opcional de valores que define el contexto en el que está disponible la acción del mensaje. Los valores posibles son message, composeo commandBox. El valor predeterminado es ["compose", "commandBox"]. No 1,5

Extensiones de mensaje de tipo de acción

Para iniciar acciones desde una extensión de mensaje, establezca el type parámetro en action. Una sola extensión de mensaje puede tener hasta 10 comandos diferentes e incluir varios comandos basados en búsquedas y basados en acciones.

Ejemplo de manifiesto de aplicación completo

El código siguiente es un ejemplo de un manifiesto con una búsqueda y un comando create:

{
  "$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 acciones a partir de mensajes

Puede iniciar acciones desde el área de redacción del mensaje y también desde un mensaje mediante la extensión de mensaje, lo que le permite enviar el contenido del mensaje al bot para su procesamiento. Opcionalmente, puede responder a ese mensaje mediante el método descrito en Responder al envío. La respuesta se incluye como respuesta al mensaje, que los usuarios pueden editar antes de enviar.

Los usuarios pueden acceder a la extensión de mensaje desde la opción Tomar acción del menú de desbordamiento ... , como se muestra en la siguiente imagen:

Captura de pantalla que describe cómo iniciar una acción desde un mensaje.

Para permitir que la extensión de mensaje funcione desde un mensaje, agregue el context parámetro al objeto de la extensión de commands mensaje en el manifiesto de la aplicación, como en el ejemplo siguiente. Las cadenas válidas para la context matriz son "message", "commandBox"y "compose". El valor predeterminado es ["compose", "commandBox"]. Consulte la sección definir comandos para obtener detalles completos sobre el 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
    }]
    ...

El código siguiente es un ejemplo del value objeto que contiene los detalles del mensaje que se envían como parte de la composeExtensions solicitud al 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
          }
        }
      ]
    }
  ...

Prueba a través de la carga

Para probar la extensión de mensaje, cargue la aplicación. Para obtener más información, consulte Carga de la aplicación en un equipo.

Para abrir la extensión de mensaje, vaya a cualquiera de sus chats o canales. Seleccione el botón Más opciones () en el cuadro de redacción y elija la extensión del mensaje.

Recopilación de entradas de usuarios

Hay tres maneras de recopilar información de un usuario en Teams.

Lista de parámetros estáticos

En este método, todo lo que necesita hacer es definir una lista estática de parámetros en el manifiesto, como se muestra en el comando "Crear que hacer". Para usar este método, asegúrese de fetchTask que está establecido false en y de que define los parámetros en el manifiesto.

Cuando un usuario elige un comando con parámetros estáticos, Teams genera un formulario en un módulo de tareas con los parámetros definidos en el manifiesto. Al presionar Enviar, se envía un composeExtensions/submitAction al bot. Para obtener más información sobre el conjunto de respuestas esperado, vea Responder al envío.

Entrada dinámica mediante una tarjeta adaptable

En este método, el servicio puede definir una tarjeta adaptable personalizada para recopilar la entrada del usuario. Para este enfoque, establezca el fetchTask parámetro true en en el manifiesto. Si establece en fetchTasktrue, se omiten los parámetros estáticos definidos para el comando.

En este método, el servicio recibe un composeExtensions/fetchTask evento y responde con una respuesta del módulo de tareas basada en tarjeta adaptable. A continuación se muestra una respuesta de ejemplo con una tarjeta adaptable:

{
    "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"
                }
            }
        }
    }
}

El bot también puede responder con una respuesta de autenticación o configuración si el usuario necesita autenticar o configurar la extensión antes de obtener la entrada del usuario.

Entrada dinámica mediante una vista web

En este método, el servicio puede mostrar un <iframe> widget basado para mostrar cualquier interfaz de usuario personalizada y recopilar la entrada del usuario. Para este enfoque, establezca el fetchTask parámetro true en en el manifiesto.

Al igual que en el flujo de tarjeta adaptable, el servicio envía un fetchTask evento y responde con una respuesta del módulo de tareas basada en direcciones URL. A continuación se muestra una respuesta de ejemplo con una tarjeta adaptable:

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

Solicitud para instalar el bot conversacional

Si la aplicación contiene un bot de conversación, asegúrese de que está instalado en la conversación antes de cargar el módulo de tareas para obtener más contexto para el módulo de tareas. Por ejemplo, es posible que tenga que capturar la lista para rellenar un control de selector de personas o la lista de canales de un equipo.

Para facilitar este flujo, cuando la extensión de mensaje reciba por primera vez la composeExtensions/fetchTask invocación, compruebe si el bot está instalado en el contexto actual. Para obtener esto, intente obtener la llamada a la lista. Por ejemplo, si el bot no está instalado, devuelve una tarjeta adaptable con una acción que solicita al usuario que instale el bot. El usuario debe tener permiso para instalar aplicaciones en esa ubicación. Si no se pueden instalar, el mensaje le pide que se ponga en contacto con el administrador.

Este es un ejemplo de la respuesta:

{
  "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"
}

Una vez que el usuario completa la instalación, el bot recibe otro mensaje de invocación con name = composeExtensions/submitAction y value.data.msteams.justInTimeInstall = true.

Este es un ejemplo de la invocación:

{
  "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 a la invocación con la misma respuesta de tarea con la que ha respondido, si se instaló el bot.

Responder al envío

Una vez que un usuario completa la entrada, el bot recibe un composeExtensions/submitAction evento con el identificador de comando y los valores de parámetro establecidos.

Estas son las distintas respuestas esperadas a .submitAction

Respuesta del módulo de tareas

La respuesta del módulo de tareas se usa cuando la extensión necesita encadenar cuadros de diálogo para obtener más información. La respuesta es la misma que fetchTask se mencionó anteriormente.

Redacción de la respuesta de autenticación/configuración de extensiones

La respuesta de autenticación o configuración de las extensiones de redacción se usa cuando la extensión necesita autenticarse o configurarse para continuar. Para obtener más información, consulte la sección autenticación en la sección de búsqueda.

Respuesta del resultado de las extensiones de redacción

La respuesta de resultado de las extensiones de redacción se usa para insertar una tarjeta en el cuadro de redacción como resultado del comando . Es la misma respuesta que se usa en el comando de búsqueda, pero se limita a una tarjeta o a un resultado en la 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 con un mensaje de tarjeta adaptable enviado desde un bot

Responda a la acción de envío insertando un mensaje con una tarjeta adaptable en el canal con un bot. El usuario puede obtener una vista previa del mensaje antes de enviarlo y, potencialmente, editarlo o interactuar con él también. Esto puede ser útil en escenarios en los que necesita recopilar información de los usuarios antes de crear una respuesta de tarjeta adaptable. En el escenario siguiente se muestra cómo puede usar este flujo para configurar un sondeo sin incluir los pasos de configuración en el mensaje del canal.

  1. El usuario selecciona la extensión de mensaje para desencadenar el módulo de tareas.
  2. El usuario usa el módulo de tareas para configurar el sondeo.
  3. Después de enviar el módulo de tareas de configuración, la aplicación usa la información proporcionada en el módulo de tareas para crear una tarjeta adaptable y enviarla como respuesta botMessagePreview al cliente.
  4. A continuación, el usuario puede obtener una vista previa del mensaje de tarjeta adaptable antes de que el bot lo inserte en el canal. Si el bot aún no es miembro del canal, al hacer clic en Send se agrega el bot.
  5. Interactuar con la tarjeta adaptable cambia el mensaje antes de enviarlo.
  6. Una vez que el usuario selecciona Send, el bot envía el mensaje al canal.

Nota:

  • activityPreview debe contener una actividad message con exactamente un archivo adjunto de tarjeta adaptable.
  • Outlook no admite la respuesta con un mensaje de tarjeta adaptable enviado desde un bot.

Para habilitar este flujo, el módulo de tareas debe responder como en el ejemplo siguiente, que presenta el mensaje de vista previa al usuario:

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

La extensión de mensaje debe responder a dos nuevos tipos de interacciones, value.botMessagePreviewAction = "send" y value.botMessagePreviewAction = "edit". El código siguiente es un ejemplo del value objeto que debe procesar:

{
  "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" }
      }
    ],
  }
}

Al responder a la edit solicitud, debe responder con una task respuesta con los valores rellenados con la información que envió el usuario. Al responder a la send solicitud, debe enviar un mensaje al canal que contiene la tarjeta adaptable finalizada.

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

Vea también

Ejemplos de Bot Framework