diff --git a/api/channels.go b/api/channels.go index 29e473ce..cd9f0149 100644 --- a/api/channels.go +++ b/api/channels.go @@ -45,13 +45,13 @@ type MessageChannel struct { } // SendMessage sends a Message to a TextChannel -func (c MessageChannel) SendMessage(message MessageCreate) (*Message, error) { +func (c MessageChannel) SendMessage(message *MessageCreate) (*Message, error) { // Todo: attachments return c.Disgo.RestClient().SendMessage(c.ID, message) } // EditMessage edits a Message in this TextChannel -func (c MessageChannel) EditMessage(messageID Snowflake, message MessageUpdate) (*Message, error) { +func (c MessageChannel) EditMessage(messageID Snowflake, message *MessageUpdate) (*Message, error) { return c.Disgo.RestClient().EditMessage(c.ID, messageID, message) } diff --git a/api/command.go b/api/command.go index 7af7885c..773d01e8 100644 --- a/api/command.go +++ b/api/command.go @@ -13,7 +13,7 @@ type Command struct { ApplicationID Snowflake `json:"application_id,omitempty"` Name string `json:"name"` Description string `json:"description"` - DefaultPermission bool `json:"default_permission"` + DefaultPermission *bool `json:"default_permission,omitempty"` Options []*CommandOption `json:"options,omitempty"` } @@ -30,26 +30,6 @@ func (c Command) FromGuild() bool { return c.GuildID == nil } -// Create creates the Command either as global or guild Command depending on if GuildID is set -func (c *Command) Create() error { - if c.Disgo == nil { - return errNoDisgoInstance - } - var rC *Command - var err error - if c.GuildID == nil { - rC, err = c.Disgo.RestClient().CreateGlobalCommand(c.Disgo.ApplicationID(), *c) - - } else { - rC, err = c.Disgo.RestClient().CreateGuildCommand(c.Disgo.ApplicationID(), *c.GuildID, *c) - } - if err != nil { - return err - } - *c = *rC - return nil -} - // Fetch updates/fetches the current Command from discord func (c *Command) Fetch() error { if c.Disgo == nil { @@ -71,7 +51,7 @@ func (c *Command) Fetch() error { } // Update updates the current Command with the given fields -func (c *Command) Update(command UpdateCommand) error { +func (c *Command) Update(command *CommandUpdate) error { if c.Disgo == nil { return errNoDisgoInstance } @@ -91,8 +71,8 @@ func (c *Command) Update(command UpdateCommand) error { } // SetPermissions sets the GuildCommandPermissions for a specific Guild. this overrides all existing CommandPermission(s). thx discord for that -func (c *Command) SetPermissions(guildID Snowflake, permissions ...CommandPermission) error { - _, err := c.Disgo.RestClient().SetGuildCommandPermissions(c.Disgo.ApplicationID(), guildID, c.ID, SetGuildCommandPermissions{Permissions: permissions}) +func (c *Command) SetPermissions(guildID Snowflake, permissions ...*CommandPermission) error { + _, err := c.Disgo.RestClient().SetGuildCommandPermissions(c.Disgo.ApplicationID(), guildID, c.ID, &SetGuildCommandPermissions{Permissions: permissions}) if err != nil { return err } @@ -146,8 +126,8 @@ type CommandOption struct { Name string `json:"name"` Description string `json:"description"` Required bool `json:"required,omitempty"` - Choices []OptionChoice `json:"choices,omitempty"` - Options []CommandOption `json:"options,omitempty"` + Choices []*OptionChoice `json:"choices,omitempty"` + Options []*CommandOption `json:"options,omitempty"` } // OptionChoice contains the data for a user using your command @@ -159,10 +139,10 @@ type OptionChoice struct { // GuildCommandPermissions holds all permissions for a Command type GuildCommandPermissions struct { Disgo Disgo - ID Snowflake `json:"id"` - ApplicationID Snowflake `json:"application_id"` - GuildID Snowflake `json:"guild_id"` - Permissions []CommandPermission `json:"permissions"` + ID Snowflake `json:"id"` + ApplicationID Snowflake `json:"application_id"` + GuildID Snowflake `json:"guild_id"` + Permissions []*CommandPermission `json:"permissions"` } // TODO: add methods to update those @@ -184,16 +164,24 @@ type CommandPermission struct { } // SetGuildCommandsPermissions holds a slice of SetGuildCommandPermissions -type SetGuildCommandsPermissions []SetGuildCommandPermissions +type SetGuildCommandsPermissions []*SetGuildCommandPermissions // SetGuildCommandPermissions is used to update CommandPermission ID should be omitted fro bulk update type SetGuildCommandPermissions struct { - ID Snowflake `json:"id,omitempty"` - Permissions []CommandPermission `json:"permissions"` + ID Snowflake `json:"id,omitempty"` + Permissions []*CommandPermission `json:"permissions"` +} + +// CommandCreate is used to create an Command. all fields are optional +type CommandCreate struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + DefaultPermission *bool `json:"default_permission,omitempty"` + Options []*CommandOption `json:"options,omitempty"` } -// UpdateCommand is used to update an existing Command. all fields are optional -type UpdateCommand struct { +// CommandUpdate is used to update an existing Command. all fields are optional +type CommandUpdate struct { Name *string `json:"name,omitempty"` Description *string `json:"description,omitempty"` DefaultPermission *bool `json:"default_permission,omitempty"` diff --git a/api/disgo.go b/api/disgo.go index 90112a94..7730a960 100644 --- a/api/disgo.go +++ b/api/disgo.go @@ -6,7 +6,6 @@ import ( "strings" "time" - "github.com/DisgoOrg/disgo/api/endpoints" "github.com/DisgoOrg/log" ) @@ -16,7 +15,7 @@ type Disgo interface { Connect() error Start() Close() - Token() endpoints.Token + Token() string Gateway() Gateway RestClient() RestClient WebhookServer() WebhookServer @@ -36,10 +35,10 @@ type Disgo interface { GetCommand(commandID Snowflake) (*Command, error) GetCommands() ([]*Command, error) - CreateCommand(command Command) (*Command, error) - EditCommand(commandID Snowflake, command UpdateCommand) (*Command, error) - DeleteCommand(command Command) (*Command, error) - SetCommands(commands ...Command) ([]*Command, error) + CreateCommand(command *CommandCreate) (*Command, error) + EditCommand(commandID Snowflake, command *CommandUpdate) (*Command, error) + DeleteCommand(commandID Snowflake) error + SetCommands(commands ...*CommandCreate) ([]*Command, error) } // EventHandler provides info about the EventHandler diff --git a/api/disgo_builder.go b/api/disgo_builder.go index c38245a0..5469f2e7 100644 --- a/api/disgo_builder.go +++ b/api/disgo_builder.go @@ -1,15 +1,16 @@ package api import ( - "github.com/DisgoOrg/log" + "net/http" - "github.com/DisgoOrg/disgo/api/endpoints" + "github.com/DisgoOrg/log" ) // DisgoBuilder allows you to create a Disgo client through a series of methods type DisgoBuilder interface { SetLogger(level log.Logger) DisgoBuilder - SetToken(token endpoints.Token) DisgoBuilder + SetToken(token string) DisgoBuilder + SetHTTPClient(httpClient *http.Client) DisgoBuilder SetIntents(intents Intents) DisgoBuilder SetRawGatewayEventsEnabled(enabled bool) DisgoBuilder SetVoiceDispatchInterceptor(voiceDispatchInterceptor VoiceDispatchInterceptor) DisgoBuilder diff --git a/api/embed.go b/api/embed.go index d1238ff9..f591b0d8 100644 --- a/api/embed.go +++ b/api/embed.go @@ -1,7 +1,6 @@ package api import ( - "fmt" "time" ) @@ -35,13 +34,6 @@ type Embed struct { Fields []*EmbedField `json:"fields,omitempty"` } -// The EmbedFooter of an Embed -type EmbedFooter struct { - Text string `json:"text"` - IconURL *string `json:"icon_url,omitempty"` - ProxyIconURL *string `json:"proxy_icon_url,omitempty"` -} - // The EmbedResource of an Embed.Image/Embed.Thumbnail/Embed.Video type EmbedResource struct { URL *string `json:"url,omitempty"` @@ -64,152 +56,16 @@ type EmbedAuthor struct { ProxyIconURL *string `json:"proxy_icon_url,omitempty"` } +// The EmbedFooter of an Embed +type EmbedFooter struct { + Text string `json:"text"` + IconURL *string `json:"icon_url,omitempty"` + ProxyIconURL *string `json:"proxy_icon_url,omitempty"` +} + // EmbedField (s) of an Embed type EmbedField struct { Name string `json:"name"` Value string `json:"value"` Inline *bool `json:"inline,omitempty"` } - -// NewEmbedBuilder returns a new embed builder -func NewEmbedBuilder() *EmbedBuilder { - return &EmbedBuilder{} -} - -// EmbedBuilder allows you to create embeds and use methods to set values -type EmbedBuilder struct { - Embed -} - -// SetTitle sets the title of the EmbedBuilder -func (b *EmbedBuilder) SetTitle(title string) *EmbedBuilder { - b.Title = &title - return b -} - -// SetDescription sets the description of the EmbedBuilder -func (b *EmbedBuilder) SetDescription(description string) *EmbedBuilder { - b.Description = &description - return b -} - -// SetDescriptionf sets the description of the EmbedBuilder with format -func (b *EmbedBuilder) SetDescriptionf(description string, a ...interface{}) *EmbedBuilder { - descriptionf := fmt.Sprintf(description, a...) - b.Description = &descriptionf - return b -} - -// SetEmbedAuthor sets the author of the EmbedBuilder using an EmbedAuthor struct -func (b *EmbedBuilder) SetEmbedAuthor(author *EmbedAuthor) *EmbedBuilder { - b.Author = author - return b -} - -// SetAuthor sets the author of the EmbedBuilder without an Icon URL -func (b *EmbedBuilder) SetAuthor(name string, url string) *EmbedBuilder { - b.Author = &EmbedAuthor{ - Name: &name, - URL: &url, - } - return b -} - -// SetAuthorI sets the author of the EmbedBuilder with all properties -func (b *EmbedBuilder) SetAuthorI(name string, url string, iconURL string) *EmbedBuilder { - b.Author = &EmbedAuthor{ - Name: &name, - URL: &url, - IconURL: &iconURL, - } - return b -} - -// SetColor sets the color of the EmbedBuilder -func (b *EmbedBuilder) SetColor(color int) *EmbedBuilder { - b.Color = &color - return b -} - -// SetFooter sets the footer of the EmbedBuilder -func (b *EmbedBuilder) SetFooter(footer *EmbedFooter) *EmbedBuilder { - b.Footer = footer - return b -} - -// SetFooterBy sets the footer of the EmbedBuilder by text and iconURL -func (b *EmbedBuilder) SetFooterBy(text string, iconURL *string) *EmbedBuilder { - b.Footer = &EmbedFooter{ - Text: text, - IconURL: iconURL, - } - return b -} - -// SetImage sets the image of the EmbedBuilder -func (b *EmbedBuilder) SetImage(i *string) *EmbedBuilder { - b.Image = &EmbedResource{ - URL: i, - } - return b -} - -// SetThumbnail sets the thumbnail of the EmbedBuilder -func (b *EmbedBuilder) SetThumbnail(i *string) *EmbedBuilder { - b.Thumbnail = &EmbedResource{ - URL: i, - } - return b -} - -// SetURL sets the URL of the EmbedBuilder -func (b *EmbedBuilder) SetURL(url string) *EmbedBuilder { - b.URL = &url - return b -} - -// AddField adds a field to the EmbedBuilder by name and value -func (b *EmbedBuilder) AddField(name string, value string, inline bool) *EmbedBuilder { - b.Fields = append(b.Fields, &EmbedField{name, value, &inline}) - return b -} - -// SetField sets a field to the EmbedBuilder by name and value -func (b *EmbedBuilder) SetField(index int, name string, value string, inline bool) *EmbedBuilder { - if len(b.Fields) > index { - b.Fields[index] = &EmbedField{name, value, &inline} - } - return b -} - -// AddFields adds multiple fields to the EmbedBuilder -func (b *EmbedBuilder) AddFields(f *EmbedField, fs ...*EmbedField) *EmbedBuilder { - b.Fields = append(b.Fields, f) - b.Fields = append(b.Fields, fs...) - return b -} - -// SetFields sets fields of the EmbedBuilder -func (b *EmbedBuilder) SetFields(fs ...*EmbedField) *EmbedBuilder { - b.Fields = fs - return b -} - -// ClearFields removes all of the fields from the EmbedBuilder -func (b *EmbedBuilder) ClearFields() *EmbedBuilder { - b.Fields = []*EmbedField{} - return b -} - -// RemoveField removes a field from the EmbedBuilder -func (b *EmbedBuilder) RemoveField(index int) *EmbedBuilder { - if len(b.Fields) > index { - b.Fields = append(b.Fields[:index], b.Fields[index+1:]...) - } - return b -} - -// Build returns your built Embed -func (b *EmbedBuilder) Build() Embed { - return b.Embed -} diff --git a/api/embed_builder.go b/api/embed_builder.go new file mode 100644 index 00000000..c2e445d5 --- /dev/null +++ b/api/embed_builder.go @@ -0,0 +1,191 @@ +package api + +import "fmt" + +// NewEmbedBuilder returns a new embed builder +func NewEmbedBuilder() *EmbedBuilder { + return &EmbedBuilder{} +} + +// EmbedBuilder allows you to create embeds and use methods to set values +type EmbedBuilder struct { + Embed +} + +// SetTitle sets the title of the EmbedBuilder +func (b *EmbedBuilder) SetTitle(title string) *EmbedBuilder { + b.Title = &title + return b +} + +// SetTitlef sets the title of the EmbedBuilder with format +func (b *EmbedBuilder) SetTitlef(title string, a ...interface{}) *EmbedBuilder { + b.Title = &title + return b +} + +// SetDescription sets the description of the EmbedBuilder +func (b *EmbedBuilder) SetDescription(description string) *EmbedBuilder { + b.Description = &description + return b +} + +// SetDescriptionf sets the description of the EmbedBuilder with format +func (b *EmbedBuilder) SetDescriptionf(description string, a ...interface{}) *EmbedBuilder { + descriptionf := fmt.Sprintf(description, a...) + b.Description = &descriptionf + return b +} + +// SetEmbedAuthor sets the author of the EmbedBuilder using an EmbedAuthor struct +func (b *EmbedBuilder) SetEmbedAuthor(author *EmbedAuthor) *EmbedBuilder { + b.Author = author + return b +} + +// SetAuthor sets the author of the EmbedBuilder without an Icon URL +func (b *EmbedBuilder) SetAuthor(name string, url string, iconURL string) *EmbedBuilder { + if b.Author == nil { + b.Author = &EmbedAuthor{} + } + b.Author.Name = &name + b.Author.URL = &url + b.Author.IconURL = &iconURL + return b +} + +// SetAuthorName sets the author of the EmbedBuilder +func (b *EmbedBuilder) SetAuthorName(name string) *EmbedBuilder { + if b.Author == nil { + b.Author = &EmbedAuthor{} + } + b.Author.Name = &name + return b +} + +// SetAuthorURL sets the author of the EmbedBuilder with an URL +func (b *EmbedBuilder) SetAuthorURL(url string) *EmbedBuilder { + if b.Author == nil { + b.Author = &EmbedAuthor{} + } + b.Author.URL = &url + return b +} + +// SetAuthorIcon sets the author of the EmbedBuilder with all properties +func (b *EmbedBuilder) SetAuthorIcon(iconURL string) *EmbedBuilder { + if b.Author == nil { + b.Author = &EmbedAuthor{} + } + b.Author.IconURL = &iconURL + return b +} + +// SetColor sets the color of the EmbedBuilder +func (b *EmbedBuilder) SetColor(color int) *EmbedBuilder { + b.Color = &color + return b +} + +// SetEmbedFooter sets the footer of the EmbedBuilder +func (b *EmbedBuilder) SetEmbedFooter(footer *EmbedFooter) *EmbedBuilder { + b.Footer = footer + return b +} + +// SetFooter sets the footer of the EmbedBuilder +func (b *EmbedBuilder) SetFooter(text string, iconURL string) *EmbedBuilder { + if b.Footer == nil { + b.Footer = &EmbedFooter{} + } + b.Footer.Text = text + b.Footer.IconURL = &iconURL + return b +} + +// SetFooterText sets the footer of the EmbedBuilder by text +func (b *EmbedBuilder) SetFooterText(text string) *EmbedBuilder { + if b.Footer == nil { + b.Footer = &EmbedFooter{} + } + b.Footer.Text = text + return b +} + +// SetFooterIcon sets the footer of the EmbedBuilder by iconURL +func (b *EmbedBuilder) SetFooterIcon(iconURL string) *EmbedBuilder { + if b.Footer == nil { + b.Footer = &EmbedFooter{} + } + b.Footer.IconURL = &iconURL + return b +} + +// SetImage sets the image of the EmbedBuilder +func (b *EmbedBuilder) SetImage(url string) *EmbedBuilder { + if b.Image == nil { + b.Image = &EmbedResource{} + } + b.Image.URL = &url + return b +} + +// SetThumbnail sets the thumbnail of the EmbedBuilder +func (b *EmbedBuilder) SetThumbnail(url string) *EmbedBuilder { + if b.Thumbnail == nil { + b.Thumbnail = &EmbedResource{} + } + b.Thumbnail.URL = &url + return b +} + +// SetURL sets the URL of the EmbedBuilder +func (b *EmbedBuilder) SetURL(url string) *EmbedBuilder { + b.URL = &url + return b +} + +// AddField adds a field to the EmbedBuilder by name and value +func (b *EmbedBuilder) AddField(name string, value string, inline bool) *EmbedBuilder { + b.Fields = append(b.Fields, &EmbedField{name, value, &inline}) + return b +} + +// SetField sets a field to the EmbedBuilder by name and value +func (b *EmbedBuilder) SetField(i int, name string, value string, inline bool) *EmbedBuilder { + if len(b.Fields) > i { + b.Fields[i] = &EmbedField{name, value, &inline} + } + return b +} + +// AddFields adds multiple fields to the EmbedBuilder +func (b *EmbedBuilder) AddFields(field *EmbedField, fields ...*EmbedField) *EmbedBuilder { + b.Fields = append(append(b.Fields, field), fields...) + return b +} + +// SetFields sets fields of the EmbedBuilder +func (b *EmbedBuilder) SetFields(fields ...*EmbedField) *EmbedBuilder { + b.Fields = fields + return b +} + +// ClearFields removes all of the fields from the EmbedBuilder +func (b *EmbedBuilder) ClearFields() *EmbedBuilder { + b.Fields = []*EmbedField{} + return b +} + +// RemoveField removes a field from the EmbedBuilder +func (b *EmbedBuilder) RemoveField(i int) *EmbedBuilder { + if len(b.Fields) > i { + b.Fields = append(b.Fields[:i], b.Fields[i+1:]...) + } + return b +} + +// Build returns your built Embed +func (b *EmbedBuilder) Build() *Embed { + return &b.Embed +} diff --git a/api/endpoints/route.go b/api/endpoints/route.go index eb5b661d..771a8e58 100644 --- a/api/endpoints/route.go +++ b/api/endpoints/route.go @@ -24,13 +24,7 @@ func (r Route) Compile(args ...interface{}) (*CompiledRoute, error) { for _, arg := range args { start := strings.Index(route, "{") end := strings.Index(route, "}") - var value string - if t, ok := arg.(Token); ok { - value = string(t) - } else { - value = fmt.Sprint(arg) - } - route = route[:start] + value + route[end+1:] + route = route[:start] + fmt.Sprint(arg) + route[end+1:] } } diff --git a/api/endpoints/token.go b/api/endpoints/token.go deleted file mode 100644 index 29e23dc9..00000000 --- a/api/endpoints/token.go +++ /dev/null @@ -1,29 +0,0 @@ -package endpoints - -import ( - "strings" -) - -// Token holds a discord token and is used to keep your logs clean from critical information -type Token string - -// MarshalJSON makes sure we don#t send ********* to discords as tokens -func (t Token) MarshalJSON() ([]byte, error) { - return []byte("\"" + t + "\""), nil -} - -// UnmarshalJSON makes sure we parse tokens from discord correctly -func (t *Token) UnmarshalJSON(raw []byte) error { - *t = Token(strings.ReplaceAll(string(raw), "\"", "")) - return nil -} - -// String masks the token -func (t Token) String() string { - return strings.Repeat("*", len(t)) -} - -// GoString masks the token -func (t Token) GoString() string { - return t.String() -} diff --git a/api/entity_builder.go b/api/entity_builder.go index 7cded026..073b7711 100644 --- a/api/entity_builder.go +++ b/api/entity_builder.go @@ -15,6 +15,8 @@ var ( type EntityBuilder interface { Disgo() Disgo + CreateInteraction(interaction *Interaction, updateCache CacheStrategy) *Interaction + CreateGlobalCommand(command *Command, updateCache CacheStrategy) *Command CreateUser(user *User, updateCache CacheStrategy) *User @@ -26,7 +28,7 @@ type EntityBuilder interface { CreateGuildCommand(guildID Snowflake, command *Command, updateCache CacheStrategy) *Command CreateGuildCommandPermissions(guildCommandPermissions *GuildCommandPermissions, updateCache CacheStrategy) *GuildCommandPermissions CreateRole(guildID Snowflake, role *Role, updateCache CacheStrategy) *Role - CreateVoiceState(role *VoiceState, updateCache CacheStrategy) *VoiceState + CreateVoiceState(guildID Snowflake, voiceState *VoiceState, updateCache CacheStrategy) *VoiceState CreateTextChannel(channel *Channel, updateCache CacheStrategy) *TextChannel CreateVoiceChannel(channel *Channel, updateCache CacheStrategy) *VoiceChannel diff --git a/api/events/interaction_events.go b/api/events/interaction_events.go index fe691428..bc9611d3 100644 --- a/api/events/interaction_events.go +++ b/api/events/interaction_events.go @@ -55,7 +55,7 @@ func (e GenericInteractionEvent) GuildChannel() *api.GuildChannel { // SlashCommandEvent indicates that a slash api.Command was ran in a api.Guild type SlashCommandEvent struct { GenericInteractionEvent - ResponseChannel chan interface{} + ResponseChannel chan *api.InteractionResponse FromWebhook bool CommandID api.Snowflake CommandName string @@ -114,7 +114,7 @@ func (e *SlashCommandEvent) Acknowledge() error { } // Reply replies to the api.Interaction with the provided api.InteractionResponse -func (e *SlashCommandEvent) Reply(response api.InteractionResponse) error { +func (e *SlashCommandEvent) Reply(response *api.InteractionResponse) error { if e.Replied { return errors.New("you already replied to this interaction") } @@ -129,7 +129,7 @@ func (e *SlashCommandEvent) Reply(response api.InteractionResponse) error { } // EditOriginal edits the original api.InteractionResponse -func (e *SlashCommandEvent) EditOriginal(followupMessage api.FollowupMessage) (*api.Message, error) { +func (e *SlashCommandEvent) EditOriginal(followupMessage *api.FollowupMessage) (*api.Message, error) { return e.Disgo().RestClient().EditInteractionResponse(e.Disgo().ApplicationID(), e.Interaction.Token, followupMessage) } @@ -139,12 +139,12 @@ func (e *SlashCommandEvent) DeleteOriginal() error { } // SendFollowup used to send a api.FollowupMessage to an api.Interaction -func (e *SlashCommandEvent) SendFollowup(followupMessage api.FollowupMessage) (*api.Message, error) { +func (e *SlashCommandEvent) SendFollowup(followupMessage *api.FollowupMessage) (*api.Message, error) { return e.Disgo().RestClient().SendFollowupMessage(e.Disgo().ApplicationID(), e.Interaction.Token, followupMessage) } // EditFollowup used to edit a api.FollowupMessage from an api.Interaction -func (e *SlashCommandEvent) EditFollowup(messageID api.Snowflake, followupMessage api.FollowupMessage) (*api.Message, error) { +func (e *SlashCommandEvent) EditFollowup(messageID api.Snowflake, followupMessage *api.FollowupMessage) (*api.Message, error) { return e.Disgo().RestClient().EditFollowupMessage(e.Disgo().ApplicationID(), e.Interaction.Token, messageID, followupMessage) } diff --git a/api/gateway_commands.go b/api/gateway_commands.go index 792c5486..239a6963 100644 --- a/api/gateway_commands.go +++ b/api/gateway_commands.go @@ -1,7 +1,5 @@ package api -import "github.com/DisgoOrg/disgo/api/endpoints" - // NewGatewayCommand returns a new GatewayCommand struct with the given payload func NewGatewayCommand(op GatewayOp, d interface{}) GatewayCommand { return GatewayCommand{ @@ -22,7 +20,7 @@ type GatewayCommand struct { // IdentifyCommand is the data used in IdentifyCommand type IdentifyCommand struct { - Token endpoints.Token `json:"token"` + Token string `json:"token"` Properties IdentifyCommandDataProperties `json:"properties"` Compress bool `json:"compress,omitempty"` LargeThreshold int `json:"large_threshold,omitempty"` @@ -42,9 +40,9 @@ type IdentifyCommandDataProperties struct { // ResumeCommand is used to resume a connection to discord in the case that you are disconnected. Is automatically // handled by the library and should rarely be used. type ResumeCommand struct { - Token endpoints.Token `json:"token"` - SessionID string `json:"session_id"` - Seq int `json:"seq"` + Token string `json:"token"` + SessionID string `json:"session_id"` + Seq int `json:"seq"` } // HeartbeatCommand is used to ensure the websocket connection remains open, and disconnect if not. diff --git a/api/guild.go b/api/guild.go index 3e607f9a..393d9a83 100644 --- a/api/guild.go +++ b/api/guild.go @@ -177,12 +177,12 @@ func (g *Guild) Disconnect() error { } // CreateRole allows you to create a new Role -func (g *Guild) CreateRole(role UpdateRole) (*Role, error) { +func (g *Guild) CreateRole(role *UpdateRole) (*Role, error) { return g.Disgo.RestClient().CreateRole(g.ID, role) } // AddMember adds a member to the guild with the oauth2 access token -func (g *Guild) AddMember(userID Snowflake, addGuildMemberData AddGuildMemberData) (*Member, error) { +func (g *Guild) AddMember(userID Snowflake, addGuildMemberData *AddGuildMemberData) (*Member, error) { return g.Disgo.RestClient().AddMember(g.ID, userID, addGuildMemberData) } @@ -215,22 +215,22 @@ func (g *Guild) GetCommands() ([]*Command, error) { } // CreateCommand creates a new command for this guild -func (g *Guild) CreateCommand(command Command) (*Command, error) { +func (g *Guild) CreateCommand(command *CommandCreate) (*Command, error) { return g.Disgo.RestClient().CreateGuildCommand(g.Disgo.ApplicationID(), g.ID, command) } // EditCommand edits a specific guild command -func (g *Guild) EditCommand(commandID Snowflake, command UpdateCommand) (*Command, error) { +func (g *Guild) EditCommand(commandID Snowflake, command *CommandUpdate) (*Command, error) { return g.Disgo.RestClient().EditGuildCommand(g.Disgo.ApplicationID(), g.ID, commandID, command) } // DeleteCommand creates a new command for this guild -func (g *Guild) DeleteCommand(command Command) (*Command, error) { - return g.Disgo.RestClient().CreateGuildCommand(g.Disgo.ApplicationID(), g.ID, command) +func (g *Guild) DeleteCommand(commandID Snowflake) error { + return g.Disgo.RestClient().DeleteGuildCommand(g.Disgo.ApplicationID(), g.ID, commandID) } // SetCommands overrides all commands for this guild -func (g *Guild) SetCommands(commands ...Command) ([]*Command, error) { +func (g *Guild) SetCommands(commands ...*CommandCreate) ([]*Command, error) { return g.Disgo.RestClient().SetGuildCommands(g.Disgo.ApplicationID(), g.ID, commands...) } @@ -245,11 +245,11 @@ func (g *Guild) GetCommandPermissions(commandID Snowflake) (*GuildCommandPermiss } // SetCommandsPermissions sets the GuildCommandPermissions for a all Command(s) -func (g *Guild) SetCommandsPermissions(commandPermissions ...SetGuildCommandPermissions) ([]*GuildCommandPermissions, error) { +func (g *Guild) SetCommandsPermissions(commandPermissions ...*SetGuildCommandPermissions) ([]*GuildCommandPermissions, error) { return g.Disgo.RestClient().SetGuildCommandsPermissions(g.Disgo.ApplicationID(), g.ID, commandPermissions...) } // SetCommandPermissions sets the GuildCommandPermissions for a specific Command -func (g *Guild) SetCommandPermissions(commandID Snowflake, permissions SetGuildCommandPermissions) (*GuildCommandPermissions, error) { +func (g *Guild) SetCommandPermissions(commandID Snowflake, permissions *SetGuildCommandPermissions) (*GuildCommandPermissions, error) { return g.Disgo.RestClient().SetGuildCommandPermissions(g.Disgo.ApplicationID(), g.ID, commandID, permissions) } diff --git a/api/interaction.go b/api/interaction.go index 689c17e3..20cdbba4 100644 --- a/api/interaction.go +++ b/api/interaction.go @@ -1,7 +1,5 @@ package api -import "github.com/DisgoOrg/disgo/api/endpoints" - // InteractionType is the type of Interaction type InteractionType int @@ -20,7 +18,7 @@ type Interaction struct { ChannelID *Snowflake `json:"channel_id,omitempty"` Member *Member `json:"member,omitempty"` User *User `json:"User,omitempty"` - Token endpoints.Token `json:"token"` + Token string `json:"token"` Version int `json:"version"` } @@ -61,6 +59,11 @@ func (o Option) String() string { return o.Value.(string) } +// Integer returns the Option.Value as int +func (o Option) Integer() int { + return o.Value.(int) +} + // Bool returns the Option.Value as bool func (o Option) Bool() bool { return o.Value.(bool) diff --git a/api/interaction_followup.go b/api/interaction_followup.go index 2cd7bb7f..529d9f12 100644 --- a/api/interaction_followup.go +++ b/api/interaction_followup.go @@ -1,16 +1,14 @@ package api +import "fmt" + // FollowupMessage is used to add additional messages to an Interaction after you've responded initially type FollowupMessage struct { - Content string `json:"content,omitempty"` - Username string `json:"username,omitempty"` - AvatarURL string `json:"avatar_url,omitempty"` - TTS bool `json:"tts,omitempty"` - Embeds []Embed `json:"embeds,omitempty"` + Content *string `json:"content,omitempty"` + TTS *bool `json:"tts,omitempty"` + Embeds []*Embed `json:"embeds,omitempty"` AllowedMentions *AllowedMentions `json:"allowed_mentions,omitempty"` - Flags MessageFlags `json:"flags,omitempty"` - //PayloadJSON string `json:"payload_json"` - //File FileContents `json:"file"` + Flags *MessageFlags `json:"flags,omitempty"` } // FollowupMessageBuilder allows you to create an FollowupMessage with ease @@ -21,39 +19,46 @@ type FollowupMessageBuilder struct { // NewFollowupMessageBuilder returns a new FollowupMessageBuilder func NewFollowupMessageBuilder() *FollowupMessageBuilder { return &FollowupMessageBuilder{ - FollowupMessage{}, + FollowupMessage{ + AllowedMentions: &DefaultInteractionAllowedMentions, + }, } } // SetTTS sets if the FollowupMessage is a tts message func (b *FollowupMessageBuilder) SetTTS(tts bool) *FollowupMessageBuilder { - b.TTS = tts + b.TTS = &tts return b } // SetContent sets the content of the FollowupMessage func (b *FollowupMessageBuilder) SetContent(content string) *FollowupMessageBuilder { - b.Content = content + b.Content = &content + return b +} + +// SetContentf sets the content of the FollowupMessage with format +func (b *FollowupMessageBuilder) SetContentf(content string, a ...interface{}) *FollowupMessageBuilder { + contentf := fmt.Sprintf(content, a...) + b.Content = &contentf return b } // SetEmbeds sets the embeds of the FollowupMessage -func (b *FollowupMessageBuilder) SetEmbeds(embeds ...Embed) *FollowupMessageBuilder { +func (b *FollowupMessageBuilder) SetEmbeds(embeds ...*Embed) *FollowupMessageBuilder { b.Embeds = embeds return b } // AddEmbeds adds multiple embeds to the FollowupMessage -func (b *FollowupMessageBuilder) AddEmbeds(embeds ...Embed) *FollowupMessageBuilder { +func (b *FollowupMessageBuilder) AddEmbeds(embeds ...*Embed) *FollowupMessageBuilder { b.Embeds = append(b.Embeds, embeds...) return b } // ClearEmbeds removes all of the embeds from the FollowupMessage func (b *FollowupMessageBuilder) ClearEmbeds() *FollowupMessageBuilder { - if b.Embeds != nil { - b.Embeds = []Embed{} - } + b.Embeds = []*Embed{} return b } @@ -78,7 +83,7 @@ func (b *FollowupMessageBuilder) SetAllowedMentionsEmpty() *FollowupMessageBuild // SetFlags sets the message flags of the FollowupMessage func (b *FollowupMessageBuilder) SetFlags(flags MessageFlags) *FollowupMessageBuilder { - b.Flags = flags + b.Flags = &flags return b } @@ -97,6 +102,6 @@ func (b *FollowupMessageBuilder) SetEphemeral(ephemeral bool) *FollowupMessageBu } // Build returns your built FollowupMessage -func (b *FollowupMessageBuilder) Build() FollowupMessage { - return b.FollowupMessage +func (b *FollowupMessageBuilder) Build() *FollowupMessage { + return &b.FollowupMessage } diff --git a/api/interaction_response.go b/api/interaction_response.go index 02546ac3..4df2f0dd 100644 --- a/api/interaction_response.go +++ b/api/interaction_response.go @@ -1,5 +1,7 @@ package api +import "fmt" + // InteractionResponseType indicates the type of slash command response, whether it's responding immediately or deferring to edit your response later type InteractionResponseType int @@ -20,11 +22,11 @@ type InteractionResponse struct { // The InteractionResponseData is used to specify the message_events options when creating an InteractionResponse type InteractionResponseData struct { - TTS bool `json:"tts,omitempty"` - Content string `json:"content,omitempty"` - Embeds []Embed `json:"embeds,omitempty"` + TTS *bool `json:"tts,omitempty"` + Content *string `json:"content,omitempty"` + Embeds []*Embed `json:"embeds,omitempty"` AllowedMentions *AllowedMentions `json:"allowed_mentions,omitempty"` - Flags MessageFlags `json:"flags,omitempty"` + Flags *MessageFlags `json:"flags,omitempty"` } // InteractionResponseBuilder allows you to create an InteractionResponse with ease @@ -61,7 +63,7 @@ func (b *InteractionResponseBuilder) SetTTS(tts bool) *InteractionResponseBuilde if b.Data == nil { b.Data = &InteractionResponseData{} } - b.Data.TTS = tts + b.Data.TTS = &tts return b } @@ -70,12 +72,22 @@ func (b *InteractionResponseBuilder) SetContent(content string) *InteractionResp if b.Data == nil { b.Data = &InteractionResponseData{} } - b.Data.Content = content + b.Data.Content = &content + return b +} + +// SetContentf sets the content of the InteractionResponse with format +func (b *InteractionResponseBuilder) SetContentf(content string, a ...interface{}) *InteractionResponseBuilder { + if b.Data == nil { + b.Data = &InteractionResponseData{} + } + contentf := fmt.Sprintf(content, a...) + b.Data.Content = &contentf return b } // SetEmbeds sets the embeds of the InteractionResponse -func (b *InteractionResponseBuilder) SetEmbeds(embeds ...Embed) *InteractionResponseBuilder { +func (b *InteractionResponseBuilder) SetEmbeds(embeds ...*Embed) *InteractionResponseBuilder { if b.Data == nil { b.Data = &InteractionResponseData{} } @@ -84,7 +96,7 @@ func (b *InteractionResponseBuilder) SetEmbeds(embeds ...Embed) *InteractionResp } // AddEmbeds adds multiple embeds to the InteractionResponse -func (b *InteractionResponseBuilder) AddEmbeds(embeds ...Embed) *InteractionResponseBuilder { +func (b *InteractionResponseBuilder) AddEmbeds(embeds ...*Embed) *InteractionResponseBuilder { if b.Data == nil { b.Data = &InteractionResponseData{} } @@ -94,16 +106,16 @@ func (b *InteractionResponseBuilder) AddEmbeds(embeds ...Embed) *InteractionResp // ClearEmbeds removes all of the embeds from the InteractionResponse func (b *InteractionResponseBuilder) ClearEmbeds() *InteractionResponseBuilder { - if b.Data != nil && b.Data.Embeds != nil { - b.Data.Embeds = []Embed{} + if b.Data != nil { + b.Data.Embeds = []*Embed{} } return b } // RemoveEmbed removes an embed from the InteractionResponse -func (b *InteractionResponseBuilder) RemoveEmbed(index int) *InteractionResponseBuilder { - if b.Data != nil && len(b.Data.Embeds) > index { - b.Data.Embeds = append(b.Data.Embeds[:index], b.Data.Embeds[index+1:]...) +func (b *InteractionResponseBuilder) RemoveEmbed(i int) *InteractionResponseBuilder { + if b.Data != nil && len(b.Data.Embeds) > i { + b.Data.Embeds = append(b.Data.Embeds[:i], b.Data.Embeds[i+1:]...) } return b } @@ -127,7 +139,7 @@ func (b *InteractionResponseBuilder) SetFlags(flags MessageFlags) *InteractionRe if b.Data == nil { b.Data = &InteractionResponseData{} } - b.Data.Flags = flags + b.Data.Flags = &flags return b } @@ -149,6 +161,6 @@ func (b *InteractionResponseBuilder) SetEphemeral(ephemeral bool) *InteractionRe } // Build returns your built InteractionResponse -func (b *InteractionResponseBuilder) Build() InteractionResponse { - return b.InteractionResponse +func (b *InteractionResponseBuilder) Build() *InteractionResponse { + return &b.InteractionResponse } diff --git a/api/member.go b/api/member.go index f74f566d..a5ef98e1 100644 --- a/api/member.go +++ b/api/member.go @@ -17,6 +17,19 @@ type Member struct { Permissions *Permissions `json:"permissions,omitempty"` } +// VoiceState returns the VoiceState for this Member from the Cache(requires CacheFlagVoiceState and IntentsGuildVoiceStates) +func (m Member) VoiceState() *VoiceState { + return m.Disgo.Cache().VoiceState(m.GuildID, m.User.ID) +} + +// EffectiveName returns either the nickname or username depending on if the user has a nickname +func (m Member) EffectiveName() string { + if m.Nick != nil { + return *m.Nick + } + return m.User.Username +} + // Guild returns the members guild from the cache func (m Member) Guild() *Guild { return m.Disgo.Cache().Guild(m.GuildID) @@ -28,7 +41,7 @@ func (m Member) IsOwner() bool { } // Update updates the member -func (m Member) Update(updateGuildMemberData UpdateGuildMemberData) (*Member, error) { +func (m Member) Update(updateGuildMemberData *UpdateGuildMemberData) (*Member, error) { return m.Disgo.RestClient().UpdateMember(m.GuildID, m.User.ID, updateGuildMemberData) } diff --git a/api/message.go b/api/message.go index 22bb05de..ad5906f9 100644 --- a/api/message.go +++ b/api/message.go @@ -37,23 +37,23 @@ const ( type MessageFlags int64 // Add allows you to add multiple bits together, producing a new bit -func (f MessageFlags) Add(bits ...MessageFlags) MessageFlags { +func (f MessageFlags) Add(bits ...MessageFlags) *MessageFlags { total := MessageFlags(0) for _, bit := range bits { total |= bit } f |= total - return f + return &f } // Remove allows you to subtract multiple bits from the first, producing a new bit -func (f MessageFlags) Remove(bits ...MessageFlags) MessageFlags { +func (f MessageFlags) Remove(bits ...MessageFlags) *MessageFlags { total := MessageFlags(0) for _, bit := range bits { total |= bit } f &^= total - return f + return &f } // HasAll will ensure that the bit includes all of the bits entered @@ -206,7 +206,7 @@ type MessageInteraction struct { } // Guild gets the guild_events the message_events was sent in -func (m Message) Guild() *Guild { +func (m *Message) Guild() *Guild { if m.GuildID == nil { return nil } @@ -214,32 +214,32 @@ func (m Message) Guild() *Guild { } // Channel gets the channel the message_events was sent in -func (m Message) Channel() *MessageChannel { +func (m *Message) Channel() *MessageChannel { return m.Disgo.Cache().MessageChannel(m.ChannelID) } // AddReactionByEmote allows you to add an Emote to a message_events via reaction -func (m Message) AddReactionByEmote(emote Emote) error { +func (m *Message) AddReactionByEmote(emote Emote) error { return m.AddReaction(emote.Reaction()) } // AddReaction allows you to add a reaction to a message_events from a string, for example a custom emoji ID, or a native emoji -func (m Message) AddReaction(emoji string) error { +func (m *Message) AddReaction(emoji string) error { return m.Disgo.RestClient().AddReaction(m.ChannelID, m.ID, emoji) } // Edit allows you to edit an existing Message sent by you -func (m Message) Edit(message MessageUpdate) (*Message, error) { +func (m *Message) Edit(message *MessageUpdate) (*Message, error) { return m.Disgo.RestClient().EditMessage(m.ChannelID, m.ID, message) } // Delete allows you to edit an existing Message sent by you -func (m Message) Delete() error { +func (m *Message) Delete() error { return m.Disgo.RestClient().DeleteMessage(m.ChannelID, m.ID) } // Crosspost crossposts an existing message -func (m Message) Crosspost() (*Message, error) { +func (m *Message) Crosspost() (*Message, error) { channel := m.Channel() if channel != nil && channel.Type != ChannelTypeNews { return nil, errors.New("channel type is not NEWS") @@ -248,7 +248,7 @@ func (m Message) Crosspost() (*Message, error) { } // Reply allows you to reply to an existing Message -func (m Message) Reply(message MessageCreate) (*Message, error) { +func (m *Message) Reply(message *MessageCreate) (*Message, error) { message.MessageReference = &MessageReference{ MessageID: &m.ID, } @@ -264,16 +264,16 @@ type MessageReaction struct { // MessageUpdate is used to edit a Message type MessageUpdate struct { - Content string `json:"content,omitempty"` + Content *string `json:"content,omitempty"` Embed *Embed `json:"embed,omitempty"` - Flags MessageFlags `json:"flags,omitempty"` + Flags *MessageFlags `json:"flags,omitempty"` AllowedMentions *AllowedMentions `json:"allowed_mentions,omitempty"` } // MessageCreate is the struct to create a new Message with type MessageCreate struct { - Content string `json:"content,omitempty"` - TTS bool `json:"tts,omitempty"` + Content *string `json:"content,omitempty"` + TTS *bool `json:"tts,omitempty"` Embed *Embed `json:"embed,omitempty"` AllowedMentions *AllowedMentions `json:"allowed_mentions,omitempty"` MessageReference *MessageReference `json:"message_reference,omitempty"` diff --git a/api/message_builder.go b/api/message_builder.go index 4a5616d7..2d28e544 100644 --- a/api/message_builder.go +++ b/api/message_builder.go @@ -1,5 +1,7 @@ package api +import "fmt" + // MessageBuilder helper to build Message(s) easier type MessageBuilder struct { MessageCreate @@ -14,15 +16,32 @@ func NewMessageBuilder() *MessageBuilder { } } +// NewMessageBuilderWithEmbed creates a new MessageBuilder with an Embed to be built later +func NewMessageBuilderWithEmbed(embed *Embed) *MessageBuilder { + return NewMessageBuilder().SetEmbed(embed) +} + +// NewMessageBuilderWithContent creates a new MessageBuilder with a content to be built later +func NewMessageBuilderWithContent(content string) *MessageBuilder { + return NewMessageBuilder().SetContent(content) +} + // SetContent sets content of the Message func (b *MessageBuilder) SetContent(content string) *MessageBuilder { - b.Content = content + b.Content = &content + return b +} + +// SetContentf sets content of the Message +func (b *MessageBuilder) SetContentf(content string, a ...interface{}) *MessageBuilder { + contentf := fmt.Sprintf(content, a...) + b.Content = &contentf return b } // SetTTS sets the text to speech of the Message func (b *MessageBuilder) SetTTS(tts bool) *MessageBuilder { - b.TTS = tts + b.TTS = &tts return b } @@ -38,8 +57,8 @@ func (b *MessageBuilder) SetAllowedMentions(allowedMentions *AllowedMentions) *M return b } -// SetAllowedMentionsEmpty sets the allowed mentions of the Message to nothing -func (b *MessageBuilder) SetAllowedMentionsEmpty() *MessageBuilder { +// ClearAllowedMentions clears the allowed mentions of the Message +func (b *MessageBuilder) ClearAllowedMentions() *MessageBuilder { return b.SetAllowedMentions(&AllowedMentions{}) } @@ -51,13 +70,14 @@ func (b *MessageBuilder) SetMessageReference(messageReference *MessageReference) // SetMessageReferenceByMessageID allows you to specify a Message ID to reply to func (b *MessageBuilder) SetMessageReferenceByMessageID(messageID Snowflake) *MessageBuilder { - b.MessageReference = &MessageReference{ - MessageID: &messageID, + if b.MessageReference == nil { + b.MessageReference = &MessageReference{} } + b.MessageReference.MessageID = &messageID return b } // Build builds the MessageBuilder to a MessageCreate struct -func (b *MessageBuilder) Build() MessageCreate { - return b.MessageCreate +func (b *MessageBuilder) Build() *MessageCreate { + return &b.MessageCreate } diff --git a/api/options.go b/api/options.go index 90da003c..22b01cdb 100644 --- a/api/options.go +++ b/api/options.go @@ -1,6 +1,10 @@ package api -import "github.com/DisgoOrg/log" +import ( + "net/http" + + "github.com/DisgoOrg/log" +) // Options is the configuration used when creating the client type Options struct { @@ -13,4 +17,5 @@ type Options struct { PublicKey string LargeThreshold int RawGatewayEventsEnabled bool + HTTPClient *http.Client } diff --git a/api/restclient.go b/api/restclient.go index 4eb40110..3eaba0d0 100644 --- a/api/restclient.go +++ b/api/restclient.go @@ -15,16 +15,22 @@ var ( ErrTooMuchApplicationCommands = errors.New("you can provide a max of 100 application commands") ) +// ErrorResponse contains custom errors from discord +type ErrorResponse struct { + Code int + Message string +} + // RestClient is a manager for all of disgo's HTTP requests type RestClient interface { Close() Disgo() Disgo UserAgent() string - Request(route endpoints.CompiledAPIRoute, rqBody interface{}, rsBody interface{}) error + Request(route *endpoints.CompiledAPIRoute, rqBody interface{}, rsBody interface{}) error - SendMessage(channelID Snowflake, message MessageCreate) (*Message, error) - EditMessage(channelID Snowflake, messageID Snowflake, message MessageUpdate) (*Message, error) + SendMessage(channelID Snowflake, message *MessageCreate) (*Message, error) + EditMessage(channelID Snowflake, messageID Snowflake, message *MessageUpdate) (*Message, error) DeleteMessage(channelID Snowflake, messageID Snowflake) error BulkDeleteMessages(channelID Snowflake, messageIDs ...Snowflake) error CrosspostMessage(channelID Snowflake, messageID Snowflake) (*Message, error) @@ -36,17 +42,17 @@ type RestClient interface { GetUser(userID Snowflake) (*User, error) GetMember(guildID Snowflake, userID Snowflake) (*Member, error) GetMembers(guildID Snowflake) ([]*Member, error) - AddMember(guildID Snowflake, userID Snowflake, addGuildMemberData AddGuildMemberData) (*Member, error) + AddMember(guildID Snowflake, userID Snowflake, addGuildMemberData *AddGuildMemberData) (*Member, error) KickMember(guildID Snowflake, userID Snowflake, reason *string) error - UpdateMember(guildID Snowflake, userID Snowflake, updateGuildMemberData UpdateGuildMemberData) (*Member, error) + UpdateMember(guildID Snowflake, userID Snowflake, updateGuildMemberData *UpdateGuildMemberData) (*Member, error) MoveMember(guildID Snowflake, userID Snowflake, channelID *Snowflake) (*Member, error) AddMemberRole(guildID Snowflake, userID Snowflake, roleID Snowflake) error RemoveMemberRole(guildID Snowflake, userID Snowflake, roleID Snowflake) error GetRoles(guildID Snowflake) ([]*Role, error) - CreateRole(guildID Snowflake, role UpdateRole) (*Role, error) - UpdateRole(guildID Snowflake, roleID Snowflake, role UpdateRole) (*Role, error) - UpdateRolePositions(guildID Snowflake, roleUpdates ...UpdateRolePosition) ([]*Role, error) + CreateRole(guildID Snowflake, role *UpdateRole) (*Role, error) + UpdateRole(guildID Snowflake, roleID Snowflake, role *UpdateRole) (*Role, error) + UpdateRolePositions(guildID Snowflake, roleUpdates ...*UpdateRolePosition) ([]*Role, error) DeleteRole(guildID Snowflake, roleID Snowflake) error AddReaction(channelID Snowflake, messageID Snowflake, emoji string) error @@ -55,34 +61,28 @@ type RestClient interface { GetGlobalCommands(applicationID Snowflake) ([]*Command, error) GetGlobalCommand(applicationID Snowflake, commandID Snowflake) (*Command, error) - CreateGlobalCommand(applicationID Snowflake, command Command) (*Command, error) - SetGlobalCommands(applicationID Snowflake, commands ...Command) ([]*Command, error) - EditGlobalCommand(applicationID Snowflake, commandID Snowflake, command UpdateCommand) (*Command, error) + CreateGlobalCommand(applicationID Snowflake, command *CommandCreate) (*Command, error) + SetGlobalCommands(applicationID Snowflake, commands ...*CommandCreate) ([]*Command, error) + EditGlobalCommand(applicationID Snowflake, commandID Snowflake, command *CommandUpdate) (*Command, error) DeleteGlobalCommand(applicationID Snowflake, commandID Snowflake) error GetGuildCommands(applicationID Snowflake, guildID Snowflake) ([]*Command, error) GetGuildCommand(applicationID Snowflake, guildID Snowflake, commandID Snowflake) (*Command, error) - CreateGuildCommand(applicationID Snowflake, guildID Snowflake, command Command) (*Command, error) - SetGuildCommands(applicationID Snowflake, guildID Snowflake, commands ...Command) ([]*Command, error) - EditGuildCommand(applicationID Snowflake, guildID Snowflake, commandID Snowflake, command UpdateCommand) (*Command, error) + CreateGuildCommand(applicationID Snowflake, guildID Snowflake, command *CommandCreate) (*Command, error) + SetGuildCommands(applicationID Snowflake, guildID Snowflake, commands ...*CommandCreate) ([]*Command, error) + EditGuildCommand(applicationID Snowflake, guildID Snowflake, commandID Snowflake, command *CommandUpdate) (*Command, error) DeleteGuildCommand(applicationID Snowflake, guildID Snowflake, commandID Snowflake) error GetGuildCommandsPermissions(applicationID Snowflake, guildID Snowflake) ([]*GuildCommandPermissions, error) GetGuildCommandPermissions(applicationID Snowflake, guildID Snowflake, commandID Snowflake) (*GuildCommandPermissions, error) - SetGuildCommandsPermissions(applicationID Snowflake, guildID Snowflake, commandPermissions ...SetGuildCommandPermissions) ([]*GuildCommandPermissions, error) - SetGuildCommandPermissions(applicationID Snowflake, guildID Snowflake, commandID Snowflake, commandPermissions SetGuildCommandPermissions) (*GuildCommandPermissions, error) + SetGuildCommandsPermissions(applicationID Snowflake, guildID Snowflake, commandPermissions ...*SetGuildCommandPermissions) ([]*GuildCommandPermissions, error) + SetGuildCommandPermissions(applicationID Snowflake, guildID Snowflake, commandID Snowflake, commandPermissions *SetGuildCommandPermissions) (*GuildCommandPermissions, error) - SendInteractionResponse(interactionID Snowflake, interactionToken endpoints.Token, interactionResponse InteractionResponse) error - EditInteractionResponse(applicationID Snowflake, interactionToken endpoints.Token, followupMessage FollowupMessage) (*Message, error) - DeleteInteractionResponse(applicationID Snowflake, interactionToken endpoints.Token) error + SendInteractionResponse(interactionID Snowflake, interactionToken string, interactionResponse *InteractionResponse) error + EditInteractionResponse(applicationID Snowflake, interactionToken string, followupMessage *FollowupMessage) (*Message, error) + DeleteInteractionResponse(applicationID Snowflake, interactionToken string) error - SendFollowupMessage(applicationID Snowflake, interactionToken endpoints.Token, followupMessage FollowupMessage) (*Message, error) - EditFollowupMessage(applicationID Snowflake, interactionToken endpoints.Token, messageID Snowflake, followupMessage FollowupMessage) (*Message, error) - DeleteFollowupMessage(applicationID Snowflake, interactionToken endpoints.Token, followupMessageID Snowflake) error -} - -// ErrorResponse contains custom errors from discord -type ErrorResponse struct { - Code int - Message string + SendFollowupMessage(applicationID Snowflake, interactionToken string, followupMessage *FollowupMessage) (*Message, error) + EditFollowupMessage(applicationID Snowflake, interactionToken string, messageID Snowflake, followupMessage *FollowupMessage) (*Message, error) + DeleteFollowupMessage(applicationID Snowflake, interactionToken string, followupMessageID Snowflake) error } diff --git a/api/role.go b/api/role.go index cd813e9b..617e6abe 100644 --- a/api/role.go +++ b/api/role.go @@ -31,12 +31,12 @@ func (r Role) Guild() *Guild { } // Update updates the Role with specific values -func (r Role) Update(roleUpdate UpdateRole) (*Role, error) { +func (r Role) Update(roleUpdate *UpdateRole) (*Role, error) { return r.Disgo.RestClient().UpdateRole(r.GuildID, r.ID, roleUpdate) } // SetPosition sets the position of the Role -func (r Role) SetPosition(rolePositionUpdate UpdateRolePosition) ([]*Role, error) { +func (r Role) SetPosition(rolePositionUpdate *UpdateRolePosition) ([]*Role, error) { return r.Disgo.RestClient().UpdateRolePositions(r.GuildID, rolePositionUpdate) } diff --git a/api/user.go b/api/user.go index 70b04138..7c996c24 100644 --- a/api/user.go +++ b/api/user.go @@ -1,5 +1,13 @@ package api +import ( + "fmt" + "strconv" + "strings" + + "github.com/DisgoOrg/disgo/api/endpoints" +) + // User is a struct for interacting with discord's users type User struct { Disgo Disgo @@ -18,6 +26,27 @@ type User struct { PublicFlags *int `json:"public_flags"` } +// AvatarURL returns the Avatar URL of the User +func (u *User) AvatarURL() string { + if u.Avatar == nil { + discrim, _ := strconv.Atoi(u.Discriminator) + route, err := endpoints.DefaultUserAvatar.Compile(endpoints.PNG, discrim%5) + if err != nil { + return "" + } + return route.Route() + } + format := endpoints.PNG + if strings.HasPrefix(*u.Avatar, "a_") { + format = endpoints.GIF + } + route, err := endpoints.UserAvatar.Compile(format, u.ID.String(), *u.Avatar) + if err != nil { + return "" + } + return route.Route() +} + // Mention returns the user as a mention func (u User) Mention() string { return "<@" + u.ID.String() + ">" @@ -25,7 +54,7 @@ func (u User) Mention() string { // Tag returns the user's Username and Discriminator func (u User) Tag() string { - return u.Username + "#" + u.Discriminator + return fmt.Sprintf("%s#%s", u.Username, u.Discriminator) } func (u User) String() string { diff --git a/api/voice_dispatch_interceptor.go b/api/voice_dispatch_interceptor.go index eae50a6d..20b72a53 100644 --- a/api/voice_dispatch_interceptor.go +++ b/api/voice_dispatch_interceptor.go @@ -13,7 +13,7 @@ func (u *VoiceServerUpdateEvent) Guild() *Guild { // VoiceStateUpdateEvent sent when someone joins/leaves/moves voice channels type VoiceStateUpdateEvent struct { - VoiceState + *VoiceState Member *Member `json:"member"` } diff --git a/disgo.go b/disgo.go index 8f708591..1e61da43 100644 --- a/disgo.go +++ b/disgo.go @@ -2,16 +2,15 @@ package disgo import ( "github.com/DisgoOrg/disgo/api" - "github.com/DisgoOrg/disgo/api/endpoints" "github.com/DisgoOrg/disgo/internal" ) // New Initialises a new Disgo client -func New(token endpoints.Token, options api.Options) (api.Disgo, error) { +func New(token string, options api.Options) (api.Disgo, error) { return internal.New(token, options) } // NewBuilder creates an api.DisgoBuilder for the client -func NewBuilder(token endpoints.Token) api.DisgoBuilder { +func NewBuilder(token string) api.DisgoBuilder { return internal.NewBuilder(token) } diff --git a/testbot/testbot.go b/example/examplebot.go similarity index 88% rename from testbot/testbot.go rename to example/examplebot.go index 77a0ebd0..0c86325e 100644 --- a/testbot/testbot.go +++ b/example/examplebot.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "net/http" "os" "os/signal" "strconv" @@ -13,7 +14,6 @@ import ( "github.com/DisgoOrg/disgo" "github.com/DisgoOrg/disgo/api" - "github.com/DisgoOrg/disgo/api/endpoints" "github.com/DisgoOrg/disgo/api/events" ) @@ -26,19 +26,21 @@ const adminRoleID = "817327279583264788" const testRoleID = "825156597935243304" var logger = logrus.New() +var client = http.DefaultClient func main() { logger.SetLevel(logrus.DebugLevel) - logger.Info("starting testbot...") + logger.Info("starting TestBot...") - dgo, err := disgo.NewBuilder(endpoints.Token(os.Getenv("token"))). + dgo, err := disgo.NewBuilder(os.Getenv("token")). SetLogger(logger). + SetHTTPClient(client). SetIntents(api.IntentsGuilds | api.IntentsGuildMessages | api.IntentsGuildMembers). SetMemberCachePolicy(api.MemberCachePolicyAll). AddEventListeners(&events.ListenerAdapter{ - OnGuildAvailable: guildAvailListener, + OnGuildAvailable: guildAvailListener, OnGuildMessageCreate: messageListener, - OnSlashCommand: slashCommandListener, + OnSlashCommand: slashCommandListener, }). Build() if err != nil { @@ -46,11 +48,11 @@ func main() { return } - rawCmds := []api.Command{ + rawCmds := []*api.CommandCreate{ { Name: "eval", Description: "runs some go code", - DefaultPermission: false, + DefaultPermission: ptrBool(false), Options: []*api.CommandOption{ { Type: api.CommandOptionTypeString, @@ -63,12 +65,12 @@ func main() { { Name: "test", Description: "test test test test test test", - DefaultPermission: false, + DefaultPermission: ptrBool(false), }, { Name: "say", Description: "says what you say", - DefaultPermission: false, + DefaultPermission: ptrBool(false), Options: []*api.CommandOption{ { Type: api.CommandOptionTypeString, @@ -81,7 +83,7 @@ func main() { { Name: "addrole", Description: "This command adds a role to a member", - DefaultPermission: false, + DefaultPermission: ptrBool(false), Options: []*api.CommandOption{ { Type: api.CommandOptionTypeUser, @@ -100,7 +102,7 @@ func main() { { Name: "removerole", Description: "This command removes a role from a member", - DefaultPermission: false, + DefaultPermission: ptrBool(false), Options: []*api.CommandOption{ { Type: api.CommandOptionTypeUser, @@ -124,25 +126,25 @@ func main() { logger.Errorf("error while registering guild commands: %s", err) } - var cmdsPermissions []api.SetGuildCommandPermissions + var cmdsPermissions []*api.SetGuildCommandPermissions for _, cmd := range cmds { - var perms api.CommandPermission + var perms *api.CommandPermission if cmd.Name == "eval" { - perms = api.CommandPermission{ + perms = &api.CommandPermission{ ID: adminRoleID, Type: api.CommandPermissionTypeRole, Permission: true, } } else { - perms = api.CommandPermission{ + perms = &api.CommandPermission{ ID: testRoleID, Type: api.CommandPermissionTypeRole, Permission: true, } } - cmdsPermissions = append(cmdsPermissions, api.SetGuildCommandPermissions{ + cmdsPermissions = append(cmdsPermissions, &api.SetGuildCommandPermissions{ ID: cmd.ID, - Permissions: []api.CommandPermission{perms}, + Permissions: []*api.CommandPermission{perms}, }) } if _, err = dgo.RestClient().SetGuildCommandsPermissions(dgo.ApplicationID(), guildID, cmdsPermissions...); err != nil { @@ -156,7 +158,7 @@ func main() { defer dgo.Close() - logger.Infof("Bot is now running. Press CTRL-C to exit.") + logger.Infof("TestBot is now running. Press CTRL-C to exit.") s := make(chan os.Signal, 1) signal.Notify(s, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill) <-s @@ -195,7 +197,7 @@ func slashCommandListener(event *events.SlashCommandEvent) { _, _ = event.EditOriginal(api.NewFollowupMessageBuilder(). SetEmbeds(embed. SetColor(red). - SetField(0, "Status", "failed", true). + SetField(0, "Status", "Failed", true). SetField(3, "Output", "```"+err.Error()+"```", false). Build(), ). @@ -206,7 +208,7 @@ func slashCommandListener(event *events.SlashCommandEvent) { _, _ = event.EditOriginal(api.NewFollowupMessageBuilder(). SetEmbeds(embed. SetColor(green). - SetField(0, "Status", "success", true). + SetField(0, "Status", "Success", true). SetField(3, "Output", "```"+fmt.Sprintf("%+v", output)+"```", false). Build(), ). @@ -310,3 +312,7 @@ func messageListener(event *events.GuildMessageCreateEvent) { }() } } + +func ptrBool(bool bool) *bool { + return &bool +} diff --git a/testbot/go.mod b/example/go.mod similarity index 64% rename from testbot/go.mod rename to example/go.mod index 911abcf9..2222cba8 100644 --- a/testbot/go.mod +++ b/example/go.mod @@ -1,11 +1,11 @@ -module github.com/DisgoOrg/disgo/testbot +module github.com/DisgoOrg/disgo/example go 1.16 replace github.com/DisgoOrg/disgo => ../ require ( - github.com/DisgoOrg/disgo v0.1.6 + github.com/DisgoOrg/disgo v0.2.0 github.com/PaesslerAG/gval v1.1.0 github.com/sirupsen/logrus v1.8.1 ) diff --git a/testbot/go.sum b/example/go.sum similarity index 88% rename from testbot/go.sum rename to example/go.sum index 094591a0..a35100cb 100644 --- a/testbot/go.sum +++ b/example/go.sum @@ -1,7 +1,3 @@ -github.com/DisgoOrg/log v1.0.0 h1:X8WSKatQUhZ/D8nYerJz75X3yD4/0vQgmAVbQ7XSVCI= -github.com/DisgoOrg/log v1.0.0/go.mod h1:E60iniXaAsm9Iuxlz53nQDTYzJTSf1Kn/oH9KQhaK6w= -github.com/DisgoOrg/log v1.0.2 h1:qDOmBkB2xnN0sG74dTNKs/qdWekVAJAyVPDASofIWOc= -github.com/DisgoOrg/log v1.0.2/go.mod h1:KFGKhBQr37d6rxZ7p2bmc8BEmDH8DZbtgdlJDSCsE7I= github.com/DisgoOrg/log v1.0.3 h1:IjmZQQu/kuBIui22EdXmxzQGYwcPCJEkXa0Fe6W9fJk= github.com/DisgoOrg/log v1.0.3/go.mod h1:KFGKhBQr37d6rxZ7p2bmc8BEmDH8DZbtgdlJDSCsE7I= github.com/PaesslerAG/gval v1.1.0 h1:k3RuxeZDO3eejD4cMPSt+74tUSvTnbGvLx0df4mdwFc= diff --git a/internal/cache_impl.go b/internal/cache_impl.go index 3c16a37d..50671ab2 100644 --- a/internal/cache_impl.go +++ b/internal/cache_impl.go @@ -305,6 +305,7 @@ func (c *CacheImpl) CacheGuild(guild *api.Guild) *api.Guild { c.guilds[guild.ID] = guild c.guildCommands[guild.ID] = map[api.Snowflake]*api.Command{} c.members[guild.ID] = map[api.Snowflake]*api.Member{} + c.voiceStates[guild.ID] = map[api.Snowflake]*api.VoiceState{} c.roles[guild.ID] = map[api.Snowflake]*api.Role{} c.categories[guild.ID] = map[api.Snowflake]*api.Category{} c.textChannels[guild.ID] = map[api.Snowflake]*api.TextChannel{} @@ -419,7 +420,7 @@ func (c *CacheImpl) Member(guildID api.Snowflake, userID api.Snowflake) *api.Mem func (c *CacheImpl) MemberByTag(guildID api.Snowflake, tag string) *api.Member { if guildMembers, ok := c.members[guildID]; ok { for _, member := range guildMembers { - if member.User.Username+"#"+member.User.Discriminator == tag { + if member.User.Tag() == tag { return member } } diff --git a/internal/disgo_builder_impl.go b/internal/disgo_builder_impl.go index 31e9003d..ded4528e 100644 --- a/internal/disgo_builder_impl.go +++ b/internal/disgo_builder_impl.go @@ -2,26 +2,26 @@ package internal import ( "errors" + "net/http" "github.com/DisgoOrg/log" "github.com/DisgoOrg/disgo/api" - "github.com/DisgoOrg/disgo/api/endpoints" ) // NewBuilder returns a new api.DisgoBuilder instance -func NewBuilder(token endpoints.Token) api.DisgoBuilder { +func NewBuilder(token string) api.DisgoBuilder { return &DisgoBuilderImpl{ - BotToken: token, + token: token, cacheFlags: api.CacheFlagsDefault, } } // DisgoBuilderImpl implementation of the api.DisgoBuilder interface type DisgoBuilderImpl struct { - logger log.Logger - // make this public so it does not print in fmt.Sprint("%+v, DisgoBuilderImpl{}) - BotToken endpoints.Token + logger log.Logger + token string + httpClient *http.Client gateway api.Gateway restClient api.RestClient audioController api.AudioController @@ -48,8 +48,14 @@ func (b *DisgoBuilderImpl) SetLogger(logger log.Logger) api.DisgoBuilder { } // SetToken sets the BotToken to connect to discord -func (b *DisgoBuilderImpl) SetToken(token endpoints.Token) api.DisgoBuilder { - b.BotToken = token +func (b *DisgoBuilderImpl) SetToken(token string) api.DisgoBuilder { + b.token = token + return b +} + +// SetHTTPClient sets the http.Client the api.RestClient uses +func (b *DisgoBuilderImpl) SetHTTPClient(httpClient *http.Client) api.DisgoBuilder { + b.httpClient = httpClient return b } @@ -166,12 +172,12 @@ func (b *DisgoBuilderImpl) Build() (api.Disgo, error) { logger: b.logger, rawGatewayEventsEnabled: b.rawGatewayEventsEnabled, } - if b.BotToken == "" { + if b.token == "" { return nil, errors.New("please specify the BotToken") } - disgo.BotToken = b.BotToken + disgo.botToken = b.token - id, err := IDFromToken(disgo.BotToken) + id, err := IDFromToken(disgo.botToken) if err != nil { disgo.Logger().Errorf("error while getting application id from BotToken: %s", err) return nil, err @@ -184,8 +190,12 @@ func (b *DisgoBuilderImpl) Build() (api.Disgo, error) { } disgo.gateway = b.gateway + if b.httpClient == nil { + b.httpClient = http.DefaultClient + } + if b.restClient == nil { - b.restClient = newRestClientImpl(disgo) + b.restClient = newRestClientImpl(disgo, b.httpClient) } disgo.restClient = b.restClient diff --git a/internal/disgo_impl.go b/internal/disgo_impl.go index 6b4dfc4f..dc8d1fce 100644 --- a/internal/disgo_impl.go +++ b/internal/disgo_impl.go @@ -6,11 +6,10 @@ import ( "github.com/DisgoOrg/log" "github.com/DisgoOrg/disgo/api" - "github.com/DisgoOrg/disgo/api/endpoints" ) // New creates a new api.Disgo instance -func New(token endpoints.Token, options api.Options) (api.Disgo, error) { +func New(token string, options api.Options) (api.Disgo, error) { if options.LargeThreshold < 50 { options.LargeThreshold = 50 } else if options.LargeThreshold > 250 { @@ -18,7 +17,7 @@ func New(token endpoints.Token, options api.Options) (api.Disgo, error) { } disgo := &DisgoImpl{ - BotToken: token, + botToken: token, intents: options.Intents, largeThreshold: options.LargeThreshold, logger: options.Logger, @@ -33,7 +32,7 @@ func New(token endpoints.Token, options api.Options) (api.Disgo, error) { disgo.selfUserID = *id - disgo.restClient = newRestClientImpl(disgo) + disgo.restClient = newRestClientImpl(disgo, options.HTTPClient) disgo.audioController = newAudioControllerImpl(disgo) @@ -52,8 +51,7 @@ func New(token endpoints.Token, options api.Options) (api.Disgo, error) { // DisgoImpl is the main discord client type DisgoImpl struct { - // make this public so it does not print in fmt.Sprint("%+v, DisgoImpl{}) - BotToken endpoints.Token + botToken string logger log.Logger gateway api.Gateway restClient api.RestClient @@ -109,8 +107,8 @@ func (d *DisgoImpl) Close() { } // Token returns the BotToken of the client -func (d *DisgoImpl) Token() endpoints.Token { - return d.BotToken +func (d *DisgoImpl) Token() string { + return d.botToken } // Gateway returns the websocket information @@ -206,21 +204,21 @@ func (d DisgoImpl) GetCommands() ([]*api.Command, error) { } // CreateCommand creates a new command for this guild -func (d DisgoImpl) CreateCommand(command api.Command) (*api.Command, error) { +func (d DisgoImpl) CreateCommand(command *api.CommandCreate) (*api.Command, error) { return d.RestClient().CreateGlobalCommand(d.ApplicationID(), command) } // EditCommand edits a specific guild command -func (d DisgoImpl) EditCommand(commandID api.Snowflake, command api.UpdateCommand) (*api.Command, error) { +func (d DisgoImpl) EditCommand(commandID api.Snowflake, command *api.CommandUpdate) (*api.Command, error) { return d.RestClient().EditGlobalCommand(d.ApplicationID(), commandID, command) } // DeleteCommand creates a new command for this guild -func (d DisgoImpl) DeleteCommand(command api.Command) (*api.Command, error) { - return d.RestClient().CreateGlobalCommand(d.ApplicationID(), command) +func (d DisgoImpl) DeleteCommand(commandID api.Snowflake) error { + return d.RestClient().DeleteGlobalCommand(d.ApplicationID(), commandID) } // SetCommands overrides all commands for this guild -func (d DisgoImpl) SetCommands(commands ...api.Command) ([]*api.Command, error) { +func (d DisgoImpl) SetCommands(commands ...*api.CommandCreate) ([]*api.Command, error) { return d.RestClient().SetGlobalCommands(d.ApplicationID(), commands...) } diff --git a/internal/entity_builder_impl.go b/internal/entity_builder_impl.go index d3c4976c..f4e9744a 100644 --- a/internal/entity_builder_impl.go +++ b/internal/entity_builder_impl.go @@ -18,6 +18,44 @@ func (b EntityBuilderImpl) Disgo() api.Disgo { return b.disgo } +// CreateInteraction returns a new api.Interaction entity +func (b EntityBuilderImpl) CreateInteraction(interaction *api.Interaction, updateCache api.CacheStrategy) *api.Interaction { + if interaction.Member != nil { + interaction.Member = b.CreateMember(*interaction.GuildID, interaction.Member, api.CacheStrategyYes) + } + if interaction.User != nil { + interaction.User = b.CreateUser(interaction.User, updateCache) + } + + if interaction.Data != nil && interaction.Data.Resolved != nil { + resolved := interaction.Data.Resolved + if resolved.Users != nil { + for _, user := range resolved.Users { + user = b.CreateUser(user, updateCache) + } + } + if resolved.Members != nil { + for id, member := range resolved.Members { + member.User = resolved.Users[id] + member = b.CreateMember(*interaction.GuildID, member, updateCache) + } + } + if resolved.Roles != nil { + for _, role := range resolved.Roles { + role = b.CreateRole(*interaction.GuildID, role, updateCache) + } + } + // TODO how do we cache partial channels? + /*if resolved.Channels != nil { + for _, channel := range resolved.Channels { + channel.Disgo = disgo + disgo.Cache().CacheChannel(channel) + } + }*/ + } + return interaction +} + // CreateGlobalCommand returns a new api.Command entity func (b EntityBuilderImpl) CreateGlobalCommand(command *api.Command, updateCache api.CacheStrategy) *api.Command { command.Disgo = b.Disgo() @@ -73,8 +111,11 @@ func (b EntityBuilderImpl) CreateMember(guildID api.Snowflake, member *api.Membe } // CreateVoiceState returns a new api.VoiceState entity -func (b EntityBuilderImpl) CreateVoiceState(voiceState *api.VoiceState, updateCache api.CacheStrategy) *api.VoiceState { +func (b EntityBuilderImpl) CreateVoiceState(guildID api.Snowflake, voiceState *api.VoiceState, updateCache api.CacheStrategy) *api.VoiceState { voiceState.Disgo = b.Disgo() + voiceState.GuildID = guildID + b.Disgo().Logger().Infof("voiceState: %+v", voiceState) + if updateCache(b.Disgo()) { return b.Disgo().Cache().CacheVoiceState(voiceState) } diff --git a/internal/gateway_impl.go b/internal/gateway_impl.go index f0856e80..4490b356 100644 --- a/internal/gateway_impl.go +++ b/internal/gateway_impl.go @@ -77,7 +77,7 @@ func (g *GatewayImpl) Open() error { if err != nil { return err } - if err = g.Disgo().RestClient().Request(*compiledRoute, nil, &gatewayRs); err != nil { + if err = g.Disgo().RestClient().Request(compiledRoute, nil, &gatewayRs); err != nil { return err } g.url = &gatewayRs.URL diff --git a/internal/handlers/guild_create_handler.go b/internal/handlers/guild_create_handler.go index b0405f3e..f801a5b7 100644 --- a/internal/handlers/guild_create_handler.go +++ b/internal/handlers/guild_create_handler.go @@ -56,7 +56,7 @@ func (h GuildCreateHandler) HandleGatewayEvent(disgo api.Disgo, eventManager api } for _, voiceState := range fullGuild.VoiceStates { - disgo.EntityBuilder().CreateVoiceState(voiceState, api.CacheStrategyYes) + disgo.EntityBuilder().CreateVoiceState(guild.ID, voiceState, api.CacheStrategyYes) } for _, emote := range fullGuild.Emotes { diff --git a/internal/handlers/interaction_create_handler.go b/internal/handlers/interaction_create_handler.go index 861fa375..b50c6d96 100644 --- a/internal/handlers/interaction_create_handler.go +++ b/internal/handlers/interaction_create_handler.go @@ -27,49 +27,9 @@ func (h InteractionCreateHandler) HandleGatewayEvent(disgo api.Disgo, eventManag handleInteraction(disgo, eventManager, sequenceNumber, interaction, nil) } -func handleInteraction(disgo api.Disgo, eventManager api.EventManager, sequenceNumber int, interaction *api.Interaction, c chan interface{}) { - if interaction.Member != nil { - interaction.Member.Disgo = disgo - if interaction.Member.User != nil { - interaction.Member.User.Disgo = disgo - } - disgo.Cache().CacheMember(interaction.Member) - } - if interaction.User != nil { - interaction.User.Disgo = disgo - disgo.Cache().CacheUser(interaction.User) - } - - if interaction.Data != nil && interaction.Data.Resolved != nil { - resolved := interaction.Data.Resolved - if resolved.Users != nil { - for _, user := range resolved.Users { - user.Disgo = disgo - disgo.Cache().CacheUser(user) - } - } - if resolved.Members != nil { - for id, member := range resolved.Members { - member.User = resolved.Users[id] - member.Disgo = disgo - disgo.Cache().CacheMember(member) - } - } - if resolved.Roles != nil { - for _, role := range resolved.Roles { - role.Disgo = disgo - disgo.Cache().CacheRole(role) - } - } - // TODO how do we cache partial channels? - /*if resolved.Channels != nil { - for _, channel := range resolved.Channels { - channel.Disgo = disgo - disgo.Cache().CacheChannel(channel) - } - }*/ - } +func handleInteraction(disgo api.Disgo, eventManager api.EventManager, sequenceNumber int, interaction *api.Interaction, c chan *api.InteractionResponse) { + interaction = disgo.EntityBuilder().CreateInteraction(interaction, api.CacheStrategyYes) genericInteractionEvent := events.GenericInteractionEvent{ GenericEvent: events.NewEvent(disgo, sequenceNumber), Interaction: interaction, diff --git a/internal/handlers/interaction_create_webhook_handler.go b/internal/handlers/interaction_create_webhook_handler.go index 0cf2282a..1751759f 100644 --- a/internal/handlers/interaction_create_webhook_handler.go +++ b/internal/handlers/interaction_create_webhook_handler.go @@ -18,14 +18,14 @@ func (h InteractionCreateWebhookHandler) New() interface{} { } // HandleWebhookEvent handles the specific raw gateway event -func (h InteractionCreateWebhookHandler) HandleWebhookEvent(disgo api.Disgo, eventManager api.EventManager, c chan interface{}, i interface{}) { +func (h InteractionCreateWebhookHandler) HandleWebhookEvent(disgo api.Disgo, eventManager api.EventManager, c chan *api.InteractionResponse, i interface{}) { interaction, ok := i.(*api.Interaction) if !ok { return } if interaction.Type == api.InteractionTypePing { - c <- api.InteractionResponse{ + c <- &api.InteractionResponse{ Type: api.InteractionResponseTypePong, } return diff --git a/internal/handlers/voice_state_update_handler.go b/internal/handlers/voice_state_update_handler.go index 124149b9..5cb8f151 100644 --- a/internal/handlers/voice_state_update_handler.go +++ b/internal/handlers/voice_state_update_handler.go @@ -2,6 +2,7 @@ package handlers import ( "github.com/DisgoOrg/disgo/api" + "github.com/DisgoOrg/disgo/api/events" ) // VoiceStateUpdateHandler handles api.VoiceStateUpdateGatewayEvent @@ -23,16 +24,12 @@ func (h VoiceStateUpdateHandler) HandleGatewayEvent(disgo api.Disgo, eventManage if !ok { return } - - voiceStateUpdate.Disgo = disgo - - //guild := disgo.Cache().Guild(voiceStateUpdate.GuildID) - - //oldMember := disgo.Cache().Member(voiceStateUpdate.GuildID, voiceStateUpdate.UserID) - //newMember := voiceStateUpdate.Member - - // TODO update voice state cache - // TODO fire several events + oldVoiceState := disgo.Cache().VoiceState(voiceStateUpdate.GuildID, voiceStateUpdate.UserID) + if oldVoiceState != nil { + oldVoiceState = &*oldVoiceState + } + voiceStateUpdate.VoiceState = disgo.EntityBuilder().CreateVoiceState(voiceStateUpdate.GuildID, voiceStateUpdate.VoiceState, api.CacheStrategyYes) + voiceStateUpdate.Member = disgo.EntityBuilder().CreateMember(voiceStateUpdate.Member.GuildID, voiceStateUpdate.Member, api.CacheStrategyYes) if disgo.ApplicationID() == voiceStateUpdate.UserID { if interceptor := disgo.VoiceDispatchInterceptor(); interceptor != nil { @@ -40,4 +37,37 @@ func (h VoiceStateUpdateHandler) HandleGatewayEvent(disgo api.Disgo, eventManage } } + guild := voiceStateUpdate.Guild() + if guild == nil { + disgo.Logger().Error("received guild voice state update for unknown guild: %s", voiceStateUpdate.GuildID) + return + } + + genericGuildEvent := events.GenericGuildEvent{ + GenericEvent: events.NewEvent(disgo, sequenceNumber), + Guild: guild, + } + disgo.EventManager().Dispatch(genericGuildEvent) + + genericGuildMemberEvent := events.GenericGuildMemberEvent{ + GenericGuildEvent: genericGuildEvent, + Member: voiceStateUpdate.Member, + } + disgo.EventManager().Dispatch(genericGuildMemberEvent) + + genericGuildVoiceEvent := events.GenericGuildVoiceEvent{ + GenericGuildMemberEvent: genericGuildMemberEvent, + VoiceState: voiceStateUpdate.VoiceState, + } + disgo.EventManager().Dispatch(genericGuildVoiceEvent) + + if (oldVoiceState == nil || oldVoiceState.ChannelID == nil) && voiceStateUpdate.ChannelID != nil { + disgo.EventManager().Dispatch(events.GuildVoiceJoinEvent{GenericGuildVoiceEvent: genericGuildVoiceEvent}) + } else if oldVoiceState != nil && oldVoiceState.ChannelID != nil && voiceStateUpdate.ChannelID == nil { + disgo.EventManager().Dispatch(events.GuildVoiceLeaveEvent{GenericGuildVoiceEvent: genericGuildVoiceEvent}) + } else if oldVoiceState != nil && oldVoiceState.ChannelID != nil && voiceStateUpdate.ChannelID != nil { + disgo.EventManager().Dispatch(events.GuildVoiceUpdateEvent{GenericGuildVoiceEvent: genericGuildVoiceEvent, OldVoiceState: oldVoiceState}) + } else { + disgo.Logger().Warnf("could not decide which GuildVoiceEvent to fire") + } } diff --git a/internal/restclient_impl.go b/internal/restclient_impl.go index b56f66fb..86d8f6fb 100644 --- a/internal/restclient_impl.go +++ b/internal/restclient_impl.go @@ -15,17 +15,20 @@ import ( "github.com/DisgoOrg/disgo/api/endpoints" ) -func newRestClientImpl(disgo api.Disgo) api.RestClient { +func newRestClientImpl(disgo api.Disgo, client *http.Client) api.RestClient { + if client == nil { + client = http.DefaultClient + } return &RestClientImpl{ disgo: disgo, - Client: &http.Client{}, + client: client, } } // RestClientImpl is the rest client implementation used for HTTP requests to discord type RestClientImpl struct { disgo api.Disgo - Client *http.Client + client *http.Client token string } @@ -34,9 +37,14 @@ func (r RestClientImpl) Disgo() api.Disgo { return r.disgo } +// Client returns the http.Client used by this api.RestClient +func (r RestClientImpl) Client() *http.Client { + return r.client +} + // Close cleans up the http managers connections func (r RestClientImpl) Close() { - r.Client.CloseIdleConnections() + r.client.CloseIdleConnections() } // UserAgent returns the user agent for this api.RestClient @@ -45,7 +53,7 @@ func (r RestClientImpl) UserAgent() string { } // Request makes a new rest request to discords api with the specific endpoints.APIRoute -func (r RestClientImpl) Request(route endpoints.CompiledAPIRoute, rqBody interface{}, rsBody interface{}) error { +func (r RestClientImpl) Request(route *endpoints.CompiledAPIRoute, rqBody interface{}, rsBody interface{}) error { var reader io.Reader var rqJSON []byte if rqBody != nil { @@ -65,10 +73,10 @@ func (r RestClientImpl) Request(route endpoints.CompiledAPIRoute, rqBody interfa } rq.Header.Set("User-Agent", r.UserAgent()) - rq.Header.Set("Authorization", string("Bot "+r.disgo.Token())) + rq.Header.Set("Authorization", "Bot "+r.disgo.Token()) rq.Header.Set("Content-Type", "application/json") - rs, err := r.Client.Do(rq) + rs, err := r.client.Do(rq) if err != nil { return err } @@ -135,12 +143,12 @@ func (r RestClientImpl) Request(route endpoints.CompiledAPIRoute, rqBody interfa } // SendMessage lets you send a api.Message to a api.MessageChannel -func (r RestClientImpl) SendMessage(channelID api.Snowflake, message api.MessageCreate) (msg *api.Message, err error) { +func (r RestClientImpl) SendMessage(channelID api.Snowflake, message *api.MessageCreate) (msg *api.Message, err error) { compiledRoute, err := endpoints.CreateMessage.Compile(channelID) if err != nil { return nil, err } - err = r.Request(*compiledRoute, message, &msg) + err = r.Request(compiledRoute, message, &msg) if err == nil { msg = r.Disgo().EntityBuilder().CreateMessage(msg, api.CacheStrategyNoWs) } @@ -148,12 +156,12 @@ func (r RestClientImpl) SendMessage(channelID api.Snowflake, message api.Message } // EditMessage lets you edit a api.Message -func (r RestClientImpl) EditMessage(channelID api.Snowflake, messageID api.Snowflake, message api.MessageUpdate) (msg *api.Message, err error) { +func (r RestClientImpl) EditMessage(channelID api.Snowflake, messageID api.Snowflake, message *api.MessageUpdate) (msg *api.Message, err error) { compiledRoute, err := endpoints.UpdateMessage.Compile(channelID, messageID) if err != nil { return nil, err } - err = r.Request(*compiledRoute, message, &msg) + err = r.Request(compiledRoute, message, &msg) if err == nil { msg = r.Disgo().EntityBuilder().CreateMessage(msg, api.CacheStrategyNoWs) } @@ -166,7 +174,7 @@ func (r RestClientImpl) DeleteMessage(channelID api.Snowflake, messageID api.Sno if err != nil { return err } - err = r.Request(*compiledRoute, nil, nil) + err = r.Request(compiledRoute, nil, nil) if err == nil && api.CacheStrategyNoWs(r.Disgo()) { r.Disgo().Cache().UncacheMessage(channelID, messageID) } @@ -179,7 +187,7 @@ func (r RestClientImpl) BulkDeleteMessages(channelID api.Snowflake, messageIDs . if err != nil { return err } - err = r.Request(*compiledRoute, api.MessageBulkDelete{Messages: messageIDs}, nil) + err = r.Request(compiledRoute, api.MessageBulkDelete{Messages: messageIDs}, nil) if err == nil && api.CacheStrategyNoWs(r.Disgo()) { // TODO: check here if no err means all messages deleted for _, messageID := range messageIDs { @@ -195,7 +203,7 @@ func (r RestClientImpl) CrosspostMessage(channelID api.Snowflake, messageID api. if err != nil { return nil, err } - err = r.Request(*compiledRoute, nil, &msg) + err = r.Request(compiledRoute, nil, &msg) if err == nil { msg = r.Disgo().EntityBuilder().CreateMessage(msg, api.CacheStrategyNoWs) } @@ -213,7 +221,7 @@ func (r RestClientImpl) OpenDMChannel(userID api.Snowflake) (channel *api.DMChan }{ RecipientID: userID, } - err = r.Request(*compiledRoute, body, &channel) + err = r.Request(compiledRoute, body, &channel) if err == nil { channel = r.Disgo().EntityBuilder().CreateDMChannel(&channel.MessageChannel.Channel, api.CacheStrategyNoWs) } @@ -227,7 +235,7 @@ func (r RestClientImpl) UpdateSelfNick(guildID api.Snowflake, nick *string) (new return nil, err } var updateNick *api.UpdateSelfNick - err = r.Request(*compiledRoute, api.UpdateSelfNick{Nick: nick}, &updateNick) + err = r.Request(compiledRoute, &api.UpdateSelfNick{Nick: nick}, &updateNick) if err == nil && api.CacheStrategyNoWs(r.Disgo()) { r.Disgo().Cache().Member(guildID, r.Disgo().ApplicationID()).Nick = updateNick.Nick newNick = updateNick.Nick @@ -241,7 +249,7 @@ func (r RestClientImpl) GetUser(userID api.Snowflake) (user *api.User, err error if err != nil { return nil, err } - err = r.Request(*compiledRoute, nil, &user) + err = r.Request(compiledRoute, nil, &user) if err == nil { user = r.Disgo().EntityBuilder().CreateUser(user, api.CacheStrategyNoWs) } @@ -254,7 +262,7 @@ func (r RestClientImpl) GetMember(guildID api.Snowflake, userID api.Snowflake) ( if err != nil { return nil, err } - err = r.Request(*compiledRoute, nil, &member) + err = r.Request(compiledRoute, nil, &member) if err == nil { member = r.Disgo().EntityBuilder().CreateMember(guildID, member, api.CacheStrategyNoWs) } @@ -267,7 +275,7 @@ func (r RestClientImpl) GetMembers(guildID api.Snowflake) (members []*api.Member if err != nil { return nil, err } - err = r.Request(*compiledRoute, nil, &members) + err = r.Request(compiledRoute, nil, &members) if err == nil { for _, member := range members { member = r.Disgo().EntityBuilder().CreateMember(guildID, member, api.CacheStrategyNoWs) @@ -277,12 +285,12 @@ func (r RestClientImpl) GetMembers(guildID api.Snowflake) (members []*api.Member } // AddMember adds a member to the guild with the oauth2 access BotToken. requires api.PermissionCreateInstantInvite -func (r RestClientImpl) AddMember(guildID api.Snowflake, userID api.Snowflake, addGuildMemberData api.AddGuildMemberData) (member *api.Member, err error) { +func (r RestClientImpl) AddMember(guildID api.Snowflake, userID api.Snowflake, addGuildMemberData *api.AddGuildMemberData) (member *api.Member, err error) { compiledRoute, err := endpoints.AddMember.Compile(guildID, userID) if err != nil { return nil, err } - err = r.Request(*compiledRoute, addGuildMemberData, &member) + err = r.Request(compiledRoute, addGuildMemberData, &member) if err == nil { member = r.Disgo().EntityBuilder().CreateMember(guildID, member, api.CacheStrategyNoWs) } @@ -300,7 +308,7 @@ func (r RestClientImpl) KickMember(guildID api.Snowflake, userID api.Snowflake, if err != nil { return } - err = r.Request(*compiledRoute, nil, nil) + err = r.Request(compiledRoute, nil, nil) if err == nil && api.CacheStrategyNoWs(r.Disgo()) { r.Disgo().Cache().UncacheMember(guildID, userID) } @@ -308,12 +316,12 @@ func (r RestClientImpl) KickMember(guildID api.Snowflake, userID api.Snowflake, } // UpdateMember updates a member -func (r RestClientImpl) UpdateMember(guildID api.Snowflake, userID api.Snowflake, updateGuildMemberData api.UpdateGuildMemberData) (member *api.Member, err error) { +func (r RestClientImpl) UpdateMember(guildID api.Snowflake, userID api.Snowflake, updateGuildMemberData *api.UpdateGuildMemberData) (member *api.Member, err error) { compiledRoute, err := endpoints.UpdateMember.Compile(guildID, userID) if err != nil { return nil, err } - err = r.Request(*compiledRoute, updateGuildMemberData, &member) + err = r.Request(compiledRoute, updateGuildMemberData, &member) if err == nil { member = r.Disgo().EntityBuilder().CreateMember(guildID, member, api.CacheStrategyNoWs) } @@ -326,7 +334,7 @@ func (r RestClientImpl) MoveMember(guildID api.Snowflake, userID api.Snowflake, if err != nil { return nil, err } - err = r.Request(*compiledRoute, api.MoveGuildMemberData{ChannelID: channelID}, &member) + err = r.Request(compiledRoute, api.MoveGuildMemberData{ChannelID: channelID}, &member) if err == nil { member = r.Disgo().EntityBuilder().CreateMember(guildID, member, api.CacheStrategyNoWs) } @@ -339,7 +347,7 @@ func (r RestClientImpl) AddMemberRole(guildID api.Snowflake, userID api.Snowflak if err != nil { return err } - err = r.Request(*compiledRoute, nil, nil) + err = r.Request(compiledRoute, nil, nil) if err == nil && api.CacheStrategyNoWs(r.Disgo()) { member := r.Disgo().Cache().Member(guildID, userID) if member != nil { @@ -355,7 +363,7 @@ func (r RestClientImpl) RemoveMemberRole(guildID api.Snowflake, userID api.Snowf if err != nil { return err } - err = r.Request(*compiledRoute, nil, nil) + err = r.Request(compiledRoute, nil, nil) if err == nil && api.CacheStrategyNoWs(r.Disgo()) { member := r.Disgo().Cache().Member(guildID, userID) if member != nil { @@ -376,7 +384,7 @@ func (r RestClientImpl) GetRoles(guildID api.Snowflake) (roles []*api.Role, err if err != nil { return nil, err } - err = r.Request(*compiledRoute, nil, &roles) + err = r.Request(compiledRoute, nil, &roles) if err == nil { for _, role := range roles { role = r.Disgo().EntityBuilder().CreateRole(guildID, role, api.CacheStrategyNoWs) @@ -386,12 +394,12 @@ func (r RestClientImpl) GetRoles(guildID api.Snowflake) (roles []*api.Role, err } // CreateRole creates a new role for a guild. Requires api.PermissionManageRoles -func (r RestClientImpl) CreateRole(guildID api.Snowflake, role api.UpdateRole) (newRole *api.Role, err error) { +func (r RestClientImpl) CreateRole(guildID api.Snowflake, role *api.UpdateRole) (newRole *api.Role, err error) { compiledRoute, err := endpoints.CreateRole.Compile(guildID) if err != nil { return nil, err } - err = r.Request(*compiledRoute, role, &newRole) + err = r.Request(compiledRoute, role, &newRole) if err == nil { newRole = r.Disgo().EntityBuilder().CreateRole(guildID, newRole, api.CacheStrategyNoWs) } @@ -399,12 +407,12 @@ func (r RestClientImpl) CreateRole(guildID api.Snowflake, role api.UpdateRole) ( } // UpdateRole updates a role from a guild. Requires api.PermissionManageRoles -func (r RestClientImpl) UpdateRole(guildID api.Snowflake, roleID api.Snowflake, role api.UpdateRole) (newRole *api.Role, err error) { +func (r RestClientImpl) UpdateRole(guildID api.Snowflake, roleID api.Snowflake, role *api.UpdateRole) (newRole *api.Role, err error) { compiledRoute, err := endpoints.UpdateRole.Compile(guildID, roleID) if err != nil { return nil, err } - err = r.Request(*compiledRoute, role, &newRole) + err = r.Request(compiledRoute, role, &newRole) if err == nil { newRole = r.Disgo().EntityBuilder().CreateRole(guildID, newRole, api.CacheStrategyNoWs) } @@ -412,12 +420,12 @@ func (r RestClientImpl) UpdateRole(guildID api.Snowflake, roleID api.Snowflake, } // UpdateRolePositions updates the position of a role from a guild. Requires api.PermissionManageRoles -func (r RestClientImpl) UpdateRolePositions(guildID api.Snowflake, roleUpdates ...api.UpdateRolePosition) (roles []*api.Role, err error) { +func (r RestClientImpl) UpdateRolePositions(guildID api.Snowflake, roleUpdates ...*api.UpdateRolePosition) (roles []*api.Role, err error) { compiledRoute, err := endpoints.GetRoles.Compile(guildID) if err != nil { return nil, err } - err = r.Request(*compiledRoute, roleUpdates, &roles) + err = r.Request(compiledRoute, roleUpdates, &roles) if err == nil { for _, role := range roles { role = r.Disgo().EntityBuilder().CreateRole(guildID, role, api.CacheStrategyNoWs) @@ -432,7 +440,7 @@ func (r RestClientImpl) DeleteRole(guildID api.Snowflake, roleID api.Snowflake) if err != nil { return err } - err = r.Request(*compiledRoute, nil, nil) + err = r.Request(compiledRoute, nil, nil) if err == nil && api.CacheStrategyNoWs(r.Disgo()) { r.disgo.Cache().UncacheRole(guildID, roleID) } @@ -445,7 +453,7 @@ func (r RestClientImpl) AddReaction(channelID api.Snowflake, messageID api.Snowf if err != nil { return err } - return r.Request(*compiledRoute, nil, nil) + return r.Request(compiledRoute, nil, nil) } // RemoveOwnReaction lets you remove your own reaction from a message_events @@ -454,7 +462,7 @@ func (r RestClientImpl) RemoveOwnReaction(channelID api.Snowflake, messageID api if err != nil { return err } - return r.Request(*compiledRoute, nil, nil) + return r.Request(compiledRoute, nil, nil) } // RemoveUserReaction lets you remove a specific reaction from a user from a message_events @@ -463,7 +471,7 @@ func (r RestClientImpl) RemoveUserReaction(channelID api.Snowflake, messageID ap if err != nil { return err } - return r.Request(*compiledRoute, nil, nil) + return r.Request(compiledRoute, nil, nil) } // GetGlobalCommands gets you all global commands @@ -472,7 +480,7 @@ func (r RestClientImpl) GetGlobalCommands(applicationID api.Snowflake) (commands if err != nil { return nil, err } - err = r.Request(*compiledRoute, nil, &commands) + err = r.Request(compiledRoute, nil, &commands) if err == nil { for _, cmd := range commands { cmd = r.Disgo().EntityBuilder().CreateGlobalCommand(cmd, api.CacheStrategyNoWs) @@ -487,7 +495,7 @@ func (r RestClientImpl) GetGlobalCommand(applicationID api.Snowflake, commandID if err != nil { return nil, err } - err = r.Request(*compiledRoute, nil, &cmd) + err = r.Request(compiledRoute, nil, &cmd) if err == nil { cmd = r.Disgo().EntityBuilder().CreateGlobalCommand(cmd, api.CacheStrategyNoWs) } @@ -495,12 +503,12 @@ func (r RestClientImpl) GetGlobalCommand(applicationID api.Snowflake, commandID } // CreateGlobalCommand lets you create a new global command -func (r RestClientImpl) CreateGlobalCommand(applicationID api.Snowflake, command api.Command) (cmd *api.Command, err error) { +func (r RestClientImpl) CreateGlobalCommand(applicationID api.Snowflake, command *api.CommandCreate) (cmd *api.Command, err error) { compiledRoute, err := endpoints.CreateGlobalCommand.Compile(applicationID) if err != nil { return nil, err } - err = r.Request(*compiledRoute, command, &cmd) + err = r.Request(compiledRoute, command, &cmd) if err == nil { cmd = r.Disgo().EntityBuilder().CreateGlobalCommand(cmd, api.CacheStrategyNoWs) } @@ -508,7 +516,7 @@ func (r RestClientImpl) CreateGlobalCommand(applicationID api.Snowflake, command } // SetGlobalCommands lets you override all global commands -func (r RestClientImpl) SetGlobalCommands(applicationID api.Snowflake, commands ...api.Command) (cmds []*api.Command, err error) { +func (r RestClientImpl) SetGlobalCommands(applicationID api.Snowflake, commands ...*api.CommandCreate) (cmds []*api.Command, err error) { compiledRoute, err := endpoints.SetGlobalCommands.Compile(applicationID) if err != nil { return nil, err @@ -517,7 +525,7 @@ func (r RestClientImpl) SetGlobalCommands(applicationID api.Snowflake, commands err = api.ErrTooMuchApplicationCommands return } - err = r.Request(*compiledRoute, commands, &cmds) + err = r.Request(compiledRoute, commands, &cmds) if err == nil { for _, cmd := range cmds { cmd = r.Disgo().EntityBuilder().CreateGlobalCommand(cmd, api.CacheStrategyNoWs) @@ -527,12 +535,12 @@ func (r RestClientImpl) SetGlobalCommands(applicationID api.Snowflake, commands } // EditGlobalCommand lets you edit a specific global command -func (r RestClientImpl) EditGlobalCommand(applicationID api.Snowflake, commandID api.Snowflake, command api.UpdateCommand) (cmd *api.Command, err error) { +func (r RestClientImpl) EditGlobalCommand(applicationID api.Snowflake, commandID api.Snowflake, command *api.CommandUpdate) (cmd *api.Command, err error) { compiledRoute, err := endpoints.EditGlobalCommand.Compile(applicationID, commandID) if err != nil { return nil, err } - err = r.Request(*compiledRoute, command, &cmd) + err = r.Request(compiledRoute, command, &cmd) if err == nil { cmd = r.Disgo().EntityBuilder().CreateGlobalCommand(cmd, api.CacheStrategyNoWs) } @@ -545,7 +553,7 @@ func (r RestClientImpl) DeleteGlobalCommand(applicationID api.Snowflake, command if err != nil { return err } - err = r.Request(*compiledRoute, nil, nil) + err = r.Request(compiledRoute, nil, nil) if err == nil && api.CacheStrategyNoWs(r.Disgo()) { r.Disgo().Cache().UncacheCommand(commandID) } @@ -558,7 +566,7 @@ func (r RestClientImpl) GetGuildCommands(applicationID api.Snowflake, guildID ap if err != nil { return nil, err } - err = r.Request(*compiledRoute, nil, &commands) + err = r.Request(compiledRoute, nil, &commands) if err == nil { for _, cmd := range commands { cmd = r.Disgo().EntityBuilder().CreateGuildCommand(guildID, cmd, api.CacheStrategyNoWs) @@ -568,12 +576,12 @@ func (r RestClientImpl) GetGuildCommands(applicationID api.Snowflake, guildID ap } // CreateGuildCommand lets you create a new guild_events command -func (r RestClientImpl) CreateGuildCommand(applicationID api.Snowflake, guildID api.Snowflake, command api.Command) (cmd *api.Command, err error) { +func (r RestClientImpl) CreateGuildCommand(applicationID api.Snowflake, guildID api.Snowflake, command *api.CommandCreate) (cmd *api.Command, err error) { compiledRoute, err := endpoints.CreateGuildCommand.Compile(applicationID, guildID) if err != nil { return nil, err } - err = r.Request(*compiledRoute, command, &cmd) + err = r.Request(compiledRoute, command, &cmd) if err == nil { cmd = r.Disgo().EntityBuilder().CreateGuildCommand(guildID, cmd, api.CacheStrategyNoWs) } @@ -581,7 +589,7 @@ func (r RestClientImpl) CreateGuildCommand(applicationID api.Snowflake, guildID } // SetGuildCommands lets you override all guild_events commands -func (r RestClientImpl) SetGuildCommands(applicationID api.Snowflake, guildID api.Snowflake, commands ...api.Command) (cmds []*api.Command, err error) { +func (r RestClientImpl) SetGuildCommands(applicationID api.Snowflake, guildID api.Snowflake, commands ...*api.CommandCreate) (cmds []*api.Command, err error) { compiledRoute, err := endpoints.SetGuildCommands.Compile(applicationID, guildID) if err != nil { return nil, err @@ -590,7 +598,7 @@ func (r RestClientImpl) SetGuildCommands(applicationID api.Snowflake, guildID ap err = api.ErrTooMuchApplicationCommands return } - err = r.Request(*compiledRoute, commands, &cmds) + err = r.Request(compiledRoute, commands, &cmds) if err == nil { for _, cmd := range cmds { cmd = r.Disgo().EntityBuilder().CreateGuildCommand(guildID, cmd, api.CacheStrategyNoWs) @@ -605,7 +613,7 @@ func (r RestClientImpl) GetGuildCommand(applicationID api.Snowflake, guildID api if err != nil { return nil, err } - err = r.Request(*compiledRoute, nil, &cmd) + err = r.Request(compiledRoute, nil, &cmd) if err == nil { cmd = r.Disgo().EntityBuilder().CreateGuildCommand(guildID, cmd, api.CacheStrategyNoWs) } @@ -613,12 +621,12 @@ func (r RestClientImpl) GetGuildCommand(applicationID api.Snowflake, guildID api } // EditGuildCommand lets you edit a specific guild_events command -func (r RestClientImpl) EditGuildCommand(applicationID api.Snowflake, guildID api.Snowflake, commandID api.Snowflake, command api.UpdateCommand) (cmd *api.Command, err error) { +func (r RestClientImpl) EditGuildCommand(applicationID api.Snowflake, guildID api.Snowflake, commandID api.Snowflake, command *api.CommandUpdate) (cmd *api.Command, err error) { compiledRoute, err := endpoints.EditGuildCommand.Compile(applicationID, guildID, commandID) if err != nil { return nil, err } - err = r.Request(*compiledRoute, command, &cmd) + err = r.Request(compiledRoute, command, &cmd) if err == nil { cmd = r.Disgo().EntityBuilder().CreateGuildCommand(guildID, cmd, api.CacheStrategyNoWs) } @@ -631,7 +639,7 @@ func (r RestClientImpl) DeleteGuildCommand(applicationID api.Snowflake, guildID if err != nil { return err } - err = r.Request(*compiledRoute, nil, nil) + err = r.Request(compiledRoute, nil, nil) if err == nil && api.CacheStrategyNoWs(r.Disgo()) { r.Disgo().Cache().UncacheCommand(commandID) } @@ -644,7 +652,7 @@ func (r RestClientImpl) GetGuildCommandsPermissions(applicationID api.Snowflake, if err != nil { return nil, err } - err = r.Request(*compiledRoute, nil, &cmdsPerms) + err = r.Request(compiledRoute, nil, &cmdsPerms) if err == nil { for _, cmdPerms := range cmdsPerms { cmdPerms = r.Disgo().EntityBuilder().CreateGuildCommandPermissions(cmdPerms, api.CacheStrategyNoWs) @@ -659,7 +667,7 @@ func (r RestClientImpl) GetGuildCommandPermissions(applicationID api.Snowflake, if err != nil { return nil, err } - err = r.Request(*compiledRoute, nil, &cmdPerms) + err = r.Request(compiledRoute, nil, &cmdPerms) if err == nil { cmdPerms = r.Disgo().EntityBuilder().CreateGuildCommandPermissions(cmdPerms, api.CacheStrategyNoWs) } @@ -667,12 +675,12 @@ func (r RestClientImpl) GetGuildCommandPermissions(applicationID api.Snowflake, } // SetGuildCommandsPermissions sets the api.GuildCommandPermissions for a all api.Command(s) -func (r RestClientImpl) SetGuildCommandsPermissions(applicationID api.Snowflake, guildID api.Snowflake, commandsPermissions ...api.SetGuildCommandPermissions) (cmdsPerms []*api.GuildCommandPermissions, err error) { +func (r RestClientImpl) SetGuildCommandsPermissions(applicationID api.Snowflake, guildID api.Snowflake, commandsPermissions ...*api.SetGuildCommandPermissions) (cmdsPerms []*api.GuildCommandPermissions, err error) { compiledRoute, err := endpoints.SetGuildCommandsPermissions.Compile(applicationID, guildID) if err != nil { return nil, err } - err = r.Request(*compiledRoute, api.SetGuildCommandsPermissions(commandsPermissions), &cmdsPerms) + err = r.Request(compiledRoute, api.SetGuildCommandsPermissions(commandsPermissions), &cmdsPerms) if err == nil { for _, cmdPerms := range cmdsPerms { cmdPerms = r.Disgo().EntityBuilder().CreateGuildCommandPermissions(cmdPerms, api.CacheStrategyNoWs) @@ -682,12 +690,12 @@ func (r RestClientImpl) SetGuildCommandsPermissions(applicationID api.Snowflake, } // SetGuildCommandPermissions sets the api.GuildCommandPermissions for a specific api.Command -func (r RestClientImpl) SetGuildCommandPermissions(applicationID api.Snowflake, guildID api.Snowflake, commandID api.Snowflake, commandPermissions api.SetGuildCommandPermissions) (cmdPerms *api.GuildCommandPermissions, err error) { +func (r RestClientImpl) SetGuildCommandPermissions(applicationID api.Snowflake, guildID api.Snowflake, commandID api.Snowflake, commandPermissions *api.SetGuildCommandPermissions) (cmdPerms *api.GuildCommandPermissions, err error) { compiledRoute, err := endpoints.SetGuildCommandPermissions.Compile(applicationID, guildID, commandID) if err != nil { return nil, err } - err = r.Request(*compiledRoute, commandPermissions, &cmdPerms) + err = r.Request(compiledRoute, commandPermissions, &cmdPerms) if err == nil { cmdPerms = r.Disgo().EntityBuilder().CreateGuildCommandPermissions(cmdPerms, api.CacheStrategyNoWs) } @@ -695,57 +703,57 @@ func (r RestClientImpl) SetGuildCommandPermissions(applicationID api.Snowflake, } // SendInteractionResponse used to send the initial response on an interaction -func (r RestClientImpl) SendInteractionResponse(interactionID api.Snowflake, interactionToken endpoints.Token, interactionResponse api.InteractionResponse) error { +func (r RestClientImpl) SendInteractionResponse(interactionID api.Snowflake, interactionToken string, interactionResponse *api.InteractionResponse) error { compiledRoute, err := endpoints.CreateInteractionResponse.Compile(interactionID, interactionToken) if err != nil { return err } - return r.Request(*compiledRoute, interactionResponse, nil) + return r.Request(compiledRoute, interactionResponse, nil) } // EditInteractionResponse used to edit the initial response on an interaction -func (r RestClientImpl) EditInteractionResponse(applicationID api.Snowflake, interactionToken endpoints.Token, followupMessage api.FollowupMessage) (message *api.Message, err error) { +func (r RestClientImpl) EditInteractionResponse(applicationID api.Snowflake, interactionToken string, followupMessage *api.FollowupMessage) (message *api.Message, err error) { compiledRoute, err := endpoints.EditInteractionResponse.Compile(applicationID, interactionToken) if err != nil { return nil, err } - return message, r.Request(*compiledRoute, followupMessage, &message) + return message, r.Request(compiledRoute, followupMessage, &message) } // DeleteInteractionResponse used to delete the initial response on an interaction -func (r RestClientImpl) DeleteInteractionResponse(applicationID api.Snowflake, interactionToken endpoints.Token) error { +func (r RestClientImpl) DeleteInteractionResponse(applicationID api.Snowflake, interactionToken string) error { compiledRoute, err := endpoints.DeleteInteractionResponse.Compile(applicationID, interactionToken) if err != nil { return err } - return r.Request(*compiledRoute, nil, nil) + return r.Request(compiledRoute, nil, nil) } // SendFollowupMessage used to send a followup message_events to an interaction -func (r RestClientImpl) SendFollowupMessage(applicationID api.Snowflake, interactionToken endpoints.Token, followupMessage api.FollowupMessage) (message *api.Message, err error) { +func (r RestClientImpl) SendFollowupMessage(applicationID api.Snowflake, interactionToken string, followupMessage *api.FollowupMessage) (message *api.Message, err error) { compiledRoute, err := endpoints.CreateFollowupMessage.Compile(applicationID, interactionToken) if err != nil { return nil, err } - return message, r.Request(*compiledRoute, followupMessage, &message) + return message, r.Request(compiledRoute, followupMessage, &message) } // EditFollowupMessage used to edit a api.FollowupMessage from an api.Interaction -func (r RestClientImpl) EditFollowupMessage(applicationID api.Snowflake, interactionToken endpoints.Token, messageID api.Snowflake, followupMessage api.FollowupMessage) (message *api.Message, err error) { +func (r RestClientImpl) EditFollowupMessage(applicationID api.Snowflake, interactionToken string, messageID api.Snowflake, followupMessage *api.FollowupMessage) (message *api.Message, err error) { compiledRoute, err := endpoints.EditFollowupMessage.Compile(applicationID, interactionToken, messageID) if err != nil { return nil, err } - return message, r.Request(*compiledRoute, followupMessage, &message) + return message, r.Request(compiledRoute, followupMessage, &message) } // DeleteFollowupMessage used to delete a api.FollowupMessage from an api.Interaction -func (r RestClientImpl) DeleteFollowupMessage(applicationID api.Snowflake, interactionToken endpoints.Token, messageID api.Snowflake) error { +func (r RestClientImpl) DeleteFollowupMessage(applicationID api.Snowflake, interactionToken string, messageID api.Snowflake) error { compiledRoute, err := endpoints.DeleteFollowupMessage.Compile(applicationID, interactionToken, messageID) if err != nil { return err } - return r.Request(*compiledRoute, nil, nil) + return r.Request(compiledRoute, nil, nil) } func normalizeEmoji(emoji string) string { diff --git a/internal/util.go b/internal/util.go index 15a5f35c..92be3dbb 100644 --- a/internal/util.go +++ b/internal/util.go @@ -6,12 +6,11 @@ import ( "strings" "github.com/DisgoOrg/disgo/api" - "github.com/DisgoOrg/disgo/api/endpoints" ) // IDFromToken returns the applicationID from the BotToken -func IDFromToken(token endpoints.Token) (*api.Snowflake, error) { - strs := strings.Split(string(token), ".") +func IDFromToken(token string) (*api.Snowflake, error) { + strs := strings.Split(token, ".") if len(strs) == 0 { return nil, errors.New("BotToken is not in a valid format") } diff --git a/internal/webhook_server_impl.go b/internal/webhook_server_impl.go index 5a17e66c..6b4403aa 100644 --- a/internal/webhook_server_impl.go +++ b/internal/webhook_server_impl.go @@ -94,6 +94,7 @@ func (h *webhookInteractionHandler) ServeHTTP(w http.ResponseWriter, r *http.Req rawBody, err := ioutil.ReadAll(r.Body) if err != nil { w.WriteHeader(http.StatusBadRequest) + return } c := make(chan interface{}) go h.webhookServer.Disgo().EventManager().Handle(api.WebhookEventInteractionCreate, c, -1, rawBody)