panchengyong
10 days ago b2d3f7caf927e5b83ec52efb74f1f818dbb15236
commit | author | age
bc5e1e 1 /**
b2d3f7 2  * 匹配的用户私信
bc5e1e 3  */
X 4 let packageName = 'com.ss.android.ugc.aweme';
5 let searchUserIds = [];
6 let replyWords = []; //回复话术
7 let devices = [] // 设备编号
8 let deviceNum = 0; // 设备数量
9 let distributedUserIds = []
10 let lastCallTime = null;
11 let randomNum = 0;
12 var nickname = "",
13     dyNo = "",
14     praiseNum = "",
15     friends = "",
16     follow = "",
17     fans = "",
18     introduction = "",
19     age = "",
20     province = "",
21     city = "",
22     school = "",
23     postNum = "",
24     simiNum = "",
25     tenantId = "",
26     taskId = "",
27     scriptVersion = "",
28     sex = "";
29
30 //toast扩展参数
31 let toastExtra = {
32     "x": (device.getScreenWidth() - 800) / 2,
33     "y": (device.getScreenHeight() - 200) / 2,
34     "textColor": "#ffffff",
35     "duration": 30000,
36     "width": 800,
37     "height": 200,
38 }
39
b2d3f7 40 /**
P 41  * description 脚本入口
42  * launch中调用getUserId方法,逐一私信
43  */
bc5e1e 44 run()
X 45
46 /**
47  * description 唤醒设备
48  */
49 function run() {
50     if (!isAccMode()) {
51         toast('非无障碍模式,无法执行脚本', toastExtra);
52         randomSleep("非无障碍模式,无法执行脚本", "", "", "", "", "");
53         exit();
54     }
55     //自动化服务是否正常
56     if (!autoServiceStart(2)) {
57         toast('自动化服务启动失败,无法执行脚本', toastExtra);
58         randomSleep("自动化服务启动失败,无法执行脚本", "", "", "", "", "");
59         exit();
60     }
61     //脚本停止监听
62     setStopCallback(function () {
63         device.cancelKeepingAwake(); //取消保持唤醒状态
64         logd("脚本停止");
65         deviceOperaLog("脚本停止", "脚本停止", 0, "", "", "", "", "")
66         home();
67     });
68     //脚本异常停止监听
69     setExceptionCallback(function (msg) {
70         device.cancelKeepingAwake(); //取消保持唤醒状态
71         logd("脚本异常停止");
72         deviceOperaLog("脚本异常停止", "脚本异常停止", 0, "", "", "", "", "")
73         home();
74     });
75     daemonEnv(true); //守护自动化环境
76     let d = ecloud.getTaskInfo(); //任务信息
77     let version = 0; //脚本版本号
78     if (d) version = d.scriptVersion;
79     randomSleep("脚本开始运行, 版本:" + version, "脚本启动", "", "", "", "");
80     //保持设备唤醒
81     // importClass(android.os.PowerManager);
82     // device.keepAwake(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP);
83     //保持屏幕唤醒
84     device.keepScreenOn();
85     sleep(1000);
86     //息屏设备上滑解锁
87     let lock = id("com.android.systemui:id/notification_stack_scroller").getOneNodeInfo(5000);
88     if (lock) {
89         let screenWidth = device.getScreenWidth();
90         let screenHeight = device.getScreenHeight();
91         let startX = screenWidth / 2;
92         let startY = screenHeight - 200;
93         let endX = screenWidth / 2;
94         let endY = 50;
95         let duration = 2000;
96         swipeToPoint(startX, startY, endX, endY, duration);
97     }
98     getDevice(); // 获取设备信息
99     getECloudData(); //获取用户ids
100     distributedUserIds = distributeUserIdsToDevices(searchUserIds, deviceNum) // 将用户id分发给设备
101     launch(packageName, 6000, 3); //打开抖音
102 }
103
104 /**
b2d3f7 105  * hook 获取任务参数
bc5e1e 106  */
X 107 function getContentHooks() {
108     let d = ecloud.getTaskInfo()
109     let profession = d.valueJson["行业"]
110     let type = d.valueJson["类型"]
111     let level = d.valueJson["权重"]
112     if (profession && type && level) {
113         let query;
114         if (level.includes("|")) {
115             let levels = level.split("|")
116             query = {
117                 "pageNumber": 1,
118                 "pageSize": 1000,
119                 "fields": "content",
120                 "query": `and level in (${levels})`,
121                 "tableNameEn": "content_hooks",
122                 "search": {
123                     "profession": profession,
124                     "type": type,
125                 }
126             };
127         } else {
128             query = {
129                 "pageNumber": 1,
130                 "pageSize": 1000,
131                 "fields": "content",
132                 "query": '',
133                 "tableNameEn": "content_hooks",
134                 "search": {
135                     "profession": profession,
136                     "type": type,
137                     "level": level
138                 }
139             };
140         }
141         let queryr = ecloud.dynamicQuery(query)
142         queryr = JSON.parse(queryr)
143         if (queryr.result.data.length < 0) {
144             // 脚本异常
145             randomSleep("未获取到互动话术", "脚本异常", "", "", "", "");
146         } else {
147             let obj = queryr.result.data
148             for (let i = 0; i < obj.length; i++) {
149                 replyWords.push(obj[i].content)
150             }
151         }
152     } else {
153         randomSleep("参数信息不完整", "脚本异常", "", "", "", "");
154     }
155 }
156
b2d3f7 157 /**
P 158  *  逐一获取用户id,准备私信
159  */
bc5e1e 160 function getUserId() {
X 161     randomNum = Math.floor(Math.random() * (96 - 90 + 1)) + 90;
162     for (let i = 0; i < devices.length; i++) {
163         if (devices[i].equals(ecloud.getDeviceNo())) {
164             let arr = distributedUserIds[i]
165             randomSleep("设备:" + ecloud.getDeviceNo() + "分配id数量:" + arr.length, "私信数量", "", "", "", "")
166             for (let j = 0; j < arr.length; j++) {
167                 if (arr[j] != null && arr[j] !== '') {
168                     try {
169                         let catchMess = deviceCountCatch(ecloud.getDeviceNo(), formatDate(getCurrentDate()))
170                         if (catchMess) {
b2d3f7 171                             let check = checkIsFollowed(arr[j])
bc5e1e 172                             if (check) {
X 173                                 sendMessage(arr[j])
174                             } else {
175                                 continue;
176                             }
177                         } else {
178                             randomSleep("私信已达上限,停止任务", "", "", "", "", "")
179                             home();
180                             exit()
181                             break;
182                         }
183                     } catch (e) {
184                         logd(e);
185                         randomSleep("脚本异常" + e, "脚本异常", "", "", "", "");
186                         isHome()
187                         continue
188                     }
189                 }
190             }
191         }
192     }
193     randomSleep("脚本运行结束", "脚本运行结束", "", "", "", "");
194     home();
195     exit();
196 }
197
198 /**
199  * description 通过包名启动应用
200  * @param packageName {string} : 应用包名
201  * @param delay {number} : 启动后等待时长(毫秒)
202  * @param startNum {number} : 重试次数
203  * @return {boolean} : 返回是否成功
204  */
205 function launch(packageName, delay, startNum) {
206     let result = false;
207     //判断应用的包名是否存在
208     if (utils.isAppExist(packageName)) {
209         //判断应用是否在前台
210         if (getRunningPkg() == null) {
211             toast('请开启辅助功能权限');
212             exit();
213         } else if (getRunningPkg() === packageName) {
214             logd('应用已经在前台');
215             alert(); //应用启动后处理弹窗
216             operaLog(1, null);
217             getUserId();
218         } else {
219             logd('启动应用...');
220             let alert_selectors = text("允许");
221             let num = 0;
222             //判断应用是否启动成功
223             while (num < startNum) {
224                 if (getRunningPkg() === packageName) {
225                     logd('启动成功');
226                     randomSleep("脚本启动成功,版本:" + scriptVersion, "应用启动", "", "", "", "");
227                     result = true;
228                     alert(); //应用启动后处理弹窗
229                     operaLog(1, null);
230                     getUserId();
231                     break;
232                 } else if (has(alert_selectors)) {
233                     //初次打开应用 可能会弹出是否允许打开的弹窗
234                     let node = alert_selectors.getOneNodeInfo(1000);
235                     if (node) {
236                         node.click();
237                     }
238                 } else {
239                     utils.openApp(packageName);
240                     sleep(delay);
241                     num++;
242                 }
243             }
244         }
245     } else {
246         toast('应用未安装');
247         randomSleep("应用未安装", "", "", "", "", "");
248         exit();
249     }
250     return result;
251 }
252
253 /**
b2d3f7 254  * description 搜索指定抖音号,准备私信
P 255  * @param userId
256  * @returns {boolean}
bc5e1e 257  */
X 258 function sendMessage(userId) {
259     let result = false;
260     //定位到首页
261     thread.execSync(function () {
262         isHome();
263     }, 1000);
264     let search = desc("搜索").getOneNodeInfo(randomSleep("准备点击搜索按钮", "", "", "", "", ""));
265     //寻找搜索出现并点击
266     if (search.click()) {
267         let input_selectors = clz("android.widget.EditText");
268         randomSleep("点击搜索按钮,准备搜索用户id:" + userId, "", "", "", "", "")
269         //寻找输入框 输入关键词
270         if (inputText(input_selectors, userId)) {
271             randomSleep("搜索框输入用户id:" + userId, "", "", userId, "", "")
272             //开始搜索
273             if (search.click()) {
274                 randomSleep("点击搜索按钮", "搜索", "", userId, "", "")
275                 operaLog(2, userId);
276                 //打开用户页 进入用户列表
277                 let tab_node = clz("android.widget.Button").getNodeInfo(randomSleep("准备点击用户按钮", "", "", "", "", ""));
278                 for (let i = 0; i < tab_node.length; i++) {
279                     if (tab_node[i].text === "用户") {
280                         tab_node[i].click();
281                         randomSleep("点击用户按钮", "", "", userId, "", "")
282                         let nodeInfo = clz("androidx.recyclerview.widget.RecyclerView").getNodeInfo(3000);
283                         for (let j = 0; j < nodeInfo.length; j++) {
284                             if (nodeInfo[j].allChildren().length > 6) {
285                                 nodeInfo[j].allChildren()[0].click()
286                                 sleep(3000);
287                                 let oneNodeInfo = textMatch(".*抖音号:.*").getOneNodeInfo(2000);
288                                 if (oneNodeInfo) {
289                                     let dyNo = oneNodeInfo.text.split(":")[1].split("按钮")[0]
290                                     if (dyNo === userId.trim()) {
291                                         operaLog(3, null);
292                                         let words = replyWords[random(0, replyWords.length - 1)];
293                                         send(words, userId);
294                                         operaLog(6, null)
295                                     } else {
296                                         randomSleep("搜索抖音号与打开用户抖音号不一致", "", "", "", "", "")
297                                         updateUserStatus(userId)
298                                         continue
299                                     }
300                                 }
301                             }
302                         }
303                     }
304                 }
305             } else {
306                 loge('未找到搜索按钮,搜索失败');
307                 randomSleep("搜索失败", "", "", "", "", "")
308             }
309         } else {
310             loge('未找到输入框,输入失败');
311             randomSleep("未找到输入框,输入失败", "", "", "", "", "")
312         }
313     } else {
314         loge('未找到搜索按钮,搜索失败');
315         randomSleep("未找到搜索按钮,搜索失败", "", "", "", "", "")
316     }
317     return result;
318 }
319
320 /**
321  * description 发私信消息
322  * @param words 私信话术 私信时随机抽取
323  * @return {boolean} : 返回是否成功
324  */
325 function send(words, userId) {
326     let more = desc("更多").getOneNodeInfo(randomSleep("准备点击更多按钮", "", "", "", "", ""));
327     if (more) {
328         more.click()
329         randomSleep("点击更多按钮", "", "", "", "", "")
330         let sendMess = text("发私信").getOneNodeInfo(randomSleep("准备点击发私信按钮", "", "", userId, "", ""));
331         if (sendMess) {
332             sendMess.click()
333             randomSleep("点击发私信按钮", "", "", userId, "", "")
334             let input_selectors = clz("android.widget.EditText");
335             let log = "点击私信按钮,准备输入消息:" + words
336             randomSleep(log, "", "", userId, "", "")
337             //寻找输入框 输入话术
338             if (inputText(input_selectors, words)) {
339                 randomSleep("输入私信消息:" + words + ",准备发送", "", "", userId, words, "")
340                 let send_btn = desc("发送").getOneNodeInfo(1000);
341                 if (send_btn.click()) {
342                     randomSleep("点击发送按钮,执行私信操作完毕", "私信用户", "", userId, words, "")
343                     // 记录已关注已私信
344                     followLog(userId, ecloud.getDeviceNo(), words)
345                     recordDevicecatch(ecloud.getDeviceNo(), formatDate(getCurrentDate()))
346                     operaLog(5, words);
347                     // 回到首页
348                     isHome();
349                 } else {
350                     randomSleep("没有找到发送按钮", "", "", "", "", "")
351                 }
352             } else {
353                 randomSleep("输入私信消息失败", "", "", "", "", "")
354             }
355         } else {
356             randomSleep("没有找到发私信按钮", "", "", "", "", "")
357         }
358     } else {
359         randomSleep("没有找到更多按钮", "", "", "", "", "")
360     }
361 }
362
363 /**
364  * 设备用户关注记录
365  * @param uniqueNo
366  * @param deviceNo
367  */
368 function followLog(uniqueNo, deviceNo, words) {
369     let paltform = '';
370     if ('com.ss.android.ugc.aweme'.equals(packageName)) {
371         // 斗音
372         paltform = 'DY'
373     } else if ('com.xingin.xhs'.equals(packageName)) {
374         // 小红书
375         paltform = 'XHS'
376     } else if ('com.smile.gifmaker'.equals(packageName)) {
377         // 快手
378         paltform = 'KS'
379     }
a42267 380     var url = "http://111.229.137.199:8091/engine/api/device/user";
bc5e1e 381     var pa = {
X 382         "uniqueNo": uniqueNo,
383         "deviceNo": deviceNo,
384         "isFollow": 1,
385         "isChat": 1,
386         "platform": paltform,
387         "tenantId": tenantId,
388         "chatContent": words,
389     };
390     var x = http.postJSON(url, pa, 10 * 1000, {"Authorization": "jwjk2024@!"});
391     x = JSON.parse(x)
392     if (x.code == 200) {
393         randomSleep("私信成功,记录已关注、已私信", "", "", uniqueNo, "", "")
394     } else {
395         randomSleep("私信失败,联系管理员", "", "", uniqueNo, "", "")
396     }
397 }
398
399 /**
400  * 用户dyno不匹配
401  * @param uniqueNo
402  */
403 function updateUserStatus(uniqueNo) {
404     let paltform = '';
405     if ('com.ss.android.ugc.aweme'.equals(packageName)) {
406         // 斗音
407         paltform = 'DY'
408     } else if ('com.xingin.xhs'.equals(packageName)) {
409         // 小红书
410         paltform = 'XHS'
411     } else if ('com.smile.gifmaker'.equals(packageName)) {
412         // 快手
413         paltform = 'KS'
414     }
a42267 415     var url = "http://111.229.137.199:8091/engine/api/device/user/updateStatus";
bc5e1e 416     var pa = {
X 417         "uniqueNo": uniqueNo,
418         "platform": paltform,
419         "status": '不匹配',
420     };
421     var x = http.postJSON(url, pa, 10 * 1000, {"Authorization": "jwjk2024@!", "tenant-id": tenantId});
422     x = JSON.parse(x)
423     if (x.code == 200) {
424         randomSleep("搜索抖音号与打开用户抖音号不一致日志记录成功", "", "", uniqueNo, "", "")
425     } else {
426         randomSleep("抖音号不一致更新失败,请联系管理员", "", "", uniqueNo, "", "")
427     }
428 }
b2d3f7 429
P 430 /**
431  * description 获取云控参数
432  * @return {boolean} : 返回是否成功
433  */
434 function getECloudData() {
435     let d = ecloud.getTaskInfo()
436     if (d == null) {
437         randomSleep("没有任务信息", "脚本异常", "", "", "", "");
438         return
439     }
440     let bool = d.valueJson["同行账号"]
441     let fanBool = d.valueJson["意向粉丝"]
442     let fansNum = d.valueJson["粉丝量"]
443     let age = d.valueJson["年龄"]
444     let activeTime = d.valueJson["活跃时间"]
445     if (bool === "是") {
446         randomSleep("准备获取同行账号信息", "", "", "", "", "");
447         let url = "http://111.229.137.199:8091/engine/api/device/user/checkPrivateChat";
448         let pa = {
449             "platform": "DY",
450             "fansNum": fansNum,
451             "age": age,
452             "activeTime": activeTime,
453         };
454         let x = http.httpGet(url, pa, 10 * 1000, {"Authorization": "jwjk2024@!", "tenant-id": tenantId});
455         x = JSON.parse(x)
456         if (x.code === 200) {
457             let account = x.data
458             account.forEach(function (item) {
459                 searchUserIds.push(item);
460             });
461             toast('已获取任务数据,开始执行...');
462             randomSleep("以获取任务数据", "", "", "", "", "");
463         } else {
464             toast('未获取到同行账号信息,请联系管理员');
465             randomSleep("未获取到同行账号信息,请联系管理员", "脚本异常", "", "", "", "");
466         }
467     } else if (fanBool === "是") {
468         randomSleep("准备获取意向粉丝", "", "", "", "", "");
469         let url = "http://111.229.137.199:8091/engine/api/device/user/checkFansPrivateChat";
470         let pa = {
471             "platform": "DY",
472             "fansNum": fansNum,
473             "age": age,
474             "activeTime": activeTime,
475         };
476         let x = http.httpGet(url, pa, 10 * 1000, {"Authorization": "jwjk2024@!", "tenant-id": tenantId});
477         x = JSON.parse(x)
478         if (x.code === 200) {
479             let fans = x.data
480             if (fans !== null && fans !== '') {
481                 fans.forEach(function (item) {
482                     searchUserIds.push(item);
483                 });
484                 toast('已获取任务数据,开始执行...');
485                 randomSleep("已获取意向粉丝数据", "", "", "", "", "");
486             } else {
487                 toast('意向粉丝数据为空');
488                 randomSleep("意向粉丝数据为空", "", "", "", "", "");
489             }
490         } else {
491             toast('未获取到意向粉丝信息,请联系管理员');
492             randomSleep("未获取到意向粉丝信息,请联系管理员", "脚本异常", "", "", "", "");
493         }
494     }
495     let url = "http://111.229.137.199:8091/engine/api/device/user/checkPrivateUser";
496     let pa = {
497         "platform": "DY",
498         "fansNum": fansNum,
499         "age": age,
500         "activeTime": activeTime,
501     };
502     let x = http.httpGet(url, pa, 10 * 1000, {"Authorization": "jwjk2024@!", "tenant-id": tenantId});
503     x = JSON.parse(x)
504     if (x.code === 200) {
505         let account = x.data
506         account.forEach(function (item) {
507             searchUserIds.push(item);
508         });
509         toast('已获取任务数据,开始执行...');
510         randomSleep("已获取任务数据", "", "", "", "", "");
511     } else {
512         toast('未获取到账号信息,请联系管理员');
513         randomSleep("未获取到账号信息,请联系管理员", "脚本异常", "", "", "", "");
514     }
515     // 获取私信话术
516     getContentHooks()
517 }
518
bc5e1e 519
X 520 /**
521  * description 自定义返回函数
522  * @param page {number} : 返回页数
523  */
524 function go_back(page) {
525     let count = 0;
526     while (count < page) {
527         back();
528         count++;
529         randomSleep("返回上一页", "", "", "", "", "");
530     }
531 }
532
533
534 /**
535  * description 异步执行线程 处理弹窗
536  * @return {boolean} : 返回是否成功
537  */
538 function alert() {
539     thread.execAsync(function () {
540         logd('启动线程,查找弹窗');
541         let btnText = ["下次再说",
542             "以后再说",
543             "关闭",
544             "允许",
545             "暂不",
546             "暂时不要",
547             "我知道了",
548             "知道了",
549             "取消",
550             "请完成下列验证后继续",
551             "按住左边按钮拖动完成上方拼图",
552             "以后再说"];
553         while (true) {
554             for (let i = 0; i < btnText.length; i++) {
555                 if (btnText[i] === "请完成下列验证后继续" && btnText[i] === "按住左边按钮拖动完成上方拼图") {
556                     let message = "任务 “" + ecloud.getTaskInfo().taskName + "”在租户:" + tenantId + " 的设备 “" + ecloud.getDeviceNo() + "” 遇到滑块验证,需要人工处理"
557                     sendDingDing(message, null, false)
558                     // 脚本暂停
559                     setScriptPause(true,0)
560                     break;
561                 }
562                 let node = text(btnText[i]).getOneNodeInfo(1000);
563                 if (node) {
564                     node.click();
565                     logd('弹窗已处理');
566                     randomSleep("弹窗处理完毕", "", "", "", "", "")
567                 }
568             }
569         }
570     });
571     return true;
572 }
573
574 /**
575  * 发送钉钉群消息
576  * @param message {string} : 消息
577  * @param atMobile {string} : at手机号,多个用英文逗号隔开
578  * @param atAll {boolean} : 是否at所有人
579  * @return {boolean} : 返回是否成功
580  */
581 function sendDingDing(message, atMobile, atAll) {
582     let now = Date.now();
583     if (lastCallTime === null || (now - lastCallTime) >= 3600000) {
584         let d = ecloud.getTaskInfo();
585         if (d) {
586             let url = "https://oapi.dingtalk.com/robot/send?access_token=265bc1e546e825e006ea0a95bdd36e2964611bd11f5ce02d3d9ae9cd7fc7f018"
587             let sec = "SECbc87bb55413c0ee75e7630c4f2ab62ea1fc1845517cc6a65561d4864c426b9d4"
588             let res = sendDingDingMsg(url, sec, message, atMobile, atAll);
589             if (JSON.parse(res).errorCode === 0) {
590                 result = true;
591             }
592         }
593         lastCallTime = now;
594     } else {
595         logd("sendDingDing()方法在一个小时之内已经被调用过了,不会再次执行。");
596     }
597 }
598
599 /**
600  * 记录埋点数据
601  */
602 function operaLog(num, words) {
603     let paltform = '';
604     let operateType = '';
605     let uniqueNo = '';
606     if (num === 1) {
607         operateType = '应用启动'
608     } else if (num === 2) {
609         operateType = '搜索'
610     } else if (num === 3) {
611         operateType = '浏览主页'
612     } else if (num === 4) {
613         operateType = '关注用户'
614     } else if (num === 5) {
615         operateType = '私信'
616     } else if (num === 6) {
617         operateType = '脚本运行结束'
618     }
619     if ('com.ss.android.ugc.aweme'.equals(packageName)) {
620         // 斗音
621         paltform = 'DY'
622         uniqueNo = ecloud.getDeviceNo().substring(3)
623     } else if ('com.xingin.xhs'.equals(packageName)) {
624         // 小红书
625         paltform = 'XHS'
626         uniqueNo = ecloud.getDeviceNo().substring(4)
627     } else if ('com.smile.gifmaker'.equals(packageName)) {
628         // 快手
629         paltform = 'KS'
630         uniqueNo = ecloud.getDeviceNo().substring(3)
631     }
632     let add = {
633         "tableNameEn": "trace",
634         "columns": {
635             "device_no": ecloud.getDeviceNo(),
636             "platform": paltform,
637             "unique_no": uniqueNo,
638             "post_name": '',
639             "nickname": '',
640             "keyword": words,
641             "operate_type": operateType,
642             "operate_time": getDate(),
643             "task_id": ecloud.getTaskInfo().taskId,
644             "task_name": ecloud.getTaskInfo().taskName,
645             "tenant_id": tenantId,
646         }
647     }
648     ecloud.dynamicAdd(add)
649     logd("privateLetter 数据保存成功");
650 }
651
652 /**
653  * 记录设备操作记录日志
654  */
655 function deviceOperaLog(operateType, logDetail, intervals, tarPostName, tarUniqueNo, tarComment, tarNickname, time) {
656     let paltform = '';
657     let uniqueNo = '';
658     if ('com.ss.android.ugc.aweme'.equals(packageName)) {
659         // 斗音
660         paltform = 'DY'
661         uniqueNo = ecloud.getDeviceNo().substring(3)
662     } else if ('com.xingin.xhs'.equals(packageName)) {
663         // 小红书
664         paltform = 'XHS'
665         uniqueNo = ecloud.getDeviceNo().substring(4)
666     } else if ('com.smile.gifmaker'.equals(packageName)) {
667         // 快手
668         paltform = 'KS'
669         uniqueNo = ecloud.getDeviceNo().substring(3)
670     }
671     let add = {
672         "tableNameEn": "device_log",
673         "columns": {
674             "unique_no": uniqueNo,
675             "platform": paltform,
676             "device_no": ecloud.getDeviceNo(),
677             "task_name": ecloud.getTaskInfo().taskName,
678             "log_detail": logDetail,
679             "operate_type": operateType,
680             "intervals": intervals + "ms",
681             "operate_time": getDate(),
682             "tar_post_name": tarPostName,
683             "tar_unique_no": tarUniqueNo,
684             "tar_comment": tarComment,
685             "tar_nickname": tarNickname,
686             "task_id": ecloud.getTaskInfo().taskId,
687             "tenant_id": tenantId,
688             "serial_num": time
689         }
690     }
691     ecloud.dynamicAdd(add)
692 }
693
694 /**
695  * description 定位到首页
696  * @return {boolean} : 返回是否成功
697  */
698 function isHome() {
699     let result = false;
700
701     let map = { "uri": "snssdk1128://feed/" };
702     if (utils.openActivity(map)) {
703         toast('已定位首页');
704         randomSleep("已定位到首页", "", "", "", "", "");
705         result = true;
706     } else {
707         randomSleep("跳转首页失败", "脚本异常", "", "", "", "");
708         exit()
709     }
710
711     // let num = 0;
712     // while (true) {
713     //     var home_selectors = text("首页").getOneNodeInfo(3000); //首页按钮
714     //     var message_selectors = text("消息").getOneNodeInfo(3000); //消息按钮
715     //     //判断是否在首页
716     //     if (home_selectors && message_selectors) {
717     //         var follow_selectors = text("关注"); //关注按钮
718     //         var recommend_selectors = text("推荐"); //推荐按钮
719     //         if (has(follow_selectors) && has(recommend_selectors)) {
720     //             toast('已定位首页');
721     //             randomSleep("已定位到首页", "", "", "", "", "");
722     //             result = true;
723     //             break;
724     //         } else {
725     //             home_selectors.click();
726     //             sleep(3000);
727     //         }
728     //     } else {
729     //         toast('返回首页...');
730     //         //返回上一页
731     //         go_back(1);
732     //     }
733     //     num++;
734     //     if (num > 10) {
735     //         // 异常返回桌面 停止脚本
736     //         randomSleep("异常返回桌面 停止脚本", "脚本异常", "", "", "", "");
737     //         exit()
738     //         break;
739     //     }
740     // }
741     return result;
742 }
743
744 /**
b2d3f7 745  * description 随机暂停时间
P 746  */
747 function randomSleep(log, opeType, tarPostName, tarUniqueNo, tarComment, tarNickname) {
748     let min = Math.ceil(30);
749     let max = Math.floor(60);
750     let times = (Math.floor(Math.random() * (max - min + 1)) + min) * 100;
751     logd(log + ",停留" + times + "ms");
752     logd("操作类型" + opeType ? opeType : "");
753     // 记录设备操作日志
754     if (opeType === "脚本启动" || opeType === "脚本运行结束") {
755         let serialNum = time()
756         logd("时间戳" + serialNum);
757         deviceOperaLog(opeType, log + ",停留" + times + "ms", times, tarPostName, tarUniqueNo, tarComment, tarNickname, serialNum)
758     } else {
759         deviceOperaLog(opeType, log + ",停留" + times + "ms", times, tarPostName, tarUniqueNo, tarComment, tarNickname, null)
760     }
761     sleep(times);
762     return times;
763 }
764
765
766 /**
bc5e1e 767  * description 获取当前时间
X 768  * @return {string} : 返回时间
769  */
770 function getDate() {
771     let date = new Date();
772     let sign2 = ":";
773     let year = date.getFullYear() // 年
774     let month = date.getMonth() + 1; // 月
775     let day = date.getDate(); // 日
776     let hour = date.getHours(); // 时
777     let minutes = date.getMinutes(); // 分
778     let seconds = date.getSeconds() //秒
779     let weekArr = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期天'];
780     let week = weekArr[date.getDay()];
781     // 给一位数的数据前面加 “0”
782     if (month >= 1 && month <= 9) {
783         month = "0" + month;
784     }
785     if (day >= 0 && day <= 9) {
786         day = "0" + day;
787     }
788     if (hour >= 0 && hour <= 9) {
789         hour = "0" + hour;
790     }
791     if (minutes >= 0 && minutes <= 9) {
792         minutes = "0" + minutes;
793     }
794     if (seconds >= 0 && seconds <= 9) {
795         seconds = "0" + seconds;
796     }
797     return year + "-" + month + "-" + day + " " + hour + sign2 + minutes + sign2 + seconds;
798 }
799
800 /**
801  * 设备私信缓存次数
802  * @param deviceNo 设备编号
803  * @param date 年-月-日
804  */
805 function deviceCountCatch(deviceNo, date) {
806     let paltform = '';
807     if ('com.ss.android.ugc.aweme'.equals(packageName)) {
808         // 斗音
809         paltform = 'DY'
810     } else if ('com.xingin.xhs'.equals(packageName)) {
811         // 小红书
812         paltform = 'XHS'
813     } else if ('com.smile.gifmaker'.equals(packageName)) {
814         // 快手
815         paltform = 'KS'
816     }
817     let cacheKey = paltform + ":" + deviceNo + ":" + date
a42267 818     var url = "http://111.229.137.199:8091/engine/api/device/cache/getValue";
bc5e1e 819     var pa = {
X 820         "cacheKey": cacheKey
821     };
822     var x = http.httpGet(url, pa, 10 * 1000, {"Authorization": "jwjk2024@!", "tenant-id": tenantId});
823     x = JSON.parse(x)
824     if (x.code === 200) {
825         let count = x.data
826         if (count === null) {
827             return true
828         } else {
829             let num = parseInt(count, 10)
830             return num < randomNum;
831         }
832     }
833 }
834
835 /**
836  * 记录设备私信次数
837  */
838 function recordDevicecatch(deviceNo, date) {
839     let paltform = '';
840     if ('com.ss.android.ugc.aweme'.equals(packageName)) {
841         // 斗音
842         paltform = 'DY'
843     } else if ('com.xingin.xhs'.equals(packageName)) {
844         // 小红书
845         paltform = 'XHS'
846     } else if ('com.smile.gifmaker'.equals(packageName)) {
847         // 快手
848         paltform = 'KS'
849     }
850     let cacheKey = paltform + ":" + deviceNo + ":" + date
a42267 851     var url = "http://111.229.137.199:8091/engine/api/device/cache/insertOrUpdate";
bc5e1e 852     var pa = {
X 853         "cacheKey": cacheKey
854     };
855     var x = http.httpPost(url, pa, null, 10 * 1000, {"Authorization": "jwjk2024@!", "tenant-id": tenantId});
856     x = JSON.parse(x)
857     if (x.code === 200) {
858         return true;
859     } else {
860         return false;
861     }
862 }
863
864 // 获取当前日期
865 function getCurrentDate() {
866     return new Date();
867 }
868
869 // 格式化日期为年-月-日
870 function formatDate(date) {
871     const year = date.getFullYear();
872     const month = String(date.getMonth() + 1).padStart(2, '0');
873     const day = String(date.getDate()).padStart(2, '0');
874     const format = 'yyyy-MM-dd'
875     return format
876         .replace('yyyy', year)
877         .replace('MM', month)
878         .replace('dd', day);
879 }
880
881 /**
882  * 获取设备信息
883  */
884 function getDevice() {
885     var d = ecloud.getTaskInfo()
886     taskId = d.taskId
887     scriptVersion = d.scriptVersion
888     taskId = parseInt(taskId, 10)
889     var url = "http://47.120.7.97:8098/openapi/getTask";
890     var pa = {
891         "dataSecret": "test123"
892     };
893     var x = http.postJSON(url, pa, 10 * 1000, {"Authorization": "jwjk2024@!"});
894     x = JSON.parse(x)
895     for (let i = 0; i < x.length; i++) {
896         if (x[i].taskId === taskId) {
897             tenantId = x[i].tenantId
898             if (x[i].deviceNos.includes(",")) {
899                 devices = x[i].deviceNos.split(",")
900                 deviceNum = x[i].deviceNos.split(",").length
901             } else {
902                 devices.push(x[i].deviceNos)
903                 deviceNum = 1
904             }
905         }
906     }
907 }
908
909 /**
910  * 分发用户id给对应设备
911  * @param userIds
912  * @param phoneCount
913  * @returns {*[]}
914  */
915 function distributeUserIdsToDevices(userIds, phoneCount) {
916     if (phoneCount <= 0) {
917         throw new Error('设备数量不能为空!');
918     }
919
920     let chunkSize = Math.ceil(userIds.length / phoneCount);
921
922     let phones = [];
923
924     let startIndex = 0;
925     for (let i = 0; i < phoneCount; i++) {
926         let num = startIndex + chunkSize
927         let endIndex = Math.min(num, userIds.length);
928         phones[i] = userIds.slice(startIndex, endIndex);
929         startIndex = endIndex;
930     }
931     randomSleep("已获取任务数据,并将用户id分发给设备", "", "", "", "", "");
932     return phones;
933 }
934
935 /**
936  * 检查即将私信用户是否已经被私信
937  * @param userId
938  * @returns {boolean}
939  */
b2d3f7 940 function checkIsFollowed(userId) {
bc5e1e 941     let paltform = '';
X 942     let uniqueNo = '';
943     if ('com.ss.android.ugc.aweme'.equals(packageName)) {
944         // 斗音
945         paltform = 'DY'
946         uniqueNo = ecloud.getDeviceNo().substring(3)
947     } else if ('com.xingin.xhs'.equals(packageName)) {
948         // 小红书
949         paltform = 'XHS'
950         uniqueNo = ecloud.getDeviceNo().substring(4)
951     } else if ('com.smile.gifmaker'.equals(packageName)) {
952         // 快手
953         paltform = 'KS'
954         uniqueNo = ecloud.getDeviceNo().substring(3)
955     }
a42267 956     var url = "http://111.229.137.199:8091/engine/api/device/user/checkFollow";
bc5e1e 957     var pa = {
X 958         "platform": paltform,
959         "uniqueNo": userId
960     };
961     var x = http.httpGet(url, pa, 10 * 1000, {"Authorization": "jwjk2024@!"});
962     x = JSON.parse(x)
963     if (x.data == null) {
964         // 该用户其他渠道获取数据 未被私信
965         return true
966     } else if (x.data != null && x.data.isChat === 0 && x.data.isFollow === 0) {
967         // 抓到的数据未被私信
968         return true
969     } else {
970         // 已被私信
971         return false
972     }
973 }
974
975 /**
976  * description 启动自动化
977  * @return {boolean} : 返回自动化服务结果
978  */
979 function autoServiceStart(time) {
980     for (let i = 0; i < time; i++) {
981         if (isServiceOk()) {
982             return true;
983         }
984         let started = startEnv();
985         randomSleep("第' + (i + 1) + '次启动服务结果: " + started, "", "", "", "", "");
986         if (isServiceOk()) {
987             return true;
988         }
989     }
990     return isServiceOk();
991 }
992
993 function updateSendMessStatus(status) {
994     var d = ecloud.getTaskInfo()
995     taskId = d.taskId
996     var url = "http://47.120.7.97:8098/openapi/changeTask";
997     var pa = {
998         "dataSecret": "test123",
999         "taskId": taskId, // 任务ID,在云控建好的
1000         "status": status + "" // 1 停止本地,2 停止远程 0 开启
1001     };
1002     var x = http.postJSON(url, pa, 10 * 1000);
1003     x = JSON.parse(x)
1004     if (x.code === 0) {
1005         // 状态修改成功
1006         if (status === 0) {
1007             randomSleep("私信脚本状态:正常", "", "", "", "", "");
1008         } else if (status === 1) {
1009             randomSleep("私信脚本状态:停止本地", "", "", "", "", "");
1010         } else if (status === 2) {
1011             randomSleep("私信脚本状态:停止远程", "", "", "", "", "");
1012         }
1013     } else {
1014         // 状态修改失败
1015         randomSleep("修改私信脚本状态异常", "", "", "", "", "");
1016     }
1017 }