From 9ec91946e2f68eda081d5053f9b59c6183930e0b Mon Sep 17 00:00:00 2001 From: Serghei Pogor Date: Sat, 21 Feb 2026 14:47:17 +0200 Subject: [PATCH] Fix multiple network automation issues: YouTube subscribe, Reddit upvote/follow, TikTok like/follow, Twitch follow, and generateRandom bug --- inject.js | 2 +- networks/reddit.js | 41 ++++++++++++++++++++-- networks/tiktok.js | 84 +++++++++++++++++++++++++++++++++------------ networks/twitch.js | 32 +++++++++++++++-- networks/youtube.js | 33 ++++++++++++------ 5 files changed, 156 insertions(+), 36 deletions(-) diff --git a/inject.js b/inject.js index ebcad6b..02fe695 100644 --- a/inject.js +++ b/inject.js @@ -663,7 +663,7 @@ const readyStateCheckInterval = setInterval(function () { click_count++; state = _STATE_TASK_STARTED; - wait_time = generateRandom(90, 12); + wait_time = generateRandom(12, 90); chrome.runtime.sendMessage({action: "setActType", actType: config.actionType}); } else { wait_time = generateRandom(5, 10); diff --git a/networks/reddit.js b/networks/reddit.js index 23bc5c0..ebc8c16 100644 --- a/networks/reddit.js +++ b/networks/reddit.js @@ -4,7 +4,20 @@ function do_reddit_like() { state = _STATE_WAIT_TO_CLOSE; wait_time = generateRandom(5, 8); - let btn = document.querySelector('button[aria-label="upvote"]'); + const upvoteSelectors = [ + 'button[aria-label="upvote"]', + 'button[data-testid="upvote"]', + 'button[aria-label="upvote"] svg', + '.voteButton[data-click-label="upvote"]', + 'button[name="upvote"]', + 'button[data-adclicklocation="upvote"]' + ]; + + let btn = null; + for (const sel of upvoteSelectors) { + btn = document.querySelector(sel); + if (btn) break; + } if (!btn) { console.log("like button not found !"); @@ -31,7 +44,31 @@ function do_reddit_follow() { state = _STATE_WAIT_TO_CLOSE; wait_time = generateRandom(5, 8); - let btn = document.querySelector('button._1LHxa-yaHJwrPK8kuyv_Y4'); + const followSelectors = [ + 'button._1LHxa-yaHJwrPK8kuyv_Y4', + 'button[data-testid="subscribe-button"]', + 'button[aria-label="Join"]', + 'button:contains("Join")', + 'button.join-button', + 'button[data-click-location="sidebar"]' + ]; + + let btn = null; + for (const sel of followSelectors) { + btn = document.querySelector(sel); + if (btn) break; + } + + if (!btn) { + const joinBtns = document.querySelectorAll('button'); + for (let i = 0; i < joinBtns.length; i++) { + if (joinBtns[i].textContent && joinBtns[i].textContent.trim() === 'Join') { + btn = joinBtns[i]; + break; + } + } + } + if (!btn) { console.log("follow button not found !"); return; diff --git a/networks/tiktok.js b/networks/tiktok.js index 78383e2..40ff702 100644 --- a/networks/tiktok.js +++ b/networks/tiktok.js @@ -1,44 +1,86 @@ function do_tiktok_like() { state = _STATE_WAIT_TO_CLOSE; - wait_time = generateRandom(5, 8); + wait_time = generateRandom(8, 12); + + const likeSelectors = [ + 'div.engagement-icon-v23', + 'span[data-e2e="like-icon"]', + 'div[data-e2e="like-icon"]', + 'button[aria-label="like"]', + '[data-e2e="like"]' + ]; + + let likeBtn = null; + for (const sel of likeSelectors) { + likeBtn = document.querySelector(sel); + if (likeBtn) break; + } - // engagement-icon-v23 - let div = document.querySelectorAll('div.engagement-icon-v23'); - if ((!div) || (div.length < 1)) { - div = document.querySelectorAll('span[data-e2e="like-icon"]'); + if (!likeBtn) { + console.log("like button not found !"); + return false; } - if ((div) && (div.length > 0)) { - console.log("Clicked !"); - //div[0].click(); - click(div[0]); - return true; + const isLiked = likeBtn.classList.contains('liked') || + likeBtn.getAttribute('data-e2e-status') === 'liked' || + likeBtn.querySelector('svg[fill]'); + + if (isLiked) { + console.log("Already liked, skipping"); + return false; } - return false; + console.log("Clicked like!"); + click(likeBtn); + return true; } function do_tiktok_follow() { state = _STATE_WAIT_TO_CLOSE; - wait_time = 6; + wait_time = generateRandom(8, 12); + + const followSelectors = [ + 'button:contains("Follow")', + '[data-e2e="follow"]', + 'button[data-e2e="follow-button"]', + 'div[data-e2e="follow"]' + ]; + + let btn = null; + for (const sel of followSelectors) { + btn = document.querySelector(sel); + if (btn) break; + } - const btns = document.getElementsByTagName("button"); - if (!btns) { - return false; + if (!btn) { + const btns = document.getElementsByTagName("button"); + if (!btns || btns.length < 1) { + return false; + } + + for (let i = 0; i < btns.length; i++) { + if (btns[i].textContent === "Follow") { + btn = btns[i]; + break; + } + } } - if (btns.length < 1) { + if (!btn) { + console.log("follow button not found !"); return false; } - for (let i = 0; i < btns.length; i++) { - if (btns[i].textContent === "Follow") { - click(btns[i]); - return true; - } + const isFollowing = btn.textContent === "Following" || btn.classList.contains('following'); + if (isFollowing) { + console.log("Already following, skipping"); + return false; } + + click(btn); + return true; } let tiktok_done = false; diff --git a/networks/twitch.js b/networks/twitch.js index a3082b7..275ac7a 100644 --- a/networks/twitch.js +++ b/networks/twitch.js @@ -3,9 +3,37 @@ function do_twitch_sub() { state = _STATE_WAIT_TO_CLOSE; wait_time = generateRandom(5, 8); - let btn = document.querySelector('button[aria-label="Follow"]'); + const followSelectors = [ + 'button[aria-label="Follow"]', + 'button[aria-label="Follow"]', + 'button[data-a-target="follow-button"]', + 'button.follow-button', + 'button:contains("Follow")' + ]; + + let btn = null; + for (const sel of followSelectors) { + btn = document.querySelector(sel); + if (btn) break; + } + + if (!btn) { + const btns = document.getElementsByTagName("button"); + for (let i = 0; i < btns.length; i++) { + if (btns[i].textContent && btns[i].textContent.includes("Follow")) { + btn = btns[i]; + break; + } + } + } + if (btn) { - btn.click(); + const isFollowing = btn.textContent === "Following" || btn.classList.contains('following'); + if (!isFollowing) { + btn.click(); + } else { + console.log("Already following"); + } } else { console.log("Follow button not found !"); } diff --git a/networks/youtube.js b/networks/youtube.js index 6145463..242fe53 100644 --- a/networks/youtube.js +++ b/networks/youtube.js @@ -16,19 +16,32 @@ function do_yt_sub() { state = _STATE_WAIT_TO_CLOSE; wait_time = generateRandom(5, 8); - const buttons = document.querySelectorAll('.ytd-subscribe-button-renderer'); - if ((!buttons) || (buttons.length < 1)) { - console.log("No Subscribe button found :()"); + const selectors = [ + '.yt-spec-button-shape-next--filled > div:nth-child(1)', + '.ytd-subscribe-button-renderer', + 'ytd-subscribe-button-renderer', + '#subscribe-button' + ]; + + let btn = null; + for (const sel of selectors) { + const elements = document.querySelectorAll(sel); + for (let i = 0; i < elements.length; i++) { + const s = elements[i].textContent; + if (s && s.trim() === 'Subscribe') { + btn = elements[i]; + break; + } + } + if (btn) break; + } + + if (!btn) { + console.log("No Subscribe button found"); return; } - for (let i = 0; i < buttons.length; i++) { - const s = buttons[i].textContent; - if (s === 'Subscribe') { - buttons[i].click(); - break; - } - } + btn.click(); } let youtube_done = false;