Last active
January 7, 2025 10:41
-
-
Save gerwld/3151df0117b8450566257e3191c44f5c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This script automates the process of unblocking your own blocked Instagram users list. | |
* It unblocks users one-by-one to avoid hitting rate limits or breaking the page. | |
* | |
* WARNING: This function directly manipulates the DOM and depends on the current HTML | |
* structure of Instagram's website to work. If Instagram implements changes to the | |
* activity page layout, structure, or functionality, this script may break or cause | |
* unexpected behavior. Use at your own risk and always review code before running it. | |
**/ | |
(async function () { | |
const DELETION_BATCH_SIZE = 100; | |
const DELAY_BETWEEN_ACTIONS_MS = 1100; | |
const DELAY_BETWEEN_CHECKBOX_CLICKS_MS = 890; | |
const CONFIRMATION_TIMEOUT_MS = 5000; | |
const DOM_UPDATE_TIMEOUT_MS = 10000; | |
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); | |
const waitForElement = async (selector, timeout = 30000) => { | |
const startTime = Date.now(); | |
while (Date.now() - startTime < timeout) { | |
const element = document.querySelector(selector); | |
if (element) return element; | |
await delay(100); | |
} | |
throw new Error(`Element with selector "${selector}" not found within ${timeout}ms`); | |
}; | |
const clickElement = async (element) => { | |
if (!element) throw new Error('Element not found'); | |
element.click(); | |
}; | |
const waitForUpdatedCheckboxes = async (selector, timeout = DOM_UPDATE_TIMEOUT_MS) => { | |
const startTime = Date.now(); | |
while (Date.now() - startTime < timeout) { | |
const checkboxes = document.querySelectorAll(selector); | |
if (checkboxes.length > 0) return checkboxes; | |
console.log('Waiting for checkboxes to update...'); | |
await delay(500); | |
} | |
throw new Error('Checkboxes did not update in time.'); | |
}; | |
const deleteActivity = async () => { | |
try { | |
while (true) { | |
console.log("Looking for 'Unblock' checkboxes..."); | |
let checkboxes = await waitForUpdatedCheckboxes('[aria-label="Unblock"]'); | |
if (checkboxes.length === 0) { | |
console.log('No more items to unblock.'); | |
break; | |
} | |
for (let i = 0; i < Math.min(DELETION_BATCH_SIZE, checkboxes.length); i++) { | |
try { | |
// Gets all checkboxes one more time, as Instagram fetches all of them & updates the DOM on each operation. | |
checkboxes = document.querySelectorAll('[aria-label="Unblock"]'); | |
const checkbox = checkboxes[i]; | |
if (!checkbox) { | |
console.log(`Checkbox ${i + 1} disappeared, refreshing the list...`); | |
continue; // Skipping operation if checkbox dissapear | |
} | |
console.log(`Clicking checkbox ${i + 1} of ${checkboxes.length}...`); | |
await clickElement(checkbox); | |
await delay(DELAY_BETWEEN_CHECKBOX_CLICKS_MS); | |
console.log('Waiting for confirmation button...'); | |
const confirmButton = await waitForElement('._a9--._ap36._a9_1', CONFIRMATION_TIMEOUT_MS); | |
console.log('Clicking confirm button...'); | |
await clickElement(confirmButton); | |
await delay(DELAY_BETWEEN_ACTIONS_MS); | |
console.log('Successfully unblocked.'); | |
} catch (error) { | |
console.error(`Error processing checkbox ${i + 1}:`, error.message); | |
} | |
} | |
console.log('Waiting for DOM update after batch operation...'); | |
checkboxes = await waitForUpdatedCheckboxes('[aria-label="Unblock"]', DOM_UPDATE_TIMEOUT_MS); | |
if (checkboxes.length === 0) { | |
console.log('No more items to unblock.'); | |
break; | |
} | |
} | |
} catch (error) { | |
console.error('Error in deleteActivity:', error.message); | |
} | |
}; | |
try { | |
console.log('Starting unblock process...'); | |
await deleteActivity(); | |
console.log('Unblock process completed.'); | |
} catch (error) { | |
console.error('Fatal error:', error.message); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment