BotBuilder 女士:firstRun 对话框可防止基于 LUIS 意图触发其他对话框

Ms BotBuilder : firstRun dialog prevents triggering of other dialogs based on LUIS intents

我在机器人中定义了一个 firstRun 对话框,如下所示:

// First run dialog
    bot.dialog('firstRun', [
        function (session, next) {
            session.userData.token = _.get(session, 'message.user.token', null) ||  _.get(session, 'userData.token', null) 

        }
    ]).triggerAction({
        onFindAction: function (context, callback) {           
            var score = 0;
            if (session.userData.token doesn't exist or new token recieved in `session.user.message.token`){
                score = 1.1;
            }
            callback(null, score); 
        }
    });

并且有一个 LUIS 模型与一个根据意图触发的对话框集成在一起,比方说 Help :

bot.dialog('help', [
        (session, args) => {

            let entities = _.get(args, 'intent.entities', null);

            let topic = _.get(builder.EntityRecognizer.findEntity(entities, 'topic'), 'entity', null) || _.get(args, 'option', null);


            session.replaceDialog(topic);
        }
    ])
    .triggerAction({
        matches: 'Help'
    });

onFindAction 触发每条消息。当未设置 session.userData.token 时,它仅在第一条消息上触发 firstRun

问题是,如果第一条消息与 Help 意图匹配,它不会被触发。它从第二次开始工作,当 firstRun 没有被触发时。

如何确保任何匹配的意图触发相应的对话框,而不考虑 firstRun

如果有不同的方法可以实现同样的事情,请提出建议。

加法 我想要完成的是这个 - 我有一个 Web 服务身份验证令牌,我想保留在 session.userData.token 中,每小时刷新一次。所以现在我在每个话语上触发 onFindAction,检查 session.userData.token 是否不存在(这意味着它是第一个话语)或者是否已发送新令牌。在这两种情况下,我都会触发 firstRun 来更新 session.userData.token 并继续触发与话语的 LUIS 意图匹配的任何对话。但是每当 firstRun 被触发时,其他对话框中的 none 也会被触发。我想最好有一个更简单的机制来做到这一点。

谢谢

听起来您正试图拥有一个 直通 意图处理程序,该处理程序会在消息路由到 actual 处理程序。 Middleware would be the best place to handle your token refresh logic, but working with session in your middleware isn't easy. This blog post of mine explains why - http://www.pveller.com/smarter-conversations-part-4-transcript/.

你最好的选择是 routing 事件,我相信。它通过 events 同步,您将获得 session 对象。在消息到达正确的意图处理程序目的地之前,您应该能够根据需要验证和刷新 token

bot.on('routing', function (session) {
    if (!session.userData.token) {
        // receive new token 
    }
});

不过,与中间件不同的是,您不会获得 next 回调来继续链,因此您必须确保同步获取令牌。我之前提到的博客 post 也解释了这部分。