// ==UserScript== // @name Auto Click Recaptcha with Whitelist // @namespace http://tampermonkey.net/ // @version 0.2 // @description Auto clicks the recaptcha checkbox for the selected sites // @author satology // @match *://*/recaptcha/api2/anchor* // @grant GM_setValue // @grant GM_getValue // ==/UserScript== // This is a WIP. It works but it will be adjusted/refactor in the future. // The idea is simple: trying to prevent opening recaptchas that you don't want to be solved by hekt (PTCs captchas, for example) // How? // 1- Disable Auto Open for Recaptcha challenges at Hekt Extension. // 2- Install the script. It will add a button like in the screenshot. By default it will say 'Not Autoclicking'. // 3- Go through the sites you want to auto solve, and click the button to make it say 'Autoclicking' in green. // The script will now know that recaptchas with that ID (from that site) need to be autoclicked/autoopen (function() { 'use strict'; let allowedIds = undefined; var solved = false; var checkBoxClicked = false; var requestCount = 0; const MAX_ATTEMPTS = 1; // const CHECK_BOX = "recaptcha-anchor.recaptcha-checkbox-border"; // .recaptcha-checkbox-checked, .recaptcha-checkbox-expired const CHECK_BOX = '#recaptcha-anchor:not(.recaptcha-checkbox-checked) div.recaptcha-checkbox-border'; const AUDIO_BUTTON = "#recaptcha-audio-button"; const PLAY_BUTTON = ".rc-audiochallenge-play-button .rc-button-default"; const AUDIO_SOURCE = "#audio-source"; const IMAGE_SELECT = "#rc-imageselect"; const RESPONSE_FIELD = ".rc-audiochallenge-response-field"; const AUDIO_ERROR_MESSAGE = ".rc-audiochallenge-error-message"; const AUDIO_RESPONSE = "#audio-response"; const RELOAD_BUTTON = "#recaptcha-reload-button"; const RECAPTCHA_STATUS = "#recaptcha-accessible-status"; const DOSCAPTCHA = ".rc-doscaptcha-body"; const VERIFY_BUTTON = "#recaptcha-verify-button"; const LOGO_DIV = 'div.rc-anchor-logo-img-portrait'; var recaptchaInitialStatus = qSelector(RECAPTCHA_STATUS) ? qSelector(RECAPTCHA_STATUS).innerText : "" function isHidden(el) { return(el.offsetParent === null) } function qSelector(selector) { return document.querySelector(selector); } function getSiteKey() { try { let kvs = location.search.replace('?', '').split('&').map(x => { return { key: x.split('=')[0], value: x.split('=')[1] }; }); console.log('@getSiteKey'); return [...kvs.filter(x => x.key == 'k')][0].value; } catch (err) {} return false; } async function tryToOpen() { if (!Array.isArray(allowedIds)) { await wait(1000); tryToOpen(); return; } try { if(allowedIds.some(x => location.href.includes(x))) { // if(location.href.includes('6LcwYPgjAAAAAJBfijQi8XPDxrn9z3fLelrO9CH')) { if(!checkBoxClicked && qSelector(CHECK_BOX) && !isHidden(qSelector(CHECK_BOX))) { console.log("checkbox clicked"); qSelector(CHECK_BOX).click(); checkBoxClicked = true; // Retry to click after 4 mins setTimeout(() => { checkBoxClicked = false; tryToOpen(); }, 3 * 60000); appendCustomButton(true); } //Check if the captcha is solved if(qSelector(RECAPTCHA_STATUS) && (qSelector(RECAPTCHA_STATUS).innerText != recaptchaInitialStatus)) { solved = true; console.log("SOLVED"); } if(requestCount > MAX_ATTEMPTS) { console.log("Attempted Max Retries. Stopping the solver"); solved = true; } //Stop solving when Automated queries message is shown if(qSelector(DOSCAPTCHA) && qSelector(DOSCAPTCHA).innerText.length > 0) { console.log("Automated Queries Detected"); } } else { appendCustomButton(false); } } catch(err) { console.log(err.message); console.log("An error occurred while solving. Stopping the solver."); } } function changeAutoclickState(evt) { evt.stopPropagation(); evt.stopImmediatePropagation(); let button = evt.target; let isAdded = button.dataset.added === 'true'; let siteKey = getSiteKey(); if (!siteKey) { alert('Error! unable to read the site key. Please report this site to allow further analysis.'); return; } if (isAdded) { allowedIds = allowedIds.filter(x => x !== siteKey); } else { if (!allowedIds.includes(siteKey)) { allowedIds.push(siteKey); } checkBoxClicked = false; } setAllowedIds(); isAdded = !isAdded; button.dataset.added = isAdded; button.innerText = isAdded ? 'Autoclicking' : 'Not autoclicking'; button.style.color = isAdded ? 'green' : 'red'; tryToOpen(); } function appendCustomButton(isAdded = false) { console.log('@appendCustomButton'); try { let img = qSelector(LOGO_DIV); if (img) { if (img.querySelector('button')) { return; } document.querySelector('.rc-anchor-logo-portrait').style.margin = 0; img.style.margin = 0; img.classList.remove('rc-anchor-logo-img'); let button = document.createElement('button'); button.dataset.added = isAdded; button.innerText = isAdded ? 'Autoclicking' : 'Not autoclicking'; button.style.color = isAdded ? 'green' : 'red'; button.addEventListener('click', changeAutoclickState); img.appendChild(button); // img.style.background = "url('https://www.gstatic.com/recaptcha/api2/logo_48.png')"; // img.style.backgroundRepeat = "no-repeat"; } } catch(err) { console.log('append error'); console.log(err); } } function getAllowedIds() { allowedIds = GM_getValue('allowed'); if (allowedIds) { allowedIds = JSON.parse(allowedIds) } else { allowedIds = []; } } function setAllowedIds() { GM_setValue('allowed', JSON.stringify(allowedIds)); } getAllowedIds(); tryToOpen(); })();