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.
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.
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.
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. | Sí | 1.0 |
title |
Nombre del comando. Este valor aparece en la interfaz de usuario. | Sí | 1.0 |
description |
Texto de ayuda que indica lo que hace este comando. Este valor aparece en la interfaz de usuario. | Sí | 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. | Sí | 1.0 |
parameter.name |
Nombre del parámetro. Esto se envía al servicio en la solicitud del usuario. | Sí | 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. | Sí | 1.0 |
parameter.title |
Título o etiqueta de parámetros breves fáciles de usar. | Sí | 1.0 |
parameter.inputType |
Establezca en el tipo de entrada necesaria. Entre los valores posibles se incluyen , , , , , toggle time . date number textarea text 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 , compose o 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:
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 fetchTask
true
, 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.
- El usuario selecciona la extensión de mensaje para desencadenar el módulo de tareas.
- El usuario usa el módulo de tareas para configurar el sondeo.
- 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. - 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. - Interactuar con la tarjeta adaptable cambia el mensaje antes de enviarlo.
- Una vez que el usuario selecciona
Send
, el bot envía el mensaje al canal.
Nota:
-
activityPreview
debe contener una actividadmessage
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);
}
});