Skip to content

Commit b6bdd57

Browse files
author
codershiba
authored
feat(GuildBanManager): Add bulkCreate() method (#10182)
1 parent ba6476d commit b6bdd57

File tree

5 files changed

+87
-0
lines changed

5 files changed

+87
-0
lines changed

packages/discord.js/src/errors/ErrorCodes.js

+4
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@
176176
* @property {'SweepFilterReturn'} SweepFilterReturn
177177
178178
* @property {'EntitlementCreateInvalidOwner'} EntitlementCreateInvalidOwner
179+
180+
* @property {'BulkBanUsersOptionEmpty'} BulkBanUsersOptionEmpty
179181
*/
180182

181183
const keys = [
@@ -329,6 +331,8 @@ const keys = [
329331
'GuildForumMessageRequired',
330332

331333
'EntitlementCreateInvalidOwner',
334+
335+
'BulkBanUsersOptionEmpty',
332336
];
333337

334338
// JSDoc for IntelliSense purposes

packages/discord.js/src/errors/Messages.js

+2
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ const Messages = {
169169

170170
[DjsErrorCodes.EntitlementCreateInvalidOwner]:
171171
'You must provide either a guild or a user to create an entitlement, but not both',
172+
173+
[DjsErrorCodes.BulkBanUsersOptionEmpty]: 'Option "users" array or collection is empty',
172174
};
173175

174176
module.exports = Messages;

packages/discord.js/src/managers/GuildBanManager.js

+45
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,51 @@ class GuildBanManager extends CachedManager {
199199
await this.client.rest.delete(Routes.guildBan(this.guild.id, id), { reason });
200200
return this.client.users.resolve(user);
201201
}
202+
203+
/**
204+
* Options used for bulk banning users from a guild.
205+
* @typedef {Object} BulkBanOptions
206+
* @property {number} [deleteMessageSeconds] Number of seconds of messages to delete,
207+
* must be between 0 and 604800 (7 days), inclusive
208+
* @property {string} [reason] The reason for the bans
209+
*/
210+
211+
/**
212+
* Result of bulk banning users from a guild.
213+
* @typedef {Object} BulkBanResult
214+
* @property {Snowflake[]} bannedUsers IDs of the banned users
215+
* @property {Snowflake[]} failedUsers IDs of the users that could not be banned or were already banned
216+
*/
217+
218+
/**
219+
* Bulk ban users from a guild, and optionally delete previous messages sent by them.
220+
* @param {Collection<Snowflake, UserResolvable>|UserResolvable[]} users The users to ban
221+
* @param {BulkBanOptions} [options] The options for bulk banning users
222+
* @returns {Promise<BulkBanResult>} Returns an object with `bannedUsers` key containing the IDs of the banned users
223+
* and the key `failedUsers` with the IDs that could not be banned or were already banned.
224+
* @example
225+
* // Bulk ban users by ids (or with user/guild member objects) and delete all their messages from the past 7 days
226+
* guild.bans.bulkCreate(['84484653687267328'], { deleteMessageSeconds: 7 * 24 * 60 * 60 })
227+
* .then(result => {
228+
* console.log(`Banned ${result.bannedUsers.length} users, failed to ban ${result.failedUsers.length} users.`)
229+
* })
230+
* .catch(console.error);
231+
*/
232+
async bulkCreate(users, options = {}) {
233+
if (!users || !(Array.isArray(users) || users instanceof Collection)) {
234+
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'users', 'Array or Collection of UserResolvable', true);
235+
}
236+
if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
237+
238+
const userIds = users.map(user => this.client.users.resolveId(user));
239+
if (userIds.length === 0) throw new DiscordjsError(ErrorCodes.BulkBanUsersOptionEmpty);
240+
241+
const result = await this.client.rest.post(Routes.guildBulkBan(this.guild.id), {
242+
body: { delete_message_seconds: options.deleteMessageSeconds, user_ids: userIds },
243+
reason: options.reason,
244+
});
245+
return { bannedUsers: result.banned_users, failedUsers: result.failed_users };
246+
}
202247
}
203248

204249
module.exports = GuildBanManager;

packages/discord.js/src/managers/GuildMemberManager.js

