Welcome! Share code as fast as possible.
- Use the language picker to change the language manually.
- The previous link will get modified. You can then share this new link with others.
- Visit
https://code-dump.vercel.app/<extension>
- For example, to create a link which for a JavaScript code you will visit
https://code-dump.vercel.app/js
Any link generated does not have an expiry.
GitHub
;(async function () {
// ─────────────────────────────────────────────
// CONFIG (tweak if needed)
// ─────────────────────────────────────────────
const CFG = {
BATCH_SIZE: 10, // comments deleted per round
DELAY_CLICK: 350, // ms between each checkbox click
DELAY_AFTER_SELECT: 1800, // ms after clicking "Select"
DELAY_AFTER_DELETE: 2800, // ms after confirm deletion
RATE_LIMIT_PAUSE: 25000, // ms pause between batches (avoids IG rate-limit)
WATCH_MODE: true, // after cleanup, keep watching for new comments
WATCH_INTERVAL: 120000, // ms between watch-mode sweeps (2 min)
MAX_FIND_WAIT: 8000, // ms to wait for any element before giving up
}
// ─────────────────────────────────────────────
// LOGGER (styled console output)
// ─────────────────────────────────────────────
const log = {
info: (...a) => console.log('%c ℹ️ ', 'color:#4fc3f7;font-weight:bold', ...a),
ok: (...a) => console.log('%c ✅ ', 'color:#81c784;font-weight:bold', ...a),
warn: (...a) => console.warn('%c ⚠️ ', 'color:#ffb74d;font-weight:bold', ...a),
err: (...a) => console.error('%c ❌ ', 'color:#e57373;font-weight:bold', ...a),
step: (...a) => console.log('%c 🗑️ ', 'color:#ce93d8;font-weight:bold', ...a),
}
const delay = (ms) => new Promise(r => setTimeout(r, ms))
// ─────────────────────────────────────────────
// CLICK — two strategies, no double-toggle
// ─────────────────────────────────────────────
const nativeClick = (el) => el.click()
const syntheticClick = (el) => {
;['mousedown','mouseup','click'].forEach(type =>
el.dispatchEvent(new MouseEvent(type, { bubbles: true, cancelable: true }))
)
}
// Try native first (works for most buttons), fall back to synthetic
const click = (el, forceNative = false) => {
if (forceNative) return nativeClick(el)
try { syntheticClick(el) } catch { nativeClick(el) }
}
// ─────────────────────────────────────────────
// waitFor — polls until fn() returns truthy
// ─────────────────────────────────────────────
const waitFor = async (fn, ms = CFG.MAX_FIND_WAIT) => {
const end = Date.now() + ms
while (Date.now() < end) {
const el = fn()
if (el) return el
await delay(300)
}
return null
}
// ─────────────────────────────────────────────
// ELEMENT FINDERS — text/aria-only, no classes
// ─────────────────────────────────────────────
/**
* Find "Select" button.
* Strategy 1: find <span>Select</span>, walk up to role=button / <button>
* Strategy 2: querySelector role=button whose innerText is exactly "Select"
*/
const findSelectBtn = () => {
// S1 — span text walk-up
for (const span of document.querySelectorAll('span')) {
if (span.textContent.trim() === 'Select') {
let el = span
while (el && el.tagName !== 'BODY') {
if (el.getAttribute('role') === 'button' || el.tagName === 'BUTTON') return el
el = el.parentElement
}
return span.parentElement
}
}
// S2 — direct role=button text
return [...document.querySelectorAll('[role="button"], button')]
.find(el => el.innerText?.trim() === 'Select') || null
}
/**
* Find selectable comment items after "Select" mode is active.
* Tries multiple aria-labels in order.
*/
const findCommentItems = () => {
const LABELS = [
'Toggle checkbox',
'Image with button',
'Comment',
]
for (const label of LABELS) {
const els = [...document.querySelectorAll(`[aria-label="${label}"]`)]
if (els.length > 0) return els
}
// Generic fallback: any checkbox role inside the feed
const checks = [...document.querySelectorAll('[role="checkbox"]')]
return checks.length > 0 ? checks : null
}
/**
* Find the Delete action button (appears after items are selected).
* Never matches "Confirm Delete" dialog — that's a separate finder.
*/
const findDeleteBtn = () => {
// S1 — aria-label="Delete"
const byLabel = document.querySelector('[aria-label="Delete"]')
if (byLabel && isVisible(byLabel)) return byLabel
// S2 — role=button whose text is "Delete", must be visible, not inside a dialog
return [...document.querySelectorAll('[role="button"], button')]
.find(el =>
el.innerText?.trim() === 'Delete' &&
isVisible(el) &&
!el.closest('[role="dialog"],[role="alertdialog"]')
) || null
}
/**
* Find the confirm "Delete" button inside the confirmation dialog.
*/
const findConfirmBtn = () => {
// S1 — inside dialog
const inDialog = [...document.querySelectorAll('[role="dialog"] button, [role="alertdialog"] button')]
.find(el => el.innerText?.trim() === 'Delete')
if (inDialog) return inDialog
// S2 — any visible "Delete" button that's NOT the main delete action btn
return [...document.querySelectorAll('button')]
.find(el => el.innerText?.trim() === 'Delete' && isVisible(el)) || null
}
/**
* Dismiss OK/error popups from Instagram rate-limiting.
*/
const findOkBtn = () =>
[...document.querySelectorAll('button, [role="button"]')]
.find(el => el.innerText?.trim() === 'OK' && isVisible(el)) || null
const isVisible = (el) =>
el && el.offsetParent !== null && el.style.display !== 'none' && el.style.visibility !== 'hidden'
// ─────────────────────────────────────────────
// AUTO-DISMISS error dialogs in background
// ─────────────────────────────────────────────
const dismisser = setInterval(() => {
const ok = findOkBtn()
if (ok) { log.warn('Rate-limit dialog dismissed'); click(ok, true) }
}, 1200)
// ─────────────────────────────────────────────
// ESCAPE — exit select mode cleanly
// ─────────────────────────────────────────────
const pressEscape = () =>
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }))
// ─────────────────────────────────────────────
// CORE LOOP
// ─────────────────────────────────────────────
let totalDeleted = 0
const runOnce = async () => {
log.info('Starting sweep…')
while (true) {
// 1 ── Find & click "Select"
const selectBtn = await waitFor(findSelectBtn, 6000)
if (!selectBtn) {
log.ok(`No "Select" button found — sweep complete. Deleted this run: batch counted below.`)
return
}
click(selectBtn)
await delay(CFG.DELAY_AFTER_SELECT)
// 2 ── Gather comment items
const allItems = findCommentItems()
if (!allItems || allItems.length === 0) {
log.ok('No comment items visible — done.')
pressEscape()
return
}
const batch = allItems.slice(0, CFG.BATCH_SIZE)
log.step(`Selecting ${batch.length} / ${allItems.length} comments…`)
// 3 ── Click each checkbox exactly once, check aria-checked to avoid double-toggle
for (const item of batch) {
const already =
item.getAttribute('aria-checked') === 'true' ||
item.getAttribute('aria-selected') === 'true'
if (!already) {
click(item)
await delay(CFG.DELAY_CLICK)
}
}
await delay(1000)
// 4 ── Click Delete action button
const deleteBtn = await waitFor(findDeleteBtn, 6000)
if (!deleteBtn) {
log.warn('Delete button not found — escaping & retrying next batch')
pressEscape()
await delay(2000)
continue
}
click(deleteBtn)
await delay(1200)
// 5 ── Confirm deletion
const confirmBtn = await waitFor(findConfirmBtn, 6000)
if (!confirmBtn) {
log.err('Confirm dialog not found — stopping to prevent data loss')
pressEscape()
break
}
click(confirmBtn, true) // native click for dialog buttons
await delay(CFG.DELAY_AFTER_DELETE)
totalDeleted += batch.length
log.ok(`✔ ${totalDeleted} total deleted — pausing ${CFG.RATE_LIMIT_PAUSE / 1000}s…`)
await delay(CFG.RATE_LIMIT_PAUSE)
log.info('Resuming…')
}
}
// ─────────────────────────────────────────────
// WATCH MODE — re-sweep periodically
// ─────────────────────────────────────────────
await runOnce()
if (CFG.WATCH_MODE) {
log.info(`Watch mode ON — checking every ${CFG.WATCH_INTERVAL / 1000}s for new comments…`)
log.info('To stop: run window.__igStop = true in the console.')
window.__igStop = false
const watchLoop = async () => {
while (!window.__igStop) {
await delay(CFG.WATCH_INTERVAL)
if (window.__igStop) break
log.info('Watch sweep starting…')
await runOnce()
}
clearInterval(dismisser)
log.ok(`Stopped. Total deleted this session: ${totalDeleted}`)
}
watchLoop()
} else {
clearInterval(dismisser)
log.ok(`Script finished. Total deleted: ${totalDeleted}`)
}
})()