使用须知

Aibote是江西爱伯特科技自主研发的一款纯代码RPA办公自动化框架,支持Android、Browser和Windows 三大平台。框架免费、API和接口协议开源,个人、企业商用零费用
以socket tcp接口协议通信方式命令驱动,因此支持任何一门计算机语言调用,官方目前采用Node.js封装了一套SDK供开发者直接使用
Node.js拥有npm强大社区库,功能非常多,能够满足个人、企业办公自动化所有场景
OEM或特殊接口定制等商业合作联系QQ:1600381943

Aibote能力:
        1、AndroidBot,底层自主研发,支持安卓原生APP和H5界面元素和图色定位。元素元素定位速度是Appium框架的的10倍,2340*1080 图色定位仅需要50毫秒!
        2、WindowsBot,底层自主研发,支持Windows应用、.NET、WinForm、WPF、QT、JAVA(Swing和AWT等GUI库)和Electron 等语言开发的窗口界面元素和图色定位,独家xpath算法 简洁急速,
        元素/图色定位速度分别是可视化RPA的3倍和20倍!
        3、WebBot,底层自主研发,支持chromium内核的所有浏览器和应用。C/C++语言基于浏览器内核协议研发而成的一款web自动化框架。速度是selenium 10倍!
        4、Android远程投屏,底层自主研发,可在一台电脑监控观察多台安卓RPA机器人运行状态并批量管理操作
        5、自建OCR服务器,支持文字识别和定位,免费且不限制使用次数!
        6、自研AiboteScriptUI界面开发工具,提供人机交互功能,打包exe发布机器人可以在离线环境运行!

注意事项:
        1、下载Aibote全部解压出来,尽量不包含中文路径。第一次启动Aibote.exe会自动设置环境变量及Node依赖,开发者不必再安装Node
        2、Node.js SDK开源API存放 Aibote/Project/node_modules 目录下,涵盖AndroidBot、WebBot和WindowsBot,因此开发者应在Project目录下创建项目文件
        3、Node.js开发者建议使用Vs Code IDE作为开发工具,Windows 10/11系统必须以管理员权限启动Vs Code,否则因权限不足问题导致部分函数失效
        4、Node.js引入第三方库应当切入到Aibote根目录(非Project目录),再使用 npm instll xxx  安装。

拾取元素工具使用方法

Android 工具位置,Aibote/Aibote.exe->菜单项->脚本工具
Windows 工具位置,Aibote/WindowsTool.exe

Android 元素拾取工具,需要在手机端,勾选连接工具端选项

Windows 元素拾取工具,按下CTRL键,暂停拾取。支持鼠标左键/中键拾取

拾取元素注意窗口元素穿透现象

使用方法:
1、点击"+"按钮 单击手机投屏/windows 窗口,拾取元素和颜色信息。单击目标点会在右和下扩增20个像素点,用作放大目标位置。 再点击预览图片控件可拾取放大后 点的颜色值和坐标

2、点击"+"按钮 在手机投屏/windows 窗口滑动矩形大小,拾取元素和图片信息。截图前输入图片名称。Android端,图片保存在手机/storage/emulated/0/Android/data/com.aibot.client/files/
(根目录:/storage/emulated/0/)。Windows端,图片保存在指定路径目录,如果图片名称不包含路径,则默认保存在Aibote/Picture/windows

3、二值化阈值和最大值在0-255之间,阈值和最大值都为255时灰度化处理

4、BINARY算法,当前点值大于阈值thresh时,取最大值maxva,否则设置为0

5、BINARY_INV算法,当前点值大于阈值thresh时,设置为0,否则设置为最大值maxva

6、TOZERO算法,当前点值大于阈值thresh时,不改变,否则设置为0

7、TOZERO_INV算法,当前点值大于阈值thresh时,设置为0,否则不改变

8、TRUNC算法,当前点值大于阈值thresh时,设置为阈值thresh,否则不改变

9、ADAPTIVE_THRESH_MEAN_C算法,自适应阈值

10、ADAPTIVE_THRESH_GAUSSIAN_C算法,自适应阈值

AndoridBot开发手册

主函数示例

const AndroidBot = require('AndroidBot');//引用AndroidBot模块

//注册主函数,安卓端连接脚本会自动调用androidMain,并传递AndroidBot对象。设置服务端监听端口,手机端默认连接端口16678
AndroidBot.registerMain(androidMain, 16678);
/**用作代码提示,androidMain函数会被多次调用,注意使用全局变量
* @param {AndroidBot} androidBot
*/
async function androidMain(androidBot){
    await androidBot.setImplicitTimeout(3000);//设置隐式等待时间
    let point = await androidBot.findColor("#0e76b1");//查找指定颜色值坐标点
    console.log(point);
}

等待超时

await androidBot.sleep(3000);
//显示等待
//参数一 整型,等待时间,单位毫秒

await androidBot.setImplicitTimeout(waitMs, intervalMs = 5);
//隐式等待
//参数一 整型,等待时间,单位毫秒
//参数二 整型,心跳间隔,单位毫秒。可选参数,默认5毫秒
//作用全局,程序起始设置一次即可。并发会影响实际等待时间

await androidBot.setAndroidTimeout(60000);
//设置安卓客户端接收超时,默认为永久等待
//参数一 整型,超时时间,单位毫秒
//一般返回true。

图片与颜色

await androidBot.saveScreenshot(savePath, options = {});
//截图保存
//参数一 字符串类型,保存图片路径。建议存放在手机 /storage/emulated/0/Android/data/com.aibot.client/files/ 目录下
//参数二 JSON类型,可选参数{{region:[left:number, top:number, right:number, bottom:number], threshold:[thresholdType:number, thresh:number, maxval:number]}} options 
//region截图区域 [10, 20, 100, 200], 默认全屏
//threshold二值化图片, thresholdType算法类型:
//                                            0   THRESH_BINARY算法,当前点值大于阈值thresh时,取最大值maxva,否则设置为0
//                                            1   THRESH_BINARY_INV算法,当前点值大于阈值thresh时,设置为0,否则设置为最大值maxva
//                                            2   THRESH_TOZERO算法,当前点值大于阈值thresh时,不改变,否则设置为0
//                                            3   THRESH_TOZERO_INV算法,当前点值大于阈值thresh时,设置为0,否则不改变
//                                            4   THRESH_TRUNC算法,当前点值大于阈值thresh时,设置为阈值thresh,否则不改变
//                                            5   ADAPTIVE_THRESH_MEAN_C算法,自适应阈值
//                                            6   ADAPTIVE_THRESH_GAUSSIAN_C算法,自适应阈值
//                                            thresh阈值,maxval最大值,threshold默认保存原图。thresh和maxval同为255时灰度处理
//成功返回true,失败返回false

''' 代码示例
//截取全屏,图片保存至/storage/emulated/0/Android/data/com.aibot.client/files/1.png
let savePath = "/storage/emulated/0/Android/data/com.aibot.client/files/1.png";
await androidBot.saveScreenshot(savePath);

//二值化区域截图,区域起始坐标位置(10,20),右下角坐标位置(100,200)。二值化使用THRESH_BINARY算法。阈值127,最大值255
let options = {region:[10, 20, 100, 100], threshold:[0, 127, 255]};
await androidBot.saveScreenshot(savePath, options);
'''


await androidBot.takeScreenshot(options = {});
//截图
//参数一 JSON类型,可选参数{{region:[left:number, top:number, right:number, bottom:number], threshold:[thresholdType:number, thresh:number, maxval:number], scale:number}} options 
//region截图区域 [10, 20, 100, 200], 默认全屏
//threshold二值化图片, thresholdType算法类型:
//                                            0   THRESH_BINARY算法,当前点值大于阈值thresh时,取最大值maxva,否则设置为0
//                                            1   THRESH_BINARY_INV算法,当前点值大于阈值thresh时,设置为0,否则设置为最大值maxva
//                                            2   THRESH_TOZERO算法,当前点值大于阈值thresh时,不改变,否则设置为0
//                                            3   THRESH_TOZERO_INV算法,当前点值大于阈值thresh时,设置为0,否则不改变
//                                            4   THRESH_TRUNC算法,当前点值大于阈值thresh时,设置为阈值thresh,否则不改变
//                                            5   ADAPTIVE_THRESH_MEAN_C算法,自适应阈值
//                                            6   ADAPTIVE_THRESH_GAUSSIAN_C算法,自适应阈值
//                                            thresh阈值,maxval最大值,threshold默认保存原图。thresh和maxval同为255时灰度处理
//scale浮点型 图片缩放率, 默认为 1.0 原大小。小于1.0缩小,大于1.0放大
//成功返回图像字节格式,失败返回"null"的字节格式

''' 代码示例
//截图并保存到本地磁盘
let imageData = await androidBot.takeScreenshot({scale:0.5});//缩小1倍
let buffer = Buffer.from(imageData);
await fs.writeFileSync("d:\\image.png", buffer);
'''


await androidBot.getColor(x, y);
//获取颜色值
//参数一 整型,横坐标
//参数二 整型,纵坐标
//成功返回#开头的颜色值,失败返回null

await androidBot.findImage(imagePath, options = {});
//找图
//参数一 字符串,小图片路径(手机),多张小图查找应当用"|"分开小图路径
//参数二 JSON类型,可选参数,{{region:[left:number, top:number, right:number, bottom:number], sim:number, threshold:[thresholdType:number, thresh:number, maxval:number]}} options
//region 指定区域找图 [10, 20, 100, 200],region默认全屏
//sim浮点型 图片相似度 0.0-1.0,sim默认0.95
//threshold二值化图片, thresholdType算法类型:
//                                            0   THRESH_BINARY算法,当前点值大于阈值thresh时,取最大值maxva,否则设置为0
//                                            1   THRESH_BINARY_INV算法,当前点值大于阈值thresh时,设置为0,否则设置为最大值maxva
//                                            2   THRESH_TOZERO算法,当前点值大于阈值thresh时,不改变,否则设置为0
//                                            3   THRESH_TOZERO_INV算法,当前点值大于阈值thresh时,设置为0,否则不改变
//                                            4   THRESH_TRUNC算法,当前点值大于阈值thresh时,设置为阈值thresh,否则不改变
//                                            5   ADAPTIVE_THRESH_MEAN_C算法,自适应阈值
//                                            6   ADAPTIVE_THRESH_GAUSSIAN_C算法,自适应阈值
//                                            thresh阈值,maxval最大值,threshold默认保存原图。thresh和maxval同为255时灰度处理
//multi 找图数量,默认为1,找单个图片坐标
//成功返回,单个坐标点 [{x:number, y:number}],多坐标点图[{x1:number, y1:number}, {x2:number, y2:number}...] 失败返回null
//纯黑色小图,有bug?

''' 代码示例
//全屏找图
let imagePath = "/storage/emulated/0/Android/data/com.aibot.client/files/1.png";
await androidBot.findImage(imagePath);

//区域+模糊 找图,区域起始坐标位置(10, 15),右下角坐标位置(100, 100)。图片相似度设置为95%
let options = {region:[10, 15, 100, 100], sim:0.95};
await androidBot.findImage(imagePath, options);

//二值化,使用THRESH_BINARY算法,阈值127 最大值255。二值化找图需要在截图工具设置相同的算法、阈值和最大值
let options = {threshold:[0, 127, 255]};
await androidBot.findImage(imagePath, options);

//找多张相同图片坐标,返回坐标数组
let options = {multi:3};
await androidBot.findImage(imagePath, options);
'''


await androidBot.findAnimation(frameRate, options = {});
//找动态图
//参数一 整型,前后两张图相隔的时间,单位毫秒
//参数二 JSON类型,可选参数,{{region:[left:number, top:number, right:number, bottom:number]}} options
//region 指定区域找图 [10, 20, 100, 200],region默认全屏
//成功返回,单个坐标点 [{x:number, y:number}],多坐标点图[{x1:number, y1:number}, {x2:number, y2:number}...] 失败返回null

''' 代码示例
//在100毫秒内找出图片内变化的位置,其他参数参考findImage函数
await androidBot.findAnimation(100);
'''


await androidBot.findColor(mainColor, options = {});
//找色
//参数一 字符串,#开头的色值
//参数二 JSON类型,可选参数,{{subColors:[[offsetX:number, offsetY:number, strSubColor:string], ...], region:[left:number, top:number, right:number, bottom:numbe], sim:number}} options
//subColors 相对于mainColor 的子色值,[[offsetX, offsetY, "#FFFFFF"], ...],subColors默认为null
//region 指定区域找图 [10, 20, 100, 200],region默认全屏
//sim相似度0.0-1.0,sim默认为1
//成功返回{x:number, y:number} 失败返回null

''' 代码示例
//指定区域+模糊 找色。区域起始坐标位置(10, 20),右下角坐标位置(100, 200)。颜色相似度设置为95%
let mainColor = "#ffff00";
let options = {region:[10, 20, 100, 200], sim:0.95};
await androidBot.findColor(mainColor, options);

//多点区域找色。区域起始坐标位置(10, 20),右下角坐标位置(100, 200)。主颜色与3个子颜色 点的偏移坐标点。偏移点的计算(子颜色坐标点-主颜色坐标点)
let mainColor = "#ffff00";
let options = {region:[10, 20, 100, 200], subColors:[[8, 2, "#a09588"], [9, 5, "#ffffff"], [10, 6, "#ffdc92"]]};
await androidBot.findColor(mainColor, options);
'''


await androidBot.compareColor(mainX, mainY, mainColor, options = {});
//比色
//参数一 整型,主颜色所在的X坐标
//参数二 整型,主颜色所在的Y坐标
//参数三 字符串,#开头的色值
//参数四 JSON类型,可选参数,{{subColors:[[offsetX:number, offsetY:number, strSubColor:string], ...], region:[left:number, top:number, right:number, bottom:number], sim:number}} options
//subColors 相对于mainColor 的子色值,[[offsetX, offsetY, "#FFFFFF"], ...],subColors默认为null
//region 指定区域找图 [10, 20, 100, 200],region默认全屏
//sim相似度0.0-1.0,sim默认为1
//成功返回true 失败返回 false

''' 代码示例
//多点+模糊比色,主颜色值"#ffff00" 坐标位置(100,150)。主颜色与3个子颜色 点的偏移坐标点。偏移点的计算(子颜色坐标点-主颜色坐标点)。颜色相似度98%
let options = {subColors:[[8, 2, "#a09588"], [9, 5, "#ffffff"], [10, 6, "#ffdc92"]], sim:0.98};
await androidBot.compareColor(100, 150, "#ffff00", options);
'''

OCR系统

await androidBot.initOcr(ocrServerIp, options = {});
//初始化ocr服务
//参数一 字符串型,ocr服务IP或域名。端口固定 9527。当参数值为 "127.0.0.1"时,则使用手机内置的ocr识别,不必打开ppocr.exe服务端
//参数二 JSON类型,可选参数,{useAngleModel:boolean, enableGPU:boolean, enableTensorrt:boolean}  仅外部OCR ocrServer ppocr.exe有效
//useAngleModel 支持图像旋转。 默认false
//enableGPU 启动GPU 模式。默认false 。GPU模式需要电脑安装NVIDIA驱动,并且到群文件下载对应cuda版本
//enableTensorrt 启动加速,仅 enableGPU = true 时有效,默认false 。图片太大可能会导致GPU内存不足

await androidBot.findWords(words, options = {})
//找字
//参数一 字符串类型,要查找的文字
//参数二 JSON类型,可选参数 {region:[left:number, top:number, right:number, bottom:number], scale:number}} options
//region 指定区域 [10, 20, 100, 200],region默认全屏
//threshold二值化图片, thresholdType算法类型:
//                                          0   THRESH_BINARY算法,当前点值大于阈值thresh时,取最大值maxva,否则设置为0
//                                          1   THRESH_BINARY_INV算法,当前点值大于阈值thresh时,设置为0,否则设置为最大值maxva
//                                          2   THRESH_TOZERO算法,当前点值大于阈值thresh时,不改变,否则设置为0
//                                          3   THRESH_TOZERO_INV算法,当前点值大于阈值thresh时,设置为0,否则不改变
//                                          4   THRESH_TRUNC算法,当前点值大于阈值thresh时,设置为阈值thresh,否则不改变
//                                          5   ADAPTIVE_THRESH_MEAN_C算法,自适应阈值
//                                          6   ADAPTIVE_THRESH_GAUSSIAN_C算法,自适应阈值
//                    thresh阈值,maxval最大值,threshold默认保存原图。thresh和maxval同为255时灰度处理
//图片缩放率, 默认为 1.0 原大小。大于1.0放大,小于1.0缩小,不能为负数。
//成功功返回数组[{x:number, y:number}, ...],文字所在的坐标点, 失败返回null

''' 代码示例
//区域找字
await androidBot.findWords("rpa", {region:[10, 20, 100, 200]});

//二值化处理后找字
await androidBot.findWords('rpa', {threshold:[0, 100, 255]});
'''


await androidBot.getWords(options = {})
//获取屏幕文字
//参数一 JSON类型,可选参数 {region:[left:number, top:number, right:number, bottom:number], scale:number}} options
//region 指定区域 [10, 20, 100, 200],region默认全屏
//threshold二值化图片, thresholdType算法类型:
//                                          0   THRESH_BINARY算法,当前点值大于阈值thresh时,取最大值maxva,否则设置为0
//                                          1   THRESH_BINARY_INV算法,当前点值大于阈值thresh时,设置为0,否则设置为最大值maxva
//                                          2   THRESH_TOZERO算法,当前点值大于阈值thresh时,不改变,否则设置为0
//                                          3   THRESH_TOZERO_INV算法,当前点值大于阈值thresh时,设置为0,否则不改变
//                                          4   THRESH_TRUNC算法,当前点值大于阈值thresh时,设置为阈值thresh,否则不改变
//                                          5   ADAPTIVE_THRESH_MEAN_C算法,自适应阈值
//                                          6   ADAPTIVE_THRESH_GAUSSIAN_C算法,自适应阈值
//                    thresh阈值,maxval最大值,threshold默认保存原图。thresh和maxval同为255时灰度处理
//图片缩放率, 默认为 1.0 原大小。大于1.0放大,小于1.0缩小,不能为负数。
//成功返回手机上的文字, 失败返回null

YOLO目标检测

await androidBot.initYolo(yoloServerIp, modelPath, classesPath);
//初始化yolo服务
//参数一 字符串型,ocr服务IP或域名。固定9528。
//参数二 字符串型,模型路径
//参数三 字符串型,种类路径,CPU模式需要此参数
//成功返回true,失败返回false

await androidBot.yolo(options = {});
//yolo目标检测
//参数一 JSON类型,可选参数 {region:[left:number, top:number, right:number, bottom:number], scale:number}} options
//region 指定区域 [10, 20, 100, 200],region默认全屏。区域设置应当和训练时区域一致
//图片缩放率, 默认为 1.0 原大小。大于1.0放大,小于1.0缩小,不能为负数。缩放设置应当和训练时缩放一致
//失败返回null,成功返回数组形式的识别结果。 0~3目标矩形位置  4目标类别  5置信度

点击手势

