Skip to content

Instantly share code, notes, and snippets.

@ramsey
Forked from JamieMason/unfollow.js.md
Last active March 30, 2024 02:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ramsey/bdeefda66d6e2294d3466edcea30187b to your computer and use it in GitHub Desktop.
Save ramsey/bdeefda66d6e2294d3466edcea30187b to your computer and use it in GitHub Desktop.
Remove everyone following you on twitter.com
// Remove everyone following you on twitter.com
// https://gist.github.com/ramsey/bdeefda66d6e2294d3466edcea30187b
//
// 1. Go to https://twitter.com/YOUR_USER_NAME/followers
// 2. Open the Developer Console. (COMMAND+ALT+I on Mac)
// 3. Paste this into the Developer Console and run it
//
// If you start seeing error messages in the console with the code
// "429," this means Twitter is rate-limiting you. Stop the script
// (i.e., reload or close the browser tab), and try again later.
//
// Adapted from: Unfollow everyone on twitter.com, by Jamie Mason (https://twitter.com/fold_left)
// https://gist.github.com/JamieMason/7580315
//
// Last Updated: 25 Oct 2023
(() => {
const $moreButtons = '[aria-label="More"]';
const $removeFollowerButton = '[data-testid="removeFollower"]';
const $confirmButton = '[data-testid="confirmationSheetConfirm"]';
const retry = {
count: 0,
limit: 3,
};
const scrollToTheBottom = () => window.scrollTo(0, document.body.scrollHeight);
const retryLimitReached = () => retry.count === retry.limit;
const addNewRetry = () => retry.count++;
const sleep = ({ seconds }) =>
new Promise((proceed) => {
console.log(`WAITING FOR ${seconds} SECONDS...`);
setTimeout(proceed, seconds * 1000);
});
const remove = async (removeFollowerButton) => {
removeFollowerButton && removeFollowerButton.click();
await sleep({ seconds: 1 });
const confirmButton = document.querySelector($confirmButton);
confirmButton && confirmButton.click();
await sleep({ seconds: 2 });
};
const removeAll = async (moreButtons) => {
console.log(`REMOVING ${moreButtons.length} FOLLOWERS...`);
await Promise.all(
moreButtons.map(async (moreButton) => {
moreButton && moreButton.click();
await sleep({ seconds: 1 });
const removeFollowerButton = document.querySelector($removeFollowerButton);
await remove(removeFollowerButton);
})
);
};
const nextBatch = async () => {
const moreButtons = Array.from(document.querySelectorAll($moreButtons));
const moreButtonsWereFound = moreButtons.length > 0;
if (moreButtonsWereFound) {
await removeAll(moreButtons);
scrollToTheBottom();
await sleep({ seconds: 2 });
return nextBatch();
} else {
addNewRetry();
}
if (retryLimitReached()) {
console.log(`NO FOLLOWERS FOUND, SO I THINK WE'RE DONE`);
console.log(`RELOAD PAGE AND RE-RUN SCRIPT IF ANY WERE MISSED`);
} else {
scrollToTheBottom();
await sleep({ seconds: 2 });
return nextBatch();
}
};
nextBatch();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment