awesome-botkit-external 库
简单直接好用的机器人框架,支持 convoUI
- 基于类型多态的有限状态机进行流程控制
- 丰富的High-Level-API, 通过清晰的 DSL 描述任何复杂的业务流程状态转移图
- 支持对 inbound-msg 的多种匹配方式:正文Body匹配,Action匹配,也可以直接用 Low-Level-API 进行完全灵活度的自定义匹配
- 支持直接使用 Low-Level-API 在某个大状态下完成很多步精细交互操作(配合 async-await)
- 支持在某一具体状态下,下挂多种匹配的表达式。包括动态长度的自定义匹配
- 支持丰富简洁的控制流,goto,stay,repeat,stop. 对会话进行精准控制
1. 说明
1.1 Installation
npm install awesome-botkit-external
1.2 Demo
const botkit =const cuw = botkitConvoUIWrapper;Bot{return `亲,我是服务条款助手机器人【】.`;}{return `亲,我是机器人【】`;}{return {if convoreturn '上一次会话还没结束';elsereturn `亲,我是服务条款助手机器人【】,我现在进入了房间`;};}{return '会话结束';}// 主要逻辑都在这里{const startWith when goto stay stop = botkit;const Case DefaultCase match BodyCase ActionCase CommandCase = botkitMatcher;;async {ifcuw === "step1"returnelse if cuw === "step3"returnreturn};{ifcuw === "ui"returnreturn};{return;};{ifcuw === "step3"returnreturn};{ifcuw === "step1"returnelse if cuw === "done"returnreturn};{return};}const MyStates =IDLE: "IDLE"STEP1: "STEP1"STEP2: "STEP2"STEP3: "step3"UI: "ui"DONE: "DONE";;
2 机器人应用代码结构
High-Level-API
状态机定义函数
- describe 在
describe()
方法体里直接通过 DSL 描述状态机的状态转移图
状态机 DSL
- startWith 描述状态机的初始状态和初始 data,只需调用一次
- when 描述某个状态下,发生Event时,Bot业务执行与状态迁移的细节
- goto 用于生成
when()
函数的返回值,返回 nextState - stay
goto(CurrentState)
的另一种形式,停留在本状态 - stop
goto(Done)
的另一种形式,结束会话
matcher API
- BodyCase 匹配普通聊天中的string, 支持变长 pattern(String or RegExp type)
- ActionCase 匹配convoUI消息的action,支持变长 pattern(String or RegExp type)
- CommandCase 匹配convoUI消息的command类型,支持变长pattern(String or RegExp type)
- DefaultCase 模式匹配的Default分支
状态机data的共享
状态机describe()
的方法体内可以使用如下两种方式共享变量(session scope)
- 常规方式是在状态迁移时,将修改后的data对象传递给
using()
. 这里建议通过spread-rest
语法构造 immutable object 对象。后续会方便利用到状态跟踪,重演,TimeTravel Debugging 等很多玩法。 - 还有一种可行的方式是,直接将变量挂在 fsm 上面
Low-Level-API
在回调函数内,可以不借助 matcher API,通过判断 content 或者 data 的具体细节来控制分支走向, 获得最大的灵活度:
async { ifconvo_ui_wrapper === "step1" return ; else if convo_ui_wrapper === "开始业务2" return return ;};
3. ConvoUI 消息及应答格式说明
3.1 convoUI 通用说明
3.1.1 渲染参数 disply
convoUI 生成参数中(详见下列控件),参数 display 用于控制ConvoUI消息(控件)的展示形式,目前思考,有以下几种:
不提供此参数:不作限制,由前端自行决定 fixed:控件“建议”显示在固定区域 popup:控件“建议”弹出显示 inplace:控件“建议”显示在聊天历史记录中 assist: 控件“建议”显示在文字输入助理区域(目前仅文字助手控件支持此显示方式)
3.1.2 展示过期参数
convo.SetDisplayExpires(value)
参数用于指定在fixed、popup形式下的控件是否允许再次打开显示。如果未指定,则Web客户端上可以在历史消息中点开查看;若指定,则历史消息中不再提供打开按钮。
此值是一个过期时间(绝对时间,非相对时间)的长整数时间戳(epoch毫秒值)。
3.1.3 版本参数
convo.SetVersion()
,该参数用于在iOS设备上兼容旧版本的ConvoUI
当前 convo.SetVersion("2.0")
不必手动设置版本
3.1.4 接收者参数
convo.SetReceiver()
用于控制ConvoUI消息(控件)的接收对象。如果不指定,则表示不限定接收者。如果指定,这个数据是一个JSON数组,表示其中包含的userId的聊天界面上应该显示此ConvoUI消息,否则应隐藏。例如:
convo.SetReceiver(["@frank:finogeeks.club","@test:finogeeks.club"])
表示当前ConvoUI消息仅仅在frank和test两个用户的界面上显示,其他用户的界面上应该隐藏。
指定所有人接收时,请明确设置receiver为null或空数组。这是因为,如果数据完全没有这个键的话,框架会自动添加当前用户为receiver,但如果这个键存在(即使为null或空数组),它就会知道是所有用户接收,然后框架会把这个无用的空键去掉
3.1.5 控制UI应答是否显示
在机器人端发出的ConvoUI消息,客户端呈现UI界面给用户时,用户可能会在UI界面上进行操作(例如按钮点击、菜单选择或者输入等),这些操作即ConvoUI应答的结果,是否需要在消息历史中显示,以参数convo.SetShowReply()
来控制(默认值为false,即消息历史中隐藏ConvoUI应答),例如:
convo.SetShowReply(true)
例如在上述按钮出现时,用户点击了“同意条款”按钮,房间消息历史里面会显示应答消息(即应答消息的body文字部分)。这个body文字内容由客户端生成,例如上述按钮点击后文字消息如“点击按钮:同意条款”。依次类推,对于不同ConvoUI控件,这个文字格式有所不同。例如,若是菜单,则用户选择某项X后,显示文字消息为“菜单选择:X”,等等。
3.1.6 控制UI存根消息是否显示
对于display为popup,fixed,assist方式的UI消息而言,以下参数可以控制UI存根(stub,即承载UI的历史消息)是否在历史消息列表中隐藏掉。
convo.SetHideStub(true) // 默认为 false
3.1.7 控制会话控制是否显示
对于在某个与机器人会话的流程中,用户想做“结束会话”或“重置会话”等操作,这样的会话控制是否需要显示,以参数“convo_control”来控制,默认值为false,即不显示。
convo.SetConvoControl(false)
3.1.8 控制 FIX 控件是否静默处理指定操作,如是否弹起展示
convo.SetSilence(true) // 默认为 false
以上本章节参数对所有控件是通用的,convo 表示任何一种控件。在下文的格式描述中,将不再列出这些参数。
3.2 菜单(即按钮组) menu
所谓菜单,其实就是垂直或水平排列的逻辑按钮。
ConvoUI Message
const convo_ui_wrapper = require("awesome-botkit-external").ConvoUIWrapper
// title : 按钮文字
// action : 事件代码
item = new convo_ui_wrapper.MenuItem(title, action)
> `action`不仅可以是字符串,也可以是数字、对象、数组等任意JSON类型,客户端回送时保持原样就好(不要做解析及类型转换)
item.SetReply(true) // 默认为 true,可不设置
// type = "url", 点击则打开对应 value 的网页
// type = "userId", 点击则打开对应 value 用户的单聊页面
item.AddMeta(type, value)
// items : menu 上的每个选项
// caption : 菜单标题
menu = new convo_ui_wrapper.Menu([item, ...], display, caption)
- items中的
reply
为false
时,客户端可以不产生应答消息,默认为true。
menu 可以自由添加其他键,满足渲染的需要,例如给菜单增加一个标题(Caption),要求横向排列(horizontal),并在每个按钮上增加一个提示(tip):
menu.SetCaption("请选择一种收费方式")
menu.SetHorizontal(true)
menu.SetTip("想好了再按")
ConvoUI Reply
action = convo_ui_wrapper.GetAction(content)
result = convo_ui_wrapper.GetResult(content)
3.3 上传图片 image
ConvoUI Message
// prompt : 上传提示文字
// max_size : 文件最大尺寸
image = new convo_ui_wrapper.Image(prompt, max_size, display)
image.SetTypes(["png", "jpeg", "gif"]) // 该数组描述可以接受的文件格式
ConvoUI Reply
// info: {
// h: 398,
// w: 394,
// size: 31037,
// mimetype: "image/jpeg"
// }
info = convo_ui_wrapper.GetInfo(content)
url = convo_ui_wrapper.GetUrl(content)
3.4 上传视频 video
ConvoUI Message
// prompt : 上传提示文字
// max_size : 文件最大尺寸
video = new convo_ui_wrapper.Video(prompt, max_size, display)
video.SetTypes(["mp4","webm","ogg"]) // 该数组描述可以接受的文件格式
ConvoUI Reply
// info: {
// h: 320,
// w: 480,
// size: 1563685,
// duration: 2140786,
// mimetype: "video/mp4",
// thumbnail_url: "mxc://finogeeks.club/FHyPlCeYUSFFxlgbQYZmoEoe",
// thumbnail_info: {
// h: 300,
// w: 300,
// size: 46144,
// mimetype: "image/jpeg"
// }
// }
info = convo_ui_wrapper.GetInfo(content)
url = convo_ui_wrapper.GetUrl(content)
3.5 上传音频 audio
ConvoUI Message
// prompt : 上传提示文字
// max_size : 文件最大尺寸
audio = new convo_ui_wrapper.Audio(prompt, max_size, display)
audio.SetTypes(["mp3","wav","ogg"]) // 该数组描述可以接受的文件格式
ConvoUI Reply
// info: {
// size: 1563685,
// duration: 2140786,
// mimetype: "audio/mpeg"
// }
info = convo_ui_wrapper.GetInfo(content)
url = convo_ui_wrapper.GetUrl(content)
3.6 文字输入 input
ConvoUI Message
// prompt : 输入框上方提示文字, string 或者 array,对应 GetInput(content)
// text : 详细说明文字,例如关于输入内容的详细解释或说明
input = new convo_ui_wrapper.Input(prompt, text, display)
input.SetHtml(false) //text中内容是否为HTML格式化的,可省,默认非HTML格式
input.SetType("text") //可省略,默认为text
prompt 为数组时,会渲染出对应个数的input框,reply GetInput 为相应的数组值。 prompt 为字符串时,会渲染出对应的一个input框,reply GetInput 为相应的字符串值。
其中type可以填入的值暂定为:
- text:普通文本
- username:按要求符合用户名格式的文字(按本系统用户名允许字符集)
- password: 密码
- pin:纯数字密码
- number:数字(整数或带小数部分)
- phone:手机或电话
- cellphone:手机号
- email:email地址
- multiline:多行文本,类似HTML中TextArea标签的效果
ConvoUI Reply
input = convo_ui_wrapper.GetInput(content)
3.7 获取地理位置 location
ConvoUI Message
// 可对获取的地点范围等做规定,需要时扩展
location = new convo_ui_wrapper.Location(display)
ConvoUI Reply
geo_uri = convo_ui_wrapper.GetGeoUri(content)
3.8 选择 select
用途:显示一块文字,下方提供选择项。
例如:风险评估会话中的选择题 例如:一个服务协议,下方配同意还是拒绝的选择
ConvoUI Message
// text : 选项文字
// action : 事件代码
item = new convo_ui_wrapper.SelectItem (text, action)
item.SetSelected(true) // 可选,表示默认选中
// text : 选择说明文字,例如服务协议内容或选择题题面
select = new convo_ui_wrapper.Select([item, ...], text, display)
select.SetMultiple(false) // 是否允许多选,可省,默认单选
select.SetHtml(false) // text中内容是否为HTML格式化的,可省,默认非HTML格式
items中的
action
不仅可以是字符串,也可以是数字、对象、数组等任意JSON类型,客户端回送时保持原样就好(不要做解析及类型转换)
items中的
SetSelected()
参数是布尔型参数,表示是否预先选中某选项,对于menu.SetMultiple(true)
的多选情况,items中可以有多个成员带有item.SetSelected(true)
。
ConvoUI Reply
selected = convo_ui_wrapper.GetSelected(content) // 得到事件代码,如果允许多选则可能有多个
3.9 短信验证码输入 verifycode
ConvoUI Message
// prompt : 提示文字
// expires : 过期时间的长整数时间戳(epoch毫秒值)
verifycode = new convo_ui_wrapper.Verifycode(prompt, expires, display)
ConvoUI Reply
input = convo_ui_wrapper.GetInput(content) // 用户输入的验证码内容
expires = convo_ui_wrapper.GetExpired(content) // true/false 表示已超过过期时间
3.10 文字助手 text_assist
此控件的作用是机器人端发出一组文字,由客户端提供给用户作为类似自动完成的文字。具体展示形式由客户端决定(展示在固定区域的可点击文字、或者作为输入的自动完成选单等形式)。用户可以无视这种控件产生的提示。但当用户点击(若以可点击形式出现),则等同于用户发出一条文字消息。
ConvoUI Message
// items: ["文字一", "文字二", …… ]
text_assist = new convo_ui_wrapper.TextAssist(items, display)
text_assist.SetCaption("请选择") // caption 选项是可选的,可有可无
注意:对于此控件,如果提供了display
参数,则会按前述三种展示方式来显示这一控件;如果没有提供这一参数,则采用一种特殊的展示方式,例如直接展示在文字输入框附近(或者自动完成的提示区域)。所以请明确你的用途:
-
如果主要是输入辅助作用,请不要提供
display
参数! -
如果是业务流程中一种菜单性质的选择(和menu控件的区别是产生文字反馈而不是ConvoUI Reply),则可能提供
display
参数比较好。
ConvoUI Reply
此消息没有特定响应。当用户点击(若以可点击形式出现)文字时,则等同于用户发出一条普通的Matrix文字消息。
3.11 网页嵌入 url_embedded
此控件作用是在显示区直接嵌入一个外部网址。在Web客户端上,最典型的实现方式是采用iframe标签来实现。
ConvoUI Message
// caption : 必填,标题,类似微信公众号消息头文字(app端消息渲染用,及图文消息、豆腐块消息渲染用)
// url : 必填,浏览器可以解析并渲染的url格式, 例如:http://... 或 https://...
// thumbnail : 必填,类似微信公众号消息中右侧的预览图,此为预览图图片地址(app端消息渲染用,及图文消息、豆腐块消息渲染用)
// description : 必填,类似微信公众号消息细节文字(app端消息渲染用,及图文消息、豆腐块消息渲染用)
// display : 可选,显示模式, 默认为inplace,可选值有inplace、popup、fixed
url_embedded = new convo_ui_wrapper.UrlEmbedded(caption, url, thumbnail, description, display)
url_embedded.SetType("webpage") // 可选。消息UI类型,默认为网页引入格式,可选值包括webpage(网页)、graphtext(图文)、beancurd(豆腐块)
url_embedded.SetHeight(300) // 可选。指定网页嵌入区域的高度;宽度不可指定,因为宽度受限于聊天视图的大小
url_embedded.SetScrolling(false) // 可选。true,表示任何时候总是有滚动条;false,一律禁止滚动条。不提供此参数,表示auto(需要时自动出)
url_embedded.SetFooter(true) // 可选。默认值为true,(只针对图文消息)表示图文消息是否渲染出底部链接
graphtext(图文)、beancurd(豆腐块)只支持 inplace 显示模式,webpage(网页)支持三种。
ConvoUI Reply
此消息主要用于展示,没有特定响应。
3.12 富文本展示 richtext
此控件的作用根据指定的富文本源以及格式,在显示区渲染出带格式文本效果。目前支持 html 格式和 markdown 格式。
ConvoUI Message
// source : 富文本源码, 例如,带有html标签的文本;或者 format = markdown 时,markdown 文本源码
richtext = new convo_ui_wrapper.Richtext(source, display)
richtext.SetFormat("html") // 默认 html,同时也支持 markdown
richtext.SetCaption("请浏览") // 可选,标题
richtext.SetThumbnail("") // 可选,类似微信公众号消息中右侧的预览图,此为预览图图片地址
richtext.SetDescription("") // 可选,类似微信公众号消息细节文字
richtext.SetType("richtext") // 可选,消息UI类型,默认为richtext(富文本),可选值包括richtext(富文本)、graphtext(图文)、beancurd(豆腐块)、recruitment(招聘消息)
richtext.SetFooter(true) // 可选,默认值为true,(只针对图文消息)表示图文消息是否渲染出底部链接
richtext.SetAfter("") // 可选,招聘消息中头部偏右的文本
ConvoUI Reply
此消息主要用于展示,没有特定响应。
3.13 幻灯片显示 slideshow
此控件的作用是显示一个幻灯片效果。可以看成是url_embedded
及richtext
控件的一个组合容器。其成员(每页幻灯片)可以是url_embedded,也可以是richtext。
ConvoUI Message
// items : [
// new convo_ui_wrapper.UrlEmbedded(...), // 参数同 url_embedded
// new convo_ui_wrapper.Richtext(...), // 参数同 richtext
// ...
// ]
slideshow = new convo_ui_wrapper.Slideshow(items, display)
slideshow.SetCaption("演示幻灯片") // 可选,如提供则在幻灯片显示区之上显示标题
slideshow.SetThumbnail("") // 可选,类似微信公众号消息中右侧的预览图,此为预览图图片地址
slideshow.SetDescription("") // 可选,类似微信公众号消息细节文字
slideshow.SetAutoplay(true) // 可选,默认为true;如果为false,则幻灯片不会自动滚动,需手工切换
ConvoUI Reply
此消息主要用于展示,没有特定响应。
3.14 基本豆腐块 beancurd
豆腐块控件(类似微信分享)。
ConvoUI Message
// title : 按钮文字
// link : 链接地址
// content : 最多三行显示的文本内容
// icon : 图片
beancurd = new convo_ui_wrapper.Beancurd(title, link, content, icon, display)
ConvoUI Reply
此消息主要用于展示,没有特定响应。
3.15 分页组件 pager
分页 + 按钮组(链接🔗)组件
ConvoUI Message
// title : 按钮元素的文本
// type : 类型,"url" 或 "action"
// href : 根据 type,按钮链接地址或action
// after : 按钮元素偏右的文本, 选填
item = new convo_ui_wrapper.PagerItem(title, type, href, after)
// size : 每页展示数据数
pager = new convo_ui_wrapper.Pager([item, ...], size, display)
pager.SetCaption("标题文字或标签文字") // 选填,组件的标题或标签说明文字
pager.SetCurrent(1) // 选填,number,分页初始化显示页面,默认为1
items
是一个数组格式的数据,每个数组元素都是一个对象,包含title、href、after、after 属性
ConvoUI Reply
action = convo_ui_wrapper.GetAction(content)
result = convo_ui_wrapper.GetResult(content)
3.16 通知显示 notice
此控件作用是轻量化的通知一个状态、消息、内容。可以看成是url_embedded
、richtext
及'menu'控件的一个组合容器。
ConvoUI Message
// key : 文本
// value : 文本, KV 展示上类似一个 table
item = new convo_ui_wrapper.NoticeItem(key, value)
// caption : 标题
notice = new convo_ui_wrapper.Notice(caption, [item, ...], display)
// text : 可选,头部内容,为空则不显示header
// font_size : 可选,默认14
// color : 可选,默认纯黑 #000000 16 进制 RGB 色值
notice.SetHeader(text, font_size, color)
// text : 可选,底部内容,为空则不显示footer
// font_size : 可选,默认14
// color : 可选,默认纯黑 #000000 16 进制 RGB 色值
notice.SetFooter(text, font_size, color)
notice.SetUrl("") // 可选 有链接则可以跳转,没有则不能跳转
notice.SetThumbnail("url") // 可选,一张小图片
notice.SetDescription("") // 可选,类似微信公众号消息细节文字
// 可选,底部按钮,移动端建议不要超过3个
notice.SetMenu([new convo_ui_wrapper.MenuItem(title, action), new convo_ui_wrapper.MenuItem(title, action)]
ConvoUI Reply
action = convo_ui_wrapper.GetAction(content)
result = convo_ui_wrapper.GetResult(content)
4. 目前各端支持的消息的类型
ConvoUI 类型 | Web | iOS | Android |
---|---|---|---|
convo.ui.button | all + assist,不推荐 | none | none |
convo.ui.menu | all + assist | inplace / fixed | inplace / fixed |
convo.ui.image | all | inplace / fixed | |
convo.ui.video | none | inplace / fixed | |
convo.ui.audio | none | inplace / fixed | |
convo.ui.input | all | inplace / fixed | |
convo.ui.location | none | inplace / fixed | |
convo.ui.select | all | inplace / fixed | inplace / fixed |
convo.ui.verifycode | all | inplace / fixed | |
convo.ui.text_assist | assist | assist | assist |
convo.ui.url_embedded | all | inplace | |
convo.ui.richtext | all | inplace | |
convo.ui.slideshow | all | inplace | |
convo.ui.beancurd | inplace | inplace | inplace |
convo.ui.graphtext | inplace | inplace | inplace |
convo.ui.pager | inplace | inplace | inplace |
convo.ui.notice | inplace | inplace | inplace |
- all : 指inplace、fixed、popup三种形式都支持
- none:该端不支持本控件
- / :暂未实现,即将支持
- 留空:尚未填写
- 不推荐:支持但不推荐使用