-
-
Save sezgi/b92dfd70a8c959f760151f5a071c0400 to your computer and use it in GitHub Desktop.
// removes your box from the page so you don't get removed from the group | |
$$('[data-name=GroupProfileGridItem]')[0].remove(); | |
// member action dropdowns | |
const actions = $$('.adminActions'); | |
// open all dropdowns so they're added to the DOM | |
for (var i = 0; i < actions.length; i++) { | |
$$('.adminActions a')[i] && $$('.adminActions a')[i].click(); | |
} | |
// leave group buttons | |
const buttons = $$('[data-testid=leave_group]'); | |
var i = 0; | |
function removeAll() { | |
setTimeout(function () { | |
// click each button | |
buttons[i].click(); | |
// click confirm button with a half second delay | |
setTimeout(function() { | |
document.getElementsByClassName('layerConfirm')[0].click() | |
}, 500); | |
i++; | |
if (i < buttons.length) { | |
// each time this is called, there will be a 3 second delay | |
removeAll(); | |
} | |
}, 3000); | |
} | |
removeAll(); |
Just tested this on latest Chrome and on Facebook (They have a new group design) and can confirm it does not work.
Chrome gives some message about Service Worker Termination due to Time Out.
It seems to remove me ok, but then just fails with undefined in the console.
It does not work for me (Thursday, 15rd June 2017)
Any suggestion?
Thanks.
In $$('.adminActions a')[i] && $$('.adminActions a')[i].click();
line 9
you have to replace a
by button
So it becomes $$('.adminActions button')[i] && $$('.adminActions button')[i].click();
Thanks for the code !
The button change isn't a sufficient update, facebook seems to have changed the layout a lot more.
Worked for me..
I wanted to delete an old group I created.. This saved me time.
PS: Also removed me from the group.
Thanks for writing this
The structure of the all members section for groups has changed since the above code was written. The code no longer works. I've rewritten the code for the new html hierarchy. I've also modified it to use promises and intervals within the promise to eliminate some of the timeout problems. This code can specify a lower and upper range as well as a max delete queue. Obviously, there are conditions when the script will stop if you aren't deleting all the members at a time, but if multiple people are running this program at the same time on the same group with greater than 5,000 members, the alpha ranges come in handy to have them deleting members across different ranges. It's simplistic, using the first letter of the first name, but works in our use case.
Note: It's really important for the admins to use the excludedFbIds list. If they are first in the delete queue, the deletion stops because they are removed from the group. See instructions below.
`
var deleteAllGroupMembers = (function () {
var deleteAllGroupMembers = {},
// the facebook ids of the users that will not be removed.
// IMPORTANT: add your own facebook id here so that the script will not remove you!
// You can find the id using this: http://findmyfbid.com/
excludedFbIds = ['123456789','987654321'], // make sure each id is a string!
usersToDeleteQueue = [],
scriptEnabled = false, lowAlpha, highAlpha, maxDeletes;
deleteAllGroupMembers.start = function(pLowAlpha,pHighAlpha,maxDeletes) {
lowAlpha = (pLowAlpha || 'a').toLowerCase();
highAlpha = (pHighAlpha || 'z').toLowerCase();
maxDeletes = maxDeletes || 100;
scriptEnabled = true;
deleteAll();
};
deleteAllGroupMembers.stop = function() {
scriptEnabled = false;
};
function deleteAll() {
if (scriptEnabled) {
queueMembersToDelete();
if (usersToDeleteQueue.length > 0) {
removeNext();
}
//processQueue();
}
}
function getFieldParm(field,parm) {
var ipos, epos;
if (field.indexOf(parm + '=') > 0) {
ipos = field.indexOf(parm + '=') + parm.length + 1;
epos = field.indexOf('&',ipos) > 0 ? field.indexOf('&',ipos) : field.length;
return field.substring(ipos,epos);
}
return '';
}
function is_null_empty(value) {
return value === null || value === '';
}
function getElementsByAttribute(el,attrName, attrValue) {
return el.querySelectorAll('['+attrName+'=' + '"'+attrValue+'"]');
}
function queueMembersToDelete() {
var count,idx, profileDiv = document.getElementById('groupsMemberSection_all_members'), profiles = getElementsByAttribute(profileDiv,'data-name','GroupProfileGridItem');
count = profiles.length;
// For each profile, get the id, name and button to click to Leave Group
for (idx = 0;idx < count;idx++) {
memberDiv = profiles[idx];
var profileImg = memberDiv.getElementsByTagName('img'), fbMemberName, fbMemberIdv, gearWheelIconDiv, ary, firstLetter;
if (profileImg.length > 0) {
fbMemberName = profileImg[0].getAttribute('aria-label');
firstLetter = fbMemberName[0].toLowerCase();
if (firstLetter >= lowAlpha && firstLetter <= highAlpha) {
fbMemberId = getFieldParm(profileImg[0].parentNode.getAttribute('ajaxify'),'member_id');
if (excludedFbIds.indexOf(fbMemberId) != -1) {
console.log("SKIPPING "+fbMemberName+' ('+fbMemberId+')');
} else {
ary = getElementsByAttribute(memberDiv,'aria-label','Member Settings');
if (ary.length > 0) {
usersToDeleteQueue.push({'memberId': fbMemberId,'memberName' : fbMemberName, 'fbSettingsBtn': ary[0]});
if (usersToDeleteQueue.length >= maxDeletes) {
break;
}
}
}
}
}
};
}
function removeNext() {
if (!scriptEnabled) {
return;
}
if (usersToDeleteQueue.length > 0) {
var nextElement = usersToDeleteQueue.shift();
removeMember(nextElement);
} else {
deleteAll();
}
}
function removeMember(memberToRemove) {
var testForMenuItem = function(resolve, reject) {
var interval = setInterval(function(){
var menuId = memberToRemove.fbSettingsBtn.getAttribute('aria-controls');
if (!is_null_empty(menuId)) {
clearInterval(interval);
resolve(menuId);
}
},150);
}, waitForConfirm = function(memberId, memberName,startCount) {
return function(resolve, reject) {
var state = 0, interval = setInterval(function(){
if (state === 0) {
var btn = document.getElementsByClassName('layerConfirm uiOverlayButton selected');
if (btn.length > 0) {
btn[0].click();
state = 1;
}
} else {
if (document.forms.length === startCount) {
resolve({id: memberId, name: memberName});
}
}
},150);
};
}, promise, p2;
memberToRemove.fbSettingsBtn.click();
promise = new Promise(testForMenuItem);
promise.then(function(value){
var removeItem;
removeItem = getElementsByAttribute(document.getElementById(value), "data-testid", 'leave_group');
if (removeItem.length > 0) {
removeItem[0].click();
p2 = new Promise(waitForConfirm(memberToRemove.memberId, memberToRemove.memberName, document.forms.length));
p2.then(function(obj){
console.log('Member: ' + obj.name + ' (' + obj.id + ')');
removeNext();
});
} else {
console.log('link not found.');
}
});
}
return deleteAllGroupMembers;
})();
deleteAllGroupMembers.start('a','m',100);`
The structure of the all members section for groups has changed since the above code was written. The code no longer works. I've rewritten the code for the new html hierarchy. I've also modified it to use promises and intervals within the promise to eliminate some of the timeout problems. This code can specify a lower and upper range as well as a max delete queue. Obviously, there are conditions when the script will stop if you aren't deleting all the members at a time, but if multiple people are running this program at the same time on the same group with greater than 5,000 members, the alpha ranges come in handy to have them deleting members across different ranges. It's simplistic, using the first letter of the first name, but works in our use case.
Note: It's really important for the admins to use the excludedFbIds list. If they are first in the delete queue, the deletion stops because they are removed from the group. See instructions below.
`
var deleteAllGroupMembers = (function () {
var deleteAllGroupMembers = {},
// the facebook ids of the users that will not be removed.
// IMPORTANT: add your own facebook id here so that the script will not remove you!
// You can find the id using this: http://findmyfbid.com/
excludedFbIds = ['123456789','987654321'], // make sure each id is a string!
usersToDeleteQueue = [],
scriptEnabled = false, lowAlpha, highAlpha, maxDeletes;deleteAllGroupMembers.start = function(pLowAlpha,pHighAlpha,maxDeletes) { lowAlpha = (pLowAlpha || 'a').toLowerCase(); highAlpha = (pHighAlpha || 'z').toLowerCase(); maxDeletes = maxDeletes || 100; scriptEnabled = true; deleteAll(); }; deleteAllGroupMembers.stop = function() { scriptEnabled = false; }; function deleteAll() { if (scriptEnabled) { queueMembersToDelete(); if (usersToDeleteQueue.length > 0) { removeNext(); } //processQueue(); } } function getFieldParm(field,parm) { var ipos, epos; if (field.indexOf(parm + '=') > 0) { ipos = field.indexOf(parm + '=') + parm.length + 1; epos = field.indexOf('&',ipos) > 0 ? field.indexOf('&',ipos) : field.length; return field.substring(ipos,epos); } return ''; } function is_null_empty(value) { return value === null || value === ''; } function getElementsByAttribute(el,attrName, attrValue) { return el.querySelectorAll('['+attrName+'=' + '"'+attrValue+'"]'); } function queueMembersToDelete() { var count,idx, profileDiv = document.getElementById('groupsMemberSection_all_members'), profiles = getElementsByAttribute(profileDiv,'data-name','GroupProfileGridItem'); count = profiles.length; // For each profile, get the id, name and button to click to Leave Group for (idx = 0;idx < count;idx++) { memberDiv = profiles[idx]; var profileImg = memberDiv.getElementsByTagName('img'), fbMemberName, fbMemberIdv, gearWheelIconDiv, ary, firstLetter; if (profileImg.length > 0) { fbMemberName = profileImg[0].getAttribute('aria-label'); firstLetter = fbMemberName[0].toLowerCase(); if (firstLetter >= lowAlpha && firstLetter <= highAlpha) { fbMemberId = getFieldParm(profileImg[0].parentNode.getAttribute('ajaxify'),'member_id'); if (excludedFbIds.indexOf(fbMemberId) != -1) { console.log("SKIPPING "+fbMemberName+' ('+fbMemberId+')'); } else { ary = getElementsByAttribute(memberDiv,'aria-label','Member Settings'); if (ary.length > 0) { usersToDeleteQueue.push({'memberId': fbMemberId,'memberName' : fbMemberName, 'fbSettingsBtn': ary[0]}); if (usersToDeleteQueue.length >= maxDeletes) { break; } } } } } }; } function removeNext() { if (!scriptEnabled) { return; } if (usersToDeleteQueue.length > 0) { var nextElement = usersToDeleteQueue.shift(); removeMember(nextElement); } else { deleteAll(); } } function removeMember(memberToRemove) { var testForMenuItem = function(resolve, reject) { var interval = setInterval(function(){ var menuId = memberToRemove.fbSettingsBtn.getAttribute('aria-controls'); if (!is_null_empty(menuId)) { clearInterval(interval); resolve(menuId); } },150); }, waitForConfirm = function(memberId, memberName,startCount) { return function(resolve, reject) { var state = 0, interval = setInterval(function(){ if (state === 0) { var btn = document.getElementsByClassName('layerConfirm uiOverlayButton selected'); if (btn.length > 0) { btn[0].click(); state = 1; } } else { if (document.forms.length === startCount) { resolve({id: memberId, name: memberName}); } } },150); }; }, promise, p2; memberToRemove.fbSettingsBtn.click(); promise = new Promise(testForMenuItem); promise.then(function(value){ var removeItem; removeItem = getElementsByAttribute(document.getElementById(value), "data-testid", 'leave_group'); if (removeItem.length > 0) { removeItem[0].click(); p2 = new Promise(waitForConfirm(memberToRemove.memberId, memberToRemove.memberName, document.forms.length)); p2.then(function(obj){ console.log('Member: ' + obj.name + ' (' + obj.id + ')'); removeNext(); }); } else { console.log('link not found.'); } }); } return deleteAllGroupMembers;
})();
deleteAllGroupMembers.start('a','m',100);`
Can you copy - paste what i need to do? This code doesn't work
The code does work. It was used to delete a group of about 13,000 members in about 8 hours. Multiple people ran it.
- Make sure you edit the excludedFbIds and enter your own Facebook ID so it doesn’t delete you first. You can find it here: http://findmyfbid.com/.
- Edit the last line of the above.There are 2 ways to execute the program: the one above deletes group members whose first name begins with a thru m. You can change the range to something else. The other way is to remove everything between the parenthesis and the program will delete everything. i.e.: deleteAllGroupMembers.start()
- In Firefox, You need to go to the group you want to delete. You must be an admin.
- Click on Members.
- Open the Tools | Web Developer | Web Console.
- Copy/Paste the code in the JavaScript console. It could fail after a while. Reload it.
The code does work. It was used to delete a group of about 13,000 members in about 8 hours. Multiple people ran it.
- Make sure you edit the excludedFbIds and enter your own Facebook ID so it doesn’t delete you first. You can find it here: http://findmyfbid.com/.
- Edit the last line of the above.There are 2 ways to execute the program: the one above deletes group members whose first name begins with a thru m. You can change the range to something else. The other way is to remove everything between the parenthesis and the program will delete everything. i.e.: deleteAllGroupMembers.start()
- In Firefox, You need to go to the group you want to delete. You must be an admin.
- Click on Members.
- Open the Tools | Web Developer | Web Console.
- Copy/Paste the code in the JavaScript console. It could fail after a while. Reload it.
Hi @wcwilson1950, your script worked but then it failed. I've reloaded it but keep appear this error:
Uncaught TypeError: Cannot read property 'indexOf' of null
at getFieldParm (<anonymous>:33:12)
at queueMembersToDelete (<anonymous>:57:18)
at deleteAll (<anonymous>:24:3)
at Object.deleteAllGroupMembers.start (<anonymous>:16:2)
at <anonymous>:132:23
I would like to know if I can filter and remove certain members. for example based on their location or added by non-admin members or not active in group since they joined...