// ==================== 用户配置 ====================
const PACKAGE_NAME = "com.kuaishou.nebula"; // ✅ 你的快手包名
const COMMENT_LIST = [ // 话术库(随机取)
"这个作品666",
"我对你的产品感兴趣",
"感兴趣奥",
"怎么联系啊",
"支持一下",
"内容不错"
];
const PRIVATE_MSG = COMMENT_LIST[0]; // 默认私信内容(实际随机取)
const MAX_SEND_PER_DAY = 1; // ⚠️ 每天最多1条,安全上限
// ==================== 核心函数 ====================
auto.waitFor();
// ---------- 1. 从评论区进入用户主页 ----------
function enterUserProfileFromComment() {
toastLog("🔍 尝试从评论区进入主页...");
// 点击当前视频的评论头像(需手动确认控件属性)
let avatar = id("avatar").findOne(3000) ||
className("ImageView").depth(10).findOne(3000);
if (avatar) {
avatar.click();
sleep(3000);
return true;
}
toast("❌ 找不到评论头像");
return false;
}
// ---------- 2. 点击“发私信”按钮(精确控件)----------
function clickPrivateButton() {
toastLog("✉️ 点击发私信...");
let btn = text("发私信").findOne(5000) || desc("发私信").findOne(5000);
if (btn) {
btn.click();
sleep(3000);
return true;
}
toast("❌ 找不到发私信按钮");
return false;
}
// ---------- 3. 发送随机话术 ----------
function sendRandomMessage() {
let input = className("EditText").findOne(5000);
if (!input) { toast("❌ 未进入聊天界面"); return false; }
input.click(); sleep(1000);
// 随机取一条话术 + 随机数后缀
let randomIndex = random(0, COMMENT_LIST.length - 1);
let msg = COMMENT_LIST[randomIndex] + random(100, 999);
setText(msg); sleep(1000);
let sendBtn = text("发送").findOne(3000) || desc("发送").findOne(3000);
if (sendBtn) {
sendBtn.click();
toastLog("✅ 私信已发: " + msg);
sleep(2000);
back(); // 返回主页
return true;
}
toast("❌ 找不到发送按钮");
return false;
}
// ---------- 4. 安全单次执行(每天只跑一次)----------
function safeSendOnce() {
app.launch(PACKAGE_NAME);
sleep(5000);
// 伪装滑动(必做)
for (let i=0;i<random(2,4);i++) {
swipe(device.width/2, device.height*0.8,
device.width/2, device.height*0.2,
random(300,500));
sleep(random(3000,5000));
}
if (enterUserProfileFromComment()) {
if (clickPrivateButton()) {
sendRandomMessage();
}
}
}
// ==================== 执行 ====================
safeSendOnce();
toastLog("🏁 任务完成");
检查我代码是不是有问题?
回答
你的代码整体结构清晰,功能逻辑基本正确,但存在一些兼容性、逻辑完整性和错误处理方面的问题。以下是详细分析和改进建议:
主要问题及修正建议:
-
兼容性问题(使用
let和const):- Hamibot 的 JavaScript 引擎是 Rhino 1.7.15,它不完全支持 ES6 特性(如
let和const)。为了确保兼容性,建议将所有let和const改为var。 - 修正代码开头:
var PACKAGE_NAME = "com.kuaishou.nebula"; var COMMENT_LIST = ["这个作品666", "我对你的产品感兴趣", "感兴趣奥", "怎么联系啊", "支持一下", "内容不错"]; var PRIVATE_MSG = COMMENT_LIST[0]; var MAX_SEND_PER_DAY = 1;
- Hamibot 的 JavaScript 引擎是 Rhino 1.7.15,它不完全支持 ES6 特性(如
-
每日限制未实际实现:
- 你定义了
MAX_SEND_PER_DAY = 1,但在safeSendOnce()函数中没有检查是否已经发送过。需要添加逻辑来记录发送次数或日期,避免每天超过限制。 - 建议使用
hamibot的存储 API(如hamibot.setVal()和hamibot.getVal())来存储发送记录。例如:然后在function checkDailyLimit() { var today = new Date().toLocaleDateString(); // 获取当前日期 var lastSendDate = hamibot.getVal("lastSendDate"); var sendCount = hamibot.getVal("sendCount") || 0; if (lastSendDate === today && sendCount >= MAX_SEND_PER_DAY) { toastLog("⚠️ 今日发送已达上限,停止执行"); return false; } // 更新记录 if (lastSendDate !== today) { hamibot.setVal("sendCount", 0); hamibot.setVal("lastSendDate", today); } hamibot.setVal("sendCount", sendCount + 1); return true; }safeSendOnce()开头调用if (!checkDailyLimit()) return;。
- 你定义了
-
控件查找可能不稳定:
- 快手的 UI 可能因版本更新而变化,你的控件选择器(如
id("avatar")、text("发私信"))可能不准确。建议使用 Hamibot 的布局分析功能生成更精确的选择器。 - 例如,
id("avatar")可能不是唯一标识,可以尝试组合条件,如className("ImageView").id("avatar").depth(10)。 - 添加更多备用选择器或使用
bounds()或drawingOrder()来提高准确性。
- 快手的 UI 可能因版本更新而变化,你的控件选择器(如
-
错误处理不足:
- 当前代码在找不到控件时只是输出 toast,但脚本会继续执行,可能导致后续错误。建议在关键步骤失败时直接返回或终止脚本。
- 例如,在
enterUserProfileFromComment()中,如果找不到头像,应该返回false并停止后续操作。类似地处理其他函数。
-
随机滑动可能不够自然:
- 你的滑动操作使用固定坐标,但不同设备分辨率可能影响效果。建议使用相对坐标(如
device.height * 0.8)是好的,但可以添加更多随机性,例如随机方向或持续时间。 - 确保滑动后等待足够时间让内容加载(当前
sleep(random(3000,5000))是合理的)。
- 你的滑动操作使用固定坐标,但不同设备分辨率可能影响效果。建议使用相对坐标(如
-
私信内容随机性:
- 你使用
PRIVATE_MSG = COMMENT_LIST[0]但实际发送时随机选择,这有点矛盾。建议移除PRIVATE_MSG或直接使用随机选择。 - 在
sendRandomMessage()中,随机索引生成使用random(0, COMMENT_LIST.length - 1),正确。
- 你使用
-
脚本退出处理:
- 脚本最后没有明确退出,建议在完成或失败时调用
hamibot.exit()来确保脚本停止。
- 脚本最后没有明确退出,建议在完成或失败时调用
修正后的代码框架(关键部分):
// ==================== 用户配置 ====================
var PACKAGE_NAME = "com.kuaishou.nebula";
var COMMENT_LIST = ["这个作品666", "我对你的产品感兴趣", "感兴趣奥", "怎么联系啊", "支持一下", "内容不错"];
var MAX_SEND_PER_DAY = 1;
// ==================== 核心函数 ====================
auto.waitFor();
// 检查每日限制
function checkDailyLimit() {
var today = new Date().toLocaleDateString();
var lastSendDate = hamibot.getVal("lastSendDate");
var sendCount = hamibot.getVal("sendCount") || 0;
if (lastSendDate === today && sendCount >= MAX_SEND_PER_DAY) {
toastLog("⚠️ 今日发送已达上限,停止执行");
return false;
}
if (lastSendDate !== today) {
hamibot.setVal("sendCount", 0);
hamibot.setVal("lastSendDate", today);
}
hamibot.setVal("sendCount", sendCount + 1);
return true;
}
// 进入用户主页
function enterUserProfileFromComment() {
toastLog("🔍 尝试从评论区进入主页...");
var avatar = id("avatar").findOne(3000) || className("ImageView").depth(10).findOne(3000);
if (avatar) {
avatar.click();
sleep(3000);
return true;
}
toast("❌ 找不到评论头像");
return false;
}
// 点击私信按钮
function clickPrivateButton() {
toastLog("✉️ 点击发私信...");
var btn = text("发私信").findOne(5000) || desc("发私信").findOne(5000);
if (btn) {
btn.click();
sleep(3000);
return true;
}
toast("❌ 找不到发私信按钮");
return false;
}
// 发送随机消息
function sendRandomMessage() {
var input = className("EditText").findOne(5000);
if (!input) {
toast("❌ 未进入聊天界面");
return false;
}
input.click();
sleep(1000);
var randomIndex = random(0, COMMENT_LIST.length - 1);
var msg = COMMENT_LIST[randomIndex] + random(100, 999);
setText(msg);
sleep(1000);
var sendBtn = text("发送").findOne(3000) || desc("发送").findOne(3000);
if (sendBtn) {
sendBtn.click();
toastLog("✅ 私信已发: " + msg);
sleep(2000);
back();
return true;
}
toast("❌ 找不到发送按钮");
return false;
}
// 安全执行
function safeSendOnce() {
if (!checkDailyLimit()) {
hamibot.exit(); // 达到限制则退出
return;
}
app.launch(PACKAGE_NAME);
sleep(5000);
// 模拟滑动
for (var i = 0; i < random(2, 4); i++) {
swipe(device.width / 2, device.height * 0.8, device.width / 2, device.height * 0.2, random(300, 500));
sleep(random(3000, 5000));
}
if (enterUserProfileFromComment()) {
if (clickPrivateButton()) {
if (sendRandomMessage()) {
toastLog("🏁 任务完成");
}
}
}
hamibot.exit(); // 确保脚本退出
}
// ==================== 执行 ====================
safeSendOnce();
额外建议:
- 测试和调试:在真实设备上测试脚本,使用 Hamibot 的布局分析工具来验证控件选择器。
- 权限检查:确保应用有必要的权限(如无障碍服务、悬浮窗等)。
- 异常处理:添加
try-catch块来捕获意外错误,避免脚本崩溃。
如果你有具体控件属性或更多上下文,我可以帮助进一步优化选择器。