await androidBot.press(x, y, duration);
//手指按下
//参数一 整型,横坐标
//参数二 整型,纵坐标
//参数三 整型,按下时长,单位毫秒 
//成功返回true 失败返回false

await androidBot.move(x, y, duration);
//手指移动
//参数一 整型,横坐标
//参数二 整型,纵坐标
//参数三 整型,移动时长,单位毫秒 
//成功返回true 失败返回false

await androidBot.release();
//手指抬起
//成功返回true 失败返回false

''' 代码示例
//拖动操作,起始坐标位置(100,150) 拖动至(200, 300), 拖动时间1000毫秒
await androidBot.press(100, 150, 10);
await androidBot.move(200, 300, 1000);
await androidBot.release();
'''


await androidBot.click(x, y);
//点击坐标
//参数一 整型,横坐标
//参数二 整型,纵坐标
//成功返回true 失败返回false

await androidBot.doubleClick(x, y);
//双击坐标
//参数一 整型,横坐标
//参数二 整型,纵坐标
//成功返回true 失败返回false

await androidBot.longClick(x, y, duration);
//长按坐标
//参数一 整型,横坐标
//参数二 整型,纵坐标
//参数三 整型,长按时长,单位毫秒 
//成功返回true 失败返回false

''' 代码示例
//在(100,150)坐标位置 长按3秒
await androidBot.longClick(100, 150, 3000);
'''


await androidBot.swipe(startX, startY, endX, endY, duration);
//滑动坐标
//参数一 整型,起始横坐标
//参数二 整型,起始纵坐标 
//参数三 整型,结束横坐标
//参数四 整型,结束纵坐标
//参数五 整型,滑动时长,单位毫秒 
//成功返回true 失败返回false

''' 代码示例
//滑动屏幕。起始坐标位置(100,150) 滑动至(200, 300), 滑动时间2000毫秒
await androidBot.swipe(100, 150, 200, 300, 2000);
'''


await androidBot.dispatchGesture(gesturePath, duration);
//执行手势
//参数一 JSON类型,手势路径 {[[x:number, y:number], [x1:number, y1:number]...]}
//参数二 整型,手势时长,单位毫秒 
//成功返回true 失败返回false

''' 代码示例
//执行手势,起始坐标位置(100,150) 至(200, 300)最后滑动至(300, 500) 手势时间3000毫秒
let gesturePath = [[100, 150], [200, 300], [300, 500]];
await androidBot.dispatchGesture(gesturePath, 3000);
'''



await androidBot.dispatchGestures(gesturesPath);
//执行多个手势
//参数一 JSON类型,手势路径 {[[duration:number, [x:number, y:number], [x1:number, y1:number]...],[duration:number, [x:number, y:number], [x1:number, y1:number]...],...]}
//duration 为每个手势的时长
//成功返回true 失败返回false

''' 代码示例
//执行多个手势,手势1,起始坐标位置(100,100) 至(200, 200) 手势时间1000毫秒。手势2,起始坐标位置(300,300) 至(500, 500) 手势时间1000毫秒
let gesturesPath = [
    [1000, [100, 100], [200, 200]],
    [1000, [300, 300], [500, 500]]
];
await androidBot.dispatchGestures(gesturesPath);
'''

发送文本

await androidBot.sendKeys(text);
//参数一 字符串类型,发送的文本,需要打开aibote输入法
//成功返回true 失败返回false

发送按键

await androidBot.back();
//成功返回true 失败返回false。权限:无障碍或aibote输入法

await androidBot.home();
//成功返回true 失败返回false。权限:无障碍

await androidBot.recents();
//成功返回true 失败返回false。权限:无障碍

await androidBot.powerDialog();
//成功返回true 失败返回false。权限:无障碍

await androidBot.sendVk(keyCode);
//参数一 整型,发送按键值,需要打开aibote输入法。例如:回车:66 
//按键对照表 https://blog.csdn.net/yaoyaozaiye/article/details/122826340
//成功返回true 失败返回false

''' 代码示例
//发送搜索键
await androidBot.sendVk(84);
'''

启动APP

await androidBot.startApp(name);
//参数一 字符串类型,包名或者app名称
//成功返回true 失败返回false。非Aibote界面时候调用,需要开启悬浮窗

''' 代码示例
//通过名称启动
await androidBot.startApp("aibote");

//通过包名启动
await androidBot.startApp("com.aibot.client");
'''


await androidBot.appIsRunnig("Aibote");
//判断app是否正在运行(无障碍权限开启只判断前台,未开启则包含前后台 是否正在运行)
//参数一 字符串类型,包名或者app名称
//正在运行返回true,否则返回false

await androidBot.getInstalledPackages();
//获取已安装app的包名(不包含系统APP)
//成功返回已安装app包名数组,失败返回null

屏幕大小

await androidBot.getWindowSize();
//成功返回{width:number, height:number}

图片大小

await androidBot.getImageSize(imagePath);
//参数一 字符串类型,图片路径
//成功返回{width:number, height:number}

获取投屏信息

await androidBot.getAndroidId();
//成功返回安卓手机ID

await androidBot.getGroup();
//成功返回投屏组号

await androidBot.getIdentifier();
//成功返回投屏编号

await androidBot.getTitle();
//成功返回投屏标题

URL请求

await androidBot.urlRequest(url, requestType, headers = "null", postData = "null")
//参数一 字符串类型,请求的地址,http:// 或者 https://开头
//参数二 字符串类型,请求类型,GET或者POST
//参数三 字符串类型,可选参数,请求头
//参数四 字符串类型,可选参数,用作POST 提交的数据
//返回请求数据内容

''' 代码示例
//GET请求
await androidBot.urlRequest("https://www.baidu.com/, "GET");

//POST请求
let url = "https://tool.chinaz.com/ajaxsync.aspx?callback=jQuery111308936882726209896_1669640902645";
let requestType = "POST";
let headers = {'Content-Type':'application/x-www-form-urlencoded'};
let postData = "toolbox_urls=www.aibote.com";
await androidBot.urlRequest(url, requestType, JSON.stringify(headers), postData);

//POST请求 postData json格式数据
let url = "http://www.pushplus.plus/send";
let requestType = "POST";
let headers = {
    'Authorization':'Bearer key123456',
    'Content-Type': 'application/json'
};
let token = "123456";
let title = "打卡结果通知";
let postData = `{"token":${token}, "title":${title}}`
await androidBot.urlRequest(url, requestType, JSON.stringify(headers), postData);// 注意参数3和参数4 都是json字符串形式
'''


await androidBot.downloadFile(url, savePath);
//GET 下载url文件
//参数一 字符串类型,文件请求地址
//参数二 字符串类型,安卓文件路径,安卓外部存储根目录 /storage/emulated/0/
//成功返回true,失败返回 false

Toast消息提示

await androidBot.showToast(text, duration)
//参数一 字符串类型,Toast提示的内容
//参数二 整型,显示时长,最大时长3500毫秒
//成功返回true 失败返回false

验证码系统

await androidBot.getCaptcha(filePath, username, password, softId, codeType, lenMin = 0);
//识别验证码
//参数一 字符串类型,图片文件路径
//参数二 字符串类型,用户名
//参数三 字符串类型,密码
//参数四 字符串类型,软件ID
//参数四 字符串类型,图片类型 参考https://www.chaojiying.com/price.html
//参数五 字符串类型,最小位数 默认0为不启用,图片类型为可变位长时可启用这个参数
//返回JSON类型{{err_no:number, err_str:string, pic_id:string, pic_str:string, md5:string}}
//err_no,(数值) 返回代码  为0 表示正常,错误代码 参考https://www.chaojiying.com/api-23.html
//err_str,(字符串) 中文描述的返回信息 
//pic_id,(字符串) 图片标识号,或图片id号
//pic_str,(字符串) 识别出的结果
//md5,(字符串) md5校验值,用来校验此条数据返回是否真实有效

''' 代码示例
//通过超级鹰第三方平台接口,识别验证码。username, password, softId由第三方平台提供
let filePath = "/storage/emulated/0/Android/data/com.aibot.client/files/1.png";
let code = await androidBot.getCaptcha(filePath, "username", "password", "123456", "1902");
if(code["err_no"] == 0)//没有错误信息,输出识别结果
    console.log(code["pic_str"]);
'''


await androidBot.errorCaptcha(username, password, softId, picId);
//识别报错返分
//参数一 字符串类型,用户名
//参数二 字符串类型,密码
//参数三 字符串类型,软件ID
//参数四 字符串类型,图片ID 对应 getCaptcha返回值的pic_id 字段
//返回JSON类型{{err_no:number, err_str:string}}
//err_no,(数值) 返回代码
//err_str,(字符串) 中文描述的返回信息

await androidBot.scoreCaptcha(username, password);
//查询验证码剩余题分
//参数一 字符串类型,用户名
//参数二 字符串类型,密码
//返回JSON类型{{err_no:number, err_str:string, tifen:string, tifen_lock:string}}
//err_no,(数值) 返回代码
//err_str,(字符串) 中文描述的返回信息
//tifen,(数值) 题分
//tifen_lock,(数值) 锁定题分

元素操作

//文本、描述xpath 支持@containsText 和 @containsDesc 模糊定位
await androidBot.getElementRect(xpath);
//获取位置
//参数一 字符串类型,元素路径
//成功返回{left:number, top:number, right:number, bottom:number},失败返回null

await androidBot.getElementDescription(xpath);
//获取元素描述
//参数一 字符串类型,元素路径
//成功返回元素描述内容,失败返回null

await androidBot.getElementText(xpath);
//获取文本
//参数一 字符串类型,元素路径
//成功返回元素内容,失败返回null

''' 代码示例
//遍历xpath 获取所有兄弟节点内容
for(let i = 0; ; i++){
    let text = await androidBot.getElementText(`com.android.settings/android:id=title[${i}]`);//模板字符串
    if(text == null)
        break;

    console.log(text);
}
'''



await androidBot.setElementText(xpath, text);
//设置文本
//参数一 字符串类型,元素路径
//参数一 字符串类型,设置的文本
//成功返回true 失败返回false

await androidBot.clickElement(xpath);
//点击元素
//参数一 字符串类型,元素路径
//成功返回true 失败返回false

''' 代码示例
//相对路径点击元素
let xpath = "com.example.android.notepad/com.example.android.notepad:id=fab_add";
await androidBot.clickElement(xpath);

//文本模糊匹配点击元素
xpath = "com.huawei.android.launcher/android.widget.TextView@containsText=ibote";
await androidBot.clickElement(xpath);

//描述模糊匹配点击元素
xpath = "com.huawei.android.launcher/android.widget.TextView@containsDesc=ibote";
await androidBot.clickElement(xpath);

//描述模糊匹配点击第二个匹配到的元素
xpath = "com.huawei.android.launcher/android.widget.TextView@containsDesc[1]=ibote";
await androidBot.clickElement(xpath);

//注意:如果此视图层次SurfaceView结构通过嵌入了另一个视图层次结构SurfaceView#setChildSurfacePackage,
//则相对路径可能无法识别到resourceId。此时我们应当使用绝对路径、文本路径或类名路径去定位
'''



await androidBot.scrollElement(xpath, direction);
//滚动元素
//参数一 字符串类型,元素路径
//参数二 整型,0 向前滑动, 1 向后滑动
//成功返回true 失败返回false

await androidBot.existsElement(xpath);
//判断元素是否存在
//参数一 字符串类型,元素路径
//成功返回true 失败返回false

await androidBot.isSelectedElement(xpath);
//判断元素是否选中
//参数一 字符串类型,元素路径
//成功返回true 失败返回false

文件传输

await androidBot.pushFile("d:\\1.png", "/storage/emulated/0/1.png");
//上传文件到手机
//参数一 字符串类型,电脑文件路径
//参数二 字符串类型,安卓文件保存路径, 安卓外部存储根目录 /storage/emulated/0/
//媒体文件会自动更新至相册
//成功返回true 失败返回false

await androidBot.pullFile("/storage/emulated/0/1.png", "d:\\1.png");
//拉取文件到电脑
//参数一 字符串类型,安卓文件路径, 安卓外部存储根目录 /storage/emulated/0/
//参数二 字符串类型,电脑文件保存路径

安卓文件操作

await androidBot.writeAndroidFile("/storage/emulated/0/1.txt", "aibote是一款非常优秀的RPA自动化平台", false);
//写入安卓文件
//参数一 字符串类型,安卓文件路径,安卓外部存储根目录 /storage/emulated/0/
//参数二 字符串类型,写入的内容
//参数三 布尔类型,可选参数,是否追加,默认覆盖文件内容
//成功返回true 失败返回false

await androidBot.readAndroidFile("/storage/emulated/0/1.txt");
//读取安卓文件
//参数一 字符串类型,安卓文件路径,安卓外部存储根目录 /storage/emulated/0/
//成功返回文件内容,失败返回 null

await androidBot.deleteAndroidFile("/storage/emulated/0/Android/data/com.aibot.client/files/1.png");
//删除安卓文件
//参数一 字符串类型,安卓文件路径,安卓外部存储根目录 /storage/emulated/0/
//成功返回true 失败返回false

await androidBot.existsAndroidFile("/storage/emulated/0/Android/data/com.aibot.client/files/1.png");
//判断文件是否存在
//参数一 字符串类型,安卓文件路径,安卓外部存储根目录 /storage/emulated/0/
//成功返回true 失败返回false

await androidBot.getAndroidSubFiles("/storage/emulated/0/Android/data/com.aibot.client/files/");
//获取文件夹内的所有文件(不包含深层子目录)
//参数一 字符串类型,安卓文件目录
//成功返回所有子文件名称,失败返回null

await androidBot.makeAndroidDir("/storage/emulated/0/Android/data/com.aibot.client/image1");
//创建安卓文件夹
//参数一 字符串类型,安卓目录
//成功返回true 失败返回false

Intent跳转

//在Aibote界面或者开启悬浮窗才有效
await androidBot.startActivity("android.settings.ACCESSIBILITY_SETTINGS", options = {}});
//Activity 跳转
//参数一 字符串类型,动作,例如 "android.intent.action.VIEW"
//参数二 json对象,可选参数{uri:string, packageName:string, className:string, type:string}
//uri跳转链接,可选参数 例如:打开支付宝扫一扫界面,"alipayqr://platformapi/startapp?saId=10000007"
//ackageName 包名,可选参数 "com.xxx.xxxxx"
//className 类名,可选参数
//type 类型,可选参数
//成功返回true,失败返回 false

''' 代码示例
//跳转到应用详情
await androidBot.startActivity("android.settings.APPLICATION_DETAILS_SETTINGS", {uri:"package:com.taobao.taobao"});
'''


await androidBot.callPhone("10086");
//拨打电话
//参数一 字符串类型,拨打的电话号码
//成功返回true,失败返回 false

await androidBot.sendMsg("10086", "123")
//发送短信
//参数一 字符串类型,发送的电话号码
//参数二 字符串类型,短信内容
//成功返回true,失败返回 false

获取包名/窗口

await androidBot.getActivity();
//成功返回当前activity

await androidBot.getPackage();
//成功返回当前package

安卓剪切板

await androidBot.setClipboardText(text);
//设置剪切板内容
//参数一 字符串型,设置的文本
//成功返回true 失败返回 false

await androidBot.getClipboardText();
//获取剪切板内容,需要打开aibote输入法。
//成功返回剪切板文本,失败返回null

创建脚本控件

await androidBot.createTextView(id, text, x, y, width, height);
//创建TextView控件
//参数一 整型,控件ID,不可与其他控件重复
//参数二 字符串型,控件文本
//参数三 整型,控件在屏幕上x坐标
//参数四 整型,控件在屏幕上y坐标
//参数五 整型,控件宽度
//参数六 整型,控件高度
//成功返回true,失败返回 false

await androidBot.createEditText(id, hintText, x, y, width, height);
//创建EditText控件
//参数一 整型,控件ID,不可与其他控件重复
//参数二 字符串型,提示文本
//参数三 整型,控件在屏幕上x坐标
//参数四 整型,控件在屏幕上y坐标
//参数五 整型,控件宽度
//参数六 整型,控件高度
//成功返回true,失败返回 false

await androidBot.createCheckBox(id, text, x, y, width, height, isSelect);
//创建CheckBox控件
//参数一 整型,控件ID,不可与其他控件重复
//参数二 字符串型,控件文本
//参数三 整型,控件在屏幕上x坐标
//参数四 整型,控件在屏幕上y坐标
//参数五 整型,控件宽度
//参数六 整型,控件高度
//参数七 布尔型,是否勾选
//成功返回true,失败返回 false

await androidBot.createSwitchButton(id, text, x, y, width, height, isChecked);
//创建SwitchButton控件
//参数一 整型,控件ID,不可与其他控件重复
//参数二 字符串型,控件文本
//参数三 整型,控件在屏幕上x坐标
//参数四 整型,控件在屏幕上y坐标
//参数五 整型,控件宽度
//参数六 整型,控件高度
//参数七 布尔型,是否开/关
//成功返回true,失败返回 false

await androidBot.createListText(id, hintText, x, y, width, height, listText);
//创建ListText控件
//参数一 整型,控件ID,不可与其他控件重复
//参数二 字符串型,提示文本
//参数三 整型,控件在屏幕上x坐标
//参数四 整型,控件在屏幕上y坐标
//参数五 整型,控件宽度
//参数六 整型,控件高度
//参数七 字符串数组,列表文本
//成功返回true,失败返回 false

await androidBot.createWebView(id, url, x, y, width, height);
//创建WebView控件
//参数一 整型,控件ID,不可与其他控件重复
//参数二 字符串型,加载的链接
//参数三 整型,控件在屏幕上x坐标,值为-1时自动填充宽高
//参数四 整型,控件在屏幕上y坐标,值为-1时自动填充宽高
//参数五 整型,控件宽度,值为-1时自动填充宽高
//参数六 整型,控件高度,值为-1时自动填充宽高
//成功返回true,失败返回 false

await androidBot.clearScriptControl();
//清除脚本控件
//成功返回true,失败返回 false

await androidBot.getScriptParam();
//获取脚本配置参数,用户点击安卓端 "提交参数"按钮 触发
//成功返回{"id":"text", "id":"isSelect"} 此类对象,失败返回null。

''' 代码示例
//创建TextView 和 EditText 控件
await androidBot.createTextView(100, "输入参数", 10, 10, 400, 200);
await androidBot.createEditText(101, "", 450, 10, 500, 200);

//等待用户提交,获取参数
let retParams = await androidBot.getScriptParam();
param = retParams["101"];
console.log("用户输入的参数是:", param);
'''

hid串口触屏

await androidBot.initHid();
//初始化hid
//成功返回true,失败返回 false。

await androidBot.hidPress(x, y);
//按下
//参数一 整型, 横坐标
//参数二 整型, 纵坐标
//成功返回true 失败返回false

await androidBot.hidMove(x, y, duration);
//移动
//参数一 整型,横坐标
//参数二 整型,纵坐标
//参数三 整型,移动时长
//成功返回true 失败返回false

await androidBot.hidRelease();
//释放
//成功返回true 失败返回false

