Last active
September 11, 2019 17:49
-
-
Save poteto/0d1cb865f187edd38d9350caed5a6a38 to your computer and use it in GitHub Desktop.
Delete everyone from your Facebook group! Thanks for the dark UX, FB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class FBGroupMemberRemover { | |
constructor() { | |
this.adminText = 'Admin'; | |
this.removeMemberModalHeadingText = 'Remove Member'; | |
this.memberElementSelector = '[data-name="GroupProfileGridItem"]'; | |
this.memberContextMenuSelector = 'button[aria-label="Member Settings"]'; | |
this.removeMemberButtonSelector = 'a[data-testid="leave_group"]' | |
this.removalOptions = { | |
delete_posts: true, | |
delete_comments: true, | |
delete_invites: true, | |
ban_user: true | |
} | |
} | |
*visibleMembers() { | |
for (let el of Array.from( | |
document.querySelectorAll(this.memberElementSelector) | |
).filter(el => !el.textContent.includes(this.adminText))) { | |
yield el; | |
} | |
} | |
openContextMenuForMember(memberEl) { | |
memberEl.querySelector(this.memberContextMenuSelector).click(); | |
} | |
openRemoveMemberDialog() { | |
const el = document.querySelector(this.removeMemberButtonSelector) | |
el.click(); | |
el.remove(); // clean up old element since querySelector picks the first one | |
} | |
setRemovalOptions() { | |
for (let key in this.removalOptions) { | |
const value = this.removalOptions[key]; | |
if (value === false) { return; } | |
this.removeMemberModalEl | |
.querySelector(`input[type="checkbox"][name="${key}"]`).click(); | |
} | |
} | |
confirmRemoveMember() { | |
this.removeMemberModalEl.querySelector('button').click(); | |
} | |
wait(ms) { | |
return new Promise((resolve) => setTimeout(resolve, ms)); | |
} | |
get removeMemberModalEl() { | |
return Array.from(document.querySelectorAll('form')) | |
.find(el => el.textContent.includes(this.removeMemberModalHeadingText)) | |
} | |
async start() { | |
for (let memberEl of this.visibleMembers()) { | |
this.openContextMenuForMember(memberEl); | |
await this.wait(100); | |
this.openRemoveMemberDialog(); | |
await this.wait(1000); | |
// this.setRemovalOptions(); // if you care about deleting posts etc | |
// await this.wait(100); | |
this.confirmRemoveMember(); | |
} | |
} | |
} | |
const fbgmr = new FBGroupMemberRemover(); | |
fbgmr.start(); |
Removed some procedures use the code break system and set the functions as local to suppress the error
This works great all apart from the confirmRemoveMember(); function it fails to recognise @button@ and so none of the dialogues close. You have to confirm them individually
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
VM478:41 Uncaught (in promise) TypeError: Cannot read property 'querySelector' of undefined
at FBGroupMemberRemover.setRemovalOptions (:41:10)
at FBGroupMemberRemover.start (:65:12)
at
How can I solve?