Security News
Node.js EOL Versions CVE Dubbed the "Worst CVE of the Year" by Security Experts
Critics call the Node.js EOL CVE a misuse of the system, sparking debate over CVE standards and the growing noise in vulnerability databases.
awesome-botkit-external
Advanced tools
简单直接好用的机器人框架,支持 convoUI
npm install awesome-botkit-external
const botkit = require('awesome-botkit-external')
const cuw = botkit.ConvoUIWrapper;
class MyBotApp extends botkit.Bot {
onJoinRoom(bot, roomId) {
return new cuw.PureText(`亲,我是服务条款助手机器人【${bot.name}】.`);
}
onUserJoinRoom(bot, roomId){
return new cuw.PureText(`亲,我是机器人【${bot.name}】`);
}
onUserEnterRoom(bot, roomId, userId, displayName){
return convo => {
if (convo) {
return new cuw.PureText('上一次会话还没结束');
} else {
return new cuw.PureText(`亲,我是服务条款助手机器人【${bot.name}】,我现在进入了房间`);
}
};
}
onTimeout(bot, roomId, userId, displayName) {
return new cuw.PureText('会话结束');
}
// 主要逻辑都在这里
describe(fsm) {
const {startWith, when, goto, stay, stop} = botkit.DSL(fsm);
const { Case, DefaultCase, match, BodyCase, ActionCase, CommandCase } = botkit.Matcher;
startWith(MyStates.IDLE, {counter: 0});
when(MyStates.IDLE)(async (sender, content, data) => {
if(cuw.GetBody(content) === "step1") {
return goto(MyStates.STEP1).withConvoMsg(new cuw.PureText("进入step1"))
} else if (cuw.GetBody(content) === "step3") {
return goto(MyStates.STEP3).withConvoMsg(new cuw.PureText("进入step3"))
}
return stay().withConvoMsg(new cuw.PureText("待在idle"))
});
when(MyStates.STEP1)((sender, content, data) => {
if(cuw.GetBody(content) === "ui") {
return goto(MyStates.UI).withConvoMsg(new cuw.Menu(
[
new cuw.MenuItem("step1", "s1"),
new cuw.MenuItem("step2", "s2"),
new cuw.MenuItem("step3", "s3"),
new cuw.MenuItem("command", "command"),
new cuw.MenuItem("stay", "stay"),
],
"display"))
}
return stay().withConvoMsg(new cuw.PureText("待在step1"))
});
when(MyStates.UI)((sender, content, data) => {
return match(content,
ActionCase("s1")(() => goto(MyStates.STEP1).withConvoMsg(new cuw.PureText("进入step1"))),
ActionCase("s2")(() => goto(MyStates.STEP2).withConvoMsg(new cuw.PureText("进入step2"))),
ActionCase("s3")(() => goto(MyStates.STEP3).withConvoMsg(new cuw.PureText("进入step3"))),
CommandCase("convo.ui.menu")((command) => stay().withConvoMsg(new cuw.PureText(command))),
DefaultCase(() => stay().withConvoMsg(new cuw.PureText("待在UI")))
);
});
when(MyStates.STEP2)((sender, content, data) => {
if(cuw.GetBody(content) === "step3") {
return goto(MyStates.STEP1).withConvoMsg(new cuw.PureText("进入step3"))
}
return stay().withConvoMsg(new cuw.PureText("待在step2"))
});
when(MyStates.STEP3)((sender, content, data) => {
if(cuw.GetBody(content) === "step1") {
return goto(MyStates.STEP1).withConvoMsg(new cuw.PureText("回到step1"))
} else if (cuw.GetBody(content) === "done") {
return goto(MyStates.DONE).withConvoMsg(new cuw.PureText("进入done"))
}
return stay().withConvoMsg(new cuw.PureText("待在step3"))
});
when(MyStates.DONE)((sender, content, data) => {
return stop().withConvoMsg(new cuw.PureText("结束会话"))
});
}
}
const MyStates = {
IDLE: "IDLE",
STEP1: "STEP1",
STEP2: "STEP2",
STEP3: "step3",
UI: "ui",
DONE: "DONE"
};
new MyBotApp(require('./config.js')).run();
describe()
方法体里直接通过 DSL 描述状态机的状态转移图when()
函数的返回值,返回 nextStategoto(CurrentState)
的另一种形式,停留在本状态goto(Done)
的另一种形式,结束会话状态机describe()
的方法体内可以使用如下两种方式共享变量(session scope)
using()
. 这里建议通过 spread-rest
语法构造 immutable object 对象。后续会方便利用到状态跟踪,重演,TimeTravel Debugging 等很多玩法。在回调函数内,可以不借助 matcher API,通过判断 content 或者 data 的具体细节来控制分支走向, 获得最大的灵活度:
when(MyStates.IDLE)(async (sender, content, data) => {
if(convo_ui_wrapper.GetBody(content) === "step1") {
return goto(MyStates.STEP1).withConvoMsg({body: "I goto step1!"});
} else if (convo_ui_wrapper.GetBody(content) === "开始业务2") {
return goto(MyStates.STEP2)
}
return stay().withConvoMsg({body: "Stay!"});
});
convoUI 生成参数中(详见下列控件),参数 display 用于控制ConvoUI消息(控件)的展示形式,目前思考,有以下几种:
不提供此参数:不作限制,由前端自行决定 fixed:控件“建议”显示在固定区域 popup:控件“建议”弹出显示 inplace:控件“建议”显示在聊天历史记录中 assist: 控件“建议”显示在文字输入助理区域(目前仅文字助手控件支持此显示方式)
convo.SetDisplayExpires(value)
参数用于指定在fixed、popup形式下的控件是否允许再次打开显示。如果未指定,则Web客户端上可以在历史消息中点开查看;若指定,则历史消息中不再提供打开按钮。
此值是一个过期时间(绝对时间,非相对时间)的长整数时间戳(epoch毫秒值)。
convo.SetVersion()
,该参数用于在iOS设备上兼容旧版本的ConvoUI
当前 convo.SetVersion("2.0")
不必手动设置版本
convo.SetReceiver()
用于控制ConvoUI消息(控件)的接收对象。如果不指定,则表示不限定接收者。如果指定,这个数据是一个JSON数组,表示其中包含的userId的聊天界面上应该显示此ConvoUI消息,否则应隐藏。例如:
convo.SetReceiver(["@frank:finogeeks.club","@test:finogeeks.club"])
表示当前ConvoUI消息仅仅在frank和test两个用户的界面上显示,其他用户的界面上应该隐藏。
指定所有人接收时,请明确设置receiver为null或空数组。这是因为,如果数据完全没有这个键的话,框架会自动添加当前用户为receiver,但如果这个键存在(即使为null或空数组),它就会知道是所有用户接收,然后框架会把这个无用的空键去掉
在机器人端发出的ConvoUI消息,客户端呈现UI界面给用户时,用户可能会在UI界面上进行操作(例如按钮点击、菜单选择或者输入等),这些操作即ConvoUI应答的结果,是否需要在消息历史中显示,以参数convo.SetShowReply()
来控制(默认值为false,即消息历史中隐藏ConvoUI应答),例如:
convo.SetShowReply(true)
例如在上述按钮出现时,用户点击了“同意条款”按钮,房间消息历史里面会显示应答消息(即应答消息的body文字部分)。这个body文字内容由客户端生成,例如上述按钮点击后文字消息如“点击按钮:同意条款”。依次类推,对于不同ConvoUI控件,这个文字格式有所不同。例如,若是菜单,则用户选择某项X后,显示文字消息为“菜单选择:X”,等等。
对于display为popup,fixed,assist方式的UI消息而言,以下参数可以控制UI存根(stub,即承载UI的历史消息)是否在历史消息列表中隐藏掉。
convo.SetHideStub(true) // 默认为 false
对于在某个与机器人会话的流程中,用户想做“结束会话”或“重置会话”等操作,这样的会话控制是否需要显示,以参数“convo_control”来控制,默认值为false,即不显示。
convo.SetConvoControl(false)
convo.SetSilence(true) // 默认为 false
以上本章节参数对所有控件是通用的,convo 表示任何一种控件。在下文的格式描述中,将不再列出这些参数。
所谓菜单,其实就是垂直或水平排列的逻辑按钮。
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)
reply
为false
时,客户端可以不产生应答消息,默认为true。menu 可以自由添加其他键,满足渲染的需要,例如给菜单增加一个标题(Caption),要求横向排列(horizontal),并在每个按钮上增加一个提示(tip):
menu.SetCaption("请选择一种收费方式")
menu.SetHorizontal(true)
menu.SetTip("想好了再按")
action = convo_ui_wrapper.GetAction(content)
result = convo_ui_wrapper.GetResult(content)
// prompt : 上传提示文字
// max_size : 文件最大尺寸
image = new convo_ui_wrapper.Image(prompt, max_size, display)
image.SetTypes(["png", "jpeg", "gif"]) // 该数组描述可以接受的文件格式
// info: {
// h: 398,
// w: 394,
// size: 31037,
// mimetype: "image/jpeg"
// }
info = convo_ui_wrapper.GetInfo(content)
url = convo_ui_wrapper.GetUrl(content)
// prompt : 上传提示文字
// max_size : 文件最大尺寸
video = new convo_ui_wrapper.Video(prompt, max_size, display)
video.SetTypes(["mp4","webm","ogg"]) // 该数组描述可以接受的文件格式
// 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)
// prompt : 上传提示文字
// max_size : 文件最大尺寸
audio = new convo_ui_wrapper.Audio(prompt, max_size, display)
audio.SetTypes(["mp3","wav","ogg"]) // 该数组描述可以接受的文件格式
// info: {
// size: 1563685,
// duration: 2140786,
// mimetype: "audio/mpeg"
// }
info = convo_ui_wrapper.GetInfo(content)
url = convo_ui_wrapper.GetUrl(content)
// 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可以填入的值暂定为:
input = convo_ui_wrapper.GetInput(content)
// 可对获取的地点范围等做规定,需要时扩展
location = new convo_ui_wrapper.Location(display)
geo_uri = convo_ui_wrapper.GetGeoUri(content)
用途:显示一块文字,下方提供选择项。
例如:风险评估会话中的选择题 例如:一个服务协议,下方配同意还是拒绝的选择
// 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)
。
selected = convo_ui_wrapper.GetSelected(content) // 得到事件代码,如果允许多选则可能有多个
// prompt : 提示文字
// expires : 过期时间的长整数时间戳(epoch毫秒值)
verifycode = new convo_ui_wrapper.Verifycode(prompt, expires, display)
input = convo_ui_wrapper.GetInput(content) // 用户输入的验证码内容
expires = convo_ui_wrapper.GetExpired(content) // true/false 表示已超过过期时间
此控件的作用是机器人端发出一组文字,由客户端提供给用户作为类似自动完成的文字。具体展示形式由客户端决定(展示在固定区域的可点击文字、或者作为输入的自动完成选单等形式)。用户可以无视这种控件产生的提示。但当用户点击(若以可点击形式出现),则等同于用户发出一条文字消息。
// items: ["文字一", "文字二", …… ]
text_assist = new convo_ui_wrapper.TextAssist(items, display)
text_assist.SetCaption("请选择") // caption 选项是可选的,可有可无
注意:对于此控件,如果提供了display
参数,则会按前述三种展示方式来显示这一控件;如果没有提供这一参数,则采用一种特殊的展示方式,例如直接展示在文字输入框附近(或者自动完成的提示区域)。所以请明确你的用途:
如果主要是输入辅助作用,请不要提供
display
参数!
如果是业务流程中一种菜单性质的选择(和menu控件的区别是产生文字反馈而不是ConvoUI Reply),则可能提供display
参数比较好。
此消息没有特定响应。当用户点击(若以可点击形式出现)文字时,则等同于用户发出一条普通的Matrix文字消息。
此控件作用是在显示区直接嵌入一个外部网址。在Web客户端上,最典型的实现方式是采用iframe标签来实现。
// 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(网页)支持三种。
此消息主要用于展示,没有特定响应。
此控件的作用根据指定的富文本源以及格式,在显示区渲染出带格式文本效果。目前支持 html 格式和 markdown 格式。
// 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("") // 可选,招聘消息中头部偏右的文本
此消息主要用于展示,没有特定响应。
此控件的作用是显示一个幻灯片效果。可以看成是url_embedded
及richtext
控件的一个组合容器。其成员(每页幻灯片)可以是url_embedded,也可以是richtext。
// 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,则幻灯片不会自动滚动,需手工切换
此消息主要用于展示,没有特定响应。
豆腐块控件(类似微信分享)。
// title : 按钮文字
// link : 链接地址
// content : 最多三行显示的文本内容
// icon : 图片
beancurd = new convo_ui_wrapper.Beancurd(title, link, content, icon, display)
此消息主要用于展示,没有特定响应。
分页 + 按钮组(链接🔗)组件
// 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 属性action = convo_ui_wrapper.GetAction(content)
result = convo_ui_wrapper.GetResult(content)
此控件作用是轻量化的通知一个状态、消息、内容。可以看成是url_embedded
、richtext
及'menu'控件的一个组合容器。
// 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)]
action = convo_ui_wrapper.GetAction(content)
result = convo_ui_wrapper.GetResult(content)
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 |
FAQs
bot framework with fsm and pattern-matcher
We found that awesome-botkit-external demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Critics call the Node.js EOL CVE a misuse of the system, sparking debate over CVE standards and the growing noise in vulnerability databases.
Security News
cURL and Go security teams are publicly rejecting CVSS as flawed for assessing vulnerabilities and are calling for more accurate, context-aware approaches.
Security News
Bun 1.2 enhances its JavaScript runtime with 90% Node.js compatibility, built-in S3 and Postgres support, HTML Imports, and faster, cloud-first performance.