await androidBot.hidClick(x, y);
//单击
//参数一 整型, 横坐标
//参数二 整型, 纵坐标
//成功返回true 失败返回false

await androidBot.hidDoubleClick(x, y);
//双击
//参数一 整型, 横坐标
//参数二 整型, 纵坐标
//成功返回true 失败返回false

await androidBot.hidLongClick(x, y, duration);
//长按
//参数一 整型,横坐标
//参数二 整型,纵坐标
//参数三 整型,按下时长
//成功返回true 失败返回false

await androidBot.hidSwipe(startX, startY, endX, endY, duration);
//滑动坐标
//参数一 整型,起始横坐标
//参数二 整型,起始纵坐标
//参数三 整型,结束横坐标
//参数四 整型,结束纵坐标
//参数五 整型, 滑动时长
//成功返回true 失败返回false

await androidBot.hidDispatchGesture(gesturePath, duration);
//执行手势
//参数一 JSON类型,手势路径 {[[x:number, y:number], [x1:number, y1:number]...]}
//参数二 整型,手势时长,单位毫秒 
//成功返回true 失败返回false

await androidBot.hidDispatchGestures(gesturePaths);
//执行多个手势
//参数一 JSON类型,手势路径 {[[duration:number, [x:number, y:number], [x1:number, y1:number]...],[duration:number, [x:number, y:number], [x1:number, y1:number]...],...]}
//duration 为每个手势的时长
//成功返回true 失败返回false

await androidBot.hidBack();
//返回
//成功返回true 失败返回false

await androidBot.hidHome();
//home
//成功返回true 失败返回false

await androidBot.hidRecents();
//最近应用列表
//成功返回true 失败返回false

await androidBot.getRotationAngle();
//获取手机旋转角度
//成功手机旋转的角度

关闭连接

await androidBot.closeDriver();

激活Android框架

await androidBot.activateFrame(activateKey);
//参数一 字符串型,激活密钥
//返回激活信息

WindowsBot开发手册

主函数示例

const WindowsBot = require('WindowsBot');//引用WindowsBot模块

//注册主函数
WindowsBot.registerMain(windowsMain, "127.0.0.1", 26678);

/**用作代码提示,windowsMain函数会被多次调用,注意使用全局变量
* @param {WindowsBot} windowsBot
*/
async function windowsMain(windowsBot){
    //设置隐式等待
    await windowsBot.setImplicitTimeout(5000);

    let hwnd = await windowsBot.findWindow(null, "运行");
    await windowsBot.clickElement(hwnd, "Window/Button[2]", 1);
}

注册主函数

WindowsBot.registerMain(windowsMain, "127.0.0.1", 26678);
//参数一 回调函数,要注册的函数,必须含一个参数,用作接收WindowsBot对象
//参数二 字符串型, 脚本所在的地址,传递给WindowsDriver.exe。如果值为 "127.0.0.1"脚本会将参数 ip和port作为启动参数并启动WindowsDriver.exe,否则用户需要手动启动WindowsDriver.exe 并且提供启动参数。
//命令行启动示例:WindowsDriver.exe "192.168.1.88" 26678
//脚本多进程需要指定不同的端口!
//参数三 整型,监听端口, WindowsDriver.exe。默认26678。WindowsDriver.exe会通过ip和port 连接脚本

''' 代码示例
//远程云端部署
WindowsBot.registerMain(windowsMain, "192.168.1.88", 26678);
'''

等待超时

await windowsBot.sleep(3000);
//显示等待
//参数一 整型,等待时间,单位毫秒

await windowsBot.setImplicitTimeout(waitMs, intervalMs = 5);
//隐式等待
//参数一 整型,等待时间,单位毫秒
//参数二 整型,心跳间隔,单位毫秒。可选参数,默认5毫秒
//作用全局,程序起始设置一次即可。并发会影响实际等待时间

查找句柄

await windowsBot.findWindow(className, windowName);
//查找窗口句柄,仅查找顶级窗口,不包含子窗口
//参数一 字符串型,窗口类名
//参数二 字符串型,窗口名
//成功返回窗口句柄,失败返回null

''' 代码示例
//不同的应用中相同窗口类名比较常见,使用类名查找句柄要确保窗口类名唯一性
//通过类名查找句柄
let hwnd = await windowsBot.findWindow("#32770", null);

//通过窗口名称查找句柄
let hwnd = await windowsBot.findWindow(null, "运行");

//通过窗口名称和类名查找句柄
let hwnd = await windowsBot.findWindow("#32770", "运行");
'''


await windowsBot.findWindows(className, windowName);
//查找窗口句柄数组,仅查找顶级窗口,不包含子窗口。className和windowNmae都为null,则返回所有窗口句柄
//参数一 字符串型,窗口类名
//参数二 字符串型,窗口名
//成功返回窗口句柄数组,失败返回null

''' 代码示例
//通过类名查找句柄数组
let hwnds = await windowsBot.findWindow("Chrome_WidgetWin_1", null);
'''


await windowsBot.findSubWindow(curHwnd, className, windowName);
//查找子窗口句柄
//参数一 字符串/整型,当前窗口句柄
//参数二 字符串型,窗口类名
//参数三 字符串型,窗口名
//成功返回窗口句柄,失败返回null

''' 代码示例
//查找指定窗口的子窗口句柄
let hwnd = await windowsBot.findWindow("#32770", "设备投屏1");
let subHwnd = await windowsBot.findSubWindow(hwnd, null, "001  GDBNW19A45831389");
'''


await windowsBot.findParentWindow(curHwnd);
//查找父窗口句柄
//参数一 字符串/整型,当前窗口句柄
//成功返回窗口句柄,失败返回null

await windowsBot.findDesktopWindow();
//查找桌面窗口句柄
//成功返回窗口句柄,失败返回null

获取窗口名称

await windowsBot.getWindowName(hwnd);
//参数一 字符串/整型,窗口句柄
//成功返回窗口名称,失败返回null

窗口操作

await windowsBot.showWindow(hwnd, isShow);
//参数一 字符串/整型,窗口句柄
//参数二 布尔型,显示窗口 true, 隐藏窗口 false
//成功返回true,失败返回false

await windowsBot.setWindowTop(hwnd, isTop);
//设置窗口到最顶层
//参数一 字符串/整型,窗口句柄
//参数二 整型,是否置顶。true置顶, false取消置顶
//成功返回true,失败返回false

await windowsBot.getWindowPos(hwnd);
//获取窗口位置
//参数一 字符串/整型,窗口句柄
//成功返回窗口位置,失败返回null

await windowsBot.setWindowPos(hwnd, left, top, width, height);
//设置窗口位置
//参数一 字符串/整型,窗口句柄
//参数二 整型,左上角横坐标
//参数三 整型,左上角纵坐标
//参数四 整型,窗口宽度
//参数五 整型,窗口高度
//成功返回true,失败返回 false

鼠标键盘

await windowsBot.moveMouse(hwnd, x, y, options = {});
//移动鼠标
//参数一 字符串/整型,窗口句柄
//参数二 整型,横坐标
//参数三 整型,纵坐标
//参数四 JSON类型,可选参数{{mode:boolean, elementHwnd:string|number}} options 操作模式,后台 true,前台 false。默认前台操作。
//如果mode值为true且目标控件有单独的句柄,则需要通过getElementWindow获得元素句柄,指定elementHwnd的值(新板本底层代码会自动获取子窗口句柄)
//总是返回true

''' 代码示例
//前台移动鼠标
await windowsBot.moveMouse(hwnd, 100, 200);

//后台移动鼠标
await windowsBot.moveMouse(hwnd, 100, 200, {mode:true});
'''


await windowsBot.moveMouseRelative(hwnd, x, y, mode = false);
//移动鼠标(相对坐标)
//参数一 字符串/整型,窗口句柄
//参数二 整型,相对横坐标
//参数三 整型,相对纵坐标
//参数四 布尔型,操作模式,后台 true,前台 false。默认前台操作
//总是返回true

await windowsBot.rollMouse(hwnd, x, y, dwData, mode = false);
//滚动鼠标
//参数一 字符串/整型,窗口句柄
//参数二 整型,横坐标
//参数三 整型,纵坐标
//参数四 整型,鼠标滚动次数,负数下滚鼠标,正数上滚鼠标
//参数五 布尔型,操作模式,后台 true,前台 false。默认前台操作
//总是返回true

await windowsBot.clickMouse(hwnd, x, y, msg, options = {});
//鼠标点击
//参数一 字符串/整型,窗口句柄
//参数二 整型,横坐标
//参数三 整型,纵坐标
//参数四 整型,点击类型,单击左键:1 单击右键:2 按下左键:3 弹起左键:4 按下右键:5 弹起右键:6 双击左键:7 双击右键:8
//参数五 JSON类型,可选参数{{mode:boolean, elementHwnd:string|number}} options 操作模式,后台 true,前台 false。默认前台操作。
//如果mode值为true且目标控件有单独的句柄,则需要通过getElementWindow获得元素句柄,指定elementHwnd的值(新板本底层代码会自动获取子窗口句柄)
//总是返回true。

''' 代码示例
//前台单击左键
let hwnd = await windowsBot.findWindow(null, "运行");
await windowsBot.clickMouse(hwnd, 100, 200, 1);

//后台单击左键(目标坐标点没有单独的句柄)
await windowsBot.clickMouse(hwnd, 100, 200, 1, {mode:true});

//后台单击左键(目标坐标点有单独的句柄)
let subHwnd = await windowsBot.getElementWindow(hwnd, "Window/Button[2]"); 
await windowsBot.clickMouse(hwnd, 100, 200, 1, {mode:true, elementHwnd:subHwnd});
'''


await windowsBot.sendKeys(text);
//输入文本
//参数一 字符串型,输入的文本
//总是返回true

await windowsBot.sendKeysByHwnd(hwnd, text);
//后台输入文本(杀毒软件可能会拦截)
//参数一 字符串/整型,窗口句柄,如果目标控件有单独的句柄,需要通过getElementWindow获得句柄
//参数二 字符串型,输入的文本
//总是返回true

''' 代码示例
//后台输入文本(目标坐标点有单独的句柄)
let hwnd = await windowsBot.findWindow(null, "运行");
let subHwnd = await windowsBot.getElementWindow(hwnd, "ComboBox/Edit"); 
await windowsBot.sendKeysByHwnd(subHwnd, "cmd");
'''


await windowsBot.sendVk(bVk, msg);
//输入虚拟键值(VK)
//参数一 整型,VK键值
//参数二 整型,输入类型,按下弹起:1 按下:2 弹起:3
//总是返回true

await windowsBot.sendVkByHwnd(hwnd, bVk, msg);
//后台输入虚拟键值(VK) (杀毒软件可能会拦截)
//参数一 字符串/整型,窗口句柄,如果目标控件有单独的句柄,需要通过getElementWindow获得句柄
//参数二 整型,VK键值
//参数三 整型,输入类型,按下弹起:1 按下:2 弹起:3
//总是返回true。若是后台组合键,可使用sendVk 按下控制键(Alt、Shift、Ctrl...),再组合其他按键

''' 代码示例
//后台输入键盘"A"(目标坐标点有单独的句柄)
let hwnd = await windowsBot.findWindow(null, "运行");
let subHwnd = await windowsBot.getElementWindow(hwnd, "ComboBox/Edit"); 
await windowsBot.sendVkByHwnd(subHwnd, 0x41, 1);
'''

图色操作

await windowsBot.saveScreenshot(hwnd, savePath, options = {});
//截图保存
//参数一 字符串/整型,窗口句柄
//参数二 字符串类型,保存图片路径。
//参数三 JSON类型,可选参数{{region:[left:number, top:number, right:number, bottom:number], threshold:[thresholdType:number, thresh:number, maxval:number], mode:boolean}} options 
//region截图区域 [10, 20, 100, 200], 默认 hwnd对应的窗口
//threshold二值化图片, thresholdType算法类型:
//                                            0   THRESH_BINARY算法,当前点值大于阈值thresh时,取最大值maxva,否则设置为0
//                                            1   THRESH_BINARY_INV算法,当前点值大于阈值thresh时,设置为0,否则设置为最大值maxva
//                                            2   THRESH_TOZERO算法,当前点值大于阈值thresh时,不改变,否则设置为0
//                                            3   THRESH_TOZERO_INV算法,当前点值大于阈值thresh时,设置为0,否则不改变
//                                            4   THRESH_TRUNC算法,当前点值大于阈值thresh时,设置为阈值thresh,否则不改变
//                                            5   ADAPTIVE_THRESH_MEAN_C算法,自适应阈值
//                                            6   ADAPTIVE_THRESH_GAUSSIAN_C算法,自适应阈值
//                                            thresh阈值,maxval最大值,threshold默认保存原图。thresh和maxval同为255时灰度处理
//mode操作模式,后台 true,前台 false。默认前台操作     
//成功返回true,失败返回false

''' 代码示例
//截取窗口全屏,图片保存至d:\\1.png
let savePath = "d:\\1.png";
await windowsBot.saveScreenshot(hwnd, savePath);

//二值化区域截图,区域起始坐标位置(10,20),右下角坐标位置(100,200)。二值化使用THRESH_BINARY算法。阈值127,最大值255
let options = {region:[10, 20, 100, 100], threshold:[0, 127, 255]};
await windowsBot.saveScreenshot(hwnd, savePath, options);
'''


await windowsBot.getColor(hwnd, x, y, mode = false);
//获取指定坐标点的色值
//参数一 字符串/整型,窗口句柄
//参数二 整型,横坐标
//参数三 整型,纵坐标
//参数四 布尔型,操作模式,可选参数,后台 true,前台 false。默认前台操作
//成功返回#开头的颜色值,失败返回null

await windowsBot.findImage(hwndOrBigImagePath, smallImagePath, options = {});
//找图
//参数一 字符串/整型,窗口句柄或者图片路径
//参数二 字符串,小图片路径,多张小图查找应当用"|"分开小图路径
//参数三 JSON类型,可选参数,{{region:[left:number, top:number, right:number, bottom:number], sim:number, threshold:[thresholdType:number, thresh:number, maxval:number], mode:boolean}} options
//region 指定区域找图 [10, 20, 100, 200],region默认 hwnd对应的窗口
//sim浮点型 图片相似度 0.0-1.0,sim默认0.95
//threshold二值化图片, thresholdType算法类型:
//                                            0   THRESH_BINARY算法,当前点值大于阈值thresh时,取最大值maxva,否则设置为0
//                                            1   THRESH_BINARY_INV算法,当前点值大于阈值thresh时,设置为0,否则设置为最大值maxva
//                                            2   THRESH_TOZERO算法,当前点值大于阈值thresh时,不改变,否则设置为0
//                                            3   THRESH_TOZERO_INV算法,当前点值大于阈值thresh时,设置为0,否则不改变
//                                            4   THRESH_TRUNC算法,当前点值大于阈值thresh时,设置为阈值thresh,否则不改变
//                                            5   ADAPTIVE_THRESH_MEAN_C算法,自适应阈值
//                                            6   ADAPTIVE_THRESH_GAUSSIAN_C算法,自适应阈值
//                                            thresh阈值,maxval最大值,threshold默认保存原图。thresh和maxval同为255时灰度处理
//multi 找图数量,默认为1,找单个图片坐标
//mode 操作模式,后台 true,前台 false。默认前台操作   
//成功返回,单个坐标点 [{x:number, y:number}],多坐标点图[{x1:number, y1:number}, {x2:number, y2:number}...] 失败返回null

''' 代码示例
//全屏找图
let smallImagePath = "d:\\1.png";
await windowsBot.findImage(hwnd, smallImagePath);

//区域+模糊 找图,区域起始坐标位置(10, 15),右下角坐标位置(100, 100)。图片相似度设置为95%
let options = {region:[10, 15, 100, 100], sim:0.95};
await windowsBot.findImage(hwnd, smallImagePath, options);

//二值化,使用THRESH_BINARY算法,阈值127 最大值255。二值化找图需要在截图工具设置相同的算法、阈值和最大值
let options = {threshold:[0, 127, 255]};
await windowsBot.findImage(hwnd, smallImagePath, options);

//找多张相同图片坐标,返回坐标数组。
let options = {multi:3};
await windowsBot.findImage(hwnd, smallImagePath, options);
'''


await windowsBot.findAnimation(hwnd, frameRate, options = {});
//找动态图
//参数一 字符串/整型,窗口句柄
//参数二 整型,前后两张图相隔的时间,单位毫秒
//参数三 JSON类型,可选参数,{{region:[left:number, top:number, right:number, bottom:number], mode:boolean}} options
//region 指定区域找图 [10, 20, 100, 200],region默认 hwnd对应的窗口
//mode 操作模式,后台 true,前台 false。默认前台操作   
//成功返回,单个坐标点 [{x:number, y:number}],多坐标点图[{x1:number, y1:number}, {x2:number, y2:number}...] 失败返回null

''' 代码示例
//在100毫秒内找出图片内变化的位置,其他参数参考findImage函数
await windowsBot.findAnimation(hwnd, 100);
'''


await windowsBot.findColor(hwnd, mainColor, options = {});
//查找指定色值的坐标点
//参数一 字符串/整型,窗口句柄
//参数二 字符串,#开头的色值
//参数三 JSON类型,可选参数,{{subColors:[[offsetX:number, offsetY:number, strSubColor:string], ...], region:[left:number, top:number, right:number, bottom:numbe], sim:number, mode:boolean}} options
//subColors 相对于mainColor 的子色值,[[offsetX, offsetY, "#FFFFFF"], ...],subColors默认为null
//region 指定区域找图 [10, 20, 100, 200],region默认 hwnd对应的窗口
//sim相似度0.0-1.0,sim默认为1
//mode 操作模式,后台 true,前台 false。默认前台操作   
//成功返回{x:number, y:number} 失败返回null

''' 代码示例
//指定区域+模糊 找色。区域起始坐标位置(10, 20),右下角坐标位置(100, 200)。颜色相似度设置为95%
let mainColor = "#ffff00";
let options = {region:[10, 20, 100, 200], sim:0.95};
await windowsBot.findColor(hwnd, mainColor, options);

//多点区域找色。区域起始坐标位置(10, 20),右下角坐标位置(100, 200)。主颜色与3个子颜色 点的偏移坐标点。偏移点的计算(子颜色坐标点-主颜色坐标点)
let mainColor = "#ffff00";
let options = {region:[10, 20, 100, 200], subColors:[[8, 2, "#a09588"], [9, 5, "#ffffff"], [10, 6, "#ffdc92"]]};
await windowsBot.findColor(hwnd, mainColor, options);
'''


await windowsBot.compareColor(hwnd, mainX, mainY, mainColor, options = {});
//比较指定坐标点的颜色值
//参数一 字符串/整型,窗口句柄
//参数二 整型,主颜色所在的X坐标
//参数三 整型,主颜色所在的Y坐标
//参数四 字符串,#开头的色值
//参数五 JSON类型,可选参数,{{subColors:[[offsetX:number, offsetY:number, strSubColor:string], ...], region:[left:number, top:number, right:number, bottom:number], sim:number, mode:boolean}} options
//subColors 相对于mainColor 的子色值,[[offsetX, offsetY, "#FFFFFF"], ...],subColors默认为null
//region 指定区域找图 [10, 20, 100, 200],region默认 hwnd对应的窗口
//sim相似度0.0-1.0,sim默认为1
//成功返回true 失败返回 false

