Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions discord/application_command_option.go
Original file line number Diff line number Diff line change
Expand Up @@ -547,9 +547,18 @@ type ApplicationCommandOptionAttachment struct {
Description string `json:"description"`
DescriptionLocalizations map[Locale]string `json:"description_localizations,omitempty"`
Required bool `json:"required,omitempty"`
FileTypes []FileType `json:"file_types,omitempty"`
}

func (o ApplicationCommandOptionAttachment) MarshalJSON() ([]byte, error) {
if len(o.FileTypes) > MaxFileTypes {
return nil, fmt.Errorf("cannot have more than %d file types, got %d", MaxFileTypes, len(o.FileTypes))
}
for _, fileType := range o.FileTypes {
if !fileType.isValid() {
return nil, fmt.Errorf("invalid file type %q, must be image, video, audio or a dot-prefixed extension (e.g. \".pdf\")", fileType)
}
}
Comment thread
vmphase marked this conversation as resolved.
Outdated
type applicationCommandOptionAttachment ApplicationCommandOptionAttachment
return json.Marshal(struct {
Type ApplicationCommandOptionType `json:"type"`
Expand Down
16 changes: 16 additions & 0 deletions discord/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -1477,6 +1477,8 @@ type FileUploadComponent struct {
MaxValues int `json:"max_values,omitempty"`
// Required specifies whether the file upload is required. (default: false)
Required bool `json:"required"`
// FileTypes is the file types to filter for. (default: allows all file types, max: 10)
FileTypes []FileType `json:"file_types,omitempty"`
// Values is only set when the FileUploadComponent is received from an InteractionTypeModalSubmit
Values []snowflake.ID `json:"values,omitempty"`
}
Expand All @@ -1486,6 +1488,14 @@ func (f FileUploadComponent) interactiveComponent() {}
func (f FileUploadComponent) labelSubComponent() {}

func (f FileUploadComponent) MarshalJSON() ([]byte, error) {
if len(f.FileTypes) > MaxFileTypes {
return nil, fmt.Errorf("cannot have more than %d file types, got %d", MaxFileTypes, len(f.FileTypes))
}
for _, fileType := range f.FileTypes {
if !fileType.isValid() {
return nil, fmt.Errorf("invalid file type %q, must be image, video, audio or a dot-prefixed extension (e.g. \".pdf\")", fileType)
}
}
Comment thread
vmphase marked this conversation as resolved.
Outdated
type fileUploadComponent FileUploadComponent
return json.Marshal(struct {
Type ComponentType `json:"type"`
Expand Down Expand Up @@ -1538,6 +1548,12 @@ func (f FileUploadComponent) WithRequired(required bool) FileUploadComponent {
return f
}

// WithFileTypes returns a new FileUploadComponent with the provided fileTypes
func (f FileUploadComponent) WithFileTypes(fileTypes ...FileType) FileUploadComponent {
f.FileTypes = fileTypes
return f
}

var (
_ Component = (*RadioGroupComponent)(nil)
_ InteractiveComponent = (*RadioGroupComponent)(nil)
Expand Down
49 changes: 49 additions & 0 deletions discord/file_type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package discord

import (
"fmt"
"regexp"
)

// MaxFileTypes is the maximum number of file types that can be filtered for at once.
// https://docs.discord.com/developers/reference#file-type-filtering
const MaxFileTypes = 10

var fileTypeExtensionPattern = regexp.MustCompile(`^\.[\w](?:[\w.-]*[\w])?$`)

// NewFileType creates a new FileType for a custom file extension, e.g. NewFileType(".pdf").
// The extension must be dot-prefixed and only contain latin letters, digits, dashes or dots.
// Use the FileTypeImage, FileTypeVideo or FileTypeAudio constants for the preset file groups.
func NewFileType(extension string) (FileType, error) {
Comment thread
vmphase marked this conversation as resolved.
if !fileTypeExtensionPattern.MatchString(extension) {
return "", fmt.Errorf(`file type extension %q must be dot-prefixed (e.g. ".pdf") and only contain latin letters, digits, dashes or dots`, extension)
}
return FileType(extension), nil
}

// FileType represents a type of file to filter for in FileUploadComponents and ApplicationCommandOptionAttachment.
// It can be a preset group like FileTypeImage, FileTypeVideo or FileTypeAudio, or a custom file extension like ".pdf".
// File types only match against the file extension, Discord does not validate the actual content of the file.
// Up to [MaxFileTypes] file types can be specified, each file type is validated when marshaled.
// https://docs.discord.com/developers/reference#file-type-filtering
type FileType string

// Preset FileType groups.
const (
FileTypeGroupImage FileType = "image"
FileTypeGroupVideo FileType = "video"
FileTypeGroupAudio FileType = "audio"
)

func (t FileType) String() string {
return string(t)
}

func (t FileType) isValid() bool {
switch t {
case FileTypeGroupImage, FileTypeGroupVideo, FileTypeGroupAudio:
return true
default:
return fileTypeExtensionPattern.MatchString(string(t))
}
}
Loading