Skip to content
This repository has been archived by the owner on Jul 11, 2024. It is now read-only.

feat: get/list commands, bulk set & fix update/delete #529

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
172 changes: 135 additions & 37 deletions application_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,20 @@ type ApplicationCommandOptionChoice struct {
}

type ApplicationCommandOption struct {
Type OptionType `json:"type"`
Name string `json:"name"`
Description string `json:"description"`
Required bool `json:"required"`
Choices []*ApplicationCommandOptionChoice `json:"choices"`
Options []*ApplicationCommandOption `json:"options"`
ChannelTypes []ChannelType `json:"channel_types"`
MinValue float64 `json:"min_value"`
MaxValue float64 `json:"max_value"`
Autocomplete bool `json:"autocomplete"`
Type OptionType `json:"type"`
Name string `json:"name"`
NameLocalizations map[string]string `json:"name_localizations,omitempty"`
Description string `json:"description"`
DescriptionLocalizations map[string]string `json:"description_localizations,omitempty"`
Required bool `json:"required,omitempty"`
Choices []*ApplicationCommandOptionChoice `json:"choices,omitempty"`
Options []*ApplicationCommandOption `json:"options,omitempty"`
ChannelTypes []ChannelType `json:"channel_types,omitempty"`
MinValue float64 `json:"min_value,omitempty"`
MaxValue float64 `json:"max_value,omitempty"`
MinLength int `json:"min_length,omitempty"`
MaxLength int `json:"max_length,omitempty"`
Autocomplete bool `json:"autocomplete,omitempty"`
}

