panchengyong
10 days ago b2d3f7caf927e5b83ec52efb74f1f818dbb15236
commit | author | age
bc5e1e 1 /**
b2d3f7 2  * description 消息已读未读状态检测
bc5e1e 3  */
X 4 let packageName = 'com.ss.android.ugc.aweme';
5 let tenantId = "";
6 let scriptVersion = "";
7 //toast扩展参数
8 let toastExtra = {
9     "x":(device.getScreenWidth() - 800) / 2,
10     "y":(device.getScreenHeight() - 200) / 2,
11     "textColor":"#ffffff",
12     "duration":30000,
13     "width":800,
14     "height":200,
15 }
b2d3f7 16
P 17 /**
18  * description 脚本入口
19  */
bc5e1e 20 run()
b2d3f7 21 /**
P 22  * description 跳转消息页面
23  */
24 toMessage();
bc5e1e 25
X 26 /**
27  * description 唤醒设备
28  */
29 function run() {
30     if (!isAccMode()) {
31         toast('非无障碍模式,无法执行脚本', toastExtra);
32         randomSleep("非无障碍模式,无法执行脚本", "", "", "", "", "");
33         exit();
34     }
35     //自动化服务是否正常
36     if (!autoServiceStart(2)) {
37         toast('自动化服务启动失败,无法执行脚本', toastExtra);
38         randomSleep("自动化服务启动失败,无法执行脚本", "", "", "", "", "");
39         exit();
40     }
41     //脚本停止监听
42     setStopCallback(function () {
43         device.cancelKeepingAwake(); //取消保持唤醒状态
44         logd("脚本停止");
45         deviceOperaLog("脚本停止", "脚本停止", 0, "", "", "", "", "")
46         home();
47     });
48     //脚本异常停止监听
49     setExceptionCallback(function (msg) {
50         device.cancelKeepingAwake(); //取消保持唤醒状态
51         logd("脚本异常停止");
52         deviceOperaLog("脚本异常停止", "脚本异常停止", 0, "", "", "", "", "")
53         home();
54     });
55     daemonEnv(true); //守护自动化环境
56     randomSleep("脚本开始运行", "脚本运行", "", "", "", "");
57     //保持设备唤醒
58     importClass(android.os.PowerManager);
59     device.keepAwake(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP);
60     //保持屏幕唤醒
61     device.keepScreenOn();
62     sleep(1000);
63     //息屏设备上滑解锁
64     let lock = id("com.android.systemui:id/notification_stack_scroller").getOneNodeInfo(5000);
65     if (lock) {
66         let screenWidth = device.getScreenWidth();
67         let screenHeight = device.getScreenHeight();
68         let startX = screenWidth / 2;
69         let startY = screenHeight - 200;
70         let endX = screenWidth / 2;
71         let endY = 50;
72         let duration = 2000;
73         swipeToPoint(startX, startY, endX, endY, duration);
74     }
75     getDevice()
76     launch(packageName, 5000, 2); //打开抖音
77 }
78
79 /**
80  * description 通过包名启动应用
81  * @param packageName {string} : 应用包名
82  * @param delay {number} : 启动后等待时长(毫秒)
83  * @param startNum {number} : 重试次数
84  * @return {boolean} : 返回是否成功
85  */
86 function launch(packageName, delay, startNum) {
87     let result = false;
88     //判断应用的包名是否存在
89     if (utils.isAppExist(packageName)) {
90         //判断应用是否在前台
91         if (getRunningPkg() == null) {
92             toast('请开启辅助功能权限');
93             exit();
94         } else if (getRunningPkg() === packageName) {
95             logd('应用已经在前台');
96             result = true;
97         } else {
98             logd('启动应用...');
99             let alert_selectors = text("允许");
100             let num = 0;
101             //判断应用是否启动成功
102             while (num < startNum) {
103                 if (getRunningPkg() === packageName) {
104                     logd('启动成功');
105                     randomSleep("脚本启动成功,版本:" + scriptVersion, "脚本启动", "", "", "", "");
106                     result = true;
107                     break;
108                 } else if (has(alert_selectors)) {
109                     //初次打开应用 可能会弹出是否允许打开的弹窗
110                     let node = alert_selectors.getOneNodeInfo(1000);
111                     if (node) {
112                         node.click();
113                     }
114                 } else {
115                     utils.openApp(packageName);
116                     sleep(delay);
117                     num++;
118                 }
119             }
120         }
121         alert(); //应用启动后处理弹窗
122         operaLog(1);
123     } else {
124         toast('应用未安装');
125         exit();
126     }
127     return result;
128 }
129
b2d3f7 130 /**
P 131  * description 跳转消息页面
132  */
bc5e1e 133 function toMessage() {
X 134     try {
135         //定位到首页
136         execSync(function () {
137             isHome();
138         }, 1000);
139         let message_icon = text("消息").getOneNodeInfo(randomSleep("准备点击消息按钮", "", "", "", "", ""));
140         //寻找消息图标并点击
141         if (message_icon.click()) {
142             operaLog(2);
143             randomSleep("点击消息按钮,进入消息页面", "", "", "", "", "")
144             // 获取已读 回复数量
145             let reply = ''
146             let message_icon = desc("消息,按钮").getOneNodeInfo(2000)
147             if (message_icon) {
148                 let nodeInfo = message_icon.parent().parent();
149                 let siblings = nodeInfo.siblings();
150                 if (siblings) {
151                     // 私信回复数量
152                     reply = siblings[0].allChildren()[0].text;
153                 }
154             }
155             let read = 0
156             while (true) {
157                 let nodeInfo = text("已读 ·").getNodeInfo(2000);
158                 let more = text("暂时没有更多了").getOneNodeInfo(2000);
159                 if (nodeInfo) {
160                     read = nodeInfo.length + read
161                 }
162                 if (more) {
163                     break
164                 }
165                 sleep(3000);
166                 swiper()
167             }
168             updateStatus(read, reply)
169             // 定位到首页
170             isHome();
171             randomSleep("脚本运行结束", "脚本运行结束", "", "", "", "");
172         }
173     } catch (e) {
174         logd(e)
175         randomSleep("脚本异常", "脚本异常", "", "", "", "");
176         isHome()
177     }
178 }
179
180 function swiper() {
181     let screenWidth = device.getScreenWidth();
182     let screenHeight = device.getScreenHeight();
183
184     let startX = screenWidth / 2;
185     let startY = screenHeight - 200;
186     let endX = screenWidth / 2;
187     let endY = 50;
188     let duration = 2000;
189
190     swipeToPoint(startX, startY, endX, endY, duration);
191 }
192
193 function updateStatus(read, reply) {
194     let deviceNo = ecloud.getDeviceNo();
195     let query = {
196         "pageNumber": 1,
197         "pageSize": 2,
198         "fields": "",
199         "query": "",
200         "tableNameEn": "device_user",
201         "search": {
202             "device_no": deviceNo
203         }
204     };
205     let queryr = ecloud.dynamicQuery(query)
206     queryr = JSON.parse(queryr)
207     let replyed = queryr.reply
208     if (replyed !== null && replyed !== '' && replyed !== undefined && replyed !== 'undefined') {
209         reply = parseInt(replyed, 10) + parseInt(reply, 10)
210     }
211     let update = {
212         "tableNameEn": "device_user",
213         "columns": {
214             "readed": read + "",
215             "reply": reply + ""
216         },
217         "query": "",
218         "search": {
219             "device_no": deviceNo
220         }
221     }
222     let updater = ecloud.dynamicUpdate(update)
223     logd("=== {}", updater);
224 }
225
226 /**
227  * 记录设备操作记录日志
228  */
229 function deviceOperaLog(operateType, logDetail, intervals, tarPostName, tarUniqueNo, tarComment, tarNickname,time) {
230     let paltform = '';
231     let uniqueNo = '';
232     if ('com.ss.android.ugc.aweme'.equals(packageName)) {
233         // 斗音
234         paltform = 'DY'
235         uniqueNo = ecloud.getDeviceNo().substring(3)
236     } else if ('com.xingin.xhs'.equals(packageName)) {
237         // 小红书
238         paltform = 'XHS'
239         uniqueNo = ecloud.getDeviceNo().substring(4)
240     } else if ('com.smile.gifmaker'.equals(packageName)) {
241         // 快手
242         paltform = 'KS'
243         uniqueNo = ecloud.getDeviceNo().substring(3)
244     }
245     let add = {
246         "tableNameEn": "device_log",
247         "columns": {
248             "unique_no": uniqueNo,
249             "platform": paltform,
250             "device_no": ecloud.getDeviceNo(),
251             "task_name": ecloud.getTaskInfo().taskName,
252             "log_detail": logDetail,
253             "operate_type": operateType,
254             "intervals": intervals + "ms",
255             "operate_time": getDate(),
256             "tar_post_name": tarPostName,
257             "tar_unique_no": tarUniqueNo,
258             "tar_comment": tarComment,
259             "tar_nickname": tarNickname,
260             "task_id": ecloud.getTaskInfo().taskId,
261             "tenant_id": tenantId,
262             "serial_num": time
263         }
264     }
265     ecloud.dynamicAdd(add)
266 }
267
268 /**
269  * description 获取当前时间
270  * @return {string} : 返回时间
271  */
272 function getDate() {
273     let date = new Date();
274     let sign2 = ":";
275     let year = date.getFullYear() // 年
276     let month = date.getMonth() + 1; // 月
277     let day = date.getDate(); // 日
278     let hour = date.getHours(); // 时
279     let minutes = date.getMinutes(); // 分
280     let seconds = date.getSeconds() //秒
281     let weekArr = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期天'];
282     let week = weekArr[date.getDay()];
283     // 给一位数的数据前面加 “0”
284     if (month >= 1 && month <= 9) {
285         month = "0" + month;
286     }
287     if (day >= 0 && day <= 9) {
288         day = "0" + day;
289     }
290     if (hour >= 0 && hour <= 9) {
291         hour = "0" + hour;
292     }
293     if (minutes >= 0 && minutes <= 9) {
294         minutes = "0" + minutes;
295     }
296     if (seconds >= 0 && seconds <= 9) {
297         seconds = "0" + seconds;
298     }
299     return year + "-" + month + "-" + day + " " + hour + sign2 + minutes + sign2 + seconds;
300 }
301
302 /**
303  * 记录埋点数据
304  */
305 function operaLog(num) {
306     let paltform = '';
307     let operateType = '';
308     let uniqueNo = '';
309     if (num === 1) {
310         operateType = '应用启动'
311     } else if (num === 2) {
312         operateType = '点击消息'
313     } else if (num === 3) {
314         operateType = '点击互动消息'
315     } else if (num === 4) {
316         operateType = '脚本运行结束'
317     }
318     if ('com.ss.android.ugc.aweme'.equals(packageName)) {
319         // 斗音
320         paltform = 'DY'
321         uniqueNo = ecloud.getDeviceNo().substring(3)
322     } else if ('com.xingin.xhs'.equals(packageName)) {
323         // 小红书
324         paltform = 'XHS'
325         uniqueNo = ecloud.getDeviceNo().substring(4)
326     } else if ('com.smile.gifmaker'.equals(packageName)) {
327         // 快手
328         paltform = 'KS'
329         uniqueNo = ecloud.getDeviceNo().substring(3)
330     }
331     let add = {
332         "tableNameEn": "trace",
333         "columns": {
334             "device_no": ecloud.getDeviceNo(),
335             "platform": paltform,
336             "unique_no": uniqueNo,
337             "post_name": '',
338             "nickname": '',
339             "keyword": '',
340             "operate_type": operateType,
341             "operate_time": timeFormat("yyyy-MM-dd HH:mm:ss")+'',
342             "task_id": ecloud.getTaskInfo().taskId,
343             "task_name": ecloud.getTaskInfo().taskName,
344             "tenant_id": tenantId,
345         }
346     }
347     ecloud.dynamicAdd(add)
348 }
349
350 /**
351  * description 异步执行线程 处理弹窗
352  * @return {boolean} : 返回是否成功
353  */
354 function alert() {
355     thread.execAsync(function () {
356         logd('启动线程,查找弹窗');
357         let btnText = ["下次再说",
358             "以后再说",
359             "关闭",
360             "允许",
361             "暂不",
362             "暂时不要",
363             "我知道了",
364             "知道了",
365             "取消"];
366         while (true) {
367             for (let i = 0; i < btnText.length; i++) {
368                 let node = text(btnText[i]).getOneNodeInfo(1000);
369                 if (node) {
370                     node.click();
371                     logd('弹窗已处理');
372                     randomSleep("弹窗处理完毕", "", "", "", "", "")
373                 }
374             }
375         }
376     });
377     return true;
378 }
379
380 /**
381  * description 定位到首页
382  * @return {boolean} : 返回是否成功
383  */
384 function isHome() {
385     let result = false;
386     while (true) {
387         var home_selectors = text("首页").getOneNodeInfo(3000); //首页按钮
388         var message_selectors = text("消息").getOneNodeInfo(3000); //消息按钮
389         //判断是否在首页
390         if (home_selectors && message_selectors) {
391             var follow_selectors = text("关注"); //关注按钮
392             var recommend_selectors = text("推荐"); //推荐按钮
393             if (has(follow_selectors) && has(recommend_selectors)) {
394                 toast('已定位首页');
395                 randomSleep("定位到首页", "", "", "", "", "");
396                 result = true;
397                 break;
398             } else {
399                 home_selectors.click();
400                 sleep(3000);
401             }
402         } else {
403             toast('返回首页...');
404             //返回上一页
405             go_back(1);
406         }
407     }
408     return result;
409 }
410
411 /**
412  * description 自定义返回函数
413  * @param page {number} : 返回页数
414  */
415 function go_back(page) {
416     let count = 0;
417     while (count < page) {
418         back();
419         count++;
420         randomSleep("返回上一页", "", "", "", "", "");
421     }
422 }
423
424 /**
425  * description 随机暂停时间
426  */
427 function randomSleep(log, opeType, tarPostName, tarUniqueNo, tarComment, tarNickname) {
428     let min = Math.ceil(30);
429     let max = Math.floor(60);
430     let times = (Math.floor(Math.random() * (max - min + 1)) + min) * 100;
431     logd(log + ",停留" + times + "ms");
432     // 记录设备操作日志
433     if (opeType === "脚本启动" || opeType === "脚本运行结束") {
434         let serialNum = time()
435         deviceOperaLog(opeType, log + ",停留" + times + "ms", times, tarPostName, tarUniqueNo, tarComment, tarNickname, serialNum)
436     }else {
437         deviceOperaLog(opeType, log + ",停留" + times + "ms", times, tarPostName, tarUniqueNo, tarComment, tarNickname,null)
438     }
439     sleep(times);
440     return times;
441 }
442
443 /**
444  * 获取设备信息
445  */
446 function getDevice() {
447     var d = ecloud.getTaskInfo()
448     let taskId = d.taskId
449     taskId = parseInt(taskId, 10)
450     scriptVersion = d.scriptVersion
451     var url = "http://47.120.7.97:8098/openapi/getTask";
452     var pa = {
453         "dataSecret": "test123"
454     };
455     var x = http.postJSON(url, pa, 10 * 1000);
456     x = JSON.parse(x)
457     for (let i = 0; i < x.length; i++) {
458         if (x[i].taskId === taskId) {
459             tenantId = x[i].tenantId
460         }
461     }
462 }
463
464 /**
465  * description 启动自动化
466  * @return {boolean} : 返回自动化服务结果
467  */
468 function autoServiceStart(time) {
469     for (let i = 0; i < time; i++) {
470         if (isServiceOk()) {
471             return true;
472         }
473         let started = startEnv();
474         randomSleep("第' + (i + 1) + '次启动服务结果: " + started, "", "", "", "", "");
475         if (isServiceOk()) {
476             return true;
477         }
478     }
479     return isServiceOk();
480 }