Incorporación de datos adjuntos de tarjetas enriquecidas a mensajesAdd rich card attachments to messages

Nota

Este tema se aplica a la versión SDK v3.This topic applies to SDK v3 release. Puede encontrar la documentación sobre la versión más reciente de SDK v4 aquí.You can find the documentation for the latest version of the SDK v4 here.

Varios canales, como Facebook, admiten el envío de tarjetas gráficas enriquecidas a los usuarios con botones interactivos en los cuales el usuario hace clic para iniciar una acción.Several channels, like Facebook, support sending rich graphical cards to users with interactive buttons that the user clicks to initiate an action. El SDK proporciona varias clases de generadores de tarjetas y mensajes que se pueden usar para crear y enviar tarjetas.The SDK provides several message and card builder classes which can be used to create and send cards. El servicio Bot Framework Connector representará estas tarjetas con un esquema nativo para el canal, compatible con la comunicación multiplataforma.The Bot Framework Connector Service will render these cards using schema native to the channel, supporting cross-platform communication. Si el canal no es compatible con las tarjetas, como SMS, Bot Framework hará todo lo posible para representar una experiencia razonable a los usuarios.If the channel does not support cards, such as SMS, the Bot Framework will do its best to render a reasonable experience to users.

Tipos de tarjetas enriquecidasTypes of rich cards

Bot Framework admite actualmente ocho tipos de tarjetas enriquecidas:The Bot Framework currently supports eight types of rich cards:

Tipo de tarjetaCard type DescripciónDescription
Tarjeta adaptableAdaptive Card Una tarjeta personalizable que puede contener cualquier combinación de texto, voz, imágenes, botones y campos de entrada.A customizable card that can contain any combination of text, speech, images, buttons, and input fields. Consulte la compatibilidad por canal.See per-channel support.
Tarjeta de animaciónAnimation Card Una tarjeta que puede reproducir archivos GIF animados o vídeos cortos.A card that can play animated GIFs or short videos.
Tarjeta de audioAudio Card Una tarjeta que se puede reproducir un archivo de audio.A card that can play an audio file.
Tarjeta de héroeHero Card Una tarjeta que normalmente contiene una sola imagen grande, uno o varios botones y texto.A card that typically contains a single large image, one or more buttons, and text.
Tarjeta de miniaturaThumbnail Card Una tarjeta que normalmente contiene una sola imagen miniatura, uno o varios botones, y texto.A card that typically contains a single thumbnail image, one or more buttons, and text.
Tarjeta de recepciónReceipt Card Una tarjeta que permite que un bot proporcione un recibo al usuario.A card that enables a bot to provide a receipt to the user. Normalmente, contiene la lista de elementos que se incluyen en el recibo, la información de impuestos y del total, y texto adicional.It typically contains the list of items to include on the receipt, tax and total information, and other text.
Tarjeta de inicio de sesiónSignin Card Una tarjeta que permite al bot solicitar que un usuario inicie sesión.A card that enables a bot to request that a user sign-in. Normalmente contiene texto y uno o varios botones en los que el usuario puede hacer clic para iniciar el proceso de inicio de sesión.It typically contains text and one or more buttons that the user can click to initiate the sign-in process.
Tarjeta de videollamadaVideo Card Una tarjeta que puede reproducir vídeos.A card that can play videos.

En el ejemplo siguiente se muestra un bot para una compañía ficticia de camisetas y cómo enviar un carrusel de tarjetas en respuesta a la solicitud del usuario para "mostrar camisetas".The following example shows a bot for a fictional t-shirt company and shows how to send a carousel of cards in response to the user saying "show shirts".

// Create your bot with a function to receive messages from the user
// Create bot and default message handler
var bot = new builder.UniversalBot(connector, function (session) {
    session.send("Hi... We sell shirts. Say 'show shirts' to see our products.");
});

// Add dialog to return list of shirts available
bot.dialog('showShirts', function (session) {
    var msg = new builder.Message(session);
    msg.attachmentLayout(builder.AttachmentLayout.carousel)
    msg.attachments([
        new builder.HeroCard(session)
            .title("Classic White T-Shirt")
            .subtitle("100% Soft and Luxurious Cotton")
            .text("Price is $25 and carried in sizes (S, M, L, and XL)")
            .images([builder.CardImage.create(session, 'http://petersapparel.parseapp.com/img/whiteshirt.png')])
            .buttons([
                builder.CardAction.imBack(session, "buy classic white t-shirt", "Buy")
            ]),
        new builder.HeroCard(session)
            .title("Classic Gray T-Shirt")
            .subtitle("100% Soft and Luxurious Cotton")
            .text("Price is $25 and carried in sizes (S, M, L, and XL)")
            .images([builder.CardImage.create(session, 'http://petersapparel.parseapp.com/img/grayshirt.png')])
            .buttons([
                builder.CardAction.imBack(session, "buy classic gray t-shirt", "Buy")
            ])
    ]);
    session.send(msg).endDialog();
}).triggerAction({ matches: /^(show|list)/i });