type ApplicationCommandDataOption struct {
Expand Down Expand Up @@ -63,29 +67,46 @@ type GuildApplicationCommandPermissions struct {
}

type ApplicationCommand struct {
ID Snowflake `json:"id"`
Type ApplicationCommandType `json:"type"`
ApplicationID Snowflake `json:"application_id"`
GuildID Snowflake `json:"guild_id"`
Name string `json:"name"`
Description string `json:"description"`
Options []*ApplicationCommandOption `json:"options"`
DefaultPermission bool `json:"default_permission,omitempty"`
ID Snowflake `json:"id"`
Type ApplicationCommandType `json:"type,omitempty"`
ApplicationID Snowflake `json:"application_id"`
GuildID Snowflake `json:"guild_id,omitempty"`
Name string `json:"name"`
NameLocalizations map[string]string `json:"name_localization,omitempty"`
Description string `json:"description"`
DescriptionLocalizations map[string]string `json:"description_localization,omitempty"`
Options []*ApplicationCommandOption `json:"options,omitempty"`
DefaultMemberPermissions *PermissionBit `json:"default_member_permissions,omitempty"`
DMPermission *bool `json:"dm_permission,omitempty"` // Global only.
DefaultPermission bool `json:"default_permission,omitempty"`
NSFW bool `json:"nsfw,omitempty"`
Version Snowflake `json:"version,omitempty"`
}

type CreateApplicationCommand struct {
Name string `json:"name"`
Description string `json:"description"`
Type ApplicationCommandType `json:"type,omitempty"`
Options []*ApplicationCommandOption `json:"options,omitempty"`
DefaultPermission bool `json:"default_permission,omitempty"`
Name string `json:"name"`
NameLocalizations map[string]string `json:"name_localization,omitempty"`
Description string `json:"description,omitempty"`
DescriptionLocalizations map[string]string `json:"description_localization,omitempty"`
Type ApplicationCommandType `json:"type,omitempty"`
Options []*ApplicationCommandOption `json:"options,omitempty"`
DMPermission *bool `json:"dm_permission,omitempty"`
DefaultMemberPermissions *PermissionBit `json:"default_member_permissions,omitempty"`
DefaultPermission bool `json:"default_permission,omitempty"`
NSFW *bool `json:"nsfw,omitempty"`
}

type UpdateApplicationCommand struct {
Name *string `json:"name,omitempty"`
DefaultPermission *bool `json:"default_permission,omitempty"`
Description *string `json:"description,omitempty"`
Options *[]*ApplicationCommandOption `json:"options,omitempty"`
Name *string `json:"name,omitempty"`
NameLocalizations *map[string]string `json:"name_localization,omitempty"`
Description *string `json:"description,omitempty"`
DescriptionLocalizations *map[string]string `json:"description_localization,omitempty"`
Type *ApplicationCommandType `json:"type,omitempty"`
Options *[]*ApplicationCommandOption `json:"options,omitempty"`
DMPermission *bool `json:"dm_permission,omitempty"` // Global only.
DefaultMemberPermissions *PermissionBit `json:"default_member_permissions,omitempty"`
DefaultPermission *bool `json:"default_permission,omitempty"`
NSFW *bool `json:"nsfw,omitempty"`
}

type ApplicationCommandQueryBuilder interface {
Expand All @@ -95,9 +116,12 @@ type ApplicationCommandQueryBuilder interface {
}

type ApplicationCommandFunctions interface {
Get(commandId Snowflake) (*ApplicationCommand, error)
Commands() ([]*ApplicationCommand, error)
Delete(commandId Snowflake) error
Create(command *CreateApplicationCommand) error
Update(commandId Snowflake, command *UpdateApplicationCommand) error
BulkOverwrite(commands []*CreateApplicationCommand) error
}

type applicationCommandFunctions struct {
Expand All @@ -123,21 +147,67 @@ func applicationCommandFactory() interface{} {
return &ApplicationCommand{}
}

func (c *applicationCommandFunctions) Get(commandID Snowflake) (*ApplicationCommand, error) {
var endpoint string
if c.guildID == 0 {
endpoint = fmt.Sprintf("/applications/%d/commands/%d", c.applicationID(), commandID)
} else {
endpoint = fmt.Sprintf("/applications/%d/guilds/%d/commands/%d", c.applicationID(), c.guildID, commandID)
}

req := &httd.Request{
Endpoint: endpoint,
Method: http.MethodGet,
Ctx: c.ctx,
ContentType: httd.ContentTypeJSON,
}

r := c.client.newRESTRequest(req, c.flags)
r.factory = applicationCommandFactory

return getApplicationCommand(r.Execute)
}

func (c *applicationCommandFunctions) Commands() ([]*ApplicationCommand, error) {
var endpoint string
if c.guildID == 0 {
endpoint = fmt.Sprintf("/applications/%d/commands", c.applicationID())
} else {
endpoint = fmt.Sprintf("/applications/%d/guilds/%d/commands", c.applicationID(), c.guildID)
}

req := &httd.Request{
Endpoint: endpoint,
Method: http.MethodGet,
Ctx: c.ctx,
ContentType: httd.ContentTypeJSON,
}

r := c.client.newRESTRequest(req, c.flags)
r.factory = func() interface{} {
tmp := make([]*ApplicationCommand, 0)
return &tmp
}

return getApplicationCommands(r.Execute)
}

func (c *applicationCommandFunctions) Create(command *CreateApplicationCommand) error {
var endpoint string
if c.guildID == 0 {
endpoint = fmt.Sprintf("/applications/%d/commands", c.applicationID())
} else {
endpoint = fmt.Sprintf("/applications/%d/guilds/%d/commands", c.applicationID(), c.guildID)
}
ctx := c.ctx

req := &httd.Request{
Endpoint: endpoint,
Method: http.MethodPost,
Body: command,
Ctx: ctx,
Ctx: c.ctx,
ContentType: httd.ContentTypeJSON,
}

r := c.client.newRESTRequest(req, c.flags)
r.factory = applicationCommandFactory
_, err := r.Execute()
Expand All @@ -146,20 +216,21 @@ func (c *applicationCommandFunctions) Create(command *CreateApplicationCommand)

func (c *applicationCommandFunctions) Update(commandID Snowflake, command *UpdateApplicationCommand) error {
var endpoint string
ctx := c.ctx

if c.guildID == 0 {
endpoint = fmt.Sprintf("applications/%d/commands/%d", c.applicationID(), commandID)
endpoint = fmt.Sprintf("/applications/%d/commands/%d", c.applicationID(), commandID)
} else {
endpoint = fmt.Sprintf("applications/%d/guilds/%d/commands/%d", c.applicationID(), c.guildID, commandID)
endpoint = fmt.Sprintf("/applications/%d/guilds/%d/commands/%d", c.applicationID(), c.guildID, commandID)
}

req := &httd.Request{
Endpoint: endpoint,
Method: http.MethodPatch,
Body: command,
Ctx: ctx,
Ctx: c.ctx,
ContentType: httd.ContentTypeJSON,
}

r := c.client.newRESTRequest(req, c.flags)
r.factory = applicationCommandFactory
_, err := r.Execute()
Expand All @@ -168,25 +239,51 @@ func (c *applicationCommandFunctions) Update(commandID Snowflake, command *Updat

func (c *applicationCommandFunctions) Delete(commandID Snowflake) error {
var endpoint string
ctx := c.ctx

if c.guildID == 0 {
endpoint = fmt.Sprintf("applications/%d/commands/%d", c.applicationID(), commandID)
endpoint = fmt.Sprintf("/applications/%d/commands/%d", c.applicationID(), commandID)
} else {
endpoint = fmt.Sprintf("applications/%d/guilds/%d/commands/%d", c.applicationID(), c.guildID, commandID)
endpoint = fmt.Sprintf("/applications/%d/guilds/%d/commands/%d", c.applicationID(), c.guildID, commandID)
}

req := &httd.Request{
Endpoint: endpoint,
Method: http.MethodDelete,
Ctx: ctx,
Ctx: c.ctx,
ContentType: httd.ContentTypeJSON,
}

r := c.client.newRESTRequest(req, c.flags)
r.factory = applicationCommandFactory
_, err := r.Execute()
return err
}

func (c *applicationCommandFunctions) BulkOverwrite(commands []*CreateApplicationCommand) error {
var endpoint string
if c.guildID == 0 {
endpoint = fmt.Sprintf("/applications/%d/commands", c.applicationID())
} else {
endpoint = fmt.Sprintf("/applications/%d/guilds/%d/commands", c.applicationID(), c.guildID)
}

req := &httd.Request{
Endpoint: endpoint,
Method: http.MethodPut,
Body: commands,
Ctx: c.ctx,
ContentType: httd.ContentTypeJSON,
}

r := c.client.newRESTRequest(req, c.flags)
r.factory = func() interface{} {
tmp := make([]*ApplicationCommand, 0)
return &tmp
}
_, err := r.Execute()
return err
}

type applicationCommandQueryBuilder struct {
ctx context.Context
client *Client
Expand All @@ -197,6 +294,7 @@ type applicationCommandQueryBuilder struct {
func (q applicationCommandQueryBuilder) Guild(guildId Snowflake) ApplicationCommandFunctions {
return &applicationCommandFunctions{appID: q.appID, ctx: q.ctx, guildID: guildId, client: q.client, flags: q.flags}
}

func (q applicationCommandQueryBuilder) Global() ApplicationCommandFunctions {
return &applicationCommandFunctions{appID: q.appID, ctx: q.ctx, client: q.client, flags: q.flags}
}
Expand Down
63 changes: 45 additions & 18 deletions rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ type AvatarParamHolder interface {

type urlQuery map[string]interface{}

var _ URLQueryStringer = (*urlQuery)(nil)
var _ fmt.Stringer = (*urlQuery)(nil)
var (
_ URLQueryStringer = (*urlQuery)(nil)
_ fmt.Stringer = (*urlQuery)(nil)
)

func (p urlQuery) String() string {
return p.URLQueryString()
Expand All @@ -60,22 +62,24 @@ func (p urlQuery) URLQueryString() string {
return ""
}

type restStepDoRequest func() (resp *http.Response, body []byte, err error)
type rest struct {
c *Client
flags Flag // merge flags
httpMethod string
type (
restStepDoRequest func() (resp *http.Response, body []byte, err error)
rest struct {
c *Client
flags Flag // merge flags
httpMethod string

// item creation
// pool is prioritized over factory
pool Pool
factory func() interface{}
// item creation
// pool is prioritized over factory
pool Pool
factory func() interface{}

conf *httd.Request
conf *httd.Request

// steps
doRequest restStepDoRequest
}
// steps
doRequest restStepDoRequest
}
)

func (r *rest) Put(x interface{}) {
if r.pool != nil {
Expand Down Expand Up @@ -168,9 +172,11 @@ func (r *rest) Execute() (v interface{}, err error) {
return obj, nil
}

type fRESTRequestMiddleware func(resp *http.Response, body []byte, err error) error
type fRESTCacheMiddleware func(resp *http.Response, v interface{}, err error) error
type fRESTItemFactory func() interface{}
type (
fRESTRequestMiddleware func(resp *http.Response, body []byte, err error) error
fRESTCacheMiddleware func(resp *http.Response, v interface{}, err error) error
fRESTItemFactory func() interface{}
)

type RESTBuilder struct {
middleware fRESTRequestMiddleware
Expand Down Expand Up @@ -846,3 +852,24 @@ func getScheduledEventUsers(f func() (interface{}, error)) (scheduledEventUsers

return nil, err
}

func getApplicationCommand(f func() (interface{}, error)) (command *ApplicationCommand, err error) {
var v interface{}
if v, err = exec(f); err != nil {
return nil, err
}
return v.(*ApplicationCommand), nil
}

func getApplicationCommands(f func() (interface{}, error)) (command []*ApplicationCommand, err error) {
var v interface{}
if v, err = exec(f); err != nil {
return nil, err
}
if list, ok := v.(*[]*ApplicationCommand); ok {
return *list, nil
} else if list, ok := v.([]*ApplicationCommand); ok {
return list, nil
}
panic("v was not assumed type. Got " + fmt.Sprint(v))
}