''' 代码示例
//多点+模糊比色,主颜色值"#ffff00" 坐标位置(100,150)。主颜色与3个子颜色 点的偏移坐标点。偏移点的计算(子颜色坐标点-主颜色坐标点)。颜色相似度98%
let options = {subColors:[[8, 2, "#a09588"], [9, 5, "#ffffff"], [10, 6, "#ffdc92"]], sim:0.98};
await windowsBot.compareColor(hwnd, 100, 150, "#ffff00", options);
'''


await windowsBot.extractImageByVideo(videoPath, saveFolder, jumpFrame);
//提取视频帧
//参数一 字符串类型, 视频路径
//参数二 字符串类型, 提取的图片保存的文件夹目录
//参数三 整型,jumpFrame 跳帧,默认为1 不跳帧
//成功返回true,失败返回false

await windowsBot.cropImage(imagePath, savePath, left, top, rigth, bottom);
//裁剪图片
//参数一 字符串类型,图片路径
//参数一 字符串类型,裁剪后保存的图片路径
//参数三 整型,裁剪的左上角横坐标
//参数四 整型,裁剪的左上角纵坐标
//参数五 整型,裁剪的右下角横坐标
//参数六 整型,裁剪的右下角纵坐标
//成功返回true,失败返回false

OCR系统

await windowsBot.initOcr(ocrServerIp, options = {});
//初始化ocr服务
//参数一 字符串型,ocr服务IP或域名。固定9527。当参数值为 "127.0.0.1"时 为本地DLL模式,
//根据显卡驱动对应的版本,将 ocr_cuda11.8或者ocr_cuda10.1里面的所有文件,复制到WindowsDriver.exe同级目录下,不必打开ppocr.exe服务端
//参数二 JSON类型,可选参数,{useAngleModel:boolean, enableGPU:boolean, enableTensorrt:boolean}
//useAngleModel 支持图像旋转。 默认false
//enableGPU 启动GPU 模式。默认false 。GPU模式需要电脑安装NVIDIA驱动,并且到群文件下载对应cuda版本
//enableTensorrt 启动加速,仅 enableGPU = true 时有效,默认false 。图片太大可能会导致GPU内存不足

await windowsBot.findWords(hwndOrImagePath, words, options = {})
//找字
//参数一 字符串/整型,窗口句柄或者图片路径
//参数二 字符串类型,要查找的文字
//参数三 JSON类型,可选参数 {region:[left:number, top:number, right:number, bottom:number], threshold:[thresholdType:number, thresh:number, maxval:number], mode:boolean} options
//region 指定区域 [10, 20, 100, 200],region默认全图
//threshold二值化图片, thresholdType算法类型:
//                                          0   THRESH_BINARY算法,当前点值大于阈值thresh时,取最大值maxva,否则设置为0
//                                          1   THRESH_BINARY_INV算法,当前点值大于阈值thresh时,设置为0,否则设置为最大值maxva
//                                          2   THRESH_TOZERO算法,当前点值大于阈值thresh时,不改变,否则设置为0
//                                          3   THRESH_TOZERO_INV算法,当前点值大于阈值thresh时,设置为0,否则不改变
//                                          4   THRESH_TRUNC算法,当前点值大于阈值thresh时,设置为阈值thresh,否则不改变
//                                          5   ADAPTIVE_THRESH_MEAN_C算法,自适应阈值
//                                          6   ADAPTIVE_THRESH_GAUSSIAN_C算法,自适应阈值
//                    thresh阈值,maxval最大值,threshold默认保存原图。thresh和maxval同为255时灰度处理
//mode 操作模式,后台 true,前台 false。默认前台操作, 仅适用于hwnd
//成功功返回数组[{x:number, y:number}, ...],文字所在的坐标点, 失败返回null

''' 代码示例
//后台区域找字
await windowsBot.findWords(hwnd, "rpa", {region:[10, 20, 100, 200], mode:true});

//二值化处理后找字
await windowsBot.findWords(hwnd, 'rpa', {threshold:[0, 100, 255]});
'''


await windowsBot.getWords(hwndOrImagePath, options = {})
//获取屏幕文字
//参数一 字符串/整型,窗口句柄或者图片路径
//参数二 JSON类型,可选参数 {region:[left:number, top:number, right:number, bottom:number], threshold:[thresholdType:number, thresh:number, maxval:number], mode:boolean} options
//region 指定区域 [10, 20, 100, 200],region默认全图
//threshold二值化图片, thresholdType算法类型:
//                                          0   THRESH_BINARY算法,当前点值大于阈值thresh时,取最大值maxva,否则设置为0
//                                          1   THRESH_BINARY_INV算法,当前点值大于阈值thresh时,设置为0,否则设置为最大值maxva
//                                          2   THRESH_TOZERO算法,当前点值大于阈值thresh时,不改变,否则设置为0
//                                          3   THRESH_TOZERO_INV算法,当前点值大于阈值thresh时,设置为0,否则不改变
//                                          4   THRESH_TRUNC算法,当前点值大于阈值thresh时,设置为阈值thresh,否则不改变
//                                          5   ADAPTIVE_THRESH_MEAN_C算法,自适应阈值
//                                          6   ADAPTIVE_THRESH_GAUSSIAN_C算法,自适应阈值
//                    thresh阈值,maxval最大值,threshold默认保存原图。thresh和maxval同为255时灰度处理
//mode 操作模式,后台 true,前台 false。默认前台操作, 仅适用于hwnd
//成功返回手机上的文字, 失败返回null

''' 代码示例
//获取图片上的文字
let words = await windowsBot.getWords("d:\\1.png");
console.log(words);
'''

YOLO目标检测

await windowsBot.initYolo(yoloServerIp, modelPath, classesPath);
//初始化yolo服务
//参数一 字符串型,ocr服务IP或域名。固定9528。当参数值为 "127.0.0.1"时 为本地DLL模式,
//根据显卡驱动对应的版本,将 yolo_cuda11.8或者yolo_cuda10.1里面的所有文件,复制到WindowsDriver.exe同级目录下,不必打开yolov8.exe服务端
//参数二 字符串型,模型路径
//参数三 字符串型,种类路径,CPU模式需要此参数
//成功返回true,失败返回false


await windowsBot.yolo(hwndOrFile, options = {});
//yolo目标检测
//参数一 字符串/整型,窗口句柄或者图片路径
//参数二 JSON类型,可选参数 {region:[left:number, top:number, right:number, bottom:number], mode:boolean} options
//region 指定区域 [10, 20, 100, 200],region默认全图。区域设置应当和训练时区域一致
//mode 操作模式,后台 true,前台 false。默认前台操作, 仅适用于hwnd,文件识别会自动忽略此参数
//失败返回null,成功返回数组形式的识别结果。 0~3目标矩形位置  4目标类别  5置信度

元素操作

await windowsBot.getElementName(hwnd, xpath);
//获取元素名称
//参数一 字符串/整型,窗口句柄。如果是java窗口并且窗口句柄和元素句柄不一致,需要使用getElementWindow获取窗口句柄。
//getElementWindow参数的xpath,Aibote Tool应当使用正常模式下获取的XPATH路径,不要 “勾选java窗口” 复选按钮。对话框子窗口,需要获取对应的窗口句柄操作
//参数二 字符串型,元素路径
//成功返回元素名称,失败返回null

''' 代码示例
//遍历xpath 获取所有兄弟节点name
for(let i = 0; ; i++){
    let text = await windowsBot.getElementName(hwnd, `Pane[2]/Pane/Pane/Pane/Pane[1]/Pane/Pane/Pane/Pane/Pane/Pane/Pane/Pane[2]/List/List/ListItem[${i}]`);//模板字符串
    if(text == null)
        break;

    console.log(text);
}
'''


await windowsBot.getElementValue(hwnd, xpath);
//获取元素文本
//参数一 字符串/整型,窗口句柄
//参数二 字符串型,元素路径
//成功返回元素文本,失败返回null

await windowsBot.getElementRect(hwnd, xpath);
//获取元素矩形大小
//参数一 字符串/整型,窗口句柄。如果是java窗口并且窗口句柄和元素句柄不一致,需要使用getElementWindow获取窗口句柄。
//getElementWindow参数的xpath,Aibote Tool应当使用正常模式下获取的XPATH路径,不要 “勾选java窗口” 复选按钮。对话框子窗口,需要获取对应的窗口句柄操作
//参数二 字符串型,元素路径
//成功返回{left:number, top:number, right:number, bottom:number},失败返回null

await windowsBot.getElementWindow(hwnd, xpath);
//获取元素窗口句柄
//参数一 字符串/整型,窗口句柄
//参数二 字符串型,元素路径
//成功返回窗口句柄,失败返回null

await windowsBot.clickElement(hwnd, xpath, msg);
//点击元素
//参数一 字符串/整型,窗口句柄。如果是java窗口并且窗口句柄和元素句柄不一致,需要使用getElementWindow获取窗口句柄。
//getElementWindow参数的xpath,Aibote Tool应当使用正常模式下获取的XPATH路径,不要 “勾选java窗口” 复选按钮。对话框子窗口,需要获取对应的窗口句柄操作
//参数二 字符串型,元素路径
//参数三 整型,点击类型,单击左键:1 单击右键:2 按下左键:3 弹起左键:4 按下右键:5 弹起右键:6 双击左键:7 双击右键:8
//成功返回true 失败返回 false。如果此函数不能点击,可尝试使用invokeElement函数

await windowsBot.invokeElement(hwnd, xpath);
//执行元素默认操作(一般是点击操作)
//参数一 字符串/整型,窗口句柄。
//参数二 字符串型,元素路径
//成功返回true 失败返回 false。

await windowsBot.setElementFocus(hwnd, xpath);
//设置元素作为焦点
//参数一 字符串/整型,窗口句柄
//参数二 字符串型,元素路径
//成功返回true 失败返回 false

await windowsBot.setElementValue(hwnd, xpath, value);
//设置元素文本
//参数一 字符串/整型,窗口句柄。如果是java窗口并且窗口句柄和元素句柄不一致,需要使用getElementWindow获取窗口句柄。
//getElementWindow参数的xpath,Aibote Tool应当使用正常模式下获取的XPATH路径,不要 “勾选java窗口” 复选按钮。对话框子窗口,需要获取对应的窗口句柄操作
//参数二 字符串型,元素路径
//参数三 字符串型,要设置的内容
//成功返回true 失败返回 false

await windowsBot.setElementScroll(hwnd, xpath, horizontalPercent, verticalPercent);
//滚动元素
//参数一 字符串/整型,窗口句柄
//参数二 字符串型,元素路径(滚动条所属的窗口路径,非滚动条路径)
//参数三 整型,水平百分比 -1不滚动
//参数四 整型,垂直百分比 -1不滚动
//成功返回true 失败返回 false

await windowsBot.isSelected(hwnd, xpath);
//单/复选框是否选中
//参数一 字符串/整型,窗口句柄
//参数二 字符串型,元素路径
//成功返回true 失败返回 false

await windowsBot.closeWindow(hwnd, xpath);
//关闭窗口
//参数一 字符串/整型,窗口句柄。如果是java窗口并且窗口句柄和元素句柄不一致,需要使用getElementWindow获取窗口句柄。
//getElementWindow参数的xpath,Aibote Tool应当使用正常模式下获取的XPATH路径,不要 “勾选java窗口” 复选按钮。对话框子窗口,需要获取对应的窗口句柄操作
//参数二 字符串型,元素路径
//成功返回true 失败返回 false

await windowsBot.setWindowState(hwnd, xpath, state);
//设置窗口状态
//参数一 字符串/整型,窗口句柄。如果是java窗口并且窗口句柄和元素句柄不一致,需要使用getElementWindow获取窗口句柄。
//getElementWindow参数的xpath,Aibote Tool应当使用正常模式下获取的XPATH路径,不要 “勾选java窗口” 复选按钮。对话框子窗口,需要获取对应的窗口句柄操作
//参数二 字符串型,元素路径
//参数三 整型,0正常 1最大化 2 最小化
//成功返回true 失败返回 false

系统剪切板

await windowsBot.setClipboardText(text);
//设置剪切板内容
//参数一 字符串型,设置的文本
//成功返回true 失败返回 false

await windowsBot.getClipboardText();
//获取剪切板内容
//返回剪切板文本

启动进程

await windowsBot.startProcess(commandLine, showWindow = true, isWait = false);
//参数一 字符串型,启动命令行
//参数二 布尔型,是否显示窗口。可选参数,默认显示窗口
//参数三 布尔型,是否等待程序结束。可选参数,默认不等待
//成功返回true,失败返回false

''' 代码示例
//后台启动应用程序
await windowsBot.startProcess("d:\\Aibote\\Aibote.exe",  false, false);

//启动WindowsDriver.exe 指定启动参数
await windowsBot.startProcess("WindowsDriver.exe \"192.168.1.88\" 26672",  true, false);

//启动WindowsDriver.exe 指定启动参数并且等待进程关闭
await windowsBot.startProcess("WindowsDriver.exe \"192.168.1.88\" 26672",  true, true);
'''

执行cmd命令

await windowsBot.executeCommand(command, waitTimeout = 300);
//此函数用于获取cmd执行结果,函数执行完毕会自动关闭启动的相关进程
//参数一 字符串型,cmd命令
//参数二 整型,可选参数,等待结果返回超时,单位毫秒,默认300毫秒
//返回cmd执行结果

''' 代码示例
//执行cmd 等待3000毫秒返回结果
await windowsBot.executeCommand("ping www.baidu.com", 3000);
'''

指定url下载文件

await windowsBot.downloadFile(url, filePath, isWait);
//参数一 字符串型,文件地址
//参数二 字符串型,文件保存的路径
//参数三 布尔型,是否等待.为true时,等待下载完成
//总是返回true

Excel文档

await windowsBot.openExcel(excelPath);
//打开excel文档
//参数一 字符串,excle路径
//成功返回excel对象,失败返回null

await windowsBot.openExcelSheet(excelObject, sheetName);
//打开excel表格
//参数一 对象,excel对象
//参数二 字符串,表名
//成功返回sheet对象,失败返回null

await windowsBot.saveExcel(excelObject);
//保存/关闭excel文档
//参数一 对象,excel对象
//成功返回true,失败返回false

await windowsBot.writeExcelNum(sheetObject, row, col, value);
//写入数字到excel表格
//参数一 对象,sheet对象
//参数二 整型,行
//参数三 整型,列
//参数四 数字型,写入的值
//成功返回true,失败返回false

await windowsBot.writeExcelStr(sheetObject, row, col, strValue);
//写入字串到excel表格
//参数一 对象,sheet对象
//参数二 整型,行
//参数三 整型,列
//参数四 字符串,写入的值
//成功返回true,失败返回false

await windowsBot.readExcelNum(sheetObject, row, col);
//读取excel表格数字
//参数一 对象,sheet对象
//参数二 整型,行
//参数三 整型,列
//返回读取到的数字

await windowsBot.readExcelStr(sheetObject, row, col);
//读取excel表格字串
//参数一 对象,sheet对象
//参数二 整型,行
//参数三 整型,列
//返回读取到的字符

await windowsBot.removeExcelRow(sheetObject, rowFirst, rowLast);
//删除excel表格行
//参数一 对象,sheet对象
//参数二 整型,起始行
//参数三 整型,结束行
//成功返回true,失败返回false

await windowsBot.removeExcelCol(sheetObject, colFirst, colLast);
//删除excel表格列
//参数一 对象,sheet对象
//参数二 整型,起始列
//参数三 整型,结束列
//成功返回true,失败返回false

''' 代码示例
//打开excel
let excelPath = "d:\\1.xlsx";
let excelObject = await windowsBot.openExcel(excelPath);

//打开/创建表
let sheetName = "第1张表";
let sheetObject = await windowsBot.openExcelSheet(excelObject, sheetName);

//写入字符串到第一个表格
await windowsBot.writeExcelStr(sheetObject, 0, 0, "aibote RPA");

//读取第一个表格内容
let text = await windowsBot.readExcelStr(sheetObject, 0, 0);
console.log(text);

//保存/关闭excel。如果再次操作需要重新调用openExcel、openExcelSheet 函数
await windowsBot.saveExcel(excelObject);
'''

验证码系统

await windowsBot.getCaptcha(filePath, username, password, softId, codeType, lenMin = 0);
//识别验证码
//参数一 字符串类型,图片文件路径
//参数二 字符串类型,用户名
//参数三 字符串类型,密码
//参数四 字符串类型,软件ID
//参数四 字符串类型,图片类型 参考https://www.chaojiying.com/price.html
//参数五 字符串类型,最小位数 默认0为不启用,图片类型为可变位长时可启用这个参数
//返回JSON类型{{err_no:number, err_str:string, pic_id:string, pic_str:string, md5:string}}
//err_no,(数值) 返回代码  为0 表示正常,错误代码 参考https://www.chaojiying.com/api-23.html
//err_str,(字符串) 中文描述的返回信息 
//pic_id,(字符串) 图片标识号,或图片id号
//pic_str,(字符串) 识别出的结果
//md5,(字符串) md5校验值,用来校验此条数据返回是否真实有效

''' 代码示例
//通过超级鹰第三方平台接口,识别验证码。username, password, softId由第三方平台提供
let filePath = "d:\\1.png";
let code = await androidBot.getCaptcha(filePath, "username", "password", "123456", "1902");
if(code["err_no"] == 0)//没有错误信息,输出识别结果
    console.log(code["pic_str"]);
'''


await windowsBot.errorCaptcha(username, password, softId, picId);
//识别报错返分
//参数一 字符串类型,用户名
//参数二 字符串类型,密码
//参数三 字符串类型,软件ID
//参数四 字符串类型,图片ID 对应 getCaptcha返回值的pic_id 字段
//返回JSON类型{{err_no:number, err_str:string}}
//err_no,(数值) 返回代码
//err_str,(字符串) 中文描述的返回信息

await windowsBot.scoreCaptcha(username, password);
//查询验证码剩余题分
//参数一 字符串类型,用户名
//参数二 字符串类型,密码
//返回JSON类型{{err_no:number, err_str:string, tifen:string, tifen_lock:string}}
//err_no,(数值) 返回代码
//err_str,(字符串) 中文描述的返回信息
//tifen,(数值) 题分
//tifen_lock,(数值) 锁定题分

自然语言处理(NLP)

初始化NLP

await windowsBot.initNLP(aipKey);
//初始化NLP
//参数一 字符串型,chatgpt API密钥。
//成功返回true,失败返回false

chatgpt的使用

