目前我这个脚本在配置里面[
{
"label": "订单号",
"name": "orderNo",
"type": "text",
"default": ""
},
{
"label": "起点地址",
"name": "startAddress",
"type": "text",
"default": ""
},
{
"label": "终点地址",
"name": "endAddress",
"type": "text",
"default": ""
},
{
"label": "标题",
"name": "title",
"type": "text",
"default": "新订单通知"
},
{
"label": "描述",
"name": "desc",
"type": "text",
"default": ""
},
{
"label": "链接",
"name": "url",
"type": "text",
"default": ""
},
{
"label": "金额",
"name": "payAmount",
"type": "text",
"default": "0"
},
{
"label": "联系人",
"name": "contactName",
"type": "text",
"default": "文件传输助手"
}
]这样添加参数没有问题,但是当我运行脚本的时候https://api.hamibot.com/v1/scripts/69e072303969746367d33ece/run这里post请求,携带参数{
"devices": [
{
"_id": "69e07fc1f91f4f25291b1c46",
"name": "朴茂豆芽"
}
],
"vars": {
"contactName": "小助手",
"title": "新订单通知",
"orderNo": "ORD20240115001",
"startAddress": "北京市朝阳区",
"endAddress": "上海市浦东新区",
"desc": "加急订单,请尽快处理",
"payAmount": "299.00",
"url": "https://example.com/order/123"
}
},但是🌟订单通知:新订单通知
🐾订单号: 无订单号
🚩起点: 无地址信息
🏠终点: 无地址信息
💬描述: 无描述
💰赏金: 0元
🔗详情:
快递外卖代取、跑腿万能代办,就上小程序【潍院服务站】还是这样的,而且我也延时了呀,function getContactName() {
return hamibot.env.contactName || "文件传输助手";
}
function buildMessage() {
if (hamibot.env.messageText) {
return hamibot.env.messageText;
}
const title = hamibot.env.title || "新订单通知";
const orderNo = hamibot.env.orderNo || "无订单号";
const startAddress = hamibot.env.startAddress || "无地址信息";
const endAddress = hamibot.env.endAddress || "无地址信息";
const desc = hamibot.env.desc || "无描述";
const payAmount = hamibot.env.payAmount || "0";
const url = hamibot.env.url || "";
return [
`🌟订单通知:${title}`,
`🐾订单号: ${orderNo}`,
`🚩起点: ${startAddress}`,
`🏠终点: ${endAddress}`,
`💬描述: ${desc}`,
`💰赏金: ${payAmount}元`,
`🔗详情: ${url}`,
"快递外卖代取、跑腿万能代办,就上小程序【潍院服务站】"
].join("\n");
}
function backToWechatHome() {
toastLog("开始返回微信主页面");
for (let i = 0; i < 5; i++) {
if (text("微信").exists() && text("通讯录").exists() && text("发现").exists() && text("我").exists()) {
toastLog("已返回微信主页面");
return true;
}
back();
sleep(800);
}
toastLog("未能完全返回微信主页面,请手动检查");
return false;
}
function main() {
sleep(500);
const contactName = getContactName();
const messageText = buildMessage();
if (!app.launch("com.tencent.mm")) {
toastLog("启动微信失败");
exit();
}
sleep(3000);
console.log("开始查找聊天列表中的联系人...", contactName);
let chatItem = text(contactName).findOne(5000) ||
desc(contactName).findOne(5000) ||
className("android.widget.TextView").textContains(contactName).findOne(5000);
if (chatItem) {
chatItem.click();
let bounds = chatItem.bounds();
click(bounds.centerX(), bounds.centerY());
toastLog("点击联系人成功");
} else {
let searchButton = id("com.tencent.mm:id/h5n").findOne(3000);
if (searchButton) {
searchButton.click();
let bounds = searchButton.bounds();
click(bounds.centerX(), bounds.centerY());
toastLog("点击搜索按钮成功");
} else {
let altSearchButton = text("搜索").findOne(3000) ||
desc("搜索").findOne(3000) ||
className("android.widget.ImageView").findOne(3000);
if (altSearchButton) {
altSearchButton.click();
let bounds = altSearchButton.bounds();
click(bounds.centerX(), bounds.centerY());
toastLog("点击备用搜索按钮成功");
} else {
console.show();
classNameMatches(/.*/).find().forEach(v => console.log(v));
takeScreenshot("debug_search.jpg");
toastLog("错误:未找到任何搜索按钮");
exit();
}
}
另外我想这样调试, console.show();
console.log("hamibot.env raw =", JSON.stringify(hamibot.env));
console.log("contactName =", hamibot.env.contactName);
console.log("title =", hamibot.env.title);
console.log("orderNo =", hamibot.env.orderNo);
console.log("startAddress =", hamibot.env.startAddress);
console.log("endAddress =", hamibot.env.endAddress);
console.log("desc =", hamibot.env.desc);
console.log("payAmount =", hamibot.env.payAmount);
console.log("url =", hamibot.env.url);
const contactName = getContactName();
const messageText = buildMessage();
console.log("resolved contactName =", contactName);
console.log("resolved messageText =", messageText);
直接在在线编辑器里,怎么看这个输出呀,目前还是不太行
如果我传递的参数里面有数组,这个怎么解析呢,另外在配置文件里面怎么弄呢,{
"devices": [
{
"_id": "68c20f66f30b8f60ffd65df7",
"name": "朴茂豆芽"
}
],
"vars": {
"contactName": ["小助手"],
"title": "新订单通知",
"orderNo": "ORD20240115001",
"startAddress": "北京市朝阳区",
"endAddress": "上海市浦东新区",
"desc": "加急订单,请尽快处理",
"payAmount": "299.00",
"url": "https://example.com/order/123"
}
}现在运行脚本的参数是这样的,把contactName改为数组了,那function getScriptParams() {
const {
contactName,
messageText,
title,
orderNo,
startAddress,
endAddress,
desc,
payAmount,
url
} = hamibot.env;
return {
contactName: (contactName || "文件传输助手").trim(),
messageText: (messageText || "").trim(),
title: title || "新订单通知",
orderNo: orderNo || "无订单号",
startAddress: startAddress || "无地址信息",
endAddress: endAddress || "无地址信息",
desc: desc || "无描述",
payAmount: payAmount || "0",
url: url || ""
};
}怎么解析,另外就是这个配置文件怎么写呢[
{
"label": "订单号",
"name": "orderNo",
"type": "text",
"default": ""
},
{
"label": "起点地址",
"name": "startAddress",
"type": "text",
"default": ""
},
{
"label": "终点地址",
"name": "endAddress",
"type": "text",
"default": ""
},
{
"label": "标题",
"name": "title",
"type": "text",
"default": "新订单通知"
},
{
"label": "描述",
"name": "desc",
"type": "text",
"default": ""
},
{
"label": "链接",
"name": "url",
"type": "text",
"default": ""
},
{
"label": "金额",
"name": "payAmount",
"type": "text",
"default": "0"
},
{
"label": "联系人",
"name": "contactName",
"type": "text",
"default": "文件传输助手"
}
]
回答
问题可能是 hamibot.env 的注入时机或字段名不匹配。以下是强制调试和修复方案:
// 文档地址 https://docs.hamibot.com/
// 强制延迟并轮询等待 env 注入
function waitForEnv(timeout) {
timeout = timeout || 5000;
var start = new Date().getTime();
while (new Date().getTime() - start < timeout) {
// 检查关键字段是否存在且不为空
if (hamibot.env && hamibot.env.orderNo && hamibot.env.orderNo !== "") {
return true;
}
sleep(200);
}
return false;
}
// 安全读取 env,带调试日志
function getEnv(key, defaultValue) {
var value = (hamibot.env && hamibot.env[key]) ? hamibot.env[key] : defaultValue;
log("ENV[" + key + "]: " + (value === defaultValue ? "(默认值)" : value));
return value;
}
function getContactName() {
return getEnv("contactName", "文件传输助手");
}
function buildMessage() {
var messageText = getEnv("messageText", "");
if (messageText && messageText !== "") {
return messageText;
}
var title = getEnv("title", "新订单通知");
var orderNo = getEnv("orderNo", "无订单号");
var startAddress = getEnv("startAddress", "无地址信息");
var endAddress = getEnv("endAddress", "无地址信息");
var desc = getEnv("desc", "无描述");
var payAmount = getEnv("payAmount", "0");
var url = getEnv("url", "");
return [
"🌟订单通知:" + title,
"🐾订单号: " + orderNo,
"🚩起点: " + startAddress,
"🏠终点: " + endAddress,
"💬描述: " + desc,
"💰赏金: " + payAmount + "元",
"🔗详情: " + url,
"快递外卖代取、跑腿万能代办,就上小程序【潍院服务站】"
].join("\n");
}
function main() {
// 关键:先等待 env 注入
log("等待 hamibot.env 注入...");
var envReady = waitForEnv(5000);
log("env 注入状态: " + envReady);
// 打印完整的 hamibot.env 内容
log("=== 完整的 hamibot.env ===");
if (typeof hamibot !== "undefined" && hamibot.env) {
for (var key in hamibot.env) {
log(key + ": " + hamibot.env[key]);
}
} else {
log("hamibot.env 不存在!");
}
log("===========================");
var contactName = getContactName();
var messageText = buildMessage();
log("最终联系人: " + contactName);
log("最终消息:\n" + messageText);
// 后续逻辑...
if (!app.launch("com.tencent.mm")) {
toastLog("启动微信失败");
exit();
}
// ...
}
main();
如果调试输出显示 hamibot.env 始终为空,问题可能在 API 调用端。检查:
- 令牌权限:确保使用的是开发者令牌(
hmp_开头),不是脚本令牌 - 脚本状态:确保脚本已发布,且设备已订阅该脚本
- 字段名完全匹配:
orderNo不是order_no,大小写敏感
备选方案:直接在脚本顶部硬编码测试参数,确认逻辑正确后再排查 API 传递问题。
在线编辑器无法直接查看 console.show() 的输出,因为 console.show() 是在设备端显示悬浮窗控制台,不是在浏览器里显示。
在线编辑器查看日志的方法
方法1:使用 log() 代替 console.log()
// 文档地址 https://docs.hamibot.com/
log("hamibot.env raw = " + JSON.stringify(hamibot.env));
log("contactName = " + hamibot.env.contactName);
log("title = " + hamibot.env.title);
log("orderNo = " + hamibot.env.orderNo);
在线编辑器运行后,点击**"日志"**标签页查看输出。
方法2:使用 toastLog() 双输出
// 文档地址 https://docs.hamibot.com/
function debugLog(msg) {
// 同时输出到在线编辑器日志和设备弹窗
toastLog(msg);
}
debugLog("contactName = " + hamibot.env.contactName);
方法3:在线编辑器直接运行看底部日志
// 文档地址 https://docs.hamibot.com/
// 不用 console.show(),直接用 log
log("=== 调试 hamibot.env ===");
log("env 是否存在: " + (typeof hamibot !== "undefined"));
log("env 对象: " + (hamibot.env ? "存在" : "不存在"));
if (hamibot.env) {
log("orderNo: " + hamibot.env.orderNo);
log("title: " + hamibot.env.title);
// ... 其他字段
}
运行后看编辑器底部的日志区域。
关键问题:在线编辑器的 env 来源
| 运行方式 | hamibot.env 来源 |
|---|---|
| 在线编辑器 | 配置模式里填写的默认值 |
| API 调用 | vars 参数传入的值 |
| 客户端手动运行 | 配置表单里用户填写的值 |
在线编辑器无法测试 API 传入的 vars 参数,它只能用配置模式里的默认值。
完整调试代码(在线编辑器可用)
// 文档地址 https://docs.hamibot.com/
function main() {
// 在线编辑器看这里:运行后点"日志"标签
log("========== 调试开始 ==========");
log("运行时间: " + new Date().toLocaleString());
// 检查 hamibot 对象
log("hamibot 存在: " + (typeof hamibot !== "undefined"));
if (typeof hamibot === "undefined") {
log("错误: hamibot 对象不存在");
return;
}
log("hamibot.env 存在: " + (hamibot.env ? "是" : "否"));
if (!hamibot.env) {
log("错误: hamibot.env 不存在");
return;
}
// 打印所有字段
log("--- hamibot.env 内容 ---");
for (var key in hamibot.env) {
log(key + ": " + hamibot.env[key]);
}
// 测试具体字段
log("--- 字段测试 ---");
log("contactName: [" + hamibot.env.contactName + "]");
log("title: [" + hamibot.env.title + "]");
log("orderNo: [" + hamibot.env.orderNo + "]");
log("startAddress: [" + hamibot.env.startAddress + "]");
log("endAddress: [" + hamibot.env.endAddress + "]");
log("desc: [" + hamibot.env.desc + "]");
log("payAmount: [" + hamibot.env.payAmount + "]");
log("url: [" + hamibot.env.url + "]");
// 测试函数
log("--- 函数测试 ---");
var contactName = hamibot.env.contactName || "文件传输助手";
var title = hamibot.env.title || "新订单通知";
log("resolved contactName: " + contactName);
log("resolved title: " + title);
log("========== 调试结束 ==========");
}
main();
真正测试 API 传入的参数
必须用 API 调用 或 脚本控制台:
-
脚本控制台(推荐测试):
- 手机打开 Hamibot 客户端
- 进入「脚本控制台」
- 找到你的脚本,点击「配置」填写参数
- 运行后看客户端日志
-
API 调用后看设备日志:
- 调用 API 运行脚本
- 在 Hamibot 客户端右上角点击日志图标查看
在线编辑器只能验证脚本语法和基本逻辑,无法测试 API 动态传参。
hamibot.env 传递的数组会被转为JSON字符串,需要手动解析。同时 Rhino 1.7.15 不支持解构赋值,需要改写。
脚本代码(兼容 Rhino)
// 文档地址 https://docs.hamibot.com/
function getScriptParams() {
// 等待 env 注入
sleep(500);
var env = hamibot.env || {};
// 解析 contactName(支持字符串或数组JSON)
var contactNameRaw = env.contactName || "文件传输助手";
var contactName = contactNameRaw;
// 尝试解析为数组
if (typeof contactNameRaw === "string" && contactNameRaw.indexOf("[") === 0) {
try {
var parsed = JSON.parse(contactNameRaw);
if (parsed && parsed.length > 0) {
contactName = parsed[0]; // 取第一个,或保持数组
}
} catch (e) {
// 解析失败,保持原值
}
}
// 其他字段
var messageText = env.messageText || "";
var title = env.title || "新订单通知";
var orderNo = env.orderNo || "无订单号";
var startAddress = env.startAddress || "无地址信息";
var endAddress = env.endAddress || "无地址信息";
var desc = env.desc || "无描述";
var payAmount = env.payAmount || "0";
var url = env.url || "";
// 调试输出
log("contactName raw: " + JSON.stringify(env.contactName));
log("contactName parsed: " + contactName);
return {
contactName: String(contactName).trim(),
messageText: String(messageText).trim(),
title: title,
orderNo: orderNo,
startAddress: startAddress,
endAddress: endAddress,
desc: desc,
payAmount: payAmount,
url: url
};
}
// 使用
function main() {
var params = getScriptParams();
log("最终联系人: " + params.contactName);
// ...
}
main();
配置文件(支持多联系人)
[
{
"label": "订单号",
"name": "orderNo",
"type": "text",
"default": ""
},
{
"label": "起点地址",
"name": "startAddress",
"type": "text",
"default": ""
},
{
"label": "终点地址",
"name": "endAddress",
"type": "text",
"default": ""
},
{
"label": "标题",
"name": "title",
"type": "text",
"default": "新订单通知"
},
{
"label": "描述",
"name": "desc",
"type": "text",
"default": ""
},
{
"label": "链接",
"name": "url",
"type": "text",
"default": ""
},
{
"label": "金额",
"name": "payAmount",
"type": "text",
"default": "0"
},
{
"label": "联系人(多个用逗号分隔)",
"name": "contactName",
"type": "text",
"default": "文件传输助手"
}
]
API 调用方式(推荐)
{
"devices": [{"_id": "xxx", "name": "设备名"}],
"vars": {
"contactName": "[\"小助手\",\"客服1\",\"客服2\"]",
"title": "新订单通知",
"orderNo": "ORD001"
}
}
或单联系人字符串:
{
"vars": {
"contactName": "小助手"
}
}
完整解析多联系人版本
// 文档地址 https://docs.hamibot.com/
function parseContactName(raw) {
if (!raw) return ["文件传输助手"];
// 已经是数组(直接传递时)
if (typeof raw === "object" && raw.length) {
return raw;
}
// JSON 数组字符串
if (typeof raw === "string" && raw.indexOf("[") === 0) {
try {
return JSON.parse(raw);
} catch (e) {
// 解析失败
}
}
// 逗号分隔的字符串
if (typeof raw === "string" && raw.indexOf(",") >= 0) {
return raw.split(",").map(function(s) { return s.trim(); });
}
// 单个字符串
return [String(raw).trim()];
}
// 使用
var contacts = parseContactName(hamibot.env.contactName);
log("联系人数量: " + contacts.length);
for (var i = 0; i < contacts.length; i++) {
log("联系人" + (i+1) + ": " + contacts[i]);
}