CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-net-dv8tion--jda

Java Discord API - A comprehensive Java library for building Discord bots and applications

Pending
Overview
Eval results
Files

restactions.mddocs/

RestAction System

Powerful asynchronous request system with automatic rate-limit handling, chaining capabilities, error handling, and execution control for Discord API interactions.

Capabilities

Core RestAction

The foundation of JDA's asynchronous request system providing multiple execution patterns.

/**
 * Represents an asynchronous Discord API request that can be executed in various ways.
 * @param <T> The type that will be returned when this RestAction is executed
 */
interface RestAction<T> {
    /** Execute asynchronously without callbacks */
    void queue();
    
    /** Execute asynchronously with success callback */
    void queue(Consumer<? super T> success);
    
    /** Execute asynchronously with success and failure callbacks */
    void queue(Consumer<? super T> success, Consumer<? super Throwable> failure);
    
    /** Execute and return CompletableFuture */
    CompletableFuture<T> submit();
    
    /** Execute synchronously (blocking) */
    T complete() throws RuntimeException;
    
    /** Execute synchronously with timeout */
    T complete(long timeout, TimeUnit unit) throws RuntimeException, TimeoutException;
    
    /** Execute after delay */
    RestAction<T> queueAfter(long delay, TimeUnit unit);
    RestAction<T> queueAfter(long delay, TimeUnit unit, ScheduledExecutorService executor);
    
    /** Execute after delay with callbacks */
    void queueAfter(long delay, TimeUnit unit, Consumer<? super T> success);
    void queueAfter(long delay, TimeUnit unit, Consumer<? super T> success, Consumer<? super Throwable> failure);
    
    /** Execute after delay and return future */
    CompletableFuture<T> submitAfter(long delay, TimeUnit unit);
    CompletableFuture<T> submitAfter(long delay, TimeUnit unit, ScheduledExecutorService executor);
    
    /** Execute after delay, blocking */
    T completeAfter(long delay, TimeUnit unit);
    
    /** Transform result with function */
    <U> RestAction<U> map(Function<? super T, ? extends U> mapper);
    
    /** Chain with another RestAction */
    <U> RestAction<U> flatMap(Function<? super T, ? extends RestAction<U>> flatMapper);
    
    /** Handle errors and provide fallback */
    RestAction<T> onErrorMap(Function<? super Throwable, ? extends T> mapper);
    RestAction<T> onErrorMap(Predicate<? super Throwable> condition, Function<? super Throwable, ? extends T> mapper);
    
    /** Chain error handling with RestAction */
    RestAction<T> onErrorFlatMap(Function<? super Throwable, ? extends RestAction<T>> flatMapper);
    RestAction<T> onErrorFlatMap(Predicate<? super Throwable> condition, Function<? super Throwable, ? extends RestAction<T>> flatMapper);
    
    /** Set request timeout */
    RestAction<T> timeout(long timeout, TimeUnit unit);
    
    /** Set deadline for request */
    RestAction<T> deadline(long timestamp);
    
    /** Add check before execution */
    RestAction<T> setCheck(BooleanSupplier checks);
    
    /** Get the check supplier */
    BooleanSupplier getCheck();
    
    /** Check if this RestAction is completed */
    boolean isPassContext();
    
    /** Set context passing */
    RestAction<T> setPassContext(boolean passContext);
    
    /** Get JDA instance */
    JDA getJDA();
}

Usage Examples:

import net.dv8tion.jda.api.requests.RestAction;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

// Basic asynchronous execution
channel.sendMessage("Hello!").queue();

// With success callback
channel.sendMessage("Hello!").queue(
    message -> System.out.println("Message sent: " + message.getId())
);

// With success and error callbacks
channel.sendMessage("Hello!").queue(
    message -> System.out.println("Success: " + message.getId()),
    error -> System.err.println("Failed to send: " + error.getMessage())
);

