diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..63e14622f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,60 @@ +on: + push: + pull_request: + +name: CI + +jobs: + format: + runs-on: ubuntu-latest + steps: + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: 1.17 + - name: Code + uses: actions/checkout@v2 + - name: Check diff between gofmt and code + run: diff <(gofmt -d .) <(echo -n) + + test: + runs-on: ubuntu-latest + strategy: + matrix: + go-version: [1.13, 1.14, 1.15, 1.16, 1.17] + steps: + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go-version }} + - name: Code + uses: actions/checkout@v2 + - run: go test -v -race ./... + + lint: + runs-on: ubuntu-latest + steps: + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: 1.17 + - name: Code + uses: actions/checkout@v2 + - name: Go vet + run: go vet -x ./... + + - name: GolangCI-Lint + uses: golangci/golangci-lint-action@v2.5.2 + if: github.event.name == 'pull_request' + with: + only-new-issues: true + skip-pkg-cache: true + skip-build-cache: true + + - name: GolangCI-Lint + if: github.event.name != 'pull_request' # See https://github.com/golangci/golangci-lint-action/issues/362 + run: | + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.43.0 + + $(go env GOPATH)/bin/golangci-lint run + diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 000000000..dd9d2e5b4 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,19 @@ +linters: + disable-all: true + enable: + # - staticcheck + # - unused + - golint + +linters-settings: + staticcheck: + go: "1.13" + + checks: ["all"] + + unused: + go: "1.13" + +issues: + include: + - EXC0002 diff --git a/README.md b/README.md index b1928bd02..2bcd43b81 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Go Reference](https://pkg.go.dev/badge/github.com/bwmarrin/discordgo.svg)](https://pkg.go.dev/github.com/bwmarrin/discordgo) [![Go Report Card](https://goreportcard.com/badge/github.com/bwmarrin/discordgo)](https://goreportcard.com/report/github.com/bwmarrin/discordgo) [![Build Status](https://travis-ci.com/bwmarrin/discordgo.svg?branch=master)](https://travis-ci.com/bwmarrin/discordgo) [![Discord Gophers](https://img.shields.io/badge/Discord%20Gophers-%23discordgo-blue.svg)](https://discord.gg/golang) [![Discord API](https://img.shields.io/badge/Discord%20API-%23go_discordgo-blue.svg)](https://discord.com/invite/discord-api) - +DiscordGo logo DiscordGo is a [Go](https://golang.org/) package that provides low level bindings to the [Discord](https://discord.com/) chat client API. DiscordGo diff --git a/components.go b/components.go index 2ad19a07d..a6716c0ef 100644 --- a/components.go +++ b/components.go @@ -13,6 +13,7 @@ const ( ActionsRowComponent ComponentType = 1 ButtonComponent ComponentType = 2 SelectMenuComponent ComponentType = 3 + TextInputComponent ComponentType = 4 ) // MessageComponent is a base interface for all message components. @@ -42,12 +43,15 @@ func (umc *unmarshalableMessageComponent) UnmarshalJSON(src []byte) error { umc.MessageComponent = &Button{} case SelectMenuComponent: umc.MessageComponent = &SelectMenu{} + case TextInputComponent: + umc.MessageComponent = &TextInput{} default: return fmt.Errorf("unknown component type: %d", v.Type) } return json.Unmarshal(src, umc.MessageComponent) } +// MessageComponentFromJSON is a helper function for unmarshaling message components func MessageComponentFromJSON(b []byte) (MessageComponent, error) { var u unmarshalableMessageComponent err := u.UnmarshalJSON(b) @@ -195,3 +199,42 @@ func (m SelectMenu) MarshalJSON() ([]byte, error) { Type: m.Type(), }) } + +// TextInput represents text input component. +type TextInput struct { + CustomID string `json:"custom_id"` + Label string `json:"label"` + Style TextInputStyle `json:"style"` + Placeholder string `json:"placeholder,omitempty"` + Value string `json:"value,omitempty"` + Required bool `json:"required,omitempty"` + MinLength int `json:"min_length,omitempty"` + MaxLength int `json:"max_length,omitempty"` +} + +// Type is a method to get the type of a component. +func (TextInput) Type() ComponentType { + return TextInputComponent +} + +// MarshalJSON is a method for marshaling TextInput to a JSON object. +func (m TextInput) MarshalJSON() ([]byte, error) { + type inputText TextInput + + return json.Marshal(struct { + inputText + Type ComponentType `json:"type"` + }{ + inputText: inputText(m), + Type: m.Type(), + }) +} + +// TextInputStyle is style of text in TextInput component. +type TextInputStyle uint + +// Text styles +const ( + TextInputShort TextInputStyle = 1 + TextInputParagraph TextInputStyle = 2 +) diff --git a/discord_test.go b/discord_test.go index 973e3a654..720397ba3 100644 --- a/discord_test.go +++ b/discord_test.go @@ -15,14 +15,14 @@ var ( dg *Session // Stores a global discordgo user session dgBot *Session // Stores a global discordgo bot session - envToken = os.Getenv("DGU_TOKEN") // Token to use when authenticating the user account - envBotToken = os.Getenv("DGB_TOKEN") // Token to use when authenticating the bot account - envGuild = os.Getenv("DG_GUILD") // Guild ID to use for tests - envChannel = os.Getenv("DG_CHANNEL") // Channel ID to use for tests - envAdmin = os.Getenv("DG_ADMIN") // User ID of admin user to use for tests + envOAuth2Token = os.Getenv("DG_OAUTH2_TOKEN") // Token to use when authenticating using OAuth2 token + envBotToken = os.Getenv("DGB_TOKEN") // Token to use when authenticating the bot account + envGuild = os.Getenv("DG_GUILD") // Guild ID to use for tests + envChannel = os.Getenv("DG_CHANNEL") // Channel ID to use for tests + envAdmin = os.Getenv("DG_ADMIN") // User ID of admin user to use for tests ) -func init() { +func TestMain(m *testing.M) { fmt.Println("Init is being called.") if envBotToken != "" { if d, err := New(envBotToken); err == nil { @@ -30,11 +30,17 @@ func init() { } } - if d, err := New(envToken); err == nil { - dg = d - } else { - fmt.Println("dg is nil, error", err) + if envOAuth2Token == "" { + envOAuth2Token = os.Getenv("DGU_TOKEN") } + + if envOAuth2Token != "" { + if d, err := New(envOAuth2Token); err == nil { + dg = d + } + } + + os.Exit(m.Run()) } ////////////////////////////////////////////////////////////////////////////// @@ -43,11 +49,11 @@ func init() { // TestNewToken tests the New() function with a Token. func TestNewToken(t *testing.T) { - if envToken == "" { + if envOAuth2Token == "" { t.Skip("Skipping New(token), DGU_TOKEN not set") } - d, err := New(envToken) + d, err := New(envOAuth2Token) if err != nil { t.Fatalf("New(envToken) returned error: %+v", err) } @@ -62,11 +68,11 @@ func TestNewToken(t *testing.T) { } func TestOpenClose(t *testing.T) { - if envToken == "" { + if envOAuth2Token == "" { t.Skip("Skipping TestClose, DGU_TOKEN not set") } - d, err := New(envToken) + d, err := New(envOAuth2Token) if err != nil { t.Fatalf("TestClose, New(envToken) returned error: %+v", err) } diff --git a/docs/img/discordgo.png b/docs/img/discordgo.png deleted file mode 100644 index eb15a3dc0..000000000 Binary files a/docs/img/discordgo.png and /dev/null differ diff --git a/docs/img/discordgo.svg b/docs/img/discordgo.svg new file mode 100644 index 000000000..059ae7ab7 --- /dev/null +++ b/docs/img/discordgo.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/endpoints.go b/endpoints.go index f6eb5eb17..5e9dabc94 100644 --- a/endpoints.go +++ b/endpoints.go @@ -108,6 +108,7 @@ var ( EndpointThreadMembers = func(tID string) string { return EndpointChannel(tID) + "/thread-members" } EndpointThreadMember = func(tID, mID string) string { return EndpointThreadMembers(tID) + "/" + mID } + EndpointGroupIcon = func(cID, hash string) string { return EndpointCDNChannelIcons + cID + "/" + hash + ".png" } EndpointSticker = func(sID string) string { return EndpointStickers + sID } @@ -143,6 +144,12 @@ var ( EndpointApplicationGuildCommand = func(aID, gID, cID string) string { return EndpointApplicationGuildCommands(aID, gID) + "/" + cID } + EndpointApplicationCommandPermissions = func(aID, gID, cID string) string { + return EndpointApplicationGuildCommand(aID, gID, cID) + "/permissions" + } + EndpointApplicationCommandsGuildPermissions = func(aID, gID string) string { + return EndpointApplicationGuildCommands(aID, gID) + "/permissions" + } EndpointInteraction = func(aID, iToken string) string { return EndpointAPI + "interactions/" + aID + "/" + iToken } diff --git a/examples/autocomplete/main.go b/examples/autocomplete/main.go index 3e509af4d..55dbc6a39 100644 --- a/examples/autocomplete/main.go +++ b/examples/autocomplete/main.go @@ -239,8 +239,8 @@ func main() { log.Fatalf("Cannot register commands: %v", err) } - stop := make(chan os.Signal) - signal.Notify(stop, os.Interrupt) //nolint: staticcheck + stop := make(chan os.Signal, 1) + signal.Notify(stop, os.Interrupt) <-stop log.Println("Gracefully shutting down") diff --git a/examples/avatar/main.go b/examples/avatar/main.go index e0a9c8802..58fa608fd 100644 --- a/examples/avatar/main.go +++ b/examples/avatar/main.go @@ -82,7 +82,7 @@ func main() { // Now lets format our base64 image into the proper format Discord wants // and then call UserUpdate to set it as our user's Avatar. avatar := fmt.Sprintf("data:%s;base64,%s", contentType, base64img) - _, err = dg.UserUpdate("", "", "", avatar, "") + _, err = dg.UserUpdate("", avatar) if err != nil { fmt.Println(err) } diff --git a/examples/modals/main.go b/examples/modals/main.go new file mode 100644 index 000000000..effd8f1a3 --- /dev/null +++ b/examples/modals/main.go @@ -0,0 +1,160 @@ +package main + +import ( + "flag" + "fmt" + "log" + "os" + "os/signal" + "strings" + + "github.com/bwmarrin/discordgo" +) + +// Bot parameters +var ( + GuildID = flag.String("guild", "", "Test guild ID") + BotToken = flag.String("token", "", "Bot access token") + AppID = flag.String("app", "", "Application ID") + Cleanup = flag.Bool("cleanup", true, "Cleanup of commands") + ResultsChannel = flag.String("results", "", "Channel where send survey results to") +) + +var s *discordgo.Session + +func init() { + flag.Parse() +} + +func init() { + var err error + s, err = discordgo.New("Bot " + *BotToken) + if err != nil { + log.Fatalf("Invalid bot parameters: %v", err) + } +} + +var ( + commands = []discordgo.ApplicationCommand{ + { + Name: "modals-survey", + Description: "Take a survey about modals", + }, + } + commandsHandlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){ + "modals-survey": func(s *discordgo.Session, i *discordgo.InteractionCreate) { + err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ + Type: discordgo.InteractionResponseModal, + Data: &discordgo.InteractionResponseData{ + CustomID: "modals_survey_" + i.Interaction.Member.User.ID, + Title: "Modals survey", + Components: []discordgo.MessageComponent{ + discordgo.ActionsRow{ + Components: []discordgo.MessageComponent{ + discordgo.TextInput{ + CustomID: "opinion", + Label: "What is your opinion on them?", + Style: discordgo.TextInputShort, + Placeholder: "Don't be shy, share your opinion with us", + Required: true, + MaxLength: 300, + MinLength: 10, + }, + }, + }, + discordgo.ActionsRow{ + Components: []discordgo.MessageComponent{ + discordgo.TextInput{ + CustomID: "suggestions", + Label: "What would you suggest to improve them?", + Style: discordgo.TextInputParagraph, + Required: false, + MaxLength: 2000, + }, + }, + }, + }, + }, + }) + if err != nil { + panic(err) + } + }, + } +) + +func main() { + s.AddHandler(func(s *discordgo.Session, r *discordgo.Ready) { + log.Println("Bot is up!") + }) + + s.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) { + switch i.Type { + case discordgo.InteractionApplicationCommand: + if h, ok := commandsHandlers[i.ApplicationCommandData().Name]; ok { + h(s, i) + } + case discordgo.InteractionModalSubmit: + err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ + Type: discordgo.InteractionResponseChannelMessageWithSource, + Data: &discordgo.InteractionResponseData{ + Content: "Thank you for taking your time to fill this survey", + Flags: 1 << 6, + }, + }) + if err != nil { + panic(err) + } + data := i.ModalSubmitData() + + if !strings.HasPrefix(data.CustomID, "modals_survey") { + return + } + + userid := strings.Split(data.CustomID, "_")[2] + _, err = s.ChannelMessageSend(*ResultsChannel, fmt.Sprintf( + "Feedback received. From <@%s>\n\n**Opinion**:\n%s\n\n**Suggestions**:\n%s", + userid, + data.Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value, + data.Components[1].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value, + )) + if err != nil { + panic(err) + } + } + }) + + cmdIDs := make(map[string]string, len(commands)) + + for _, cmd := range commands { + rcmd, err := s.ApplicationCommandCreate(*AppID, *GuildID, &cmd) + if err != nil { + log.Fatalf("Cannot create slash command %q: %v", cmd.Name, err) + } + + cmdIDs[rcmd.ID] = rcmd.Name + } + + err := s.Open() + if err != nil { + log.Fatalf("Cannot open the session: %v", err) + } + defer s.Close() + + stop := make(chan os.Signal, 1) + signal.Notify(stop, os.Interrupt) + <-stop + log.Println("Graceful shutdown") + + if !*Cleanup { + return + } + + for id, name := range cmdIDs { + err := s.ApplicationCommandDelete(*AppID, *GuildID, id) + if err != nil { + log.Fatalf("Cannot delete slash command %q: %v", name, err) + } + } + +} diff --git a/examples/slash_commands/main.go b/examples/slash_commands/main.go index 1cb3dead0..3a1cf584c 100644 --- a/examples/slash_commands/main.go +++ b/examples/slash_commands/main.go @@ -379,7 +379,7 @@ func main() { defer s.Close() - stop := make(chan os.Signal) + stop := make(chan os.Signal, 1) signal.Notify(stop, os.Interrupt) <-stop log.Println("Gracefully shutdowning") diff --git a/interactions.go b/interactions.go index ef4427513..9ce3d4811 100644 --- a/interactions.go +++ b/interactions.go @@ -30,15 +30,17 @@ const ( // ApplicationCommand represents an application's slash command. type ApplicationCommand struct { - ID string `json:"id,omitempty"` - ApplicationID string `json:"application_id,omitempty"` - Type ApplicationCommandType `json:"type,omitempty"` - Name string `json:"name"` - // NOTE: Chat commands only. Otherwise it mustn't be set. - Description string `json:"description,omitempty"` - Version string `json:"version,omitempty"` + ID string `json:"id,omitempty"` + ApplicationID string `json:"application_id,omitempty"` + Version string `json:"version,omitempty"` + Type ApplicationCommandType `json:"type,omitempty"` + Name string `json:"name"` + DefaultPermission *bool `json:"default_permission,omitempty"` + // NOTE: Chat commands only. Otherwise it mustn't be set. - Options []*ApplicationCommandOption `json:"options"` + + Description string `json:"description,omitempty"` + Options []*ApplicationCommandOption `json:"options"` } // ApplicationCommandOptionType indicates the type of a slash command's option. @@ -55,6 +57,7 @@ const ( ApplicationCommandOptionChannel ApplicationCommandOptionType = 7 ApplicationCommandOptionRole ApplicationCommandOptionType = 8 ApplicationCommandOptionMentionable ApplicationCommandOptionType = 9 + ApplicationCommandOptionAttachment ApplicationCommandOptionType = 11 ) func (t ApplicationCommandOptionType) String() string { @@ -77,6 +80,8 @@ func (t ApplicationCommandOptionType) String() string { return "Role" case ApplicationCommandOptionMentionable: return "Mentionable" + case ApplicationCommandOptionAttachment: + return "Attachment" } return fmt.Sprintf("ApplicationCommandOptionType(%d)", t) } @@ -104,6 +109,35 @@ type ApplicationCommandOptionChoice struct { Value interface{} `json:"value"` } +// ApplicationCommandPermissions represents a single user or role permission for a command. +type ApplicationCommandPermissions struct { + ID string `json:"id"` + Type ApplicationCommandPermissionType `json:"type"` + Permission bool `json:"permission"` +} + +// ApplicationCommandPermissionsList represents a list of ApplicationCommandPermissions, needed for serializing to JSON. +type ApplicationCommandPermissionsList struct { + Permissions []*ApplicationCommandPermissions `json:"permissions"` +} + +// GuildApplicationCommandPermissions represents all permissions for a single guild command. +type GuildApplicationCommandPermissions struct { + ID string `json:"id"` + ApplicationID string `json:"application_id"` + GuildID string `json:"guild_id"` + Permissions []*ApplicationCommandPermissions `json:"permissions"` +} + +// ApplicationCommandPermissionType indicates whether a permission is user or role based. +type ApplicationCommandPermissionType uint8 + +// Application command permission types. +const ( + ApplicationCommandPermissionTypeRole ApplicationCommandPermissionType = 1 + ApplicationCommandPermissionTypeUser ApplicationCommandPermissionType = 2 +) + // InteractionType indicates the type of an interaction event. type InteractionType uint8 @@ -113,6 +147,7 @@ const ( InteractionApplicationCommand InteractionType = 2 InteractionMessageComponent InteractionType = 3 InteractionApplicationCommandAutocomplete InteractionType = 4 + InteractionModalSubmit InteractionType = 5 ) func (t InteractionType) String() string { @@ -123,6 +158,8 @@ func (t InteractionType) String() string { return "ApplicationCommand" case InteractionMessageComponent: return "MessageComponent" + case InteractionModalSubmit: + return "ModalSubmit" } return fmt.Sprintf("InteractionType(%d)", t) } @@ -192,6 +229,13 @@ func (i *Interaction) UnmarshalJSON(raw []byte) error { return err } i.Data = v + case InteractionModalSubmit: + v := ModalSubmitInteractionData{} + err = json.Unmarshal(tmp.Data, &v) + if err != nil { + return err + } + i.Data = v } return nil } @@ -214,6 +258,15 @@ func (i Interaction) ApplicationCommandData() (data ApplicationCommandInteractio return i.Data.(ApplicationCommandInteractionData) } +// ModalSubmitData is helper function to assert the inner InteractionData to ModalSubmitInteractionData. +// Make sure to check that the Type of the interaction is InteractionModalSubmit before calling. +func (i Interaction) ModalSubmitData() (data ModalSubmitInteractionData) { + if i.Type != InteractionModalSubmit { + panic("ModalSubmitData called on interaction of type " + i.Type.String()) + } + return i.Data.(ModalSubmitInteractionData) +} + // InteractionData is a common interface for all types of interaction data. type InteractionData interface { Type() InteractionType @@ -236,11 +289,12 @@ type ApplicationCommandInteractionData struct { // Partial Member objects are missing user, deaf and mute fields. // Partial Channel objects only have id, name, type and permissions fields. type ApplicationCommandInteractionDataResolved struct { - Users map[string]*User `json:"users"` - Members map[string]*Member `json:"members"` - Roles map[string]*Role `json:"roles"` - Channels map[string]*Channel `json:"channels"` - Messages map[string]*Message `json:"messages"` + Users map[string]*User `json:"users"` + Members map[string]*Member `json:"members"` + Roles map[string]*Role `json:"roles"` + Channels map[string]*Channel `json:"channels"` + Messages map[string]*Message `json:"messages"` + Attachments map[string]*MessageAttachment `json:"attachments"` } // Type returns the type of interaction data. @@ -262,6 +316,36 @@ func (MessageComponentInteractionData) Type() InteractionType { return InteractionMessageComponent } +// ModalSubmitInteractionData contains the data of modal submit interaction. +type ModalSubmitInteractionData struct { + CustomID string `json:"custom_id"` + Components []MessageComponent `json:"-"` +} + +// Type returns the type of interaction data. +func (ModalSubmitInteractionData) Type() InteractionType { + return InteractionModalSubmit +} + +// UnmarshalJSON is a helper function to correctly unmarshal Components. +func (d *ModalSubmitInteractionData) UnmarshalJSON(data []byte) error { + type modalSubmitInteractionData ModalSubmitInteractionData + var v struct { + modalSubmitInteractionData + RawComponents []unmarshalableMessageComponent `json:"components"` + } + err := json.Unmarshal(data, &v) + if err != nil { + return err + } + *d = ModalSubmitInteractionData(v.modalSubmitInteractionData) + d.Components = make([]MessageComponent, len(v.RawComponents)) + for i, v := range v.RawComponents { + d.Components[i] = v.MessageComponent + } + return err +} + // ApplicationCommandInteractionDataOption represents an option of a slash command. type ApplicationCommandInteractionDataOption struct { Name string `json:"name"` @@ -404,6 +488,8 @@ const ( InteractionResponseUpdateMessage InteractionResponseType = 7 // InteractionApplicationCommandAutocompleteResult shows autocompletion results. Autocomplete interaction only. InteractionApplicationCommandAutocompleteResult InteractionResponseType = 8 + // InteractionResponseModal is for responding to an interaction with a modal window. + InteractionResponseModal InteractionResponseType = 9 ) // InteractionResponse represents a response for an interaction event. @@ -424,6 +510,11 @@ type InteractionResponseData struct { // NOTE: autocomplete interaction only. Choices []*ApplicationCommandOptionChoice `json:"choices,omitempty"` + + // NOTE: modal interaction only. + + CustomID string `json:"custom_id,omitempty"` + Title string `json:"title,omitempty"` } // VerifyInteraction implements message verification of the discord interactions api diff --git a/message.go b/message.go index a76a98b85..00ea50a45 100644 --- a/message.go +++ b/message.go @@ -190,11 +190,24 @@ type MessageFlags int // Valid MessageFlags values const ( - MessageFlagsCrossPosted MessageFlags = 1 << 0 - MessageFlagsIsCrossPosted MessageFlags = 1 << 1 - MessageFlagsSupressEmbeds MessageFlags = 1 << 2 + // MessageFlagsCrossPosted This message has been published to subscribed channels (via Channel Following). + MessageFlagsCrossPosted MessageFlags = 1 << 0 + // MessageFlagsIsCrossPosted this message originated from a message in another channel (via Channel Following). + MessageFlagsIsCrossPosted MessageFlags = 1 << 1 + // MessageFlagsSupressEmbeds do not include any embeds when serializing this message. + MessageFlagsSupressEmbeds MessageFlags = 1 << 2 + // MessageFlagsSourceMessageDeleted the source message for this crosspost has been deleted (via Channel Following). MessageFlagsSourceMessageDeleted MessageFlags = 1 << 3 - MessageFlagsUrgent MessageFlags = 1 << 4 + // MessageFlagsUrgent this message came from the urgent message system. + MessageFlagsUrgent MessageFlags = 1 << 4 + // MessageFlagsHasThread this message has an associated thread, with the same id as the message. + MessageFlagsHasThread MessageFlags = 1 << 5 + // MessageFlagsEphemeral this message is only visible to the user who invoked the Interaction. + MessageFlagsEphemeral MessageFlags = 1 << 6 + // MessageFlagsLoading this message is an Interaction Response and the bot is "thinking". + MessageFlagsLoading MessageFlags = 1 << 7 + // MessageFlagsFailedToMentionSomeRolesInThread this message failed to mention some roles and add their members to the thread. + MessageFlagsFailedToMentionSomeRolesInThread MessageFlags = 1 << 8 ) // File stores info about files you e.g. send in messages. diff --git a/restapi.go b/restapi.go index 453b60929..c2836cb48 100644 --- a/restapi.go +++ b/restapi.go @@ -2523,6 +2523,62 @@ func (s *Session) ApplicationCommands(appID, guildID string) (cmd []*Application return } +// GuildApplicationCommandsPermissions returns permissions for application commands in a guild. +// appID : The application ID +// guildID : Guild ID to retrieve application commands permissions for. +func (s *Session) GuildApplicationCommandsPermissions(appID, guildID string) (permissions []*GuildApplicationCommandPermissions, err error) { + endpoint := EndpointApplicationCommandsGuildPermissions(appID, guildID) + + var body []byte + body, err = s.RequestWithBucketID("GET", endpoint, nil, endpoint) + if err != nil { + return + } + + err = unmarshal(body, &permissions) + return +} + +// ApplicationCommandPermissions returns all permissions of an application command +// appID : The Application ID +// guildID : The guild ID containing the application command +// cmdID : The command ID to retrieve the permissions of +func (s *Session) ApplicationCommandPermissions(appID, guildID, cmdID string) (permissions *GuildApplicationCommandPermissions, err error) { + endpoint := EndpointApplicationCommandPermissions(appID, guildID, cmdID) + + var body []byte + body, err = s.RequestWithBucketID("GET", endpoint, nil, endpoint) + if err != nil { + return + } + + err = unmarshal(body, &permissions) + return +} + +// ApplicationCommandPermissionsEdit edits the permissions of an application command +// appID : The Application ID +// guildID : The guild ID containing the application command +// cmdID : The command ID to edit the permissions of +// permissions : An object containing a list of permissions for the application command +func (s *Session) ApplicationCommandPermissionsEdit(appID, guildID, cmdID string, permissions *ApplicationCommandPermissionsList) (err error) { + endpoint := EndpointApplicationCommandPermissions(appID, guildID, cmdID) + + _, err = s.RequestWithBucketID("PUT", endpoint, permissions, endpoint) + return +} + +// ApplicationCommandPermissionsBatchEdit edits the permissions of a batch of commands +// appID : The Application ID +// guildID : The guild ID to batch edit commands of +// permissions : A list of permissions paired with a command ID, guild ID, and application ID per application command +func (s *Session) ApplicationCommandPermissionsBatchEdit(appID, guildID string, permissions []*GuildApplicationCommandPermissions) (err error) { + endpoint := EndpointApplicationCommandsGuildPermissions(appID, guildID) + + _, err = s.RequestWithBucketID("PUT", endpoint, permissions, endpoint) + return +} + // InteractionRespond creates the response to an interaction. // appID : The application ID. // interaction : Interaction instance. diff --git a/structs.go b/structs.go index 185c8597c..75390fc8b 100644 --- a/structs.go +++ b/structs.go @@ -1039,53 +1039,148 @@ type AuditLogChangeKey string // Block of valid AuditLogChangeKey const ( - AuditLogChangeKeyName AuditLogChangeKey = "name" - AuditLogChangeKeyIconHash AuditLogChangeKey = "icon_hash" - AuditLogChangeKeySplashHash AuditLogChangeKey = "splash_hash" - AuditLogChangeKeyOwnerID AuditLogChangeKey = "owner_id" - AuditLogChangeKeyRegion AuditLogChangeKey = "region" - AuditLogChangeKeyAfkChannelID AuditLogChangeKey = "afk_channel_id" - AuditLogChangeKeyAfkTimeout AuditLogChangeKey = "afk_timeout" - AuditLogChangeKeyMfaLevel AuditLogChangeKey = "mfa_level" - AuditLogChangeKeyVerificationLevel AuditLogChangeKey = "verification_level" - AuditLogChangeKeyExplicitContentFilter AuditLogChangeKey = "explicit_content_filter" + // AuditLogChangeKeyAfkChannelID is sent when afk channel changed (snowflake) - guild + AuditLogChangeKeyAfkChannelID AuditLogChangeKey = "afk_channel_id" + // AuditLogChangeKeyAfkTimeout is sent when afk timeout duration changed (int) - guild + AuditLogChangeKeyAfkTimeout AuditLogChangeKey = "afk_timeout" + // AuditLogChangeKeyAllow is sent when a permission on a text or voice channel was allowed for a role (string) - role + AuditLogChangeKeyAllow AuditLogChangeKey = "allow" + // AudirChangeKeyApplicationID is sent when application id of the added or removed webhook or bot (snowflake) - channel + AuditLogChangeKeyApplicationID AuditLogChangeKey = "application_id" + // AuditLogChangeKeyArchived is sent when thread was archived/unarchived (bool) - thread + AuditLogChangeKeyArchived AuditLogChangeKey = "archived" + // AuditLogChangeKeyAsset is sent when asset is changed (string) - sticker + AuditLogChangeKeyAsset AuditLogChangeKey = "asset" + // AuditLogChangeKeyAutoArchiveDuration is sent when auto archive duration changed (int) - thread + AuditLogChangeKeyAutoArchiveDuration AuditLogChangeKey = "auto_archive_duration" + // AuditLogChangeKeyAvailable is sent when availability of sticker changed (bool) - sticker + AuditLogChangeKeyAvailable AuditLogChangeKey = "available" + // AuditLogChangeKeyAvatarHash is sent when user avatar changed (string) - user + AuditLogChangeKeyAvatarHash AuditLogChangeKey = "avatar_hash" + // AuditLogChangeKeyBannerHash is sent when guild banner changed (string) - guild + AuditLogChangeKeyBannerHash AuditLogChangeKey = "banner_hash" + // AuditLogChangeKeyBitrate is sent when voice channel bitrate changed (int) - channel + AuditLogChangeKeyBitrate AuditLogChangeKey = "bitrate" + // AuditLogChangeKeyChannelID is sent when channel for invite code or guild scheduled event changed (snowflake) - invite or guild scheduled event + AuditLogChangeKeyChannelID AuditLogChangeKey = "channel_id" + // AuditLogChangeKeyCode is sent when invite code changed (string) - invite + AuditLogChangeKeyCode AuditLogChangeKey = "code" + // AuditLogChangeKeyColor is sent when role color changed (int) - role + AuditLogChangeKeyColor AuditLogChangeKey = "color" + // AuditLogChangeKeyCommunicationDisabledUntil is sent when member timeout state changed (ISO8601 timestamp) - member + AuditLogChangeKeyCommunicationDisabledUntil AuditLogChangeKey = "communication_disabled_until" + // AuditLogChangeKeyDeaf is sent when user server deafened/undeafened (bool) - member + AuditLogChangeKeyDeaf AuditLogChangeKey = "deaf" + // AuditLogChangeKeyDefaultAutoArchiveDuration is sent when default auto archive duration for newly created threads changed (int) - channel + AuditLogChangeKeyDefaultAutoArchiveDuration AuditLogChangeKey = "default_auto_archive_duration" + // AuditLogChangeKeyDefaultMessageNotification is sent when default message notification level changed (int) - guild AuditLogChangeKeyDefaultMessageNotification AuditLogChangeKey = "default_message_notifications" - AuditLogChangeKeyVanityURLCode AuditLogChangeKey = "vanity_url_code" - AuditLogChangeKeyRoleAdd AuditLogChangeKey = "$add" - AuditLogChangeKeyRoleRemove AuditLogChangeKey = "$remove" - AuditLogChangeKeyPruneDeleteDays AuditLogChangeKey = "prune_delete_days" - AuditLogChangeKeyWidgetEnabled AuditLogChangeKey = "widget_enabled" - AuditLogChangeKeyWidgetChannelID AuditLogChangeKey = "widget_channel_id" - AuditLogChangeKeySystemChannelID AuditLogChangeKey = "system_channel_id" - AuditLogChangeKeyPosition AuditLogChangeKey = "position" - AuditLogChangeKeyTopic AuditLogChangeKey = "topic" - AuditLogChangeKeyBitrate AuditLogChangeKey = "bitrate" - AuditLogChangeKeyPermissionOverwrite AuditLogChangeKey = "permission_overwrites" - AuditLogChangeKeyNSFW AuditLogChangeKey = "nsfw" - AuditLogChangeKeyApplicationID AuditLogChangeKey = "application_id" - AuditLogChangeKeyRateLimitPerUser AuditLogChangeKey = "rate_limit_per_user" - AuditLogChangeKeyPermissions AuditLogChangeKey = "permissions" - AuditLogChangeKeyColor AuditLogChangeKey = "color" - AuditLogChangeKeyHoist AuditLogChangeKey = "hoist" - AuditLogChangeKeyMentionable AuditLogChangeKey = "mentionable" - AuditLogChangeKeyAllow AuditLogChangeKey = "allow" - AuditLogChangeKeyDeny AuditLogChangeKey = "deny" - AuditLogChangeKeyCode AuditLogChangeKey = "code" - AuditLogChangeKeyChannelID AuditLogChangeKey = "channel_id" - AuditLogChangeKeyInviterID AuditLogChangeKey = "inviter_id" - AuditLogChangeKeyMaxUses AuditLogChangeKey = "max_uses" - AuditLogChangeKeyUses AuditLogChangeKey = "uses" - AuditLogChangeKeyMaxAge AuditLogChangeKey = "max_age" - AuditLogChangeKeyTempoary AuditLogChangeKey = "temporary" - AuditLogChangeKeyDeaf AuditLogChangeKey = "deaf" - AuditLogChangeKeyMute AuditLogChangeKey = "mute" - AuditLogChangeKeyNick AuditLogChangeKey = "nick" - AuditLogChangeKeyAvatarHash AuditLogChangeKey = "avatar_hash" - AuditLogChangeKeyID AuditLogChangeKey = "id" - AuditLogChangeKeyType AuditLogChangeKey = "type" - AuditLogChangeKeyEnableEmoticons AuditLogChangeKey = "enable_emoticons" - AuditLogChangeKeyExpireBehavior AuditLogChangeKey = "expire_behavior" - AuditLogChangeKeyExpireGracePeriod AuditLogChangeKey = "expire_grace_period" + // AuditLogChangeKeyDeny is sent when a permission on a text or voice channel was denied for a role (string) - role + AuditLogChangeKeyDeny AuditLogChangeKey = "deny" + // AuditLogChangeKeyDescription is sent when description changed (string) - guild, sticker, or guild scheduled event + AuditLogChangeKeyDescription AuditLogChangeKey = "description" + // AuditLogChangeKeyDiscoverySplashHash is sent when discovery splash changed (string) - guild + AuditLogChangeKeyDiscoverySplashHash AuditLogChangeKey = "discovery_splash_hash" + // AuditLogChangeKeyEnableEmoticons is sent when integration emoticons enabled/disabled (bool) - integration + AuditLogChangeKeyEnableEmoticons AuditLogChangeKey = "enable_emoticons" + // AuditLogChangeKeyEntityType is sent when entity type of guild scheduled event was changed (int) - guild scheduled event + AuditLogChangeKeyEntityType AuditLogChangeKey = "entity_type" + // AuditLogChangeKeyExpireBehavior is sent when integration expiring subscriber behavior changed (int) - integration + AuditLogChangeKeyExpireBehavior AuditLogChangeKey = "expire_behavior" + // AuditLogChangeKeyExpireGracePeriod is sent when integration expire grace period changed (int) - integration + AuditLogChangeKeyExpireGracePeriod AuditLogChangeKey = "expire_grace_period" + // AuditLogChangeKeyExplicitContentFilter is sent when change in whose messages are scanned and deleted for explicit content in the server is made (int) - guild + AuditLogChangeKeyExplicitContentFilter AuditLogChangeKey = "explicit_content_filter" + // AuditLogChangeKeyFormatType is sent when format type of sticker changed (int - sticker format type) - sticker + AuditLogChangeKeyFormatType AuditLogChangeKey = "format_type" + // AuditLogChangeKeyGuildID is sent when guild sticker is in changed (snowflake) - sticker + AuditLogChangeKeyGuildID AuditLogChangeKey = "guild_id" + // AuditLogChangeKeyHoist is sent when role is now displayed/no longer displayed separate from online users (bool) - role + AuditLogChangeKeyHoist AuditLogChangeKey = "hoist" + // AuditLogChangeKeyIconHash is sent when icon changed (string) - guild or role + AuditLogChangeKeyIconHash AuditLogChangeKey = "icon_hash" + // AuditLogChangeKeyID is sent when the id of the changed entity - sometimes used in conjunction with other keys (snowflake) - any + AuditLogChangeKeyID AuditLogChangeKey = "id" + // AuditLogChangeKeyInvitable is sent when private thread is now invitable/uninvitable (bool) - thread + AuditLogChangeKeyInvitable AuditLogChangeKey = "invitable" + // AuditLogChangeKeyInviterID is sent when person who created invite code changed (snowflake) - invite + AuditLogChangeKeyInviterID AuditLogChangeKey = "inviter_id" + // AuditLogChangeKeyLocation is sent when channel id for guild scheduled event changed (string) - guild scheduled event + AuditLogChangeKeyLocation AuditLogChangeKey = "location" + // AuditLogChangeKeyLocked is sent when thread was locked/unlocked (bool) - thread + AuditLogChangeKeyLocked AuditLogChangeKey = "locked" + // AuditLogChangeKeyMaxAge is sent when invite code expiration time changed (int) - invite + AuditLogChangeKeyMaxAge AuditLogChangeKey = "max_age" + // AuditLogChangeKeyMaxUses is sent when max number of times invite code can be used changed (int) - invite + AuditLogChangeKeyMaxUses AuditLogChangeKey = "max_uses" + // AuditLogChangeKeyMentionable is sent when role is now mentionable/unmentionable (bool) - role + AuditLogChangeKeyMentionable AuditLogChangeKey = "mentionable" + // AuditLogChangeKeyMfaLevel is sent when two-factor auth requirement changed (int - mfa level) - guild + AuditLogChangeKeyMfaLevel AuditLogChangeKey = "mfa_level" + // AuditLogChangeKeyMute is sent when user server muted/unmuted (bool) - member + AuditLogChangeKeyMute AuditLogChangeKey = "mute" + // AuditLogChangeKeyName is sent when name changed (string) - any + AuditLogChangeKeyName AuditLogChangeKey = "name" + // AuditLogChangeKeyNick is sent when user nickname changed (string) - member + AuditLogChangeKeyNick AuditLogChangeKey = "nick" + // AuditLogChangeKeyNSFW is sent when channel nsfw restriction changed (bool) - channel + AuditLogChangeKeyNSFW AuditLogChangeKey = "nsfw" + // AuditLogChangeKeyOwnerID is sent when owner changed (snowflake) - guild + AuditLogChangeKeyOwnerID AuditLogChangeKey = "owner_id" + // AuditLogChangeKeyPermissionOverwrite is sent when permissions on a channel changed (array of channel overwrite objects) - channel + AuditLogChangeKeyPermissionOverwrite AuditLogChangeKey = "permission_overwrites" + // AuditLogChangeKeyPermissions is sent when permissions for a role changed (string) - role + AuditLogChangeKeyPermissions AuditLogChangeKey = "permissions" + // AuditLogChangeKeyPosition is sent when text or voice channel position changed (int) - channel + AuditLogChangeKeyPosition AuditLogChangeKey = "position" + // AuditLogChangeKeyPreferredLocale is sent when preferred locale changed (string) - guild + AuditLogChangeKeyPreferredLocale AuditLogChangeKey = "preferred_locale" + // AuditLogChangeKeyPrivacylevel is sent when privacy level of the stage instance changed (integer - privacy level) - stage instance or guild scheduled event + AuditLogChangeKeyPrivacylevel AuditLogChangeKey = "privacy_level" + // AuditLogChangeKeyPruneDeleteDays is sent when number of days after which inactive and role-unassigned members are kicked changed (int) - guild + AuditLogChangeKeyPruneDeleteDays AuditLogChangeKey = "prune_delete_days" + // AuditLogChangeKeyPulibUpdatesChannelID is sent when id of the public updates channel changed (snowflake) - guild + AuditLogChangeKeyPulibUpdatesChannelID AuditLogChangeKey = "public_updates_channel_id" + // AuditLogChangeKeyRateLimitPerUser is sent when amount of seconds a user has to wait before sending another message changed (int) - channel + AuditLogChangeKeyRateLimitPerUser AuditLogChangeKey = "rate_limit_per_user" + // AuditLogChangeKeyRegion is sent when region changed (string) - guild + AuditLogChangeKeyRegion AuditLogChangeKey = "region" + // AuditLogChangeKeyRulesChannelID is sent when id of the rules channel changed (snowflake) - guild + AuditLogChangeKeyRulesChannelID AuditLogChangeKey = "rules_channel_id" + // AuditLogChangeKeySplashHash is sent when invite splash page artwork changed (string) - guild + AuditLogChangeKeySplashHash AuditLogChangeKey = "splash_hash" + // AuditLogChangeKeyStatus is sent when status of guild scheduled event was changed (int - guild scheduled event status) - guild scheduled event + AuditLogChangeKeyStatus AuditLogChangeKey = "status" + // AuditLogChangeKeySystemChannelID is sent when id of the system channel changed (snowflake) - guild + AuditLogChangeKeySystemChannelID AuditLogChangeKey = "system_channel_id" + // AuditLogChangeKeyTags is sent when related emoji of sticker changed (string) - sticker + AuditLogChangeKeyTags AuditLogChangeKey = "tags" + // AuditLogChangeKeyTemporary is sent when invite code is now temporary or never expires (bool) - invite + AuditLogChangeKeyTemporary AuditLogChangeKey = "temporary" + // TODO: remove when compatibility is not required + AuditLogChangeKeyTempoary = AuditLogChangeKeyTemporary + // AuditLogChangeKeyTopic is sent when text channel topic or stage instance topic changed (string) - channel or stage instance + AuditLogChangeKeyTopic AuditLogChangeKey = "topic" + // AuditLogChangeKeyType is sent when type of entity created (int or string) - any + AuditLogChangeKeyType AuditLogChangeKey = "type" + // AuditLogChangeKeyUnicodeEmoji is sent when role unicode emoji changed (string) - role + AuditLogChangeKeyUnicodeEmoji AuditLogChangeKey = "unicode_emoji" + // AuditLogChangeKeyUserLimit is sent when new user limit in a voice channel set (int) - voice channel + AuditLogChangeKeyUserLimit AuditLogChangeKey = "user_limit" + // AuditLogChangeKeyUses is sent when number of times invite code used changed (int) - invite + AuditLogChangeKeyUses AuditLogChangeKey = "uses" + // AuditLogChangeKeyVanityURLCode is sent when guild invite vanity url changed (string) - guild + AuditLogChangeKeyVanityURLCode AuditLogChangeKey = "vanity_url_code" + // AuditLogChangeKeyVerificationLevel is sent when required verification level changed (int - verification level) - guild + AuditLogChangeKeyVerificationLevel AuditLogChangeKey = "verification_level" + // AuditLogChangeKeyWidgetChannelID is sent when channel id of the server widget changed (snowflake) - guild + AuditLogChangeKeyWidgetChannelID AuditLogChangeKey = "widget_channel_id" + // AuditLogChangeKeyWidgetEnabled is sent when server widget enabled/disabled (bool) - guild + AuditLogChangeKeyWidgetEnabled AuditLogChangeKey = "widget_enabled" + // AuditLogChangeKeyRoleAdd is sent when new role added (array of partial role objects) - guild + AuditLogChangeKeyRoleAdd AuditLogChangeKey = "$add" + // AuditLogChangeKeyRoleRemove is sent when role removed (array of partial role objects) - guild + AuditLogChangeKeyRoleRemove AuditLogChangeKey = "$remove" ) // AuditLogOptions optional data for the AuditLog @@ -1132,6 +1227,9 @@ const ( AuditLogActionMemberBanRemove AuditLogAction = 23 AuditLogActionMemberUpdate AuditLogAction = 24 AuditLogActionMemberRoleUpdate AuditLogAction = 25 + AuditLogActionMemberMove AuditLogAction = 26 + AuditLogActionMemberDisconnect AuditLogAction = 27 + AuditLogActionBotAdd AuditLogAction = 28 AuditLogActionRoleCreate AuditLogAction = 30 AuditLogActionRoleUpdate AuditLogAction = 31 @@ -1154,9 +1252,24 @@ const ( AuditLogActionMessagePin AuditLogAction = 74 AuditLogActionMessageUnpin AuditLogAction = 75 - AuditLogActionIntegrationCreate AuditLogAction = 80 - AuditLogActionIntegrationUpdate AuditLogAction = 81 - AuditLogActionIntegrationDelete AuditLogAction = 82 + AuditLogActionIntegrationCreate AuditLogAction = 80 + AuditLogActionIntegrationUpdate AuditLogAction = 81 + AuditLogActionIntegrationDelete AuditLogAction = 82 + AuditLogActionStageInstanceCreate AuditLogAction = 83 + AuditLogActionStageInstanceUpdate AuditLogAction = 84 + AuditLogActionStageInstanceDelete AuditLogAction = 85 + + AuditLogActionStickerCreate AuditLogAction = 90 + AuditLogActionStickerUpdate AuditLogAction = 91 + AuditLogActionStickerDelete AuditLogAction = 92 + + AuditLogGuildScheduledEventCreate AuditLogAction = 100 + AuditLogGuildScheduledEventUpdare AuditLogAction = 101 + AuditLogGuildScheduledEventDelete AuditLogAction = 102 + + AuditLogActionThreadCreate AuditLogAction = 110 + AuditLogActionThreadUpdate AuditLogAction = 111 + AuditLogActionThreadDelete AuditLogAction = 112 ) // A UserGuildSettingsChannelOverride stores data for a channel override for a users guild settings. @@ -1423,57 +1536,162 @@ const ( // Block contains Discord JSON Error Response codes const ( - ErrCodeUnknownAccount = 10001 - ErrCodeUnknownApplication = 10002 - ErrCodeUnknownChannel = 10003 - ErrCodeUnknownGuild = 10004 - ErrCodeUnknownIntegration = 10005 - ErrCodeUnknownInvite = 10006 - ErrCodeUnknownMember = 10007 - ErrCodeUnknownMessage = 10008 - ErrCodeUnknownOverwrite = 10009 - ErrCodeUnknownProvider = 10010 - ErrCodeUnknownRole = 10011 - ErrCodeUnknownToken = 10012 - ErrCodeUnknownUser = 10013 - ErrCodeUnknownEmoji = 10014 - ErrCodeUnknownWebhook = 10015 - ErrCodeUnknownBan = 10026 - - ErrCodeBotsCannotUseEndpoint = 20001 - ErrCodeOnlyBotsCanUseEndpoint = 20002 - - ErrCodeMaximumGuildsReached = 30001 - ErrCodeMaximumFriendsReached = 30002 - ErrCodeMaximumPinsReached = 30003 - ErrCodeMaximumGuildRolesReached = 30005 - ErrCodeTooManyReactions = 30010 - - ErrCodeUnauthorized = 40001 - - ErrCodeMissingAccess = 50001 - ErrCodeInvalidAccountType = 50002 - ErrCodeCannotExecuteActionOnDMChannel = 50003 - ErrCodeEmbedDisabled = 50004 - ErrCodeCannotEditFromAnotherUser = 50005 - ErrCodeCannotSendEmptyMessage = 50006 - ErrCodeCannotSendMessagesToThisUser = 50007 - ErrCodeCannotSendMessagesInVoiceChannel = 50008 - ErrCodeChannelVerificationLevelTooHigh = 50009 - ErrCodeOAuth2ApplicationDoesNotHaveBot = 50010 - ErrCodeOAuth2ApplicationLimitReached = 50011 - ErrCodeInvalidOAuthState = 50012 - ErrCodeMissingPermissions = 50013 - ErrCodeInvalidAuthenticationToken = 50014 - ErrCodeNoteTooLong = 50015 - ErrCodeTooFewOrTooManyMessagesToDelete = 50016 - ErrCodeCanOnlyPinMessageToOriginatingChannel = 50019 - ErrCodeCannotExecuteActionOnSystemMessage = 50021 - ErrCodeMessageProvidedTooOldForBulkDelete = 50034 - ErrCodeInvalidFormBody = 50035 - ErrCodeInviteAcceptedToGuildApplicationsBotNotIn = 50036 + ErrCodeGeneralError = 0 + + ErrCodeUnknownAccount = 10001 + ErrCodeUnknownApplication = 10002 + ErrCodeUnknownChannel = 10003 + ErrCodeUnknownGuild = 10004 + ErrCodeUnknownIntegration = 10005 + ErrCodeUnknownInvite = 10006 + ErrCodeUnknownMember = 10007 + ErrCodeUnknownMessage = 10008 + ErrCodeUnknownOverwrite = 10009 + ErrCodeUnknownProvider = 10010 + ErrCodeUnknownRole = 10011 + ErrCodeUnknownToken = 10012 + ErrCodeUnknownUser = 10013 + ErrCodeUnknownEmoji = 10014 + ErrCodeUnknownWebhook = 10015 + ErrCodeUnknownWebhookService = 10016 + ErrCodeUnknownSession = 10020 + ErrCodeUnknownBan = 10026 + ErrCodeUnknownSKU = 10027 + ErrCodeUnknownStoreListing = 10028 + ErrCodeUnknownEntitlement = 10029 + ErrCodeUnknownBuild = 10030 + ErrCodeUnknownLobby = 10031 + ErrCodeUnknownBranch = 10032 + ErrCodeUnknownStoreDirectoryLayout = 10033 + ErrCodeUnknownRedistributable = 10036 + ErrCodeUnknownGiftCode = 10038 + ErrCodeUnknownStream = 10049 + ErrCodeUnknownPremiumServerSubscribeCooldown = 10050 + ErrCodeUnknownGuildTemplate = 10057 + ErrCodeUnknownDiscoveryCategory = 10059 + ErrCodeUnknownSticker = 10060 + ErrCodeUnknownInteraction = 10062 + ErrCodeUnknownApplicationCommand = 10063 + ErrCodeUnknownApplicationCommandPermissions = 10066 + ErrCodeUnknownStageInstance = 10067 + ErrCodeUnknownGuildMemberVerificationForm = 10068 + ErrCodeUnknownGuildWelcomeScreen = 10069 + ErrCodeUnknownGuildScheduledEvent = 10070 + ErrCodeUnknownGuildScheduledEventUser = 10071 + + ErrCodeBotsCannotUseEndpoint = 20001 + ErrCodeOnlyBotsCanUseEndpoint = 20002 + ErrCodeExplicitContentCannotBeSentToTheDesiredRecipients = 20009 + ErrCodeYouAreNotAuthorizedToPerformThisActionOnThisApplication = 20012 + ErrCodeThisActionCannotBePerformedDueToSlowmodeRateLimit = 20016 + ErrCodeOnlyTheOwnerOfThisAccountCanPerformThisAction = 20018 + ErrCodeMessageCannotBeEditedDueToAnnouncementRateLimits = 20022 + ErrCodeChannelHasHitWriteRateLimit = 20028 + ErrCodeTheWriteActionYouArePerformingOnTheServerHasHitTheWriteRateLimit = 20029 + ErrCodeStageTopicContainsNotAllowedWordsForPublicStages = 20031 + ErrCodeGuildPremiumSubscriptionLevelTooLow = 20035 + + ErrCodeMaximumPinsReached = 30003 + ErrCodeMaximumNumberOfRecipientsReached = 30004 + ErrCodeMaximumGuildRolesReached = 30005 + ErrCodeMaximumNumberOfWebhooksReached = 30007 + ErrCodeMaximumNumberOfEmojisReached = 30008 + ErrCodeTooManyReactions = 30010 + ErrCodeMaximumNumberOfGuildChannelsReached = 30013 + ErrCodeMaximumNumberOfAttachmentsInAMessageReached = 30015 + ErrCodeMaximumNumberOfInvitesReached = 30016 + ErrCodeMaximumNumberOfAnimatedEmojisReached = 30018 + ErrCodeMaximumNumberOfServerMembersReached = 30019 + ErrCodeMaximumNumberOfGuildDiscoverySubcategoriesReached = 30030 + ErrCodeGuildAlreadyHasATemplate = 30031 + ErrCodeMaximumNumberOfThreadParticipantsReached = 30033 + ErrCodeMaximumNumberOfBansForNonGuildMembersHaveBeenExceeded = 30035 + ErrCodeMaximumNumberOfBansFetchesHasBeenReached = 30037 + ErrCodeMaximumNumberOfUncompletedGuildScheduledEventsReached = 30038 + ErrCodeMaximumNumberOfStickersReached = 30039 + ErrCodeMaximumNumberOfPruneRequestsHasBeenReached = 30040 + ErrCodeMaximumNumberOfGuildWidgetSettingsUpdatesHasBeenReached = 30042 + ErrCodeMaximumNumberOfEditsToMessagesOlderThanOneHourReached = 30046 + + ErrCodeUnauthorized = 40001 + ErrCodeActionRequiredVerifiedAccount = 40002 + ErrCodeOpeningDirectMessagesTooFast = 40003 + ErrCodeSendMessagesHasBeenTemporarilyDisabled = 40004 + ErrCodeRequestEntityTooLarge = 40005 + ErrCodeFeatureTemporarilyDisabledServerSide = 40006 + ErrCodeUserIsBannedFromThisGuild = 40007 + ErrCodeTargetIsNotConnectedToVoice = 40032 + ErrCodeMessageAlreadyCrossposted = 40033 + ErrCodeAnApplicationWithThatNameAlreadyExists = 40041 + ErrCodeInteractionHasAlreadyBeenAcknowledged = 40060 + + ErrCodeMissingAccess = 50001 + ErrCodeInvalidAccountType = 50002 + ErrCodeCannotExecuteActionOnDMChannel = 50003 + ErrCodeEmbedDisabled = 50004 + ErrCodeGuildWidgetDisabled = 50004 + ErrCodeCannotEditFromAnotherUser = 50005 + ErrCodeCannotSendEmptyMessage = 50006 + ErrCodeCannotSendMessagesToThisUser = 50007 + ErrCodeCannotSendMessagesInVoiceChannel = 50008 + ErrCodeChannelVerificationLevelTooHigh = 50009 + ErrCodeOAuth2ApplicationDoesNotHaveBot = 50010 + ErrCodeOAuth2ApplicationLimitReached = 50011 + ErrCodeInvalidOAuthState = 50012 + ErrCodeMissingPermissions = 50013 + ErrCodeInvalidAuthenticationToken = 50014 + ErrCodeTooFewOrTooManyMessagesToDelete = 50016 + ErrCodeCanOnlyPinMessageToOriginatingChannel = 50019 + ErrCodeInviteCodeWasEitherInvalidOrTaken = 50020 + ErrCodeCannotExecuteActionOnSystemMessage = 50021 + ErrCodeCannotExecuteActionOnThisChannelType = 50024 + ErrCodeInvalidOAuth2AccessTokenProvided = 50025 + ErrCodeMissingRequiredOAuth2Scope = 50026 + ErrCodeInvalidWebhookTokenProvided = 50027 + ErrCodeInvalidRole = 50028 + ErrCodeInvalidRecipients = 50033 + ErrCodeMessageProvidedTooOldForBulkDelete = 50034 + ErrCodeInvalidFormBody = 50035 + ErrCodeInviteAcceptedToGuildApplicationsBotNotIn = 50036 + ErrCodeInvalidAPIVersionProvided = 50041 + ErrCodeFileUploadedExceedsTheMaximumSize = 50045 + ErrCodeInvalidFileUploaded = 50046 + ErrCodeInvalidGuild = 50055 + ErrCodeInvalidMessageType = 50068 + ErrCodeCannotDeleteAChannelRequiredForCommunityGuilds = 50074 + ErrCodeInvalidStickerSent = 50081 + ErrCodePerformedOperationOnArchivedThread = 50083 + ErrCodeBeforeValueIsEarlierThanThreadCreationDate = 50085 + ErrCodeCommunityServerChannelsMustBeTextChannels = 50086 + ErrCodeThisServerIsNotAvailableInYourLocation = 50095 + ErrCodeThisServerNeedsMonetizationEnabledInOrderToPerformThisAction = 50097 + ErrCodeThisServerNeedsMoreBoostsToPerformThisAction = 50101 + ErrCodeTheRequestBodyContainsInvalidJSON = 50109 + + ErrCodeNoUsersWithDiscordTagExist = 80004 ErrCodeReactionBlocked = 90001 + + ErrCodeAPIResourceIsCurrentlyOverloaded = 130000 + + ErrCodeTheStageIsAlreadyOpen = 150006 + + ErrCodeCannotReplyWithoutPermissionToReadMessageHistory = 160002 + ErrCodeThreadAlreadyCreatedForThisMessage = 160004 + ErrCodeThreadIsLocked = 160005 + ErrCodeMaximumNumberOfActiveThreadsReached = 160006 + ErrCodeMaximumNumberOfActiveAnnouncementThreadsReached = 160007 + + ErrCodeInvalidJSONForUploadedLottieFile = 170001 + ErrCodeUploadedLottiesCannotContainRasterizedImages = 170002 + ErrCodeStickerMaximumFramerateExceeded = 170003 + ErrCodeStickerFrameCountExceedsMaximumOfOneThousandFrames = 170004 + ErrCodeLottieAnimationMaximumDimensionsExceeded = 170005 + ErrCodeStickerFrameRateOutOfRange = 170006 + ErrCodeStickerAnimationDurationExceedsMaximumOfFiveSeconds = 170007 + + ErrCodeCannotUpdateAFinishedEvent = 180000 + ErrCodeFailedToCreateStageNeededForStageEvent = 180002 ) // Intent is the type of a Gateway Intent @@ -1482,6 +1700,26 @@ type Intent int // Constants for the different bit offsets of intents const ( + IntentGuilds Intent = 1 << 0 + IntentGuildMembers Intent = 1 << 1 + IntentGuildBans Intent = 1 << 2 + IntentGuildEmojis Intent = 1 << 3 + IntentGuildIntegrations Intent = 1 << 4 + IntentGuildWebhooks Intent = 1 << 5 + IntentGuildInvites Intent = 1 << 6 + IntentGuildVoiceStates Intent = 1 << 7 + IntentGuildPresences Intent = 1 << 8 + IntentGuildMessages Intent = 1 << 9 + IntentGuildMessageReactions Intent = 1 << 10 + IntentGuildMessageTyping Intent = 1 << 11 + IntentDirectMessages Intent = 1 << 12 + IntentDirectMessageReactions Intent = 1 << 13 + IntentDirectMessageTyping Intent = 1 << 14 + IntentMessageContent Intent = 1 << 15 + IntentGuildScheduledEvents Intent = 1 << 16 + + // TODO: remove when compatibility is not needed + IntentsGuilds Intent = 1 << 0 IntentsGuildMembers Intent = 1 << 1 IntentsGuildBans Intent = 1 << 2 @@ -1497,23 +1735,29 @@ const ( IntentsDirectMessages Intent = 1 << 12 IntentsDirectMessageReactions Intent = 1 << 13 IntentsDirectMessageTyping Intent = 1 << 14 + IntentsMessageContent Intent = 1 << 15 + IntentsGuildScheduledEvents Intent = 1 << 16 + + IntentsAllWithoutPrivileged = IntentGuilds | + IntentGuildBans | + IntentGuildEmojis | + IntentGuildIntegrations | + IntentGuildWebhooks | + IntentGuildInvites | + IntentGuildVoiceStates | + IntentGuildMessages | + IntentGuildMessageReactions | + IntentGuildMessageTyping | + IntentDirectMessages | + IntentDirectMessageReactions | + IntentDirectMessageTyping | + IntentGuildScheduledEvents - IntentsAllWithoutPrivileged = IntentsGuilds | - IntentsGuildBans | - IntentsGuildEmojis | - IntentsGuildIntegrations | - IntentsGuildWebhooks | - IntentsGuildInvites | - IntentsGuildVoiceStates | - IntentsGuildMessages | - IntentsGuildMessageReactions | - IntentsGuildMessageTyping | - IntentsDirectMessages | - IntentsDirectMessageReactions | - IntentsDirectMessageTyping IntentsAll = IntentsAllWithoutPrivileged | - IntentsGuildMembers | - IntentsGuildPresences + IntentGuildMembers | + IntentGuildPresences | + IntentMessageContent + IntentsNone Intent = 0 )