如何将值传递给bot框架的英雄卡而不显示在UI中?

How to pass value to hero card of bot framework and not show in UI?

我正在使用机器人框架来显示英雄卡片。

场景:我想将 UI 中的任务列表显示为英雄卡片。每个任务都有一个 ID link编辑到 it.I 不希望任务 ID 显示在卡片中。当用户选择卡片时,我想在后端获取 linked 任务的 ID 并存储在内存中,以便我通过根据 ID 进行一些 api 调用来执行下一个活动。

我正在使用下面的方法显示卡片 code.But 如何发送 ID 并在选择卡片时取回 ID。可变元素有一个名为 ID 的字段,我想 link 它到卡片,所以当单击按钮 "select" 时,我想在后端捕获 ID。

var card = new builder.HeroCard(session)
                        .title(element.name)
                        .subtitle(element.startTime)
                        .text(shortdesc)
                        .images([builder.CardImage.create(session, 'https://www.newstatesman.com/sites/all/themes/creative-responsive-theme/images/new_statesman_events.jpg')])
                        .buttons([
                            builder.CardAction.imBack(session, element.name, "Select")
                        ]);

完整代码:

var restify = require('restify');
var builder = require('botbuilder');
const Request = require("request");
global.res = []
    // Setup Restify Server
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function() {
    console.log('%s listening to %s', server.name, server.url);
});

// Create chat connector for communicating with the Bot Framework Service
var connector = new builder.ChatConnector({
    appId: process.env.MicrosoftAppId,
    appPassword: process.env.MicrosoftAppPassword
});

// Listen for messages from users 
server.post('/api/messages', connector.listen());

var inMemoryStorage = new builder.MemoryBotStorage();

// This is a  bot that uses a waterfall technique to prompt users for input.
var bot = new builder.UniversalBot(connector, [
    function(session) {
        session.send("Hi , I can help you about about hotels and updates.");
        builder.Prompts.text(session, "Can i know your name to get started ?");
    },
    function(session, results) {
        session.dialogData.username = results.response;
        var msg = 'Thanks ' + session.dialogData.username + ' For which area do you want me to check?'
        builder.Prompts.text(session, msg);
    },
    function(session, results) {
        session.dialogData.eventname = results.response;
        let cards = [];
        var uri = 'https://dummy/api/hotels/search/name/' + session.dialogData.hotelname
            //I need to call my api to get the hotels based on the typed value and set it to the hero card?

        Request.get(uri, (error, response, body) => {
            if (error) {
                return console.dir(error);
            }
            global.res = JSON.parse(body);
            if (global.res.length != 0) {
                name = global.res[0].name;
                console.log(name);


                //formulate the hotel details
                var msg = new builder.Message(session);
                msg.attachmentLayout(builder.AttachmentLayout.carousel)
                    //loop throught the result set and append to the msg attachment
                global.res.forEach(function(element, index) {

                    console.log(element.name + " " + element.startTime);
                    var shortdesc = element.description.substring(0, 50);
                    shortdesc = shortdesc + '...'
                    var card = new builder.HeroCard(session)
                        .title(element.name)
                        .subtitle(element.startTime)
                        .text(shortdesc)
                        .images([builder.CardImage.create(session, 'https://www.newstatesman.com/sites/all/themes/creative-responsive-theme/images/new_statesman_events.jpg')])
                        .buttons([
                            builder.CardAction.imBack(session, element.name, "Select")
                            //want to collect the element.id but not show in UI.
                        ]);
                    cards.push(card);
                    msg.attachments(cards)
                });
                //builder.Prompts.choice(session, msg, global.res);
                builder.Prompts.text(session, "Please select from the following hotels");
                session.send(msg)
            } else {


            }
        });
    },
    function(session, results) {
        session.dialogData.selectedevent = results.response;
        var text = 'What details do you want to know for the ' + session.dialogData.selectedevent + ' hotel'
        var msg = new builder.Message(session)
            .text('text')
            .suggestedActions(
                builder.SuggestedActions.create(
                    session, [
                        builder.CardAction.imBack(session, "Parking", "Parking"),
                        builder.CardAction.imBack(session, "activities", "Activities")

                    ]
                ));
        builder.Prompts.text(session, text);
        session.send(msg);

    },

    function(session, results) {
        session.dialogData.selectedcondition = results.response;

        if (session.dialogData.selectedcondition == 'Parking') {
            //when parking i will pass the hotel id (element.id) to another api return them as cards
            var msg = 'Parking is full for hotel ' + session.dialogData.selectedevent
            session.send(msg);
            session.endDialog();
        } else {
            var msg = 'Heavy traffic for hotel ' + session.dialogData.selectedevent
            session.send(msg);
            session.endDialog();
        }




    }

]).set('storage', inMemoryStorage); // Register in-memory storage

您可以利用函数 builder.CardAction.imBack(session: Session, msg: string, title?: TextType) 的第二个参数,它可以设置要发送给机器人的字符串值。

请检查问题 https://github.com/Microsoft/BotBuilder/issues/2715 中的代码:

bot.dialog('example', [
    (session, args, next) => {
      const choices = ['1','2','3']

      const cards = choices.map(item => {
        // return new builder.ThumbnailCard(session) // You can use thumbnails
        return new builder.HeroCard(session)
          .buttons([builder.CardAction.imBack(session, item, item)])
          .images([builder.CardImage.create(
            session, `http://via.placeholder.com/300x150?text=${item}`
          )])
      })

      const msg = new builder.Message(session)
        // .attachmentLayout(builder.AttachmentLayout.carousel) // This works
        .attachments(cards)
        .text('Choose a card')

      builder.Prompts.choice(session, msg, choices, {
        retryPrompt: msg
      })
    }, (session, args, next) => {
      session.send(args.response.entity)
      session.endDialogWithResult(args)
    }
  ])