diff --git a/javacord-api/src/main/java/org/javacord/api/entity/server/BulkBanResponse.java b/javacord-api/src/main/java/org/javacord/api/entity/server/BulkBanResponse.java new file mode 100644 index 000000000..bcc4facab --- /dev/null +++ b/javacord-api/src/main/java/org/javacord/api/entity/server/BulkBanResponse.java @@ -0,0 +1,23 @@ +package org.javacord.api.entity.server; + +import java.util.Collection; + +/** + * The response of a bulk ban request. + */ +public interface BulkBanResponse { + + /** + * Gets the user ids that were banned successfully. + * + * @return The banned user ids. + */ + Collection getBannedUserIds(); + + /** + * Gets the user ids that could not be banned. + * + * @return The failed user ids. + */ + Collection getFailedUserIds(); +} diff --git a/javacord-api/src/main/java/org/javacord/api/entity/server/Server.java b/javacord-api/src/main/java/org/javacord/api/entity/server/Server.java index 77d217c5d..4f201e963 100644 --- a/javacord-api/src/main/java/org/javacord/api/entity/server/Server.java +++ b/javacord-api/src/main/java/org/javacord/api/entity/server/Server.java @@ -67,6 +67,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import java.util.stream.LongStream; /** * The class represents a Discord server, sometimes also called guild. @@ -2282,6 +2283,55 @@ default CompletableFuture banUser(long userId, Duration duration, String r return banUser(Long.toUnsignedString(userId), duration, reason); } + /** + * Bans the given user from the server. + * + * @param userIds The ids of the users to ban. + * @return A future returning details about the bulk ban. + */ + default CompletableFuture bulkBanUsers(long... userIds) { + return bulkBanUsers( + LongStream.of(userIds).boxed().map(Long::toUnsignedString).collect(Collectors.toList()), + 0, TimeUnit.SECONDS, null); + } + + /** + * Bans the given user from the server. + * + * @param userIds The ids of the users to ban. + * @return A future returning details about the bulk ban. + */ + default CompletableFuture bulkBanUsers(String... userIds) { + return bulkBanUsers(Arrays.stream(userIds).collect(Collectors.toList()), 0, TimeUnit.SECONDS, null); + } + + /** + * Bans the given user from the server. + * + * @param userIds The ids of the users to ban. + * @param deleteMessageDuration The number of messages to delete within the duration. + * (Between 0 and 604800 seconds (7 days)) + * @param unit The unit of time for the duration. + * @return A future returning details about the bulk ban. + */ + default CompletableFuture bulkBanUsers(Collection userIds, long deleteMessageDuration, + TimeUnit unit) { + return bulkBanUsers(userIds, 0, TimeUnit.SECONDS, null); + } + + /** + * Bans the given users from the server. + * + * @param userIds The ids of the users to ban. + * @param deleteMessageDuration The number of messages to delete within the duration. + * (Between 0 and 604800 seconds (7 days)) + * @param unit The unit of time for the duration. + * @param reason The Audit Log reason for the bulk ban. + * @return A future returning details about the bulk ban. + */ + CompletableFuture bulkBanUsers(Collection userIds, long deleteMessageDuration, + TimeUnit unit, String reason); + /** * Unbans the given user from the server. * @@ -3845,4 +3895,4 @@ default Optional getWidgetChannel() { * @return The system channel flags for this server. */ EnumSet getSystemChannelFlags(); -} \ No newline at end of file +} diff --git a/javacord-core/src/main/java/org/javacord/core/entity/server/BulkBanResponseImpl.java b/javacord-core/src/main/java/org/javacord/core/entity/server/BulkBanResponseImpl.java new file mode 100644 index 000000000..22586b26d --- /dev/null +++ b/javacord-core/src/main/java/org/javacord/core/entity/server/BulkBanResponseImpl.java @@ -0,0 +1,40 @@ +package org.javacord.core.entity.server; + +import com.fasterxml.jackson.databind.JsonNode; +import org.javacord.api.entity.server.BulkBanResponse; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.Set; + +public class BulkBanResponseImpl implements BulkBanResponse { + + /** + * The user ids that were banned successfully. + */ + private final Set bannedUserIds = new LinkedHashSet<>(); + + /** + * The user ids that could not be banned. + */ + private final Set failedUserIds = new LinkedHashSet<>(); + + /** + * Create a new BulkBanResponseImpl. + * + * @param data The json data about this response. + */ + public BulkBanResponseImpl(JsonNode data) { + data.get("banned_users").forEach(bannedUser -> bannedUserIds.add(bannedUser.asLong())); + data.get("failed_users").forEach(failedUser -> failedUserIds.add(failedUser.asLong())); + } + + @Override + public Collection getBannedUserIds() { + return bannedUserIds; + } + + @Override + public Collection getFailedUserIds() { + return failedUserIds; + } +} diff --git a/javacord-core/src/main/java/org/javacord/core/entity/server/ServerImpl.java b/javacord-core/src/main/java/org/javacord/core/entity/server/ServerImpl.java index 56d59823b..8dd8496da 100644 --- a/javacord-core/src/main/java/org/javacord/core/entity/server/ServerImpl.java +++ b/javacord-core/src/main/java/org/javacord/core/entity/server/ServerImpl.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.logging.log4j.Logger; import org.javacord.api.DiscordApi; import org.javacord.api.Javacord; @@ -35,6 +36,7 @@ import org.javacord.api.entity.server.ActiveThreads; import org.javacord.api.entity.server.Ban; import org.javacord.api.entity.server.BoostLevel; +import org.javacord.api.entity.server.BulkBanResponse; import org.javacord.api.entity.server.DefaultMessageNotificationLevel; import org.javacord.api.entity.server.ExplicitContentFilterLevel; import org.javacord.api.entity.server.MultiFactorAuthenticationLevel; @@ -1746,6 +1748,27 @@ public CompletableFuture banUser(String userId, long deleteMessageDuration return request.execute(result -> null); } + @Override + public CompletableFuture bulkBanUsers( + Collection userIds, + long deleteMessageDuration, + TimeUnit unit, + String reason + ) { + ObjectNode body = JsonNodeFactory.instance.objectNode(); + ArrayNode users = body.putArray("user_ids"); + userIds.forEach(users::add); + if (deleteMessageDuration > 0) { + body.put("delete_message_seconds", unit.toSeconds(deleteMessageDuration)); + } + + return new RestRequest(getApi(), RestMethod.POST, RestEndpoint.BULK_BAN) + .setUrlParameters(getIdAsString()) + .setAuditLogReason(reason) + .setBody(body) + .execute(result -> new BulkBanResponseImpl(result.getJsonBody())); + } + @Override public CompletableFuture unbanUser(long userId, String reason) { return new RestRequest(getApi(), RestMethod.DELETE, RestEndpoint.BAN) diff --git a/javacord-core/src/main/java/org/javacord/core/util/rest/RestEndpoint.java b/javacord-core/src/main/java/org/javacord/core/util/rest/RestEndpoint.java index 17d6026af..b117314c9 100644 --- a/javacord-core/src/main/java/org/javacord/core/util/rest/RestEndpoint.java +++ b/javacord-core/src/main/java/org/javacord/core/util/rest/RestEndpoint.java @@ -43,6 +43,7 @@ public enum RestEndpoint { WEBHOOK_MESSAGE("/webhooks/%s/%s/messages/%s",0), INVITE("/invites/%s"), BAN("/guilds/%s/bans", 0), + BULK_BAN("/guilds/%s/bulk-ban", 0), CURRENT_USER("/users/@me"), AUDIT_LOG("/guilds/%s/audit-logs", 0), CUSTOM_EMOJI("/guilds/%s/emojis", 0),