// Using CompletableFuture
CompletableFuture<Message> future = channel.sendMessage("Hello!").submit();
future.thenAccept(message -> System.out.println("Message sent: " + message.getId()))
      .exceptionally(error -> {
          System.err.println("Error: " + error.getMessage());
          return null;
      });

// Synchronous execution (blocking)
try {
    Message message = channel.sendMessage("Hello!").complete();
    System.out.println("Message sent synchronously: " + message.getId());
} catch (Exception e) {
    System.err.println("Failed to send message: " + e.getMessage());
}

// Delayed execution
channel.sendMessage("This will be sent in 5 seconds")
    .queueAfter(5, TimeUnit.SECONDS);

// With timeout
channel.sendMessage("Hello!")
    .timeout(10, TimeUnit.SECONDS)
    .queue(
        success -> System.out.println("Sent within timeout"),
        error -> System.err.println("Failed or timed out: " + error.getMessage())
    );

RestAction Chaining

Powerful chaining capabilities for sequential and dependent operations.

/**
 * Chain RestActions together for complex operations.
 */
// Example chaining methods (part of RestAction interface)

/** Transform the result */
<U> RestAction<U> map(Function<? super T, ? extends U> mapper);

/** Chain with another RestAction */
<U> RestAction<U> flatMap(Function<? super T, ? extends RestAction<U>> flatMapper);

/** Handle errors with transformation */
RestAction<T> onErrorMap(Function<? super Throwable, ? extends T> mapper);

/** Handle errors with RestAction chaining */
RestAction<T> onErrorFlatMap(Function<? super Throwable, ? extends RestAction<T>> flatMapper);

Usage Examples:

// Transform message content
channel.retrieveMessageById("123456789")
    .map(Message::getContentRaw)
    .queue(content -> System.out.println("Message content: " + content));

// Chain operations: send message, then pin it
channel.sendMessage("Important announcement!")
    .flatMap(Message::pin)
    .queue(
        success -> System.out.println("Message sent and pinned"),
        error -> System.err.println("Failed: " + error.getMessage())
    );

// Complex chaining: create role, assign to user, send confirmation
guild.createRole()
    .setName("New Member")
    .setColor(Color.GREEN)
    .flatMap(role -> guild.addRoleToMember(member, role)
        .map(success -> role))
    .flatMap(role -> channel.sendMessage("Welcome! You've been given the " + role.getAsMention() + " role."))
    .queue(
        message -> System.out.println("Welcome process completed"),
        error -> System.err.println("Welcome process failed: " + error.getMessage())
    );

// Error handling with fallback
guild.retrieveMemberById(userId)
    .onErrorFlatMap(error -> {
        if (error instanceof ErrorResponseException) {
            ErrorResponseException ere = (ErrorResponseException) error;
            if (ere.getErrorCode() == 10007) { // Unknown Member
                return jda.retrieveUserById(userId)
                    .map(user -> null); // Return null for non-members
            }
        }
        return RestAction.forResult(null);
    })
    .queue(member -> {
        if (member != null) {
            System.out.println("Member found: " + member.getEffectiveName());
        } else {
            System.out.println("User exists but is not a member");
        }
    });

// Transform with error handling
channel.retrieveMessageById(messageId)
    .map(message -> message.getContentRaw().length())
    .onErrorMap(error -> -1) // Return -1 if message not found
    .queue(length -> {
        if (length == -1) {
            System.out.println("Message not found");
        } else {
            System.out.println("Message length: " + length);
        }
    });

Auditable RestActions

RestActions that create entries in the guild's audit log with reason tracking.

/**
 * Extension of RestAction for actions that appear in audit log.
 * @param <T> The return type of this RestAction
 */
interface AuditableRestAction<T> extends RestAction<T> {
    /** Set audit log reason */
    AuditableRestAction<T> reason(String reason);
    
    /** Get current audit log reason */
    String getReason();
}

Usage Examples:

// Ban with audit log reason
guild.ban(user, 7, TimeUnit.DAYS)
    .reason("Spamming in chat")
    .queue(
        success -> System.out.println("User banned with reason logged"),
        error -> System.err.println("Ban failed: " + error.getMessage())
    );

// Kick with reason
guild.kick(member)
    .reason("Violation of community guidelines")
    .queue();

// Role modification with reason
guild.createRole()
    .setName("Moderator")
    .setPermissions(Permission.KICK_MEMBERS, Permission.MESSAGE_MANAGE)
    .reason("Creating moderator role for new staff")
    .queue();

// Channel creation with reason
guild.createTextChannel("announcements")
    .setTopic("Important server announcements")
    .reason("Creating dedicated announcement channel")
    .queue();

// Member timeout with reason
member.timeoutFor(1, TimeUnit.HOURS)
    .reason("Inappropriate behavior in voice chat")
    .queue(
        success -> channel.sendMessage("Member has been timed out for 1 hour").queue(),
        error -> channel.sendMessage("Failed to timeout member: " + error.getMessage()).queue()
    );

Specialized RestActions

Specific RestAction implementations for different Discord API operations.

/**
 * RestAction for creating messages with additional message-specific options.
 */
interface MessageCreateAction extends RestAction<Message> {
    MessageCreateAction setContent(String content);
    MessageCreateAction setEmbeds(MessageEmbed... embeds);
    MessageCreateAction setFiles(FileUpload... files);
    MessageCreateAction setComponents(ActionRow... components);
    MessageCreateAction setTTS(boolean tts);
    MessageCreateAction setSuppressEmbeds(boolean suppress);
    MessageCreateAction mentionUsers(String... userIds);
    MessageCreateAction mentionRoles(String... roleIds);
}

/**
 * RestAction for editing messages.
 */
interface MessageEditAction extends RestAction<Message> {
    MessageEditAction setContent(String content);
    MessageEditAction setEmbeds(MessageEmbed... embeds);
    MessageEditAction setComponents(ActionRow... components);
    MessageEditAction setAttachments(AttachedFile... attachments);
    MessageEditAction setSuppressEmbeds(boolean suppress);
}

/**
 * RestAction for creating channels.
 */
interface ChannelAction<T extends GuildChannel> extends AuditableRestAction<T> {
    ChannelAction<T> setName(String name);
    ChannelAction<T> setTopic(String topic);
    ChannelAction<T> setNSFW(boolean nsfw);
    ChannelAction<T> setPosition(Integer position);
    ChannelAction<T> setParent(Category parent);
    ChannelAction<T> setSlowmode(int slowmode);
    ChannelAction<T> setBitrate(Integer bitrate);
    ChannelAction<T> setUserlimit(Integer userlimit);
    ChannelAction<T> addPermissionOverride(IPermissionHolder permHolder, long allow, long deny);
    ChannelAction<T> addMemberPermissionOverride(long memberId, long allow, long deny);
    ChannelAction<T> addRolePermissionOverride(long roleId, long allow, long deny);
}

/**
 * RestAction for creating roles.
 */
interface RoleAction extends AuditableRestAction<Role> {
    RoleAction setName(String name);
    RoleAction setHoisted(Boolean hoisted);
    RoleAction setMentionable(Boolean mentionable);
    RoleAction setColor(Color color);
    RoleAction setColor(int rgb);
    RoleAction setPermissions(Permission... permissions);
    RoleAction setPermissions(Collection<Permission> permissions);
    RoleAction setPermissions(long permissions);
    RoleAction setIcon(Icon icon);
    RoleAction setEmoji(Emoji emoji);
}

/**
 * RestAction for creating invites.
 */
interface InviteAction extends RestAction<Invite> {
    InviteAction setMaxAge(Integer maxAge);
    InviteAction setMaxUses(Integer maxUses);
    InviteAction setTemporary(Boolean temporary);
    InviteAction setUnique(Boolean unique);
    InviteAction setTargetUser(User targetUser);
    InviteAction setTargetApplication(long applicationId);
    InviteAction setTargetType(Invite.TargetType targetType);
}

Usage Examples:

// Complex channel creation
guild.createTextChannel("general-chat")
    .setTopic("General discussion channel")
    .setNSFW(false)
    .setSlowmode(5) // 5 second slowmode
    .addMemberPermissionOverride(member.getIdLong(), 
        Permission.VIEW_CHANNEL.getRawValue(), 0)
    .addRolePermissionOverride(mutedRole.getIdLong(), 
        0, Permission.SEND_MESSAGES.getRawValue())
    .reason("Creating general chat channel")
    .queue(channel -> {
        System.out.println("Created channel: " + channel.getName());
        
        // Send welcome message to new channel
        channel.sendMessage("Welcome to the general chat!")
            .queue();
    });

// Complex role creation with permissions
guild.createRole()
    .setName("Helper")
    .setColor(Color.CYAN)
    .setHoisted(true)
    .setMentionable(true)
    .setPermissions(
        Permission.MESSAGE_MANAGE,
        Permission.KICK_MEMBERS,
        Permission.MANAGE_ROLES
    )
    .reason("Creating helper role for trusted members")
    .flatMap(role -> {
        // Assign role to specific member
        return guild.addRoleToMember(member, role)
            .reason("Promoting member to helper")
            .map(success -> role);
    })
    .queue(role -> {
        channel.sendMessage("Created " + role.getAsMention() + " role and assigned to " + member.getAsMention())
            .queue();
    });

// Invite creation with specific settings
channel.createInvite()
    .setMaxAge(3600) // 1 hour
    .setMaxUses(10)
    .setTemporary(false)
    .setUnique(true)
    .queue(invite -> {
        System.out.println("Created invite: " + invite.getUrl());
        
        // Send invite in DM
        member.getUser().openPrivateChannel()
            .flatMap(dm -> dm.sendMessage("Here's your server invite: " + invite.getUrl()))
            .queue();
    });

RestAction Utilities

Utility methods and classes for advanced RestAction manipulation.

/**
 * Utility methods for RestAction operations.
 */
class RestAction {
    /** Create RestAction that immediately completes with value */
    static <E> RestAction<E> forResult(E result);
    
    /** Combine multiple RestActions */
    static RestAction<List<Object>> allOf(RestAction<?>... actions);
    static RestAction<List<Object>> allOf(Collection<? extends RestAction<?>> actions);
    
    /** Execute first successful RestAction */
    static <T> RestAction<T> firstOf(RestAction<T>... actions);
    static <T> RestAction<T> firstOf(Collection<? extends RestAction<T>> actions);
    
    /** Set default failure handler */
    static void setDefaultFailure(Consumer<? super Throwable> callback);
    
    /** Set default success handler */
    static void setDefaultSuccess(Consumer<Object> callback);
    
    /** Get default timeout */
    static long getDefaultTimeout(TimeUnit unit);
    
    /** Set default timeout */
    static void setDefaultTimeout(long timeout, TimeUnit unit);
}

Usage Examples:

// Combine multiple operations
List<RestAction<Message>> messageActions = Arrays.asList(
    channel1.sendMessage("Hello from channel 1"),
    channel2.sendMessage("Hello from channel 2"),
    channel3.sendMessage("Hello from channel 3")
);

RestAction.allOf(messageActions)
    .queue(results -> System.out.println("All messages sent successfully"));

// First successful operation
List<RestAction<User>> userRetrieves = Arrays.asList(
    jda.retrieveUserById("123456789"),
    jda.retrieveUserById("987654321"),
    jda.retrieveUserById("555666777")
);

RestAction.firstOf(userRetrieves)
    .queue(user -> System.out.println("Found user: " + user.getName()));

// Immediate result
RestAction<String> immediateResult = RestAction.forResult("Cached value");
immediateResult.queue(value -> System.out.println("Got: " + value));

// Set global defaults
RestAction.setDefaultTimeout(30, TimeUnit.SECONDS);
RestAction.setDefaultFailure(error -> 
    System.err.println("Default error handler: " + error.getMessage()));

// Complex batch operation
List<Member> membersToTimeout = getViolatingMembers();
List<RestAction<Void>> timeoutActions = membersToTimeout.stream()
    .map(member -> member.timeoutFor(10, TimeUnit.MINUTES)
        .reason("Automated moderation action"))
    .collect(Collectors.toList());

RestAction.allOf(timeoutActions)
    .queue(
        success -> channel.sendMessage("Timed out " + membersToTimeout.size() + " members").queue(),
        error -> channel.sendMessage("Failed to timeout some members: " + error.getMessage()).queue()
    );

Types

// Error response exception for API errors
class ErrorResponseException extends RuntimeException {
    /** Get Discord error code */
    int getErrorCode();
    
    /** Get error response */
    ErrorResponse getErrorResponse();
    
    /** Get meaning of error */
    String getMeaning();
    
    /** Check if error is server error */
    boolean isServerError();
}

// Common error responses
enum ErrorResponse {
    GENERAL_ERROR(0, "General error"),
    UNKNOWN_ACCOUNT(10001, "Unknown account"),
    UNKNOWN_APPLICATION(10002, "Unknown application"),
    UNKNOWN_CHANNEL(10003, "Unknown channel"),
    UNKNOWN_GUILD(10004, "Unknown guild"),
    UNKNOWN_INTEGRATION(10005, "Unknown integration"),
    UNKNOWN_INVITE(10006, "Unknown invite"),
    UNKNOWN_MEMBER(10007, "Unknown member"),
    UNKNOWN_MESSAGE(10008, "Unknown message"),
    UNKNOWN_OVERWRITE(10009, "Unknown permission overwrite"),
    UNKNOWN_PROVIDER(10010, "Unknown provider"),
    UNKNOWN_ROLE(10011, "Unknown role"),
    UNKNOWN_TOKEN(10012, "Unknown token"),
    UNKNOWN_USER(10013, "Unknown user"),
    UNKNOWN_EMOJI(10014, "Unknown emoji"),
    UNKNOWN_WEBHOOK(10015, "Unknown webhook"),
    UNKNOWN_BAN(10026, "Unknown ban"),
    UNKNOWN_INTERACTION(10062, "Unknown interaction"),
    BOT_PROHIBITED_ENDPOINT(20001, "Bots cannot use this endpoint"),
    BOT_ONLY_ENDPOINT(20002, "Only bots can use this endpoint"),
    ANNOUNCEMENT_EDIT_LIMIT_EXCEEDED(20022, "Announcement rate limit exceeded"),
    CHANNEL_HIT_WRITE_RATELIMIT(20028, "Channel rate limit exceeded"),
    MAXIMUM_GUILDS(30001, "Maximum number of guilds reached"),
    MAXIMUM_FRIENDS(30002, "Maximum number of friends reached"),
    MAXIMUM_PINS(30003, "Maximum number of pins reached for the channel"),
    MAXIMUM_ROLES(30005, "Maximum number of guild roles reached"),
    MAXIMUM_WEBHOOKS(30007, "Maximum number of webhooks reached"),
    MAXIMUM_EMOJIS(30008, "Maximum number of emojis reached"),
    MAXIMUM_REACTIONS(30010, "Maximum number of reactions reached"),
    MAXIMUM_CHANNELS(30013, "Maximum number of guild channels reached"),
    MAXIMUM_ATTACHMENTS(30015, "Maximum number of attachments in a message reached"),
    MAXIMUM_INVITES(30016, "Maximum number of invites reached"),
    GUILD_ALREADY_HAS_TEMPLATE(30031, "Guild already has a template"),
    UNAUTHORIZED(40001, "Unauthorized"),
    ACCOUNT_VERIFICATION_REQUIRED(40002, "Account verification required"),
    REQUEST_ENTITY_TOO_LARGE(40005, "Request entity too large"),
    FEATURE_TEMPORARILY_DISABLED(40006, "Feature temporarily disabled server-side"),
    USER_BANNED(40007, "User banned from this guild"),
    MISSING_ACCESS(50001, "Missing access"),
    INVALID_ACCOUNT_TYPE(50002, "Invalid account type"),
    CANNOT_EXECUTE_ON_DM(50003, "Cannot execute action on a DM channel"),
    GUILD_WIDGET_DISABLED(50004, "Guild widget disabled"),
    CANNOT_EDIT_MESSAGE_BY_OTHER(50005, "Cannot edit a message authored by another user"),
    CANNOT_SEND_EMPTY_MESSAGE(50006, "Cannot send an empty message"),
    CANNOT_MESSAGE_USER(50007, "Cannot send messages to this user"),
    CANNOT_SEND_IN_VOICE_CHANNEL(50008, "Cannot send messages in a voice channel"),
    CHANNEL_VERIFICATION_TOO_HIGH(50009, "Channel verification level is too high for you to gain access"),
    OAUTH2_APPLICATION_BOT_ABSENT(50010, "OAuth2 application does not have a bot"),
    OAUTH2_APPLICATION_LIMIT_REACHED(50011, "OAuth2 application limit reached"),
    INVALID_OAUTH_STATE(50012, "Invalid OAuth2 state"),
    MISSING_PERMISSIONS(50013, "Missing permissions"),
    INVALID_AUTHENTICATION_TOKEN(50014, "Invalid authentication token"),
    NOTE_TOO_LONG(50015, "Note was too long"),
    INVALID_BULK_DELETE_QUANTITY(50016, "Invalid bulk delete quantity"),
    CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL(50019, "Cannot pin a message in a different channel"),
    INVALID_OR_TAKEN_INVITE_CODE(50020, "Invalid or taken invite code"),
    CANNOT_EXECUTE_ON_SYSTEM_MESSAGE(50021, "Cannot execute action on a system message"),
    CANNOT_EXECUTE_ON_CHANNEL_TYPE(50024, "Cannot execute action on this channel type"),
    INVALID_OAUTH_TOKEN(50025, "Invalid OAuth2 access token"),
    MISSING_OAUTH_SCOPE(50026, "Missing required OAuth2 scope"),
    INVALID_WEBHOOK_TOKEN(50027, "Invalid webhook token"),
    INVALID_ROLE(50028, "Invalid role"),
    INVALID_RECIPIENTS(50033, "Invalid Recipient(s)"),
    BULK_DELETE_MESSAGE_TOO_OLD(50034, "Bulk delete messages too old"),
    INVALID_FORM_BODY(50035, "Invalid form body"),
    INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT(50036, "Invite accepted to guild not containing bot"),
    INVALID_API_VERSION(50041, "Invalid API version"),
    FILE_UPLOADED_EXCEEDS_MAXIMUM_SIZE(50045, "File uploaded exceeds maximum size"),
    INVALID_FILE_UPLOADED(50046, "Invalid file uploaded"),
    REACTION_BLOCKED(90001, "Reaction was blocked"),
    API_RESOURCE_OVERLOADED(130000, "API resource is currently overloaded");
    
    /** Get numeric error code */
    int getCode();
    
    /** Get error meaning */
    String getMeaning();
}

// Rate limit exception
class RateLimitedException extends RuntimeException {
    /** Get retry after time in milliseconds */
    long getRetryAfter();
    
    /** Get rate limit bucket */
    String getScope();
    
    /** Check if rate limit is global */
    boolean isGlobal();
}

Install with Tessl CLI

npx tessl i tessl/maven-net-dv8tion--jda

docs

audio.md

core-management.md

entities.md

events.md

index.md

interactions.md

messaging.md

restactions.md

sharding.md

tile.json