From 10b8f7c351952215016fff7cd83c0a09763fad33 Mon Sep 17 00:00:00 2001 From: Gregory DALMAR Date: Mon, 18 Jun 2018 15:42:17 +0200 Subject: [PATCH 01/52] Add pagination to MessageReactions --- restapi.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/restapi.go b/restapi.go index 5dc0467..2249dcc 100644 --- a/restapi.go +++ b/restapi.go @@ -1946,7 +1946,9 @@ func (s *Session) MessageReactionsRemoveAll(channelID, messageID string) error { // messageID : The message ID. // emojiID : Either the unicode emoji for the reaction, or a guild emoji identifier. // limit : max number of users to return (max 100) -func (s *Session) MessageReactions(channelID, messageID, emojiID string, limit int) (st []*User, err error) { +// beforeID : If provided all reactions returned will be before given ID. +// afterID : If provided all reactions returned will be after given ID. +func (s *Session) MessageReactions(channelID, messageID, emojiID string, limit int, beforeID, afterID string) (st []*User, err error) { uri := EndpointMessageReactions(channelID, messageID, emojiID) v := url.Values{} @@ -1955,6 +1957,13 @@ func (s *Session) MessageReactions(channelID, messageID, emojiID string, limit i v.Set("limit", strconv.Itoa(limit)) } + if afterID != "" { + v.Set("after", afterID) + } + if beforeID != "" { + v.Set("before", beforeID) + } + if len(v) > 0 { uri = fmt.Sprintf("%s?%s", uri, v.Encode()) } From 7d04e7dfb397ece13569026709a18c484ae6c499 Mon Sep 17 00:00:00 2001 From: recapitalverb Date: Fri, 9 Aug 2019 20:59:46 +0700 Subject: [PATCH 02/52] Remove State fallback from Session#Guild --- restapi.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/restapi.go b/restapi.go index 02909d0..1ef8d8b 100644 --- a/restapi.go +++ b/restapi.go @@ -578,14 +578,6 @@ func memberPermissions(guild *Guild, channel *Channel, member *Member) (apermiss // Guild returns a Guild structure of a specific Guild. // guildID : The ID of a Guild func (s *Session) Guild(guildID string) (st *Guild, err error) { - if s.StateEnabled { - // Attempt to grab the guild from State first. - st, err = s.State.Guild(guildID) - if err == nil && !st.Unavailable { - return - } - } - body, err := s.RequestWithBucketID("GET", EndpointGuild(guildID), nil, EndpointGuild(guildID)) if err != nil { return From bc6197c5e6c11a998ab4361ff6c91ffcf712423a Mon Sep 17 00:00:00 2001 From: tuckerrrrrrrrrrrr Date: Tue, 10 Sep 2019 18:09:24 -0700 Subject: [PATCH 03/52] fix inconsistent tts casing --- message.go | 4 ++-- restapi.go | 2 +- structs.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/message.go b/message.go index 5aab7e5..eb292d5 100644 --- a/message.go +++ b/message.go @@ -63,7 +63,7 @@ type Message struct { MentionRoles []string `json:"mention_roles"` // Whether the message is text-to-speech. - Tts bool `json:"tts"` + TTS bool `json:"tts"` // Whether the message mentions everyone. MentionEveryone bool `json:"mention_everyone"` @@ -106,7 +106,7 @@ type File struct { type MessageSend struct { Content string `json:"content,omitempty"` Embed *MessageEmbed `json:"embed,omitempty"` - Tts bool `json:"tts"` + TTS bool `json:"tts"` Files []*File `json:"-"` // TODO: Remove this when compatibility is not required. diff --git a/restapi.go b/restapi.go index 02909d0..1b63586 100644 --- a/restapi.go +++ b/restapi.go @@ -1588,7 +1588,7 @@ func (s *Session) ChannelMessageSendComplex(channelID string, data *MessageSend) func (s *Session) ChannelMessageSendTTS(channelID string, content string) (*Message, error) { return s.ChannelMessageSendComplex(channelID, &MessageSend{ Content: content, - Tts: true, + TTS: true, }) } diff --git a/structs.go b/structs.go index e7192d9..aa60f12 100644 --- a/structs.go +++ b/structs.go @@ -682,7 +682,7 @@ type Settings struct { RenderEmbeds bool `json:"render_embeds"` InlineEmbedMedia bool `json:"inline_embed_media"` InlineAttachmentMedia bool `json:"inline_attachment_media"` - EnableTtsCommand bool `json:"enable_tts_command"` + EnableTTSCommand bool `json:"enable_tts_command"` MessageDisplayCompact bool `json:"message_display_compact"` ShowCurrentGame bool `json:"show_current_game"` ConvertEmoticons bool `json:"convert_emoticons"` From 6c8f64b92c7bab54227fea3b50582cdc5976095d Mon Sep 17 00:00:00 2001 From: Bruce Marriner Date: Fri, 18 Oct 2019 10:49:24 -0500 Subject: [PATCH 04/52] Bump version to v0.21.0-devel --- discord.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord.go b/discord.go index cb43e7e..e8199e1 100644 --- a/discord.go +++ b/discord.go @@ -21,7 +21,7 @@ import ( ) // VERSION of DiscordGo, follows Semantic Versioning. (http://semver.org/) -const VERSION = "0.20.0-alpha" +const VERSION = "0.21.0-devel" // ErrMFA will be risen by New when the user has 2FA. var ErrMFA = errors.New("account has 2FA enabled") From bd7cb04d47c01222f4529b7ab048a5f7532f0a53 Mon Sep 17 00:00:00 2001 From: Bruce Marriner Date: Fri, 18 Oct 2019 11:29:55 -0500 Subject: [PATCH 05/52] Since Go is intent on a Go value being in go.mod We're going to set it to 1.10 for now. --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 8cd2cf6..79ea036 100644 --- a/go.mod +++ b/go.mod @@ -5,4 +5,4 @@ require ( golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16 ) -go 1.13 +go 1.10 From 9a0071df7e3329b83c67b3d88b771926289f86b7 Mon Sep 17 00:00:00 2001 From: Bruce Marriner Date: Fri, 18 Oct 2019 11:32:51 -0500 Subject: [PATCH 06/52] Update tested versions. --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2656ae5..b88f11e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,9 @@ language: go go: - - 1.9.x - 1.10.x - 1.11.x + - 1.12.x + - 1.13.x install: - go get github.com/bwmarrin/discordgo - go get -v . From 0219fb9901098dd59ee9a863e4bb92791b230c1d Mon Sep 17 00:00:00 2001 From: MistahJ Date: Fri, 25 Oct 2019 01:31:19 -0700 Subject: [PATCH 07/52] Support for Batch Request Guild Members This is supported by the Discord API and will save requests. --- wsapi.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wsapi.go b/wsapi.go index eccbb9f..f662c2e 100644 --- a/wsapi.go +++ b/wsapi.go @@ -399,7 +399,7 @@ func (s *Session) UpdateStatusComplex(usd UpdateStatusData) (err error) { } type requestGuildMembersData struct { - GuildID string `json:"guild_id"` + GuildID []string `json:"guild_id"` Query string `json:"query"` Limit int `json:"limit"` } @@ -411,10 +411,10 @@ type requestGuildMembersOp struct { // RequestGuildMembers requests guild members from the gateway // The gateway responds with GuildMembersChunk events -// guildID : The ID of the guild to request members of +// guildID : Slice of guild IDs to request members of // query : String that username starts with, leave empty to return all members // limit : Max number of items to return, or 0 to request all members matched -func (s *Session) RequestGuildMembers(guildID, query string, limit int) (err error) { +func (s *Session) RequestGuildMembers(guildID []string, query string, limit int) (err error) { s.log(LogInformational, "called") s.RLock() From 7057551cd01b25747a50b6e4e9f400c68fc8f769 Mon Sep 17 00:00:00 2001 From: MistahJ Date: Fri, 25 Oct 2019 01:53:26 -0700 Subject: [PATCH 08/52] go fmt file --- wsapi.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wsapi.go b/wsapi.go index f662c2e..7b7f4ba 100644 --- a/wsapi.go +++ b/wsapi.go @@ -400,8 +400,8 @@ func (s *Session) UpdateStatusComplex(usd UpdateStatusData) (err error) { type requestGuildMembersData struct { GuildID []string `json:"guild_id"` - Query string `json:"query"` - Limit int `json:"limit"` + Query string `json:"query"` + Limit int `json:"limit"` } type requestGuildMembersOp struct { From b317e27d39c21a8ef9b434b00cde750fe9e0b985 Mon Sep 17 00:00:00 2001 From: MistahJ Date: Sat, 26 Oct 2019 09:53:31 -0700 Subject: [PATCH 09/52] Improvements --- wsapi.go | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/wsapi.go b/wsapi.go index 7b7f4ba..0f840d2 100644 --- a/wsapi.go +++ b/wsapi.go @@ -399,9 +399,10 @@ func (s *Session) UpdateStatusComplex(usd UpdateStatusData) (err error) { } type requestGuildMembersData struct { - GuildID []string `json:"guild_id"` - Query string `json:"query"` - Limit int `json:"limit"` + GuildID string `json:"guild_id"` + GuildIDs []string `json:"guild_id"` + Query string `json:"query"` + Limit int `json:"limit"` } type requestGuildMembersOp struct { @@ -411,10 +412,35 @@ type requestGuildMembersOp struct { // RequestGuildMembers requests guild members from the gateway // The gateway responds with GuildMembersChunk events +// guildID : Single Guild ID to request members of +// query : String that username starts with, leave empty to return all members +// limit : Max number of items to return, or 0 to request all members matched +func (s *Session) RequestGuildMembers(guildID string, query string, limit int) (err error) { + data := requestGuildMembersData{ + GuildID: guildID, + Query: query, + Limit: limit, + } + err = s.requestGuildMember(&data) + return err +} + +// RequestGuildMembersBatch requests guild members from the gateway +// The gateway responds with GuildMembersChunk events // guildID : Slice of guild IDs to request members of // query : String that username starts with, leave empty to return all members // limit : Max number of items to return, or 0 to request all members matched -func (s *Session) RequestGuildMembers(guildID []string, query string, limit int) (err error) { +func (s *Session) RequestGuildMembersBatch(guildIDs []string, query string, limit int) (err error) { + data := requestGuildMembersData{ + GuildIDs: guildIDs, + Query: query, + Limit: limit, + } + err = s.requestGuildMember(&data) + return err +} + +func (s *Session) requestGuildMember(data *requestGuildMembersData) (err error) { s.log(LogInformational, "called") s.RLock() @@ -423,17 +449,11 @@ func (s *Session) RequestGuildMembers(guildID []string, query string, limit int) return ErrWSNotFound } - data := requestGuildMembersData{ - GuildID: guildID, - Query: query, - Limit: limit, - } - s.wsMutex.Lock() - err = s.wsConn.WriteJSON(requestGuildMembersOp{8, data}) + err = s.wsConn.WriteJSON(requestGuildMembersOp{8, *data}) s.wsMutex.Unlock() - return + return err } // onEvent is the "event handler" for all messages received on the From f4d9341a31e6628457df579fe9f8e0755bfaeaa0 Mon Sep 17 00:00:00 2001 From: MistahJ Date: Sat, 26 Oct 2019 09:53:31 -0700 Subject: [PATCH 10/52] Improvements --- wsapi.go | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/wsapi.go b/wsapi.go index 7b7f4ba..bfeab25 100644 --- a/wsapi.go +++ b/wsapi.go @@ -399,9 +399,9 @@ func (s *Session) UpdateStatusComplex(usd UpdateStatusData) (err error) { } type requestGuildMembersData struct { - GuildID []string `json:"guild_id"` - Query string `json:"query"` - Limit int `json:"limit"` + GuildIDs []string `json:"guild_id"` + Query string `json:"query"` + Limit int `json:"limit"` } type requestGuildMembersOp struct { @@ -411,10 +411,35 @@ type requestGuildMembersOp struct { // RequestGuildMembers requests guild members from the gateway // The gateway responds with GuildMembersChunk events +// guildID : Single Guild ID to request members of +// query : String that username starts with, leave empty to return all members +// limit : Max number of items to return, or 0 to request all members matched +func (s *Session) RequestGuildMembers(guildID string, query string, limit int) (err error) { + data := requestGuildMembersData{ + GuildIDs: []string{guildID}, + Query: query, + Limit: limit, + } + err = s.requestGuildMember(data) + return err +} + +// RequestGuildMembersBatch requests guild members from the gateway +// The gateway responds with GuildMembersChunk events // guildID : Slice of guild IDs to request members of // query : String that username starts with, leave empty to return all members // limit : Max number of items to return, or 0 to request all members matched -func (s *Session) RequestGuildMembers(guildID []string, query string, limit int) (err error) { +func (s *Session) RequestGuildMembersBatch(guildIDs []string, query string, limit int) (err error) { + data := requestGuildMembersData{ + GuildIDs: guildIDs, + Query: query, + Limit: limit, + } + err = s.requestGuildMember(data) + return err +} + +func (s *Session) requestGuildMember(data requestGuildMembersData) (err error) { s.log(LogInformational, "called") s.RLock() @@ -423,17 +448,11 @@ func (s *Session) RequestGuildMembers(guildID []string, query string, limit int) return ErrWSNotFound } - data := requestGuildMembersData{ - GuildID: guildID, - Query: query, - Limit: limit, - } - s.wsMutex.Lock() err = s.wsConn.WriteJSON(requestGuildMembersOp{8, data}) s.wsMutex.Unlock() - return + return err } // onEvent is the "event handler" for all messages received on the From cc90f690b377e75a2633771c4bbe80c3f41890d5 Mon Sep 17 00:00:00 2001 From: MistahJ Date: Sun, 27 Oct 2019 20:41:12 -0700 Subject: [PATCH 11/52] go fmt --- wsapi.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wsapi.go b/wsapi.go index bfeab25..3650308 100644 --- a/wsapi.go +++ b/wsapi.go @@ -417,8 +417,8 @@ type requestGuildMembersOp struct { func (s *Session) RequestGuildMembers(guildID string, query string, limit int) (err error) { data := requestGuildMembersData{ GuildIDs: []string{guildID}, - Query: query, - Limit: limit, + Query: query, + Limit: limit, } err = s.requestGuildMember(data) return err From 307c335eb6a184a754b15d05551a0f8336c46609 Mon Sep 17 00:00:00 2001 From: Eric Wohltman Date: Thu, 19 Dec 2019 12:46:45 -0500 Subject: [PATCH 12/52] Fix for Discord's API returning a 400 Bad Request if Content-Type is set, but the request body is empty. --- restapi.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/restapi.go b/restapi.go index 8134d92..69c5507 100644 --- a/restapi.go +++ b/restapi.go @@ -88,7 +88,12 @@ func (s *Session) RequestWithLockedBucket(method, urlStr, contentType string, b req.Header.Set("authorization", s.Token) } - req.Header.Set("Content-Type", contentType) + // Discord's API returns a 400 Bad Request is Content-Type is set, but the + // request body is empty. + if b != nil { + req.Header.Set("Content-Type", contentType) + } + // TODO: Make a configurable static variable. req.Header.Set("User-Agent", s.UserAgent) From c3e4a2dea8af4d59bc78f912848b3a160c219f02 Mon Sep 17 00:00:00 2001 From: MistahJ Date: Fri, 27 Dec 2019 17:44:20 -0700 Subject: [PATCH 13/52] fix typo --- wsapi.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wsapi.go b/wsapi.go index 3650308..5656f97 100644 --- a/wsapi.go +++ b/wsapi.go @@ -420,7 +420,7 @@ func (s *Session) RequestGuildMembers(guildID string, query string, limit int) ( Query: query, Limit: limit, } - err = s.requestGuildMember(data) + err = s.requestGuildMembers(data) return err } @@ -435,11 +435,11 @@ func (s *Session) RequestGuildMembersBatch(guildIDs []string, query string, limi Query: query, Limit: limit, } - err = s.requestGuildMember(data) + err = s.requestGuildMembers(data) return err } -func (s *Session) requestGuildMember(data requestGuildMembersData) (err error) { +func (s *Session) requestGuildMembers(data requestGuildMembersData) (err error) { s.log(LogInformational, "called") s.RLock() From 49f3160ac481c2c8276b728a9cd5e64a2b07bb80 Mon Sep 17 00:00:00 2001 From: MistahJ Date: Fri, 27 Dec 2019 17:50:21 -0700 Subject: [PATCH 14/52] clean up returns --- wsapi.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wsapi.go b/wsapi.go index 5656f97..c1fb91a 100644 --- a/wsapi.go +++ b/wsapi.go @@ -421,7 +421,7 @@ func (s *Session) RequestGuildMembers(guildID string, query string, limit int) ( Limit: limit, } err = s.requestGuildMembers(data) - return err + return } // RequestGuildMembersBatch requests guild members from the gateway @@ -436,7 +436,7 @@ func (s *Session) RequestGuildMembersBatch(guildIDs []string, query string, limi Limit: limit, } err = s.requestGuildMembers(data) - return err + return } func (s *Session) requestGuildMembers(data requestGuildMembersData) (err error) { @@ -452,7 +452,7 @@ func (s *Session) requestGuildMembers(data requestGuildMembersData) (err error) err = s.wsConn.WriteJSON(requestGuildMembersOp{8, data}) s.wsMutex.Unlock() - return err + return } // onEvent is the "event handler" for all messages received on the From 973580a2baa483e0e4613c1b1afd32d474687f7a Mon Sep 17 00:00:00 2001 From: Bruce Marriner Date: Mon, 20 Jan 2020 12:01:58 -0600 Subject: [PATCH 15/52] Initial commit of ExposeIdentify feature --- discord.go | 24 +++++++++++++++++------- structs.go | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ wsapi.go | 50 ++++++++++++++++++-------------------------------- 3 files changed, 88 insertions(+), 39 deletions(-) diff --git a/discord.go b/discord.go index 755b087..e0f6f63 100644 --- a/discord.go +++ b/discord.go @@ -17,6 +17,7 @@ import ( "errors" "fmt" "net/http" + "runtime" "time" ) @@ -63,6 +64,14 @@ func New(args ...interface{}) (s *Session, err error) { LastHeartbeatAck: time.Now().UTC(), } + // Initilize the Identify Package with defaults + // These can be modified prior to calling Open() + s.Identify.Compress = true + s.Identify.LargeThreshold = 250 + s.Identify.GuildSubscriptions = true + s.Identify.Properties.OS = runtime.GOOS + s.Identify.Properties.Browser = "DiscordGo v" + VERSION + // If no arguments are passed return the empty Session interface. if args == nil { return @@ -94,7 +103,8 @@ func New(args ...interface{}) (s *Session, err error) { // If third string exists, it must be an auth token. if len(v) > 2 { - s.Token = v[2] + s.Identify.Token = v[2] + s.Token = v[2] // TODO: Remove, Deprecated - Kept for backwards compatibility. } case string: @@ -107,7 +117,8 @@ func New(args ...interface{}) (s *Session, err error) { } else if pass == "" { pass = v } else if s.Token == "" { - s.Token = v + s.Identify.Token = v + s.Token = v // TODO: Remove, Deprecated - Kept for backwards compatibility. } else { err = fmt.Errorf("too many string parameters provided") return @@ -127,10 +138,12 @@ func New(args ...interface{}) (s *Session, err error) { // Discord will verify it for free, or log the user in if it is // invalid. if pass == "" { - s.Token = auth + s.Identify.Token = auth + s.Token = auth // TODO: Remove, Deprecated - Kept for backwards compatibility. } else { err = s.Login(auth, pass) - if err != nil || s.Token == "" { + // TODO: Remove last s.Token part, Deprecated - Kept for backwards compatibility. + if err != nil || s.Identify.Token == "" || s.Token == "" { if s.MFA { err = ErrMFA } else { @@ -140,8 +153,5 @@ func New(args ...interface{}) (s *Session, err error) { } } - // The Session is now able to have RestAPI methods called on it. - // It is recommended that you now call Open() so that events will trigger. - return } diff --git a/structs.go b/structs.go index 19bb5be..c509f3a 100644 --- a/structs.go +++ b/structs.go @@ -39,6 +39,11 @@ type Session struct { // Should the session reconnect the websocket on errors. ShouldReconnectOnError bool + // Identify is sent during initial handshake with the discord gateway. + // https://discordapp.com/developers/docs/topics/gateway#identify + Identify Identify + + // TODO: REMOVE Below, DEPRECATED, Use IDENTITY struct // Should the session request compressed websocket data. Compress bool @@ -909,6 +914,54 @@ type GatewayBotResponse struct { Shards int `json:"shards"` } +// Gateway Status Update is sent by the client to indicate a presence or status update +// https://discordapp.com/developers/docs/topics/gateway#update-status-gateway-status-update-structure +type GatewayStatusUpdate struct { + Since int `json:"since"` + Game Activity `json:"game"` + Status string `json:"status"` + AFK bool `json:"afk"` +} + +type Activity struct { + Name string + Type ActivityType + URL string +} + +// GameType is the type of "game" (see GameType* consts) in the Game struct +// https://discordapp.com/developers/docs/topics/gateway#activity-object-activity-types +type ActivityType int + +// Valid GameType values +const ( + ActivityTypeGame GameType = iota + ActivityTypeStreaming + ActivityTypeListening + // ActivityTypeWatching // not valid in the use? + ActivityTypeCustom = 4 +) + +// Identify is sent during initial handshake with the discord gateway. +// https://discordapp.com/developers/docs/topics/gateway#identify +type Identify struct { + Token string `json:"token"` + Properties IdentifyProperties `json:"properties"` + Compress bool `json:"compress"` + LargeThreshold int `json:"large_threshold"` + Shard *[2]int `json:"shard,omitempty"` + Presence GatewayStatusUpdate `json:"presence,omitempty"` + GuildSubscriptions bool `json:"guild_subscriptions"` +} + +type IdentifyProperties struct { + OS string `json:"$os"` + Browser string `json:"$browser"` + Device string `json:"$device"` + Referer string `json:"$referer"` + ReferringDomain string `json:"$referring_domain"` +} + // Constants for the different bit offsets of text channel permissions const ( PermissionReadMessages = 1 << (iota + 10) diff --git a/wsapi.go b/wsapi.go index c1fb91a..770c5df 100644 --- a/wsapi.go +++ b/wsapi.go @@ -18,7 +18,6 @@ import ( "fmt" "io" "net/http" - "runtime" "sync/atomic" "time" @@ -741,55 +740,42 @@ func (s *Session) onVoiceServerUpdate(st *VoiceServerUpdate) { } } -type identifyProperties struct { - OS string `json:"$os"` - Browser string `json:"$browser"` - Device string `json:"$device"` - Referer string `json:"$referer"` - ReferringDomain string `json:"$referring_domain"` -} - -type identifyData struct { - Token string `json:"token"` - Properties identifyProperties `json:"properties"` - LargeThreshold int `json:"large_threshold"` - Compress bool `json:"compress"` - Shard *[2]int `json:"shard,omitempty"` -} - type identifyOp struct { - Op int `json:"op"` - Data identifyData `json:"d"` + Op int `json:"op"` + Data Identify `json:"d"` } // identify sends the identify packet to the gateway func (s *Session) identify() error { + s.log(LogDebug, "called") - properties := identifyProperties{runtime.GOOS, - "Discordgo v" + VERSION, - "", - "", - "", + // TODO: This is a temporary block of code to help + // maintain backwards compatability + if s.Compress == false { + s.Identify.Compress = false } - data := identifyData{s.Token, - properties, - 250, - s.Compress, - nil, + // TODO: This is a temporary block of code to help + // maintain backwards compatability + if s.Token != "" && s.Identify.Token == "" { + s.Identify.Token = s.Token } + // TODO: Below block should be refactored so ShardID and ShardCount + // can be deprecated and their usage moved to the Session.Identify + // struct if s.ShardCount > 1 { if s.ShardID >= s.ShardCount { return ErrWSShardBounds } - data.Shard = &[2]int{s.ShardID, s.ShardCount} + s.Identify.Shard = &[2]int{s.ShardID, s.ShardCount} } - op := identifyOp{2, data} - + // Send Identify packet to Discord + op := identifyOp{2, s.Identify} + s.log(LogDebug, "Identify Packet: \n%#v", op) s.wsMutex.Lock() err := s.wsConn.WriteJSON(op) s.wsMutex.Unlock() From ee9178e2372894da113ae0bcaa9051cfa7b0faf2 Mon Sep 17 00:00:00 2001 From: Bruce Marriner Date: Mon, 20 Jan 2020 12:06:54 -0600 Subject: [PATCH 16/52] Fix wording --- structs.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/structs.go b/structs.go index c509f3a..f9b7f1f 100644 --- a/structs.go +++ b/structs.go @@ -29,8 +29,10 @@ type Session struct { // General configurable settings. // Authentication token for this session + // TODO: Remove Below, Deprecated, Use Identify struct Token string - MFA bool + + MFA bool // Debug for printing JSON request/responses Debug bool // Deprecated, will be removed. @@ -43,7 +45,7 @@ type Session struct { // https://discordapp.com/developers/docs/topics/gateway#identify Identify Identify - // TODO: REMOVE Below, DEPRECATED, Use IDENTITY struct + // TODO: Remove Below, Deprecated, Use Identify struct // Should the session request compressed websocket data. Compress bool From eff98faf41318a674260221bd3b82107618c7e8d Mon Sep 17 00:00:00 2001 From: Bruce Marriner Date: Mon, 20 Jan 2020 12:10:20 -0600 Subject: [PATCH 17/52] Fix wording --- structs.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/structs.go b/structs.go index f9b7f1f..4e09194 100644 --- a/structs.go +++ b/structs.go @@ -925,22 +925,25 @@ type GatewayStatusUpdate struct { AFK bool `json:"afk"` } +// https://discordapp.com/developers/docs/topics/gateway#activity-object +// Activity defines the Activity sent with GatewayStatusUpdate type Activity struct { Name string Type ActivityType URL string } -// GameType is the type of "game" (see GameType* consts) in the Game struct +// ActivityType is the type of Activity (see ActivityType* consts) in the Activity struct // https://discordapp.com/developers/docs/topics/gateway#activity-object-activity-types type ActivityType int -// Valid GameType values +// Valid ActivityType values +//https://discordapp.com/developers/docs/topics/gateway#activity-object-activity-types const ( ActivityTypeGame GameType = iota ActivityTypeStreaming ActivityTypeListening - // ActivityTypeWatching // not valid in the use? + // ActivityTypeWatching // not valid in this use case? ActivityTypeCustom = 4 ) From 69f369a9f41321d082db72ff9bf16c6714f5f8cd Mon Sep 17 00:00:00 2001 From: Bruce Marriner Date: Mon, 20 Jan 2020 12:20:30 -0600 Subject: [PATCH 18/52] Linting. --- structs.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/structs.go b/structs.go index 4e09194..8abc1c6 100644 --- a/structs.go +++ b/structs.go @@ -916,7 +916,7 @@ type GatewayBotResponse struct { Shards int `json:"shards"` } -// Gateway Status Update is sent by the client to indicate a presence or status update +// GatewayStatusUpdate is sent by the client to indicate a presence or status update // https://discordapp.com/developers/docs/topics/gateway#update-status-gateway-status-update-structure type GatewayStatusUpdate struct { Since int `json:"since"` @@ -925,8 +925,8 @@ type GatewayStatusUpdate struct { AFK bool `json:"afk"` } -// https://discordapp.com/developers/docs/topics/gateway#activity-object // Activity defines the Activity sent with GatewayStatusUpdate +// https://discordapp.com/developers/docs/topics/gateway#activity-object type Activity struct { Name string Type ActivityType @@ -959,6 +959,8 @@ type Identify struct { GuildSubscriptions bool `json:"guild_subscriptions"` } +// IdentifyProperties contains the "properties" portion of an Identify packet +// https://discordapp.com/developers/docs/topics/gateway#identify-identify-connection-properties type IdentifyProperties struct { OS string `json:"$os"` Browser string `json:"$browser"` From c737258c067a0b91f5c24d273102a896940b9043 Mon Sep 17 00:00:00 2001 From: Helba Date: Wed, 22 Jan 2020 14:50:38 -0800 Subject: [PATCH 19/52] Added missing features --- go.mod | 2 ++ structs.go | 14 ++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 2ff8868..8cd2cf6 100644 --- a/go.mod +++ b/go.mod @@ -4,3 +4,5 @@ require ( github.com/gorilla/websocket v1.4.0 golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16 ) + +go 1.13 diff --git a/structs.go b/structs.go index fd78fc9..827df72 100644 --- a/structs.go +++ b/structs.go @@ -587,12 +587,13 @@ type VoiceState struct { // A Presence stores the online, offline, or idle and game status of Guild members. type Presence struct { - User *User `json:"user"` - Status Status `json:"status"` - Game *Game `json:"game"` - Nick string `json:"nick"` - Roles []string `json:"roles"` - Since *int `json:"since"` + User *User `json:"user"` + Status Status `json:"status"` + Game *Game `json:"game"` + Activities []*Game `json:"activities"` + Nick string `json:"nick"` + Roles []string `json:"roles"` + Since *int `json:"since"` } // GameType is the type of "game" (see GameType* consts) in the Game struct @@ -604,6 +605,7 @@ const ( GameTypeStreaming GameTypeListening GameTypeWatching + GameTypeCustom ) // A Game struct holds the name of the "playing .." game for a user From 19c4a067d05b5835d314a8b4e651811c6c9bbf61 Mon Sep 17 00:00:00 2001 From: Bruce Marriner Date: Thu, 23 Jan 2020 09:33:36 -0600 Subject: [PATCH 20/52] Fixing Nits --- structs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/structs.go b/structs.go index 8abc1c6..f8f6707 100644 --- a/structs.go +++ b/structs.go @@ -938,7 +938,7 @@ type Activity struct { type ActivityType int // Valid ActivityType values -//https://discordapp.com/developers/docs/topics/gateway#activity-object-activity-types +// https://discordapp.com/developers/docs/topics/gateway#activity-object-activity-types const ( ActivityTypeGame GameType = iota ActivityTypeStreaming From 817c9f816a93b9aeeb1ed85f2687f54e0d37c311 Mon Sep 17 00:00:00 2001 From: Helba Date: Thu, 23 Jan 2020 09:50:17 -0800 Subject: [PATCH 21/52] Update go.mod --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 8cd2cf6..79ea036 100644 --- a/go.mod +++ b/go.mod @@ -5,4 +5,4 @@ require ( golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16 ) -go 1.13 +go 1.10 From d41f0ec7e06b7114fd9c91fc01d2e9ecabfdfdf7 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 1 Mar 2020 20:46:23 +0300 Subject: [PATCH 22/52] events: add BeforeDelete to MessageDelete --- events.go | 1 + 1 file changed, 1 insertion(+) diff --git a/events.go b/events.go index c416813..accad7e 100644 --- a/events.go +++ b/events.go @@ -169,6 +169,7 @@ type MessageUpdate struct { // MessageDelete is the data for a MessageDelete event. type MessageDelete struct { *Message + BeforeDelete *Message `json:"-"` } // MessageReactionAdd is the data for a MessageReactionAdd event. From 97c5e2f7dc1951041c9e2ed62ea0c00225c01524 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 1 Mar 2020 20:48:14 +0300 Subject: [PATCH 23/52] state: add filling out BeforeDelete before deleting message --- state.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/state.go b/state.go index 7babc11..55619ef 100644 --- a/state.go +++ b/state.go @@ -893,6 +893,13 @@ func (s *State) OnInterface(se *Session, i interface{}) (err error) { } case *MessageDelete: if s.MaxMessageCount != 0 { + var old *Message + old, err = s.Message(t.ChannelID, t.ID) + if err == nil { + oldCopy := *old + t.BeforeDelete = &oldCopy + } + err = s.MessageRemove(t.Message) } case *MessageDeleteBulk: From edf402529a14307ccb56412bb9eee724c2a0b416 Mon Sep 17 00:00:00 2001 From: Filip Sufitchi Date: Wed, 11 Mar 2020 16:14:48 -0400 Subject: [PATCH 24/52] Add clarifying docs for using an OAuth2 token --- discord.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/discord.go b/discord.go index ac4e542..71fb0de 100644 --- a/discord.go +++ b/discord.go @@ -30,10 +30,13 @@ var ErrMFA = errors.New("account has 2FA enabled") // tasks if given enough information to do so. Currently you can pass zero // arguments and it will return an empty Discord session. // There are 3 ways to call New: -// With a single auth token - All requests will use the token blindly, +// With a single auth token - All requests will use the token blindly +// (just tossing it into the HTTP Authorization header); // no verification of the token will be done and requests may fail. // IF THE TOKEN IS FOR A BOT, IT MUST BE PREFIXED WITH `BOT ` // eg: `"Bot "` +// IF IT IS AN OAUTH2 ACCESS TOKEN, IT MUST BE PREFIXED WITH `Bearer ` +// eg: `"Bearer "` // With an email and password - Discord will sign in with the provided // credentials. // With an email, password and auth token - Discord will verify the auth From abf56b54f89ea85a303fb9c19799f0c1a4d99e55 Mon Sep 17 00:00:00 2001 From: Cameron Wood <40234975+camsw@users.noreply.github.com> Date: Sun, 29 Mar 2020 11:23:11 -0700 Subject: [PATCH 25/52] Added Presences field for GuildMembersChunk (#755) --- events.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/events.go b/events.go index accad7e..be394ae 100644 --- a/events.go +++ b/events.go @@ -139,8 +139,9 @@ type GuildEmojisUpdate struct { // A GuildMembersChunk is the data for a GuildMembersChunk event. type GuildMembersChunk struct { - GuildID string `json:"guild_id"` - Members []*Member `json:"members"` + GuildID string `json:"guild_id"` + Members []*Member `json:"members"` + Presences []*Presence `json:"presences,omitempty"` } // GuildIntegrationsUpdate is the data for a GuildIntegrationsUpdate event. From e26e63568421f7d4af71cef5eba3c3d1d329c039 Mon Sep 17 00:00:00 2001 From: Eric Wohltman Date: Wed, 1 Apr 2020 08:04:42 -0400 Subject: [PATCH 26/52] Add bitwise permission const PermissionViewChannel --- .gitignore | 2 ++ structs.go | 1 + 2 files changed, 3 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..34d2efa --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# IDE-specific metadata +.idea/ diff --git a/structs.go b/structs.go index 0afe138..3e9aecd 100644 --- a/structs.go +++ b/structs.go @@ -1014,6 +1014,7 @@ const ( PermissionManageServer PermissionAddReactions PermissionViewAuditLogs + PermissionViewChannel PermissionAllText = PermissionReadMessages | PermissionSendMessages | From e83cac31da0299415634884f5d2d3ee73f992752 Mon Sep 17 00:00:00 2001 From: Eric Wohltman Date: Wed, 1 Apr 2020 10:00:26 -0400 Subject: [PATCH 27/52] Add PermissionReadMessages deprecated comment --- structs.go | 1 + 1 file changed, 1 insertion(+) diff --git a/structs.go b/structs.go index 3e9aecd..5b8fc45 100644 --- a/structs.go +++ b/structs.go @@ -973,6 +973,7 @@ type IdentifyProperties struct { // Constants for the different bit offsets of text channel permissions const ( + // Deprecated: PermissionReadMessages has been replaced with PermissionViewChannel for text and voice channels PermissionReadMessages = 1 << (iota + 10) PermissionSendMessages PermissionSendTTSMessages From e66f73bf50a067510b38f58959ca1cb7436417d1 Mon Sep 17 00:00:00 2001 From: Eric Wohltman Date: Wed, 1 Apr 2020 10:05:24 -0400 Subject: [PATCH 28/52] Update compound permission sets to use PermissionViewChannel --- structs.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/structs.go b/structs.go index 5b8fc45..e177d29 100644 --- a/structs.go +++ b/structs.go @@ -1017,7 +1017,7 @@ const ( PermissionViewAuditLogs PermissionViewChannel - PermissionAllText = PermissionReadMessages | + PermissionAllText = PermissionViewChannel | PermissionSendMessages | PermissionSendTTSMessages | PermissionManageMessages | @@ -1025,7 +1025,8 @@ const ( PermissionAttachFiles | PermissionReadMessageHistory | PermissionMentionEveryone - PermissionAllVoice = PermissionVoiceConnect | + PermissionAllVoice = PermissionViewChannel | + PermissionVoiceConnect | PermissionVoiceSpeak | PermissionVoiceMuteMembers | PermissionVoiceDeafenMembers | From 0a159acc0cfb12fd4dd37d67a0d224f4af24d9ea Mon Sep 17 00:00:00 2001 From: Eric Wohltman Date: Mon, 6 Apr 2020 12:50:24 -0400 Subject: [PATCH 29/52] Fix offset for PermissionViewChannel (#757) --- structs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/structs.go b/structs.go index e177d29..730c91f 100644 --- a/structs.go +++ b/structs.go @@ -1015,7 +1015,7 @@ const ( PermissionManageServer PermissionAddReactions PermissionViewAuditLogs - PermissionViewChannel + PermissionViewChannel = 1 << (iota + 10) PermissionAllText = PermissionViewChannel | PermissionSendMessages | From 3736887e9b97c2b26bf0767d60543ded5a41c851 Mon Sep 17 00:00:00 2001 From: Eric Wohltman Date: Mon, 6 Apr 2020 14:00:23 -0400 Subject: [PATCH 30/52] Bitwise view channel permission (#758) * Fix offset for PermissionViewChannel * Fix offset for PermissionViewChannel --- structs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/structs.go b/structs.go index 730c91f..5ce8769 100644 --- a/structs.go +++ b/structs.go @@ -1015,7 +1015,7 @@ const ( PermissionManageServer PermissionAddReactions PermissionViewAuditLogs - PermissionViewChannel = 1 << (iota + 10) + PermissionViewChannel = 1 << (iota + 2) PermissionAllText = PermissionViewChannel | PermissionSendMessages | From 3fa12df9f04bf6e8402edd80983175e8eb9f8499 Mon Sep 17 00:00:00 2001 From: Eric Wohltman Date: Tue, 7 Apr 2020 14:00:36 -0400 Subject: [PATCH 31/52] Change log level for websocket connection failure from warning to error --- wsapi.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wsapi.go b/wsapi.go index 770c5df..0439a93 100644 --- a/wsapi.go +++ b/wsapi.go @@ -79,7 +79,7 @@ func (s *Session) Open() error { header.Add("accept-encoding", "zlib") s.wsConn, _, err = websocket.DefaultDialer.Dial(s.gateway, header) if err != nil { - s.log(LogWarning, "error connecting to gateway %s, %s", s.gateway, err) + s.log(LogError, "error connecting to gateway %s, %s", s.gateway, err) s.gateway = "" // clear cached gateway s.wsConn = nil // Just to be safe. return err From 17892272990ad3cda0b2d80d47b2879ff14361bf Mon Sep 17 00:00:00 2001 From: Carson Hoffman Date: Sat, 11 Apr 2020 22:05:27 -0400 Subject: [PATCH 32/52] Allow resume on reconnect --- wsapi.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/wsapi.go b/wsapi.go index 770c5df..d835ac2 100644 --- a/wsapi.go +++ b/wsapi.go @@ -516,7 +516,7 @@ func (s *Session) onEvent(messageType int, message []byte) (*Event, error) { // Must immediately disconnect from gateway and reconnect to new gateway. if e.Operation == 7 { s.log(LogInformational, "Closing and reconnecting in response to Op7") - s.Close() + s.CloseWithCode(websocket.CloseServiceRestart) s.reconnect() return e, nil } @@ -838,9 +838,13 @@ func (s *Session) reconnect() { } } +func (s *Session) Close() error { + return s.CloseWithCode(websocket.CloseNormalClosure) +} + // Close closes a websocket and stops all listening/heartbeat goroutines. // TODO: Add support for Voice WS/UDP connections -func (s *Session) Close() (err error) { +func (s *Session) CloseWithCode(closeCode int) (err error) { s.log(LogInformational, "called") s.Lock() @@ -862,7 +866,7 @@ func (s *Session) Close() (err error) { // To cleanly close a connection, a client should send a close // frame and wait for the server to close the connection. s.wsMutex.Lock() - err := s.wsConn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) + err := s.wsConn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(closeCode, "")) s.wsMutex.Unlock() if err != nil { s.log(LogInformational, "error closing websocket, %s", err) From 757302eb784d8317c5126b745205a4c712eccb5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Horonziak?= Date: Sat, 18 Apr 2020 22:30:51 +0200 Subject: [PATCH 33/52] Add intents --- discord.go | 1 + structs.go | 1 + 2 files changed, 2 insertions(+) diff --git a/discord.go b/discord.go index 74c7887..1944c15 100644 --- a/discord.go +++ b/discord.go @@ -74,6 +74,7 @@ func New(args ...interface{}) (s *Session, err error) { s.Identify.GuildSubscriptions = true s.Identify.Properties.OS = runtime.GOOS s.Identify.Properties.Browser = "DiscordGo v" + VERSION + s.Identify.Intents = 32767 // If no arguments are passed return the empty Session interface. if args == nil { diff --git a/structs.go b/structs.go index 5ce8769..43b39b5 100644 --- a/structs.go +++ b/structs.go @@ -959,6 +959,7 @@ type Identify struct { Shard *[2]int `json:"shard,omitempty"` Presence GatewayStatusUpdate `json:"presence,omitempty"` GuildSubscriptions bool `json:"guild_subscriptions"` + Intents int `json:"intents"` } // IdentifyProperties contains the "properties" portion of an Identify packet From 349da37386212f2236adcb8b3cf5e209f47544d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Horonziak?= Date: Sun, 19 Apr 2020 11:11:41 +0200 Subject: [PATCH 34/52] Refactor --- discord.go | 2 +- structs.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/discord.go b/discord.go index 1944c15..789ca68 100644 --- a/discord.go +++ b/discord.go @@ -74,7 +74,7 @@ func New(args ...interface{}) (s *Session, err error) { s.Identify.GuildSubscriptions = true s.Identify.Properties.OS = runtime.GOOS s.Identify.Properties.Browser = "DiscordGo v" + VERSION - s.Identify.Intents = 32767 + s.Identify.Intents = IntentsAllWithoutPrivileged // If no arguments are passed return the empty Session interface. if args == nil { diff --git a/structs.go b/structs.go index 43b39b5..944f899 100644 --- a/structs.go +++ b/structs.go @@ -1103,3 +1103,38 @@ const ( ErrCodeReactionBlocked = 90001 ) + +const ( + IntentsGuilds = 1 << iota + IntentsGuildMembers + IntentsGuildBans + IntentsGuildEmojis + IntentsGuildIntegrations + IntentsGuildWebhooks + IntentsGuildInvites + IntentsGuildVoiceStates + IntentsGuildPresences + IntentsGuildMessages + IntentsGuildMessageReactions + IntentsGuildMessageTyping + IntentsDirectMessagesMessages + IntentsDirectMessageReaction + IntentsDirectMessageTyping + + IntentsAllWithoutPrivileged = IntentsGuilds | + IntentsGuildBans | + IntentsGuildEmojis | + IntentsGuildIntegrations | + IntentsGuildWebhooks | + IntentsGuildInvites | + IntentsGuildVoiceStates | + IntentsGuildMessages | + IntentsGuildMessageReactions | + IntentsGuildMessageTyping | + IntentsDirectMessagesMessages | + IntentsDirectMessageReaction | + IntentsDirectMessageTyping + IntentsAll = IntentsAllWithoutPrivileged | + IntentsGuildMembers | + IntentsGuildPresences +) From 895df5370c02497cf1fac60b6c235aa4985b65e6 Mon Sep 17 00:00:00 2001 From: Carson Hoffman Date: Sun, 19 Apr 2020 10:29:47 -0400 Subject: [PATCH 35/52] Add allowed mentions --- message.go | 50 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/message.go b/message.go index aebddbb..00b8112 100644 --- a/message.go +++ b/message.go @@ -129,10 +129,11 @@ type File struct { // MessageSend stores all parameters you can send with ChannelMessageSendComplex. type MessageSend struct { - Content string `json:"content,omitempty"` - Embed *MessageEmbed `json:"embed,omitempty"` - TTS bool `json:"tts"` - Files []*File `json:"-"` + Content string `json:"content,omitempty"` + Embed *MessageEmbed `json:"embed,omitempty"` + TTS bool `json:"tts"` + Files []*File `json:"-"` + AllowedMentions *MessageAllowedMentions `json:"allowed_mentions,omitempty"` // TODO: Remove this when compatibility is not required. File *File `json:"-"` @@ -141,8 +142,9 @@ type MessageSend struct { // MessageEdit is used to chain parameters via ChannelMessageEditComplex, which // is also where you should get the instance from. type MessageEdit struct { - Content *string `json:"content,omitempty"` - Embed *MessageEmbed `json:"embed,omitempty"` + Content *string `json:"content,omitempty"` + Embed *MessageEmbed `json:"embed,omitempty"` + AllowedMentions *MessageAllowedMentions `json:"allowed_mentions,omitempty"` ID string Channel string @@ -171,6 +173,42 @@ func (m *MessageEdit) SetEmbed(embed *MessageEmbed) *MessageEdit { return m } +// AllowedMentionType describes the types of mentions used +// in the MessageAllowedMentions type. +type AllowedMentionType string + +// The types of mentions used in MessageAllowedMentions. +const ( + AllowedMentionTypeRoles AllowedMentionType = "roles" + AllowedMentionTypeUsers AllowedMentionType = "users" + AllowedMentionTypeEveryone AllowedMentionType = "everyone" +) + +// MessageAllowedMentions allows the user to specify which mentions +// Discord is allowed to parse in this message. This is useful when +// sending user input as a message, as it prevents unwanted mentions. +// If this type is used, all mentions must be explicitly whitelisted, +// either by putting an AllowedMentionType in the Parse slice +// (allowing all mentions of that type) or, in the case of roles and +// users, explicitly allowing those mentions on an ID-by-ID basis. +// For more information on this functionality, see: +// https://discordapp.com/developers/docs/resources/channel#allowed-mentions-object-allowed-mentions-reference +type MessageAllowedMentions struct { + // The mention types that are allowed to be parsed in this message. + // Please note that this is purposely **not** marked as omitempty, + // so if a zero-value MessageAllowedMentions object is provided no + // mentions will be allowed. + Parse []AllowedMentionType `json:"parse"` + + // A list of role IDs to allow. This cannot be used when specifying + // AllowedMentionTypeRoles in the Parse slice. + Roles []string `json:"roles,omitempty"` + + // A list of user IDs to allow. This cannot be used when specifying + // AllowedMentionTypeUsers in the Parse slice. + Users []string `json:"users,omitempty"` +} + // A MessageAttachment stores data for message attachments. type MessageAttachment struct { ID string `json:"id"` From d12e6550c69e59951f8d657753d51c24f6243377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Horonziak?= Date: Sun, 19 Apr 2020 17:36:35 +0200 Subject: [PATCH 36/52] Typos --- structs.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/structs.go b/structs.go index 944f899..3efc326 100644 --- a/structs.go +++ b/structs.go @@ -1117,8 +1117,8 @@ const ( IntentsGuildMessages IntentsGuildMessageReactions IntentsGuildMessageTyping - IntentsDirectMessagesMessages - IntentsDirectMessageReaction + IntentsDirectMessages + IntentsDirectMessageReactions IntentsDirectMessageTyping IntentsAllWithoutPrivileged = IntentsGuilds | @@ -1131,8 +1131,8 @@ const ( IntentsGuildMessages | IntentsGuildMessageReactions | IntentsGuildMessageTyping | - IntentsDirectMessagesMessages | - IntentsDirectMessageReaction | + IntentsDirectMessages | + IntentsDirectMessageReactions | IntentsDirectMessageTyping IntentsAll = IntentsAllWithoutPrivileged | IntentsGuildMembers | From 44c2b25369d039538b40d7c094bf8639a0d789e3 Mon Sep 17 00:00:00 2001 From: Eric Wohltman Date: Tue, 21 Apr 2020 08:16:51 -0400 Subject: [PATCH 37/52] Fix godoc style exported function comments --- wsapi.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/wsapi.go b/wsapi.go index 0098094..e3d5045 100644 --- a/wsapi.go +++ b/wsapi.go @@ -838,11 +838,14 @@ func (s *Session) reconnect() { } } +// Close closes a websocket and stops all listening/heartbeat goroutines. +// TODO: Add support for Voice WS/UDP func (s *Session) Close() error { return s.CloseWithCode(websocket.CloseNormalClosure) } -// Close closes a websocket and stops all listening/heartbeat goroutines. +// CloseWithCode closes a websocket using the provided closeCode and stops all +// listening/heartbeat goroutines. // TODO: Add support for Voice WS/UDP connections func (s *Session) CloseWithCode(closeCode int) (err error) { From db7a34f303989b3f6f40c3fa4ecc73294a7658b8 Mon Sep 17 00:00:00 2001 From: Tobias Messner Date: Thu, 30 Apr 2020 23:22:18 +0200 Subject: [PATCH 38/52] Fix typo in PingPong example (#767) --- examples/pingpong/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/pingpong/main.go b/examples/pingpong/main.go index 155e782..f3000be 100644 --- a/examples/pingpong/main.go +++ b/examples/pingpong/main.go @@ -51,7 +51,7 @@ func main() { } // This function will be called (due to AddHandler above) every time a new -// message is created on any channel that the autenticated bot has access to. +// message is created on any channel that the authenticated bot has access to. func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) { // Ignore all messages created by the bot itself From f4ca8874a38e566b7693170c8c759cac32428623 Mon Sep 17 00:00:00 2001 From: Hunter Paulson Date: Tue, 5 May 2020 00:13:28 -0400 Subject: [PATCH 39/52] Changed domain from `discordapp.com` to `discord.com` (#769) * Allow resume on reconnect * Version 0.20.3: allow resume on reconnect * Update index.md * Update README.md * Update GettingStarted.md * Update endpoints.go * Update README.md * Update event.go * Update wsapi.go * Update restapi.go * Resolved spelling issue Co-authored-by: Carson Hoffman --- README.md | 6 +++--- docs/GettingStarted.md | 6 +++--- docs/index.md | 6 +++--- endpoints.go | 4 ++-- event.go | 2 +- examples/appmaker/README.md | 2 +- restapi.go | 4 ++-- wsapi.go | 6 +++++- 8 files changed, 20 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 7a83b9e..4410d1e 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ # DiscordGo -[![GoDoc](https://godoc.org/github.com/bwmarrin/discordgo?status.svg)](https://godoc.org/github.com/bwmarrin/discordgo) [![Go report](http://goreportcard.com/badge/bwmarrin/discordgo)](http://goreportcard.com/report/bwmarrin/discordgo) [![Build Status](https://travis-ci.org/bwmarrin/discordgo.svg?branch=master)](https://travis-ci.org/bwmarrin/discordgo) [![Discord Gophers](https://img.shields.io/badge/Discord%20Gophers-%23discordgo-blue.svg)](https://discord.gg/0f1SbxBZjYoCtNPP) [![Discord API](https://img.shields.io/badge/Discord%20API-%23go_discordgo-blue.svg)](https://discordapp.com/invite/discord-api) +[![GoDoc](https://godoc.org/github.com/bwmarrin/discordgo?status.svg)](https://godoc.org/github.com/bwmarrin/discordgo) [![Go report](http://goreportcard.com/badge/bwmarrin/discordgo)](http://goreportcard.com/report/bwmarrin/discordgo) [![Build Status](https://travis-ci.org/bwmarrin/discordgo.svg?branch=master)](https://travis-ci.org/bwmarrin/discordgo) [![Discord Gophers](https://img.shields.io/badge/Discord%20Gophers-%23discordgo-blue.svg)](https://discord.gg/0f1SbxBZjYoCtNPP) [![Discord API](https://img.shields.io/badge/Discord%20API-%23go_discordgo-blue.svg)](https://discord.com/invite/discord-api) DiscordGo is a [Go](https://golang.org/) package that provides low level -bindings to the [Discord](https://discordapp.com/) chat client API. DiscordGo +bindings to the [Discord](https://discord.com/) chat client API. DiscordGo has nearly complete support for all of the Discord API endpoints, websocket interface, and voice interface. If you would like to help the DiscordGo package please use -[this link](https://discordapp.com/oauth2/authorize?client_id=173113690092994561&scope=bot) +[this link](https://discord.com/oauth2/authorize?client_id=173113690092994561&scope=bot) to add the official DiscordGo test bot **dgo** to your server. This provides indispensable help to this project. diff --git a/docs/GettingStarted.md b/docs/GettingStarted.md index efeb3ea..2d48a5a 100644 --- a/docs/GettingStarted.md +++ b/docs/GettingStarted.md @@ -58,7 +58,7 @@ support multi-server voice connections and some other features that are exclusive to Bot accounts only. To create a new user account (if you have not done so already) visit the -[Discord](https://discordapp.com/) website and click on the +[Discord](https://discord.com/) website and click on the **Try Discord Now, It's Free** button then follow the steps to setup your new account. @@ -77,12 +77,12 @@ have access to some user client specific features however they gain access to many Bot specific features. To create a new bot account first create yourself a normal user account on -Discord then visit the [My Applications](https://discordapp.com/developers/applications/me) +Discord then visit the [My Applications](https://discord.com/developers/applications/me) page and click on the **New Application** box. Follow the prompts from there to finish creating your account. -**More information about Bots vs Client accounts can be found [here](https://discordapp.com/developers/docs/topics/oauth2#bot-vs-user-accounts)** +**More information about Bots vs Client accounts can be found [here](https://discord.com/developers/docs/topics/oauth2#bot-vs-user-accounts)** # Requirements diff --git a/docs/index.md b/docs/index.md index 1dfdd90..81c3d51 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,12 +2,12 @@
-[Go](https://golang.org/) (golang) interface for the [Discord](https://discordapp.com/) +[Go](https://golang.org/) (golang) interface for the [Discord](https://discord.com/) chat service. Provides both low-level direct bindings to the Discord API and helper functions that allow you to make custom clients and chat bot applications easily. -[Discord](https://discordapp.com/) is an all-in-one voice and text chat for +[Discord](https://discord.com/) is an all-in-one voice and text chat for gamers that's free, secure, and works on both your desktop and phone. ### Why DiscordGo? @@ -30,4 +30,4 @@ information and support for DiscordGo. There's also a chance to make some friends :) * Join the [Discord Gophers](https://discord.gg/0f1SbxBZjYoCtNPP) chat server dedicated to Go programming. -* Join the [Discord API](https://discordapp.com/invite/discord-API) chat server dedicated to the Discord API. +* Join the [Discord API](https://discord.com/invite/discord-API) chat server dedicated to the Discord API. diff --git a/endpoints.go b/endpoints.go index 6f86b67..3d0c614 100644 --- a/endpoints.go +++ b/endpoints.go @@ -18,12 +18,12 @@ var APIVersion = "6" // Known Discord API Endpoints. var ( - EndpointStatus = "https://status.discordapp.com/api/v2/" + EndpointStatus = "https://status.discord.com/api/v2/" EndpointSm = EndpointStatus + "scheduled-maintenances/" EndpointSmActive = EndpointSm + "active.json" EndpointSmUpcoming = EndpointSm + "upcoming.json" - EndpointDiscord = "https://discordapp.com/" + EndpointDiscord = "https://discord.com/" EndpointAPI = EndpointDiscord + "api/v" + APIVersion + "/" EndpointGuilds = EndpointAPI + "guilds/" EndpointChannels = EndpointAPI + "channels/" diff --git a/event.go b/event.go index 97cc00a..67c5f7d 100644 --- a/event.go +++ b/event.go @@ -110,7 +110,7 @@ func (s *Session) addEventHandlerOnce(eventHandler EventHandler) func() { // }) // // List of events can be found at this page, with corresponding names in the -// library for each event: https://discordapp.com/developers/docs/topics/gateway#event-names +// library for each event: https://discord.com/developers/docs/topics/gateway#event-names // There are also synthetic events fired by the library internally which are // available for handling, like Connect, Disconnect, and RateLimit. // events.go contains all of the Discord WSAPI and synthetic events that can be handled. diff --git a/examples/appmaker/README.md b/examples/appmaker/README.md index e0cc29a..351f559 100644 --- a/examples/appmaker/README.md +++ b/examples/appmaker/README.md @@ -6,7 +6,7 @@ This example demonstrates how to utilize DiscordGo to create, view, and delete Bot Applications on your account. These tasks are normally accomplished from the -[Discord Developers](https://discordapp.com/developers/applications/me) site. +[Discord Developers](https://discord.com/developers/applications/me) site. **Join [Discord Gophers](https://discord.gg/0f1SbxBZjYoCtNPP) Discord chat channel for support.** diff --git a/restapi.go b/restapi.go index 4bf1ba6..2eba734 100644 --- a/restapi.go +++ b/restapi.go @@ -38,7 +38,7 @@ var ( ErrPruneDaysBounds = errors.New("the number of days should be more than or equal to 1") ErrGuildNoIcon = errors.New("guild does not have an icon set") ErrGuildNoSplash = errors.New("guild does not have a splash set") - ErrUnauthorized = errors.New("HTTP request was unauthorized. This could be because the provided token was not a bot token. Please add \"Bot \" to the start of your token. https://discordapp.com/developers/docs/reference#authentication-example-bot-token-authorization-header") + ErrUnauthorized = errors.New("HTTP request was unauthorized. This could be because the provided token was not a bot token. Please add \"Bot \" to the start of your token. https://discord.com/developers/docs/reference#authentication-example-bot-token-authorization-header") ) // Request is the same as RequestWithBucketID but the bucket id is the same as the urlStr @@ -506,7 +506,7 @@ func (s *Session) UserChannelPermissions(userID, channelID string) (apermissions } // Calculates the permissions for a member. -// https://support.discordapp.com/hc/en-us/articles/206141927-How-is-the-permission-hierarchy-structured- +// https://support.discord.com/hc/en-us/articles/206141927-How-is-the-permission-hierarchy-structured- func memberPermissions(guild *Guild, channel *Channel, member *Member) (apermissions int) { userID := member.User.ID diff --git a/wsapi.go b/wsapi.go index e3d5045..e5f576a 100644 --- a/wsapi.go +++ b/wsapi.go @@ -46,7 +46,7 @@ type resumePacket struct { } // Open creates a websocket connection to Discord. -// See: https://discordapp.com/developers/docs/topics/gateway#connecting +// See: https://discord.com/developers/docs/topics/gateway#connecting func (s *Session) Open() error { s.log(LogInformational, "called") @@ -838,6 +838,10 @@ func (s *Session) reconnect() { } } +func (s *Session) Close() error { + return s.CloseWithCode(websocket.CloseNormalClosure) +} + // Close closes a websocket and stops all listening/heartbeat goroutines. // TODO: Add support for Voice WS/UDP func (s *Session) Close() error { From 45124d8303b8f0d34c19acd030dc37bf24546d89 Mon Sep 17 00:00:00 2001 From: Carson Hoffman Date: Thu, 7 May 2020 12:27:07 -0400 Subject: [PATCH 40/52] Revert "Changed domain from `discordapp.com` to `discord.com` (#769)" This reverts commit f4ca8874a38e566b7693170c8c759cac32428623. --- README.md | 6 +++--- docs/GettingStarted.md | 6 +++--- docs/index.md | 6 +++--- endpoints.go | 4 ++-- event.go | 2 +- examples/appmaker/README.md | 2 +- restapi.go | 4 ++-- wsapi.go | 6 +----- 8 files changed, 16 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 4410d1e..7a83b9e 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ # DiscordGo -[![GoDoc](https://godoc.org/github.com/bwmarrin/discordgo?status.svg)](https://godoc.org/github.com/bwmarrin/discordgo) [![Go report](http://goreportcard.com/badge/bwmarrin/discordgo)](http://goreportcard.com/report/bwmarrin/discordgo) [![Build Status](https://travis-ci.org/bwmarrin/discordgo.svg?branch=master)](https://travis-ci.org/bwmarrin/discordgo) [![Discord Gophers](https://img.shields.io/badge/Discord%20Gophers-%23discordgo-blue.svg)](https://discord.gg/0f1SbxBZjYoCtNPP) [![Discord API](https://img.shields.io/badge/Discord%20API-%23go_discordgo-blue.svg)](https://discord.com/invite/discord-api) +[![GoDoc](https://godoc.org/github.com/bwmarrin/discordgo?status.svg)](https://godoc.org/github.com/bwmarrin/discordgo) [![Go report](http://goreportcard.com/badge/bwmarrin/discordgo)](http://goreportcard.com/report/bwmarrin/discordgo) [![Build Status](https://travis-ci.org/bwmarrin/discordgo.svg?branch=master)](https://travis-ci.org/bwmarrin/discordgo) [![Discord Gophers](https://img.shields.io/badge/Discord%20Gophers-%23discordgo-blue.svg)](https://discord.gg/0f1SbxBZjYoCtNPP) [![Discord API](https://img.shields.io/badge/Discord%20API-%23go_discordgo-blue.svg)](https://discordapp.com/invite/discord-api) DiscordGo is a [Go](https://golang.org/) package that provides low level -bindings to the [Discord](https://discord.com/) chat client API. DiscordGo +bindings to the [Discord](https://discordapp.com/) chat client API. DiscordGo has nearly complete support for all of the Discord API endpoints, websocket interface, and voice interface. If you would like to help the DiscordGo package please use -[this link](https://discord.com/oauth2/authorize?client_id=173113690092994561&scope=bot) +[this link](https://discordapp.com/oauth2/authorize?client_id=173113690092994561&scope=bot) to add the official DiscordGo test bot **dgo** to your server. This provides indispensable help to this project. diff --git a/docs/GettingStarted.md b/docs/GettingStarted.md index 2d48a5a..efeb3ea 100644 --- a/docs/GettingStarted.md +++ b/docs/GettingStarted.md @@ -58,7 +58,7 @@ support multi-server voice connections and some other features that are exclusive to Bot accounts only. To create a new user account (if you have not done so already) visit the -[Discord](https://discord.com/) website and click on the +[Discord](https://discordapp.com/) website and click on the **Try Discord Now, It's Free** button then follow the steps to setup your new account. @@ -77,12 +77,12 @@ have access to some user client specific features however they gain access to many Bot specific features. To create a new bot account first create yourself a normal user account on -Discord then visit the [My Applications](https://discord.com/developers/applications/me) +Discord then visit the [My Applications](https://discordapp.com/developers/applications/me) page and click on the **New Application** box. Follow the prompts from there to finish creating your account. -**More information about Bots vs Client accounts can be found [here](https://discord.com/developers/docs/topics/oauth2#bot-vs-user-accounts)** +**More information about Bots vs Client accounts can be found [here](https://discordapp.com/developers/docs/topics/oauth2#bot-vs-user-accounts)** # Requirements diff --git a/docs/index.md b/docs/index.md index 81c3d51..1dfdd90 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,12 +2,12 @@
-[Go](https://golang.org/) (golang) interface for the [Discord](https://discord.com/) +[Go](https://golang.org/) (golang) interface for the [Discord](https://discordapp.com/) chat service. Provides both low-level direct bindings to the Discord API and helper functions that allow you to make custom clients and chat bot applications easily. -[Discord](https://discord.com/) is an all-in-one voice and text chat for +[Discord](https://discordapp.com/) is an all-in-one voice and text chat for gamers that's free, secure, and works on both your desktop and phone. ### Why DiscordGo? @@ -30,4 +30,4 @@ information and support for DiscordGo. There's also a chance to make some friends :) * Join the [Discord Gophers](https://discord.gg/0f1SbxBZjYoCtNPP) chat server dedicated to Go programming. -* Join the [Discord API](https://discord.com/invite/discord-API) chat server dedicated to the Discord API. +* Join the [Discord API](https://discordapp.com/invite/discord-API) chat server dedicated to the Discord API. diff --git a/endpoints.go b/endpoints.go index 3d0c614..6f86b67 100644 --- a/endpoints.go +++ b/endpoints.go @@ -18,12 +18,12 @@ var APIVersion = "6" // Known Discord API Endpoints. var ( - EndpointStatus = "https://status.discord.com/api/v2/" + EndpointStatus = "https://status.discordapp.com/api/v2/" EndpointSm = EndpointStatus + "scheduled-maintenances/" EndpointSmActive = EndpointSm + "active.json" EndpointSmUpcoming = EndpointSm + "upcoming.json" - EndpointDiscord = "https://discord.com/" + EndpointDiscord = "https://discordapp.com/" EndpointAPI = EndpointDiscord + "api/v" + APIVersion + "/" EndpointGuilds = EndpointAPI + "guilds/" EndpointChannels = EndpointAPI + "channels/" diff --git a/event.go b/event.go index 67c5f7d..97cc00a 100644 --- a/event.go +++ b/event.go @@ -110,7 +110,7 @@ func (s *Session) addEventHandlerOnce(eventHandler EventHandler) func() { // }) // // List of events can be found at this page, with corresponding names in the -// library for each event: https://discord.com/developers/docs/topics/gateway#event-names +// library for each event: https://discordapp.com/developers/docs/topics/gateway#event-names // There are also synthetic events fired by the library internally which are // available for handling, like Connect, Disconnect, and RateLimit. // events.go contains all of the Discord WSAPI and synthetic events that can be handled. diff --git a/examples/appmaker/README.md b/examples/appmaker/README.md index 351f559..e0cc29a 100644 --- a/examples/appmaker/README.md +++ b/examples/appmaker/README.md @@ -6,7 +6,7 @@ This example demonstrates how to utilize DiscordGo to create, view, and delete Bot Applications on your account. These tasks are normally accomplished from the -[Discord Developers](https://discord.com/developers/applications/me) site. +[Discord Developers](https://discordapp.com/developers/applications/me) site. **Join [Discord Gophers](https://discord.gg/0f1SbxBZjYoCtNPP) Discord chat channel for support.** diff --git a/restapi.go b/restapi.go index 2eba734..4bf1ba6 100644 --- a/restapi.go +++ b/restapi.go @@ -38,7 +38,7 @@ var ( ErrPruneDaysBounds = errors.New("the number of days should be more than or equal to 1") ErrGuildNoIcon = errors.New("guild does not have an icon set") ErrGuildNoSplash = errors.New("guild does not have a splash set") - ErrUnauthorized = errors.New("HTTP request was unauthorized. This could be because the provided token was not a bot token. Please add \"Bot \" to the start of your token. https://discord.com/developers/docs/reference#authentication-example-bot-token-authorization-header") + ErrUnauthorized = errors.New("HTTP request was unauthorized. This could be because the provided token was not a bot token. Please add \"Bot \" to the start of your token. https://discordapp.com/developers/docs/reference#authentication-example-bot-token-authorization-header") ) // Request is the same as RequestWithBucketID but the bucket id is the same as the urlStr @@ -506,7 +506,7 @@ func (s *Session) UserChannelPermissions(userID, channelID string) (apermissions } // Calculates the permissions for a member. -// https://support.discord.com/hc/en-us/articles/206141927-How-is-the-permission-hierarchy-structured- +// https://support.discordapp.com/hc/en-us/articles/206141927-How-is-the-permission-hierarchy-structured- func memberPermissions(guild *Guild, channel *Channel, member *Member) (apermissions int) { userID := member.User.ID diff --git a/wsapi.go b/wsapi.go index e5f576a..e3d5045 100644 --- a/wsapi.go +++ b/wsapi.go @@ -46,7 +46,7 @@ type resumePacket struct { } // Open creates a websocket connection to Discord. -// See: https://discord.com/developers/docs/topics/gateway#connecting +// See: https://discordapp.com/developers/docs/topics/gateway#connecting func (s *Session) Open() error { s.log(LogInformational, "called") @@ -838,10 +838,6 @@ func (s *Session) reconnect() { } } -func (s *Session) Close() error { - return s.CloseWithCode(websocket.CloseNormalClosure) -} - // Close closes a websocket and stops all listening/heartbeat goroutines. // TODO: Add support for Voice WS/UDP func (s *Session) Close() error { From 69edfdf4ace896e83a593e9ec537490c96cf11d3 Mon Sep 17 00:00:00 2001 From: Noah Santschi-Cooney Date: Sat, 9 May 2020 02:26:13 +0100 Subject: [PATCH 41/52] discordapp.com -> discord.com (#772) Change API URL from discordapp.com to discord.com --- README.md | 6 +++--- docs/GettingStarted.md | 6 +++--- docs/index.md | 6 +++--- endpoints.go | 4 ++-- event.go | 2 +- examples/appmaker/README.md | 2 +- restapi.go | 4 ++-- structs.go | 14 +++++++------- wsapi.go | 2 +- 9 files changed, 23 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 7a83b9e..4410d1e 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ # DiscordGo -[![GoDoc](https://godoc.org/github.com/bwmarrin/discordgo?status.svg)](https://godoc.org/github.com/bwmarrin/discordgo) [![Go report](http://goreportcard.com/badge/bwmarrin/discordgo)](http://goreportcard.com/report/bwmarrin/discordgo) [![Build Status](https://travis-ci.org/bwmarrin/discordgo.svg?branch=master)](https://travis-ci.org/bwmarrin/discordgo) [![Discord Gophers](https://img.shields.io/badge/Discord%20Gophers-%23discordgo-blue.svg)](https://discord.gg/0f1SbxBZjYoCtNPP) [![Discord API](https://img.shields.io/badge/Discord%20API-%23go_discordgo-blue.svg)](https://discordapp.com/invite/discord-api) +[![GoDoc](https://godoc.org/github.com/bwmarrin/discordgo?status.svg)](https://godoc.org/github.com/bwmarrin/discordgo) [![Go report](http://goreportcard.com/badge/bwmarrin/discordgo)](http://goreportcard.com/report/bwmarrin/discordgo) [![Build Status](https://travis-ci.org/bwmarrin/discordgo.svg?branch=master)](https://travis-ci.org/bwmarrin/discordgo) [![Discord Gophers](https://img.shields.io/badge/Discord%20Gophers-%23discordgo-blue.svg)](https://discord.gg/0f1SbxBZjYoCtNPP) [![Discord API](https://img.shields.io/badge/Discord%20API-%23go_discordgo-blue.svg)](https://discord.com/invite/discord-api) DiscordGo is a [Go](https://golang.org/) package that provides low level -bindings to the [Discord](https://discordapp.com/) chat client API. DiscordGo +bindings to the [Discord](https://discord.com/) chat client API. DiscordGo has nearly complete support for all of the Discord API endpoints, websocket interface, and voice interface. If you would like to help the DiscordGo package please use -[this link](https://discordapp.com/oauth2/authorize?client_id=173113690092994561&scope=bot) +[this link](https://discord.com/oauth2/authorize?client_id=173113690092994561&scope=bot) to add the official DiscordGo test bot **dgo** to your server. This provides indispensable help to this project. diff --git a/docs/GettingStarted.md b/docs/GettingStarted.md index efeb3ea..2d48a5a 100644 --- a/docs/GettingStarted.md +++ b/docs/GettingStarted.md @@ -58,7 +58,7 @@ support multi-server voice connections and some other features that are exclusive to Bot accounts only. To create a new user account (if you have not done so already) visit the -[Discord](https://discordapp.com/) website and click on the +[Discord](https://discord.com/) website and click on the **Try Discord Now, It's Free** button then follow the steps to setup your new account. @@ -77,12 +77,12 @@ have access to some user client specific features however they gain access to many Bot specific features. To create a new bot account first create yourself a normal user account on -Discord then visit the [My Applications](https://discordapp.com/developers/applications/me) +Discord then visit the [My Applications](https://discord.com/developers/applications/me) page and click on the **New Application** box. Follow the prompts from there to finish creating your account. -**More information about Bots vs Client accounts can be found [here](https://discordapp.com/developers/docs/topics/oauth2#bot-vs-user-accounts)** +**More information about Bots vs Client accounts can be found [here](https://discord.com/developers/docs/topics/oauth2#bot-vs-user-accounts)** # Requirements diff --git a/docs/index.md b/docs/index.md index 1dfdd90..81c3d51 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,12 +2,12 @@
-[Go](https://golang.org/) (golang) interface for the [Discord](https://discordapp.com/) +[Go](https://golang.org/) (golang) interface for the [Discord](https://discord.com/) chat service. Provides both low-level direct bindings to the Discord API and helper functions that allow you to make custom clients and chat bot applications easily. -[Discord](https://discordapp.com/) is an all-in-one voice and text chat for +[Discord](https://discord.com/) is an all-in-one voice and text chat for gamers that's free, secure, and works on both your desktop and phone. ### Why DiscordGo? @@ -30,4 +30,4 @@ information and support for DiscordGo. There's also a chance to make some friends :) * Join the [Discord Gophers](https://discord.gg/0f1SbxBZjYoCtNPP) chat server dedicated to Go programming. -* Join the [Discord API](https://discordapp.com/invite/discord-API) chat server dedicated to the Discord API. +* Join the [Discord API](https://discord.com/invite/discord-API) chat server dedicated to the Discord API. diff --git a/endpoints.go b/endpoints.go index 6f86b67..3d0c614 100644 --- a/endpoints.go +++ b/endpoints.go @@ -18,12 +18,12 @@ var APIVersion = "6" // Known Discord API Endpoints. var ( - EndpointStatus = "https://status.discordapp.com/api/v2/" + EndpointStatus = "https://status.discord.com/api/v2/" EndpointSm = EndpointStatus + "scheduled-maintenances/" EndpointSmActive = EndpointSm + "active.json" EndpointSmUpcoming = EndpointSm + "upcoming.json" - EndpointDiscord = "https://discordapp.com/" + EndpointDiscord = "https://discord.com/" EndpointAPI = EndpointDiscord + "api/v" + APIVersion + "/" EndpointGuilds = EndpointAPI + "guilds/" EndpointChannels = EndpointAPI + "channels/" diff --git a/event.go b/event.go index 97cc00a..67c5f7d 100644 --- a/event.go +++ b/event.go @@ -110,7 +110,7 @@ func (s *Session) addEventHandlerOnce(eventHandler EventHandler) func() { // }) // // List of events can be found at this page, with corresponding names in the -// library for each event: https://discordapp.com/developers/docs/topics/gateway#event-names +// library for each event: https://discord.com/developers/docs/topics/gateway#event-names // There are also synthetic events fired by the library internally which are // available for handling, like Connect, Disconnect, and RateLimit. // events.go contains all of the Discord WSAPI and synthetic events that can be handled. diff --git a/examples/appmaker/README.md b/examples/appmaker/README.md index e0cc29a..351f559 100644 --- a/examples/appmaker/README.md +++ b/examples/appmaker/README.md @@ -6,7 +6,7 @@ This example demonstrates how to utilize DiscordGo to create, view, and delete Bot Applications on your account. These tasks are normally accomplished from the -[Discord Developers](https://discordapp.com/developers/applications/me) site. +[Discord Developers](https://discord.com/developers/applications/me) site. **Join [Discord Gophers](https://discord.gg/0f1SbxBZjYoCtNPP) Discord chat channel for support.** diff --git a/restapi.go b/restapi.go index 4bf1ba6..2eba734 100644 --- a/restapi.go +++ b/restapi.go @@ -38,7 +38,7 @@ var ( ErrPruneDaysBounds = errors.New("the number of days should be more than or equal to 1") ErrGuildNoIcon = errors.New("guild does not have an icon set") ErrGuildNoSplash = errors.New("guild does not have a splash set") - ErrUnauthorized = errors.New("HTTP request was unauthorized. This could be because the provided token was not a bot token. Please add \"Bot \" to the start of your token. https://discordapp.com/developers/docs/reference#authentication-example-bot-token-authorization-header") + ErrUnauthorized = errors.New("HTTP request was unauthorized. This could be because the provided token was not a bot token. Please add \"Bot \" to the start of your token. https://discord.com/developers/docs/reference#authentication-example-bot-token-authorization-header") ) // Request is the same as RequestWithBucketID but the bucket id is the same as the urlStr @@ -506,7 +506,7 @@ func (s *Session) UserChannelPermissions(userID, channelID string) (apermissions } // Calculates the permissions for a member. -// https://support.discordapp.com/hc/en-us/articles/206141927-How-is-the-permission-hierarchy-structured- +// https://support.discord.com/hc/en-us/articles/206141927-How-is-the-permission-hierarchy-structured- func memberPermissions(guild *Guild, channel *Channel, member *Member) (apermissions int) { userID := member.User.ID diff --git a/structs.go b/structs.go index 5ce8769..dd84fa7 100644 --- a/structs.go +++ b/structs.go @@ -42,7 +42,7 @@ type Session struct { ShouldReconnectOnError bool // Identify is sent during initial handshake with the discord gateway. - // https://discordapp.com/developers/docs/topics/gateway#identify + // https://discord.com/developers/docs/topics/gateway#identify Identify Identify // TODO: Remove Below, Deprecated, Use Identify struct @@ -919,7 +919,7 @@ type GatewayBotResponse struct { } // GatewayStatusUpdate is sent by the client to indicate a presence or status update -// https://discordapp.com/developers/docs/topics/gateway#update-status-gateway-status-update-structure +// https://discord.com/developers/docs/topics/gateway#update-status-gateway-status-update-structure type GatewayStatusUpdate struct { Since int `json:"since"` Game Activity `json:"game"` @@ -928,7 +928,7 @@ type GatewayStatusUpdate struct { } // Activity defines the Activity sent with GatewayStatusUpdate -// https://discordapp.com/developers/docs/topics/gateway#activity-object +// https://discord.com/developers/docs/topics/gateway#activity-object type Activity struct { Name string Type ActivityType @@ -936,11 +936,11 @@ type Activity struct { } // ActivityType is the type of Activity (see ActivityType* consts) in the Activity struct -// https://discordapp.com/developers/docs/topics/gateway#activity-object-activity-types +// https://discord.com/developers/docs/topics/gateway#activity-object-activity-types type ActivityType int // Valid ActivityType values -// https://discordapp.com/developers/docs/topics/gateway#activity-object-activity-types +// https://discord.com/developers/docs/topics/gateway#activity-object-activity-types const ( ActivityTypeGame GameType = iota ActivityTypeStreaming @@ -950,7 +950,7 @@ const ( ) // Identify is sent during initial handshake with the discord gateway. -// https://discordapp.com/developers/docs/topics/gateway#identify +// https://discord.com/developers/docs/topics/gateway#identify type Identify struct { Token string `json:"token"` Properties IdentifyProperties `json:"properties"` @@ -962,7 +962,7 @@ type Identify struct { } // IdentifyProperties contains the "properties" portion of an Identify packet -// https://discordapp.com/developers/docs/topics/gateway#identify-identify-connection-properties +// https://discord.com/developers/docs/topics/gateway#identify-identify-connection-properties type IdentifyProperties struct { OS string `json:"$os"` Browser string `json:"$browser"` diff --git a/wsapi.go b/wsapi.go index e3d5045..b00ad92 100644 --- a/wsapi.go +++ b/wsapi.go @@ -46,7 +46,7 @@ type resumePacket struct { } // Open creates a websocket connection to Discord. -// See: https://discordapp.com/developers/docs/topics/gateway#connecting +// See: https://discord.com/developers/docs/topics/gateway#connecting func (s *Session) Open() error { s.log(LogInformational, "called") From f5c33ab5c3783054a7d502acb0caee6f0bfee0b0 Mon Sep 17 00:00:00 2001 From: Carson Hoffman Date: Sat, 16 May 2020 11:26:48 -0400 Subject: [PATCH 42/52] Add ChunkIndex and ChunkCount fields to GuildMembersChunk --- events.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/events.go b/events.go index be394ae..99099c9 100644 --- a/events.go +++ b/events.go @@ -139,9 +139,11 @@ type GuildEmojisUpdate struct { // A GuildMembersChunk is the data for a GuildMembersChunk event. type GuildMembersChunk struct { - GuildID string `json:"guild_id"` - Members []*Member `json:"members"` - Presences []*Presence `json:"presences,omitempty"` + GuildID string `json:"guild_id"` + Members []*Member `json:"members"` + ChunkIndex int `json:"chunk_index"` + ChunkCount int `json:"chunk_count"` + Presences []*Presence `json:"presences,omitempty"` } // GuildIntegrationsUpdate is the data for a GuildIntegrationsUpdate event. From 57c962912e21b67f877ccb17615de61a4f511db9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Horonziak?= Date: Sun, 17 May 2020 19:52:52 +0200 Subject: [PATCH 43/52] Make intents optional field --- discord.go | 1 - structs.go | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/discord.go b/discord.go index 789ca68..74c7887 100644 --- a/discord.go +++ b/discord.go @@ -74,7 +74,6 @@ func New(args ...interface{}) (s *Session, err error) { s.Identify.GuildSubscriptions = true s.Identify.Properties.OS = runtime.GOOS s.Identify.Properties.Browser = "DiscordGo v" + VERSION - s.Identify.Intents = IntentsAllWithoutPrivileged // If no arguments are passed return the empty Session interface. if args == nil { diff --git a/structs.go b/structs.go index 3efc326..b706c18 100644 --- a/structs.go +++ b/structs.go @@ -959,7 +959,7 @@ type Identify struct { Shard *[2]int `json:"shard,omitempty"` Presence GatewayStatusUpdate `json:"presence,omitempty"` GuildSubscriptions bool `json:"guild_subscriptions"` - Intents int `json:"intents"` + Intents *Intent `json:"intents,omitempty"` } // IdentifyProperties contains the "properties" portion of an Identify packet @@ -1104,8 +1104,10 @@ const ( ErrCodeReactionBlocked = 90001 ) +type Intent int + const ( - IntentsGuilds = 1 << iota + IntentsGuilds Intent = 1 << iota IntentsGuildMembers IntentsGuildBans IntentsGuildEmojis @@ -1137,4 +1139,5 @@ const ( IntentsAll = IntentsAllWithoutPrivileged | IntentsGuildMembers | IntentsGuildPresences + IntentsNone Intent = 0 ) From a7305dd7b76f44d381d01bcf5ce1ff987e37e302 Mon Sep 17 00:00:00 2001 From: Carson Hoffman Date: Tue, 19 May 2020 23:06:59 -0400 Subject: [PATCH 44/52] Stop voice re-connection on manual disconnection --- voice.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/voice.go b/voice.go index 51ac16c..586b783 100644 --- a/voice.go +++ b/voice.go @@ -346,6 +346,25 @@ func (v *VoiceConnection) wsListen(wsConn *websocket.Conn, close <-chan struct{} for { _, message, err := v.wsConn.ReadMessage() if err != nil { + // 4014 indicates a manual disconnection by someone in the guild; + // we shouldn't reconnect. + if websocket.IsCloseError(err, 4014) { + v.log(LogInformational, "received 4014 manual disconnection") + + // Abandon the voice WS connection + v.Lock() + v.wsConn = nil + v.Unlock() + + v.session.Lock() + delete(v.session.VoiceConnections, v.GuildID) + v.session.Unlock() + + v.Close() + + return + } + // Detect if we have been closed manually. If a Close() has already // happened, the websocket we are listening on will be different to the // current session. From de7803becd8a2b4230f8e0bca74f8f6d14acbba9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Horonziak?= Date: Sun, 24 May 2020 08:34:29 +0200 Subject: [PATCH 45/52] Refactor --- discord.go | 1 + structs.go | 2 +- util.go | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/discord.go b/discord.go index 74c7887..1f5f5a0 100644 --- a/discord.go +++ b/discord.go @@ -74,6 +74,7 @@ func New(args ...interface{}) (s *Session, err error) { s.Identify.GuildSubscriptions = true s.Identify.Properties.OS = runtime.GOOS s.Identify.Properties.Browser = "DiscordGo v" + VERSION + s.Identify.Intents = MakeIntent(IntentsAllWithoutPrivileged) // If no arguments are passed return the empty Session interface. if args == nil { diff --git a/structs.go b/structs.go index b706c18..914bd4e 100644 --- a/structs.go +++ b/structs.go @@ -1139,5 +1139,5 @@ const ( IntentsAll = IntentsAllWithoutPrivileged | IntentsGuildMembers | IntentsGuildPresences - IntentsNone Intent = 0 + IntentsNone Intent = 0 ) diff --git a/util.go b/util.go index 02443ca..1dc3f47 100644 --- a/util.go +++ b/util.go @@ -15,3 +15,7 @@ func SnowflakeTimestamp(ID string) (t time.Time, err error) { t = time.Unix(timestamp/1000, 0) return } + +func MakeIntent(intents Intent) *Intent { + return &intents +} From 0e6ec53738e5708a55b48ca01e2d578c6d92c3f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Horonziak?= Date: Sun, 24 May 2020 09:44:33 +0200 Subject: [PATCH 46/52] Move MakeIntent method --- structs.go | 5 +++++ util.go | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/structs.go b/structs.go index 914bd4e..a6b572e 100644 --- a/structs.go +++ b/structs.go @@ -1141,3 +1141,8 @@ const ( IntentsGuildPresences IntentsNone Intent = 0 ) + +// MakeIntent helps convert a gateway intent value for use in the Identify structure. +func MakeIntent(intents Intent) *Intent { + return &intents +} diff --git a/util.go b/util.go index 1dc3f47..02443ca 100644 --- a/util.go +++ b/util.go @@ -15,7 +15,3 @@ func SnowflakeTimestamp(ID string) (t time.Time, err error) { t = time.Unix(timestamp/1000, 0) return } - -func MakeIntent(intents Intent) *Intent { - return &intents -} From 42fd45c4a3e3713404208bc3ffdeeed1956a2a8f Mon Sep 17 00:00:00 2001 From: RoJamieson Date: Mon, 8 Jun 2020 14:01:37 +0200 Subject: [PATCH 47/52] Changed "consistancy" to "consistency" in logging.go --- logging.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logging.go b/logging.go index 6460b35..41f0481 100644 --- a/logging.go +++ b/logging.go @@ -37,7 +37,7 @@ const ( // Logger can be used to replace the standard logging for discordgo var Logger func(msgL, caller int, format string, a ...interface{}) -// msglog provides package wide logging consistancy for discordgo +// msglog provides package wide logging consistency for discordgo // the format, a... portion this command follows that of fmt.Printf // msgL : LogLevel of the message // caller : 1 + the number of callers away from the message source From ee7a5ae519052b63b92c469670c816cbc295afb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Horonziak?= Date: Thu, 11 Jun 2020 12:26:34 +0200 Subject: [PATCH 48/52] Add missing comments --- structs.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/structs.go b/structs.go index a6b572e..750f18e 100644 --- a/structs.go +++ b/structs.go @@ -1104,8 +1104,11 @@ const ( ErrCodeReactionBlocked = 90001 ) +// Intent is the type of a Gateway Intent +// https://discord.com/developers/docs/topics/gateway#gateway-intents type Intent int +// Constants for the different bit offsets of intents const ( IntentsGuilds Intent = 1 << iota IntentsGuildMembers From a853557f4dd44b134b65e5e7defc8fa1bc35beab Mon Sep 17 00:00:00 2001 From: b-o-r-k <39185647+b-o-r-k@users.noreply.github.com> Date: Mon, 15 Jun 2020 18:14:01 +0000 Subject: [PATCH 49/52] Add missing fields in GuildChannelCreateData (#782) According to https://discord.com/developers/docs/resources/guild#create-guild-channel, the endpoint also accepts the following fields: - rate_limit_per_user: integer - position: integer --- restapi.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/restapi.go b/restapi.go index 2eba734..36af969 100644 --- a/restapi.go +++ b/restapi.go @@ -923,6 +923,8 @@ type GuildChannelCreateData struct { Topic string `json:"topic,omitempty"` Bitrate int `json:"bitrate,omitempty"` UserLimit int `json:"user_limit,omitempty"` + RateLimitPerUser int `json:"rate_limit_per_user,omitempty"` + Position int `json:"position,omitempty"` PermissionOverwrites []*PermissionOverwrite `json:"permission_overwrites,omitempty"` ParentID string `json:"parent_id,omitempty"` NSFW bool `json:"nsfw,omitempty"` From 9b1ba78bc6f4a2373bff6d371c60785ccdde6675 Mon Sep 17 00:00:00 2001 From: NANI Date: Wed, 17 Jun 2020 05:43:34 +0200 Subject: [PATCH 50/52] Adding millisecond precision to SnowflakeTimestamp utility (#732) * Millisecond precision * formatting * Update util.go * remove unnecessary int64 * Add unit test for SnowflakeTimestamp Co-authored-by: NANI Co-authored-by: Carson Hoffman --- util.go | 2 +- util_test.go | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 util_test.go diff --git a/util.go b/util.go index 02443ca..8a2b2e0 100644 --- a/util.go +++ b/util.go @@ -12,6 +12,6 @@ func SnowflakeTimestamp(ID string) (t time.Time, err error) { return } timestamp := (i >> 22) + 1420070400000 - t = time.Unix(timestamp/1000, 0) + t = time.Unix(0, timestamp*1000000) return } diff --git a/util_test.go b/util_test.go new file mode 100644 index 0000000..7ce32e5 --- /dev/null +++ b/util_test.go @@ -0,0 +1,21 @@ +package discordgo + +import ( + "testing" + "time" +) + +func TestSnowflakeTimestamp(t *testing.T) { + // #discordgo channel ID :) + id := "155361364909621248" + parsedTimestamp, err := SnowflakeTimestamp(id) + + if err != nil { + t.Errorf("returned error incorrect: got %v, want nil", err) + } + + correctTimestamp := time.Date(2016, time.March, 4, 17, 10, 35, 869*1000000, time.UTC) + if !parsedTimestamp.Equal(correctTimestamp) { + t.Errorf("parsed time incorrect: got %v, want %v", parsedTimestamp, correctTimestamp) + } +} From 103055d2bed005fae5f6e2c73213b1ee1124e324 Mon Sep 17 00:00:00 2001 From: Carson Hoffman Date: Sat, 20 Jun 2020 19:55:19 -0400 Subject: [PATCH 51/52] Add presences field to RequestGuildMembers --- wsapi.go | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/wsapi.go b/wsapi.go index b00ad92..1cf1598 100644 --- a/wsapi.go +++ b/wsapi.go @@ -398,9 +398,10 @@ func (s *Session) UpdateStatusComplex(usd UpdateStatusData) (err error) { } type requestGuildMembersData struct { - GuildIDs []string `json:"guild_id"` - Query string `json:"query"` - Limit int `json:"limit"` + GuildIDs []string `json:"guild_id"` + Query string `json:"query"` + Limit int `json:"limit"` + Presences bool `json:"presences"` } type requestGuildMembersOp struct { @@ -410,14 +411,16 @@ type requestGuildMembersOp struct { // RequestGuildMembers requests guild members from the gateway // The gateway responds with GuildMembersChunk events -// guildID : Single Guild ID to request members of -// query : String that username starts with, leave empty to return all members -// limit : Max number of items to return, or 0 to request all members matched -func (s *Session) RequestGuildMembers(guildID string, query string, limit int) (err error) { +// guildID : Single Guild ID to request members of +// query : String that username starts with, leave empty to return all members +// limit : Max number of items to return, or 0 to request all members matched +// presences : Whether to request presences of guild members +func (s *Session) RequestGuildMembers(guildID string, query string, limit int, presences bool) (err error) { data := requestGuildMembersData{ - GuildIDs: []string{guildID}, - Query: query, - Limit: limit, + GuildIDs: []string{guildID}, + Query: query, + Limit: limit, + Presences: presences, } err = s.requestGuildMembers(data) return @@ -425,14 +428,16 @@ func (s *Session) RequestGuildMembers(guildID string, query string, limit int) ( // RequestGuildMembersBatch requests guild members from the gateway // The gateway responds with GuildMembersChunk events -// guildID : Slice of guild IDs to request members of -// query : String that username starts with, leave empty to return all members -// limit : Max number of items to return, or 0 to request all members matched -func (s *Session) RequestGuildMembersBatch(guildIDs []string, query string, limit int) (err error) { +// guildID : Slice of guild IDs to request members of +// query : String that username starts with, leave empty to return all members +// limit : Max number of items to return, or 0 to request all members matched +// presences : Whether to request presences of guild members +func (s *Session) RequestGuildMembersBatch(guildIDs []string, query string, limit int, presences bool) (err error) { data := requestGuildMembersData{ - GuildIDs: guildIDs, - Query: query, - Limit: limit, + GuildIDs: guildIDs, + Query: query, + Limit: limit, + Presences: presences, } err = s.requestGuildMembers(data) return From 096fd806a7858d5a7456fc38a1eb184dd65c23dd Mon Sep 17 00:00:00 2001 From: Carson Hoffman Date: Sat, 20 Jun 2020 20:32:32 -0400 Subject: [PATCH 52/52] Track presences from GuildMembersChunk --- state.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/state.go b/state.go index 55619ef..80bd8df 100644 --- a/state.go +++ b/state.go @@ -848,6 +848,12 @@ func (s *State) OnInterface(se *Session, i interface{}) (err error) { err = s.MemberAdd(t.Members[i]) } } + + if s.TrackPresences { + for _, p := range t.Presences { + err = s.PresenceAdd(t.GuildID, p) + } + } case *GuildRoleCreate: if s.TrackRoles { err = s.RoleAdd(t.GuildID, t.Role)