Skip to content

Instantly share code, notes, and snippets.

@gerwld
Last active January 9, 2025 00:39
Show Gist options
  • Save gerwld/6f767a238ad7510497167c56b0aecce0 to your computer and use it in GitHub Desktop.
Save gerwld/6f767a238ad7510497167c56b0aecce0 to your computer and use it in GitHub Desktop.
/**
* This script automates the process of deleting your own Instagram saved posts.
*
* Tested on 12429 posts - around 4h non-stop working script on the background tab. Result: Success! 0 saved.
*
* WARNING: This function directly manipulates the DOM and depends on the current HTML
* structure of Instagram's website to work. If Instagram implements changes to the
* activity page layout, structure, or functionality, this script may break or cause
* unexpected behavior. Use at your own risk and always review code before running it.
*
* How to use:
* 1. Navigate to the Instagram posts page by going to:
* https://www.instagram.com/your_nickname/saved/all-posts/
* 2. Open the developer console in your web browser:
* - Chrome/Firefox: Press Ctrl+Shift+J (Windows/Linux) or Cmd+Option+J (Mac)
* - Safari: Enable the Develop menu in Safari's Advanced preferences, then press Cmd+Option+C
* 3. Copy and paste this entire script into the console and press Enter to run it.
*
* How to navigate to the posts page on instagram.com:
* 1. Log in to Instagram on a desktop browser.
* 2. Go to https://www.instagram.com/your_nickname/saved/all-posts/
* 3. Follow the usage steps above to run this script.
*/
; (async function () {
// Constants
/** @const {number} - The number of posts to delete in each batch. */
const DELETION_BATCH_SIZE = 14
/** @const {number} - The delay between first action in milliseconds. */
const DELAY_BETWEEN_ACTION_MS = 1000
/** @const {number} - The delay after post was opened before it was unsaved */
const DELAY_BEFORE_UNSAVE_AFTER_OPENED_MS = 200
/** @const {number} - The delay before next post opening */
const DELAY_BEFORE_NEXT_POST_OPEN_MS = 200
/** @const {number} - The amount of scroll down events to fetch more posts. Bigger is better, but takes more time. */
const SCROLL_FETCH_AMOUNT = 5
let counter = 0;
/**
* Disables all images and videos to reduce the GPU usage
*/
const style = document.createElement('style');
style.innerHTML = `
img,
video {
display: none!important;
}
`;
// comment this line if you want to see images & videos
// document.head.appendChild(style);
/**
* Utility function that delays execution for a given amount of time.
* @param {number} ms - The milliseconds to delay.
* @returns {Promise<void>} A promise that resolves after the specified delay.
*/
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
/**
* Utility function that clicks on a given element.
* @param {Element} element - The element to click.
* @throws {Error} If the element is not found.
*/
const clickElement = (element) => {
return new Promise((resolve, reject) => {
if (!element) {
console.error('Element not found');
reject(new Error('Element not found'));
} else if (typeof element.click !== 'function') {
reject(new Error('Element does not have a click method'));
} else {
counter += 1;
element.click();
resolve('Element clicked successfully');
}
});
};
/**
* Utility function that scroll pages SCROLL_FETCH_AMOUNT times to fetch posts.
*/
async function fetchPostsNTimes() {
console.log('Fetching all saved posts by scrolling the page. Please wait.');
const scrollTimes = SCROLL_FETCH_AMOUNT; // Number of times to scroll
const scrollDelay = 4000; // Delay in milliseconds (4 seconds) between scrolls
for (let i = 0; i < scrollTimes; i++) {
window.scrollBy(0, window.innerHeight); // Scroll down by one viewport height
console.log(`Fetching all saved posts before unsaving them. Scrolled ${i + 1} times`);
await new Promise(resolve => setTimeout(resolve, scrollDelay)); // Wait 4 seconds before the next scroll
}
console.log('Finished scrolling');
}
/**
* Deletes all user saved posts by opening each one post and unsaving it.
* @returns {Promise<void>} A promise that resolves when all saved posts marks are deleted.
*/
const deleteActivity = async () => {
try {
while (true) {
let allPosts = document.querySelectorAll('.x1lliihq.x1n2onr6.xh8yej3.x4gyw5p.x2pgyrj.x56m6dy.x1ntc13c.xn45foy.x9i3mqj [role="link"]')
await delay(DELAY_BETWEEN_ACTION_MS)
for (let i = 0; i < Math.min(DELETION_BATCH_SIZE, allPosts.length); i++) {
await clickElement(allPosts[i])
await delay(500);
// queryselector of the opened post => save button
const currentSavedButtonUnsaved = document.querySelectorAll('[aria-label="Save"]');
if (currentSavedButtonUnsaved.length === 0) {
const currentSavedButton = document.querySelector('[aria-label="Remove"]')
const event = new MouseEvent('click', {
bubbles: true, // Ensures the event bubbles up (if needed)
cancelable: true, // Allows the event to be canceled
view: window // Links the event to the window object
});
// Dispatch the event on the element
currentSavedButton.dispatchEvent(event);
try {
await clickElement(currentSavedButton);
} catch (e) { }
console.log("Unsaved post, " + counter);
await delay(DELAY_BEFORE_UNSAVE_AFTER_OPENED_MS);
allPosts[i].remove()
await delay(DELAY_BEFORE_NEXT_POST_OPEN_MS)
} else {
console.log("Post already unsaved. Skipping");
allPosts[i].remove();
}
if (allPosts.length < 5) {
allPosts = document.querySelectorAll('.x1lliihq.x1n2onr6.xh8yej3.x4gyw5p.x2pgyrj.x56m6dy.x1ntc13c.xn45foy.x9i3mqj [role="link"]')
const closeButton = document.querySelector('[role="button"]:has([aria-label="Close"])')
await clickElement(closeButton);
await delay(5000);
console.log("Finished all fetched post. Restarting.\n");
await fetchPostsNTimes();
await deleteActivity();
}
}
}
} catch (error) {
console.error('Error in deleteActivity:', error.message)
}
}
// Start the deletion process
try {
// TODO: I'm bit tired now to make it in loop properly. Any pull-requests are higly appreciated.
await fetchPostsNTimes();
await delay(2000);
await deleteActivity();
console.log('Activity deletion completed')
} catch (error) {
console.error('Fatal error:', error.message)
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment