Privileges
Another common use case when making commands is to be able to restrict access to some commands that should not be used by everyone. The Privilege API provides a way to conveniently implement these kind of restrictions.
The permission system proposed by Discord is currently not yet supported by Discord4J. As such, using this Privilege API is the recommended approach until Discord native permissions are fully supported. There is no plan to deprecate this feature for now.
The Privilege
interface
Privilege
is a functional interface that is in charge of checking if access to the command is granted for a specific
context. If granted, the abstract method of the interface returns a Mono
that completes empty, which signals that the
command can be run normally. If not granted, the returned Mono
is expected to emit PrivilegeException
(or a subclass
of this exception), possibly carrying details on the reason of the failure. In this case, the command execution will be
cancelled.
The InteractionListener
superinterface, which is extended
by ChatInputInteractionListener
, UserInteractionListener
, MessageInteractionListener
and ComponentInteractionListener
, provides a privilege()
method that can be overriden in your command
implementations.
An instance of this interface can be provided via a lambda expression. The example below defines a privilege which only grants users whose username starts with "A":
@Override
public Privilege privilege() {
return ctx -> Mono.justOrEmpty(ctx.event().getMessage().getAuthor())
.filter(author -> author.getUsername().startsWith("A"))
.switchIfEmpty(Mono.error(PrivilegeException::new))
.then();
}
Handling PrivilegeException
(for example to display a user-friendly message) is documented on
the Handling Errors page.
Privilege presets
In most cases, checking if access to a command is granted will simply consist of checking if the user has a particular
role or a particular permission in the guild. You can use one of the static methods of the Privileges
class instead of
implementing that yourself:
@Override
public Privilege privilege() {
return Privileges.checkPermissions(perms -> perms.contains(ADMINISTRATOR));
}
Check out
the Javadoc for the Privileges
class
for more presets like this one.
Composing privileges
You can compose several Privilege
instances by using the and()
and or()
methods:
@Override
public Privilege privilege() {
return Privileges.checkRoles(roles -> !roles.isEmpty())
.or(Privileges.guildOwner());
}
This code means "Grant if the user has at least one role OR if they are the owner of the server".