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

时间:2018-03-20 16:17:49

标签: botframework azure-bot-service

我正在使用bot框架来显示英雄卡。

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

我正在使用以下代码显示卡片。但是如何发送ID并在选择卡片时取回。变量元素有一个名为ID的字段我想将它链接到卡上,所以当按钮"选择"单击我想在后端捕获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

1 个答案:

答案 0 :(得分:0)

您可以利用函数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)
    }
  ])