Facebook Activity Auto Deleter (2025)

Automatically deletes Facebook activity log entries, confirms popups, skips failed ones, and handles Facebook quirks. Starts paused. GUI included.

当前为 2025-04-06 提交的版本,查看 最新版本

// ==UserScript==
// @name         Facebook Activity Auto Deleter (2025)
// @namespace    https://gf.qytechs.cn/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);
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址