diff --git a/discord/interaction.go b/discord/interaction.go index 3c86fc61..e12d66ec 100644 --- a/discord/interaction.go +++ b/discord/interaction.go @@ -108,6 +108,30 @@ func UnmarshalInteraction(data []byte) (Interaction, error) { return interaction, nil } +type ResolvedData struct { + Users map[snowflake.ID]User `json:"users,omitempty"` + Members map[snowflake.ID]ResolvedMember `json:"members,omitempty"` + Roles map[snowflake.ID]Role `json:"roles,omitempty"` + Channels map[snowflake.ID]ResolvedChannel `json:"channels,omitempty"` + Attachments map[snowflake.ID]Attachment `json:"attachments,omitempty"` +} + +func (r *ResolvedData) UnmarshalJSON(data []byte) error { + type resolvedData ResolvedData + var v resolvedData + if err := json.Unmarshal(data, &v); err != nil { + return err + } + *r = ResolvedData(v) + for id, member := range r.Members { + if user, ok := r.Users[id]; ok { + member.User = user + r.Members[id] = member + } + } + return nil +} + type ResolvedMember struct { Member Permissions Permissions `json:"permissions,omitempty"` diff --git a/discord/interaction_application_command.go b/discord/interaction_application_command.go index 03c9f3aa..afa88f97 100644 --- a/discord/interaction_application_command.go +++ b/discord/interaction_application_command.go @@ -139,7 +139,7 @@ type rawSlashCommandInteractionData struct { Name string `json:"name"` Type ApplicationCommandType `json:"type"` GuildID *snowflake.ID `json:"guild_id,omitempty"` - Resolved SlashCommandResolved `json:"resolved"` + Resolved ResolvedData `json:"resolved"` Options []internalSlashCommandOption `json:"options"` } @@ -170,7 +170,7 @@ type SlashCommandInteractionData struct { guildID *snowflake.ID SubCommandName *string SubCommandGroupName *string - Resolved SlashCommandResolved + Resolved ResolvedData Options map[string]SlashCommandOption } @@ -498,30 +498,6 @@ func (d SlashCommandInteractionData) FindAll(optionFindFunc func(option SlashCom func (SlashCommandInteractionData) applicationCommandInteractionData() {} -type SlashCommandResolved struct { - Users map[snowflake.ID]User `json:"users,omitempty"` - Members map[snowflake.ID]ResolvedMember `json:"members,omitempty"` - Roles map[snowflake.ID]Role `json:"roles,omitempty"` - Channels map[snowflake.ID]ResolvedChannel `json:"channels,omitempty"` - Attachments map[snowflake.ID]Attachment `json:"attachments,omitempty"` -} - -func (r *SlashCommandResolved) UnmarshalJSON(data []byte) error { - type slashCommandResolved SlashCommandResolved - var v slashCommandResolved - if err := json.Unmarshal(data, &v); err != nil { - return err - } - *r = SlashCommandResolved(v) - for id, member := range r.Members { - if user, ok := r.Users[id]; ok { - member.User = user - r.Members[id] = member - } - } - return nil -} - type ContextCommandInteractionData interface { ApplicationCommandInteractionData TargetID() snowflake.ID diff --git a/discord/message.go b/discord/message.go index 93ef3818..d6c0a065 100644 --- a/discord/message.go +++ b/discord/message.go @@ -113,6 +113,7 @@ type Message struct { Thread *MessageThread `json:"thread,omitempty"` Position *int `json:"position,omitempty"` RoleSubscriptionData *RoleSubscriptionData `json:"role_subscription_data,omitempty"` + Resolved *ResolvedData `json:"resolved,omitempty"` } func (m *Message) UnmarshalJSON(data []byte) error { diff --git a/discord/select_menu.go b/discord/select_menu.go index e4db9a9d..6f7105de 100644 --- a/discord/select_menu.go +++ b/discord/select_menu.go @@ -1,6 +1,9 @@ package discord -import "github.com/disgoorg/json" +import ( + "github.com/disgoorg/json" + "github.com/disgoorg/snowflake/v2" +) type SelectMenuComponent interface { InteractiveComponent @@ -189,11 +192,12 @@ func NewUserSelectMenu(customID string, placeholder string) UserSelectMenuCompon } type UserSelectMenuComponent struct { - CustomID string `json:"custom_id"` - Placeholder string `json:"placeholder,omitempty"` - MinValues *int `json:"min_values,omitempty"` - MaxValues int `json:"max_values,omitempty"` - Disabled bool `json:"disabled,omitempty"` + CustomID string `json:"custom_id"` + Placeholder string `json:"placeholder,omitempty"` + DefaultValues []SelectMenuDefaultValue `json:"default_values,omitempty"` + MinValues *int `json:"min_values,omitempty"` + MaxValues int `json:"max_values,omitempty"` + Disabled bool `json:"disabled,omitempty"` } func (c UserSelectMenuComponent) MarshalJSON() ([]byte, error) { @@ -261,6 +265,30 @@ func (c UserSelectMenuComponent) WithDisabled(disabled bool) UserSelectMenuCompo return c } +// SetDefaultValues returns a new UserSelectMenuComponent with the provided default values +func (c UserSelectMenuComponent) SetDefaultValues(defaultValues ...snowflake.ID) UserSelectMenuComponent { + values := make([]SelectMenuDefaultValue, 0, len(defaultValues)) + for _, value := range defaultValues { + values = append(values, NewSelectMenuDefaultUser(value)) + } + c.DefaultValues = values + return c +} + +// AddDefaultValue returns a new UserSelectMenuComponent with the provided default value added +func (c UserSelectMenuComponent) AddDefaultValue(defaultValue snowflake.ID) UserSelectMenuComponent { + c.DefaultValues = append(c.DefaultValues, NewSelectMenuDefaultUser(defaultValue)) + return c +} + +// RemoveDefaultValue returns a new UserSelectMenuComponent with the provided default value at the index removed +func (c UserSelectMenuComponent) RemoveDefaultValue(index int) UserSelectMenuComponent { + if len(c.DefaultValues) > index { + c.DefaultValues = append(c.DefaultValues[:index], c.DefaultValues[index+1:]...) + } + return c +} + var ( _ Component = (*UserSelectMenuComponent)(nil) _ InteractiveComponent = (*UserSelectMenuComponent)(nil) @@ -276,11 +304,12 @@ func NewRoleSelectMenu(customID string, placeholder string) RoleSelectMenuCompon } type RoleSelectMenuComponent struct { - CustomID string `json:"custom_id"` - Placeholder string `json:"placeholder,omitempty"` - MinValues *int `json:"min_values,omitempty"` - MaxValues int `json:"max_values,omitempty"` - Disabled bool `json:"disabled,omitempty"` + CustomID string `json:"custom_id"` + Placeholder string `json:"placeholder,omitempty"` + DefaultValues []SelectMenuDefaultValue `json:"default_values,omitempty"` + MinValues *int `json:"min_values,omitempty"` + MaxValues int `json:"max_values,omitempty"` + Disabled bool `json:"disabled,omitempty"` } func (c RoleSelectMenuComponent) MarshalJSON() ([]byte, error) { @@ -348,6 +377,30 @@ func (c RoleSelectMenuComponent) WithDisabled(disabled bool) RoleSelectMenuCompo return c } +// SetDefaultValues returns a new RoleSelectMenuComponent with the provided default values +func (c RoleSelectMenuComponent) SetDefaultValues(defaultValues ...snowflake.ID) RoleSelectMenuComponent { + values := make([]SelectMenuDefaultValue, 0, len(defaultValues)) + for _, value := range defaultValues { + values = append(values, NewSelectMenuDefaultRole(value)) + } + c.DefaultValues = values + return c +} + +// AddDefaultValue returns a new RoleSelectMenuComponent with the provided default value added +func (c RoleSelectMenuComponent) AddDefaultValue(defaultValue snowflake.ID) RoleSelectMenuComponent { + c.DefaultValues = append(c.DefaultValues, NewSelectMenuDefaultRole(defaultValue)) + return c +} + +// RemoveDefaultValue returns a new RoleSelectMenuComponent with the provided default value at the index removed +func (c RoleSelectMenuComponent) RemoveDefaultValue(index int) RoleSelectMenuComponent { + if len(c.DefaultValues) > index { + c.DefaultValues = append(c.DefaultValues[:index], c.DefaultValues[index+1:]...) + } + return c +} + var ( _ Component = (*MentionableSelectMenuComponent)(nil) _ InteractiveComponent = (*MentionableSelectMenuComponent)(nil) @@ -363,11 +416,12 @@ func NewMentionableSelectMenu(customID string, placeholder string) MentionableSe } type MentionableSelectMenuComponent struct { - CustomID string `json:"custom_id"` - Placeholder string `json:"placeholder,omitempty"` - MinValues *int `json:"min_values,omitempty"` - MaxValues int `json:"max_values,omitempty"` - Disabled bool `json:"disabled,omitempty"` + CustomID string `json:"custom_id"` + Placeholder string `json:"placeholder,omitempty"` + DefaultValues []SelectMenuDefaultValue `json:"default_values,omitempty"` + MinValues *int `json:"min_values,omitempty"` + MaxValues int `json:"max_values,omitempty"` + Disabled bool `json:"disabled,omitempty"` } func (c MentionableSelectMenuComponent) MarshalJSON() ([]byte, error) { @@ -435,6 +489,27 @@ func (c MentionableSelectMenuComponent) WithDisabled(disabled bool) MentionableS return c } +// SetDefaultValues returns a new MentionableSelectMenuComponent with the provided default values +func (c MentionableSelectMenuComponent) SetDefaultValues(defaultValues ...SelectMenuDefaultValue) MentionableSelectMenuComponent { + c.DefaultValues = defaultValues + return c +} + +// AddDefaultValue returns a new MentionableSelectMenuComponent with the provided default value added. +// SelectMenuDefaultValue can easily be constructed using helpers like NewSelectMenuDefaultUser or NewSelectMenuDefaultRole +func (c MentionableSelectMenuComponent) AddDefaultValue(value SelectMenuDefaultValue) MentionableSelectMenuComponent { + c.DefaultValues = append(c.DefaultValues, value) + return c +} + +// RemoveDefaultValue returns a new MentionableSelectMenuComponent with the provided default value at the index removed +func (c MentionableSelectMenuComponent) RemoveDefaultValue(index int) MentionableSelectMenuComponent { + if len(c.DefaultValues) > index { + c.DefaultValues = append(c.DefaultValues[:index], c.DefaultValues[index+1:]...) + } + return c +} + var ( _ Component = (*ChannelSelectMenuComponent)(nil) _ InteractiveComponent = (*ChannelSelectMenuComponent)(nil) @@ -450,12 +525,13 @@ func NewChannelSelectMenu(customID string, placeholder string) ChannelSelectMenu } type ChannelSelectMenuComponent struct { - CustomID string `json:"custom_id"` - Placeholder string `json:"placeholder,omitempty"` - MinValues *int `json:"min_values,omitempty"` - MaxValues int `json:"max_values,omitempty"` - Disabled bool `json:"disabled,omitempty"` - ChannelTypes []ChannelType `json:"channel_types,omitempty"` + CustomID string `json:"custom_id"` + Placeholder string `json:"placeholder,omitempty"` + DefaultValues []SelectMenuDefaultValue `json:"default_values,omitempty"` + MinValues *int `json:"min_values,omitempty"` + MaxValues int `json:"max_values,omitempty"` + Disabled bool `json:"disabled,omitempty"` + ChannelTypes []ChannelType `json:"channel_types,omitempty"` } func (c ChannelSelectMenuComponent) MarshalJSON() ([]byte, error) { @@ -528,3 +604,64 @@ func (c ChannelSelectMenuComponent) WithChannelTypes(channelTypes ...ChannelType c.ChannelTypes = channelTypes return c } + +// SetDefaultValues returns a new ChannelSelectMenuComponent with the provided default values +func (c ChannelSelectMenuComponent) SetDefaultValues(defaultValues ...snowflake.ID) ChannelSelectMenuComponent { + values := make([]SelectMenuDefaultValue, 0, len(defaultValues)) + for _, value := range defaultValues { + values = append(values, NewSelectMenuDefaultChannel(value)) + } + c.DefaultValues = values + return c +} + +// AddDefaultValue returns a new ChannelSelectMenuComponent with the provided default value added +func (c ChannelSelectMenuComponent) AddDefaultValue(defaultValue snowflake.ID) ChannelSelectMenuComponent { + c.DefaultValues = append(c.DefaultValues, NewSelectMenuDefaultChannel(defaultValue)) + return c +} + +// RemoveDefaultValue returns a new ChannelSelectMenuComponent with the provided default value at the index removed +func (c ChannelSelectMenuComponent) RemoveDefaultValue(index int) ChannelSelectMenuComponent { + if len(c.DefaultValues) > index { + c.DefaultValues = append(c.DefaultValues[:index], c.DefaultValues[index+1:]...) + } + return c +} + +type SelectMenuDefaultValue struct { + ID snowflake.ID `json:"id"` + Type SelectMenuDefaultValueType `json:"type"` +} + +type SelectMenuDefaultValueType string + +const ( + SelectMenuDefaultValueTypeUser SelectMenuDefaultValueType = "user" + SelectMenuDefaultValueTypeRole SelectMenuDefaultValueType = "role" + SelectMenuDefaultValueTypeChannel SelectMenuDefaultValueType = "channel" +) + +// NewSelectMenuDefaultUser returns a new SelectMenuDefaultValue of type SelectMenuDefaultValueTypeUser +func NewSelectMenuDefaultUser(id snowflake.ID) SelectMenuDefaultValue { + return SelectMenuDefaultValue{ + ID: id, + Type: SelectMenuDefaultValueTypeUser, + } +} + +// NewSelectMenuDefaultRole returns a new SelectMenuDefaultValue of type SelectMenuDefaultValueTypeRole +func NewSelectMenuDefaultRole(id snowflake.ID) SelectMenuDefaultValue { + return SelectMenuDefaultValue{ + ID: id, + Type: SelectMenuDefaultValueTypeRole, + } +} + +// NewSelectMenuDefaultChannel returns a new SelectMenuDefaultValue of type SelectMenuDefaultValueTypeChannel +func NewSelectMenuDefaultChannel(id snowflake.ID) SelectMenuDefaultValue { + return SelectMenuDefaultValue{ + ID: id, + Type: SelectMenuDefaultValueTypeChannel, + } +}