Skip to content

Instantly share code, notes, and snippets.

@JamieMason
Last active December 15, 2023 07:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save JamieMason/c408dc3ad96291a9bd75f7d462a4f545 to your computer and use it in GitHub Desktop.
Save JamieMason/c408dc3ad96291a9bd75f7d462a4f545 to your computer and use it in GitHub Desktop.
// Unfollow everyone on twitter.com, by Jamie Mason
// (https://twitter.com/fold_left)
//
// Commented version of
// https://gist.github.com/JamieMason/7580315
//
// 1. Go to https://twitter.com/YOUR_USER_NAME/following
// 2. Open the Developer Console. (COMMAND+ALT+I on Mac)
// 3. Paste this into the Developer Console and run it
//
// Last Updated: 24 January 2023
(() => {
// CSS Selector to find the unfollow buttons
const $followButtons = '[data-testid$="-unfollow"]';
// CSS Selector to find the confirm button in the popup
const $confirmButton = '[data-testid="confirmationSheetConfirm"]';
const retry = {
// Keep track of how many times the script has failed
count: 0,
// Set how many times the script can fail and try again before we give up
limit: 3,
};
// we begin here by going to `function nextBatch`
nextBatch();
async function nextBatch() {
// scroll down the page so that more users are loaded
scrollToTheBottom();
// allow some time for Twitter/your Browser to load the next set of users
await sleep({ seconds: 1 });
// get all the unfollow buttons which are currently on screen
const followButtons = Array.from(document.querySelectorAll($followButtons));
// count how many unfollow buttons were found
const followButtonsWereFound = followButtons.length > 0;
// if unfollow buttons were found
if (followButtonsWereFound) {
// then we can go and click them one by one
await unfollowAll(followButtons);
// then allow some time for Twitter/your Browser to unfollow those users
await sleep({ seconds: 2 });
// now we can repeat what we just did to see if there are more users
return nextBatch();
} else {
// if NO unfollow buttons were found, keep trying for a while just incase
addNewRetry();
}
// if we ran out of attempts to try again, either we've finished and there
// are no more users to unfollow, or something went wrong
if (retryLimitReached()) {
console.log(`NO ACCOUNTS FOUND, SO I THINK WE'RE DONE`);
console.log(`RELOAD PAGE AND RE-RUN SCRIPT IF ANY WERE MISSED`);
} else {
// otherwise we have more attempts to try again, so we'll give
// Twitter/your Browser some time first...
await sleep({ seconds: 2 });
// ..and then repeat what we just did to see if there are more users
return nextBatch();
}
}
// scroll down the page so that more users are loaded
function scrollToTheBottom() {
return window.scrollTo(0, document.body.scrollHeight);
}
// don't do anything for the given number `seconds`, then carry on
function sleep({ seconds }) {
return new Promise((proceed) => {
console.log(`WAITING FOR ${seconds} SECONDS...`);
setTimeout(proceed, seconds * 1000);
});
}
// compare how many times we've retried with the maximum amount we've set
// ourselves to retry before we quit
function retryLimitReached() {
return retry.count === retry.limit;
}
// add one to the number we're tracking of how many times we've tried again
function addNewRetry() {
return retry.count++;
}
// click each one of these unfollow buttons
async function unfollowAll(followButtons) {
console.log(`UNFOLLOWING ${followButtons.length} USERS...`);
// don't continue until we've finished unfollowing each user
await Promise.all(
// repeat the steps inside the {}s once for every button
followButtons.map(async (followButton) => {
// if the button exists, click it
followButton && followButton.click();
// allow some time for Twitter/your Browser
await sleep({ seconds: 1 });
// look for the "confirm" button in the popup that appears
const confirmButton = document.querySelector($confirmButton);
// if we found it, click it to unfollow the user
confirmButton && confirmButton.click();
// now we'll repeat with the next unfollow button in the list
})
);
}
// this wrapper is known as an "IIFE"
// https://developer.mozilla.org/en-US/docs/Glossary/IIFE
})();
@danielvaladao
Copy link

Now it is working just fine. I wasn't on the page https://twitter.com/YOUR_USER_NAME/following

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment