├── Auto.js packaging-去更新.apk ├── Auto.js packaging.apk ├── Autojs 4.1.1A-去更新.apk ├── Autojs 4.1.1A.apk ├── README.md ├── dingtalk_jisu.js ├── dingtalk_nq.js ├── dingtalk_wq.js ├── 演示视频.mp4 └── 演示进度截图.png /Auto.js packaging-去更新.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ker-ge/autojs-dingtalk/2c435bf42eba7bf8f1b1dc90d63729815babfcd8/Auto.js packaging-去更新.apk -------------------------------------------------------------------------------- /Auto.js packaging.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ker-ge/autojs-dingtalk/2c435bf42eba7bf8f1b1dc90d63729815babfcd8/Auto.js packaging.apk -------------------------------------------------------------------------------- /Autojs 4.1.1A-去更新.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ker-ge/autojs-dingtalk/2c435bf42eba7bf8f1b1dc90d63729815babfcd8/Autojs 4.1.1A-去更新.apk -------------------------------------------------------------------------------- /Autojs 4.1.1A.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ker-ge/autojs-dingtalk/2c435bf42eba7bf8f1b1dc90d63729815babfcd8/Autojs 4.1.1A.apk -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # autojs-dingtalk 2 | 3 | 在家上班!每天需要打外勤卡、想偷懒写一个自动脚本来定时每天打卡 4 | 5 | 测试机器是闲置的魅族手机,是比较卡的 6 | 7 | 小米手机也已经通过测试 8 | 9 | 已经稳定打卡两周 10 | 11 | ## 注意 12 | 需要打开手机权限,省电策略要开启后台运行 13 | 申请juhe.cn的接口,免费使用:https://www.juhe.cn/docs/api/id/606 -------------------------------------------------------------------------------- /dingtalk_jisu.js: -------------------------------------------------------------------------------- 1 | /** 针对极速打卡,打开软件即可 2 | * 权限记得开 3 | */ 4 | 5 | auto.waitFor(); 6 | 7 | let NowTime = new Date(); //当前时间不戳 8 | 9 | //读取配置 10 | let config = { 11 | "appName": "钉钉", 12 | "stopAppBtn": "强行停止", // 关闭后台运行按钮、不同手机不一样的按钮、强行停止、结束运行、关闭 13 | "stopAppConfirmBtn": "确定", // 确认关闭后台运行按钮 14 | "randomMin": 0, // 随机最小数 15 | "randomMax": 5, // 随机最大数 16 | }; 17 | 18 | let keepScreenOnMinutes = 15; // 保存常亮时间 19 | let sleepTime = 5 * 1000; // 暂停的时间 20 | let sleepTime_app = 60 * 1000; // 暂停的时间 21 | 22 | let $$init = { 23 | start() { 24 | return wakeUp(); 25 | 26 | // 唤醒机器 27 | function wakeUp() { 28 | while (!device.isScreenOn()) { 29 | toastLog("正在唤醒屏幕"); 30 | device.wakeUpIfNeeded(); // 唤醒设备 31 | device.keepScreenOn(keepScreenOnMinutes * 60 * 1000); // 脚本执行时保持屏幕常亮15分钟 32 | sleep(sleepTime); 33 | // 上滑解锁 34 | // swipe(device.width / 2, 1300, device.width / 2, 300, 1000); 35 | swipe(device.width / 2, device.height - 500, device.width / 2, 0, random(16, 18) * 50); 36 | sleep(sleepTime); 37 | home(); // 回到桌面 38 | } 39 | //注册退出事件 40 | events.on("exit", function () { 41 | toastLog('已经全部处理完毕,回到桌面'); 42 | device.keepScreenOn(5000); // 脚本执行结束,常亮5秒钟、5秒后按系统自动设定来自己锁屏 43 | home(); // 回到桌面 44 | }); 45 | 46 | fullChain(); // 开始执行链 47 | } 48 | 49 | // 流程操作链 50 | function fullChain() { 51 | getRangSleep(); // 先随机睡觉 52 | // 先关闭 53 | closeApp(); 54 | // 在打开 55 | openApp(); 56 | } 57 | 58 | // 关闭软件(这个关闭操作根据自己设备具体情况配置) 59 | function closeApp() { 60 | sleep(sleepTime); 61 | toastLog("先关闭"+config.appName+"APP ing"); 62 | let packageName = app.getPackageName(config.appName); 63 | if (!packageName) return postMessage("没有找到可以打开的"+config.appName); 64 | app.openAppSetting(packageName); 65 | text(config.appName).waitFor(); 66 | sleep(sleepTime); 67 | click(config.stopAppBtn); 68 | sleep(sleepTime); 69 | click(config.stopAppConfirmBtn); 70 | sleep(sleepTime); 71 | home(); // 回到桌面 72 | } 73 | 74 | // 打开软件 75 | function openApp() { 76 | sleep(sleepTime); 77 | toastLog("在启动"+config.appName+"APP ing"); 78 | let res = app.launchApp(config.appName); 79 | if (!res) return postMessage("没有找到可以打开的"+config.appName); 80 | sleep(sleepTime_app); // 呆在软件里面的时间 81 | } 82 | 83 | // 随机睡觉的时间 84 | function getRangSleep() { 85 | let randNum = random(config.randomMin, config.randomMax); 86 | toastLog("随机延迟" + randNum + "分钟"); 87 | sleep(randNum * 60 * 1000); 88 | } 89 | 90 | function postMessage(message) { 91 | toastLog(message); 92 | // 发送到微信通知 93 | exit(); 94 | } 95 | }, 96 | 97 | bind() { 98 | return this; 99 | }, 100 | }.bind(); 101 | 102 | $$init.start(); 103 | -------------------------------------------------------------------------------- /dingtalk_nq.js: -------------------------------------------------------------------------------- 1 | // 钉钉自动内勤打卡-wifi范围内 2 | 3 | auto.waitFor(); 4 | 5 | let NowTime = new Date(); //当前时间不戳 6 | 7 | //读取配置 8 | let config = { 9 | "appName": "钉钉", 10 | "stopAppBtn": "强行停止", // 关闭后台运行按钮、不同手机不一样的按钮、强行停止、结束运行、关闭 11 | "stopAppConfirmBtn": "确定", // 确认关闭后台运行按钮 12 | "workTitle": "工作台", 13 | "kaoQinTitle": "考勤打卡", 14 | "randomMin": 0, // 随机最小数 15 | "randomMax": 5, // 随机最大数 16 | "apiUrl": "http://apis.juhe.cn/fapig/calendar/day.php", 17 | "apiKey": "", 18 | }; 19 | 20 | let keepScreenOnMinutes = 5; // 保存常亮时间 21 | let sleepTime = 5 * 1000; // 暂停的时间 22 | let sleepTime_app = 10 * 1000; // 软件暂停的时间、手机比较卡的,可以延长这个时间 23 | // 上下班时间设定,可以设定提前打或者延迟打,弹性 24 | let sbTime = 9 * 3600 + 0 * 60 + 0; // 9:00:00 上班 25 | let xbTime = 18 * 3600 + 0 * 60 + 0; // 18:00:00 下班 26 | let thisTime = NowTime.getHours() * 3600 + NowTime.getMinutes() * 60 + NowTime.getSeconds(); // 当前时间 27 | 28 | let $$init = { 29 | start() { 30 | // 判断是否是放假 31 | // isHoliday(); 32 | 33 | return wakeUp(); 34 | 35 | // 唤醒机器 36 | function wakeUp() { 37 | while (!device.isScreenOn()) { 38 | toastLog("正在唤醒屏幕"); 39 | device.wakeUpIfNeeded(); // 唤醒设备 40 | device.keepScreenOn(keepScreenOnMinutes * 60 * 1000); // 脚本执行时保持屏幕常亮15分钟 41 | sleep(sleepTime); 42 | // 上滑解锁 43 | // swipe(device.width / 2, 1300, device.width / 2, 300, 1000); 44 | swipe(device.width / 2, device.height - 500, device.width / 2, 0, random(16, 18) * 50); 45 | sleep(sleepTime); 46 | home(); // 回到桌面 47 | } 48 | //注册退出事件 49 | events.on("exit", function () { 50 | toastLog('已经全部处理完毕,回到桌面'); 51 | device.keepScreenOn(5000); // 脚本执行结束,常亮5秒钟、5秒后按系统自动设定来自己锁屏 52 | home(); // 回到桌面 53 | }); 54 | 55 | fullChain(); // 开始执行链 56 | } 57 | 58 | // 流程操作链 59 | function fullChain() { 60 | // 先关闭 61 | closeApp(); 62 | // 再打开 63 | openApp(); 64 | // 进入考勤 65 | inKaoqin(); 66 | // 点击打卡 67 | clickDaka(); 68 | } 69 | 70 | // 判断是否是放假 71 | function isHoliday() { 72 | // let nowday = NowTime.getDay(); // 0-周日,6-周六 73 | // if (nowday == 0 || nowday == 6) { 74 | // exit(); // 周末直接停止脚本 75 | // } 76 | let year = NowTime.getFullYear(); 77 | let month = NowTime.getMonth() + 1; 78 | let day = NowTime.getDate(); 79 | day = day > 9 ? day : '0' + day; 80 | let dater = year + "-" + month + "-" + day; 81 | let url = config.apiUrl + "?date=" + dater + "&key=" + config.apiKey; 82 | let res = http.get(url); 83 | // let data = res.body.json(); 84 | // console.log(data); 85 | let statusDesc = res.body.json()['result']['statusDesc']; 86 | if (statusDesc != '工作日') { 87 | toastLog('非工作日,停止脚本'); 88 | engines.myEngine().forceStop(); // 非工作日直接停止脚本 89 | } 90 | } 91 | 92 | // 随机延迟 93 | function randomSleep() { 94 | let randNum = random(config.randomMin, config.randomMax); 95 | toastLog("随机延迟" + randNum + "分钟"); 96 | sleep(randNum * 60 * 1000); // 随机睡觉的数字,分钟为单位 97 | } 98 | 99 | // 关闭软件(这个关闭操作根据自己设备具体情况配置) 100 | function closeApp() { 101 | sleep(sleepTime); 102 | toastLog("先关闭" + config.appName + "APP ing"); 103 | let packageName = app.getPackageName(config.appName); 104 | if (!packageName) return postMessage("没有找到可以打开的" + config.appName); 105 | app.openAppSetting(packageName); 106 | text(config.appName).waitFor(); 107 | sleep(sleepTime); 108 | click(config.stopAppBtn); 109 | sleep(sleepTime); 110 | click(config.stopAppConfirmBtn); 111 | sleep(sleepTime); 112 | home(); // 回到桌面 113 | } 114 | 115 | // 打开软件 116 | function openApp() { 117 | sleep(sleepTime); 118 | toastLog("在启动" + config.appName + "APP ing"); 119 | let res = app.launchApp(config.appName); 120 | if (!res) return postMessage("没有找到可以打开的" + config.appName); 121 | randomSleep(); // 随机睡觉 122 | } 123 | 124 | //进入考勤页面 125 | function inKaoqin() { 126 | sleep(sleepTime_app); // 有时候进入比较慢 127 | clickMessage(config.workTitle); 128 | toastLog("点击" + config.workTitle); 129 | sleep(sleepTime_app); // 有时候进入比较慢 130 | clickMessage(config.kaoQinTitle); 131 | toastLog("点击" + config.kaoQinTitle); 132 | sleep(sleepTime_app); // 有时候进入比较慢 133 | } 134 | 135 | //点击打卡 136 | function clickDaka() { 137 | sleep(sleepTime_app); // 有时候进入比较慢 138 | if (sbTime > thisTime) { // 上班前打卡 139 | text1 = "上班打卡"; 140 | } else if (xbTime < thisTime) { // 下班后打卡 141 | text1 = "下班打卡"; 142 | } 143 | toastLog("进入打卡页, 当前是" + text1); 144 | clickMessage(text1); 145 | sleep(sleepTime_app); // 有时候进入比较慢 146 | postMessage('打卡成功'); 147 | } 148 | 149 | //根据控件文字点击,如果点击失败,则说明打卡流程无法正常进行,结束脚本运行 150 | function clickMessage(message) { 151 | var n = 3; 152 | var logo = false; 153 | while (n--) { 154 | if (click(message)) { 155 | logo = true; 156 | break; 157 | } 158 | sleep(sleepTime); 159 | } 160 | if (logo == false) { 161 | console.error("点击" + message + "出错"); 162 | exit(); 163 | } 164 | } 165 | 166 | function postMessage(message) { 167 | toastLog(message); 168 | // 发送到微信通知 169 | exit(); 170 | } 171 | }, 172 | 173 | bind() { 174 | return this; 175 | }, 176 | }.bind(); 177 | 178 | $$init.start(); 179 | -------------------------------------------------------------------------------- /dingtalk_wq.js: -------------------------------------------------------------------------------- 1 | // 钉钉自动外勤打卡-定位打卡 2 | 3 | auto.waitFor(); 4 | 5 | let NowTime = new Date(); //当前时间不戳 6 | 7 | //读取配置 8 | let config = { 9 | "appName": "钉钉", 10 | "stopAppBtn": "强行停止", // 关闭后台运行按钮、不同手机不一样的按钮、强行停止、结束运行、关闭 11 | "stopAppConfirmBtn": "确定", // 确认关闭后台运行按钮 12 | "workTitle": "工作台", 13 | "kaoQinTitle": "考勤打卡", 14 | "randomMin": 0, // 随机最小数 15 | "randomMax": 5, // 随机最大数 16 | "apiUrl": "http://apis.juhe.cn/fapig/calendar/day.php", 17 | "apiKey": "", 18 | }; 19 | 20 | let keepScreenOnMinutes = 15; // 保存常亮时间 21 | let sleepTime = 5 * 1000; // 暂停的时间 22 | let sleepTime_app = 10 * 1000; // 钉钉暂停的时间 23 | 24 | let $$init = { 25 | start() { 26 | // 判断是否是放假 27 | // isHoliday(); 28 | 29 | return wakeUp(); 30 | 31 | // 唤醒机器 32 | function wakeUp() { 33 | while (!device.isScreenOn()) { 34 | toastLog("正在唤醒屏幕"); 35 | device.wakeUpIfNeeded(); // 唤醒设备 36 | device.keepScreenOn(keepScreenOnMinutes * 60 * 1000); // 脚本执行时保持屏幕常亮15分钟 37 | sleep(sleepTime); 38 | // 上滑解锁 39 | // swipe(device.width / 2, 1300, device.width / 2, 300, 1000); 40 | swipe(device.width / 2, device.height - 500, device.width / 2, 0, random(16, 18) * 50); 41 | sleep(sleepTime); 42 | home(); // 回到桌面 43 | } 44 | //注册退出事件 45 | events.on("exit", function () { 46 | toastLog('已经全部处理完毕,回到桌面'); 47 | device.keepScreenOn(5000); // 脚本执行结束,常亮5秒钟、5秒后按系统自动设定来自己锁屏 48 | home(); // 回到桌面 49 | }); 50 | 51 | fullChain(); // 开始执行链 52 | } 53 | 54 | // 流程操作链 55 | function fullChain() { 56 | // 先关闭 57 | closeApp(); 58 | // 再打开 59 | openApp(); 60 | // 进入考勤 61 | inKaoqin(); 62 | // 进入打卡页 63 | inDaka(); 64 | // 确认定位打卡 65 | confirmDaka(); 66 | } 67 | 68 | // 判断是否是放假 69 | function isHoliday() { 70 | // let nowday = NowTime.getDay(); // 0-周日,6-周六 71 | // if (nowday == 0 || nowday == 6) { 72 | // exit(); // 周末直接停止脚本 73 | // } 74 | let year = NowTime.getFullYear(); 75 | let month = NowTime.getMonth() + 1; 76 | let day = NowTime.getDate(); 77 | day = day > 9 ? day : '0' + day; 78 | let dater = year + "-" + month + "-" + day; 79 | let url = config.apiUrl + "?date=" + dater + "&key=" + config.apiKey; 80 | let res = http.get(url); 81 | // let data = res.body.json(); 82 | // console.log(data); 83 | let statusDesc = res.body.json()['result']['statusDesc']; 84 | if (statusDesc != '工作日') { 85 | toastLog('非工作日,停止脚本'); 86 | engines.myEngine().forceStop(); // 非工作日直接停止脚本 87 | } 88 | } 89 | 90 | // 随机延迟 91 | function randomSleep() { 92 | let randNum = random(config.randomMin, config.randomMax); 93 | toastLog("随机延迟" + randNum + "分钟"); 94 | sleep(randNum * 60 * 1000); // 随机睡觉的数字,分钟为单位 95 | } 96 | 97 | // 关闭软件(这个关闭操作根据自己设备具体情况配置) 98 | function closeApp() { 99 | sleep(sleepTime); 100 | toastLog("先关闭" + config.appName + "APP ing"); 101 | let packageName = app.getPackageName(config.appName); 102 | if (!packageName) return postMessage("没有找到可以打开的" + config.appName); 103 | app.openAppSetting(packageName); 104 | text(config.appName).waitFor(); 105 | sleep(sleepTime); 106 | click(config.stopAppBtn); 107 | sleep(sleepTime); 108 | click(config.stopAppConfirmBtn); 109 | sleep(sleepTime); 110 | home(); // 回到桌面 111 | } 112 | 113 | // 打开软件 114 | function openApp() { 115 | sleep(sleepTime); 116 | toastLog("在启动" + config.appName + "APP ing"); 117 | let res = app.launchApp(config.appName); 118 | if (!res) return postMessage("没有找到可以打开的" + config.appName); 119 | randomSleep(); // 随机睡觉 120 | } 121 | 122 | //进入考勤页面 123 | function inKaoqin() { 124 | sleep(sleepTime_app); // 有时候进入比较慢 125 | clickMessage(config.workTitle); 126 | toastLog("点击" + config.workTitle); 127 | sleep(sleepTime_app); // 有时候进入比较慢 128 | clickMessage(config.kaoQinTitle); 129 | toastLog("点击" + config.kaoQinTitle); 130 | sleep(sleepTime_app); // 有时候进入比较慢 131 | } 132 | 133 | //点击打卡 134 | function inDaka() { 135 | sleep(sleepTime_app); // 有时候进入比较慢 136 | let text = "外勤打卡"; 137 | clickMessage(text); 138 | sleep(sleepTime_app); // 有时候进入比较慢 139 | } 140 | 141 | // 确认定位打卡 142 | function confirmDaka() { 143 | sleep(sleepTime_app); // 有时候进入比较慢 144 | let text = "外勤打卡"; 145 | clickMessage(text); 146 | sleep(sleepTime_app); // 有时候进入比较慢 147 | return postMessage('打卡成功'); 148 | // let scope, x, y; 149 | // let text1 = "0/1000"; 150 | // scope = text(text1).findOne().bounds(); // 找到0/1000的位置,方便计算出打卡的按钮位置 151 | // x = scope.centerX(); 152 | // y = scope.centerY(); 153 | // // console.log(text1, x, y); 154 | // // console.log(device.width, device.height); 155 | // // X轴直接取中间,Y轴需要计算,在0/1000的下方100 156 | // x = device.width * 0.5; 157 | // y = y + 100; 158 | // console.log('打卡坐标:', x, y); 159 | // click(x, y); 160 | // sleep(sleepTime_ding); 161 | // postMessage('打卡成功'); 162 | } 163 | 164 | //根据控件文字点击,如果点击失败,则说明打卡流程无法正常进行,结束脚本运行 165 | function clickMessage(message) { 166 | var n = 3; 167 | var logo = false; 168 | while (n--) { 169 | if (click(message)) { 170 | logo = true; 171 | break; 172 | } 173 | sleep(sleepTime); 174 | } 175 | if (logo == false) { 176 | console.error("点击" + message + "出错"); 177 | exit(); 178 | } 179 | } 180 | 181 | function postMessage(message) { 182 | toastLog(message); 183 | // 发送到微信通知 184 | exit(); 185 | } 186 | }, 187 | 188 | bind() { 189 | return this; 190 | }, 191 | }.bind(); 192 | 193 | $$init.start(); 194 | -------------------------------------------------------------------------------- /演示视频.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ker-ge/autojs-dingtalk/2c435bf42eba7bf8f1b1dc90d63729815babfcd8/演示视频.mp4 -------------------------------------------------------------------------------- /演示进度截图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ker-ge/autojs-dingtalk/2c435bf42eba7bf8f1b1dc90d63729815babfcd8/演示进度截图.png --------------------------------------------------------------------------------