Skip to content

Instantly share code, notes, and snippets.

@cyrillsemenov
Created October 29, 2024 11:09
Show Gist options
  • Save cyrillsemenov/e9b014a68e4a2c1c2a1c175b8314f3de to your computer and use it in GitHub Desktop.
Save cyrillsemenov/e9b014a68e4a2c1c2a1c175b8314f3de to your computer and use it in GitHub Desktop.
Batch remove twitter followers
// Function to extract the username from the follower element
const get_username = (follower) => {
return new URL(
follower.children[1].querySelector("a").href
).pathname.substring(1);
};
// Function to extract the user ID from the button within the follower element
const get_user_id = (follower) => {
return follower.querySelector("button").dataset.testid.split("-")[0];
};
// Main function to print out JSON-formatted list of followers
(function print_followers() {
let users = {};
document
.querySelectorAll('button[data-testid="UserCell"] > div')
.forEach((follower) => {
const username = get_username(follower);
const userId = get_user_id(follower);
if (username && userId) {
users[username] = userId;
}
});
console.table(users);
console.log(JSON.stringify(users, null, 4));
})()
const users = {
// Paste users here
};
// Replace with your actual Bearer token, csrf token, and query ID
const BEARER_TOKEN = "YOUR_BEARER_TOKEN_HERE";
const CSRF_TOKEN = "YOUR_CSRF_TOKEN_HERE";
const QUERY_ID = "YOUR_QUERY_ID_HERE";
async function unfollowUser(user_id) {
try {
const response = await fetch(
"https://x.com/i/api/graphql/" + QUERY_ID + "/RemoveFollower",
{
headers: {
accept: "*/*",
"accept-language": "en-US,en;q=0.9",
authorization: `Bearer ${BEARER_TOKEN}`,
"content-type": "application/json",
"x-csrf-token": CSRF_TOKEN,
"x-twitter-active-user": "yes",
"x-twitter-auth-type": "OAuth2Session",
"x-twitter-client-language": "en",
},
body: JSON.stringify({
variables: {
target_user_id: user_id,
},
}),
method: "POST",
mode: "cors",
credentials: "include",
}
);
if (response.ok) {
console.log(`Successfully removed follower: ${user_id}`);
} else {
console.error(
`Failed to remove follower: ${user_id}`,
response.statusText
);
}
} catch (error) {
console.error(`Error unfollowing user ${user_id}`, error);
}
}
(function remove_followers(users, y = false) {
for (const [username, user_id] of Object.entries(users)) {
if (
y ||
confirm(
`User ${username} will unfollow you\nCancel to leave them in followers`
)
) {
unfollowUser(value);
}
}
})(
users,
false // If `true`, it skips the prompt and removes each user automatically
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment