我刚刚得到一个项目,在该项目中我需要学习和处理Microsoft Bot Framework 3.2版(这是我正在修改的旧项目)。
我正在研究示例,并试图了解对话框流程的工作方式以及如何最好地对其进行模块化。
据我了解,当您像这样创建机器人时
// CODE SAMPLE 1
const bot = new builder.UniversalBot(connector, [
function (session) {
session.send("Welcome to the dinner reservation.");
session.beginDialog('askForDateTime');
},
/*
functions omitted for brevity
*/
]).set('storage', inMemoryStorage); // Register in-memory storage
创建bot时必须给出构成“默认对话框”的功能数组-也就是说,您不能在以后添加或更改默认对话框。正确吗?
然后,如果以后要对对话框结构进行模块化,则可以有类似的内容(请参见上面的代码)
// CODE SAMPLE 2 (in same file as code above)
bot.dialog('askForDateTime', [
function (session) {
builder.Prompts.time(session, "Please provide a reservation date and time (e.g.: June 6th at 5pm)");
},
function (session, results) {
session.endDialogWithResult(results);
}
]);
那么,bot.dialog
是否正在向机器人注册此对话框以供以后使用?也就是说,在运行时(在对话过程中)会进行某种形式的查找,该字符串基于将第一个代码示例中的session.beginDialog('askForDateTime');
与在{第二个代码示例?
当我查看SDK参考时,我发现bot.dialog('askForDateTime')
接受beginDialog
IAddress
上面写着
事件的地址路由信息。地址是双向的 意味着它们可用于处理传入和传出事件。 它们也是特定于连接器的,这意味着连接器可以自由 在地址中添加自己的字段。
因此,通过字符串进行的“注册”基本上是一种事件注册系统,类似于function beginDialog(address: IAddress, dialogId: string, dialogArgs?: any, done?: (err: Error) => void)
,但在这种情况下,它不是在注册动作本身,而是在对话框?
最后两个问题:
一个人可以从addEventListener
内部呼叫session.beginDialog
吗?也就是说,是否有嵌套的对话框树?就这样,唯一的例子是从默认对话框嵌套,但是我不知道它是否可以更深入。
最后,如何将对话框模块化到单独的节点模块中,即将子对话框移动到单独的文件中?我想到了这样的东西:
bot.dialog
但看不到如何在我的主应用程序中使用
// askForDateTime.js
module.exports = bot =>
bot.dialog('askForDateTime', [
function (session) {
builder.Prompts.time(session, "Please provide a reservation date and time (e.g.: June 6th at 5pm)");
},
function (session, results) {
session.endDialogWithResult(results);
}
]);
感谢您的帮助!我意识到使用版本4可能会更容易,但是我需要使用更早的版本。
答案 0 :(得分:1)
首先,请注意,Botbuilder V3即将终止,支持将在2019年底结束。您可以详细了解此主题here以及从v3迁移到v4的选项here
关于默认对话框,另一种方法是仅将连接器传递到适配器中,然后在发生conversationUpdate
时启动对话框。使用conversationUpdate
时可能会遇到一些挑战,因此在继续之前,我将仔细阅读this博客文章。
var bot = new builder.UniversalBot(connector)
bot.on('conversationUpdate', function (message) {
if (message.membersAdded) {
message.membersAdded.forEach(function (identity) {
if (identity.id === message.address.bot.id) {
bot.beginDialog(message.address, '/main');
}
});
}
});
// ----greetings.js -----
bot.dialog('/main', [
function (session, args, next) {
session.send("Glad you could join.");
session.beginDialog('/nextDialog');
}
]);
关于beginDialog()
注册/寻址,没有发生任何预注册。调用对话框时,它实际上就像其他函数一样被调用。该地址或多或少用于管理对话框状态(即机器人在对话中的位置)-是将对话框添加到堆栈中,正在使用中还是从对话框中弹出。
关于在另一个对话框中调用一个对话框,是的,这是可行的,如this示例中所示:
lib.dialog('/', [
[...other functions...]
function (session, args) {
session.dialogData.recipientPhoneNumber = args.response;
session.beginDialog('validators:notes', {
prompt: session.gettext('ask_note'),
retryPrompt: session.gettext('invalid_note')
});
},
[...other functions...]
]);
最后,关于模块化,是的,这也是可行的。查看这两个样本中的任何一个。 core-MultiDialogs不太复杂,但是demo-ContosoFlowers也是一个很好的例子。
希望有帮助!