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 也解释了这部分。
我在机器人中定义了一个 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 也解释了这部分。