Nodejs Bot学习
关于示例部分可以参考《BotFramework Nodejs示例》《BotBuilder Nodejs示例查看》
Bot Framework Nodejs SDK包括几种与用户或会话相关的数据持久化方法:
- 【userData】 用户级别--》包含为指定Channel上(多个Channel应该不共享数据)的用户保存的数据(其他用户不可见)。此数据将持续多个会话(如果使用模拟器,关闭对话之后还是可以查看到数据)。
- 【conversationData】 会话级别--》包含保存在指定Channel上特定会话的上下文中的数据。此数据与参与会话的所有用户共享,并将持续存在当前会话。会话结束或 endConversation 明确调用时,该属性将被清除。
- 【privateConversationData】 会话级别--》包含在指定Channel上的特定会话的上下文中为用户保存的数据。此数据对当前用户是私有的,并且将仅持续当前对话。会话结束或 endConversation 明确调用时,该属性将被清除。
- 【dialogData】 对话级别--》保留单个对话框实例的信息,对于瀑布的步骤之前存储临时信息非常重要

使用Bot Builder构建的Bot是无状态的,因此可以轻松扩展以跨多个计算节点运行,因为你应该避免使用全局变量或函数闭包保存状态,这样做会产生问题,当你想扩展你的机器人,相反,利用上面的数据包来保持临时和永久状态。
官方文档地址:https://docs.microsoft.com/en-us/bot-framework/nodejs/bot-builder-nodejs-state
数据的操作




会话中的对话框瀑布流

例如以下代码中与第二段代码效果是一致的,所以上图中的意思就是可以将对话框分开成不同的文件,方便管理
当然,这些dialog存放在同一个文件也是可以的,并不影响效果
dialog调用的效果即,第一个dialog以beginDialog()访问跳转至第二个dialog,第二个dialog就得到了主动权,与用户进行对话,
当第二个完成了,只需要以endDialog()或endDialogWithResult()方法返回于第一个dialog,此时主动权又回到了第一个dialog
// This is a dinner reservation bot that uses a waterfall technique to prompt users for input.
var bot = new builder.UniversalBot(connector, [
function (session) {
session.send("Welcome to the dinner reservation.");
builder.Prompts.time(session, "Please provide a reservation date and time (e.g.: June 6th at 5pm)");
},
function (session, results) {
session.dialogData.reservationDate = builder.EntityRecognizer.resolveTime([results.response]);
builder.Prompts.text(session, "How many people are in your party?");
},
function (session, results) {
session.dialogData.partySize = results.response;
builder.Prompts.text(session, "Whose name will this reservation be under?");
},
function (session, results) {
session.dialogData.reservationName = results.response; // Process request and display reservation details
session.send("Reservation confirmed. Reservation details: <br/>Date/Time: %s <br/>Party size: %s <br/>Reservation name: %s",
session.dialogData.reservationDate, session.dialogData.partySize, session.dialogData.reservationName);
session.endDialog();
}
]);
// This is a dinner reservation bot that uses multiple dialogs to prompt users for input.
var bot = new builder.UniversalBot(connector, [
function (session) {
session.send("Welcome to the dinner reservation.");
session.beginDialog('askForDateTime');//开始对话框
},
function (session, results) {
session.dialogData.reservationDate = builder.EntityRecognizer.resolveTime([results.response]);//保存输入结果至dialogData
session.beginDialog('askForPartySize');//开始对话框
},
function (session, results) {
session.dialogData.partySize = results.response;//保存输入结果至dialogData
session.beginDialog('askForReserverName');//开始对话框
},
function (session, results) {
session.dialogData.reservationName = results.response;//保存输入结果至dialogData // Process request and display reservation details
session.send("Reservation confirmed. Reservation details: <br/>Date/Time: %s <br/>Party size: %s <br/>Reservation name: %s",
session.dialogData.reservationDate, session.dialogData.partySize, session.dialogData.reservationName);
session.endDialog();//结束对话框
}
]); // Dialog to ask for a date and time
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);
}
]); // Dialog to ask for number of people in the party
bot.dialog('askForPartySize', [
function (session) {
builder.Prompts.text(session, "How many people are in your party?");
},
function (session, results) {
session.endDialogWithResult(results);
}
]) // Dialog to ask for the reservation name.
bot.dialog('askForReserverName', [
function (session) {
builder.Prompts.text(session, "Who's name will this reservation be under?");
},
function (session, results) {
session.endDialogWithResult(results);
}
]);
endDialog()和endDialogWithResult()及replaceDialog()方法
endDialog()方法只是完成当前的dialog,将主动权返回调用现在的dialog的对象
endDialogWithResult()方法是完成当前的dialog并返回参数,将主动权返回调用现在的dialog的对象


bot framework架构

收集输入
Bot Builder附带了一些内置的提示,可用于从用户收集输入。
提示类型 描述
Prompts.text 要求用户输入文本字符串。
提示 要求用户确认操作。
提示 要求用户输入号码。
提示时间 向用户询问时间或日期。
提示 要求用户从选择列表中进行选择。
提示 要求用户上传图片或视频。
这些内置的提示被实现为对话所以他们会回报用户通过调用响应session.endDialogWithresult() 。任何DialogHandler都可以接收对话的结果,但是瀑布往往是处理提示结果的最简单的方法。
提示返回给调用者的IPromptResult。用户响应将包含在results.response字段中,并且可以为null。响应为null的原因有很多。内置提示让用户通过说出像“cancel”或“nevermind”之类的操作来取消操作,这将导致null响应。或者用户可能无法输入正确格式的响应,这也可能导致空响应。确切的原因可以通过检查在result.resumed中返回的ResumeReason来确定。
Prompts.text()
该Prompts.text()方法要求的文本字符串用户。用户的响应将返回作为IPromptTextResult。
builder.Prompts.text(session, "What is your name?");
Prompts.confirm()
该Prompts.confirm()方法将要求用户确认是/否响应的动作。用户的响应将返回作为IPromptConfirmResult。
builder.Prompts.confirm(session, "Are you sure you wish to cancel your order?");
Prompts.number()
该Prompts.number()方法将要求用户用一个数字来回答。用户的响应将返回作为IPromptNumberResult。
builder.Prompts.number(session, "How many would you like to order?");
Prompts.time()
该Prompts.time()方法将要求用户用时间来回答。用户的响应将返回作为IPromptTimeResult。该框架采用了一种名为库计时来分析用户的响应,都相对的“5分钟”和非亲属“6月6日下午2点”式的回应支持。
该results.response返回的是一个实体可以使用被解析为一个JavaScript Date对象EntityRecognizer.resolveTime() 。
bot.dialog('/createAlarm', [
function (session) {
session.dialogData.alarm = {};
builder.Prompts.text(session, "What would you like to name this alarm?");
},
function (session, results, next) {
if (results.response) {
session.dialogData.name = results.response;
builder.Prompts.time(session, "What time would you like to set an alarm for?");
} else {
next();
}
},
function (session, results) {
if (results.response) {
session.dialogData.time = builder.EntityRecognizer.resolveTime([results.response]);
}
// Return alarm to caller
if (session.dialogData.name && session.dialogData.time) {
session.endDialogWithResult({
response: { name: session.dialogData.name, time: session.dialogData.time }
});
} else {
session.endDialogWithResult({
resumed: builder.ResumeReason.notCompleted
});
}
}
]);
Prompts.choice()
所述Prompts.choice()方法要求用户接从一个列表中选择一个选项。用户的响应将返回作为IPromptChoiceResult。选择列表可被呈现给用户以各种经由样式IPromptOptions.listStyle属性。用户可以通过输入选项的编号或其名称来表达他们的选择。支持选项名称的完全匹配和部分匹配。
选择列表可以以各种方式传递到Prompts.choice()。作为管道'|' 分隔字符串。
builder.Prompts.choice(session, "Which color?", "red|green|blue");
作为字符串数组。
builder.Prompts.choice(session, "Which color?", ["red","green","blue"]);
或作为对象映射。当传递一个对象时,将使用对象键来确定选择。
var salesData = {
"west": {
units: 200,
total: "$6,000"
},
"central": {
units: 100,
total: "$3,000"
},
"east": {
units: 300,
total: "$9,000"
}
};
bot.dialog('/', [
function (session) {
builder.Prompts.choice(session, "Which region would you like sales for?", salesData);
},
function (session, results) {
if (results.response) {
var region = salesData[results.response.entity];
session.send("We sold %(units)d units for a total of %(total)s.", region);
} else {
session.send("ok");
}
}
]);
Prompts.attachment()
该Prompts.attachment()方法会要求用户上传像图像或视频文件附件。用户的响应将返回作为IPromptAttachmentResult。
builder.Prompts.attachment(session, "Upload a picture for me to transform.");
Nodejs Bot学习的更多相关文章
- # nodejs模块学习: express 解析
# nodejs模块学习: express 解析 nodejs 发展很快,从 npm 上面的包托管数量就可以看出来.不过从另一方面来看,也是反映了 nodejs 的基础不稳固,需要开发者创造大量的轮子 ...
- nodejs模块学习: webpack
nodejs模块学习: webpack nodejs 发展很快,从 npm 上面的包托管数量就可以看出来.不过从另一方面来看,也是反映了 nodejs 的基础不稳固,需要开发者创造大量的轮子来解决现实 ...
- NodeJs入门学习(一)
NodeJs是针对前端工程师向web后端深入理解的一门很好的语言. 首先,记录NodeJS几大特性,后续补充: 一.Node.js 是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高. ...
- NodeJs开发学习目录
1.Nodejs基本概念及Nodejs.npm安装测试[2014-06-06] 2.开发工具简介(主要介绍Sublime Text使用) [2014-06-06] 3.Sublime text插件安装 ...
- nodejs模块学习: connect解析
nodejs模块学习: connect解析 nodejs 发展很快,从 npm 上面的包托管数量就可以看出来.不过从另一方面来看,也是反映了 nodejs 的基础不稳固,需要开发者创造大量的轮子来解决 ...
- nodejs模块学习: connect2解析
nodejs模块学习: connect2 解析 nodejs 发展很快,从 npm 上面的包托管数量就可以看出来.不过从另一方面来看,也是反映了 nodejs 的基础不稳固,需要开发者创造大量的轮子来 ...
- nodejs模块学习: express-session 解析
nodejs模块学习: express-session 解析 nodejs 发展很快,从 npm 上面的包托管数量就可以看出来.不过从另一方面来看,也是反映了 nodejs 的基础不稳固,需要开发者创 ...
- nodejs基础学习1
ES6常用新语法 ES6新语法 什么是ES6? 由于JavaScript是上个世纪90年代,由Brendan Eich在用了10天左右的时间发明的:虽然语言的设计者很牛逼,但是也扛不住"时间 ...
- NodeJS入门学习
node.js 概念:是一个由c++编写的,本质上是一个javascript的运行环境,他可以让js代码运行在服务器端. node可以解析JS代码(没有浏览器安全级的限制) 提供系统级别的API: 1 ...
随机推荐
- Activity-ListView
在手机中经常有列表方式.如果Activity中只有唯一一个List(这也是通常的情况),可以继承ListActivity来实现.我们用两个例子来学习List. List例子一:利用Android自带的 ...
- 在windows下如何使用密钥对远程登录服务器?
在企业的生产中相信各位朋友都会使用远程登录服务器,这样即高效也非常方便,(服务器在西藏,没有远程技术,公司在北京,你只能到西藏与机器相伴,在这里我使用xshell软件),我们使用ssh 服务登录服务器 ...
- [LeetCode] string整体做hash key,窗口思想复杂度O(n)。附来自LeetCode的4例题(标题有字数限制,写不下所有例题题目 T.T)
引言 在字符串类型的题目中,常常在解题的时候涉及到大量的字符串的两两比较,比如要统计某一个字符串出现的次数.如果每次比较都通过挨个字符比较的方式,那么毫无疑问是非常占用时间的,因此在一些情况下,我们可 ...
- 使用jquery.qrcode生成二维码及常见问题解决方案
转载文章 使用jquery.qrcode生成二维码及常见问题解决方案 一.jquery.qrcode.js介 jquery.qrcode.js 是一个纯浏览器 生成 QRcode 的 jQuery ...
- Java实现二叉树的先序、中序、后序、层序遍历(递归和非递归)
二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易 ...
- Robot Framework Chrome
1. 下载对应版本的chromedriver, 好像都是windows32位的,不过没关系,可以用即可. 2. 将chromedriver放入到chrome的安装路径下,然后将chromrdriver ...
- 「6月雅礼集训 2017 Day4」寻找天哥
[题目大意] 给出$n$个三维向量,设当前向量长度为$L$,每次沿着向量等概率走$[0,L]$个长度.一个球每秒半径增加1个长度,直到覆盖位置,每秒耗能为球体积,求总耗能的期望. 设最后半径为R,那么 ...
- 【NOIP】提高组2012 借教室
[算法]线段树||二分+前缀和 [题解]线段树记录区间加值和区间最大值. #include<cstdio> #include<algorithm> using namespac ...
- ios资源加载策略
做了好几个月的ios,大框架都是别人搭好的,自己只是实现逻辑,很是失落.慢慢开始整理学习一些概念类的东西吧,希望自己能提高点. cocos2d-x从cocos2d-2.0-x-2.0.2开始,考虑到自 ...
- 暑假集训——cf热身赛部分题有感加其题解
刚刚开始集训,集训队队长暂时还没有拉专题,而是拉了部分codeforces上过题人数在2000左右的题组成了一场热身赛(其实就是一场练习),花了一天时间终于把它刷完了,其中很多题让我学到了很多骚操作, ...