Skip to content

Instantly share code, notes, and snippets.

@Shikkic
Last active April 7, 2025 13:56
Show Gist options
  • Save Shikkic/89414b26da97930bd3e0e43d377ef95b to your computer and use it in GitHub Desktop.
Save Shikkic/89414b26da97930bd3e0e43d377ef95b to your computer and use it in GitHub Desktop.
Remove all saved (deleted) messages from your saved view in Slack
// 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!');
})();
@Shikkic
Copy link
Author

Shikkic commented Apr 4, 2025

@Shikkic
Copy link
Author

Shikkic commented Apr 4, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment