Skip to content

Commit

Permalink
Add Support for Application-Command Permissions V2 (#2113)
Browse files Browse the repository at this point in the history
* Add ApplicationCommandUpdatePermissionsEvent
* Add ActionType#APPLICATION_COMMAND_PERMISSION_UPDATE
* Use IntegrationPrivilege and remove CommandData#setDefaultEnabled
* Rename retrieveCommandPrivilegesById
* Add GenericPrivilegeUpdateEvent
* Update SlashBotExample to use perms v2
* Add PrivilegeConfig
  • Loading branch information
Xirado committed Jun 28, 2022
1 parent ae40d1b commit 4fc8c35
Show file tree
Hide file tree
Showing 25 changed files with 1,131 additions and 752 deletions.
9 changes: 8 additions & 1 deletion src/examples/java/SlashBotExample.java
Expand Up @@ -24,6 +24,7 @@
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.interactions.InteractionHook;
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
Expand Down Expand Up @@ -53,8 +54,10 @@ public static void main(String[] args) throws LoginException
.addOptions(new OptionData(USER, "user", "The user to ban") // USER type allows to include members of the server or other users by id
.setRequired(true)) // This command requires a parameter
.addOptions(new OptionData(INTEGER, "del_days", "Delete messages from the past days.") // This is optional
.setRequiredRange(0, 7)) // Only allow values between 0 and 7 (inclusive)
.setRequiredRange(0, 7)) // Only allow values between 0 and 7 (inclusive)
.addOptions(new OptionData(STRING, "reason", "The ban reason to use (default: Banned by <user>)")) // optional reason
.setGuildOnly(true) // This way the command can only be executed from a guild, and not the DMs
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.BAN_MEMBERS)) // Only members with the BAN_MEMBERS permission are going to see this command
);

// Simple reply commands
Expand All @@ -66,11 +69,15 @@ public static void main(String[] args) throws LoginException
// Commands without any inputs
commands.addCommands(
Commands.slash("leave", "Make the bot leave the server")
.setGuildOnly(true) // this doesn't make sense in DMs
.setDefaultPermissions(DefaultMemberPermissions.DISABLED) // only admins should be able to use this command.
);

commands.addCommands(
Commands.slash("prune", "Prune messages from this channel")
.addOption(INTEGER, "amount", "How many messages to prune (Default 100)") // simple optional argument
.setGuildOnly(true)
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.MESSAGE_MANAGE))
);

// Send the new set of commands to discord, this will override any existing global commands with the new set provided here
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/net/dv8tion/jda/api/audit/ActionType.java
Expand Up @@ -533,6 +533,11 @@ public enum ActionType
*/
THREAD_DELETE(112, TargetType.THREAD),

/**
* A moderator updated the privileges for an application
*/
APPLICATION_COMMAND_PRIVILEGES_UPDATE(121, TargetType.INTEGRATION),

UNKNOWN(-1, TargetType.UNKNOWN);

private final int key;
Expand Down
180 changes: 24 additions & 156 deletions src/main/java/net/dv8tion/jda/api/entities/Guild.java
Expand Up @@ -25,9 +25,10 @@
import net.dv8tion.jda.api.entities.templates.Template;
import net.dv8tion.jda.api.exceptions.InsufficientPermissionException;
import net.dv8tion.jda.api.interactions.commands.Command;
import net.dv8tion.jda.api.interactions.commands.PrivilegeConfig;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege;
import net.dv8tion.jda.api.interactions.commands.privileges.IntegrationPrivilege;
import net.dv8tion.jda.api.managers.AudioManager;
import net.dv8tion.jda.api.managers.GuildManager;
import net.dv8tion.jda.api.managers.GuildStickerManager;
Expand Down Expand Up @@ -285,194 +286,61 @@ default RestAction<Void> deleteCommandById(long commandId)
}

