Azure机器人程序框架(Node.js)-瀑布不';不能使用网络聊天在对话中工作

Azure机器人程序框架(Node.js)-瀑布不';不能使用网络聊天在对话中工作,node.js,botframework,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.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框架模拟器,它运行良好。

但是,使用Web聊天(Azure控制台)并没有达到瀑布式步骤中的第二个功能。

Bot框架仿真器和Web聊天的行为有什么不同

我应该在代码中修改什么

你知道吗

  • Node.js版本:8.10.0
  • Bot框架仿真器版本:4.0.15-alpha

我知道,您想要做的是让机器人启动对话,而不是等待用户说些什么,这是一个非常常见的目标。不幸的是,对于内置功能来说,这并不是一项简单的任务,但幸运的是,有一个解决方案。这篇博文摘自a中发布的一个变通方法,该方法链接到了“韩飞链接”中的一个

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

一般来说,您应该预期不同渠道之间会有许多差异,特别是当涉及到渠道产生的事件的性质时
conversationUpdate
是一个特别有争议的事件,众所周知,它在Bot Emulator中的行为与其他通道不同。从博客帖子(我的重点):

如果您使用的是WebChat或directline,则bot的对话更新是 在创建对话和用户双方的对话时发送 ConversationUpdate在他们第一次发送消息时发送。什么时候 ConversationUpdate最初已发送,没有足够的信息 在消息中创建对话框堆栈。这是为什么? 在仿真器中似乎可以工作,是仿真器模拟排序 伪DirectLine的,但两个ConversationUpdate都在 在emulator中同时执行,并且实际的 服务执行。

如果您希望避免编写客户端代码,并且您确信您的bot只会在支持
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']);
    }
});

请注意,这种概念证明远远不够可靠。由于在一个真正的机器人程序中,根对话框可能会从许多不同的地方访问,因此您可能需要在其中设置一个条件,以确保它只响应一次介绍提示,并且您可能还需要生成其他对话框。

我可以复制相同的问题,并且在:“ConversationUpdate没有发送足够的信息来构造数据包,因此对话框状态没有持久化。”,这可能会导致问题。你们两个使用的是BotBuilder SDK v3还是v4?另外,由根对话框而不是ConversationUpdate生成此功能是否可以接受?