Last active
August 7, 2024 00:14
-
-
Save deanmcpherson/cba1c873d954d84f8a7baf061fad1ad8 to your computer and use it in GitHub Desktop.
This file contains 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
/** | |
* Go To x.com/{YOUR_PROFILE}/following, copy and paste these functions into your console and run | |
* await summarizeFollowers() | |
* await removeFollowers(excluding? = ['usernaname_to_keep']) | |
*/ | |
// Auto-scroll function | |
const autoScroll = (onComplete) => { | |
const scrollHeight = document.documentElement.scrollHeight; | |
const currentPosition = window.pageYOffset; | |
const windowHeight = window.innerHeight; | |
if (currentPosition + windowHeight < scrollHeight) { | |
window.scrollTo({ | |
top: currentPosition + 500, | |
behavior: 'smooth' | |
}); | |
return false; | |
} else { | |
// If we've reached the bottom | |
onComplete(); | |
return true; | |
} | |
}; | |
//build list | |
const summarizeFollowers = () => new Promise((resolve) => { | |
const usernames = []; | |
const followers = []; | |
const non_followers = []; | |
const checkForNew = () => { | |
Array.from(document.querySelectorAll('[data-testid="UserCell"] ')) | |
.forEach((userCell) => { | |
const a = userCell.querySelector('a'); | |
const id = a.href?.split('/').pop(); | |
const isFollower = !!userCell.querySelector('[data-testid="userFollowIndicator"]'); | |
if (id && !usernames.includes(id)) { | |
usernames.push(id); | |
if (isFollower) { | |
followers.push(id); | |
} else { | |
non_followers.push(id); | |
} | |
} | |
}); | |
} | |
let polling = setInterval(checkForNew, 500); | |
const onComplete = () => { | |
clearInterval(scrollInterval); | |
clearInterval(polling); | |
resolve({ | |
usernames, | |
followers, | |
non_followers | |
}); | |
}; | |
let scrollInterval = setInterval(() => autoScroll(onComplete), 1000); // Scroll every second | |
}); | |
//Remove whoever you want. | |
const removeFollowers = (excluding) => new Promise((resolve) => { | |
excluding = excluding || []; | |
const usernames = []; | |
const removed = []; | |
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms)); | |
const checkForNew = async () => { | |
const userCells = Array.from(document.querySelectorAll('[data-testid="UserCell"] ')) | |
for (const userCell of userCells) { | |
const a = userCell.querySelector('a'); | |
const id = a.href?.split('/').pop(); | |
const unfollowBtn = userCell.querySelector('[data-testid*="-unfollow"]'); | |
if (id && !usernames.includes(id)) { | |
usernames.push(id); | |
if (unfollowBtn && !excluding.includes(id)) { | |
unfollowBtn.click(); | |
//adjust if you want to add delay in between unfollows, but it might cause bugs as the auto scroll keeps on going | |
await sleep(50); | |
document.querySelector('[data-testid="confirmationSheetConfirm"]').click(); | |
removed.push(id); | |
} | |
} | |
} | |
} | |
const polling = setInterval(checkForNew, 1000); | |
const onComplete = () => { | |
clearInterval(polling); | |
clearInterval(autoScrollInterval); | |
resolve(removed); | |
}; | |
const autoScrollInterval = setInterval(() => autoScroll(onComplete), 1000); // Scroll every second | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment