diff --git a/src/managers/GuildMemberManager.js b/src/managers/GuildMemberManager.js index 0d98d3360..8072374be 100644 --- a/src/managers/GuildMemberManager.js +++ b/src/managers/GuildMemberManager.js @@ -142,6 +142,7 @@ class GuildMemberManager extends BaseManager { * @param {number} [options.days=7] Number of days of inactivity required to kick * @param {boolean} [options.dry=false] Get number of users that will be kicked, without actually kicking them * @param {boolean} [options.count=true] Whether or not to return the number of users that have been kicked. + * @param {RoleResolvable[]} [options.roles=[]] Array of roles to bypass the "...and no roles" constraint when pruning * @param {string} [options.reason] Reason for this prune * @returns {Promise} The number of members that were/will be kicked * @example @@ -154,19 +155,40 @@ class GuildMemberManager extends BaseManager { * guild.members.prune({ days: 1, reason: 'too many people!' }) * .then(pruned => console.log(`I just pruned ${pruned} people!`)) * .catch(console.error); + * @example + * // Include members with a specified role + * guild.members.prune({ days: 7, roles: ['657259391652855808'] }) + * .then(pruned => console.log(`I just pruned ${pruned} people!`)) + * .catch(console.error); */ - prune({ days = 7, dry = false, count = true, reason } = {}) { + prune({ days = 7, dry = false, count = true, roles = [], reason } = {}) { if (typeof days !== 'number') throw new TypeError('PRUNE_DAYS_TYPE'); - return this.client.api - .guilds(this.guild.id) - .prune[dry ? 'get' : 'post']({ - query: { - days, - compute_prune_count: count, - }, - reason, - }) - .then(data => data.pruned); + + const query = new URLSearchParams(); + query.set('days', days); + query.set('compute_prune_count', count); + + for (const role of roles) { + const resolvedRole = this.guild.roles.resolveID(role); + if (!resolvedRole) { + return Promise.reject(new TypeError('INVALID_TYPE', 'roles', 'Array of Roles or Snowflakes', true)); + } + query.append('include_roles', role); + } + + const endpoint = this.client.api.guilds(this.guild.id).prune; + + if (dry) { + return endpoint.get({ query, reason }).then(data => data.pruned); + } + + const body = [...query.entries()].reduce((acc, [k, v]) => { + if (k === 'include_roles') v = (acc[k] || []).concat(v); + acc[k] = v; + return acc; + }, {}); + + return endpoint.post({ data: body, reason }).then(data => data.pruned); } /** diff --git a/typings/index.d.ts b/typings/index.d.ts index f3e347b42..1cfce28ae 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -2606,6 +2606,7 @@ declare module 'discord.js' { days?: number; dry?: boolean; reason?: string; + roles?: RoleResolvable[]; } interface GuildWidgetData {