Facebook Activity Auto Deleter (2025) - Improved

Automatically deletes Facebook activity log entries, confirms popups, and scrolls. Includes GUI toggle. Starts paused. Permanently skips problematic items.

目前為 2025-04-06 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Facebook Activity Auto Deleter (2025) - Improved
// @namespace    https://gf.qytechs.cn/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
// ==/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 = `
                <div>Items Deleted: <span style="color:lime">${deletionCount}</span></div>
                <div>Problem Items: <span style="color:orange">${problemItems.size}</span></div>
                `;
            }
        }, 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
})();

QingJ © 2025

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