MS Bot Framework (Nodejs):会话生命周期和延迟消息

MS Bot Framework (Nodejs): Session lifetime and delayed messages

这是我第一次尝试使用 Bot Framework (Nodejs)。我想测试延迟消息,例如,我的机器人必须在收到消息后 5 秒后回答。 所以我尝试了这段代码:

var builder = require('botbuilder');

var connector = new builder.consoleconnector().listen();
var bot = new builder.universalbot(connector);

bot.dialog('/', function (session) {
    if (!session.userData.TimeoutStarted) {
        session.send("I'll answer in 5 seconds");
        session.userData.TimeoutStarted = true;

        setTimeout(function() {
            session.send("Answer after 5 seconds");
            session.userData.TimeoutStarted = false;
        }, 5000);
    } else {
        session.send("Bot is busy");
    }
});

但这行不通。 setTimeout 中的回调函数触发,但所有与会话的操作根本不起作用。

所以,我在这里找到了可能的解决方案: 并重写了我的代码:

var builder = require('botbuilder');

var connector = new builder.ConsoleConnector().listen();
var bot = new builder.UniversalBot(connector);

bot.dialog('/', function (session) {
    if (session.userData.Timeout > 0 && Date.now() - session.userData.Timeout > 5000)
        session.userData.Timeout = 0;

    if (!session.userData.Timeout) {
        session.send("I'll answer in 5 seconds");

        var reply = session.message;

        setTimeout(function() {
           reply.text = "Answer after 5 seconds";
           bot.send(reply);
        }, 5000);

        session.userData.Timeout = Date.now();
    } else {
        session.send("Bot is busy");
    }
});

此代码有效,但经过这么多检查后看起来很糟糕。所以我有几个问题:

  1. 为什么第一个代码示例不起作用?我猜是会话生命周期中的问题然后什么是会话生命周期?
  2. 本例中如何设置session.userData?所以在第一个代码示例中,我想在 setTimeout 的回调函数中设置它,但它也不起作用。
  3. 创建延迟答案的最佳方法是什么?

我刚刚调查了这个问题。 ConsoleConnector 中似乎存在一个错误,导致无法使用相同的 session 对象发送两条消息(由于内部批处理,消息之间的给定间隔以上)。由于状态也在 send 期间持续存在,您的延迟状态更新也将不起作用。如果您将对 session.save 的调用添加到 setTimeout 中的回调,它将保持新状态(但仍不会发送消息)。

我相信您的第一个示例应该与 ChatConnector 一起使用(尽管还没有机会尝试)。我将创建一个包含 ConsoleConnector.

修复的拉取请求

我希望这能回答你所有的问题。

更新

有关更多详细信息,请参阅 this issue 和相关的拉取请求。

更新2

它适用于 ChatConnector,使用此代码:

var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function () {
console.log('%s listening to %s', server.name, server.url); 
});

var connector = new builder.ChatConnector({
    appId: '',
    appPassword: ''
});

var bot = new builder.UniversalBot(connector);

server.post('/api/messages', connector.listen());


bot.dialog('/', function (session) {
    if (!session.userData.TimeoutStarted) {
        session.send("I'll answer in 5 seconds");
        session.userData.TimeoutStarted = true;

        setTimeout(function() {
            session.send("Answer after 5 seconds");
            session.userData.TimeoutStarted = false;
        }, 5000);
    } else {
        session.send("Bot is busy");
    }
});

对于有兴趣从机器人发送延迟消息的人,您可以使用 session.delay(<ms>)

例如,

session.send('msg')
session.delay(5000) // delay 5 seconds 
session.endDialog()