Greasy Fork is available in English.
Automatically deletes Facebook activity log entries, confirms popups, skips failed ones, and handles Facebook quirks. Starts paused. GUI included.
当前为
// ==UserScript==
// @name Facebook Activity Auto Deleter (2025)
// @namespace http://greasyfork.icu/en/users/1454546-shawnfrost13
// @version 4.07
// @description Automatically deletes Facebook activity log entries, confirms popups, skips failed ones, and handles Facebook quirks. Starts paused. GUI included.
// @author shawnfrost13
// @license MIT
// @match https://www.facebook.com/*/allactivity*
// @grant none
// @run-at document-end
// @note Stable base: v4.02 — This version adds better skip handling and error popup detection/fixing
// ==/UserScript==
(function () {
'use strict';
let paused = true;
let deletionCount = 0;
let failureMap = new WeakMap();
let skipNext = false;
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 = '60px';
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() {
let toggle = document.createElement('button');
toggle.id = 'fb-toggle-button';
toggle.textContent = '▶️ Start Deleter';
toggle.style.position = 'fixed';
toggle.style.bottom = '100px';
toggle.style.right = '10px';
toggle.style.padding = '8px 12px';
toggle.style.borderRadius = '8px';
toggle.style.background = '#333';
toggle.style.color = '#fff';
toggle.style.zIndex = '9999';
toggle.style.border = '1px solid lime';
toggle.style.fontFamily = 'monospace';
toggle.onclick = function () {
paused = !paused;
toggle.textContent = paused ? '▶️ Start Deleter' : '⏸️ Pause Deleter';
if (!paused) {
logStatus("Resumed");
deleteNext();
} else {
logStatus("Paused");
}
};
document.body.appendChild(toggle);
}
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 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) {
deleteBtn.click();
logStatus("Auto-confirmed delete popup");
}
});
// Close "Something went wrong" popups
const failPopup = Array.from(document.querySelectorAll('[role="alertdialog"]'))
.find(el => el.innerText.includes("Something went wrong"));
if (failPopup) {
const closeBtn = failPopup.querySelector('[aria-label="Close"]');
if (closeBtn) closeBtn.click();
}
}
function autoScrollAndRetry() {
window.scrollTo({
top: document.body.scrollHeight,
behavior: 'smooth'
});
setTimeout(() => {
deleteNext();
}, 2500);
}
function deleteNext() {
if (paused) return;
autoConfirmPopups();
const buttons = findMenuButtons();
if (buttons.length === 0) {
logStatus("No deletable buttons found. Scrolling...");
return autoScrollAndRetry();
}
if (skipNext) {
buttons.shift();
skipNext = false;
}
const btn = buttons[0];
if (!btn) {
logStatus("No valid button. Skipping...");
return setTimeout(deleteNext, getRandomDelay());
}
btn.scrollIntoView({ behavior: 'smooth', block: 'center' });
btn.click();
logStatus(`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) {
logStatus("⚠️ No delete option found. Skipping...");
return setTimeout(deleteNext, getRandomDelay());
}
deleteOption.click();
deletionCount++;
logStatus(`🗑️ Attempted to delete #${deletionCount}`);
const currentEntry = btn.closest('[role="article"], [data-pagelet]');
let failureCount = failureMap.get(currentEntry) || 0;
setTimeout(() => {
const stillThere = currentEntry && document.body.contains(currentEntry);
const errorPopup = !!Array.from(document.querySelectorAll('[role="alertdialog"]'))
.find(el => el.innerText.includes("Something went wrong"));
if (stillThere || errorPopup) {
failureCount++;
failureMap.set(currentEntry, failureCount);
if (errorPopup) {
const closeBtn = document.querySelector('[aria-label="Close"]');
if (closeBtn) closeBtn.click();
}
if (failureCount >= 2) {
skipNext = true;
logStatus("❌ Failed twice. Skipping next entry.");
} else {
logStatus("⚠️ Failed to delete. Retrying...");
}
} else {
logStatus(`✅ Deleted item #${deletionCount}`);
failureMap.delete(currentEntry);
}
setTimeout(deleteNext, getRandomDelay());
}, 2000);
}, 1500);
}
setTimeout(() => {
createToggleButton();
logStatus("Paused. Click ▶️ to start.");
setInterval(autoConfirmPopups, 1000);
}, 3000);
})();