En este ejemplo se usa la clase Message para compilar un carrusel.This example uses the Message class to build a carousel.
El carrusel está formado por una lista de clases HeroCard que contienen una imagen, texto y un solo botón que desencadena la compra del elemento.The carousel is comprised of a list of HeroCard classes that contain an image, text, and a single button that triggers buying the item.
Al hacer clic en el botón Comprar, se desencadena el envío de un mensaje, por lo que se debe agregar un segundo diálogo para detectar el clic del botón.Clicking the Buy button triggers sending a message so we need to add a second dialog to catch the button click.

Controlar la entrada del botónHandle button input

El diálogo buyButtonClick se desencadenará cada vez que se reciba un mensaje que comience por "comprar" o "agregar" y, después, contenga algún texto que incluya la palabra "camiseta".The buyButtonClick dialog will be triggered any time a message is received that starts with "buy" or "add" and is followed by something containing the word "shirt". El diálogo se inicia mediante el uso de un par de expresiones regulares para buscar la camisa de tamaño opcional y el color que haya pedido el usuario.The dialog starts by using a couple of regular expressions to look for the color and optional size shirt that the user asked for. Esta flexibilidad añadida le permite admitir los clics de botón y los mensajes de lenguaje natural del usuario, como "agrega una camisa gris de tamaño grande a mi carro de la compra".This added flexibility lets you support both button clicks and natural language messages from the user like "please add a large gray shirt to my cart". Si el color es válido, pero se desconoce el tamaño, el bot pide al usuario que elija un tamaño de una lista antes de agregar el artículo al carro de la compra.If the color is valid but the size is unknown, the bot prompts the user to pick a size from a list before adding the item to the cart. Una vez que el bot tiene toda la información que necesita, coloca el artículo en un carro de la compra que se ha conservado con session.userData y, a continuación, envía al usuario un mensaje de confirmación.Once the bot has all the information it needs, it puts the item onto a cart that’s persisted using session.userData and then sends the user a confirmation message.

// Add dialog to handle 'Buy' button click
bot.dialog('buyButtonClick', [
    function (session, args, next) {
        // Get color and optional size from users utterance
        var utterance = args.intent.matched[0];
        var color = /(white|gray)/i.exec(utterance);
        var size = /\b(Extra Large|Large|Medium|Small)\b/i.exec(utterance);
        if (color) {
            // Initialize cart item
            var item = session.dialogData.item = {
                product: "classic " + color[0].toLowerCase() + " t-shirt",
                size: size ? size[0].toLowerCase() : null,
                price: 25.0,
                qty: 1
            };
            if (!item.size) {
                // Prompt for size
                builder.Prompts.choice(session, "What size would you like?", "Small|Medium|Large|Extra Large");
            } else {
                //Skip to next waterfall step
                next();
            }
        } else {
            // Invalid product
            session.send("I'm sorry... That product wasn't found.").endDialog();
        }
    },
    function (session, results) {
        // Save size if prompted
        var item = session.dialogData.item;
        if (results.response) {
            item.size = results.response.entity.toLowerCase();
        }

        // Add to cart
        if (!session.userData.cart) {
            session.userData.cart = [];
        }
        session.userData.cart.push(item);

        // Send confirmation to users
        session.send("A '%(size)s %(product)s' has been added to your cart.", item).endDialog();
    }
]).triggerAction({ matches: /(buy|add)\s.*shirt/i });

Agregar un retraso de mensaje para descargas de imágenesAdd a message delay for image downloads

Algunos canales tienden a descargar imágenes antes de mostrar un mensaje al usuario, de modo que si envía un mensaje que contiene una imagen inmediatamente seguida de un mensaje sin imágenes, a veces verá los mensajes volteados en la fuente del usuario.Some channels tend to download images before displaying a message to the user so that if you send a message containing an image followed immediately by a message without images you’ll sometimes see the messages flipped in the user's feed. Para minimizar la posibilidad de que esto ocurra, puede intentar asegurarse de que sus imágenes procedan de redes de entrega de contenido (CDN) y evitar el uso de imágenes demasiado grandes.To minimize the chance of this you can try to insure that your images are coming from content deliver networks (CDNs) and avoid the use of overly large images. En casos extremos incluso es posible que necesite insertar un retraso de 1 a 2 segundos entre el mensaje con la imagen y el siguiente.In extreme cases you may even need to insert a 1-2 second delay between the message with the image and the one that follows it. Puede hacer que este retraso parezca un poco más natural para el usuario mediante una llamada a session.sendTyping() para enviar un indicador de escritura antes de iniciar el retraso.You can make this delay feel a bit more natural to the user by calling session.sendTyping() to send a typing indicator before starting your delay.

Bot Framework implementa un procesamiento por lotes para intentar evitar varios mensajes del bot que muestren que no está en funcionamiento.The Bot Framework implements a batching to try to prevent multiple messages from the bot from being displayed out of order. Cuando su bot envía varias respuestas al usuario, los mensajes individuales se agrupan automáticamente en un lote y se entregan al usuario como un conjunto en un esfuerzo por conservar el orden original de los mensajes.When your bot sends multiple replies to the user, the individual messages will be automatically grouped into a batch and delivered to the user as a set in an effort to preserve the original order of the messages. Este procesamiento por lotes automático espera un tiempo predeterminado de 250 ms después de cada llamada a session.send() antes de iniciar la siguiente llamada a send() .This automatic batching waits a default of 250ms after every call to session.send() before initiating the next call to send().

El retraso de procesamiento por lotes del mensaje se puede configurar.The message batching delay is configurable. Para deshabilitar la lógica del procesamiento por lotes automático del SDK, establezca el retraso predeterminado en un número grande y, a continuación, llame manualmente a sendBatch() con una devolución de llamada para realizar la invocación una vez que se haya entregado el lote.To disable the SDK’s auto-batching logic, set the default delay to a large number and then manually call sendBatch() with a callback to invoke after the batch is delivered.

Enviar una tarjeta adaptableSend an Adaptive card

Una tarjeta adaptable puede contener cualquier combinación de texto, voz, imágenes, botones y campos de entrada.The Adaptive Card can contain any combination of text, speech, images, buttons, and input fields. Las tarjetas adaptables se crean con el formato JSON especificado en Adaptive Cards (Tarjetas adaptables), que proporciona control total sobre el contenido y el formato de la tarjeta.Adaptive Cards are created using the JSON format specified in Adaptive Cards, which gives you full control over card content and format.

Para crear una tarjeta adaptable con Node.js, utilice la información del sitio Adaptive Cards (Tarjetas adaptables) a fin de comprender el esquema de la tarjeta adaptable, explorar los elementos de la tarjeta adaptable y ver ejemplos de JSON que puede usar para crear tarjetas de diferente composición y complejidad.To create an Adaptive Card using Node.js, leverage the information within the Adaptive Cards site to understand Adaptive Card schema, explore Adaptive Card elements, and see JSON samples that can be used to create cards of varying composition and complexity. Además, puede usar el visualizador interactivo para diseñar cargas útiles de la tarjeta adaptable y obtener una vista previa de la salida de la tarjeta.Additionally, you can use the Interactive Visualizer to design Adaptive Card payloads and preview card output.

En este ejemplo de código se muestra cómo crear un mensaje que contiene una tarjeta adaptable para un recordatorio del calendario:This code example shows how to create a message that contains an Adaptive Card for a calendar reminder:

var msg = new builder.Message(session)
    .addAttachment({
        contentType: "application/vnd.microsoft.card.adaptive",
        content: {
            type: "AdaptiveCard",
            speak: "<s>Your  meeting about \"Adaptive Card design session\"<break strength='weak'/> is starting at 12:30pm</s><s>Do you want to snooze <break strength='weak'/> or do you want to send a late notification to the attendees?</s>",
               body: [
                    {
                        "type": "TextBlock",
                        "text": "Adaptive Card design session",
                        "size": "large",
                        "weight": "bolder"
                    },
                    {
                        "type": "TextBlock",
                        "text": "Conf Room 112/3377 (10)"
                    },
                    {
                        "type": "TextBlock",
                        "text": "12:30 PM - 1:30 PM"
                    },
                    {
                        "type": "TextBlock",
                        "text": "Snooze for"
                    },
                    {
                        "type": "Input.ChoiceSet",
                        "id": "snooze",
                        "style":"compact",
                        "choices": [
                            {
                                "title": "5 minutes",
                                "value": "5",
                                "isSelected": true
                            },
                            {
                                "title": "15 minutes",
                                "value": "15"
                            },
                            {
                                "title": "30 minutes",
                                "value": "30"
                            }
                        ]
                    }
                ],
                "actions": [
                    {
                        "type": "Action.OpenUrl",
                        "method": "POST",
                        "url": "http://foo.com",
                        "title": "Snooze"
                    },
                    {
                        "type": "Action.OpenUrl",
                        "method": "POST",
                        "url": "http://foo.com",
                        "title": "I'll be late"
                    },
                    {
                        "type": "Action.OpenUrl",
                        "method": "POST",
                        "url": "http://foo.com",
                        "title": "Dismiss"
                    }
                ]
        }
    });
session.send(msg);

La tarjeta resultante contiene tres bloques de texto, un campo de entrada (lista de opciones) y tres botones:The resulting card contains three blocks of text, an input field (choice list), and three buttons:

Recordatorio del calendario de tarjeta adaptable

Recursos adicionalesAdditional resources