Skip to content

Instantly share code, notes, and snippets.

@SEAPUNK
Last active December 2, 2022 08:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SEAPUNK/a3ab12970796d17980216ea9f4d55e99 to your computer and use it in GitHub Desktop.
Save SEAPUNK/a3ab12970796d17980216ea9f4d55e99 to your computer and use it in GitHub Desktop.
steam bulk key activation
// Step 1: Head to https://store.steampowered.com/account/registerkey
// Step 2: Change the content of _remaining_keys to your list of keys (1 key per line!)
// Step 3: Paste this shit into your browser Javascript console
// Step 4: Type `activateKeys()` and press enter and wait
const _remaining_keys = new Set(`
YOUR1-KEYS1-HERE1
YOUR2-KEYS2-HERE2
YOUR3-KEYS3-HERE3
YOUR4-KEYS4-HERE4
YOUR5-KEYS5-HERE5
YOUR6-KEYS6-HERE6
YOUR7-KEYS7-HERE7
`.trim().split('\n').map(key => key.trim()));
async function __activateKey(key) {
console.log(`[${key}] Redeeming`);
document.querySelector('#product_key').value = key;
document.querySelector('#accept_ssa').checked = true;
document.querySelector('#register_btn').click();
let waitAttempts = 0;
while (true) {
console.log(`[${key}] Waiting (attempt: ${++waitAttempts})`);
await new Promise((resolve) => setTimeout(resolve, 1500));
const isSuccess = document.querySelector('#receipt_form').style.display != 'none';
if (isSuccess) {
DisplayPage('code');
const productName = document.querySelector('#registerkey_productlist').textContent;
console.log(`[${key}] Redeemed: ${productName}`);
return true;
} else {
const errorDisplay = document.querySelector('#error_display');
const isError = errorDisplay.style.display == 'block';
if (errorDisplay.textContent.includes('This Steam account already owns')) {
console.log(`[${key}] Already redeemed`);
return true;
}
if (errorDisplay.textContent.includes('ownership of another product before activation')) {
console.log(`[${key}] Has prerequisite`);
return 'skip';
}
if (errorDisplay.textContent.includes('There have been too many recent activation attempts')) {
console.log(`[${key}] Rate limited!`);
} else {
console.error(`[${key}] TODO: ${errorDisplay.textContent}`);
}
if (isError) return false;
}
}
}
let lastActivateKeysRun = null;
async function activateKeys() {
const redeemed_keys = new Set();
const current_remaining_keys = new Set(Array.from(_remaining_keys));
for (let key of current_remaining_keys) {
const result = await __activateKey(key);
if (result === 'skip') continue;
if (!result) break;
_remaining_keys.delete(key);
redeemed_keys.add(key);
}
console.log(`Redeemed ${redeemed_keys.size} keys, ${_remaining_keys.size} remain...`);
console.log('Wait some time and then run activateKeys() again');
if (lastActivateKeysRun == null) {
setInterval(() => {
console.log(`Last activateKeys run: ${Math.floor((Date.now() - lastActivateKeysRun) / 1000 / 60)} minutes ago`);
}, 1000 * 60 * 5); // 5 mins
}
lastActivateKeysRun = Date.now();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment