-
-
Save Domiii/52cf49d780ec8c9f01771973c36197af to your computer and use it in GitHub Desktop.
| /** | |
| * This script types for you automatically on www.typingclub.com: | |
| * 1. Open the website | |
| * 2. Blaze past the tutorials | |
| * 3. Go into a level | |
| * 4. Open Console | |
| * 5. Paste the script and press ENTER | |
| */ | |
| // NOTE: When delay (in ms between two strokes) is too low, the site might bug out and the result page will not be shown | |
| const minDelay = 60; | |
| const maxDelay = 60; | |
| const keyOverrides = { | |
| [String.fromCharCode(160)]: ' ' // convert hardspace to normal space | |
| }; | |
| function getTargetCharacters() { | |
| const els = Array.from(document.querySelectorAll('.token span.token_unit')); | |
| const chrs = els | |
| .map(el => { | |
| // get letter to type from each letter DOM element | |
| if (el.firstChild?.classList?.contains('_enter')) { | |
| // special case: ENTER | |
| return '\n'; | |
| } | |
| let text = el.textContent[0]; | |
| return text; | |
| }) | |
| .map(c => keyOverrides.hasOwnProperty(c) ? keyOverrides[c] : c); // convert special characters | |
| return chrs; | |
| } | |
| function recordKey(chr) { | |
| // send it straight to the internal API | |
| window.core.record_keydown_time(chr); | |
| } | |
| function sleep(ms) { | |
| return new Promise(r => setTimeout(r, ms)); | |
| } | |
| async function autoPlay(finish) { | |
| const chrs = getTargetCharacters(); | |
| for (let i = 0; i < chrs.length - (!finish); ++i) { | |
| const c = chrs[i]; | |
| recordKey(c); | |
| //console.log(c, c.charCodeAt()); | |
| await sleep(Math.random() * (maxDelay - minDelay) + minDelay); | |
| } | |
| } | |
| // ############################################################################################################ | |
| // old utilities | |
| // ############################################################################################################ | |
| // /** | |
| // * @see https://stackoverflow.com/questions/8942678/keyboardevent-in-chrome-keycode-is-0/12522752#12522752 | |
| // */ | |
| // function simulateKey(chr, el) { | |
| // _simulateKey(chr, 'keydown', el); | |
| // _simulateKey(chr, 'keypress', el); | |
| // } | |
| // function _simulateKey(chr, type, el) { | |
| // var eventObj = document.createEventObject ? | |
| // document.createEventObject() : document.createEvent("Events"); | |
| // if (eventObj.initEvent) { | |
| // eventObj.initEvent(type || "keydown", true, true); | |
| // } | |
| // let keyCode = chr.charCodeAt(0); | |
| // eventObj.key = chr[0]; | |
| // eventObj.keyCode = keyCode; | |
| // eventObj.which = keyCode; | |
| // eventObj.isTrusted = true; | |
| // el = el || document.body; | |
| // // console.log(keyCode, eventObj); | |
| // el.dispatchEvent ? el.dispatchEvent(eventObj) : el.fireEvent("onkeydown", eventObj); | |
| // } | |
| // document.addEventListener("keydown", function (e) { | |
| // console.log('down', e); | |
| // }); | |
| // document.addEventListener("keypress", function (e) { | |
| // console.log('press', e); | |
| // }); | |
| //$($('.menu-btn')[0].parentNode).prepend('<button onclick=\'simulateKeyPress("c")\'>sim</button>'); | |
| // simulateKey('a', $('input')[0]); | |
| // ############################################################################################################ | |
| // go! | |
| // ############################################################################################################ | |
| autoPlay(true); |
why is not working for me
show the error, let me see if I found the solution
has anyone found the solution????
has anyone found the solution? I think it dosen't work anymore, probably we need to make another code
someone pls make a new code
ยฟAlguien ha encontrado la soluciรณn? Creo que ya no funciona, probablemente necesitemos hacer otro cรณdigo
https://github.com/DonMarmolejo727/TypingClub-Extractor.git
Hello brother, try using this code that was developed by a great team of programmers.
Que alguien cree un cรณdigo nuevo, por favor
Alright bro, check out my repository :)
someone pls make a new code
Yeah we need one, pls someone make one
Did you or someone find the solution??? Im trying to fix it but this is a little more difficult and I can't find a solution
Yeah np just asking C:
maybe cuz its not your code? Wowie.
can any one share the new code pls
// Typing Club Automator - AUTO START
(function() {
'use strict';
if (window.typingClubBot) {
console.log('Bot already running! Close it first with: window.typingClubBot.close()');
return;
}
console.log('๐ Loading Typing Club Bot...');
const gui = document.createElement('div');
gui.id = 'typing-bot-gui';
gui.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
width: 340px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 15px;
box-shadow: 0 10px 40px rgba(0,0,0,0.5);
z-index: 2147483647;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
color: white;
`;
gui.innerHTML = `
<div style="padding: 15px 20px; border-bottom: 1px solid rgba(255,255,255,0.2); display: flex; justify-content: space-between; align-items: center; cursor: move;" id="bot-header">
<div style="font-weight: 700; font-size: 16px;">๐ฏ Typing Club Bot</div>
<button id="bot-close" style="background: rgba(255,255,255,0.2); border: none; color: white; width: 28px; height: 28px; border-radius: 50%; cursor: pointer; font-size: 18px;">ร</button>
</div>
<div style="padding: 20px;">
<div style="background: rgba(255,255,255,0.1); padding: 10px; border-radius: 8px; font-size: 11px; margin-bottom: 10px;">
<strong style="display: block; margin-bottom: 5px;">๐ Detected:</strong>
<span id="level-info">Waiting...</span>
</div>
<div style="margin-bottom: 18px;">
<label style="display: block; font-size: 12px; font-weight: 600; margin-bottom: 8px; text-transform: uppercase;">Speed</label>
<div style="background: rgba(255,255,255,0.15); padding: 12px; border-radius: 10px;">
<input type="range" id="speed-slider" min="30" max="190" value="70" style="width: 100%; margin: 8px 0; cursor: pointer;">
<div style="text-align: center; font-size: 20px; font-weight: 700; margin-top: 5px;"><span id="speed-value">70</span> WPM</div>
</div>
</div>
<div style="margin-bottom: 18px;">
<label style="display: block; font-size: 12px; font-weight: 600; margin-bottom: 8px; text-transform: uppercase;">Accuracy</label>
<div style="background: rgba(255,255,255,0.15); padding: 12px; border-radius: 10px;">
<input type="range" id="accuracy-slider" min="92" max="100" value="97" style="width: 100%; margin: 8px 0; cursor: pointer;">
<div style="text-align: center; font-size: 20px; font-weight: 700; margin-top: 5px;"><span id="accuracy-value">97</span>%</div>
</div>
</div>
<div style="display: flex; align-items: center; gap: 10px; background: rgba(255,255,255,0.15); padding: 12px; border-radius: 10px; margin-bottom: 10px;">
<input type="checkbox" id="auto-advance" checked style="width: 20px; height: 20px; cursor: pointer;">
<label for="auto-advance" style="cursor: pointer; flex: 1; font-size: 14px;">Auto-advance</label>
</div>
<button id="start-btn" style="width: 100%; padding: 12px; border: none; border-radius: 10px; font-size: 14px; font-weight: 700; cursor: pointer; text-transform: uppercase; background: #10ac84; color: white; margin-bottom: 10px;">โถ Start Bot</button>
<button id="stop-btn" disabled style="width: 100%; padding: 12px; border: none; border-radius: 10px; font-size: 14px; font-weight: 700; cursor: pointer; text-transform: uppercase; background: #ff6b6b; color: white; margin-bottom: 10px; opacity: 0.5;">โน Stop</button>
<div id="status" style="background: rgba(255,255,255,0.15); padding: 12px; border-radius: 10px; text-align: center; font-size: 13px; font-weight: 600; margin-top: 15px;">Ready</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 15px;">
<div style="background: rgba(255,255,255,0.15); padding: 10px 8px; border-radius: 8px; text-align: center;">
<div style="font-size: 18px; font-weight: 700;" id="chars-typed">0</div>
<div style="font-size: 9px; opacity: 0.8; margin-top: 3px;">CHARS</div>
</div>
<div style="background: rgba(255,255,255,0.15); padding: 10px 8px; border-radius: 8px; text-align: center;">
<div style="font-size: 18px; font-weight: 700;" id="levels-completed">0</div>
<div style="font-size: 9px; opacity: 0.8; margin-top: 3px;">LEVELS</div>
</div>
</div>
</div>
`;
document.body.appendChild(gui);
const speedSlider = document.getElementById('speed-slider');
const speedValue = document.getElementById('speed-value');
const accuracySlider = document.getElementById('accuracy-slider');
const accuracyValue = document.getElementById('accuracy-value');
const autoAdvance = document.getElementById('auto-advance');
const startBtn = document.getElementById('start-btn');
const stopBtn = document.getElementById('stop-btn');
const status = document.getElementById('status');
const levelInfo = document.getElementById('level-info');
const charsTypedEl = document.getElementById('chars-typed');
const levelsCompletedEl = document.getElementById('levels-completed');
const closeBtn = document.getElementById('bot-close');
const header = document.getElementById('bot-header');
let botRunning = false;
let charsTypedCount = 0;
let levelsCompleted = 0;
speedSlider.addEventListener('input', (e) => speedValue.textContent = e.target.value);
accuracySlider.addEventListener('input', (e) => accuracyValue.textContent = e.target.value);
// Draggable
let isDragging = false;
let currentX, currentY, initialX, initialY;
header.addEventListener('mousedown', (e) => {
initialX = e.clientX - gui.offsetLeft;
initialY = e.clientY - gui.offsetTop;
isDragging = true;
});
document.addEventListener('mousemove', (e) => {
if (isDragging) {
e.preventDefault();
currentX = e.clientX - initialX;
currentY = e.clientY - initialY;
gui.style.left = currentX + 'px';
gui.style.top = currentY + 'px';
gui.style.right = 'auto';
}
});
document.addEventListener('mouseup', () => isDragging = false);
function detectLevel() {
// Try to find typing text
const typable = document.querySelector('div.typable');
if (typable && typable.textContent) {
const text = typable.textContent.trim().replace(/\s+/g, ' ');
levelInfo.textContent = `${text.length} chars detected`;
return { text, type: 'typing' };
}
// Check for games - look for game container or canvas
const gameContainer = document.querySelector('.game-container, .game-canvas, canvas, #game, [class*="game"]');
if (gameContainer) {
levelInfo.textContent = 'Game detected';
return { text: null, type: 'game' };
}
return { text: null, type: null };
}
function typeChar(char, field) {
const keyCode = char.charCodeAt(0);
let code = 'Unidentified';
let shiftKey = false;
// Map special characters properly
const specialChars = {
' ': { code: 'Space', keyCode: 32 },
'"': { code: 'Quote', keyCode: 222, shiftKey: true },
"'": { code: 'Quote', keyCode: 222, shiftKey: false },
',': { code: 'Comma', keyCode: 188 },
'.': { code: 'Period', keyCode: 190 },
'!': { code: 'Digit1', keyCode: 49, shiftKey: true },
'?': { code: 'Slash', keyCode: 191, shiftKey: true },
':': { code: 'Semicolon', keyCode: 186, shiftKey: true },
';': { code: 'Semicolon', keyCode: 186 },
'-': { code: 'Minus', keyCode: 189 },
'(': { code: 'Digit9', keyCode: 57, shiftKey: true },
')': { code: 'Digit0', keyCode: 48, shiftKey: true }
};
if (specialChars[char]) {
code = specialChars[char].code;
shiftKey = specialChars[char].shiftKey || false;
} else if (/[a-z]/.test(char)) {
code = `Key${char.toUpperCase()}`;
shiftKey = false;
} else if (/[A-Z]/.test(char)) {
code = `Key${char}`;
shiftKey = true;
} else if (/[0-9]/.test(char)) {
code = `Digit${char}`;
shiftKey = false;
}
const opts = {
key: char,
code: code,
keyCode: keyCode,
which: keyCode,
shiftKey: shiftKey,
bubbles: true,
cancelable: true,
view: window
};
field.dispatchEvent(new KeyboardEvent('keydown', opts));
field.dispatchEvent(new KeyboardEvent('keypress', opts));
field.value += char;
field.dispatchEvent(new Event('input', { bubbles: true }));
field.dispatchEvent(new Event('change', { bubbles: true }));
field.dispatchEvent(new KeyboardEvent('keyup', opts));
}
async function processLevel() {
if (!botRunning) return;
const level = detectLevel();
if (!level.text && level.type !== 'game') {
status.textContent = 'โ ๏ธ No text or game found';
console.log('โ Could not find text or game');
stopBot();
return;
}
// Handle games
if (level.type === 'game') {
console.log('๐ฎ Game detected, auto-playing...');
status.textContent = '๐ฎ Playing game...';
// Wait for game to load
await new Promise(r => setTimeout(r, 2000));
// Spam keys that games commonly use
const gameKeys = ['Space', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Enter', 'KeyW', 'KeyA', 'KeyS', 'KeyD'];
for (let i = 0; i < 50; i++) {
if (!botRunning) return;
// Press random game key
const randomKey = gameKeys[Math.floor(Math.random() * gameKeys.length)];
const keyOpts = {
key: randomKey.includes('Arrow') || randomKey.includes('Space') ? randomKey.replace('Arrow', '').replace('Key', '') : randomKey.replace('Key', '').toLowerCase(),
code: randomKey,
keyCode: randomKey === 'Space' ? 32 : randomKey.includes('Arrow') ? (randomKey === 'ArrowUp' ? 38 : randomKey === 'ArrowDown' ? 40 : randomKey === 'ArrowLeft' ? 37 : 39) : randomKey.charCodeAt(3),
bubbles: true,
cancelable: true,
view: window
};
document.dispatchEvent(new KeyboardEvent('keydown', keyOpts));
document.dispatchEvent(new KeyboardEvent('keyup', keyOpts));
// Also click randomly on screen
if (i % 5 === 0) {
const x = Math.random() * window.innerWidth;
const y = Math.random() * window.innerHeight;
const el = document.elementFromPoint(x, y);
if (el && !el.closest('#typing-bot-gui')) {
el.click();
}
}
await new Promise(r => setTimeout(r, 100));
}
console.log('๐ฎ Game sequence complete');
status.textContent = 'โ
Game complete!';
if (autoAdvance.checked) {
await new Promise(r => setTimeout(r, 6000));
// Click to advance
document.body.click();
const clickables = document.querySelectorAll('button, .btn, [role="button"]');
clickables.forEach(el => {
if (el.offsetParent !== null && !el.closest('#typing-bot-gui')) {
el.click();
}
});
await new Promise(r => setTimeout(r, 1000));
if (botRunning) processLevel();
} else {
stopBot();
}
return;
}
// Handle typing (existing code)
const text = level.text;
console.log('๐ Text:', text);
status.textContent = '๐ Starting lesson...';
// Try multiple ways to trigger the lesson
// Method 1: Click the typing area
const typingArea = document.querySelector('.tpmodes, .typable, .inview');
if (typingArea) {
console.log('Clicking typing area...');
typingArea.click();
}
// Method 2: Click anywhere on body
document.body.click();
// Method 3: Press a key to trigger
document.dispatchEvent(new KeyboardEvent('keydown', { key: ' ', keyCode: 32, bubbles: true }));
await new Promise(r => setTimeout(r, 500));
// Find the input field (might take a moment to appear)
let input = null;
for (let attempt = 0; attempt < 30; attempt++) {
const allInputs = document.querySelectorAll('input[type="text"]');
console.log(`Attempt ${attempt}: Found ${allInputs.length} inputs`);
for (const inp of allInputs) {
console.log(' Input:', {
visible: inp.offsetParent !== null,
ariaHidden: inp.getAttribute('aria-hidden'),
style: inp.style.cssText
});
// Accept ANY text input, even if hidden or aria-hidden
if (inp.type === 'text') {
input = inp;
console.log('โ
Using this input!');
break;
}
}
if (input) break;
await new Promise(r => setTimeout(r, 100));
}
if (!input) {
status.textContent = 'โ ๏ธ Input not found';
console.log('โ No input field found at all');
stopBot();
return;
}
console.log('๐ Typing...');
input.value = '';
input.focus();
await new Promise(r => setTimeout(r, 100));
const wpm = parseInt(speedSlider.value);
const accuracy = parseInt(accuracySlider.value);
const baseDelay = 60000 / (wpm * 5);
status.textContent = `โจ๏ธ Typing...`;
for (let i = 0; i < text.length; i++) {
if (!botRunning) return;
const char = text[i];
const shouldError = Math.random() * 100 > accuracy;
if (shouldError && /[a-z]/i.test(char)) {
const wrong = String.fromCharCode(char.charCodeAt(0) + (Math.random() > 0.5 ? 1 : -1));
typeChar(wrong, input);
await new Promise(r => setTimeout(r, baseDelay * 0.5));
input.value = input.value.slice(0, -1);
await new Promise(r => setTimeout(r, baseDelay * 0.3));
}
typeChar(char, input);
charsTypedCount++;
charsTypedEl.textContent = charsTypedCount;
let delay = baseDelay * (0.8 + Math.random() * 0.4);
if (['.', '!', '?'].includes(char)) delay *= 2;
else if (char === ' ') delay *= 1.3;
await new Promise(r => setTimeout(r, delay));
}
console.log('โ
Complete!');
levelsCompleted++;
levelsCompletedEl.textContent = levelsCompleted;
status.textContent = 'โ
Complete! Waiting...';
if (autoAdvance.checked) {
// Wait 6 seconds for level to finish processing
await new Promise(r => setTimeout(r, 6000));
// ONE TIME: Spam Enter on everything
console.log('Pressing Enter to advance...');
const enterOpts = {
key: 'Enter',
code: 'Enter',
keyCode: 13,
which: 13,
bubbles: true,
cancelable: true,
view: window
};
// Fire on document, input, and body
document.dispatchEvent(new KeyboardEvent('keydown', enterOpts));
document.dispatchEvent(new KeyboardEvent('keypress', enterOpts));
document.dispatchEvent(new KeyboardEvent('keyup', enterOpts));
if (input) {
input.dispatchEvent(new KeyboardEvent('keydown', enterOpts));
input.dispatchEvent(new KeyboardEvent('keypress', enterOpts));
input.dispatchEvent(new KeyboardEvent('keyup', enterOpts));
}
document.body.dispatchEvent(new KeyboardEvent('keydown', enterOpts));
document.body.dispatchEvent(new KeyboardEvent('keypress', enterOpts));
document.body.dispatchEvent(new KeyboardEvent('keyup', enterOpts));
// ONE TIME: Click everything
console.log('Clicking to advance...');
document.body.click();
// Click center of screen
const centerX = window.innerWidth / 2;
const centerY = window.innerHeight / 2;
const centerEl = document.elementFromPoint(centerX, centerY);
if (centerEl && !centerEl.closest('#typing-bot-gui')) {
centerEl.click();
}
// Click all buttons
const clickables = document.querySelectorAll('button, .btn, [role="button"], div[onclick], a');
clickables.forEach(el => {
if (el.offsetParent !== null && !el.closest('#typing-bot-gui')) {
el.click();
}
});
// Wait then restart
await new Promise(r => setTimeout(r, 1000));
if (botRunning) processLevel();
} else {
stopBot();
}
}
function startBot() {
botRunning = true;
startBtn.disabled = true;
stopBtn.disabled = false;
stopBtn.style.opacity = '1';
console.log('๐ค Bot started');
processLevel();
}
function stopBot() {
botRunning = false;
startBtn.disabled = false;
stopBtn.disabled = true;
stopBtn.style.opacity = '0.5';
status.textContent = 'โน Stopped';
}
function closeBot() {
stopBot();
gui.remove();
window.typingClubBot = null;
}
startBtn.addEventListener('click', startBot);
stopBtn.addEventListener('click', stopBot);
closeBtn.addEventListener('click', closeBtn);
window.typingClubBot = { start: startBot, stop: stopBot, close: closeBot };
setTimeout(detectLevel, 500);
console.log('โ
Bot loaded! Just click Start Bot.');
})();

why is not working for me