Last active
April 7, 2025 13:56
-
-
Save Shikkic/89414b26da97930bd3e0e43d377ef95b to your computer and use it in GitHub Desktop.
Remove all saved (deleted) messages from your saved view in Slack
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Remove all saved (deleted) messages from your saved view in Slack | |
// Open Slack in a web browser and log in | |
// Go to your Saved/Later messages screen | |
// Click on either In Progress, Archived, or Completed for the list you want to delete. | |
// F12 to raise dev console | |
// Paste the below | |
// Wait a while till it does its thing. If you need to stop it, close the tab. | |
(async function deleteDeletedLaterItems() { | |
const BATCH_SIZE = 25; | |
const CLICK_DELAY = 250; | |
const MODAL_DELAY = 200; | |
const SCROLL_DELAY = 500; | |
const MAX_SCROLL_RETRIES = 5; | |
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms)); | |
const getTombstones = () => | |
Array.from(document.querySelectorAll('.c-message_kit__tombstone')) | |
.filter(el => el.offsetParent !== null); | |
const scrollToBottom = () => { | |
const scrollArea = document.querySelector('.p-saved_for_later_page__list_wrapper .c-scrollbar__hider'); | |
if (scrollArea) { | |
scrollArea.scrollTop = scrollArea.scrollHeight; | |
} else { | |
window.scrollTo(0, document.body.scrollHeight); | |
} | |
}; | |
const refreshList = async (lastCount) => { | |
let retries = 0; | |
while (retries < MAX_SCROLL_RETRIES) { | |
scrollToBottom(); | |
await sleep(SCROLL_DELAY); | |
const newTombstones = getTombstones(); | |
if (newTombstones.length > lastCount) { | |
return; | |
} | |
retries++; | |
} | |
}; | |
let totalProcessed = 0; | |
while (true) { | |
let tombstones = getTombstones(); | |
if (tombstones.length === 0) { | |
console.log('[Slack Deleted Message Remover] No visible tombstones. Trying to scroll and refresh...'); | |
await refreshList(0); | |
tombstones = getTombstones(); | |
if (tombstones.length === 0) { | |
console.log('[Slack Deleted Message Remover] Still no tombstones. Done!'); | |
break; | |
} | |
} | |
for (let i = 0; i < tombstones.length && i < BATCH_SIZE; i++) { | |
const itemNum = totalProcessed + 1; | |
console.log(`[Slack Deleted Message Remover] Processing item ${itemNum}`); | |
tombstones[i].click(); | |
await sleep(MODAL_DELAY); | |
const modal = document.querySelector('.ReactModal__Content--after-open'); | |
if (modal) { | |
const removeBtn = Array.from(modal.querySelectorAll('button')).find(btn => btn.textContent.trim() === 'Remove'); | |
if (removeBtn) { | |
removeBtn.click(); | |
console.log(`[Slack Deleted Message Remover] Removed item ${itemNum}`); | |
} else { | |
console.warn(`[Slack Deleted Message Remover] Remove button not found for item ${itemNum}`); | |
} | |
} else { | |
console.warn(`[Slack Deleted Message Remover] Modal not found for item ${itemNum}`); | |
} | |
totalProcessed++; | |
await sleep(CLICK_DELAY); | |
} | |
console.log(`[Slack Deleted Message Remover] Processed ${totalProcessed} items, refreshing list...`); | |
await refreshList(getTombstones().length); | |
} | |
console.log('[Slack Deleted Message Remover] Done!'); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Inspired from https://gist.github.com/programmerdave/238f083cc6ca9e6fe89748fe6339c199