Skip to content

Commit 808d250

Browse files
committed
Make members bulk delete easier to use
1 parent 124d502 commit 808d250

File tree

1 file changed

+32
-20
lines changed

1 file changed

+32
-20
lines changed

members-bulk-delete.js

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,20 @@
33
*
44
* Usage:
55
*
6-
* node members-bulk-delete.js https://blah.ghost.io ADMIN_API_KEY [doDelete]
6+
* node members-bulk-delete.js https://blah.ghost.io ADMIN_API_KEY [true]
77
*
88
* If you run this script with just a URL and key, it will do a dry run
99
* If you run this script with an extra argument (e.g. true) the deletions will be executed
1010
*/
1111

1212
if (process.argv.length < 4) {
13-
console.error('Missing an argument');
13+
console.error('Missing an argument. Requires API_URL API_KEY [confirm]');
1414
process.exit(1);
1515
}
1616

1717
const url = process.argv[2];
1818
const key = process.argv[3];
19-
const doDelete = process.argv[4];
19+
const doDelete = process.argv[4] === 'true';
2020

2121
if (!doDelete) {
2222
console.log('Dry run...');
@@ -33,41 +33,53 @@ const api = new GhostAdminAPI({
3333
});
3434

3535
(async function main() {
36-
try {
37-
const allMembers = await api.members.browse({limit: 'all'});
36+
if (doDelete) {
37+
console.log('REAL Run');
38+
} else {
39+
console.log('Dry Run - nothing will be deleted');
40+
}
3841

39-
console.log(allMembers);
42+
console.log('API URL', url);
43+
console.log('API KEY', key);
44+
// Give the user time to read...
45+
await Promise.delay(1000);
4046

47+
try {
48+
const allMembers = await api.members.browse({limit: 'all'});
49+
const keep = [];
4150
const freeMembers = allMembers.filter((member) => {
4251
// Comped members should have a subscription, but just in case
4352
if (!member.comped && member.stripe.subscriptions.length === 0) {
44-
console.log('Will delete', member.email);
4553
return true;
4654
}
4755

48-
console.log('Will keep', member.email);
56+
keep.push(member.email);
4957

5058
return false;
5159
});
5260

53-
console.log(freeMembers.length, 'Members will be deleted');
61+
console.log(freeMembers.length, 'Members will be deleted out of', allMembers.length, 'total members. This will leave', keep.length, 'members');
5462

55-
const result = await Promise.mapSeries(freeMembers, async (member) => {
56-
console.log('Deleting', member.email);
57-
let result = {};
63+
console.log('Keeping:');
64+
console.log(keep);
5865

59-
// Call the API
60-
if (doDelete) {
61-
result = await api.members.delete({id: member.id});
62-
}
66+
if (doDelete) {
67+
const result = await Promise.mapSeries(freeMembers, async (member) => {
68+
console.log('Deleting', member.email);
6369

64-
// Add a delay but return the original result
65-
return Promise.delay(50).return(result);
66-
});
70+
// Call the API
71+
const result = await api.members.delete({id: member.id});
72+
// Add a delay but return the original result
73+
return Promise.delay(50).return(result);
74+
});
6775

68-
console.log('Deleted', result.length, 'members');
76+
console.log('Deleted', result.length, 'members');
77+
}
6978
} catch (err) {
7079
console.error('There was an error', require('util').inspect(err, false, null));
80+
if (err.type === 'NotFoundError') {
81+
console.log('Resource not found - is members actually enabled?');
82+
}
7183
process.exit(1);
7284
}
7385
}());

0 commit comments

Comments
 (0)