Azure Bot Framework(Node.js)-使用Web聊天对话框中的瀑布不起作用

时间:2018-08-15 10:00:30

标签: node.js botframework

我有此代码:

bot.on('conversationUpdate', (message) => {
  if (message.membersAdded) {
    message.membersAdded.forEach((identity) => {
      if (identity.id === message.address.bot.id) {
        bot.beginDialog(message.address, 'start');
      }
    });
  }
});
  bot.dialog('start', [
  (session) => {
    var msg = new builder.Message(session);
    msg.attachments([
      new builder.HeroCard(session)
      .title('test')
      .buttons([{ title: 'testButton', type: 'imBack', value: 'testButton' }])
      ]);
      builder.Prompts.choice(session, msg, ['testButton']);
  },
  (session, results) => {
    session.send('Reached 2nd function!');
    console.dir(results);
    var message = results.response.entity;
    session.beginDialog('anotherDialog', message);
  }
]);

使用Bot Framework Emulator可以正常工作。 Bot Framework Emulator Result

但是,使用Web聊天(Azure Console)在瀑布步骤中无法达到第二功能。 Test in Web Chat Result

Bot Framework仿真器和Web聊天的行为有什么区别?

我应该在代码中进行哪些修改?

你有什么主意吗?

  • Node.js版本:8.10.0
  • Bot Framework模拟器版本:4.0.15-alpha

1 个答案:

答案 0 :(得分:0)

我了解您想要做的是让机器人开始对话,而不是等待用户说些什么,这是一个非常普遍的目标。不幸的是,使用内置功能并不是一件容易的事,但幸运的是有一个blog post explaining how to do it。该博客文章摘自GitHub issue中发布的一种变通方法,该变通方法与一个Fei Han链接在一起。

要点是conversationUpdate事件没有包含足够的信息以允许漫游器状态,因此对话框和提示等不应从事件处理程序中产生。您可以通过在客户端代码中生成自己的事件来解决此问题。当然,在Azure门户中进行测试时,这可能对您没有帮助。

通常,您应该期望不同渠道之间存在许多差异,尤其是涉及渠道所产生事件的性质时。 conversationUpdate是一个特别有争议的事件,并且在Bot Emulator中其行为与其他渠道不同。从博客文章(重点是我的):

  

如果您使用的是WebChat或Directline,则该机器人的ConversationUpdate为   在创建会话和用户双方的“   他们首次发送消息时即发送ConversationUpdate。什么时候   最初发送的是ConversationUpdate,信息不足   在消息中构造对话框堆栈。之所以这样   似乎在模拟器中工作,是模拟器模拟了某种排序   伪DirectLine,但两个sessionUpdates都在   在模拟器中同时运行,实际情况并非如此   服务执行。

如果您想避免编写客户端代码,并且确定只在支持conversationUpdate事件的渠道中使用您的漫游器,那么我可能还有另一种解决方法。即使该博客文章明确指出您不应该使用conversationUpdate,但在您只需要发送一条消息的情况下,仍然可以接受。您可以通过在事件处理程序中发送一条消息,然后像在根对话框中跟踪该消息一样来模拟提示。这是概念证明:

bot.on('conversationUpdate', (message) => {
    if (message.membersAdded) {
        message.membersAdded.forEach((identity) => {
            if (identity.id === message.address.bot.id) {
                var msg = new builder.Message()
                    .address(message.address)
                    .attachments([
                        new builder.HeroCard()
                            .title('test')
                            .buttons([{ title: 'testButton', type: 'imBack', value: 'testButton' }])
                    ]);

                bot.send(msg);
            }
        });
    }
});

bot.dialog('/', function (session) {
    if (session.message.text == "testButton") {
        session.send('Reached 2nd function!');
        session.beginDialog('/getStarted');
    } else {
        builder.Prompts.choice(session, "I didn’t understand. Please choose an option from the list.", ['testButton']);
    }
});

请注意,这种概念证明远非可靠。由于可能从真实的bot的许多不同位置访问根对话框,因此您可能希望在其中放置一个条件,以确保它只响应一次Intro提示,并且还可能希望生成其他对话框。