await windowsBot.chatgpt(model, promptOrMessages, maxTokens, temperature, stop = "");
//使用chatgpt
//参数一 字符串型,指定使用的模型,"gpt-3.5-turbo"、"text-davinci-003"、text-curie-001、text-babbage-001、text-ada-001和自定义微调模型
//参数二 字符串型,提出的问题,当model = "gpt-3.5-turbo"时,提问格式必须为 '[{"role": "user", "content": "你好!"}]' 。role 角色,content 问题内容
//参数三 最大令牌书,大约 3个字符1个令牌,1个汉字2个令牌
//参数四 浮点型,调节结果的创意程度,0为单一结果, 1创意度更高
//参数五 字符串型,可选参数,停止结果输出标志,一般用在微调模型上,例如 stop = '["END"]'
//返回json类型,{{text:string, finish:boolean} || null}
//text 返回的答案内容
//finish 为true回答结束,false 还有未输出的答案。我们可以继续 promptOrMessages + 输出的答案 获取后续内容,直到finish为true

await windowsBot.chatgptEdit(model, input, instruction, maxTokens, temperature);
//使用chatgpt编辑模式
//参数一 字符串型,指定使用的模型,"text-davinci-edit-001"、"code-davinci-edit-001"
//参数二 字符串型,要编辑的文本
//参数三 字符串型,提示如何去编辑修改
//参数四 最大令牌书,大约 3个字符1个令牌,1个汉字2个令牌
//参数五 浮点型,调节结果的创意程度,0为单一结果, 1创意度更高
//返回json类型,{{text:string, finish:boolean} || null}
//text 返回的答案内容
//finish 为true回答结束,false 还有未输出的答案。我们可以继续 prompt + 输出的答案 获取后续内容,直到finish为true

''' 代码示例
//初始化
let bRet = await windowsBot.initNLP("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
if(!bRet)
    return ;

//chatgpt
let result = await windowsBot.chatgpt("gpt-3.5-turbo", '[{"role": "学生", "content": "同学你好!"}]', 256, 0.7);
console.log(result["text"]);

//chatgpt 循环获取答案
let prompt = "请介绍下Aibote的应用场景,不少于500字";
let isFinish;
do{
    let result = await windowsBot.chatgpt("text-davinci-003", prompt, 256, 0.7);
    isFinish = result["finish"];
    if(!isFinish)
        prompt += result["text"];

    console.log(result["text"]);
}while(!isFinish)

//chatgptEdit
let result = await windowsBot.chatgptEdit("text-davinci-edit-001", "你好码?","修正错误文字" 256, 0);
console.log(result["text"]);
'''

训练模型

await windowsBot.createFineTune(fileId, baseModel, suffix);
//创建微调模型
//参数一 字符串型,文件id,可通过 uploadTrainFile函数上传并获取文件id
//参数二 字符串型,基础模型,可以是以下参数之一,"ada", "babbage", "curie", "davinci"和自定义微调模型
//参数三 字符串型  微调生成的模型名称后缀,不建议使用中文
//成功返回微调id,失败返回null

await windowsBot.listFineTunes();
//列出所有微调信息
//返回json对象数组 {[{baseModel:string, object:string, fineTuneId:string, fineTunedModel:string, fineTuneStatus:string, fileName:string, fileId:strinig, fileStatus:string}, ...] || null}
//baseModel 基础模型,一般是"ada", "babbage", "curie", "davinci"
//object 
//fineTuneId 微调id
//fineTunedModel 微调模型的名称
//fineTuneStatus 正在微调模型的进度状态
//fileName 训练数据文件的名称
//fileId 训练数据文件的id
//fileStatus 训练数据文件的状态

await windowsBot.listFineTune(fineTuneId);
//获取指定微调id的详细信息
//参数一 字符串型 微调id
//返回json对象 {{baseModel:string, fineTuneCosts:string, fineTunedModel:string, fineTuneStatus:string, fileName:string, fileId:string,  fileStatus:string} || null} 
//baseModel 基础模型,一般是"ada", "babbage", "curie", "davinci"
//fineTuneCosts 训练该模型消耗的$
//fineTunedModel 微调模型的名称
//fineTuneStatus 正在微调模型的进度状态
//fileName 训练数据文件的名称
//fileId 训练数据文件的id
//fileStatus 训练数据文件的状态

await windowsBot.cancelFineTune(fineTuneId);
//取消正在微调的作业
//参数一 字符串型, 微调id
//成功返回true,失败返回false

await windowsBot.deleteFineTuneModel(fineTuneId);
//删除微调模型
//参数一 字符串型, 微调id
//成功返回true,失败返回false

训练数据文件

await windowsBot.uploadTrainFile(filePath);
//上传训练文件到服务器
//参数一 字符串型, 文件路径,不支持中文路径
//成功返回文件id,失败返回null

await windowsBot.listTrainFiles();
//列出所有训练文件信息
//返回json对象数组 {Promise.<[{bytes:number, fileName:string, fileId:string, purpose:string}] || null>}
//bytes 训练数据文件的大小
//fileName 训练数据文件的名称
//fileId 训练数据文件的id
//purpose 文件的意图 例如:"fine-tune" 意图为 用作微调模型

await windowsBot.listTrainFile(fileId);
//参数一 字符串型, 文件id
//返回json对象 {Promise.<{bytes:number, fileName:string, fileId:string, purpose:string} || null>}
//bytes 训练数据文件的大小
//fileName 训练数据文件的名称
//fileId 训练数据文件的id
//purpose 文件的意图 例如:"fine-tune" 意图为 用作微调模型

await windowsBot.downloadTrainFile(fileId);
//下载训练文件内容
//参数一 字符串型, =文件id
//成功返回文件内容,失败返回null

await windowsBot.deleteTrainFile(fileId);
//删除训练文件
//参数一 字符串型, =文件id
//成功返回文件内容,失败返回null

自然语言处理(NLP)使用指南

Chatgpt

//模型种类
"text-ada-001"      用途:分析文本、简单分类、地址更正、关键字  (速度最快、成本低)
"text-babbage-001"  用途:中等分类、语义搜索分类               (速度快、成本较低低)
"text-curie-001"    用途:语言翻译、复杂分类、文本情绪、摘要    (功能强大)
"text-davinci-003"  用途:复杂的意图、因果关系、受众摘要        (功能最强大,速度慢,费用高,包含上面所有模型的功能。建议使用此模型)
"gpt-3.5-turbo"     用途:对话                                (速度快、强大、成本低)

"code-cushman-001"  用途:自然语言和代码的生成、注释...         (速度快,功能强大)
"code-davinci-002"  用途:自然语言和代码的生成、注释...         (功能最强大,尤其是杂任务方面更为强大)

//Chatgpt 是由提示(prompt) = 补全完成。
三个基本要素:
1、展示并说明。通过提供说明和示例,明确表示你想要什么。 如果想让模型按字母顺序对项目列表进行排序,或者按情绪对一段话进行分类,请向它展示这就是你的需求。
2、提供优质数据。如果使用分类器或让模型遵循某种模式,请确保提供足够的示例。请务必校对示例,模型通常很聪明,足以发现基本的拼写错误并提供回复,
但它也可能认为你是故意拼错,继而可能会影响到回复的内容。
3、temperature参数调节。 在大多数情况下,temperature设置为 0 或接近 0(0.2)会得到更好的结果。设置为1 或接近1(0.7)结果会更有创意
Chatgpt分类示例
这是一个微博情感分类器

微博:“我喜欢新的蝙蝠侠电影!”
情绪:积极

微博:“我讨厌手机没电了。”
情绪:消极

微博:“我的一天是👍”
情绪:积极

微博:“这是文章的链接”
情绪:中性

微博:“这个新的音乐视频让我大吃一惊”
情绪:

在上面的示例中,有几个值得注意的要点:
1. 使用简明的语言来描述你的输入和输出:我们使用简单明了的语言描述输入“微博”和输出的“情绪”。最佳做法是从简明的语言说明开始。 
虽然通常可以使用简写或关键词来指示输入和输出,但在生成提示时,最好先尽可能描述一下,只要提示的表现一样,就可以反向删除多余的单词。
2. 向API展示如何回应各种情况:在本例中,我们提供多种结果:“积极”、“消极”和“中立”。中立结果很重要,因为在许多情况下,即使是人类也会很难确定某件事是积极还是消极的。
3. 可以使用文本和表情符号:分类器是文本和表情符号 👍 的组合。 API 可以读取表情符号,甚至可以将它们与表达式进行转换。
4. 对于熟悉的任务,需要的示例更少:对于此分类器,我们仅提供少量示例。 这是因为 API 已经理解情绪和微博的概念。 如果要为 API 不熟悉的内容生成分类器,可能需要提供更多示例。

//提高分类器的效率
这是一个微博情感分类器

微博文字
1. “我喜欢新的蝙蝠侠电影!”
2. “我讨厌手机没电了”
3.“我的一天是👍”
4.“这是文章的链接”
5.“这个新的音乐视频让我大吃一惊”

微博情绪评级:
1:正面
2:负面
3:正面
4:中性
5:正面

微博文字
1.“我受不了作业”
2.“这很糟糕。我很无聊😠”
3.“我等不及万圣节了!!!”
4.“我的猫很可爱❤️❤️”
5.“我讨厌巧克力”

微博情绪评级:
1.
Chatgpt生成新的想法示例
涉及教育和虚拟现实的想法

1.虚拟火星
学生们可以通过虚拟现实探索火星,并执行任务来收集和编目他们所看到的东西。

2.

在示例中,我们所要做的就是为 API 提供列表内容的说明和一个示例。 然后用数字 2. 提示 API,指示它是列表的延续。
虽然这个提示非常简单,但有几个细节值得注意:
1. 我们解释了列表的意图。就像分类器一样,我们提前告诉 API 列表的内容。 这可帮助它专注于补全列表,而不是尝试猜测其背后的模式。
2. 我们的示例设置列表其余部分的模式。由于我们提供了一句话的说明,因此 API 将尝试对添加到列表的其余项遵循该模式。 如果想要更详细的回复,则需要从一开始就设置好。
3. 我们通过添加不完整的条目来提示 API。当 API 看到 2. 并且提示突然结束时,它首先会尝试确定在它之后应该出现什么内容。 
由于已经有关于 1 的示例,并为列表提供了标题,因此最明显的回应是继续向列表添加项目。
Chatgpt对话示例
以下是与AI助手的对话。 助理乐于助人、富有创意、聪明而且非常友好。

人类:你好,你是谁?
AI:我是 Aibote 创建的 AI。 今天我能帮到你什么?
人类:

创建能够进行对话的聊天机器人很简单,但有几点值得注意:
1. 我们除了告诉 API 意图,还告诉它该怎么做:与其他提示一样,我们除了向 API 提示示例所代表的意思,另外还增加了一个重要细节:
明确告诉它如何与“这个助手乐于助人、创意无限、聪慧机灵,而且非常友善”这句话进行交互。如果没有明确说明,API 可能会偏离正题、模仿与它互动的人、讽刺别人或做出其他我们想要避免的行为。
2. 我们为 API 提供了一个身份:首先,我们让 API 以 Aibote 创建的 AI 身份进行回复。 虽然 API 没有固有身份,但这有助于它以尽可能接近真实情况的方式进行回复。 
你可以通过其他方式创建其他类型的聊天机器人。 如果告诉 API 以从事生物学研究的女科学家身份回复,你将从该 API 获得经过深思熟虑的、富有见地的评论,该评论与你期望从专业人士那里得到的评论类似。
gpt-3.5-turbo模型的对话示例
[
    {"role":"系统", "content":"你是一位医学专家"},
    {"role":"学生", "content":"吃药会吃傻?不能长期吃药?"}
]

role 指定角色,gpt-3.5-turbo 会根据role寻找相关答案。我们通过系统角色告诉机器人,他是一名医学专家,后面以学生的角色提问。
Chatgpt翻译示例
中文:我不会说英语.
英语:I do not speak French.
中文:回头见!
英文:See you later!
中文: 哪里有好吃的餐厅?
英语: Where is a good restaurant?
中文: 你们有哪些房间?
英语: 
Chatgpt 汇总示例
我十岁的孩子问我这段话是什么意思:
"""
中子星是大质量超巨星坍缩的核心,其总质量在 10 到 25 个太阳质量之间,如果恒星特别富含金属,则可能更多。 [1] 中子星是除黑洞和假想的白洞、夸克星和奇异星之外最小、密度最大的恒星。 
[2] 中子星的半径约为 10 公里(6.2 英里),质量约为 1.4 个太阳质量。 [3] 它们是由大质量恒星的超新星爆炸和引力坍缩相结合产生的,后者将核心压缩到超过白矮星密度,达到原子核的密度。
"""

我用十岁的孩子都能听懂的通俗语言为他改写:
"""

在此示例中,我们将要总结的内容放在三引号之间。 值得注意的是,我们在总结文本之前和之后都解释了我们的意图是什么,以及摘要的目标读者是谁。 这是为了防止 API 在处理大量文本后偏移。
Chatgpt补全示例
垂直农业为本地生产食品、降低运输成本和

机器人会根据上下文补全内容,我们可以降低temperature设置,使 API 更专注于提示的意图;也可以增加temperature,使其偏离正题。
"""
Chatgpt防止虚假回复示例
问:蝙蝠侠是谁?
A:蝙蝠侠是一个虚构的漫画人物。

问:什么是躯干复杂性?
A: ?

问:Devz9 是什么?
A: ?

问:什么绕地球运行?
答:月亮。


问:火星有多少颗卫星?
A:两个,火卫一和火卫二。

问:


API 有很多它从训练数据中学到的知识。 它还能够提供听起来非常真实但实际上是编造的回复。 有两种方法可以限制 API 编造答案的可能性。
1. 为 API 提供一个基本事实:如果你为 API 提供一篇文字来回答相关问题(比如百度百科条目),它就不太可能虚构出一个回复。
2. 使用低概率并向 API 展示如何说“我不知道”:如果 API 知道在不太确定如何回复的情况下说“我不知道”或类似的话语是合适的,它将不太倾向于编造答案。
在此示例中,我们向 API 提供了它知道的问题和答案的示例,然后列举了它不知道的事情并用问号回复。 我们还将概率设置为 0,这样一来,如果有任何疑问,API 就更有可能回复“?”。

ChatgptEdit

//模型种类
"text-davinci-edit-001"  文本编辑模型
"code-davinci-edit-001"  代码编辑模型

//ChatgptEdit是由输入编辑文本(input) + 指令,用那种方式编辑(instruction) = 补全完成。

//示例:
编辑内容(input):
你好码?

提示(instruction):
修正错误文字

结果:
你好吗?

微调模型

//微调基础模型
"ada"       适用于分类型的微调  (速度快、成本低)
"babbage"   (速度较快、成本较低)
"curie"     默认的微调基础模型(速度居中、成本居中、功能强大)
"davinci"   适用于条件类型的微调(速度慢、成本高、功能非常强大)

//数据训练格式。.jsonl格式,UTF-8编码并包含字节顺序标记 (BOM),文件大小不能超过 200 MB。
//训练示例越多越好。 建议至少提供 200 个训练示例。
{"prompt": "<问题>", "completion": "<结果>"}
{"prompt": "<问题>", "completion": "<结果>"}
分类型模型
分类器是最简单的入门模型。 对于分类问题,建议使用 ada,经过微调后,它的性能通常只会比功能更强大的模型稍微差一点,但速度要快得多。 
在分类问题中,数据集中的每个提示都应被划进某个预定义类。 对于这种类型的问题,我们有以下建议:
1、训练"分类器"模型,建议使用ada模型,它通常只会比功能更强大的模型稍微差一点,同时速度更快,成本更低。
2、在提示末尾使用分隔符,例如 \n\n###\n\n。 请记住,在最终向模型发出请求时也要追加此分隔符。
3、选择映射到单个标记的类。 在推理时,请指定 max_tokens=1,因为只需要第一个标记进行分类。
4、确保提示加上完整结果不超过 2048 个标记(包括分隔符)
5、每个类至少 100 个示例
6、确保用于微调的数据集在结构和任务类型上与模型未来的用途非常相近
判断陈述是否真实
{"prompt":"公司:Aibote\n产品:usb投屏\n广告:满足您电脑操控手机的所有需求!\n支持:", "completion":" 是"}
{"prompt":"公司:百度\n产品:-\n广告:数周内矫正牙齿\n支持:", "completion":" 否"}

示例中,使用结构化输入,包含公司名称、产品和关联的广告。 分隔符是 \n支持:,将提示与完整结果分开。 
如果有足够多的示例,无论选择哪个分隔符都不会有很大的差别(通常小于 0.4%),只要分隔符不出现在提示或完整结果中即可。

使用上面的训练模型,"prompt": "公司:Aibote\n产品:usb投屏\n广告:支持电脑操作手机吗?\n支持:"
他会返回 "是"或者"否"
情绪分析
{"prompt":"我买了一台新电脑,好开心啊! ->", "completion":" 积极的"}
{"prompt":"今天考试没通过,难受想哭 ->", "completion":" 消极的"}

分隔符" ->"

使用上面的训练模型,"prompt": "新电脑,真好用! ->"
他会返回 "是"或者"否"
电子邮件分类
{"prompt":"主题: 更新我的地址\n收件人:张三\nTo:123456@qq.com\n日期:2021-06-03\n内容:Hi,\n我想更新我的账单地址以匹配我的送货地址 .\n\n完成后请告诉我。\n\谢谢,\n张三\n\n###\n\n", "completion":"4"}

分隔符"\n\n###\n\n"
条件生成型模型
条件生成指的是需要针对某种给定输入生成内容。 这包括解释、汇总、实体提取、按给定规范编写产品说明、聊天机器人等等。 
对于这种类型的问题有以下建议:

1、在提示末尾使用分隔符,例如 \n\n###\n\n。 请记住,在最终向模型发出请求时也要追加此分隔符。
2、在完整结果末尾时使用结束标记,例如 END。
3、请记住在推理时将结束标记添加为停止序列,例如 stop=[" END"]。
4、至少约 500 个示例。
5、确保prompt+completion不超过 2048 个标记,包括分隔符
6、确保使用高质量示例,并遵循相同的所需格式。
7、请确保用于微调的数据集在结构和任务类型上与模型未来的用途非常相近。
8、对于这些用例,采用较低的学习速率和仅 1-2 个时期往往效果更好。
基于百度百科文章编写具有吸引力的广告
这是一个生成用例,因此需要确保提供高质量的示例,因为微调后的模型将尝试模仿给定示例的样式(和错误)。 可以从大约 500 个示例开始。 示例数据集可能如下所示:
{"prompt":"Samsung Galaxy Feel\nSamsung Galaxy Feel 是三星电子专为日本市场开发的安卓智能手机。该手机于 2017 年 6 月发布,由 NTT Docomo 销售。它运行在 Android 7.0 (Nougat) ,
具有 4.7 英寸显示屏和 3000 mAh 电池。\n软件\nSamsung Galaxy Feel 在 Android 7.0 (Nougat) 上运行,但稍后可以更新到 Android 8.0 (Oreo)。\n硬件\nSamsung Galaxy Feel 具有 4.7 
英寸 Super AMOLED 高清显示屏,16 MP 后置摄像头和 5 MP 前置摄像头。它配备 3000 mAh 电池、1.6 GHz 八核 ARM Cortex-A53 CPU 和 ARM Mali-T830 MP1 700 MHz GPU。它配备 32GB 内存
内部存储,可通过 microSD 扩展至 256GB。除了其软件和硬件规格外,三星还在手机外壳上引入了一个独特的孔,以适应日本人对手机个性化的偏好。Galaxy Feel 的电池也被吹捧为主要的 卖点,
因为市场有利于手 ts 电池寿命更长。 该设备还防水,并使用单独出售的天线支持 1seg 数字广播。\n\n###\n\n", "completion":" 正在寻找一款可以做到这一切的智能手机? 三星 Galaxy Feel 
就是您的不二之选! 我们最新的智能手机采用纤薄时尚的设计,具有高质量的图片和视频功能,以及屡获殊荣的电池寿命。 END}
实体提取
这类似于语言转换任务。 为了提高性能,最好将不同的提取实体按字母顺序或按它们在原文中出现的顺序排序。 这样能帮助模型跟踪需要按顺序生成的所有实体。 数据集可能如下所示:
{"prompt":"葡萄牙将从周二起从英国的绿色旅行名单中删除,原因是冠状病毒病例不断上升,并且担心“所谓的印度变种的尼泊尔突变”。它将加入琥珀名单,这意味着度假者 不应访问,返回者必须隔离 10 天...\n\n###\n\n", "completion":" 葡萄牙\n英国\n尼泊尔突变\n印度变种 END"}
聊天机器人
聊天机器人通常包含有关对话的相关上下文(订单详细信息)、到目前为止的会话摘要以及最新消息。 
在此用例中,相同的对话记录可以在数据集中为每个代理(每次使用略有不同的上下文)生成多行内容以作为完整结果。 
此用例需要几千个示例,因为可能要处理不同类型的请求和客户问题。 为了确保优质的效果,我们建议审核对话示例以确保代理消息的质量。 可使用单独的文本转换微调模型生成摘要。 
数据集可能如下所示:

{"prompt":"摘要: <Aibote有哪些产品>\n\n具体信息:<介绍下 Aibote 自动化框架>\n\n###\n\n客户: <Aibote 支持哪些平台自动化?>\n机器人: <支持web+Android+windows>\n客户: <Android支持元素定位吗?>\n机器人:", "completion":" <支持的,我们还支持xpath算法定位>\n"}
{"prompt":"摘要: <Aibote 有哪些产品>\n\n具体信息:<介绍下 Aibote 自动化框架>\n\n###\n\n客户: <Aibote 支持哪些平台自动化?>\n机器人: <支持web+Android+windows>\n客户: <Android支持元素定位吗?>\n机器人: 
<支持的,我们还支持xpath算法定位>\n客户: <执行速度如何?>\n机器人:", "completion":" <速度非常快要,100ms以内>\n"}

聊天机器人通常包含有关对话的相关上下文(订单详细信息)、到目前为止的会话摘要以及最新消息。 在此用例中,相同的对话记录可以在数据集中为每个代理(每次使用略有不同的上下文)生成多行内容以作为完整结果。 
此用例需要几千个示例,因为可能要处理不同类型的请求和客户问题。 为了确保优质的效果,我们建议审核对话示例以确保代理消息的质量。 可使用单独的文本转换微调模型生成摘要。 数据集可能如下所示:
属性列表生成产品描述
{"prompt":"商品为手提包。颜色为军绿色。价格中等。尺寸偏小。->", "completion":" 这款时尚的绿色小手提包将为您的装扮增添独特的气息,而且不会花费您一大笔钱。"}
开放式生成型模型
对于这种类型的问题,我们有以下建议:

1、将提示留空。
2、无需使用任何分隔符。
3、你通常需要大量示例,至少几千个。
4、确保示例涵盖预期范围或所需语调

{"prompt":"", "completion":" 啊哈,今天天气真不错"}
类似的技术可用于创建一个虚拟角色,该角色具有特定个性、说话风格和谈论的主题。

Tokens(代币)计算:

计算链接:https://platform.openai.com/tokenizer

语音合成/识别服务

初始化语音服务

//数字人使用费用改为免费,此函数弃用
// await windowsBot.activateSpeechService(activateKey);
// //激活 initSpeechService 语音服务(不支持win 7系统)
// //参数一 字符串型,激活密钥。需联系管理员
// //成功返回true,失败返回false

await windowsBot.initSpeechService(speechKey, speechRegion);
//初始化语音服务(不支持win 7系统)
//参数一 字符串型,微软语音API密钥。
//参数二 字符串型,区域
//总是返回true

语音识别

await windowsBot.audioFileToText(filePath, language);
//音频文件转文本
//参数一 字符串型,音频文件路径
//参数二 字符串型,语言
//成功返回转换后的音频文本,失败返回null

await windowsBot.microphoneToText(language);
//麦克风输入音频换文本
//参数一 字符串型,语言
//成功返回转换后的音频文本,失败返回null

合成语音

await windowsBot.textToBullhorn(ssmlPathOrText, language, voiceName);
//文本合成语音输出到扬声器播放
//参数一 字符串型,要转换语音的文本或者".ssml"格式文件路径
//参数二 字符串型,语言
//参数三 字符串型,发音人
//成功返回true,失败返回false

await windowsBot.textToAudioFile(ssmlPathOrText, language, voiceName, audioPath);
//文本合成语音保存到本地音频文件
//参数一 字符串型,要转换语音的文本或者".ssml"格式文件路径
//参数二 字符串型,语言
//参数三 字符串型,发音人
//参数四 字符串型,保存音频文件路径,后缀必须为".mp3"或者".wav"
//成功返回true,失败返回false

语音翻译

await windowsBot.microphoneTranslationText(sourceLanguage, targetLanguage);
//麦克风音频翻译成目标语言文本
//参数一 字符串型,要翻译的语言
//参数二 字符串型,翻译后的语言
//成功返回翻译后的语言文本,失败返回null

await windowsBot.audioFileTranslationText(audioPath, sourceLanguage, targetLanguage);
//音频文件翻译成目标语言文本
//参数一 字符串型,要翻译的音频文件路径
//参数二 字符串型,要翻译的语言
//参数三 字符串型,翻译后的语言
//成功返回翻译后的语言文本,失败返回null

语言和发音人

语音转文本:每小时音频 ¥10
文本转语音:每50万个字符 ¥100

语言:
     * 中文(普通话,简体):"zh-cn"
     * 中文(粤语,简体):"yue-CN"
     * 英语(美国):"en-US"
     * 英语(英国):"en-GB"

发音人:
* 中文(普通话,简体):
     * 晓辰:zh-cn-XiaochenNeural(女)
     * 晓涵:zh-cn-XiaohanNeural(女)
        * 语音风格:
        * 常规    General
        * 平静    Calm
        * 可怕    Fearful
        * 开朗    Cheerful
        * 怏怏    Disgruntled
        * 严重    Serious
        * 生气    Angry
        * 伤心    Sad
        * 温柔    Gentle
        * 深情    Affectionate
        * 尴尬    Embarrassed

     * 晓梦:zh-cn-XiaomengNeural(女)
        * 语音风格:
        * 常规    General
        * 聊天    Chat

     * 晓墨:zh-cn-XiaomoNeural(女)
        * 语音风格:
        * 常规    General
        * 尴尬    Embarrassed
        * 平静    Calm
        * 可怕    Fearful
        * 开朗    Cheerful
        * 怏怏    Disgruntled
        * 严重    Serious
        * 生气    Angry
        * 伤心    Sad
        * 沮丧    Depressed
        * 深情    Affectionate
        * 温柔    Gentle
        * 羡慕    Envious

     * 晓秋:zh-cn-XiaoqiuNeural(女)
     * 晓睿:zh-cn-XiaoruiNeural(女)
        * 语音风格:
        * 常规  General
        * 平静  Calm
        * 可怕    Fearful
        * 生气    Angry
        * 伤心    Sad

     * 晓双:zh-cn-XiaoshuangNeural(女)
        * 语音风格:
        * 常规  General
        * 聊天    Chat

     * 晓晓:zh-cn-XiaoxiaoNeural(女)
        * 语音风格:
        * 常规 General
        * 助理 Assistant
        * 聊天    Chat
        * 顾客服务    Customer Service
        * 新闻    Newscast
        * 深情    Affectionate
        * 生气    Angry
        * 平静    Calm
        * 开朗    Cheerful
        * 怏怏    Disgruntled
        * 可怕    Fearful
        * 温柔    Gentle
        * 抒情    Lyrical
        * 伤心    Sad
        * 严重    Serious
        * 诗歌朗诵    Poetry-reading
        * 友好    Friendly

     * 晓萱:zh-cn-XiaoxuanNeural(女)
        * 语音风格:
        * 常规  General
        * 平静    Calm
        * 可怕    Fearful
        * 开朗    Cheerful
        * 怏怏    Disgruntled
        * 严重    Serious
        * 生气    Angry
        * 温柔    Gentle
        * 沮丧    Depressed

     * 晓颜:zh-cn-XiaoyanNeural(女)
     * 晓伊:zh-cn-XiaoyiNeural(女)
        * 语音风格:
        * 常规  General
        * 生气    Angry
        * 怏怏    Disgruntled
        * 深情    Affectionate
        * 开朗    Cheerful
        * 可怕    Fearful
        * 伤心    Sad
        * 尴尬    Embarrassed
        * 严重    Serious
        * 温柔    Gentle

     * 晓悠:zh-cn-XiaoyouNeural(女)
     * 晓甄:zh-cn-XiaozhenNeural(女)
        * 语音风格:
        * 常规  General
        * 生气    Angry
        * 怏怏    Disgruntled
        * 开朗    Cheerful
        * 可怕    Fearful
        * 伤心    Sad
        * 严重    Serious

     * 云枫:zh-cn-YunfengNeural(男)
        * 语音风格:
        * 常规     General
        * 生气    Angry
        * 怏怏    Disgruntled
        * 开朗    Cheerful
        * 可怕    Fearful
        * 伤心    Sad
        * 严重    Serious
        * 沮丧    Depressed

     * 云皓:zh-cn-YunhaoNeural(男)
        * 语音风格:
        * 常规     General
        * 广告乐观    Advertisement-upbeat

     * 云健:zh-cn-YunjianNeural(男)
        * 语音风格:
        * 常规     General
        * 旁白放松    Narration-relaxed
        * 体育评论    Sports-commentary
        * 体育评论兴奋    Sports-commentary-excited

     * 云夏:zh-cn-YunxiaNeural(男)
        * 语音风格:
        * 常规 General
        * 平静    Calm
        * 可怕    Fearful
        * 开朗    Cheerful
        * 生气    Angry
        * 伤心    Sad

     * 云希:zh-cn-YunxiNeural(男)
        * 语音风格:
        * 常规  General
        * 旁白放松    Narration-relaxed
        * 尴尬    Embarrassed
        * 可怕    Fearful
        * 开朗    Cheerful
        * 怏怏    Disgruntled
        * 严重    Serious
        * 生气    Angry
        * 伤心    Sad
        * 沮丧    Depressed
        * 聊天    Chat
        * 助理    Assistant
        * 新闻    Newscast

     * 云扬:zh-cn-YunyangNeural男)
        * 语音风格:
        * 常规     General
        * 顾客服务    Customer Service
        * 旁白-专业 Narration-professional
        * 新闻广播-休闲 Newscast-casual

     * 云野:zh-cn-YunyeNeural(男)
        * 语音风格:
        * 常规     General
        * 尴尬    Embarrassed
        * 平静    Calm
        * 可怕    Fearful
        * 开朗    Cheerful
        * 怏怏    Disgruntled
        * 严重    Serious
        * 生气    Angry
        * 伤心    Sad

     * 云泽:zh-cn-YunzeNeural(男)
        * 语音风格:
        * 常规     General
        * 平静    Calm
        * 可怕    Fearful
        * 开朗    Cheerful
        * 怏怏    Disgruntled
        * 严重    Serious
        * 生气    Angry
        * 伤心    Sad
        * 沮丧    Depressed
        * 纪录片旁白  Documentary-narration

* 中文(粤语,简体):
     * 晓敏:yue-CN-XiaoMinNeural(女)
     * 云松:yue-CN-YunSongNeural(男)
* 英语(美国):
     * AI1:en-US-AIGenerate1Neural(男)
     * AI2:en-US-AIGenerate2Neural(女)
     * en-US-AmberNeural(女)
     * 安娜:en-US-AnaNeural(女)
     * 阿丽亚:en-US-AriaNeural(女)
     * 阿什莉:en-US-AshleyNeural(女)
     * 布兰登:en-US-BrandonNeural(男)
     * 克里斯托弗:en-US-ChristopherNeural(男)
     * 科拉:en-US-CoraNeural(女)
     * 戴维斯:en-US-DavisNeural(男)
     * 伊丽莎白:en-US-ElizabethNeural(女)
     * 埃里克:en-US-EricNeural(男)
     * 盖伊:en-US-GuyNeural(男)
     * 雅各布:en-US-JacobNeural(男)
     * 简:en-US-JaneNeural(女)
     * 杰森:en-US-JasonNeural(男)
     * 珍妮(多种语言):en-US-JennyMultilingualNeural(女)
     * 珍妮:en-US-JennyNeural(女)
     * 米歇尔:en-US-MichelleNeural(女)
     * 莫妮卡:en-US-MonicaNeural(女)
     * 南茜:en-US-NancyNeural(女)
     * 罗杰:en-US-RogerNeural(男)
     * 莎拉:en-US-SaraNeural(女)
     * 史蒂芬:en-US-SteffanNeural(男)
     * 托尼:en-US-TonyNeural(男)
* 英语(英国):
     * 阿比:en-GB-AbbiNeural(女)
     * 阿尔菲:en-GB-AlfieNeural(男)
     * 贝拉:en-GB-BellaNeural(女)
     * 艾略特:en-GB-ElliotNeural(男)
     * 伊桑:en-GB-EthanNeural(男)
     * 霍莉:en-GB-HollieNeural(女)
     * 利比:en-GB-LibbyNeural(女)
     * 梅西:en-GB-MaisieNeural(女)
     * 诺亚:en-GB-NoahNeural(男)
     * 奥利弗:en-GB-OliverNeural(男)
     * 奥利维亚:en-GB-OliviaNeural(女)
     * 莱恩:en-GB-RyanNeural(男)
     * 索尼娅:en-GB-SoniaNeural(女)
     * 托马斯:en-GB-ThomasNeural(男)

声音克隆

await windowsBot.makeCloneAudio(cloneServerIp, referAudioPath, referText, cloneText, saveAudioPath);
//克隆声音,需要部署服务端
//参数一 字符串型,克隆声音服务端
//参数二 字符串型,参考音频路径,10-40秒,推荐25秒左右的参考音频
//参数三 字符串型,参考音频对应的文本
//参数四 字符串型,要克隆的文本
//参数五 字符串型,保存克隆声音的路径
//成功返回true,失败返回false

await windowsBot.makeCloneLab(labServerIp, audioPath);
//生成lab文件,需要部署服务端
//参数一 字符串型,lab服务端IP
//参数二 字符串型,音频文件
//失败返回false,成功返回true 并生成 与 audioPath 同目录下的 .lab 后缀文件。(音频文件+lab文件可以直接驱动数字人)

虚拟数字人

初始化数字人

await windowsBot.initMetahuman(metahumanModePath,  metahumanScaleWidth, metahumanScaleHeight, isUpdateMetahuman = false);
//初始化数字人
//参数一 字符串型,数字人模型路径。数据人模型需联系管理员训练定制
//参数二 浮点型,数字人宽度缩放倍数,1为原始大小。为2时放大一倍,0.5则缩小一半
//参数三 浮点型,数字人高度缩放倍数,1为原始大小。为2时放大一倍,0.5则缩小一半
//参数四 布尔型,是否强制更新,默认fasle。为true时强制更新会拖慢初始化速度
//成功返回true,失败返回false

切换新的人物形象动作

await windowsBot.switchAction(callApiKey, actionVideoOrImage);
//切换新的人物形象动作,此函数无需训练数字人模型,直接切换各种人物形象动作和场景。
//参数一 字符串型,调用函数的密钥
//参数二 字符串型,闭嘴的人物视频或者图片
//成功返回true,失败返回false。调用不会立刻生效,加载完素材会自动切换。第一帧未识别到人脸返回false

await windowsBot.switchActionBeta(callApiKey, actionVideoOrImage);
//切换新的人物形象动作(测试),此函数无需训练数字人模型,直接切换各种人物形象动作和场景。
//参数一 字符串型,调用函数的密钥
//参数二 字符串型,闭嘴的人物视频或者图片。要求:1、第一帧必须是正脸 2、标准嘴型或与通用嘴型相似
//成功返回true,失败返回false。调用不会立刻生效,加载完素材会自动切换。第一帧未识别到人脸返回false

await windowsBot.getSwitchActionState();
//获取切换人物形象动作状态
//false 表示正在切换,true 切换完成

训练数字人

await windowsBot.trainHumanModel(callApiKey, trainVideoOrImagePath, srcMetahumanModelPath, saveHumanModelFolder);
//训练数字人,训练时长为10-30分钟
//参数一 字符串型,调用函数的密钥
//参数二 字符串型,闭嘴的人物视频或者图片 素材
//参数三 字符串型,预训练数字人模型路径
//参数四 字符串型,保存训练完成的模型目录
//成功返回true,失败返回false

await windowsBot.trainHumanModelBeta(callApiKey, trainVideoOrImagePath, srcMetahumanModelPath, saveHumanModelFolder);
//训练数字人(测试),训练时长为10-30分钟
//参数一 字符串型,调用函数的密钥
//参数二 字符串型,闭嘴的人物视频或者图片 素材。要求:1、第一帧必须是正脸 2、标准嘴型或与通用嘴型相似
//参数三 字符串型,预训练数字人模型路径
//参数四 字符串型,保存训练完成的模型目录
//成功返回true,失败返回false

数字人说话

await windowsBot.metahumanSpeech(saveAudioPath, text, language, voiceName, quality = 0, waitPlaySound = true, speechRate = 0, voiceStyle = "General");
//数字人说话,此函数需要调用 initSpeechService 初始化语音服务
//参数一 字符串型,保存的音频文件路径,扩展为.MP3格式。同名的 .lab文件需要和音频文件在同一目录下
//参数二 字符串型,要转换语音的文本
//参数三 字符串型,语言,参考开发文档 语言和发音人
//参数四 字符串型,发音人,参考开发文档 语言和发音人
//参数五 整型,音质,0低品质  1中品质  2高品质, 默认为0低品质
//参数六 布尔类型,是否等待播报完毕,默认为true 等待
//参数七 整型,语速,默认为0,取值范围 -100 至 200
//参数八 字符串型,语音风格,默认General常规风格,其他风格参考开发文档 语言和发音人
//成功返回true,失败返回false

await windowsBot.metahumanSpeechCache(saveAudioPath, text, language, voiceName, quality = 0, waitPlaySound = true, speechRate = 0, voiceStyle = "General");
//数字人说话内存缓存模式,需要调用 initSpeechService 初始化语音服务。函数一般用于常用的话术播报,非常用话术切勿使用,否则内存泄漏
//参数一 字符串型,保存的音频文件路径,扩展为.MP3格式。同名的 .lab文件需要和音频文件在同一目录下
//参数二 字符串型,要转换语音的文本
//参数三 字符串型,语言,参考开发文档 语言和发音人
//参数四 字符串型,发音人,参考开发文档 语言和发音人
//参数五 整型,音质,0低品质  1中品质  2高品质, 默认为0低品质
//参数六 布尔类型,是否等待播报完毕,默认为true 等待
//参数七 整型,语速,默认为0,取值范围 -100 至 200
//参数八 字符串型,语音风格,默认General常规风格,其他风格参考开发文档 语言和发音人
//成功返回true,失败返回false

await windowsBot.metahumanSpeechByFile(audioPath, waitPlaySound = true);
//数字人说话文件缓存模式
//参数一 字符串型,音频路径, 同名的 .lab文件需要和音频文件在同一目录下。若.lab文件不存在,则自动生成.lab文件。生成.lab文件产生的费用,请联系管理员
//参数二 布尔类型,是否等待播报完毕,默认为true 等待
//成功返回true,失败返回false

await windowsBot.metahumanSpeechBreak();
//打断数字人说话,一般用作人机对话场景。metahumanSpeech和metahumanSpeechCache的 waitPlaySound 参数 设置为false时,此函数才有意义
//返回true打断正在说话, 返回false 则为未说话状态

await windowsBot.metahumanInsertVideo(videoFilePath, audioFilePath, waitPlayVideo = true);
//插入视频到数字人
//参数一 字符串型,插入的视频文件路径
//参数二 字符串型,插入的音频文件路径
//参数三 布尔型,等待视频播放完毕,默认为 true等待
//总是返回true。 此函数依赖 initMetahuman函数运行,否则程序会崩溃

await windowsBot.makeMetahumanVideo(saveVideoFolder, text, language, voiceName, bgFilePath, simValue = 0, voiceStyle = "General", quality = 0, speechRate = 0);
//生成数字人短视频,此函数需要调用 initSpeechService 初始化语音服务
//参数一 字符串型,保存的视频和音频文件目录
//参数二 字符串型,要转换语音的文本
//参数三 字符串型,语言,参考开发文档 语言和发音人
//参数四 字符串型,发音人,参考开发文档 语言和发音人
//参数五 字符串型,数字人背景 图片/视频 路径,扣除绿幕会自动获取绿幕的RGB值,null 则不替换背景。仅替换绿幕背景的数字人模型
//参数六 整型,相似度,默认为0。此处参数用作绿幕扣除微调RBG值。取值应当大于等于0
//参数七 字符串型,语音风格,默认General常规风格,其他风格参考开发文档 语言和发音人
//参数八 整型,音质,0低品质  1中品质  2高品质, 默认为0低品质
//参数九 整型,语速,默认为0,取值范围 -100 至 200
//成功返回true,失败返回false

await windowsBot.makeMetahumanVideoByFile(audioPath, bgFilePath, simValue = 0);
//通过音频文件生成数字人短视频,此函数需要调用 initSpeechService 初始化语音服务
//参数一 字符串型,音频路径, 同名的 .lab文件需要和音频文件在同一目录下
//参数二 字符串型,数字人背景 图片/视频 路径,扣除绿幕会自动获取绿幕的RGB值,null 则不替换背景。仅替换绿幕背景的数字人模型
//参数三 整型,相似度,默认为0。此处参数用作绿幕扣除微调RBG值。取值应当大于等于0
//成功返回true,失败返回false

await windowsBot.makeMetahumanSpeechFile(saveAudioPath, text, language, voiceName, quality = 0, speechRate = 0, voiceStyle = "General");
//生成数字人说话文件,生成MP3文件和 lab文件,提供给 metahumanSpeechByFile 和使用
//参数一 字符串型,保存的音频文件路径,扩展为.MP3格式。同名的 .lab文件需要和音频文件在同一目录下
//参数二 字符串型,要转换语音的文本
//参数三 字符串型,语言,参考开发文档 语言和发音人
//参数四 字符串型,发音人,参考开发文档 语言和发音人
//参数五 整型,音质,0低品质  1中品质  2高品质, 默认为0低品质
//参数六 整型,语速,默认为0,取值范围 -100 至 200
//参数七 字符串型,语音风格,默认General常规风格,其他风格参考开发文档 语言和发音人
//成功返回true,失败返回false

数字人声音克隆

await windowsBot.initSpeechCloneService(apiKey, voiceId);
//初始化数字人声音克隆服务(不支持win 7系统)
//参数一 字符串型,API密钥
//参数二 字符串型,声音ID
//总是返回true

await windowsBot.metahumanSpeechClone(saveAudioPath, text, language, waitPlaySound);
//数字人使用克隆声音说话,此函数需要调用 initSpeechCloneService 初始化语音服务
//参数一 字符串型,保存的发音文件路径。这里是路径,不是目录!
//参数二 字符串型,要转换语音的文本
//参数三 字符串型,语言,中文:zh-cn,其他语言:other-languages 
//参数四 布尔类型,等待音频播报完毕,默认为 true等待
//成功返回true,失败返回false

await windowsBot.makeMetahumanVideoClone(saveVideoFolder, text, language, bgFilePath, simValue = 0);
//使用克隆声音生成数字人短视频,此函数需要调用 initSpeechCloneService 初始化语音服务
//参数一 字符串型,保存的视频和音频文件目录
//参数二 字符串型,要转换语音的文本
//参数三 字符串型,语言,语言,中文:zh-cn,其他语言:other-languages
//参数四 字符串型,数字人背景 图片/视频 路径,扣除绿幕会自动获取绿幕的RGB值,null 则不替换背景。仅替换绿幕背景的数字人模型
//参数五 整型,相似度,默认为0。此处参数用作绿幕扣除微调RBG值。取值应当大于等于0
//成功返回true,失败返回false

await windowsBot.makeMetahumanSpeechFileClone(saveAudioPath, text, language);
//生成数字人说话文件(声音克隆),生成MP3文件和 lab文件,提供给 metahumanSpeechByFile 和使用
//参数一 字符串型,保存的发音文件路径。这里是路径,不是目录!
//参数二 字符串型,要转换语音的文本
//参数三 字符串型,语言,中文:zh-cn,其他语言:other-languages
//成功返回true,失败返回false

数字人背景设置

replaceBackground(bgFilePath, replaceRed = -1, replaceGreen = -1, replaceBlue = -1, simValue = 0);
//替换数字人背景
//参数一 字符串型,数字人背景 图片/视频 路径,默认不替换背景。仅替换绿幕背景的数字人模型
//参数二 整型,数字人背景的三通道之一的 R通道色值。默认-1 自动提取
//参数三 整型,数字人背景的三通道之一的 G通道色值。默认-1 自动提取
//参数四 整型,数字人背景的三通道之一的 B通道色值。默认-1 自动提取
//参数五 整型,相似度。 默认为0,此处参数用作微调RBG值。取值应当大于等于0
//总是返回true。此函数依赖 initMetahuman函数运行,否则程序会崩溃

showSpeechText(originY = 0, fontType = "Arial", fontSize = 30, fontRed = 128, fontGreen = 255, fontBlue = 0, italic = false, underline = false);
//显示数字人说话的文本
//参数一 整型,第一个字显示的起始Y坐标点。 默认0 自适应高度
//参数二 字符串型,字体样式,支持操作系统已安装的字体。例如"Arial"、"微软雅黑"、"楷体"
//参数三 整型,字体的大小。默认30
//参数四 整型,字体颜色三通道之一的 R通道色值。默认128
//参数五 整型,字体颜色三通道之一的 G通道色值。默认255
//参数六 整型,字体颜色三通道之一的 B通道色值。默认0
//参数七 布尔型,是否斜体,默认false
//参数八 布尔型,是否有下划线,默认false
//总是返回true。此函数依赖 initMetahuman函数运行,否则程序会崩溃

获取驱动程序命令行参数

await windowsBot.getExtendParam();
//获取WindowsDriver.exe 命令扩展参数,一般用作脚本远程部署场景,WindowsDriver.exe驱动程序传递参数给脚本服务端
//返回WindowsDriver驱动程序的命令行参数(不包含ip和port)

获取Windows ID

await windowsBot.getWindowsId();
//成功返回Windows 唯一标志

关闭WindowsDriver.exe驱动程序

await windowsBot.closeDriver();

激活Windows框架(包含windowsBot和webBot)

await windowsBot.activateFrame(activateKey);
//参数一 字符串型,激活密钥
//返回激活信息

WebBot开发手册

主函数示例

const WebBot = require('WebBot');//引用WebBot模块

//注册主函数
WebBot.registerMain(webMain, "127.0.0.1", 36678, {browserName:"chrome"});

/**用作代码提示,webMain函数会被多次调用,注意使用全局变量
* @param {WebBot} webBot
*/
async function webMain(webBot){
    //设置隐式等待
    await webBot.setImplicitTimeout(5000);

    await webBot.goto("https://www.baidu.com/");
    await webBot.sendKeys('//*[@id="kw"]', "Aibote\r");
}

注册主函数

WebBot.registerMain(webMain, "127.0.0.1", 36678, {browserName:"chrome"});
//参数一 函数行,要注册的函数,必须含一个参数,用作接收WebBot对象
//参数二 字符串型,脚本所在的地址,传递给WebDriver.exe。如果值为 "127.0.0.1"脚本会将参数 ip和port作为启动参数并启动WebDriver.exe,否则用户需要手动启动WebDriver.exe 并且提供启动参数。
//命令行启动示例:WebDriver.exe "{\"serverIp\":\"127.0.0.1\", \"serverPort\":36678, \"browserName\":\"chrome\", \"debugPort\":0, \"userDataDir\":\"./UserData\", \"browserPath\":\"null\", \"argument\":\"null\", \"extendParam\":\"null\"}"
//参数三 整型,监听端口,传递给WebDriver.exe。脚本多进程需要指定不同的端口
//参数四 json对象,{{browserName:string, debugPort:number, userDataDir:string, browserPath:string, argument:string}} 可选参数
//browserName 浏览器名称,默认 chrome 浏览器。edge和chrome会自动寻找浏览器路径,其他浏览器需要指定browserPath。
//debugPort 调试端口。默认 0 随机端口。指定端口则接管已打开的浏览器。启动浏览器指定的参数 --remote-debugging-port=19222 --user-data-dir=C:\\Users\\电脑用户名\\AppData\\Local\\Google\\Chrome\\User Data
//userDataDir 用户数据目录。多进程同时操作多个浏览器数据目录不能相同。部分操作系统edge浏览器必须指定用户数据目录。第一次指定数据目录路径会进入浏览器欢迎界面,第二次恢复正常操作
//browserPath 浏览器路径
//argument 浏览器启动参数。例如:设置代理:--proxy-server=127.0.0.1:8080  无头模式: --headless   浏览器版本>112 的无头模式:--headless=new,多个启动参数空格隔开
//extendParam 扩展参数,一般用作脚本远程部署场景,WebDriver.exe驱动程序传递参数给脚本服务端。使用 await webBot.getExtendParam(); 函数获取

''' 代码示例
//指定调试端口,接管已打开的浏览器。启动浏览器指定的参数 --remote-debugging-port=19222 --user-data-dir=C:\\Users\\电脑用户名\\AppData\\Local\\Google\\Chrome\\User Data
await WebBot.registerMain(webMain, "127.0.0.1", 36678, {browserName:"chrome", debugPort:19222});//debugPort:19222 必须和 --remote-debugging-port=19222 端口对应

//指定浏览器路径
await WebBot.registerMain(webMain, "127.0.0.1", 36678, {browserName:"360浏览器", browserPath:"D:\\Program Files\\360se.exe"});

//启动参数指定User-Agent
await WebBot.registerMain(webMain, "127.0.0.1", 36678, {browserName:"chrome", argument:"--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"});

//云端远程部署
await WebBot.registerMain(webMain, "192.168.1.88", 36678, {browserName:"chrome"});
'''

等待超时

await webBot.sleep(3000);
//显示等待
//参数一 整型,等待时间,单位毫秒

await webBot.setImplicitTimeout(waitMs, intervalMs = 100);
//隐式等待
//参数一 整型,等待时间,单位毫秒
//参数二 整型,心跳间隔,单位毫秒。可选参数,默认100毫秒
//作用全局,程序起始设置一次即可。并发会影响实际等待时间

页面和导航

await webBot.goto('http://www.ai-bot.net');
//参数一 字符串型,打开指定URL,http://或者 https://开头
//总是返回true

await webBot.newPage('https://www.baidu.com');
//参数一 字符串型,新建tab页面并跳转到指定url
//成功返回true,失败返回false

await webBot.back();
//后退

await webBot.forward();
//前进

await webBot.refresh();
//刷新

await webBot.getCurPageId();
//获取当前页面ID

await webBot.getAllPageId();
//成功返回页面ID数组,失败返回null

await webBot.switchPage(pageId);
//切换指定页面
//参数一 字符串型,要切换的页面ID
//成功返回true,失败返回false。如果失败继续操作,会造成不可知的错误

await webBot.closePage();
//关闭当前页面

await webBot.getCurrentUrl();
//获取URL

await webBot.getTitle();
//获取页面标题

IFrame

await webBot.switchFrame(xpath);
//切换frame
//参数一 字符串型,要切换frame的元素路径。
//成功返回true,失败返回false

''' 代码示例
//切换iframe
let xpath = "/html/body/div[3]/div[3]/div[1]/div/div[3]/div[1]/div[1]/iframe";
await webBot.switchFrame(xpath);
'''


await webBot.switchMainFrame();
//切换主frame,人为关闭/切换页面也需要通过此函数切换到当前页面
//成功返回true,失败返回false

元素操作

await webBot.clickElement(xpath);
//点击元素
//参数一 字符串型,元素路径
//成功返回true 失败返回false

await webBot.setElementValue(xpath, value);
//设置编辑框内容
//参数一 字符串型,元素路径
//参数二 字符串型,输入的值
//成功返回true 失败返回false

await webBot.getElementText(xpath);
//获取文本
//参数一 字符串型,元素路径
//成功返回元素文本内容,一般指元素innerText属性的值,失败返回null

''' 代码示例
//遍历xpath 获取所有兄弟节点内容
for(let i = 1; ; i++){
    let text = await webBot.getElementText(`//*[@id="s-top-left"]/a[${i}]`);//模板字符串
    if(text == null)
        break;

    console.log(text);
}
'''



await webBot.getElementOuterHTML(xpath);
//获取outerHTML
//参数一 字符串型,元素路径
//成功返回元素outerHTML,失败返回null

await webBot.getElementInnerHTML(xpath);
//获取innerHTML
//参数一 字符串型,元素路径
//成功返回元素outerHTML,失败返回null

await webBot.setElementAttribute(xpath, attributeName, value);
//设置属性值
//参数一 字符串型,元素路径
//参数二 字符串型,指定的属性名
//参数三 字符串型,属性值
//成功返回true,失败返回false

await webBot.getElementAttribute(xpath, attributeName);
//获取属性值
//参数一 字符串型,元素路径
//参数二 字符串型,指定的属性名
//成功返回元素属性值,失败返回null

await webBot.getElementRect(xpath);
//获取矩形位置
//参数一 字符串型,元素路径
//返回 {left:number, top:number, right:number, bottom:number, width:number, height:number},失败返回null

await webBot.isSelected(xpath);
//判断该元素是否选中
//参数一 字符串型,元素路径
//返回true 或 false

await webBot.isDisplayed(xpath);
//判断该元素是否可见
//参数一 字符串型,元素路径
//返回true 或 false

await webBot.isEnabled(xpath);
//判断元素是否可用
//参数一 字符串型,元素路径
//返回true 或 false

await webBot.clearElement(xpath);
//清除元素值
//参数一 字符串型,元素路径
//成功返回true 失败返回false

await webBot.setElementFocus(xpath);
//设置元素焦点
//参数一 字符串型,元素路径
//成功返回true 失败返回false

await webBot.uploadFile(xpath, filePath);
//通过元素上传文件
//参数一 字符串型,元素路径。上传文件路径一般含有 <input type="file" >标签
//参数二 字符串型,本地文件路径,路径不存在会导致网页崩溃
//成功返回true 失败返回false

await webBot.showXpath();
//显示元素xpath路径,页面加载完毕再调用。
//调用此函数后,可在页面移动鼠标会显示元素区域。移动并按下ctrl键,会在浏览器控制台打印相对xpath 和 绝对xpath路径
//ifrmae 内的元素,需要先调用 switchFrame 切入进去,再调用showXpath函数
//总是返回true

鼠标键盘

await webBot.sendKeys(xpath, text);
//发送文本
//参数一 字符串型,元素路径
//参数二 字符串型,要输入的文本,例如sendKeys('//*[@id="kw"]', 'aibote\r'); aibote换行
//成功返回true 失败返回false

''' 代码示例
//输入 aibote换行
await webBot.sendKeys("//*[@id=\"kw\"]", "aibote\r");
'''


await webBot.sendVk(vkCode);
//发送Vk虚拟键
//参数一 整型,VK键值,仅支持 回退键:8  制表键:9  回车键:13  空格键:32  方向左键:37  方向上键:38  方向右键:39  方向下键:40  删除键:46
//成功返回true 失败返回false

await webBot.clickMouse(x, y, msg);
//点击鼠标
//参数一 整型,横坐标,非Windows坐标,页面左上角为起始坐标
//参数二 整型,纵坐标,非Windows坐标,页面左上角为起始坐标
//参数三 整型,单击左键:1  单击右键:2  按下左键:3  弹起左键:4  按下右键:5  弹起右键:6  双击左键:7 
//成功返回true 失败返回false

await webBot.moveMouse(x, y);
//移动鼠标
//参数一 整型,横坐标,非Windows坐标,页面左上角为起始坐标
//参数二 整型,纵坐标,非Windows坐标,页面左上角为起始坐标
//成功返回true 失败返回false

await webBot.wheelMouse(deltaX, deltaY, x, y);
//滚动鼠标
//参数一 整型,水平滚动条移动的距离
//参数二 整型,垂直滚动条移动的距离
//参数三 整型,可选参数,鼠标横坐标位置, 默认为0
//参数四 整型,可选参数,鼠标纵坐标位置, 默认为0
//成功返回true 失败返回false

await webBot.clickMouseByXpath(xpath, msg);
//通过xpath 点击鼠标(元素中心点)
//参数一 字符串型,元素路径
//参数二 整型,单击左键:1  单击右键:2  按下左键:3  弹起左键:4  按下右键:5  弹起右键:6  双击左键:7 
//成功返回true 失败返回false

await webBot.moveMouseByXpath(xpath);
//通过xpath 移动鼠标(元素中心点)
//参数一 字符串型,元素路径
//成功返回true 失败返回false

await webBot.wheelMouseByXpath(xpath, deltaX, deltaY);
//通过xpath 滚动鼠标
//参数一 字符串型,元素路径
//参数二 整型,水平滚动条移动的距离
//参数三 整型,垂直滚动条移动的距离
//成功返回true 失败返回false

