功能简介
今天更新了抖音直播间自动点赞评论的功能,对应抖音极速版20.6.0版本,其他版本未做测试。
其他功能后面陆续完善。
Auto.js的开发环境搭建查看之前的文章:Auto.js 快速入门教程
项目源码
"ui"; importClass(android.graphics.Color); importClass(android.graphics.drawable.GradientDrawable); importClass(android.text.Spannable); importClass(android.text.SpannableStringBuilder); importClass(android.text.style.ForegroundColorSpan); importClass(android.graphics.LinearGradient); importClass(android.graphics.Shader); importClass(android.graphics.Bitmap); importClass(android.graphics.BitmapFactory); importClass(android.graphics.BitmapShader); //项目配置 let appConfig = {}; appConfig.appName = "抖音智能机器人"; appConfig.versionName = "Ver.1.1.0"; appConfig.packageName = "com.douyin.robot"; appConfig.colorPrimary = "#009688"; appConfig.colorSecondary = "#10cdbb"; appConfig.colorText = "#4a4a4a"; appConfig.colorDesc = "#FF6633"; appConfig.sizeTitle = "17dp"; appConfig.sizeText = "14dp"; appConfig.appPackageName = "com.ss.android.ugc.aweme.lite"; appConfig.appVersionCode = "200601"; appConfig.appVersionName = "20.6.0"; appConfig.screenWidth = 1080; appConfig.screenHeight = 1920; //设置分辨率 setScreenMetrics(appConfig.screenWidth, appConfig.screenHeight); //本地存储 const storage = storages.create(appConfig.packageName); function getConfig(key) { if (storage.contains(key)) { return storage.get(key, ""); } else { return ""; } } function setConfig(key, value) { storage.put(key, value); } function initConfig() { let config1 = getConfig("config1"); if (config1 === "") { let config1 = {}; config1.keyword = ""; config1.time1 = 30; config1.time2 = 180; config1.time3 = 3; config1.time4 = 6; config1.number1 = 60; config1.number2 = 20; config1.number3 = 5; config1.number4 = 5; config1.number5 = 30; config1.number6 = 30; config1.comment = ""; setConfig("config1", config1); } let config2 = getConfig("config2"); if (config2 === "") { let config2 = {}; config2.number1 = 100; config2.number2 = 200; config2.time1 = 10; config2.time2 = 30; config2.comment = ""; setConfig("config2", config2); } } //输入框边框 function setBackgroundRoundGradientCornerRadii(view) { gradientDrawable = new GradientDrawable(); gradientDrawable.setShape(GradientDrawable.RECTANGLE); gradientDrawable.setStroke(10, colors.parseColor(appConfig.colorSecondary)); gradientDrawable.setCornerRadius(10); gradientDrawable.setSize(50, 50); view.setBackground(gradientDrawable); } //获取指定应用的versionCode function getVersion(package_name) { let pkgs = context.getPackageManager().getInstalledPackages(0).toArray(); for (let i in pkgs) { if (pkgs[i].packageName.toString() === package_name) { return pkgs[i].versionCode; } } } //ui ui.statusBarColor(colors.parseColor(appConfig.colorPrimary)); initConfig(); let config1 = getConfig("config1"); let config2 = getConfig("config2"); ui.layout( <drawer id="drawer"> <vertical> <appbar> <toolbar id="toolbar" title="{{appConfig.appName}}" /> <tabs id="tabs" /> </appbar> <viewpager id="viewpager"> <frame> <ScrollView> <vertical padding="16dp"> <horizontal> <text text="作品关键词:" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> <input id="keyword" w="*" hint="请输入作品关键词" textSize="{{appConfig.sizeTitle}}" inputType="text" gravity="left" text="{{config1.keyword}}" /> </horizontal> <text text="多个关键词使用英文逗号隔开,示例:美食,探店,自助餐,甜品" textSize="{{appConfig.sizeText}}" textStyle="bold" textColor="{{appConfig.colorDesc}}" /> <horizontal> <text text="满足关键词作品浏览:" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> <input id="timeInput1" w="50dp" textSize="{{appConfig.sizeTitle}}" inputType="number" gravity="left" text="{{config1.time1}}" /> <text text="到" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> <input id="timeInput2" w="50dp" textSize="{{appConfig.sizeTitle}}" inputType="number" gravity="left" text="{{config1.time2}}" /> <text text="秒" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> </horizontal> <horizontal> <text text="其他不满足作品浏览:" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> <input id="timeInput3" w="50dp" textSize="{{appConfig.sizeTitle}}" inputType="number" gravity="left" text="{{config1.time3}}" /> <text text="到" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> <input id="timeInput4" w="50dp" textSize="{{appConfig.sizeTitle}}" inputType="number" gravity="left" text="{{config1.time4}}" /> <text text="秒" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> </horizontal> <text text="以下操作仅针对满足关键词的作品" textSize="{{appConfig.sizeText}}" textStyle="bold" textColor="{{appConfig.colorDesc}}" /> <horizontal> <text text="点赞作品:" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> <input id="numberInput1" w="50dp" textSize="{{appConfig.sizeTitle}}" inputType="number" gravity="left" text="{{config1.number1}}" /> <text text="% 评论作品:" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> <input id="numberInput2" w="50dp" textSize="{{appConfig.sizeTitle}}" inputType="number" gravity="left" text="{{config1.number2}}" /> <text text="%" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> </horizontal> <horizontal> <text text="收藏作品:" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> <input id="numberInput3" w="50dp" textSize="{{appConfig.sizeTitle}}" inputType="number" gravity="left" text="{{config1.number3}}" /> <text text="% 转发作品:" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> <input id="numberInput4" w="50dp" textSize="{{appConfig.sizeTitle}}" inputType="number" gravity="left" text="{{config1.number4}}" /> <text text="%" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> </horizontal> <horizontal> <text text="浏览主页:" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> <input id="numberInput5" w="50dp" textSize="{{appConfig.sizeTitle}}" inputType="number" gravity="left" text="{{config1.number5}}" /> <text text="% 关注作者:" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> <input id="numberInput6" w="50dp" textSize="{{appConfig.sizeTitle}}" inputType="number" gravity="left" text="{{config1.number6}}" /> <text text="%" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> </horizontal> <text text="自定义评论,多个评论请输入英文逗号隔开" textSize="{{appConfig.sizeText}}" textStyle="bold" textColor="{{appConfig.colorDesc}}" /> <input id="commentInput1" w="*" minLines="3" maxLines="5" textSize="{{appConfig.sizeText}}" inputType="textMultiLine" android:gravity="top" padding="5dp" marginTop="5dp" text="{{config1.comment}}" /> <button id="startButton1" marginTop="5dp" style="Widget.AppCompat.Button.Colored" text="启动脚本" /> </vertical> </ScrollView> </frame> <frame> <ScrollView> <vertical padding="16dp"> <text text="请先打开抖音直播间后启动" textSize="{{appConfig.sizeText}}" textStyle="bold" textColor="{{appConfig.colorDesc}}" /> <horizontal> <text text="点赞" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> <input id="numberInput7" w="100dp" textSize="{{appConfig.sizeTitle}}" inputType="number" gravity="left" text="{{config2.number1}}" /> <text text="次到" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> <input id="numberInput8" w="100dp" textSize="{{appConfig.sizeTitle}}" inputType="number" gravity="left" text="{{config2.number2}}" /> <text text="次" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> </horizontal> <horizontal> <text text="休息" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> <input id="timeInput5" w="50dp" textSize="{{appConfig.sizeTitle}}" inputType="number" gravity="left" text="{{config2.time1}}" /> <text text="秒到" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> <input id="timeInput6" w="50dp" textSize="{{appConfig.sizeTitle}}" inputType="number" gravity="left" text="{{config2.time2}}" /> <text text="秒" textSize="{{appConfig.sizeTitle}}" textColor="{{appConfig.colorText}}" /> </horizontal> <text text="休息期间评论,使用英文逗号隔开,如果为空则不评论" textSize="{{appConfig.sizeText}}" textStyle="bold" textColor="{{appConfig.colorDesc}}" /> <input id="commentInput2" w="*" minLines="3" maxLines="5" textSize="{{appConfig.sizeText}}" inputType="textMultiLine" android:gravity="top" padding="5dp" marginTop="5dp" text="{{config2.comment}}" /> <button id="startButton2" marginTop="5dp" style="Widget.AppCompat.Button.Colored" text="启动脚本" /> </vertical> </ScrollView> </frame> <frame> <ScrollView> <vertical padding="16dp"> <text text="更多功能持续开发中" textSize="{{appConfig.sizeText}}" textStyle="bold" textColor="{{appConfig.colorDesc}}" /> </vertical> </ScrollView> </frame> </viewpager> </vertical> <vertical layout_gravity="left" bg="#ffffff" w="280"> <img w="280" h="200" scaleType="fitXY" src="http://images.shejidaren.com/wp-content/uploads/2014/10/023746fki.jpg" /> <list id="menu"> <horizontal bg="?selectableItemBackground" w="*"> <img w="50" h="50" padding="16" src="{{this.icon}}" /> <text textColor="black" textSize="15sp" text="{{this.title}}" layout_gravity="center" /> </horizontal> </list> </vertical> </drawer> ); //设置输入框边框 setBackgroundRoundGradientCornerRadii(ui.commentInput1); setBackgroundRoundGradientCornerRadii(ui.commentInput2); //创建选项菜单(右上角) ui.emitter.on("create_options_menu", (menu) => { menu.add("运行环境检测"); menu.add("版本更新"); }); //监听选项菜单点击 ui.emitter.on("options_item_selected", (e, item) => { switch (item.getTitle()) { case "运行环境检测": if (checkEnv()) { toast("环境检测通过"); } break; case "版本更新": alert("版本更新", "当前版本:" + appConfig.versionName); break; } e.consumed = true; }); activity.setSupportActionBar(ui.toolbar); //设置滑动页面的标题 ui.viewpager.setTitles(["抖音养号", "直播助手", "更多功能"]); //让滑动页面和标签栏联动 ui.tabs.setupWithViewPager(ui.viewpager); //让工具栏左上角可以打开侧拉菜单 ui.toolbar.setupWithDrawer(ui.drawer); ui.menu.setDataSource([ { title: "选项一", icon: "@drawable/ic_android_black_48dp", }, { title: "选项二", icon: "@drawable/ic_settings_black_48dp", }, { title: "选项三", icon: "@drawable/ic_favorite_black_48dp", }, { title: "退出", icon: "@drawable/ic_exit_to_app_black_48dp", }, ]); ui.menu.on("item_click", (item) => { switch (item.title) { case "退出": ui.finish(); break; } }); let run = false; //Page1 抖音养号 ui.startButton1.on("click", () => { if (run) { run = false; ui.startButton1.setText("启动脚本"); } else { if (checkParams1()) { if (checkEnv()) { threads.start(function () { run = true; ui.startButton1.setText("停止"); startScript1(); }); } } } }); //Page2 直播助手 ui.startButton2.on("click", () => { if (run) { run = false; ui.startButton2.setText("启动脚本"); } else { if (checkParams2()) { if (checkEnv()) { threads.start(function () { run = true; ui.startButton2.setText("停止"); startScript2(); }); } } } }); //开启脚本1 function startScript1() { //检查无障碍是否启动 auto.waitFor(); //启动脚本 toast("脚本启动"); console.log("脚本启动"); //等待2秒钟 sleep(2000); //启动应用 launch(appConfig.appPackageName); console.log("启动抖音"); config1 = getConfig("config1"); console.log("获取配置"); //等待5秒钟 sleep(5000); while (run) { console.log("=====START====="); sleep(1000); let activityName = currentActivity(); if (activityName == "com.ss.android.ugc.aweme.main.MainActivity") { if (checkKeyword()) { sleep(random(config1.time1 * 1000, config1.time2 * 1000)); clickLike(); comment(); collection(); forward(); goHome(); follow(); slideTop(); } else { sleep(random(config1.time3 * 1000, config1.time4 * 1000)); slideTop(); } } else { run = false; toast("脚本停止,未定义的页面:" + activityName); } } } //开启脚本2 function startScript2() { //检查无障碍是否启动 auto.waitFor(); //启动脚本 toast("脚本启动"); console.log("脚本启动"); //等待2秒钟 sleep(2000); //启动应用 launch(appConfig.appPackageName); console.log("启动抖音"); config2 = getConfig("config2"); console.log("获取配置"); //等待10秒钟 sleep(10000); while (run) { sleep(2000); let activityName = currentActivity(); if (activityName == "com.ss.android.ugc.aweme.live.LivePlayActivity") { liveClickLike(); liveComment(); sleep(random(config2.time1 * 1000, config2.time2 * 1000)); } else { run = false; toast("脚本停止,未定义的页面:" + activityName); } } } function liveClickLike() { console.log("开始点赞..."); sleep(2000); let count = random(config2.number1, config2.number2); let screenWidth = appConfig.screenWidth; let screenHeight = appConfig.screenHeight; let x = random(screenWidth - 130, screenWidth - 100); let y = random(screenHeight / 2 - 40, screenHeight / 2 - 20); for (let i = 0; i < count; i++) { x = random(x - 10, x + 10); y = random(y - 10, y + 10); press(x, y, random(100, 200)); sleep(random(200, 400)); } console.log("点赞完成!"); } //检查关键词 function checkKeyword() { if (!id("desc").visibleToUser(true).exists()) { console.log("×关键词校验失败"); return false; } let title = id("desc").visibleToUser(true).findOne().text(); console.log("Title:" + title); let keywordArr = config1.keyword.split(","); for (let i = 0; i < keywordArr.length; i++) { if (title.indexOf(keywordArr[i]) != -1) { console.log("√关键词校验通过"); return true; } } console.log("×关键词校验失败"); return false; } //点赞 function clickLike() { if (config1.number1 >= random(0, 100)) { let desc = id("cc0").visibleToUser(true).findOne().desc(); if (desc.indexOf("未点赞") != -1) { console.log("点赞视频"); id("cc0").visibleToUser(true).findOne().click(); sleep(random(2000, 3000)); } } } //评论 function comment() { if (config1.number2 >= random(0, 100)) { sleep(1000); console.log("开始评论"); id("bxb").visibleToUser(true).findOne().click(); sleep(random(2000, 3000)); if (id("64").visibleToUser(true).exists()) { let text; let commentArr = config1.comment.split(","); if (commentArr.length > 1) { text = commentArr[random(0, commentArr.length - 1)]; } else { text = commentArr[0]; } console.log("评论内容:" + text); setText(text); sleep(random(2000, 3000)); id("6t").visibleToUser(true).findOne().click(); sleep(random(2000, 3000)); id("back_btn").visibleToUser(true).findOne().click(); sleep(random(2000, 3000)); } } } //直播评论 function liveComment() { if (config2.comment != "") { sleep(random(2000, 3000)); let text; let commentArr = config2.comment.split(","); if (commentArr.length > 1) { text = commentArr[random(0, commentArr.length - 1)]; } else { text = commentArr[0]; } console.log("评论内容:" + text); id("edit_btn_audience").visibleToUser(true).findOne().click(); sleep(random(2000, 3000)); setText(text); sleep(random(2000, 3000)); id("lq").visibleToUser(true).findOne().click(); console.log("发送评论"); sleep(random(2000, 3000)); } } //收藏 function collection() { if (config1.number3 >= random(0, 100)) { let desc = id("bun").visibleToUser(true).findOne().desc(); if (desc.indexOf("未选中") != -1) { console.log("收藏视频"); id("bun").visibleToUser(true).findOne().click(); sleep(random(2000, 3000)); } } } function forward() { if (config1.number4 >= random(0, 100)) { console.log("分享视频"); id("g_j").visibleToUser(true).findOne().click(); sleep(random(2000, 3000)); text("私信朋友").visibleToUser(true).findOne().parent().click(); sleep(random(2000, 3000)); id("g82").visibleToUser(true).findOne().click(); sleep(random(2000, 3000)); back(); sleep(random(2000, 3000)); } } function goHome() { if (config1.number5 >= random(0, 100)) { console.log("浏览主页"); id("user_avatar").visibleToUser(true).findOne().click(); sleep(random(3000, 5000)); follow(); let num = random(1, 3); for (let i = 0; i < num; i++) { slideTop(); sleep(random(1000, 5000)); } slideDown(); sleep(random(2000, 3000)); back(); sleep(random(2000, 3000)); } } function follow() { if (config1.number6 >= random(0, 100)) { if (id("gb6").visibleToUser(true).exists()) { console.log("关注作者"); id("gb6").visibleToUser(true).findOne().click(); sleep(random(2000, 3000)); } } } //校验保存参数 function checkParams1() { let keyword = ui.keyword.text(); if (keyword === "") { toast("请输入作品关键词"); ui.keyword.requestFocus(); return false; } let time1 = parseInt(ui.timeInput1.text()); if (time1 === "") { toast("请输入作品浏览时间"); ui.timeInput1.requestFocus(); return false; } let time2 = parseInt(ui.timeInput2.text()); if (time2 === "") { toast("请输入作品浏览时间"); ui.timeInput2.requestFocus(); return false; } if (time1 >= time2) { toast("参数错误!"); ui.timeInput1.text(""); ui.timeInput2.text(""); ui.timeInput1.requestFocus(); return false; } let time3 = parseInt(ui.timeInput3.text()); if (time3 === "") { toast("请输入作品浏览时间"); ui.timeInput3.requestFocus(); return false; } let time4 = parseInt(ui.timeInput4.text()); if (time4 === "") { toast("请输入作品浏览时间"); ui.timeInput4.requestFocus(); return false; } if (time3 >= time4) { toast("参数错误!"); ui.timeInput3.text(""); ui.timeInput4.text(""); ui.timeInput3.requestFocus(); return false; } let number1 = ui.numberInput1.text(); if (number1 === "") { toast("请输入点赞作品概率"); ui.numberInput1.requestFocus(); return false; } if (number1 < 0 || number1 > 100) { toast("参数错误"); ui.numberInput1.text(""); ui.numberInput1.requestFocus(); return false; } let number2 = ui.numberInput2.text(); if (number2 === "") { toast("请输入评论作品概率"); ui.numberInput2.requestFocus(); return false; } if (number2 < 0 || number2 > 100) { toast("参数错误"); ui.numberInput2.text(""); ui.numberInput2.requestFocus(); return false; } let number3 = ui.numberInput3.text(); if (number3 === "") { toast("请输入收藏作品概率"); ui.numberInput3.requestFocus(); return false; } if (number3 < 0 || number3 > 100) { toast("参数错误"); ui.numberInput3.text(""); ui.numberInput3.requestFocus(); return false; } let number4 = ui.numberInput4.text(); if (number4 === "") { toast("请输入转发作品概率"); ui.numberInput4.requestFocus(); return false; } if (number4 < 0 || number4 > 100) { toast("参数错误"); ui.numberInput4.text(""); ui.numberInput4.requestFocus(); return false; } let number5 = ui.numberInput5.text(); if (number5 === "") { toast("请输入浏览主页概率"); ui.numberInput5.requestFocus(); return false; } if (number5 < 0 || number5 > 100) { toast("参数错误"); ui.numberInput5.text(""); ui.numberInput5.requestFocus(); return false; } let number6 = ui.numberInput6.text(); if (number6 === "") { toast("请输入关注作者概率"); ui.numberInput6.requestFocus(); return false; } if (number6 < 0 || number6 > 100) { toast("参数错误"); ui.numberInput6.text(""); ui.numberInput6.requestFocus(); return false; } let comment = ui.commentInput1.text(); if (number2 > 0 && comment === "") { toast("请输入评论内容"); ui.commentInput1.requestFocus(); return false; } let config1 = {}; config1.keyword = keyword; config1.time1 = time1; config1.time2 = time2; config1.time3 = time3; config1.time4 = time4; config1.number1 = number1; config1.number2 = number2; config1.number3 = number3; config1.number4 = number4; config1.number5 = number5; config1.number6 = number6; config1.comment = comment; setConfig("config1", config1); return true; } //校验保存参数 function checkParams2() { let number1 = parseInt(ui.numberInput7.text()); if (number1 === "") { toast("请输入点赞次数"); ui.numberInput7.requestFocus(); return false; } let number2 = parseInt(ui.numberInput8.text()); if (number2 === "") { toast("请输入点赞次数"); ui.numberInput8.requestFocus(); return false; } let time1 = parseInt(ui.timeInput5.text()); if (time1 === "") { toast("请输入休息时间"); ui.timeInput5.requestFocus(); return false; } let time2 = parseInt(ui.timeInput6.text()); if (time2 === "") { toast("请输入休息时间"); ui.timeInput6.requestFocus(); return false; } if (number1 >= number2) { toast("参数错误"); ui.numberInput7.text(""); ui.numberInput8.text(""); ui.numberInput7.requestFocus(); return false; } if (time1 >= time2) { toast("参数错误"); ui.timeInput5.text(""); ui.timeInput6.text(""); ui.timeInput5.requestFocus(); return false; } let comment = ui.commentInput2.text(); let config2 = {}; config2.number1 = number1; config2.number2 = number2; config2.time1 = time1; config2.time2 = time2; config2.comment = comment; setConfig("config2", config2); return true; } //环境检测 function checkEnv() { if (auto.service == null) { toast("请开启无障碍"); app.startActivity({ action: "android.settings.ACCESSIBILITY_SETTINGS", }); return false; } let versionCode = getVersion(appConfig.appPackageName); if (versionCode != appConfig.appVersionCode) { toast("请安装抖音 " + appConfig.appVersionName + " 版本"); return false; } return true; } //屏幕滑动 function slideTop() { let screenWidth = appConfig.screenWidth; let screenHeight = appConfig.screenHeight; let x1, y1, x2, y2; x1 = random(screenWidth / 2 - 50, screenWidth / 2 + 50); y1 = random(screenHeight - 500, screenHeight - 400); x2 = random(screenWidth / 2 - 50, screenWidth / 2 + 50); y2 = random(screenHeight / 5 - 50, screenHeight / 5 + 100); swipe(x1, y1, x2, y2, random(200, 500)); } function slideDown() { let screenWidth = appConfig.screenWidth; let screenHeight = appConfig.screenHeight; let x1, y1, x2, y2; x1 = random(screenWidth / 2 - 50, screenWidth / 2 + 50); y1 = random(screenHeight - 500, screenHeight - 400); x2 = random(screenWidth / 2 - 50, screenWidth / 2 + 50); y2 = random(screenHeight / 5 - 50, screenHeight / 5 + 100); swipe(x2, y2, x1, y1, random(200, 500)); } //随机数 function random(min, max) { max += 1; return Math.floor(Math.random() * (max - min)) + min; }