Skip to content

Add file type filtering in slash command attachment options and modal attachment uploads - #3113

Open
freya022 wants to merge 16 commits into
discord-jda:masterfrom
freya022:feature/attachment-file-types
Open

Add file type filtering in slash command attachment options and modal attachment uploads#3113
freya022 wants to merge 16 commits into
discord-jda:masterfrom
freya022:feature/attachment-file-types

Conversation

@freya022

@freya022 freya022 commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Pull Request Etiquette

  • I have checked the PRs for upcoming features/bug fixes.
  • I have read the contributing guidelines.
  • I applied the code formatter to my changes with ./gradlew format

Changes

  • Internal code
  • Library interface (affecting end-user code)
  • Documentation
  • Other: _____

Closes Issue: NaN

Description

This PR enables slash commands options, and modal attachment uploads, to accept attachments with specific extensions or media type (image, video, audio ; the list of extensions implied by these is not documented on purpose).

Docs PR: discord/discord-api-docs#8506
Changelog: https://docs.discord.com/developers/change-log#filter-file-types-in-file-uploads-and-attachment-options

Examples

Slash commands

jda.updateCommands()
   .addCommands(
       // Accepts any kind of video and audio supported by Discord
       Commands.slash("merge", "Merge video and audio")
               .addOptions(
                   new OptionData(OptionType.ATTACHMENT, "video", "The source video", true)
                           .addFileTypes(FileType.VIDEO),
                   new OptionData(OptionType.ATTACHMENT, "audio", "The audio to merge in", true)
                           .addFileTypes(FileType.AUDIO)
               ),
       // Accepts a single .svg file
       Commands.slash("render", "Renders a SVG file")
               .addOptions(
                   new OptionData(OptionType.ATTACHMENT, "file", "The SVG to render", true)
                           .addFileTypeExtensions("svg")
               )
   )
   .queue();

Modals

The same methods exist on AttachmentUpload.Builder, with the same limit (10) and same behavior.

Comment thread src/main/java/net/dv8tion/jda/api/interactions/IFilterableFileTypes.java Outdated

private final String value;

@ApiStatus.Internal

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this instead of just making it private?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used in FileTypesImpl#fromArray where the raw value is passed.

this.maxLength = json.getInt("max_length");
}
this.fileTypes =
json.optArray("file_types").map(FileTypesImpl::fromArray).orElse(FileTypesImpl.empty());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
json.optArray("file_types").map(FileTypesImpl::fromArray).orElse(FileTypesImpl.empty());
json.optArray("file_types").map(FileTypesImpl::fromArray).orElseGet(FileTypesImpl::empty);

@freya022 freya022 Aug 9, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to keep the orElse but replaced the value to be a constant, empty & immutable list.

}

/**
* The <b>immutable</b> list of file types accepted by this option.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Immutable and unmodifiable view are different implications. Since the unmodifiable list can still change and thus throw exceptions when modified by a different thread.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if a view is returned, Command is an immutable object, so the returned list is also immutable since there is no code that can change it, that's why it's documented and annotated as immutable/unmodifiable, and not as a view.

}
}
if (type == OptionType.ATTACHMENT) {
json.put("file_types", fileTypes.toData());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So what happens here when fileTypes is still empty (initial state)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It sends an empty array, which is the same as if the field was absent, accepting any attachment.

freya022 and others added 3 commits August 9, 2026 22:36
Co-authored-by: Florian Spieß <business@minn.dev>
Co-authored-by: Florian Spieß <business@minn.dev>
Makes the payload smaller and avoids (third party) command cache flushes

Co-authored-by: Florian Spieß <business@minn.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants