功能简介
目前只做了抖音养号的功能,对应抖音极速版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.0.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); } } //输入框边框 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"); 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="commentInput" w="*" minLines="3" maxLines="5" textSize="{{appConfig.sizeText}}" inputType="textMultiLine" android:gravity="top" padding="5dp" marginTop="5dp" text="{{config1.comment}}" /> <button id="startButton" marginTop="5dp" style="Widget.AppCompat.Button.Colored" text="启动脚本" /> </vertical> </ScrollView> </frame> <frame> <text text="第二页内容" textSize="16sp" /> </frame> <frame> <text text="第三页内容" textSize="16sp" /> </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.commentInput); //创建选项菜单(右上角) 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.startButton.on("click", () => { if (run) { run = false; ui.startButton.setText("启动脚本"); } else { run = true; ui.startButton.setText("停止"); if (checkParams()) { if (checkEnv()) { threads.start(function () { startScript(); }); } } } }); //开启脚本 function startScript() { //检查无障碍是否启动 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); } } } //检查关键词 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 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 checkParams() { 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.commentInput.text(); if (number2 > 0 && comment === "") { toast("请输入评论内容"); ui.commentInput.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 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; }