Skip to content

Commit

Permalink
feat(GuildBanManager): Add bulkCreate() method (#10182)
Browse files Browse the repository at this point in the history
  • Loading branch information
codershiba authored Apr 2, 2024
1 parent ba6476d commit b6bdd57
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 0 deletions.
4 changes: 4 additions & 0 deletions packages/discord.js/src/errors/ErrorCodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@
* @property {'SweepFilterReturn'} SweepFilterReturn
* @property {'EntitlementCreateInvalidOwner'} EntitlementCreateInvalidOwner
* @property {'BulkBanUsersOptionEmpty'} BulkBanUsersOptionEmpty
*/

const keys = [
Expand Down Expand Up @@ -329,6 +331,8 @@ const keys = [
'GuildForumMessageRequired',

'EntitlementCreateInvalidOwner',

'BulkBanUsersOptionEmpty',
];

// JSDoc for IntelliSense purposes
Expand Down
2 changes: 2 additions & 0 deletions packages/discord.js/src/errors/Messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ const Messages = {

[DjsErrorCodes.EntitlementCreateInvalidOwner]:
'You must provide either a guild or a user to create an entitlement, but not both',

[DjsErrorCodes.BulkBanUsersOptionEmpty]: 'Option "users" array or collection is empty',
};

module.exports = Messages;
45 changes: 45 additions & 0 deletions packages/discord.js/src/managers/GuildBanManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,51 @@ class GuildBanManager extends CachedManager {
await this.client.rest.delete(Routes.guildBan(this.guild.id, id), { reason });
return this.client.users.resolve(user);
}

/**
* Options used for bulk banning users from a guild.
* @typedef {Object} BulkBanOptions
* @property {number} [deleteMessageSeconds] Number of seconds of messages to delete,
* must be between 0 and 604800 (7 days), inclusive
* @property {string} [reason] The reason for the bans
*/

/**
* Result of bulk banning users from a guild.
* @typedef {Object} BulkBanResult
* @property {Snowflake[]} bannedUsers IDs of the banned users
* @property {Snowflake[]} failedUsers IDs of the users that could not be banned or were already banned
*/

/**
* Bulk ban users from a guild, and optionally delete previous messages sent by them.
* @param {Collection<Snowflake, UserResolvable>|UserResolvable[]} users The users to ban
* @param {BulkBanOptions} [options] The options for bulk banning users
* @returns {Promise<BulkBanResult>} Returns an object with `bannedUsers` key containing the IDs of the banned users
* and the key `failedUsers` with the IDs that could not be banned or were already banned.
* @example
* // Bulk ban users by ids (or with user/guild member objects) and delete all their messages from the past 7 days
* guild.bans.bulkCreate(['84484653687267328'], { deleteMessageSeconds: 7 * 24 * 60 * 60 })
* .then(result => {
* console.log(`Banned ${result.bannedUsers.length} users, failed to ban ${result.failedUsers.length} users.`)
* })
* .catch(console.error);
*/
async bulkCreate(users, options = {}) {
if (!users || !(Array.isArray(users) || users instanceof Collection)) {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'users', 'Array or Collection of UserResolvable', true);
}
if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);

const userIds = users.map(user => this.client.users.resolveId(user));
if (userIds.length === 0) throw new DiscordjsError(ErrorCodes.BulkBanUsersOptionEmpty);

const result = await this.client.rest.post(Routes.guildBulkBan(this.guild.id), {
body: { delete_message_seconds: options.deleteMessageSeconds, user_ids: userIds },
reason: options.reason,
});
return { bannedUsers: result.banned_users, failedUsers: result.failed_users };
}
}

module.exports = GuildBanManager;
19 changes: 19 additions & 0 deletions packages/discord.js/src/managers/GuildMemberManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,25 @@ class GuildMemberManager extends CachedManager {
return this.guild.bans.remove(user, reason);
}

/**
* Bulk ban users from a guild, and optionally delete previous messages sent by them.
* @param {Collection<Snowflake, UserResolvable>|UserResolvable[]} users The users to ban
* @param {BulkBanOptions} [options] The options for bulk banning users
* @returns {Promise<BulkBanResult>} Returns an object with `bannedUsers` key containing the IDs of the banned users
* and the key `failedUsers` with the IDs that could not be banned or were already banned.
* Internally calls the GuildBanManager#bulkCreate method.
* @example
* // Bulk ban users by ids (or with user/guild member objects) and delete all their messages from the past 7 days
* guild.members.bulkBan(['84484653687267328'], { deleteMessageSeconds: 7 * 24 * 60 * 60 })
* .then(result => {
* console.log(`Banned ${result.bannedUsers.length} users, failed to ban ${result.failedUsers.length} users.`)
* })
* .catch(console.error);
*/
bulkBan(users, options = {}) {
return this.guild.bans.bulkCreate(users, options);
}

/**
* Options used for adding or removing a role from a member.
* @typedef {Object} AddOrRemoveGuildMemberRoleOptions
Expand Down
17 changes: 17 additions & 0 deletions packages/discord.js/typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3926,6 +3926,8 @@ export enum DiscordjsErrorCodes {
GuildForumMessageRequired = 'GuildForumMessageRequired',

EntitlementCreateInvalidOwner = 'EntitlementCreateInvalidOwner',

BulkBanUsersOptionEmpty = 'BulkBanUsersOptionEmpty',
}

export class DiscordjsError extends Error {
Expand Down Expand Up @@ -4249,6 +4251,10 @@ export class GuildMemberManager extends CachedManager<Snowflake, GuildMember, Gu
): Promise<GuildMember | null>;
public add(user: UserResolvable, options: AddGuildMemberOptions): Promise<GuildMember>;
public ban(user: UserResolvable, options?: BanOptions): Promise<GuildMember | User | Snowflake>;
public bulkBan(
users: ReadonlyCollection<Snowflake, UserResolvable> | readonly UserResolvable[],
options?: BulkBanOptions,
): Promise<BulkBanResult>;
public edit(user: UserResolvable, options: GuildMemberEditOptions): Promise<GuildMember>;
public fetch(
options: UserResolvable | FetchMemberOptions | (FetchMembersOptions & { user: UserResolvable }),
Expand All @@ -4272,6 +4278,10 @@ export class GuildBanManager extends CachedManager<Snowflake, GuildBan, GuildBan
public fetch(options: UserResolvable | FetchBanOptions): Promise<GuildBan>;
public fetch(options?: FetchBansOptions): Promise<Collection<Snowflake, GuildBan>>;
public remove(user: UserResolvable, reason?: string): Promise<User | null>;
public bulkCreate(
users: ReadonlyCollection<Snowflake, UserResolvable> | readonly UserResolvable[],
options?: BulkBanOptions,
): Promise<BulkBanResult>;
}

export class GuildInviteManager extends DataManager<string, Invite, InviteResolvable> {
Expand Down Expand Up @@ -4959,6 +4969,13 @@ export interface BanOptions {
reason?: string;
}

export interface BulkBanOptions extends Omit<BanOptions, 'deleteMessageDays'> {}

export interface BulkBanResult {
bannedUsers: readonly Snowflake[];
failedUsers: readonly Snowflake[];
}

export type Base64Resolvable = Buffer | Base64String;

export type Base64String = string;
Expand Down

0 comments on commit b6bdd57

Please sign in to comment.