-
-
Save sbolel/a2b2bfde16b3ab185fbc2e2049240abc to your computer and use it in GitHub Desktop.
| /** | |
| * This script automates the process of deleting your own Instagram comments. | |
| * It deletes comments in batches to avoid hitting rate limits or breaking the page. | |
| * | |
| * 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 comments page by going to: | |
| * https://www.instagram.com/your_activity/interactions/comments | |
| * 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 comments page on instagram.com: | |
| * 1. Log in to Instagram on a desktop browser. | |
| * 2. Go to your profile by clicking on the profile icon at the bottom right. | |
| * 3. Click on "Your Activity" in the menu. | |
| * 4. Select "Interactions" and then "Comments". | |
| * 5. Follow the usage steps above to run this script. | |
| */ | |
| ;(async function () { | |
| // Constants | |
| /** @const {number} - The number of comments to delete in each batch. */ | |
| const DELETION_BATCH_SIZE = 3 | |
| /** @const {number} - The delay between actions in milliseconds. */ | |
| const DELAY_BETWEEN_ACTIONS_MS = 1000 | |
| /** @const {number} - The delay between clicking the checkboxes in milliseconds. */ | |
| const DELAY_BETWEEN_CHECKBOX_CLICKS_MS = 300 | |
| /** @const {number} - The maximum number of retries for waiting operations */ | |
| const MAX_RETRIES = 60 | |
| /** | |
| * 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 waits for an element to appear in the DOM before resolving. | |
| * @param {string} selector - The CSS selector of the element to wait for. | |
| * @param {number} [timeout=30000] - The maximum time to wait in milliseconds. | |
| * @returns {Promise<Element>} A promise that resolves with the found element. | |
| * @throws {Error} If the element is not found within the timeout period. | |
| */ | |
| const waitForElement = async (selector, timeout = 30000) => { | |
| const startTime = Date.now() | |
| while (Date.now() - startTime < timeout) { | |
| const element = document.querySelector(selector) | |
| if (element) return element | |
| await delay(100) | |
| } | |
| throw new Error(`Element with selector "${selector}" not found within ${timeout}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 = async (element) => { | |
| if (!element) throw new Error('Element not found') | |
| element.click() | |
| } | |
| /** | |
| * Waits for the "Select" button to reappear after the page loads more comments | |
| * following the deletion of a batch of comments when the "Select" button | |
| * is hidden while a spinner indicates that more comments are loading. | |
| * @returns {Promise<void>} A promise that resolves when the select button reappears. | |
| * @throws {Error} If the select button is not found after maximum retries. | |
| */ | |
| const waitForSelectButton = async () => { | |
| for (let i = 0; i < MAX_RETRIES; i++) { | |
| const buttonCount = document.querySelectorAll('[role="button"]')?.length | |
| if (buttonCount > 1) return | |
| await delay(1000) | |
| } | |
| throw new Error('Select button not found after maximum retries') | |
| } | |
| /** | |
| * Deletes the currently selected comments. | |
| * @returns {Promise<void>} A promise that resolves when the comments are deleted. | |
| */ | |
| const deleteSelectedComments = async () => { | |
| try { | |
| const deleteButton = await waitForElement('[aria-label="Delete"]') | |
| await clickElement(deleteButton) | |
| await delay(DELAY_BETWEEN_ACTIONS_MS) | |
| const confirmButton = await waitForElement('button[tabindex="0"]') | |
| await clickElement(confirmButton) | |
| } catch (error) { | |
| console.error('Error during comment deletion:', error.message) | |
| } | |
| } | |
| /** | |
| * Deletes all user comments by selecting comments in batches. | |
| * @returns {Promise<void>} A promise that resolves when all comments are deleted. | |
| */ | |
| const deleteActivity = async () => { | |
| try { | |
| while (true) { | |
| const [, selectButton] = document.querySelectorAll('[role="button"]') | |
| if (!selectButton) throw new Error('Select button not found') | |
| await clickElement(selectButton) | |
| await delay(DELAY_BETWEEN_ACTIONS_MS) | |
| const checkboxes = document.querySelectorAll('[aria-label="Toggle checkbox"]') | |
| if (checkboxes.length === 0) { | |
| console.log('No more comments to delete') | |
| break | |
| } | |
| for (let i = 0; i < Math.min(DELETION_BATCH_SIZE, checkboxes.length); i++) { | |
| await clickElement(checkboxes[i]) | |
| await delay(DELAY_BETWEEN_CHECKBOX_CLICKS_MS) | |
| } | |
| await delay(DELAY_BETWEEN_ACTIONS_MS) | |
| await deleteSelectedComments() | |
| await delay(DELAY_BETWEEN_ACTIONS_MS) | |
| await waitForSelectButton() | |
| await delay(DELAY_BETWEEN_ACTIONS_MS) | |
| } | |
| } catch (error) { | |
| console.error('Error in deleteActivity:', error.message) | |
| } | |
| } | |
| // Start the deletion process | |
| try { | |
| await deleteActivity() | |
| console.log('Activity deletion completed') | |
| } catch (error) { | |
| console.error('Fatal error:', error.message) | |
| } | |
| })() |
Wrote a better version.
/**
* Deletes all your Instagram comments by repeatedly:
* 1. Clicking Select
* 2. Ticking every visible checkbox
* 3. Clicking Delete and confirming
* Loops until no more comments are visible. Instagram loads more after each
* batch, which is why the loop continues.
*
* URL: https://www.instagram.com/your_activity/interactions/comments
* Open console (Cmd+Option+J), paste, Enter.
*/
;(async function () {
// ===== Config =====
/** @const {number} - Max comments to select per round. Infinity = all visible. */
const DELETION_BATCH_SIZE = Infinity
/** @const {number} - Delay between high-level actions. */
const DELAY_BETWEEN_ACTIONS_MS = 700
/** @const {number} - Delay between individual checkbox clicks. */
const DELAY_BETWEEN_CHECKBOX_CLICKS_MS = 80
/** @const {number} - Retries when waiting for the Select button to reappear. */
const MAX_RETRIES = 60
/** @const {string[]} - Accounts you don't want to delete comments under. */
const AUTHOR_WHITELIST = []
// ===== Selectors =====
const XPATH_SELECT_BUTTON = "//span[text()='Select']/.."
const XPATH_DELETE_BUTTON = '//span[text()="Delete"]/../../..'
const XPATH_CONFIRM_DELETE_BUTTON = '//button[div[text()="Delete"]]'
const XPATH_ERROR_MODAL_OK_BUTTON = '//button[div[text()="OK"]]'
// ===== Utilities =====
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
const waitForElementByXpath = async (xpath, timeout = 30000) => {
const startTime = Date.now()
while (Date.now() - startTime < timeout) {
const element = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null)?.iterateNext()
if (element) return element
await delay(100)
}
throw new Error(`Element with xpath "${xpath}" not found within ${timeout}ms`)
}
const resolveAuthor = (element) => {
const postContainer = element.closest('[style*="pointer-events: none; flex-direction: column;"]')
if (!postContainer) throw new Error("Could not resolve post container")
const author = postContainer.querySelector("span")
if (!author) throw new Error("Could not resolve author")
return author.innerText.trim()
}
const clickElement = async (element) => {
if (!element) throw new Error('Element not found')
element.click()
}
const waitForSelectButton = async () => {
for (let i = 0; i < MAX_RETRIES; i++) {
const found = document.evaluate(XPATH_SELECT_BUTTON, document, null, XPathResult.ANY_TYPE, null)?.iterateNext()
if (found) return
await delay(1000)
}
throw new Error('Select button not found after maximum retries')
}
const deleteSelectedComments = async () => {
try {
const deleteButton = await waitForElementByXpath(XPATH_DELETE_BUTTON)
await clickElement(deleteButton)
await delay(DELAY_BETWEEN_ACTIONS_MS)
const confirmButton = await waitForElementByXpath(XPATH_CONFIRM_DELETE_BUTTON)
await clickElement(confirmButton)
} catch (error) {
console.error('Error during comment deletion:', error.message)
}
}
const deleteActivity = async () => {
try {
while (true) {
const selectButton = Array.from(document.querySelectorAll('span'))
.find(span => span.textContent === 'Select')?.parentElement
if (!selectButton) throw new Error('Select button not found')
await clickElement(selectButton)
await delay(DELAY_BETWEEN_ACTIONS_MS)
const checkboxes = document.querySelectorAll('[aria-label="Toggle checkbox"]')
if (checkboxes.length === 0) {
const errorOk = document.evaluate(XPATH_ERROR_MODAL_OK_BUTTON, document, null, XPathResult.ANY_TYPE, null)?.iterateNext()
if (errorOk) {
console.log('Instagram rate limit hit, dismissing error modal')
await clickElement(errorOk)
await delay(DELAY_BETWEEN_ACTIONS_MS)
await waitForSelectButton()
await delay(DELAY_BETWEEN_ACTIONS_MS)
continue
} else {
console.log('No more comments to delete')
break
}
}
const limit = Math.min(DELETION_BATCH_SIZE, checkboxes.length)
console.log(`Selecting ${limit} comments...`)
for (let i = 0; i < limit; i++) {
try {
if (AUTHOR_WHITELIST.includes(resolveAuthor(checkboxes[i]))) continue
} catch (_) { /* author resolution failed, still try to select */ }
await clickElement(checkboxes[i])
await delay(DELAY_BETWEEN_CHECKBOX_CLICKS_MS)
}
await delay(DELAY_BETWEEN_ACTIONS_MS)
await deleteSelectedComments()
await delay(DELAY_BETWEEN_ACTIONS_MS)
await waitForSelectButton()
await delay(DELAY_BETWEEN_ACTIONS_MS)
}
} catch (error) {
console.error('Error in deleteActivity:', error.message)
}
}
// ===== Main =====
try {
await deleteActivity()
console.log('Activity deletion completed')
} catch (error) {
console.error('Fatal error:', error.message)
}
})()
`🎉 Here's a repo that has a chrome extension build: https://github.com/sbolel/instagram-comment-activity-deleter
it somewhat works right now:
- selects comments
- fails to press delete
- layout is wonky
thought i would contribute what i did in case anyone wants to use it for their own ends. i will preface, i am not a coder at all. i know zero coding, haven't done BASIC html since 2002, and it'll probably take me two hours of research to write a bash script cron job to empty the trash. the entirety of what follows was created by claude, in which it would give me a script to test in the developer console, and i would run it, and report back with the outcome, error outputs, and what i visually witnessed. that said, with some tinkering, i was able to get it to create a script that is quite reliable. not only will it click Select, choose a predetermined amount of comments (which can be changed), click Delete, then Delete again on the overlay popup to confirm, it also includes a delay (which can be adjusted) so that you don't get flagged, a delay to allow for ig taking a few sec to load the next set, it can deal with the "something went wrong" ig error popup, and it can deal with the event where ig gets stuck endless loading loop. because of that last one, i ditched using a script in the developer console for a tampermonkey script instead, such that it could refresh the whole page and keep working without missing a beat and also survive the refresh.
given the success of the delete comments tampermonkey script, i also had claude create a tampermonkey script for deleting likes, and story replies. all three of these scripts were working as of 5/12/26. i don't know how to add code here so i will post the code to pastebin (unlisted).
ig unliker: https://pastebin.com/xVbbrC2m
ig delete comment: https://pastebin.com/Yydc2hxH
ig delete story reply: https://pastebin.com/QgW90zXB
hope other ppl find it useful and they stay working for quite some time. sorry for using ai. fuck ai, but im grateful i didnt have to manually delete 14 years of history by hand.
@unknown74720 @a777x @GerardUmbert @theshubzworld @AtomicRobotMan0101
I Hope below works for you (updated [you can try second one first it is more general]) :
code1
code2