await webBot.touchStart(x, y);
//仿真模式 开始触屏
//参数一 整型,横坐标,非Windows坐标,页面左上角为起始坐标,可以通过getElementRect 获取相关坐标
//参数二 整型,纵坐标,非Windows坐标,页面左上角为起始坐标,可以通过getElementRect 获取相关坐标
//成功返回true 失败返回false

await webBot.touchMove(x, y);
//仿真模式 移动触屏
//参数一 整型,横坐标,同touchStart
//参数二 整型,纵坐标,同touchStart
//成功返回true 失败返回false

await webBot.touchEnd(x, y);
//仿真模式 结束触屏
//参数一 整型,横坐标,一般同最后一个触屏事件的坐标一致
//参数二 整型,纵坐标,一般同最后一个触屏事件的坐标一致
//成功返回true 失败返回false

截图

await webBot.takeScreenshot(xpath = null);
//参数一 字符串型,可选参数,元素路径。 如果指定元素路径,则截取元素图片。默认截取全屏
//返回字符串 base-64 编码。 PNG 格式,失败返回null

''' 代码示例
//截图并且保存图片到电脑
//const fs = require("fs"); //导入fs模块
let base64 = await webBot.takeScreenshot();
base64 = base64.replace(/^data:image\/\w+;base64,/,"");
let data = new Buffer.from(base64, "base64");
await fs.writeFileSync("d:\\1.png", data);
'''

alert/prompt弹窗

//浏览器弹窗口会阻塞webBot通信,处理web弹窗的两个方案
//1、手动或者windowsBot触发弹窗。使用webBot的clickAlert点击关闭弹窗
//2、webBot触发弹窗,使用windowsBot相关函数点击关闭弹窗

await webBot.clickAlert(acceptOrCancel, promptText = "");
//点击警告框
//参数一 布尔型,true接受, false取消
//参数二 字符串型,可选参数,输入prompt警告框文本
//成功返回true,失败返回false

await webBot.getAlertText();
//获取警告框内容
//返回警告框内容
await webBot.getCookies(url);
//获取指定url匹配的cookies
//参数一 字符串型,指定的url http://或https:// 起头
//成功返回json格式的字符串,失败返回null

await webBot.getAllCookies();
//获取指定url匹配的cookies
//成功返回json格式的字符串,失败返回null

await webBot.setCookie(cookieParam);
//设置cooki
//参数一 json类型,{"name":string, "value":string, "url":string, "domain":string, "path":string, "secure":boolean, "httpOnly":boolean, "sameSite":string, "expires":number, "priority":string, "sameParty":boolean, "sourceScheme":string, "sourcePort":number, "partitionKey":string}  name、value和url必填参数,其他参数可选
//成功返回true,失败返回false

await webBot.deleteCookies(name, options = {});
//删除指定cookies
//参数一 字符串型,要删除的 Cookie 的名称。
//参数二 json类型,{{url:string, domain:string, path:string}} 可选参数
                //url 如果指定,则删除所有匹配 url 和 name的Cookie
                //domain 如果指定,则删除所有匹配 domain 和 name的Cookie
                //path 如果指定,则删除所有匹配 path 和 name的Cookie
//成功返回true,失败返回false

await webBot.deleteAllCookies();
//删除所有cookies
//成功返回true,失败返回false

await webBot.clearCache();
//清除缓存
//成功返回true,失败返回false

注入JavaScript

await webBot.executeScript(script);
//执行JavaScript 代码
//参数一 字符串型,注入的js代码
//假如注入代码为函数且有return语句,则返回retrun 的值,否则返回null;  注入示例:(function () {return "aibote rpa"})();
//注入的代码含有反斜杠"\"需要转义"\\"

''' 代码示例
//注入js代码
await webBot.executeScript('alert("aibote")');

//注入js代码并返回值
let ret = await webBot.executeScript('(function () {return "aibote rpa"})();');
console.log(ret);//输出aibote rpa
'''

浏览器窗口

await webBot.getWindowPos();
//获取窗口位置和状态
//成功返回矩形位置和窗口状态,失败返回null

await webBot.setWindowPos(windowState, rect = {left:0, top:0, width:0, height:0});
//设置窗口位置和状态
//参数一 字符串型,窗口状态,正常:"normal"  最小化:"minimized"  最大化:"maximized"  全屏:"fullscreen"
//参数二 json类型,可选参数,浏览器窗口位置,此参数仅windowState 值为 "normal" 时有效
//成功返回true,失败返回false

获取驱动程序命令行参数

await webBot.getExtendParam();
//获取WebDriver.exe 命令扩展参数,一般用作脚本远程部署场景,WebDriver.exe驱动程序传递参数给脚本服务端
//返回WebDriver 驱动程序的命令行["extendParam"] 字段的参数

手机浏览器仿真

await webBot.mobileEmulation(width, height, userAgent, platform, platformVersion, acceptLanguage = "", timezoneId = "", latitude = 0, longitude = 0, accuracy = 0);
//参数一 整型,宽度
//参数二 整型,高度
//参数三 字符串型,用户代理
//参数四 字符串型,系统平台
//参数五 字符串型,系统平台版本号
//参数六 字符串型,可选参数,语言
//参数七 字符串型,可选参数,时区标识
//参数八 浮点型,可选参数,纬度
//参数九 浮点型,可选参数,经度
//参数十 浮点型,可选参数,准确度
//成功返回true,失败返回false

''' 代码示例
//模拟 Android 7.0  地理位置 上海
await webBot.mobileEmulation(500, 800, "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36", 
                            "Android", "7.0", "zh-Hans-CN", "Asia/Shanghai", 31.230416, 121.473701, 1111);
'''

关闭浏览器

await webBot.closeBrowser();
//总是返回true

关闭WebDriver.exe驱动程序

await webBot.closeDriver();

激活Web框架(包含windowsBot和webBot)

await webBot.activateFrame(activateKey);
//参数一 字符串型,激活密钥
//返回激活信息

WebSocketBot开发手册

WebSocketBot&AndroidBot 启动App示例

服务端node.js

const WebSocketBot = require('WebSocketBot');//引用WebSocketBot
const AndroidBot = require('AndroidBot');//引用AndroidBot模块

//构建WebSocketBot
let webSocketBot = WebSocketBot.build(async (data, isBinary)=>{
    //解析客户端字符串格式数据
    //let strMsg = data.toString();

    //解析客户端json格式数据
    let jsonMsg = JSON.parse(data);
    let command = jsonMsg["command"];
    let msg = jsonMsg["data"];
    switch(command){
        case "startApp":
            //遍历所有的androidBot 执行命令,可在循环内判断安卓androidId 选择设备执行
            for(let i = 0; i < webSocketBot.androidsBot.length; i++){
                // let androidId = await webSocketBot.androidsBot[i].getAndroidId();
                // console.log(androidId);
                await webSocketBot.androidsBot[i].startApp(msg);
            }
            webSocketBot.sendData(command + "已执行");
            break;
    }
}, 8181);


//注册主函数,安卓端连接脚本会自动调用androidMain,并传递AndroidBot对象。设置服务端监听端口,手机端默认连接端口16678
AndroidBot.registerMain(androidMain, 16678);

/**用作代码提示,androidMain函数会被多次调用,注意使用全局变量
* @param {AndroidBot} androidBot
*/
async function androidMain(androidBot){
    //设置隐式等待
    await androidBot.setImplicitTimeout(5000);
    //获取安卓id
    let androidId = await androidBot.getAndroidId();

    //存入androidBot 和 androidId
    webSocketBot.androidsBot.push(androidBot);
    webSocketBot.androidsId.push(androidId);
}

客户端html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Aibote中控</title>

<style>
    .aiboteLog{
        width: 480px;
        height: 200px;
    }
    body{width: 500px; height: 300px;}
</style>

</head>
<body>
    <textarea class="aiboteLog" id="aiboteLog" placeholder="Aibote 执行日志"></textarea>
    <br><br>
    <input id="appName" placeholder="输入App名称">
    <br><br>
    <button id="startApp">打开App</button>
</body>

<script type="text/javascript">
    let ws = new WebSocket('ws://localhost:8181');//服务端端口8181 对应WebSocketBot.build第二个参数
    ws.onopen = function(){
        console.log("连接服务器成功");
    }

    ws.onclose = function(e){
        console.log("服务器关闭");
    }

    ws.onerror = function(e){
        console.log("连接出错");
    }

    let aiboteLog = document.getElementById("aiboteLog");
    ws.onmessage = function(msg){
        //接收服务端的数据
        let message = msg.data;
        aiboteLog.value += message + "\n";
    }

    let startApp = document.getElementById("startApp");
    startApp.onclick = function(){
        let appName = document.getElementById("appName").value;
        //发送json数据格式
        let jsonMsg = {
            "command":"startApp",
            "data":appName
        }
        //json格式转换成字符串
        let strMsg = JSON.stringify(jsonMsg);
        ws.send(strMsg);//发送数据到服务端
    }
</script>
</html>

WebSocketBot&WebBot url跳转示例

服务端node.js

const WebBot = require('WebBot');//引用WebBot模块
const WebSocketBot = require('WebSocketBot');//引用WebSocketBot

let gWebBot = null;//定义全局变量,存放WebBot对象

//构建WebSocketBot
let webSocketBot = WebSocketBot.build(async (data, isBinary)=>{
    //解析客户端字符串格式数据
    //let strMsg = data.toString();

    //解析客户端json格式数据
    let jsonMsg = JSON.parse(data);
    let command = jsonMsg["command"];
    let msg = jsonMsg["data"];
    switch(command){
        case "openUrl":
            await gWebBot.goto(msg);
            webSocketBot.sendData("已打开" + msg);
            break;
    }
}, 8181);


//注册主函数
WebBot.registerMain(webMain, "127.0.0.1", 36678, {browserName:"chrome"});

/**用作代码提示,webMain函数会被多次调用,注意使用全局变量
* @param {WebBot} webBot
*/
async function webMain(webBot){
    //设置隐式等待
    await webBot.setImplicitTimeout(5000);

    gWebBot = webBot;//赋值给全局变量
}

客户端html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Aibote中控</title>

<style>
    .aiboteLog{
        width: 480px;
        height: 200px;
    }
    body{width: 500px; height: 300px;}
</style>

</head>
<body>
    <textarea class="aiboteLog" id="aiboteLog" placeholder="Aibote 执行日志"></textarea>
    <br><br>
    <input id="valUrl" placeholder="输入url">
    <br><br>
    <button id="btnOpen">跳转网址</button>
</body>

<script type="text/javascript">
    let ws = new WebSocket('ws://localhost:8181');//服务端端口8181 对应WebSocketBot.build第二个参数
    ws.onopen = function(){
        console.log("连接服务器成功");
    }

    ws.onclose = function(e){
        console.log("服务器关闭");
    }

    ws.onerror = function(e){
        console.log("连接出错");
    }

    let aiboteLog = document.getElementById("aiboteLog");
    ws.onmessage = function(msg){
        //接收服务端的数据
        let message = msg.data;
        aiboteLog.value += message + "\n";
    }

    let btnOpen = document.getElementById("btnOpen");
    btnOpen.onclick = function(){
        let url = document.getElementById("valUrl").value;
        //发送json数据格式
        let jsonMsg = {
            "command":"openUrl",
            "data":url
        }
        //json格式转换成字符串
        let strMsg = JSON.stringify(jsonMsg);
        ws.send(strMsg);//发送数据到服务端
    }
</script>
</html>

WebSocketBot&WindowsBot QQ发送消息示例

服务端node.js

const WindowsBot = require('WindowsBot');//引用WindowsBot模块
const WebSocketBot = require('WebSocketBot');//引用WebSocketBot

let gWindowsBot = null;//定义全局变量,存放WindowsBot对象

//构建WebSocketBot
let webSocketBot = WebSocketBot.build(async (data, isBinary)=>{
    //解析客户端字符串格式数据
    //let strMsg = data.toString();


    //通过全局windowsBot获取聊天窗口句柄
    let hwnd = await gWindowsBot.findWindow(null, "Ai-Bot 3群");

    //解析客户端json格式数据
    let jsonMsg = JSON.parse(data);
    let command = jsonMsg["command"];
    let msg = jsonMsg["data"];
    switch(command){
        case "sendMessage":
            await gWindowsBot.sendKeysByHwnd(hwnd, msg);
            await gWindowsBot.clickElement(hwnd, "Button@name=发送(&S)", 1);
            webSocketBot.sendData("已发送" + msg);
            break;
    }
}, 8181);


//注册主函数
WindowsBot.registerMain(windowsMain, "127.0.0.1", 26678);

/**用作代码提示,windowsMain函数会被多次调用,注意使用全局变量
* @param {WindowsBot} windowsBot
*/
async function windowsMain(windowsBot){
    //设置隐式等待
    await windowsBot.setImplicitTimeout(5000);

    gWindowsBot = windowsBot;//赋值给全局变量
}

客户端html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Aibote中控</title>

<style>
    .aiboteLog{
        width: 480px;
        height: 200px;
    }
    body{width: 500px; height: 300px;}
</style>

</head>
<body>
    <textarea class="aiboteLog" id="aiboteLog" placeholder="Aibote 执行日志"></textarea>
    <br><br>
    <input id="valText" placeholder="输入发送的内容">
    <br><br>
    <button id="btnSend">发送消息</button>
</body>

<script type="text/javascript">
    let ws = new WebSocket('ws://localhost:8181');//服务端端口8181 对应WebSocketBot.build第二个参数
    ws.onopen = function(){
        console.log("连接服务器成功");
    }

    ws.onclose = function(e){
        console.log("服务器关闭");
    }

    ws.onerror = function(e){
        console.log("连接出错");
    }

    let aiboteLog = document.getElementById("aiboteLog");
    ws.onmessage = function(msg){
        //接收服务端的数据
        let message = msg.data;
        aiboteLog.value += message + "\n";
    }

    let btnSend = document.getElementById("btnSend");
    btnSend.onclick = function(){
        let text = document.getElementById("valText").value;
        //发送json数据格式
        let jsonMsg = {
            "command":"sendMessage",
            "data":text
        }
        //json格式转换成字符串
        let strMsg = JSON.stringify(jsonMsg);
        ws.send(strMsg);//发送数据到服务端
    }
</script>
</html>

多模块混合开发

WindowsBot & WebBot

const WindowsBot = require('WindowsBot');//引用WindowsBot模块
const WebBot = require('WebBot');//引用WebBot模块

//注册主函数
WindowsBot.registerMain(windowsMain, "127.0.0.1", 26678);
WebBot.registerMain(webMain, "127.0.0.1", 36678, {browserName:"chrome"});

//bot 存放全局变量
let gWindowsBot;
let gWebBot;

//回调函数接受存放驱动Bot
async function windowsMain(windowsBot){
    gWindowsBot = windowsBot;
}
async function webMain(webBot){
    gWebBot = webBot;
}


/**用作代码提示
 * @param {WindowsBot} windowsBot
 * @param {WebBot} webBot
*/
async function main(windowsBot, webBot){
    //WebBot和WindowsBot 大多数都是本地启动驱动程序,因此只有一个驱动对象,我们可以采用此方式处理。
    //如果WebBot或者WindowsBot其中有采用云端远程连接方式,我们可以参考下面的 WindowsBot & AndroidBot 实现方案

    //为null,等待再赋值
    while(windowsBot == null || webBot == null){
        await WindowsBot.sleep(1000);
        windowsBot = gWindowsBot;
        webBot = gWebBot;
        console.log('waiting windowsBot or webBot');
    }

    //设置隐式等待
    await windowsBot.setImplicitTimeout(5000);
    await webBot.setImplicitTimeout(5000);

    //实现功能...
}

main(gWindowsBot, gWebBot);//自定义主函数,并且传递windowsBot 和webBot

WindowsBot & AndroidBot

const WindowsBot = require('WindowsBot');//引用WindowsBot模块
const AndroidBot = require('AndroidBot');//引用AndroidBot模块

//注册主函数
WindowsBot.registerMain(windowsMain, "127.0.0.1", 26678);//windowsMain 应当在 androidMain之前注册,以防在androidMain 函数内,出现gWindowsBot未赋值情况
AndroidBot.registerMain(androidMain, 16678);

//bot 存放全局变量
let gWindowsBot = null;

//回调 函数接受存放驱动Bot
async function windowsMain(windowsBot){
    gWindowsBot = windowsBot;
}

/**用作代码提示,androidMain函数会被多次调用,注意使用全局变量
* @param {AndroidBot} androidBot
*/
async function androidMain(androidBot){
    //AndroidBot较为特殊,它是纯云端构架,只能远程等待连接。不像WebBot和WindowsBot 可以本地执行驱动,也可以远程等待驱动连接
    //AndroidBot 云端构架多设备连接的特殊性,我们直接在回到函数处理
    //用户也可以将androidBot存入数组,在其他函数调用。可参考WebSocketBot&AndroidBot 服务端node.js 代码

    //为null,等待gWindowsBot赋值
    while(gWindowsBot == null)
        await androidBot.sleep(1000);

    //这里直接使用gWindowsBot。
    await gWindowsBot.setImplicitTimeout(5000);
    await androidBot.setImplicitTimeout(3000);

    //实现功能
}

界面开发手册

AiboteScriptUI底层基于chromium内核,可使用html、ccs等语言开发界面。另外我们底层添加四个函数用于实现脚本执行和传参。
启动AiboteScriptUI.exe程序会自动附加当前目录下index.html文件,界面开发工作主要在这个文件

界面宽高

SetAiboteSize(width, height);
//AiboteScriptUI 宽高 由document.body.offsetHeight 和 document.body.offsetWidth决定
//此函数脚本作者不可见,内部自动执行。脚本作者需要设定页面 body 宽高

启动脚本

StartScript("../testAibote.js", true);
//参数一 字符串型。要启动脚本的路径,空格分隔脚本参数。 脚本可通过 let args = process.argv.splice(2); 接收参数
//参数二 布尔类型。是否显示控制台日志,true 显示控制台日志
//返回值 脚本进程ID

停止脚本

StopScript(processId);
//参数一 数字型。脚本进程ID
//成功返回true 失败返回false

输出日志

PrintAiboteLog();
//当StartScript第二个参数为 false 时有效,可以使用 setInterval 循环输出,输出10000字节时,会自动清空内容
//返回脚本输出内容

文件读写

WriteFile("fileName.txt", "writeText", "w");
//写入文件,仅当前目录下的文件写入
//参数一 字符串型。文件名称
//参数二 字符串型。写入的文本内容
//参数三 字符串型。写入的模式,"w"和"a"。 值为 "w" 则覆盖原文件内容,"a" 追加文件内容
//成功返回true 失败返回false

ReadFile("fileName.txt");
//读取文件,仅当前目录下的文件读取
//参数一 字符串型。文件名称
//成功返回读取的文件内容,失败返回"null"

GetFileDialogFolder()
//获取文件夹对话框路径
//成功返回选择文件夹的路径,失败返回"null"

GetFileDialogFile()
//获取文件对话框路径
//成功返回选择文件的路径,失败返回"null"