// ==UserScript==
// @name Facebook Activity Auto Deleter (2025) - Improved
// @namespace https://greasyfork.org/en/users/1454546-shawnfrost13
// @version 5
// @description Automatically deletes Facebook activity log entries, confirms popups, and scrolls. Includes GUI toggle. Starts paused. Permanently skips problematic items.
// @author shawnfrost13 (improved by Claude)
// @license MIT
// @match https://www.facebook.com/*/allactivity*
// @grant none
// @run-at document-end
// @downloadURL none
// ==/UserScript==
(function () {
'use strict';
console.log("π₯ FB Auto Deleter 4.03 loaded");
let isRunning = false;
let deletionCount = 0;
let failureCount = 0;
let skipNext = false;
// Track problematic items to permanently skip them
const problemItems = new Set();
function getRandomDelay(min = 1100, max = 2100) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function logStatus(text) {
let el = document.getElementById('fb-auto-delete-status');
if (!el) {
el = document.createElement('div');
el.id = 'fb-auto-delete-status';
el.style.position = 'fixed';
el.style.bottom = '50px';
el.style.right = '10px';
el.style.background = '#111';
el.style.color = 'lime';
el.style.padding = '10px';
el.style.borderRadius = '10px';
el.style.fontFamily = 'monospace';
el.style.zIndex = '9999';
document.body.appendChild(el);
}
el.textContent = `π§Ή ${text}`;
}
function createToggleButton() {
const toggle = document.createElement('button');
toggle.textContent = 'βΆοΈ Start Deleter';
toggle.style.position = 'fixed';
toggle.style.bottom = '95px';
toggle.style.right = '10px';
toggle.style.zIndex = '10000';
toggle.style.padding = '8px 12px';
toggle.style.background = '#222';
toggle.style.color = '#fff';
toggle.style.border = '1px solid lime';
toggle.style.borderRadius = '8px';
toggle.style.cursor = 'pointer';
toggle.style.fontFamily = 'monospace';
toggle.addEventListener('click', () => {
isRunning = !isRunning;
toggle.textContent = isRunning ? 'βΈοΈ Pause Deleter' : 'βΆοΈ Start Deleter';
if (isRunning) deleteNext();
logStatus(isRunning ? 'Script running...' : 'Script paused');
});
document.body.appendChild(toggle);
// Add statistics display
const stats = document.createElement('div');
stats.id = 'fb-auto-delete-stats';
stats.style.position = 'fixed';
stats.style.bottom = '140px';
stats.style.right = '10px';
stats.style.background = '#111';
stats.style.color = 'white';
stats.style.padding = '8px';
stats.style.borderRadius = '8px';
stats.style.fontFamily = 'monospace';
stats.style.zIndex = '10000';
stats.style.fontSize = '12px';
stats.style.textAlign = 'right';
document.body.appendChild(stats);
// Update stats every second
setInterval(() => {
if (stats) {
stats.innerHTML = `
Items Deleted: ${deletionCount}
Problem Items: ${problemItems.size}
`;
}
}, 1000);
}
function findMenuButtons() {
return Array.from(document.querySelectorAll('[role="button"]')).filter(btn => {
const label = btn.getAttribute('aria-label') || '';
return (
btn.offsetParent !== null &&
(label.toLowerCase().includes("activity options") ||
label.toLowerCase().includes("action options"))
);
});
}
function getItemSignature(element) {
// Create a unique signature for an item based on its content and position
if (!element) return null;
// Find the parent container of the menu button
let container = element.closest('[data-visualcompletion="ignore-dynamic"]');
if (!container) {
container = element.parentElement;
if (!container) return null;
}
// Extract text content and position info to create a signature
const textContent = container.textContent.slice(0, 100).replace(/\s+/g, ' ').trim();
const position = Array.from(container.parentElement.children).indexOf(container);
return `${textContent}-${position}`;
}
function closeAllErrorPopups() {
// Close "Something went wrong" popups
const popups = Array.from(document.querySelectorAll('[role="alert"]'));
let found = false;
popups.forEach(popup => {
if (popup.innerText.includes("Something went wrong")) {
const closeBtn = popup.querySelector('[aria-label="Close"], [aria-label="Dismiss"]');
if (closeBtn) {
closeBtn.click();
found = true;
console.log("π« Closed error popup");
}
}
});
// Also try to find the bottom notification popups
const bottomPopups = Array.from(document.querySelectorAll('[role="status"]'));
bottomPopups.forEach(popup => {
if (popup.innerText.includes("Something went wrong") || popup.innerText.includes("try again")) {
const closeBtn = popup.querySelector('div[role="button"]');
if (closeBtn) {
closeBtn.click();
found = true;
console.log("π« Closed bottom notification popup");
}
}
});
return found;
}
function autoConfirmPopups() {
const dialogs = Array.from(document.querySelectorAll('[role="dialog"], [role="alertdialog"]'));
dialogs.forEach(dialog => {
const deleteBtn = Array.from(dialog.querySelectorAll('div[role="button"], button'))
.find(btn =>
btn.offsetParent !== null &&
btn.innerText.trim().toLowerCase() === "delete"
);
if (deleteBtn) {
console.log("β
Auto-confirming DELETE dialog");
deleteBtn.click();
logStatus("Auto-confirmed delete popup");
}
});
}
function autoScrollAndRetry() {
console.log("π Scrolling to load more activity...");
logStatus("Scrolling to load more items...");
window.scrollTo({
top: document.body.scrollHeight,
behavior: 'smooth'
});
setTimeout(() => deleteNext(), 2500);
}
function deleteNext() {
if (!isRunning) return;
// Clean up any lingering UI elements
closeAllErrorPopups();
autoConfirmPopups();
const buttons = findMenuButtons();
if (buttons.length === 0) {
logStatus('No deletable buttons found. Trying to scroll...');
autoScrollAndRetry();
return;
}
if (skipNext) {
console.log("βοΈ Skipping next item due to earlier failure.");
skipNext = false;
if (buttons.length > 0) {
const itemToSkip = buttons[0];
const signature = getItemSignature(itemToSkip);
if (signature) {
problemItems.add(signature);
console.log(`π Permanently marking item as problematic: ${signature.substring(0, 30)}...`);
}
buttons.shift(); // remove the first one
}
}
// Filter out any buttons that belong to already identified problem items
const filteredButtons = buttons.filter(btn => {
const signature = getItemSignature(btn);
return !problemItems.has(signature);
});
const btn = filteredButtons[0];
if (!btn) {
// If no valid buttons after filtering, scroll and retry
autoScrollAndRetry();
return;
}
btn.scrollIntoView({ behavior: 'smooth', block: 'center' });
btn.click();
logStatus(`Opened menu for item #${deletionCount + 1}`);
console.log(`π Opened menu for item #${deletionCount + 1}`);
setTimeout(() => {
const menuItems = Array.from(document.querySelectorAll('[role="menuitem"]'));
const deleteOption = menuItems.find(el =>
el.innerText.includes("Move to Recycle bin") ||
el.innerText.includes("Delete") ||
el.innerText.includes("Remove") ||
el.innerText.includes("Unlike") ||
el.innerText.includes("Remove reaction") ||
el.innerText.includes("Remove tag")
);
if (deleteOption) {
deleteOption.click();
logStatus(`Clicked delete on item #${deletionCount + 1}`);
console.log(`ποΈ Attempted delete on item #${deletionCount + 1}`);
setTimeout(() => {
// First close any error popups that might have appeared
const failed = closeAllErrorPopups();
if (failed) {
failureCount++;
console.log("β Deletion failed. Failure count: " + failureCount);
logStatus("Deletion failed, retrying...");
if (failureCount >= 2) {
skipNext = true;
failureCount = 0;
}
setTimeout(deleteNext, getRandomDelay());
} else {
failureCount = 0;
deletionCount++;
logStatus(`β
Deleted item #${deletionCount}`);
setTimeout(deleteNext, getRandomDelay());
}
}, 1800);
} else {
// If no delete option, mark the item as problematic
const signature = getItemSignature(btn);
if (signature) {
problemItems.add(signature);
console.log(`π Marking item as problematic: ${signature.substring(0, 30)}...`);
}
logStatus(`No delete option found. Skipping...`);
console.log("β οΈ No delete option found.");
// Click somewhere else to close the menu
document.body.click();
setTimeout(deleteNext, getRandomDelay());
}
}, 1300);
}
// Initial setup
createToggleButton();
setInterval(autoConfirmPopups, 1000); // scan for popups every second
setInterval(closeAllErrorPopups, 1500); // scan for error popups more frequently
})();