/**
* Retrieves the {@link CommandPrivilege CommandPrivileges} for the command with the specified ID.
* Retrieves the {@link IntegrationPrivilege IntegrationPrivileges} for the target with the specified ID.
* <br><b>The ID can either be of a Command or Application!</b>
*
* <p>These privileges are used to restrict who can use commands through Role/User whitelists/blacklists.
* <p>Moderators of a guild can modify these privileges through the Integrations Menu
*
* <p>If there is no command with the provided ID,
* <p>If there is no command or application with the provided ID,
* this RestAction fails with {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_COMMAND ErrorResponse.UNKNOWN_COMMAND}
*
* @param commandId
* The id of the command, this can be global or guild command
* @param targetId
* The id of the command (global or guild), or application
*
* @throws IllegalArgumentException
* If the id is not a valid snowflake
*
* @return {@link RestAction} - Type: {@link List} of {@link CommandPrivilege}
* @return {@link RestAction} - Type: {@link List} of {@link IntegrationPrivilege}
*/
@Nonnull
@CheckReturnValue
RestAction<List<CommandPrivilege>> retrieveCommandPrivilegesById(@Nonnull String commandId);
RestAction<List<IntegrationPrivilege>> retrieveIntegrationPrivilegesById(@Nonnull String targetId);

/**
* Retrieves the {@link CommandPrivilege CommandPrivileges} for the command with the specified ID.
* Retrieves the {@link IntegrationPrivilege IntegrationPrivileges} for the target with the specified ID.
* <br><b>The ID can either be of a Command or Application!</b>
*
* <p>These privileges are used to restrict who can use commands through Role/User whitelists/blacklists.
* <p>Moderators of a guild can modify these privileges through the Integrations Menu
*
* <p>If there is no command with the provided ID,
* <p>If there is no command or application with the provided ID,
* this RestAction fails with {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_COMMAND ErrorResponse.UNKNOWN_COMMAND}
*
* @param commandId
* The id of the command, this can be global or guild command
* @param targetId
* The id of the command (global or guild), or application
*
* @throws IllegalArgumentException
* If the id is not a valid snowflake
*
* @return {@link RestAction} - Type: {@link List} of {@link CommandPrivilege}
* @return {@link RestAction} - Type: {@link List} of {@link IntegrationPrivilege}
*/
@Nonnull
@CheckReturnValue
default RestAction<List<CommandPrivilege>> retrieveCommandPrivilegesById(long commandId)
default RestAction<List<IntegrationPrivilege>> retrieveIntegrationPrivilegesById(long targetId)
{
return retrieveCommandPrivilegesById(Long.toUnsignedString(commandId));
return retrieveIntegrationPrivilegesById(Long.toUnsignedString(targetId));
}

/**
* Retrieves the {@link CommandPrivilege CommandPrivileges} for the commands in this guild.
* <br>The RestAction provides a {@link Map} from the command id to the list of privileges.
*
* <p>These privileges are used to restrict who can use commands through Role/User whitelists/blacklists.
*
* @return {@link RestAction} - Type: {@link Map} from {@link String} Command ID to {@link List} of {@link CommandPrivilege}
*/
@Nonnull
@CheckReturnValue
RestAction<Map<String, List<CommandPrivilege>>> retrieveCommandPrivileges();

/**
* Updates the list of {@link CommandPrivilege CommandPrivileges} for the specified command.
* <br>Note that commands are enabled by default for all members of a guild, which means you can only <em>blacklist</em> roles and members using this method.
* To change this behavior, use {@link CommandData#setDefaultEnabled(boolean)} on your command.
*
* <p>These privileges are used to restrict who can use commands through Role/User whitelists/blacklists.
*
* <p>If there is no command with the provided ID,
* this RestAction fails with {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_COMMAND ErrorResponse.UNKNOWN_COMMAND}
*
* @param id
* The id of the command, this can be global or guild command
* @param privileges
* Complete list of up to 10 {@link CommandPrivilege CommandPrivileges} for this command
*
* @throws IllegalArgumentException
* If null is provided, the id is not a valid snowflake, or more than 10 privileges are provided
*
* @return {@link RestAction} - Type: {@link List} or {@link CommandPrivilege}
* The updated list of privileges for this command.
*/
@Nonnull
@CheckReturnValue
RestAction<List<CommandPrivilege>> updateCommandPrivilegesById(@Nonnull String id, @Nonnull Collection<? extends CommandPrivilege> privileges);

/**
* Updates the list of {@link CommandPrivilege CommandPrivileges} for the specified command.
* <br>Note that commands are enabled by default for all members of a guild, which means you can only <em>blacklist</em> roles and members using this method.
* To change this behavior, use {@link CommandData#setDefaultEnabled(boolean)} on your command.
*
* <p>These privileges are used to restrict who can use commands through Role/User whitelists/blacklists.
*
* <p>If there is no command with the provided ID,
* this RestAction fails with {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_COMMAND ErrorResponse.UNKNOWN_COMMAND}
*
* @param id
* The id of the command, this can be global or guild command
* @param privileges
* Complete list of up to 10 {@link CommandPrivilege CommandPrivileges} for this command
*
* @throws IllegalArgumentException
* If null is provided, the id is not a valid snowflake, or more than 10 privileges are provided
* Retrieves the {@link IntegrationPrivilege IntegrationPrivileges} for the commands in this guild.
* <br>The RestAction provides a {@link PrivilegeConfig} providing the privileges of this application and its commands.
*
* @return {@link RestAction} - Type: {@link List} or {@link CommandPrivilege}
* The updated list of privileges for this command.
*/
@Nonnull
@CheckReturnValue
default RestAction<List<CommandPrivilege>> updateCommandPrivilegesById(@Nonnull String id, @Nonnull CommandPrivilege... privileges)
{
Checks.noneNull(privileges, "CommandPrivileges");
return updateCommandPrivilegesById(id, Arrays.asList(privileges));
}

/**
* Updates the list of {@link CommandPrivilege CommandPrivileges} for the specified command.
* <br>Note that commands are enabled by default for all members of a guild, which means you can only <em>blacklist</em> roles and members using this method.
* To change this behavior, use {@link CommandData#setDefaultEnabled(boolean)} on your command.
*
* <p>These privileges are used to restrict who can use commands through Role/User whitelists/blacklists.
*
* <p>If there is no command with the provided ID,
* this RestAction fails with {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_COMMAND ErrorResponse.UNKNOWN_COMMAND}
*
* @param id
* The id of the command, this can be global or guild command
* @param privileges
* Complete list of up to 10 {@link CommandPrivilege CommandPrivileges} for this command
*
* @throws IllegalArgumentException
* If null is provided or more than 10 privileges are provided
*
* @return {@link RestAction} - Type: {@link List} or {@link CommandPrivilege}
* The updated list of privileges for this command.
*/
@Nonnull
@CheckReturnValue
default RestAction<List<CommandPrivilege>> updateCommandPrivilegesById(long id, @Nonnull Collection<? extends CommandPrivilege> privileges)
{
return updateCommandPrivilegesById(Long.toUnsignedString(id), privileges);
}

/**
* Updates the list of {@link CommandPrivilege CommandPrivileges} for the specified command.
* <br>Note that commands are enabled by default for all members of a guild, which means you can only <em>blacklist</em> roles and members using this method.
* To change this behavior, use {@link CommandData#setDefaultEnabled(boolean)} on your command.
*
* <p>These privileges are used to restrict who can use commands through Role/User whitelists/blacklists.
*
* <p>If there is no command with the provided ID,
* this RestAction fails with {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_COMMAND ErrorResponse.UNKNOWN_COMMAND}
*
* @param id
* The id of the command, this can be global or guild command
* @param privileges
* Complete list of up to 10 {@link CommandPrivilege CommandPrivileges} for this command
*
* @throws IllegalArgumentException
* If null is provided or more than 10 privileges are provided
*
* @return {@link RestAction} - Type: {@link List} or {@link CommandPrivilege}
* The updated list of privileges for this command.
*/
@Nonnull
@CheckReturnValue
default RestAction<List<CommandPrivilege>> updateCommandPrivilegesById(long id, @Nonnull CommandPrivilege... privileges)
{
Checks.noneNull(privileges, "CommandPrivileges");
return updateCommandPrivilegesById(id, Arrays.asList(privileges));
}

/**
* Updates the list of {@link CommandPrivilege CommandPrivileges} for the specified commands.
* <br>The argument for this function is a {@link Map} similar to the one returned by {@link #retrieveCommandPrivileges()}.
* <br>Note that commands are enabled by default for all members of a guild, which means you can only <em>blacklist</em> roles and members using this method.
* To change this behavior, use {@link CommandData#setDefaultEnabled(boolean)} on your command.
*
* <p>These privileges are used to restrict who can use commands through Role/User whitelists/blacklists.
*
* <p>If there is no command with the provided ID,
* this RestAction fails with {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_COMMAND ErrorResponse.UNKNOWN_COMMAND}
*
* @param privileges
* Complete map of {@link CommandPrivilege CommandPrivileges} for each command
*
* @throws IllegalArgumentException
* If null is provided, any of the map keys is not a valid snowflake, or more than 10 privileges are provided for any command
* <p>Moderators of a guild can modify these privileges through the Integrations Menu
*
* @return {@link RestAction} - Type: {@link Map} from {@link String} Command ID to {@link List} of {@link CommandPrivilege}
* The updated map of command privileges for this guild.
* @return {@link RestAction} - Type: {@link PrivilegeConfig}
*/
@Nonnull
@CheckReturnValue
RestAction<Map<String, List<CommandPrivilege>>> updateCommandPrivileges(@Nonnull Map<String, ? extends Collection<CommandPrivilege>> privileges);
RestAction<PrivilegeConfig> retrieveCommandPrivileges();

/**
* Retrieves the available regions for this Guild
Expand Down
@@ -0,0 +1,68 @@
/*
* Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.dv8tion.jda.api.events.interaction.command;

import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.interactions.commands.privileges.IntegrationPrivilege;
import net.dv8tion.jda.api.interactions.commands.privileges.PrivilegeTargetType;

import javax.annotation.Nonnull;
import java.util.List;

/**
* Indicates that the {@link IntegrationPrivilege Privileges} of an application-command on a guild changed.
* <br>If the moderator updates application-wide privileges instead of command, a {@link ApplicationUpdatePrivilegesEvent} will be fired instead.
*
* <p>Can be used to get affected Guild and {@link List} of new {@link IntegrationPrivilege Privileges}
*/
public class ApplicationCommandUpdatePrivilegesEvent extends GenericPrivilegeUpdateEvent
{
public ApplicationCommandUpdatePrivilegesEvent(@Nonnull JDA api, long responseNumber, @Nonnull Guild guild,
long targetId, long applicationId, @Nonnull List<IntegrationPrivilege> privileges)
{
super(api, responseNumber, guild, targetId, applicationId, privileges);
}

@Nonnull
@Override
public PrivilegeTargetType getTargetType()
{
return PrivilegeTargetType.COMMAND;
}

/**
* The id of the command whose privileges have been changed.
*
* @return id of the command whose privileges have been changed.
*/
public long getCommandIdLong()
{
return getTargetIdLong();
}

/**
* The id of the command whose privileges have been changed.
*
* @return id of the command whose privileges have been changed.
*/
@Nonnull
public String getCommandId()
{
return getTargetId();
}
}
@@ -0,0 +1,46 @@
/*
* Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.dv8tion.jda.api.events.interaction.command;

import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.interactions.commands.privileges.IntegrationPrivilege;
import net.dv8tion.jda.api.interactions.commands.privileges.PrivilegeTargetType;

import javax.annotation.Nonnull;
import java.util.List;

/**
* Indicates that the {@link IntegrationPrivilege Privileges} of an application changed.
* <br>If the moderator updates the privileges of a specific command, a {@link ApplicationCommandUpdatePrivilegesEvent} will be fired instead.
*
* <p>Can be used to get affected Guild and {@link List} of new {@link IntegrationPrivilege Privileges}
*/
public class ApplicationUpdatePrivilegesEvent extends GenericPrivilegeUpdateEvent
{
public ApplicationUpdatePrivilegesEvent(@Nonnull JDA api, long responseNumber, @Nonnull Guild guild, long applicationId, @Nonnull List<IntegrationPrivilege> privileges)
{
super(api, responseNumber, guild, applicationId, applicationId, privileges);
}

@Nonnull
@Override
public PrivilegeTargetType getTargetType()
{
return PrivilegeTargetType.INTEGRATION;
}
}

0 comments on commit 4fc8c35

Please sign in to comment.