【问题标题】:Set next step for the waterfall dialogue in Microsoft BotBuilder NodeJS SDK在 Microsoft BotBuilder NodeJS SDK 中设置瀑布对话的下一步
【发布时间】:2018-02-02 20:55:16
【问题描述】:

我正在为我的 facebook messenger 机器人使用 Microsoft Bot Framework。我想从 json 文件中加载对话数据,而不是在 js 文件中进行硬编码。我想根据“当前”步骤的结果配置对话框中的下一步,这是 json 文件配置的一部分,类似于这样。

{
    "name": "welcome",
    "type": "waterfall",
    "steps": [
        {
            "id": 0,
            "data": [
                {
                    "type": "text",
                    "value": "Hey, It's nice to meet you."
                },
                {
                    "type": "quickReplies",
                    "value": "What do you want to do next?",
                    "options": [
                        {
                            "text": "some option 1",
                            "value": "option1"
                        },
                        {
                            "text": "some option 2",
                            "value": "option2"
                        }
                    ]
                }
            ],
            "next": [
                {
                    "result": "option1",
                    "action": "goto step 2"
                },
                {
                    "result": "option2",
                    "action": "goto step 5"
                }
            ]
        }
    ]
}

我想处理所有传入的消息,并在对话框中为用户提供正确的对话框或正确的步骤。

我正在尝试这样的事情;

handleMessage = function (session) {
    var step = session.dialogData["BotBuilder.Data.WaterfallStep"] || 0;
    // check response data from previou step and identify the next step.
    // set the waterfall step id
    session.dialogData["BotBuilder.Data.WaterfallStep"] = 2;
    session.send("Hello");
}

var bot = new builder.UniversalBot(connector, function (session) {
    handleMessage(session);
})
.set('storage',tableStorage);

使用此代码,即使将其设置为不同的数字,我也总是将 session.dialogData["BotBuilder.Data.WaterfallStep"] 的步长设为零。

此外,一旦我设置了瀑布步数,存储在我的表存储中用于此对话的所有其他状态数据都将消失。

在设置瀑布步骤之前存储数据:

{
  "BotBuilder.Data.SessionState": {
    "callstack": [
      {
        "id": "*:/",
        "state": {
          "BotBuilder.Data.WaterfallStep": 0
        }
      },
      {
        "id": "*:welcome",
        "state": {
          "BotBuilder.Data.WaterfallStep": 1
        }
      },
      {
        "id": "BotBuilder:prompt-text",
        "state": {
          "options": {
            "prompt": {
              "type": "message",
              "agent": "botbuilder",
              "source": "facebook",
              "address": {
                "id": "mid.$cAAAlr-0LRH9niO21L1hV6hs83GuJ",
                "channelId": "facebook",
                "user": {
                  "id": "XXXX",
                  "name": "XXXX"
                },
                "conversation": {
                  "isGroup": false,
                  "id": "XX"
                },
                "bot": {
                  "id": "XXX",
                  "name": "XXX"
                },
                "serviceUrl": "https://facebook.botframework.com"
              },
              "text": "what do you want to next"
              //ignored for simplicity
            },
            "promptAfterAction": true,
            "libraryNamespace": "*"
          },
          "turns": 0,
          "lastTurn": 1517594116372,
          "isReprompt": false
        }
      }
    ],
    "lastAccess": 1517594112740,
    "version": 0
  }
}

设置瀑布步后:

{
  "BotBuilder.Data.SessionState": {
    "callstack": [
      {
        "id": "*:/",
        "state": {
          "BotBuilder.Data.WaterfallStep": 2
        }
      }
    ],
    "lastAccess": 1517602122416,
    "version": 0
  }
}

有趣的是,步骤号被保存到数据库中(但处于会话状态),但我的“会话”变量在任何地方都没有这个值。另外,即使在配置了自定义状态服务之后,serviceUrl 仍然是https://facebook.botframework.com,如果没有为机器人设置状态服务,我认为这是使用的默认状态服务。

【问题讨论】:

  • 你是说你想根据你得到的 json 创建瀑布对话框。或者您只是想知道如何构建瀑布对话框并同时管理流程?

标签: json node.js botframework


【解决方案1】:

根据您的代码,因为您的机器人实际上只包含一个瀑布步骤:handleMessage(session);,这引发了您的问题。您可以考虑从 json 配置创建多个对话框,而不是复杂的瀑布步骤。

这是我的快速测试,供您参考:

const json = `
[{
    "name": "welcome",
    "type": "waterfall",
    "steps": [
        {
            "id": 0,
            "data": [
                {
                    "type": "text",
                    "value": "Hey, It's nice to meet you."
                },
                {
                    "type": "quickReplies",
                    "value": "What do you want to do next?",
                    "options": [
                        {
                            "text": "some option 1",
                            "value": "option1"
                        },
                        {
                            "text": "some option 2",
                            "value": "option2"
                        }
                    ]
                }
            ],
            "next": [
                {
                    "result": "option1",
                    "action": "dialog2"
                },
                {
                    "result": "option2",
                    "action": "dialog3"
                }
            ]
        }
    ]
},{
    "name":"dialog2",
    "type": "waterfall",
    "steps": [
        {
            "data": [
                {
                    "type": "text",
                    "value": "Hey, this is dialig2."
                }]
        }
    ]
},{
    "name":"dialog3",
    "type": "waterfall",
    "steps": [
        {
            "data": [
                {
                    "type": "text",
                    "value": "Hey, this is dialig3."
                }]
        }
    ]
}]
`;

const generateSignleStep = (step) => {
    return (session, args, next) => {
        step.forEach(sentence => {
            switch (sentence.type) {
                case 'quickReplies':
                    let choices = sentence.options.map(item => {
                        return item.value
                    });
                    let card = new builder.ThumbnailCard(session)
                        .text(sentence.value)
                        .buttons(sentence.options.map(choice => new builder.CardAction.imBack(session, choice.value, choice.text)))
                    let message = new builder.Message(session).addAttachment(card);
                    builder.Prompts.choice(session, message, choices);
                    break;
                case 'text':
                default:
                    session.send(sentence.value)
                    break;
            }
        })
    }
}

const generatenextAction = (actions) => {
    return (session, args, next) => {
        const response = args.response;
        actions.map(action => {
            if (action.result == response.entity) {
                session.beginDialog(action.action);
            }
        })
    }
}
const generateWaterfallSteps = (steps) => {
    let waterfall = [];
    steps.forEach(step => {
        waterfall.push(generateSignleStep(step.data));
        if (step.next) {
            waterfall.push(generatenextAction(step.next));
        }
    });
    return waterfall;
}
var bot = new builder.UniversalBot(connector);
const jsonobj = JSON.parse(json);
jsonobj.forEach(dialog => {
    bot.dialog(dialog.name, generateWaterfallSteps(dialog.steps))
        .triggerAction({
            matches: new RegExp(dialog.name, "g")
        })
});

结果是:

【讨论】:

    猜你喜欢
    • 2017-07-18
    • 1970-01-01
    • 1970-01-01
    • 2014-10-09
    • 2020-02-26
    • 1970-01-01
    • 1970-01-01
    • 2018-12-17
    • 2019-08-23
    相关资源
    最近更新 更多