Skip to content

Instantly share code, notes, and snippets.

@GrzegorzManiak
Created October 13, 2023 12:29
Show Gist options
  • Save GrzegorzManiak/03cdc5a2c04a90da5153d8283930cbab to your computer and use it in GitHub Desktop.
Save GrzegorzManiak/03cdc5a2c04a90da5153d8283930cbab to your computer and use it in GitHub Desktop.
Unlikes all your liked content on Twitter / X automatically
//
// ENSURE that you are on your own page eg https://twitter.com/x/likes
// Wait for the page to fully load, and than copy / paste this script
// into the console.
//
// There are two variables that you can change, SLEEP_FOR and CLICK_DELAY
// --> SLEEP_FOR: Min,Max timeout before scrolling down
// --> CLICK_DELAY: Min,Max timeout between clicking the element
//
(async() => {
const SLEEP_FOR = [1000, 2000];
const CLICK_DELAY = [50, 150];
// -- Map to store the liked content
const liked_map = new Map();
// -- Dir='ltr' exits on some elements, we just need to find the
// one where theres 'likes' in the innerText
const elms = Array.from(document.querySelectorAll('[dir="ltr"]')),
likes = elms.filter((item) => item.innerText.includes('Likes'));
// -- Skip the first element and get the second one
const likes_elm = likes[1];
if (!likes_elm) throw new Error('Could not find the likes element');
// -- Function used to return the total number of posts liked
const get_total_likes = () => {
const total_likes = parseInt(likes_elm.innerText.split(' ')[0].replace(',', ''));
console.log(`Total Likes remaining: ${total_likes}`);
return total_likes;
};
// -- Function used to return all the liked content on the page
// without returning duplicates
const get_liked = () => {
// -- Get all the liked content on the page
const liked = Array.from(document.querySelectorAll('[data-testid="unlike"]'));
// -- Ensure that we arent returning duplicates
const unique = liked.filter((item) => !liked_map.has(item));
// -- Add the liked content to the map
unique.forEach((item) => liked_map.set(item, false));
// -- Return the unique liked content
return unique;
};
// -- Progresses down the page and unlikes all the content
const step = async() => {
// -- Get the liked content
const liked = get_liked();
// -- Unlikes all the content
for (const item of liked) {
// -- Click the item
item.click();
// -- Wait for a random amount of time
await sleep(CLICK_DELAY);
}
// -- Scrolls down the page
window.scrollTo(0, document.body.scrollHeight);
}
// -- Simple sleep function
const sleep = (min_max) => new Promise((resolve) => {
const min = min_max[0], max = min_max[1];
const time = Math.floor(Math.random() * (max - min + 1)) + min;
setTimeout(resolve, time);
});
const started_with = get_total_likes();
// -- Run the step function every 2 seconds
while (true) {
await step();
await sleep(SLEEP_FOR);
// -- If there are no more likes left, exit the loop
if (get_total_likes() === 0) break;
}
console.log(`Unliked ${started_with} posts`);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment