panchengyong
10 days ago b2d3f7caf927e5b83ec52efb74f1f818dbb15236
commit | author | age
b2d3f7 1 /**
P 2  * description 抖音用户信息抓取
3  * @type {string}
4  */
bc5e1e 5 let packageName = 'com.ss.android.ugc.aweme';
X 6 var searchUserIds
7 var nickname = "",
8     dyNo = "",
9     praiseNum = "",
10     friends = "",
11     follow = "",
12     fans = "",
13     introduction = "",
14     age = "",
15     province = "",
16     city = "",
17     school = "",
18     postNum = "",
19     simiNum = "",
20     prasie = "",
21     comment = "",
22     collect = "",
23     view = "",
24     url = "",
25     postNo = "",
26     share = "",
27     postDesc = "",
28     scriptVersion = "",
29     tenantId = "",
30     sex = "";
31 //toast扩展参数
32 let toastExtra = {
33     "x":(device.getScreenWidth() - 800) / 2,
34     "y":(device.getScreenHeight() - 200) / 2,
35     "textColor":"#ffffff",
36     "duration":30000,
37     "width":800,
38     "height":200,
39 }
b2d3f7 40
bc5e1e 41 run()
X 42
43 /**
44  * description 唤醒设备
45  */
46 function run() {
47     if (!isAccMode()) {
48         toast('非无障碍模式,无法执行脚本', toastExtra);
49         randomSleep("非无障碍模式,无法执行脚本", "", "", "", "", "");
50         exit();
51     }
52     //自动化服务是否正常
53     if (!autoServiceStart(2)) {
54         toast('自动化服务启动失败,无法执行脚本', toastExtra);
55         randomSleep("自动化服务启动失败,无法执行脚本", "", "", "", "", "");
56         exit();
57     }
58     //脚本停止监听
59     setStopCallback(function () {
60         device.cancelKeepingAwake(); //取消保持唤醒状态
61         logd("脚本停止");
62         deviceOperaLog("脚本停止", "脚本停止", 0, "", "", "", "", "")
63         home();
64     });
65     //脚本异常停止监听
66     setExceptionCallback(function (msg) {
67         device.cancelKeepingAwake(); //取消保持唤醒状态
68         logd("脚本异常停止");
69         deviceOperaLog("脚本异常停止", "脚本异常停止", 0, "", "", "", "", "")
70         home();
71     });
72     daemonEnv(true); //守护自动化环境
73     randomSleep("脚本开始运行", "脚本启动", "", "", "", "");
74     //保持设备唤醒
75     importClass(android.os.PowerManager);
76     device.keepAwake(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP);
77     //保持屏幕唤醒
78     device.keepScreenOn();
79     sleep(1000);
80     //息屏设备上滑解锁
81     let lock = id("com.android.systemui:id/notification_stack_scroller").getOneNodeInfo(5000);
82     if (lock) {
83         let screenWidth = device.getScreenWidth();
84         let screenHeight = device.getScreenHeight();
85         let startX = screenWidth / 2;
86         let startY = screenHeight - 200;
87         let endX = screenWidth / 2;
88         let endY = 50;
89         let duration = 2000;
90         swipeToPoint(startX, startY, endX, endY, duration);
91     }
92     getDevice()
93     getECloudData(); //获取用户ids
94     launch(packageName, 6000, 3); //打开抖音
95 }
96
97 /**
98  * description 通过包名启动应用
99  * @param packageName {string} : 应用包名
100  * @param delay {number} : 启动后等待时长(毫秒)
101  * @param startNum {number} : 重试次数
102  * @return {boolean} : 返回是否成功
103  */
104 function launch(packageName, delay, startNum) {
105     let result = false;
106     //判断应用的包名是否存在
107     if (utils.isAppExist(packageName)) {
108         //判断应用是否在前台
109         if (getRunningPkg() == null) {
110             toast('请开启辅助功能权限');
111             exit();
112         } else if (getRunningPkg() === packageName) {
113             logd('应用已经在前台');
114             result = true;
115         } else {
116             logd('启动应用...');
117             let alert_selectors = text("允许");
118             let num = 0;
119             //判断应用是否启动成功
120             while (num < startNum) {
121                 if (getRunningPkg() === packageName) {
122                     logd('启动成功');
123                     randomSleep("脚本启动成功,版本:" + scriptVersion, "脚本启动", "", "", "", "");
124                     result = true;
125                     break;
126                 } else if (has(alert_selectors)) {
127                     //初次打开应用 可能会弹出是否允许打开的弹窗
128                     let node = alert_selectors.getOneNodeInfo(1000);
129                     if (node) {
130                         node.click();
131                     }
132                 } else {
133                     utils.openApp(packageName);
134                     sleep(delay);
135                     num++;
136                 }
137             }
138         }
139         alert(); //应用启动后处理弹窗
140         getUserId()
141     } else {
142         toast('应用未安装');
143         exit();
144     }
145     return result;
146 }
147
148 function getUserId() {
149     for (let i = 0; i < searchUserIds.length; i++) {
150         try {
151             sendMessage(searchUserIds[i])
152         } catch (e) {
153             logd(e);
154             randomSleep("脚本异常", "脚本异常", "", "", "", "");
155             isHome()
156         }
157     }
158     randomSleep("脚本运行结束", "脚本运行结束", "", "", "", "");
159 }
160
161 function sendMessage(userId) {
162     let result = false;
163     //定位到首页
164     thread.execSync(function () {
165         isHome();
166     }, 1000);
167     let search = descMatch(".*搜索.*").getOneNodeInfo(randomSleep("准备点击搜索按钮", "", "", "", "", ""));
168     //寻找搜索出现并点击
169     if (search.click()) {
170         let input_selectors = clz("android.widget.EditText");
171         randomSleep("点击搜索按钮,准备搜索用户id:" + userId, "", "", "", "", "")
172         //寻找输入框 输入关键词
173         if (inputText(input_selectors, userId)) {
174             randomSleep("搜索框输入用户id:" + userId, "", "", userId, "", "")
175             //开始搜索
176             if (search.click()) {
177                 randomSleep("点击搜索按钮", "搜索", "", userId, "", "")
178                 operaLog(2, userId);
179                 //打开用户页 进入用户列表
180                 let tab_node = clz("android.widget.Button").getNodeInfo(randomSleep("准备点击用户按钮", "", "", "", "", ""));
181                 for (let i = 0; i < tab_node.length; i++) {
182                     if (tab_node[i].text === "用户") {
183                         tab_node[i].click();
184                         //抓取用户昵称
185                         randomSleep("点击用户按钮", "", "", userId, "", "")
186                         // 进入用户主页之前
187                         let selector = clz("com.lynx.tasm.behavior.ui.LynxFlattenUI").getOneNodeInfo(randomSleep("准备进入用户主页", "", "", userId, "", ""));
188                         if (selector.click()) {
189                             operaLog(3, null);
190                             randomSleep("进入用户主页", "浏览主页", "", userId, "", "")
191                             // 进入用户主页 抓取用户作品信息
192                             grabUserPost(userId)
193                             randomSleep("进入用户主页,抓取用户信息", "浏览主页", "", userId, "", "")
194                         } else {
195                             logd("进入用户主页失败");
196                         }
197                     }
198                 }
199             } else {
200                 loge('搜索失败');
201                 exit();
202             }
203         } else {
204             loge('输入失败');
205             exit();
206         }
207     } else {
208         loge('未找到搜索按钮');
209         exit();
210     }
211     return result;
212 }
213
214 function grabUserPost(userId) {
215     // 获取作品数量
216     let node = textMatch(".*作品.*").getOneNodeInfo(2000)
217     let num = node.text.split(" ")[1]
218     num = parseInt(num)
219     let nodes = id("com.ss.android.ugc.aweme:id/container").getNodeInfo(randomSleep("准备点击第一条作品", "", "", "", "", ""));
220     if (nodes) {
221         nodes[0].click()
222         randomSleep("浏览第一条作品", "", "", "", "", "")
223     }
224     if (num > 0) {
225         // 获取作品信息
226         for (let i = 0; i < num - 1; i++) {
227             getPostMessage(userId)
228             // 滑动视频
229             swiper()
230             randomSleep("浏览下一条作品", "", "", "", "", "")
231         }
232     } else {
233         logd("无作品信息");
234     }
235 }
236
237 function getPostMessage(userId) {
238     let node1 = descMatch(".*喜欢.*").getOneNodeInfo(2000);
239     if (node1) {
240         let nodearr1 = node1.desc.split(",")
241         for (let i = 0; i < nodearr1.length; i++) {
242             if (nodearr1[i].includes("喜欢")) {
243                 let match = nodearr1[i].match(/\d+/)
244                 praiseNum = match ? match[0] : "0"
245             }
246         }
247     }
248     let node2 = descMatch(".*评论.*").getOneNodeInfo(2000);
249     if (node2) {
250         let nodearr2 = node2.desc.split(",")
251         for (let i = 0; i < nodearr2.length; i++) {
252             if (nodearr2[i].includes("评论")) {
253                 let match = nodearr2[i].match(/\d+/)
254                 comment = match ? match[0] : "0"
255             }
256         }
257     }
258     let node3 = descMatch(".*收藏.*").getOneNodeInfo(2000);
259     if (node3) {
260         let nodearr3 = node3.desc.split(",")
261         for (let i = 0; i < nodearr3.length; i++) {
262             if (nodearr3[i].includes("收藏")) {
263                 let match = nodearr3[i].match(/\d+/)
264                 collect = match ? match[0] : "0"
265             }
266         }
267     }
268     let node4 = descMatch(".*分享.*").getOneNodeInfo(2000);
269     if (node4) {
270         let nodearr4 = node4.desc.split(",")
271         for (let i = 0; i < nodearr4.length; i++) {
272             if (nodearr4[i].includes("分享")) {
273                 let match = nodearr4[i].match(/\d+/)
274                 share = match ? match[0] : "0"
275             }
276         }
277     }
278     // 视频链接
279     url = getPostUrl()
280     let postDescNode = id("com.ss.android.ugc.aweme:id/desc").getOneNodeInfo(3000);
281     postDesc = postDescNode.text
282     let postTitleNode = id("com.ss.android.ugc.aweme:id/title").getOneNodeInfo(3000);
283     nickname = postTitleNode.text
284
285     // 记录作品信息
286     deviceUserPost(userId, nickname, praiseNum, comment, collect, share, url, postDesc)
287     randomSleep("记录作品相关信息", "", "", "", "", "")
288 }
289
290 function deviceUserPost(userId, nickname, praiseNum, comment, collect, share, url, postDesc) {
291     let paltform = '';
292     let uniqueNo = '';
293     if ('com.ss.android.ugc.aweme'.equals(packageName)) {
294         // 斗音
295         paltform = 'DY'
296         uniqueNo = ecloud.getDeviceNo().substring(3)
297     } else if ('com.xingin.xhs'.equals(packageName)) {
298         // 小红书
299         paltform = 'XHS'
300         uniqueNo = ecloud.getDeviceNo().substring(4)
301     } else if ('com.smile.gifmaker'.equals(packageName)) {
302         // 快手
303         paltform = 'KS'
304         uniqueNo = ecloud.getDeviceNo().substring(3)
305     }
306     let query = {
307         "pageNumber": 1,
308         "pageSize": 2,
309         "fields": "",
310         "query": "",
311         "tableNameEn": "device_user_post",
312         "search": {
313             "unique_no": userId,
314             "post_desc": postDesc,
315             "date": formatDate(new Date())
316         }
317     };
318     let queryr = ecloud.dynamicQuery(query)
319     queryr = JSON.parse(queryr)
320     if (queryr.result.data == null || queryr.result.data == "" || queryr.result.data == {}) {
321         //新增
322         let add = {
323             "tableNameEn": "device_user_post",
324             "columns": {
325                 "task_id": ecloud.getTaskInfo().taskId,
326                 "task_name": ecloud.getTaskInfo().taskName,
327                 "device_no": ecloud.getDeviceNo(),
328                 "platform": paltform,
329                 "unique_no": userId,
330                 "nickname": nickname,
331                 "praise": praiseNum, // 点赞数
332                 "comment": comment, // 评论数
333                 "collect": collect, // 收藏数
334                 "url": url, // 作品url
335                 "check_time": getDate(),
336                 "post_desc": postDesc,
337                 "share": share,
338                 "date": formatDate(new Date()),
339                 "tenant_id": tenantId,
340             }
341         }
342         ecloud.dynamicAdd(add)
343         randomSleep("数据新增成功", "", "", "", "", "")
344     } else {
345         //更新
346         let update = {
347             "tableNameEn": "device_user_post",
348             "columns": {
349                 "task_id": ecloud.getTaskInfo().taskId,
350                 "task_name": ecloud.getTaskInfo().taskName,
351                 "device_no": ecloud.getDeviceNo(),
352                 "platform": paltform,
353                 "unique_no": userId,
354                 "nickname": nickname,
355                 "praise": praiseNum, // 点赞数
356                 "comment": comment, // 评论数
357                 "collect": collect, // 收藏数
358                 "url": url, // 作品url
359                 "check_time": getDate(),
360                 "post_desc": postDesc,
361                 "share": share,
362                 "date": formatDate(new Date()),
363                 "tenant_id": tenantId,
364             },
365             "query": "",
366             "search": {
367                 "unique_no": userId,
368                 "post_desc": postDesc,
369                 "date": formatDate(new Date())
370             }
371         }
372         ecloud.dynamicUpdate(update)
373         randomSleep("数据更新成功", "", "", "", "", "")
374     }
375
376
377 }
378
379 function getPostUrl() {
380     let node = descMatch(".*分享.*").getOneNodeInfo(randomSleep("准备点击分享按钮", "", "", "", "", ""));
381     if (node) {
382         node.click()
383         randomSleep("点击分享按钮", "", "", "", "", "")
384         let share = [textMatch(".*复制链接.*").getOneNodeInfo(3000), textMatch(".*链接分享.*").getOneNodeInfo(3000), textMatch(".*分享至.*").getOneNodeInfo(3000)]
385         for (let i = 0; i < share.length; i++) {
386             if (share[i]) {
387                 share[i].click();
388                 randomSleep("点击复制链接按钮", "", "", "", "", "")
389                 let content = utils.getClipboardText();
390                 clickPoint(device.getScreenWidth() / 2, device.getScreenHeight() / 2);
391                 if (content) {
392                     let index = content.lastIndexOf("http");
393                     let link = content.slice(index);
394                     return link
395                 } else {
396                     return null
397                 }
398             }
399         }
400     }
401 }
402
403 /**
404  * description 获取云控参数
405  * @return {boolean} : 返回是否成功
406  */
407 function getECloudData() {
408
409     let result = false;
410     let hasData = true, value;
411     let data = new Array();
412     let group = [{
413         "groupName": "斗因-设备账号",
414         "dataName": "斗因-设备账号"
415     }];
416     //通过数据组名或数据名称取得数据
417     for (let i = 0; i < group.length; i++) {
418         data = ecloud.getData(group[i]);
419         if (data[0]) {
420             if (i == 0) {
421                 searchUserIds = value = data[0].content.split("\n");
422             }
423             if (!value || value.length == 0) {
424                 hasData = false;
425                 toast('未设置' + group[i].dataName);
426                 break;
427             }
428         } else {
429             hasData = false;
430             toast('未获取' + group[i].dataName);
431             break;
432         }
433     }
434     if (hasData) {
435         toast('已获取任务数据,开始执行...');
436         result = true;
437         // reply();
438     }
439     return result;
440 }
441
442 /**
443  * description 随机暂停时间
444  */
445 function randomSleep(log, opeType, tarPostName, tarUniqueNo, tarComment, tarNickname) {
446     let min = Math.ceil(30);
447     let max = Math.floor(60);
448     let times = (Math.floor(Math.random() * (max - min + 1)) + min) * 100;
449     logd(log + ",停留" + times + "ms");
450     // 记录设备操作日志
451     if (opeType === "脚本启动" || opeType === "脚本运行结束") {
452         let serialNum = time()
453         deviceOperaLog(opeType, log + ",停留" + times + "ms", times, tarPostName, tarUniqueNo, tarComment, tarNickname, serialNum)
454     }else {
455         deviceOperaLog(opeType, log + ",停留" + times + "ms", times, tarPostName, tarUniqueNo, tarComment, tarNickname,null)
456     }
457     sleep(times);
458     return times;
459 }
460
461 /**
462  * 记录设备操作记录日志
463  */
464 function deviceOperaLog(operateType, logDetail, intervals, tarPostName, tarUniqueNo, tarComment, tarNickname,time) {
465     let paltform = '';
466     let uniqueNo = '';
467     if ('com.ss.android.ugc.aweme'.equals(packageName)) {
468         // 斗音
469         paltform = 'DY'
470         uniqueNo = ecloud.getDeviceNo().substring(3)
471     } else if ('com.xingin.xhs'.equals(packageName)) {
472         // 小红书
473         paltform = 'XHS'
474         uniqueNo = ecloud.getDeviceNo().substring(4)
475     } else if ('com.smile.gifmaker'.equals(packageName)) {
476         // 快手
477         paltform = 'KS'
478         uniqueNo = ecloud.getDeviceNo().substring(3)
479     }
480     let add = {
481         "tableNameEn": "device_log",
482         "columns": {
483             "unique_no": uniqueNo,
484             "platform": paltform,
485             "device_no": ecloud.getDeviceNo(),
486             "task_name": ecloud.getTaskInfo().taskName,
487             "log_detail": logDetail,
488             "operate_type": operateType,
489             "operate_time": getDate(),
490             "intervals": intervals + "ms",
491             "tar_post_name": tarPostName,
492             "tar_unique_no": tarUniqueNo,
493             "tar_comment": tarComment,
494             "tar_nickname": tarNickname,
495             "task_id": ecloud.getTaskInfo().taskId,
496             "tenant_id": tenantId,
497             "serial_num": time
498         }
499     }
500     ecloud.dynamicAdd(add)
501 }
502
503 /**
504  * description 自定义返回函数
505  * @param page {number} : 返回页数
506  */
507 function go_back(page) {
508     let count = 0;
509     while (count < page) {
510         back();
511         count++;
512         randomSleep("返回上一页", "", "", "", "", "");
513     }
514 }
515
516 function swiper() {
517     let result = false;
518     //设定坐标 适配全分辨率
519     let x = device.getScreenWidth() * 7 / 10;
520     let y = device.getScreenHeight() * 8 / 10;
521     let x1 = device.getScreenWidth() * 7 / 10;
522     let y1 = device.getScreenHeight() * 1.5 / 10
523
524     if (rnd_Swipe(x, y, x1, y1, 100, 200, 200)) {
525         result = true;
526     }
527     return result;
528 }
529
530 /**
531  * description 仿真随机带曲线滑动
532  */
533 function rnd_Swipe(qx, qy, zx, zy, time, times, timess) {
534     //qx, qy, zx, zy, time 代表起点x,起点y,终点x,终点y,times,timess =随机时间(times,timess)
535     let time1, xxy, point, dx0, dx1, dx2, dx3, xxyy
536     time1 = random(times, timess)
537
538     xxy = [];
539     point = [];
540     dx0 = {
541         "x": qx,
542         "y": qy
543     }
544
545     dx1 = {
546         "x": random(qx - 100, qx + 100),
547         "y": random(qy, qy + 50)
548     }
549     dx2 = {
550         "x": random(zx - 100, zx + 100),
551         "y": random(zy, zy + 50),
552     }
553     dx3 = {
554         "x": zx,
555         "y": zy
556     }
557     for (let i = 0; i < 4; i++) {
558         eval("point.push(dx" + i + ")");
559     }
560     for (let i = 0; i < 1; i += 0.08) {
561         xxyy = [parseInt(bezier_curves(point, i).x), parseInt(bezier_curves(point, i).y)]
562         xxy.push(xxyy);
563     }
564     gesture(xxy, time, time1);
565
566     return true;
567 }
568
569 /**
570  * description 贝赛尔曲线
571  */
572 function bezier_curves(cp, t) {
573     let cx, bx, ax, cy, by, ay, tSquared, tCubed, result
574     cx = 3.0 * (cp[1].x - cp[0].x);
575     bx = 3.0 * (cp[2].x - cp[1].x) - cx;
576     ax = cp[3].x - cp[0].x - cx - bx;
577     cy = 3.0 * (cp[1].y - cp[0].y);
578     by = 3.0 * (cp[2].y - cp[1].y) - cy;
579     ay = cp[3].y - cp[0].y - cy - by;
580
581     tSquared = t * t;
582     tCubed = tSquared * t;
583     result = {
584         "x": 0,
585         "y": 0
586     }
587     result.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x;
588     result.y = (ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y;
589     return result;
590 }
591
592 /**
593  * description 手势
594  */
595 function gesture(swipeList, time, time1) {
596     let touch1, touch2, x, i
597     touch1 = [{"action": 0, "x": swipeList[0][0], "y": swipeList[0][1], "pointer": 1, "delay": time}]
598
599     for (i in swipeList) {
600         ++i;
601         if (i === swipeList.length - 2) {
602             break;
603         }
604         touch1.push({"action": 1, "x": swipeList[i][0], "y": swipeList[i][1], "pointer": 1, "delay": time});
605     }
606     touch1.push({
607         "action": 2,
608         "x": swipeList[swipeList.length - 1][0],
609         "y": swipeList[swipeList.length - 1][1],
610         "pointer": 1,
611         "delay": time
612     })
613
614     x = multiTouch(touch1, null, null, time1);
615     sleep(2000);
616 }
617
618 /**
619  * description 异步执行线程 处理弹窗
620  * @return {boolean} : 返回是否成功
621  */
622 function alert() {
623     thread.execAsync(function () {
624         logd('启动线程,查找弹窗');
625         let btnText = ["下次再说",
626             "以后再说",
627             "关闭",
628             "允许",
629             "暂不",
630             "暂时不要",
631             "我知道了",
632             "知道了",
633             "取消",
634             "以后再说"];
635         while (true) {
636             for (let i = 0; i < btnText.length; i++) {
637                 let node = text(btnText[i]).getOneNodeInfo(1000);
638                 if (node) {
639                     node.click();
640                     logd('弹窗已处理');
641                 }
642             }
643         }
644     });
645     return true;
646 }
647
648 /**
649  * description 获取当前时间
650  * @return {string} : 返回时间
651  */
652 function getDate() {
653     let date = new Date();
654     let sign2 = ":";
655     let year = date.getFullYear() // 年
656     let month = date.getMonth() + 1; // 月
657     let day = date.getDate(); // 日
658     let hour = date.getHours(); // 时
659     let minutes = date.getMinutes(); // 分
660     let seconds = date.getSeconds() //秒
661     let weekArr = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期天'];
662     let week = weekArr[date.getDay()];
663     // 给一位数的数据前面加 “0”
664     if (month >= 1 && month <= 9) {
665         month = "0" + month;
666     }
667     if (day >= 0 && day <= 9) {
668         day = "0" + day;
669     }
670     if (hour >= 0 && hour <= 9) {
671         hour = "0" + hour;
672     }
673     if (minutes >= 0 && minutes <= 9) {
674         minutes = "0" + minutes;
675     }
676     if (seconds >= 0 && seconds <= 9) {
677         seconds = "0" + seconds;
678     }
679     return year + "-" + month + "-" + day + " " + hour + sign2 + minutes + sign2 + seconds;
680 }
681
682 // 格式化日期为年-月-日
683 function formatDate(date) {
684     const year = date.getFullYear();
685     const month = String(date.getMonth() + 1).padStart(2, '0');
686     const day = String(date.getDate()).padStart(2, '0');
687     const format = 'yyyy-MM-dd'
688     return format
689         .replace('yyyy', year)
690         .replace('MM', month)
691         .replace('dd', day);
692 }
693
694 /**
695  * description 定位到首页
696  * @return {boolean} : 返回是否成功
697  */
698 function isHome() {
699     let result = false;
700     while (true) {
701         var home_selectors = text("首页").getOneNodeInfo(3000); //首页按钮
702         var message_selectors = text("消息").getOneNodeInfo(3000); //消息按钮
703         //判断是否在首页
704         if (home_selectors && message_selectors) {
705             var follow_selectors = text("关注"); //关注按钮
706             var recommend_selectors = text("推荐"); //推荐按钮
707             if (has(follow_selectors) && has(recommend_selectors)) {
708                 toast('已定位首页');
709                 randomSleep("定位到首页", "", "", "", "", "");
710                 result = true;
711                 break;
712             } else {
713                 home_selectors.click();
714                 sleep(3000);
715             }
716         } else {
717             toast('返回首页...');
718             //返回上一页
719             go_back(1);
720         }
721     }
722     return result;
723 }
724
725 /**
726  * 记录埋点数据
727  */
728 function operaLog(num) {
729     let paltform = '';
730     let operateType = '';
731     let uniqueNo = '';
732     if (num === 1) {
733         operateType = '应用启动'
734     } else if (num === 2) {
735         operateType = '点击消息'
736     } else if (num === 3) {
737         operateType = '点击互动消息'
738     } else if (num === 4) {
739         operateType = '脚本运行结束'
740     }
741     if ('com.ss.android.ugc.aweme'.equals(packageName)) {
742         // 斗音
743         paltform = 'DY'
744         uniqueNo = ecloud.getDeviceNo().substring(3)
745     } else if ('com.xingin.xhs'.equals(packageName)) {
746         // 小红书
747         paltform = 'XHS'
748         uniqueNo = ecloud.getDeviceNo().substring(4)
749     } else if ('com.smile.gifmaker'.equals(packageName)) {
750         // 快手
751         paltform = 'KS'
752         uniqueNo = ecloud.getDeviceNo().substring(3)
753     }
754     let add = {
755         "tableNameEn": "trace",
756         "columns": {
757             "device_no": ecloud.getDeviceNo(),
758             "platform": paltform,
759             "unique_no": uniqueNo,
760             "post_name": '',
761             "nickname": '',
762             "keyword": '',
763             "operate_type": operateType,
764             "operate_time": getDate(),
765             "task_id": ecloud.getTaskInfo().taskId,
766             "task_name": ecloud.getTaskInfo().taskName,
767             "tenant_id": tenantId,
768         }
769     }
770     ecloud.dynamicAdd(add)
771 }
772
773 /**
774  * 获取设备信息
775  */
776 function getDevice() {
777     var d = ecloud.getTaskInfo()
778     let taskId = d.taskId
779     taskId = parseInt(taskId,10)
780     scriptVersion = d.scriptVersion
781     var url = "http://47.120.7.97:8098/openapi/getTask";
782     var pa = {
783         "dataSecret": "test123"
784     };
785     var x = http.postJSON(url, pa, 10 * 1000);
786     x = JSON.parse(x)
787     for (let i = 0; i < x.length; i++) {
788         if (x[i].taskId === taskId) {
789             tenantId = x[i].tenantId
790         }
791     }
792 }
793
794 /**
795  * description 启动自动化
796  * @return {boolean} : 返回自动化服务结果
797  */
798 function autoServiceStart(time) {
799     for (let i = 0; i < time; i++) {
800         if (isServiceOk()) {
801             return true;
802         }
803         let started = startEnv();
804         randomSleep("第' + (i + 1) + '次启动服务结果: " + started, "", "", "", "", "");
805         if (isServiceOk()) {
806             return true;
807         }
808     }
809     return isServiceOk();
810 }