Skip to main content

Bulk remove group members

First version:

(async () => {
    const delay = ms => new Promise(res => setTimeout(res, ms));

    const getNextButton = () => document.querySelector(
        '[role=button][aria-label^="More group actions for "]:not([aria-label*="Richard May"])'
    );

    const scrollAndWait = async () => {
        window.scrollTo(0, document.body.scrollHeight);
        await delay(2000);
    };

    while (true) {
        let btn = getNextButton();

        if (!btn) {
            await scrollAndWait();
            btn = getNextButton();
            if (!btn) {
                console.log('No more members to remove.');
                break;
            }
        }

        const label = btn.getAttribute('aria-label');
        console.log(`Removing: ${label}`);

        btn.click();
        await delay(1000);

        const removeBtn = document.querySelector('[text="Remove member"]') ||
            [...document.querySelectorAll('span')].find(el => el.textContent.trim() === 'Remove member');

        if (!removeBtn) {
            console.error('Could not find "Remove member" option — stopping.');
            break;
        }

        debugger; // <-- remove when comfortable

        removeBtn.click();
        await delay(1000);

        const confirmBtn = document.querySelector('[role=button][aria-label="Confirm" i]:not([aria-disabled="true"])');
        if (!confirmBtn) {
            console.error('Could not find confirm button — stopping.');
            break;
        }

        confirmBtn.click();
        await delay(2000); // wait for DOM to settle after removal
    }
})();

With limited iterations:

(async () => {
    const MAX_REMOVALS = 10;
    let removalCount = 0;

    const delay = ms => new Promise(res => setTimeout(res, ms));

    const getNextButton = () => document.querySelector(
        '[role=button][aria-label^="More group actions for "]:not([aria-label*="Richard May"])'
    );

    const scrollAndWait = async () => {
        window.scrollTo(0, document.body.scrollHeight);
        await delay(2000);
    };

    while (true) {
        let btn = getNextButton();

        if (!btn) {
            await scrollAndWait();
            btn = getNextButton();
            if (!btn) {
                console.log('No more members to remove.');
                break;
            }
        }

        const label = btn.getAttribute('aria-label');
        console.log(`Removing: ${label}`);

        btn.click();
        await delay(2000);

        const removeBtn = document.querySelector('[text="Remove member"]') ||
            [...document.querySelectorAll('span')].find(el => el.textContent.trim() === 'Remove member');

        if (!removeBtn) {
            console.error('Could not find "Remove member" option — stopping.');
            break;
        }

        debugger; // <-- remove when comfortable

        removeBtn.click();
        await delay(2000);

        const confirmBtn = document.querySelector('[role=button][aria-label="Confirm" i]:not([aria-disabled="true"])');
        if (!confirmBtn) {
            console.error('Could not find confirm button — stopping.');
            break;
        }

        confirmBtn.click();
        removalCount++;
        await delay(2000); // wait for DOM to settle after removal

        if (removalCount >= MAX_REMOVALS) {
            console.log(`Reached removal limit of ${MAX_REMOVALS}.`);
            break;
        }
    }
})();