一、环境与场景说明
使用 Hamibot 市场脚本机制:
守护脚本(本地脚本):通过 engines.execScript("市场脚本ID", [JSON字符串]) 拉起云端市场发布的子脚本;
子脚本:发布在 Hamibot 市场,ID:6a4535090a9d685af56e0442;
传参方案:将配置对象 JSON 序列化后,放入数组作为 execScript 第二个参数传递;
子脚本读取参数:engines.myEngine().execArgv。
二、现象(分两种执行方式,表现完全不同)
方式 1:本地手动单独运行该市场脚本(Hamibot 内点开脚本点运行)
无任何语法报错,代码完整执行,正常输出日志;
逻辑、语法全部正常,代码本身无分号缺失、符号错误。
方式 2:本地守护脚本调用 engines.execScript 拉起同一份市场脚本
守护层日志:显示「成功通过市场标识拉起脚本,参数下发完成」,拉起动作无异常;
子脚本启动瞬间直接报错:语句前缺少 ";",报错锁定第 1 行;
子脚本运行时长仅 0.03 秒,直接闪退,完全不执行业务逻辑。
三、已排查排除的问题
JSON 指令文件 wla_command.json 无问题:守护能完整读取并打印全部 JSON 内容,有无该文件不影响此报错;
子脚本源码语法无错误:单独运行正常,多次清空编辑框、纯文本重新粘贴发布,未改动任何业务代码;
脚本 ID、execScript 调用格式正确:execScript("ID", [JSON.stringify(obj)]);
无多实例冲突:拉起前已停止所有子脚本实例,重启守护后复现。
四、核心疑问
为什么手动点开市场脚本运行正常,用 engines.execScript 调用市场脚本就报第一行缺少分号语法错误?
市场脚本通过 execScript 引擎启动时,是否会额外加载、转译源码,导致云端脚本头部产生不可见非法字符?
engines.execScript 调用市场发布脚本,和本地手动执行市场脚本,底层加载源码逻辑是否存在差异?
补充给客服的两段关键代码
1、守护拉起代码
js
运行
function runWechatTask(taskConfig) {
try {
let execResult = engines.execScript("6a4535090a9d685af56e0442", [JSON.stringify(taskConfig)]);
log("✅ 成功通过市场标识拉起微信销售子脚本,任务参数已下发");
return execResult;
} catch (err) {
log("❌ 拉起子脚本失败:" + err);
return null;
}
}

2、市场子脚本完整代码
js
运行
// 官方标准获取启动参数,所有Hamibot可用
let args = engines.myEngine().execArgv;
let config = {};
if (args && args[0]) {
config = JSON.parse(args[0]);
} else {
log("⚠️ 未收到调度参数,使用默认10分钟测试时长");
config = { runMinutes: 10 };
}

let runMin = config.runMinutes || 1;
let runMs = runMin * 60 * 1000;

toast("【AI销售独立脚本启动】运行时长:" + runMin + "分钟");
log("AI销售模拟执行流程开始");

let startTime = new Date().getTime();
while (new Date().getTime() - startTime < runMs) {
log("模拟串行执行:加好友→朋友圈→AI聊天");
sleep(5000);
}

log("本轮任务执行完毕,脚本自动退出");
toast("AI销售独立脚本执行结束");

另外:
execScript 传递数组参数给市场脚本,execArgv 能否正常接收到序列化后的 JSON 字符串?目前就算不报错,子脚本也读取不到外部传入参数,始终走默认 10 分钟配置。

HAMI_6893877807 · 5 小时前

回答

Hamibot AI
1
· 5 小时前

你遇到的问题是 engines.execScript 参数传递方式错误,导致引擎把参数数组当成脚本代码执行,触发了语法错误。

错误原因分析

engines.execScript 的完整签名是:

engines.execScript(name, script, config)
  • name:脚本名称(可任意)
  • script脚本代码字符串
  • config:可选配置对象,其中 arguments 字段用于向新脚本传递参数数组

你当前的调用:

engines.execScript("6a4535090a9d685af56e0442", [JSON.stringify(taskConfig)])

[JSON.stringify(taskConfig)] 放在了第二个参数的位置,这会被当作脚本代码执行。
JavaScript 引擎尝试执行这段字符串时,首先遇到 [,认为这是一个数组字面量的开始,但整个上下文缺少分号(;)或合法的表达式,于是在第一行就报“语句前缺少 ;”并直接退出,根本不会执行你市场脚本中的业务逻辑。

正确的参数传递方式

想通过 execScript 给市场脚本传参,必须使用 config 对象的 arguments 字段:

// 文档地址 https://docs.hamibot.com/
function runWechatTask(taskConfig) {
    try {
        engines.execScript(
            "6a4535090a9d685af56e0442",   // 市场脚本 ID
            "",                           // 脚本代码留空即可
            { arguments: [JSON.stringify(taskConfig)] }  // 参数通过 arguments 传递
        );
        log("✅ 成功通过市场标识拉起微信销售子脚本,任务参数已下发");
    } catch (err) {
        log("❌ 拉起子脚本失败:" + err);
        return null;
    }
}

如果你希望子脚本运行时能额外带上循环等配置,也可以在 config 中指定:

engines.execScript("6a4535090a9d685af56e0442", "", {
    arguments: [JSON.stringify(taskConfig)],
    loopTimes: 10,
    interval: 3000
});

为什么手动运行正常,守护拉起就报错

  • 手动运行:市场脚本通过 Hamibot 界面直接启动,没有传入任何参数,engines.myEngine().execArgv 为空,脚本走默认配置,语法完全正确,不会触发错误。
  • 守护拉起:你把参数数组错误地放到了脚本代码的位置,导致引擎执行一段非法代码,与脚本本身的语法无关。底层加载源码没有任何差异,纯粹是调用方式错误。

关于 execArgv 能否正常接收参数

只要通过 config.arguments 正确传入,子脚本里的 engines.myEngine().execArgv 就能拿到传入的数组。
你的子脚本接收代码完全正确:

let args = engines.myEngine().execArgv;
let config = {};
if (args && args[0]) {
    config = JSON.parse(args[0]);
} else {
    log("⚠️ 未收到调度参数,使用默认10分钟测试时长");
    config = { runMinutes: 10 };
}

修正调用方式后,参数就能正常传递,不再走默认配置。

补充说明

  • 传递参数时,必须将对象序列化为 JSON 字符串,因为 arguments 数组中的元素会原样传递,接收方需要自行解析。
  • 如果你的守护脚本中还有其他地方使用了 execScript,请一并检查,确保参数都是通过 config.arguments 传递,而不是直接放在第二参数位置。
  • 编写脚本时注意兼容性:不要使用箭头函数或函数默认参数等 Rhino 1.7.15 引擎不完全支持的语法。

按照上述方式修改守护脚本,问题即可解决。

ℹ️ 内容由 AI 生成,可能不准确,请注意核实