+19
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,25 @@ class GuildMemberManager extends CachedManager {
500500
return this.guild.bans.remove(user, reason);
501501
}
502502

503+
/**
504+
* Bulk ban users from a guild, and optionally delete previous messages sent by them.
505+
* @param {Collection<Snowflake, UserResolvable>|UserResolvable[]} users The users to ban
506+
* @param {BulkBanOptions} [options] The options for bulk banning users
507+
* @returns {Promise<BulkBanResult>} Returns an object with `bannedUsers` key containing the IDs of the banned users
508+
* and the key `failedUsers` with the IDs that could not be banned or were already banned.
509+
* Internally calls the GuildBanManager#bulkCreate method.
510+
* @example
511+
* // Bulk ban users by ids (or with user/guild member objects) and delete all their messages from the past 7 days
512+
* guild.members.bulkBan(['84484653687267328'], { deleteMessageSeconds: 7 * 24 * 60 * 60 })
513+
* .then(result => {
514+
* console.log(`Banned ${result.bannedUsers.length} users, failed to ban ${result.failedUsers.length} users.`)
515+
* })
516+
* .catch(console.error);
517+
*/
518+
bulkBan(users, options = {}) {
519+
return this.guild.bans.bulkCreate(users, options);
520+
}
521+
503522
/**
504523
* Options used for adding or removing a role from a member.
505524
* @typedef {Object} AddOrRemoveGuildMemberRoleOptions

packages/discord.js/typings/index.d.ts

+17
Original file line numberDiff line numberDiff line change
@@ -3926,6 +3926,8 @@ export enum DiscordjsErrorCodes {
39263926
GuildForumMessageRequired = 'GuildForumMessageRequired',
39273927

39283928
EntitlementCreateInvalidOwner = 'EntitlementCreateInvalidOwner',
3929+
3930+
BulkBanUsersOptionEmpty = 'BulkBanUsersOptionEmpty',
39293931
}
39303932

39313933
export class DiscordjsError extends Error {
@@ -4249,6 +4251,10 @@ export class GuildMemberManager extends CachedManager<Snowflake, GuildMember, Gu
42494251
): Promise<GuildMember | null>;
42504252
public add(user: UserResolvable, options: AddGuildMemberOptions): Promise<GuildMember>;
42514253
public ban(user: UserResolvable, options?: BanOptions): Promise<GuildMember | User | Snowflake>;
4254+
public bulkBan(
4255+
users: ReadonlyCollection<Snowflake, UserResolvable> | readonly UserResolvable[],
4256+
options?: BulkBanOptions,
4257+
): Promise<BulkBanResult>;
42524258
public edit(user: UserResolvable, options: GuildMemberEditOptions): Promise<GuildMember>;
42534259
public fetch(
42544260
options: UserResolvable | FetchMemberOptions | (FetchMembersOptions & { user: UserResolvable }),
@@ -4272,6 +4278,10 @@ export class GuildBanManager extends CachedManager<Snowflake, GuildBan, GuildBan
42724278
public fetch(options: UserResolvable | FetchBanOptions): Promise<GuildBan>;
42734279
public fetch(options?: FetchBansOptions): Promise<Collection<Snowflake, GuildBan>>;
42744280
public remove(user: UserResolvable, reason?: string): Promise<User | null>;
4281+
public bulkCreate(
4282+
users: ReadonlyCollection<Snowflake, UserResolvable> | readonly UserResolvable[],
4283+
options?: BulkBanOptions,
4284+
): Promise<BulkBanResult>;
42754285
}
42764286

42774287
export class GuildInviteManager extends DataManager<string, Invite, InviteResolvable> {
@@ -4959,6 +4969,13 @@ export interface BanOptions {
49594969
reason?: string;
49604970
}
49614971

4972+
export interface BulkBanOptions extends Omit<BanOptions, 'deleteMessageDays'> {}
4973+
4974+
export interface BulkBanResult {
4975+
bannedUsers: readonly Snowflake[];
4976+
failedUsers: readonly Snowflake[];
4977+
}
4978+
49624979
export type Base64Resolvable = Buffer | Base64String;
49634980

49644981
export type Base64String = string;

0 commit comments

Comments
 (0)