我在机器人中定义了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
触发每条消息。并且仅在未设置firstRun
时的第一条消息上触发session.userData.token
。
问题是,如果第一条消息与Help
意图匹配,则不会触发。它是第二次工作,当时firstRun
未被触发。
如何确保任何匹配的意图触发相应的对话框,而不管firstRun
?
如果有不同的方式来实现同样的目的,请建议。
加成
我想要完成的是 - 我有一个web服务身份验证令牌,我想保留在session.userData.token中,每小时刷新一次。所以现在我在每个话语上触发onFindAction
,检查session.userData.token
是否不存在(这意味着它是第一个话语)还是已经发送了新的令牌。在这两种情况下,我触发firstRun
更新session.userData.token
并继续触发任何与话语的LUIS意图相匹配的对话框。但是,只要触发firstRun
,就不会触发任何其他对话框。我想,有一个更简单的机制来实现这一点是理想的。
由于
答案 0 :(得分:2)
听起来您正在尝试使用传递意图处理程序,该处理程序会在邮件路由到实际处理程序之前触发。 Middleware是处理token
刷新逻辑的最佳位置,但在中间件中使用session
并不容易。我的这篇博文解释了为什么 - 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
回调来继续链,因此您必须确保同步获取令牌。我之前提到的博客文章也解释了这一部分。