Version: v2.1.0 Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Jun 8, 2021 License: ISC Imports: 19 Imported by: 40



Package gateway handles the Discord gateway (or Websocket) connection, its events, and everything related to it. This includes logging into the Websocket.

This package does not abstract events and function handlers; instead, it leaves that to the session package. This package exposes only a single Events channel.



This section is empty.


View Source
var (
	EndpointGateway    = api.Endpoint + "gateway"
	EndpointGatewayBot = api.EndpointGateway + "/bot"

	Version  = api.Version
	Encoding = "json"
View Source
var (
	ErrMissingForResume = errors.New("missing session ID or sequence for resuming")
	ErrWSMaxTries       = errors.New(
		"could not connect to the Discord gateway before reaching the timeout")
	ErrClosed = errors.New("the gateway is closed and cannot reconnect")
View Source
var DefaultIdentity = IdentifyProperties{
	OS:      runtime.GOOS,
	Browser: "Arikawa",
	Device:  "Arikawa",

DefaultIdentity is used as the default identity when initializing a new Gateway.

View Source
var DefaultShard = &Shard{0, 1}

DefaultShard returns the default shard configuration of 1 shard total, in which the current shard ID is 0.

View Source
var ErrReconnectRequest = errors.New("ReconnectOP received")

ErrReconnectRequest is returned by HandleOP if a ReconnectOP is given. This is used mostly internally to signal the heartbeat loop to reconnect, if needed. It is not a fatal error.

View Source
var EventCreator = map[string]func() Event{
	"HELLO":              func() Event { return new(HelloEvent) },
	"READY":              func() Event { return new(ReadyEvent) },
	"READY_SUPPLEMENTAL": func() Event { return new(ReadySupplementalEvent) },
	"RESUMED":            func() Event { return new(ResumedEvent) },
	"INVALID_SESSION":    func() Event { return new(InvalidSessionEvent) },

	"CHANNEL_CREATE":        func() Event { return new(ChannelCreateEvent) },
	"CHANNEL_UPDATE":        func() Event { return new(ChannelUpdateEvent) },
	"CHANNEL_DELETE":        func() Event { return new(ChannelDeleteEvent) },
	"CHANNEL_PINS_UPDATE":   func() Event { return new(ChannelPinsUpdateEvent) },
	"CHANNEL_UNREAD_UPDATE": func() Event { return new(ChannelUnreadUpdateEvent) },

	"GUILD_CREATE": func() Event { return new(GuildCreateEvent) },
	"GUILD_UPDATE": func() Event { return new(GuildUpdateEvent) },
	"GUILD_DELETE": func() Event { return new(GuildDeleteEvent) },

	"GUILD_BAN_ADD":    func() Event { return new(GuildBanAddEvent) },
	"GUILD_BAN_REMOVE": func() Event { return new(GuildBanRemoveEvent) },

	"GUILD_EMOJIS_UPDATE":       func() Event { return new(GuildEmojisUpdateEvent) },
	"GUILD_INTEGRATIONS_UPDATE": func() Event { return new(GuildIntegrationsUpdateEvent) },

	"GUILD_MEMBER_ADD":    func() Event { return new(GuildMemberAddEvent) },
	"GUILD_MEMBER_REMOVE": func() Event { return new(GuildMemberRemoveEvent) },
	"GUILD_MEMBER_UPDATE": func() Event { return new(GuildMemberUpdateEvent) },
	"GUILD_MEMBERS_CHUNK": func() Event { return new(GuildMembersChunkEvent) },

	"GUILD_MEMBER_LIST_UPDATE": func() Event { return new(GuildMemberListUpdate) },

	"GUILD_ROLE_CREATE": func() Event { return new(GuildRoleCreateEvent) },
	"GUILD_ROLE_UPDATE": func() Event { return new(GuildRoleUpdateEvent) },
	"GUILD_ROLE_DELETE": func() Event { return new(GuildRoleDeleteEvent) },

	"INVITE_CREATE": func() Event { return new(InviteCreateEvent) },
	"INVITE_DELETE": func() Event { return new(InviteDeleteEvent) },

	"MESSAGE_CREATE":      func() Event { return new(MessageCreateEvent) },
	"MESSAGE_UPDATE":      func() Event { return new(MessageUpdateEvent) },
	"MESSAGE_DELETE":      func() Event { return new(MessageDeleteEvent) },
	"MESSAGE_DELETE_BULK": func() Event { return new(MessageDeleteBulkEvent) },

	"MESSAGE_REACTION_ADD":          func() Event { return new(MessageReactionAddEvent) },
	"MESSAGE_REACTION_REMOVE":       func() Event { return new(MessageReactionRemoveEvent) },
	"MESSAGE_REACTION_REMOVE_ALL":   func() Event { return new(MessageReactionRemoveAllEvent) },
	"MESSAGE_REACTION_REMOVE_EMOJI": func() Event { return new(MessageReactionRemoveEmojiEvent) },

	"MESSAGE_ACK": func() Event { return new(MessageAckEvent) },

	"PRESENCE_UPDATE":   func() Event { return new(PresenceUpdateEvent) },
	"PRESENCES_REPLACE": func() Event { return new(PresencesReplaceEvent) },
	"SESSIONS_REPLACE":  func() Event { return new(SessionsReplaceEvent) },

	"TYPING_START": func() Event { return new(TypingStartEvent) },

	"VOICE_STATE_UPDATE":  func() Event { return new(VoiceStateUpdateEvent) },
	"VOICE_SERVER_UPDATE": func() Event { return new(VoiceServerUpdateEvent) },

	"WEBHOOKS_UPDATE": func() Event { return new(WebhooksUpdateEvent) },

	"INTERACTION_CREATE": func() Event { return new(InteractionCreateEvent) },

	"USER_UPDATE":                func() Event { return new(UserUpdateEvent) },
	"USER_SETTINGS_UPDATE":       func() Event { return new(UserSettingsUpdateEvent) },
	"USER_GUILD_SETTINGS_UPDATE": func() Event { return new(UserGuildSettingsUpdateEvent) },
	"USER_NOTE_UPDATE":           func() Event { return new(UserNoteUpdateEvent) },

	"RELATIONSHIP_ADD":    func() Event { return new(RelationshipAddEvent) },
	"RELATIONSHIP_REMOVE": func() Event { return new(RelationshipRemoveEvent) },

	"APPLICATION_COMMAND_UPDATE": func() Event { return new(ApplicationCommandUpdateEvent) },

EventCreator maps an event type string to a constructor.

View Source
var EventIntents = map[string]Intents{
	"GUILD_CREATE":        IntentGuilds,
	"GUILD_UPDATE":        IntentGuilds,
	"GUILD_DELETE":        IntentGuilds,
	"GUILD_ROLE_CREATE":   IntentGuilds,
	"GUILD_ROLE_UPDATE":   IntentGuilds,
	"GUILD_ROLE_DELETE":   IntentGuilds,
	"CHANNEL_CREATE":      IntentGuilds,
	"CHANNEL_UPDATE":      IntentGuilds,
	"CHANNEL_DELETE":      IntentGuilds,
	"CHANNEL_PINS_UPDATE": IntentGuilds | IntentDirectMessages,

	"GUILD_MEMBER_ADD":    IntentGuildMembers,
	"GUILD_MEMBER_REMOVE": IntentGuildMembers,
	"GUILD_MEMBER_UPDATE": IntentGuildMembers,

	"GUILD_BAN_ADD":    IntentGuildBans,
	"GUILD_BAN_REMOVE": IntentGuildBans,

	"GUILD_EMOJIS_UPDATE": IntentGuildEmojis,

	"GUILD_INTEGRATIONS_UPDATE": IntentGuildIntegrations,

	"WEBHOOKS_UPDATE": IntentGuildWebhooks,

	"INVITE_CREATE": IntentGuildInvites,
	"INVITE_DELETE": IntentGuildInvites,

	"VOICE_STATE_UPDATE": IntentGuildVoiceStates,

	"PRESENCE_UPDATE": IntentGuildPresences,

	"MESSAGE_CREATE":      IntentGuildMessages | IntentDirectMessages,
	"MESSAGE_UPDATE":      IntentGuildMessages | IntentDirectMessages,
	"MESSAGE_DELETE":      IntentGuildMessages | IntentDirectMessages,
	"MESSAGE_DELETE_BULK": IntentGuildMessages,

	"MESSAGE_REACTION_ADD":          IntentGuildMessageReactions | IntentDirectMessageReactions,
	"MESSAGE_REACTION_REMOVE":       IntentGuildMessageReactions | IntentDirectMessageReactions,
	"MESSAGE_REACTION_REMOVE_ALL":   IntentGuildMessageReactions | IntentDirectMessageReactions,
	"MESSAGE_REACTION_REMOVE_EMOJI": IntentGuildMessageReactions | IntentDirectMessageReactions,

	"TYPING_START": IntentGuildMessageTyping | IntentDirectMessageTyping,

EventIntents maps event types to intents.

PrivilegedIntents contains a list of privileged intents that Discord requires bots to have these intents explicitly enabled in the Developer Portal.


func ConvertSupplementalMember

func ConvertSupplementalMember(sm SupplementalMember) discord.Member

ConvertSupplementalMember converts a SupplementalMember to a regular Member.

func URL

func URL() (string, error)

URL asks Discord for a Websocket URL to the Gateway.


type ApplicationCommandUpdateEvent added in v2.0.2

type ApplicationCommandUpdateEvent struct {
	GuildID discord.GuildID `json:"guild_id"`

type BotData

type BotData struct {
	URL        string             `json:"url"`
	Shards     int                `json:"shards,omitempty"`
	StartLimit *SessionStartLimit `json:"session_start_limit"`

BotData contains the GatewayURL as well as extra metadata on how to shard bots.

func BotURL

func BotURL(token string) (*BotData, error)

BotURL fetches the Gateway URL along with extra metadata. The token passed in will NOT be prefixed with Bot.

type ChannelPinsUpdateEvent

type ChannelPinsUpdateEvent struct {
	GuildID   discord.GuildID   `json:"guild_id,omitempty"`
	ChannelID discord.ChannelID `json:"channel_id,omitempty"`
	LastPin   discord.Timestamp `json:"timestamp,omitempty"`

type ChannelUnreadUpdateEvent

type ChannelUnreadUpdateEvent struct {
	GuildID discord.GuildID `json:"guild_id"`

	ChannelUnreadUpdates []struct {
		ID            discord.ChannelID `json:"id"`
		LastMessageID discord.MessageID `json:"last_message_id"`

type ClientStatus

type ClientStatus struct {
	// Desktop is the user's status set for an active desktop (Windows,
	// Linux, Mac) application session.
	Desktop Status `json:"desktop,omitempty"`
	// Mobile is the user's status set for an active mobile (iOS, Android)
	// application session.
	Mobile Status `json:"mobile,omitempty"`
	// Web is the user's status set for an active web (browser, bot
	// account) application session.
	Web Status `json:"web,omitempty"`

ClientStatus is the user's platform-dependent status.

type CustomUserStatus

type CustomUserStatus struct {
	Text      string            `json:"text"`
	ExpiresAt discord.Timestamp `json:"expires_at,omitempty"`
	EmojiID   discord.EmojiID   `json:"emoji_id,string"`
	EmojiName string            `json:"emoji_name"`

CustomUserStatus is the custom user status that allows setting an emoji and a piece of text on each user.

type Event

type Event = interface{}

Event is any event struct. They have an "Event" suffixed to them.

type FriendSourceFlags

type FriendSourceFlags struct {
	All           bool `json:"all,omitempty"`
	MutualGuilds  bool `json:"mutual_guilds,omitempty"`
	MutualFriends bool `json:"mutual_friends,omitempty"`

FriendSourceFlags describes sources that friend requests could be sent from. It belongs to the UserSettings struct and is undocumented.

type Gateway

type Gateway struct {
	WS *wsutil.Websocket

	// WSTimeout is a timeout for an arbitrary action. An example of this is the
	// timeout for Start and the timeout for sending each Gateway command
	// independently.
	WSTimeout time.Duration

	// ReconnectTimeout is the timeout used during reconnection.
	// If the a connection to the gateway can't be established before the
	// duration passes, the Gateway will be closed and FatalErrorCallback will
	// be called.
	// Setting this to 0 is equivalent to no timeout.
	// Deprecated: It is recommended to use ReconnectAttempts instead.
	ReconnectTimeout time.Duration
	// ReconnectAttempts are the amount of attempts made to Reconnect, before
	// aborting. If this set to 0, unlimited attempts will be made.
	ReconnectAttempts uint

	// All events sent over are pointers to Event structs (structs suffixed with
	// "Event"). This shouldn't be accessed if the Gateway is created with a
	// Session.
	Events chan Event

	Identifier *Identifier
	Sequence   *moreatomic.Int64

	PacerLoop wsutil.PacemakerLoop

	ErrorLog func(err error) // default to log.Println
	// FatalErrorCallback is called, if the Gateway exits fatally. At the point
	// of calling, the gateway will be already closed.
	// Currently this will only be called, if the ReconnectTimeout was changed
	// to a definite timeout, and connection could not be established during
	// that time.
	// err will be ErrWSMaxTries in that case.
	// Defaults to noop.
	FatalErrorCallback func(err error)

	// OnScalingRequired is the function called, if Discord closes with error
	// code 4011 aka Scaling Required. At the point of calling, the Gateway
	// will be closed, and can, after increasing the number of shards, be
	// reopened using Open. Reconnect or ReconnectCtx, however, will not be
	// available as the session is invalidated.
	OnScalingRequired func()

	// AfterClose is called after each close or pause. It is used mainly for
	// reconnections or any type of connection interruptions.
	// Constructors will use a no-op function by default.
	AfterClose func(err error)
	// contains filtered or unexported fields

func NewCustomGateway

func NewCustomGateway(gatewayURL, token string) *Gateway

NewCustomGateway creates a new Gateway with a custom gateway URL and a new Identifier. Most bots connecting to the official server should not use these custom functions.

func NewCustomIdentifiedGateway added in v2.0.6

func NewCustomIdentifiedGateway(gatewayURL string, id *Identifier) *Gateway

NewCustomIdentifiedGateway creates a new Gateway with a custom gateway URL and a pre-existing Identifier. Refer to NewCustomGateway.

func NewGateway

func NewGateway(token string) (*Gateway, error)

NewGateway creates a new Gateway to the default Discord server.

func NewGatewayWithIntents

func NewGatewayWithIntents(token string, intents ...Intents) (*Gateway, error)

NewGatewayWithIntents creates a new Gateway with the given intents and the default stdlib JSON driver. Refer to NewGatewayWithDriver and AddIntents.

func NewIdentifiedGateway added in v2.0.6

func NewIdentifiedGateway(id *Identifier) (*Gateway, error)

NewIdentifiedGateway creates a new Gateway with the given gateway identifier and the default everything. Sharded bots should prefer this function for the shared identifier.

func (*Gateway) AddIntents

func (g *Gateway) AddIntents(i Intents)

AddIntents adds a Gateway Intent before connecting to the Gateway. As such, this function will only work before Open() is called.

func (*Gateway) Close

func (g *Gateway) Close() error

Close closes the underlying Websocket connection, invalidating the session ID. A new gateway connection can be established, by calling Open again.

If the wsutil.Connection of the Gateway's WS implements wsutil.GracefulCloser, such as the default one, Close will send a closing frame before ending the connection, closing it gracefully. This will cause the bot to appear as offline instantly.

func (*Gateway) CloseGracefully deprecated added in v2.0.2

func (g *Gateway) CloseGracefully() error

CloseGracefully attempts to close the gateway connection gracefully, by sending a closing frame before ending the connection. This will cause the gateway's session id to be rendered invalid.

Note that a graceful closure is only possible, if the wsutil.Connection of the Gateway's Websocket implements wsutil.GracefulCloser.

Deprecated: Close behaves identically to CloseGracefully, and should be used instead.

func (*Gateway) GuildSubscribe

func (g *Gateway) GuildSubscribe(data GuildSubscribeData) error

func (*Gateway) GuildSubscribeCtx

func (g *Gateway) GuildSubscribeCtx(ctx context.Context, data GuildSubscribeData) error

func (*Gateway) HandleOP

func (g *Gateway) HandleOP(op *wsutil.OP) error

func (*Gateway) HasIntents

func (g *Gateway) HasIntents(intents Intents) bool

HasIntents reports if the Gateway has the passed Intents.

If no intents are set, i.e. if using a user account HasIntents will always return true.

func (*Gateway) Heartbeat

func (g *Gateway) Heartbeat() error

func (*Gateway) HeartbeatCtx

func (g *Gateway) HeartbeatCtx(ctx context.Context) error

func (*Gateway) Identify

func (g *Gateway) Identify() error

Identify sends off the Identify command with the Gateway's IdentifyData.

func (*Gateway) IdentifyCtx

func (g *Gateway) IdentifyCtx(ctx context.Context) error

IdentifyCtx sends off the Identify command with the Gateway's IdentifyData with the given context for time out.

func (*Gateway) Open

func (g *Gateway) Open() error

Open connects to the Websocket and authenticate it. You should usually use this function over Start().

func (*Gateway) OpenContext

func (g *Gateway) OpenContext(ctx context.Context) error

OpenContext connects to the Websocket and authenticates it. You should usually use this function over Start(). The given context provides cancellation and timeout.

func (*Gateway) Pause added in v2.1.0

func (g *Gateway) Pause() error

Pause pauses the Gateway connection, by ending the connection without sending a closing frame. This allows the connection to be resumed at a later point, by calling Reconnect or ReconnectCtx.

func (*Gateway) Reconnect

func (g *Gateway) Reconnect()

Reconnect tries to reconnect to the Gateway until the ReconnectAttempts or ReconnectTimeout is reached.

func (*Gateway) ReconnectCtx

func (g *Gateway) ReconnectCtx(ctx context.Context) (err error)

ReconnectCtx attempts to Reconnect until context expires. If the context expires FatalErrorCallback will be called with ErrWSMaxTries, and the last error returned by Open will be returned.

func (*Gateway) RequestGuildMembers

func (g *Gateway) RequestGuildMembers(data RequestGuildMembersData) error

func (*Gateway) RequestGuildMembersCtx

func (g *Gateway) RequestGuildMembersCtx(
	ctx context.Context, data RequestGuildMembersData) error

func (*Gateway) Resume

func (g *Gateway) Resume() error

Resume sends to the Websocket a Resume OP, but it doesn't actually resume from a dead connection. Start() resumes from a dead connection.

func (*Gateway) ResumeCtx

func (g *Gateway) ResumeCtx(ctx context.Context) error

ResumeCtx sends to the Websocket a Resume OP, but it doesn't actually resume from a dead connection. Start() resumes from a dead connection.

func (*Gateway) SendCtx

func (g *Gateway) SendCtx(ctx context.Context, code OPCode, v interface{}) error

SendCtx is a low-level function to send an OP payload to the Gateway. Most users shouldn't touch this, unless they know what they're doing.

func (*Gateway) SessionID

func (g *Gateway) SessionID() string

SessionID returns the session ID received after Ready. This function is concurrently safe.

func (*Gateway) Start

func (g *Gateway) Start() error

Start calls StartCtx with a background context. You wouldn't usually use this function, but Open() instead.

func (*Gateway) StartCtx

func (g *Gateway) StartCtx(ctx context.Context) error

StartCtx authenticates with the websocket, or resume from a dead Websocket connection. You wouldn't usually use this function, but OpenCtx() instead.

func (*Gateway) UpdateStatus

func (g *Gateway) UpdateStatus(data UpdateStatusData) error

func (*Gateway) UpdateStatusCtx

func (g *Gateway) UpdateStatusCtx(ctx context.Context, data UpdateStatusData) error

func (*Gateway) UpdateVoiceState

func (g *Gateway) UpdateVoiceState(data UpdateVoiceStateData) error

func (*Gateway) UpdateVoiceStateCtx

func (g *Gateway) UpdateVoiceStateCtx(ctx context.Context, data UpdateVoiceStateData) error

type GuildBanAddEvent

type GuildBanAddEvent struct {
	GuildID discord.GuildID `json:"guild_id"`
	User    discord.User    `json:"user"`

type GuildBanRemoveEvent

type GuildBanRemoveEvent struct {
	GuildID discord.GuildID `json:"guild_id"`
	User    discord.User    `json:"user"`

type GuildCreateEvent

type GuildCreateEvent struct {

	Joined      discord.Timestamp `json:"joined_at,omitempty"`
	Large       bool              `json:"large,omitempty"`
	Unavailable bool              `json:"unavailable,omitempty"`
	MemberCount uint64            `json:"member_count,omitempty"`

	VoiceStates []discord.VoiceState `json:"voice_states,omitempty"`
	Members     []discord.Member     `json:"members,omitempty"`
	Channels    []discord.Channel    `json:"channels,omitempty"`
	Presences   []Presence           `json:"presences,omitempty"`

type GuildDeleteEvent

type GuildDeleteEvent struct {
	ID discord.GuildID `json:"id"`
	// Unavailable if false == removed
	Unavailable bool `json:"unavailable"`

type GuildEmojisUpdateEvent

type GuildEmojisUpdateEvent struct {
	GuildID discord.GuildID `json:"guild_id"`
	Emojis  []discord.Emoji `json:"emoji"`

type GuildFolder

type GuildFolder struct {
	Name     string            `json:"name"`
	ID       GuildFolderID     `json:"id"`
	GuildIDs []discord.GuildID `json:"guild_ids"`
	Color    discord.Color     `json:"color"`

GuildFolder holds a single folder that you see in the left guild panel.

type GuildFolderID

type GuildFolderID int64

GuildFolderID is possibly a snowflake. It can also be 0 (null) or a low number of unknown significance.

func (GuildFolderID) MarshalJSON

func (g GuildFolderID) MarshalJSON() ([]byte, error)

func (*GuildFolderID) UnmarshalJSON

func (g *GuildFolderID) UnmarshalJSON(b []byte) error

type GuildIntegrationsUpdateEvent

type GuildIntegrationsUpdateEvent struct {
	GuildID discord.GuildID `json:"guild_id"`

type GuildMemberAddEvent

type GuildMemberAddEvent struct {
	GuildID discord.GuildID `json:"guild_id"`

type GuildMemberListGroup

type GuildMemberListGroup struct {
	ID    string `json:"id"` // either discord.RoleID, "online" or "offline"
	Count uint64 `json:"count"`

type GuildMemberListOp

type GuildMemberListOp struct {
	// Mysterious string, so far spotted to be [SYNC, INSERT, UPDATE, DELETE].
	Op string `json:"op"`

	// Only available for Ops that aren't "SYNC".
	Index int                   `json:"index,omitempty"`
	Item  GuildMemberListOpItem `json:"item,omitempty"`

	// Range requested in GuildSubscribeData.
	Range [2]int `json:"range,omitempty"`
	// Items is basically a linear list of roles and members, similarly to
	// how the client renders it. No, it's not nested.
	Items []GuildMemberListOpItem `json:"items,omitempty"`

type GuildMemberListOpItem

type GuildMemberListOpItem struct {
	Group  *GuildMemberListGroup `json:"group,omitempty"`
	Member *struct {
		HoistedRole string   `json:"hoisted_role"`
		Presence    Presence `json:"presence"`
	} `json:"member,omitempty"`

GuildMemberListOpItem is an enum. Either of the fields are provided, but never both. Refer to (*GuildMemberListUpdate).Ops for more.

type GuildMemberListUpdate

type GuildMemberListUpdate struct {
	ID          string          `json:"id"`
	GuildID     discord.GuildID `json:"guild_id"`
	MemberCount uint64          `json:"member_count"`
	OnlineCount uint64          `json:"online_count"`

	// Groups is all the visible role sections.
	Groups []GuildMemberListGroup `json:"groups"`

	Ops []GuildMemberListOp `json:"ops"`

GuildMemberListUpdate is an undocumented event. It's received when the client sends over GuildSubscriptions with the Channels field used. The State package does not handle this event.

type GuildMemberRemoveEvent

type GuildMemberRemoveEvent struct {
	GuildID discord.GuildID `json:"guild_id"`
	User    discord.User    `json:"user"`

type GuildMemberUpdateEvent

type GuildMemberUpdateEvent struct {
	GuildID discord.GuildID  `json:"guild_id"`
	RoleIDs []discord.RoleID `json:"roles"`
	User    discord.User     `json:"user"`
	Nick    string           `json:"nick"`

func (GuildMemberUpdateEvent) Update

func (u GuildMemberUpdateEvent) Update(m *discord.Member)

type GuildMembersChunkEvent

type GuildMembersChunkEvent struct {
	GuildID discord.GuildID  `json:"guild_id"`
	Members []discord.Member `json:"members"`

	ChunkIndex int `json:"chunk_index"`
	ChunkCount int `json:"chunk_count"`

	// Whatever's not found goes here
	NotFound []string `json:"not_found,omitempty"`

	// Only filled if requested
	Presences []Presence `json:"presences,omitempty"`
	Nonce     string     `json:"nonce,omitempty"`

GuildMembersChunkEvent is sent when Guild Request Members is called.

type GuildRoleCreateEvent

type GuildRoleCreateEvent struct {
	GuildID discord.GuildID `json:"guild_id"`
	Role    discord.Role    `json:"role"`

type GuildRoleDeleteEvent

type GuildRoleDeleteEvent struct {
	GuildID discord.GuildID `json:"guild_id"`
	RoleID  discord.RoleID  `json:"role_id"`

type GuildRoleUpdateEvent

type GuildRoleUpdateEvent struct {
	GuildID discord.GuildID `json:"guild_id"`
	Role    discord.Role    `json:"role"`

type GuildSubscribeData

type GuildSubscribeData struct {
	Typing     bool            `json:"typing"`
	Threads    bool            `json:"threads"`
	Activities bool            `json:"activities"`
	GuildID    discord.GuildID `json:"guild_id"`

	// Channels is not documented. It's used to fetch the right members sidebar.
	Channels map[discord.ChannelID][][2]int `json:"channels,omitempty"`


type HeartbeatData

type HeartbeatData int

HeartbeatData is the last sequence number to be sent.

type HelloEvent

type HelloEvent struct {
	HeartbeatInterval discord.Milliseconds `json:"heartbeat_interval"`

type Identifier

type Identifier struct {

	IdentifyShortLimit  *rate.Limiter `json:"-"` // optional
	IdentifyGlobalLimit *rate.Limiter `json:"-"` // optional

Identifier is a wrapper around IdentifyData to add in appropriate rate limiters.

func DefaultIdentifier

func DefaultIdentifier(token string) *Identifier

DefaultIdentifier creates a new default Identifier

func NewIdentifier

func NewIdentifier(data IdentifyData) *Identifier

NewIdentifier creates a new identifier with the given IdentifyData and default rate limiters.

func (*Identifier) Wait

func (i *Identifier) Wait(ctx context.Context) error

Wait waits for the rate limiters to pass. If a limiter is nil, then it will not be used to wait. This is useful

type IdentifyData

type IdentifyData struct {
	Token      string             `json:"token"`
	Properties IdentifyProperties `json:"properties"`

	Compress       bool `json:"compress,omitempty"`        // true
	LargeThreshold uint `json:"large_threshold,omitempty"` // 50

	Shard *Shard `json:"shard,omitempty"` // [ shard_id, num_shards ]

	Presence *UpdateStatusData `json:"presence,omitempty"`

	Intents Intents `json:"intents,omitempty"`

IdentifyData is the struct for a data that's sent over in an Identify command.

func DefaultIdentifyData

func DefaultIdentifyData(token string) IdentifyData

DefaultIdentifyData creates a default IdentifyData with the given token.

func (*IdentifyData) SetShard

func (i *IdentifyData) SetShard(id, num int)

SetShard is a helper function to set the shard configuration inside IdentifyData.

type IdentifyProperties

type IdentifyProperties struct {
	// Required
	OS      string `json:"os"`      // GOOS
	Browser string `json:"browser"` // Arikawa
	Device  string `json:"device"`  // Arikawa

	// Optional
	BrowserUserAgent string `json:"browser_user_agent,omitempty"`
	BrowserVersion   string `json:"browser_version,omitempty"`
	OSVersion        string `json:"os_version,omitempty"`
	Referrer         string `json:"referrer,omitempty"`
	ReferringDomain  string `json:"referring_domain,omitempty"`

type Intents

type Intents uint32

Intents for the new Discord API feature, documented at

const (
	IntentGuilds Intents = 1 << iota

func (Intents) Has

func (i Intents) Has(intents Intents) bool

Has returns true if i has the given intents.

func (Intents) IsPrivileged

func (i Intents) IsPrivileged() (presences, member bool)

IsPrivileged returns true for each of the boolean that indicates the type of the privilege.

type InteractionCreateEvent added in v2.0.2

type InteractionCreateEvent struct {
	ID        discord.InteractionID `json:"id"`
	Type      InteractionType       `json:"type"`
	Data      InteractionData       `json:"data"`
	GuildID   discord.GuildID       `json:"guild_id"`
	ChannelID discord.ChannelID     `json:"channel_id"`
	Member    discord.Member        `json:"member"`
	Token     string                `json:"token"`
	Version   int                   `json:"version"`

type InteractionData added in v2.0.2

type InteractionData struct {
	ID      discord.CommandID   `json:"id"`
	Name    string              `json:"name"`
	Options []InteractionOption `json:"options"`

type InteractionOption added in v2.0.2

type InteractionOption struct {
	Name    string              `json:"name"`
	Value   string              `json:"value"`
	Options []InteractionOption `json:"options"`

type InteractionType added in v2.0.2

type InteractionType uint
const (
	PingInteraction InteractionType = iota + 1

type InvalidSessionEvent

type InvalidSessionEvent bool

InvalidSessionEvent indicates if the event is resumable.

type InviteCreateEvent

type InviteCreateEvent struct {
	Code      string            `json:"code"`
	CreatedAt discord.Timestamp `json:"created_at"`
	ChannelID discord.ChannelID `json:"channel_id"`
	GuildID   discord.GuildID   `json:"guild_id,omitempty"`

	// Similar to discord.Invite
	Inviter    *discord.User          `json:"inviter,omitempty"`
	Target     *discord.User          `json:"target_user,omitempty"`
	TargetType discord.InviteUserType `json:"target_user_type,omitempty"`


type InviteDeleteEvent

type InviteDeleteEvent struct {
	Code      string            `json:"code"`
	ChannelID discord.ChannelID `json:"channel_id"`
	GuildID   discord.GuildID   `json:"guild_id,omitempty"`

type MergedPresences

type MergedPresences struct {
	Guilds  [][]SupplementalPresence `json:"guilds"`
	Friends []SupplementalPresence   `json:"friends"`

MergedPresences is the struct for presences of guilds' members and friends. It is undocumented.

type MessageAckEvent

type MessageAckEvent struct {
	MessageID discord.MessageID `json:"message_id"`
	ChannelID discord.ChannelID `json:"channel_id"`

type MessageCreateEvent

type MessageCreateEvent struct {
	Member *discord.Member `json:"member,omitempty"`

type MessageDeleteBulkEvent

type MessageDeleteBulkEvent struct {
	IDs       []discord.MessageID `json:"ids"`
	ChannelID discord.ChannelID   `json:"channel_id"`
	GuildID   discord.GuildID     `json:"guild_id,omitempty"`

type MessageDeleteEvent

type MessageDeleteEvent struct {
	ID        discord.MessageID `json:"id"`
	ChannelID discord.ChannelID `json:"channel_id"`
	GuildID   discord.GuildID   `json:"guild_id,omitempty"`

type MessageReactionAddEvent

type MessageReactionAddEvent struct {
	UserID    discord.UserID    `json:"user_id"`
	ChannelID discord.ChannelID `json:"channel_id"`
	MessageID discord.MessageID `json:"message_id"`

	Emoji discord.Emoji `json:"emoji,omitempty"`

	GuildID discord.GuildID `json:"guild_id,omitempty"`
	Member  *discord.Member `json:"member,omitempty"`

type MessageReactionRemoveAllEvent

type MessageReactionRemoveAllEvent struct {
	ChannelID discord.ChannelID `json:"channel_id"`
	MessageID discord.MessageID `json:"message_id"`
	GuildID   discord.GuildID   `json:"guild_id,omitempty"`

type MessageReactionRemoveEmojiEvent

type MessageReactionRemoveEmojiEvent struct {
	ChannelID discord.ChannelID `json:"channel_id"`
	MessageID discord.MessageID `json:"message_id"`
	Emoji     discord.Emoji     `json:"emoji"`
	GuildID   discord.GuildID   `json:"guild_id,omitempty"`

type MessageReactionRemoveEvent

type MessageReactionRemoveEvent struct {
	UserID    discord.UserID    `json:"user_id"`
	ChannelID discord.ChannelID `json:"channel_id"`
	MessageID discord.MessageID `json:"message_id"`
	Emoji     discord.Emoji     `json:"emoji"`
	GuildID   discord.GuildID   `json:"guild_id,omitempty"`

type MessageUpdateEvent

type MessageUpdateEvent struct {
	Member *discord.Member `json:"member,omitempty"`

type OPCode

type OPCode = wsutil.OPCode
const (
	DispatchOP            OPCode = 0 // recv
	HeartbeatOP           OPCode = 1 // send/recv
	IdentifyOP            OPCode = 2 // send...
	StatusUpdateOP        OPCode = 3 //
	VoiceStateUpdateOP    OPCode = 4 //
	VoiceServerPingOP     OPCode = 5 //
	ResumeOP              OPCode = 6 //
	ReconnectOP           OPCode = 7 // recv
	RequestGuildMembersOP OPCode = 8 // send
	InvalidSessionOP      OPCode = 9 // recv...
	HelloOP               OPCode = 10
	HeartbeatAckOP        OPCode = 11
	CallConnectOP         OPCode = 13
	GuildSubscriptionsOP  OPCode = 14

type Presence

type Presence struct {
	// User is the user presence is being updated for. Only the ID field is
	// guaranteed to be valid per Discord documentation.
	User discord.User `json:"user"`
	// GuildID is the id of the guild
	GuildID discord.GuildID `json:"guild_id"`
	// Status is either "idle", "dnd", "online", or "offline".
	Status Status `json:"status"`
	// Activities are the user's current activities.
	Activities []discord.Activity `json:"activities"`
	// ClientStatus is the user's platform-dependent status.
	ClientStatus ClientStatus `json:"client_status"`

Presence represents a partial Presence structure used by other structs to be easily embedded. It does not contain any ID to identify who it belongs to. For more information, refer to the PresenceUpdateEvent struct.

func ConvertSupplementalPresence

func ConvertSupplementalPresence(sp SupplementalPresence) Presence

ConvertSupplementalPresence converts a SupplementalPresence to a regular Presence with an empty GuildID.

type PresenceUpdateEvent

type PresenceUpdateEvent struct {

PresenceUpdateEvent represents the structure of the Presence Update Event object.

type ReadState

type ReadState struct {
	ChannelID        discord.ChannelID `json:"id"`
	LastMessageID    discord.MessageID `json:"last_message_id"`
	LastPinTimestamp discord.Timestamp `json:"last_pin_timestamp"`
	MentionCount     int               `json:"mention_count"`

ReadState is a single ReadState entry. It is undocumented.

type ReadyEvent

type ReadyEvent struct {
	Version int `json:"version"`

	User      discord.User `json:"user"`
	SessionID string       `json:"session_id"`

	PrivateChannels []discord.Channel  `json:"private_channels"`
	Guilds          []GuildCreateEvent `json:"guilds"`

	Shard *Shard `json:"shard,omitempty"`

	UserSettings      *UserSettings          `json:"user_settings,omitempty"`
	ReadStates        []ReadState            `json:"read_state,omitempty"`
	UserGuildSettings []UserGuildSetting     `json:"user_guild_settings,omitempty"`
	Relationships     []discord.Relationship `json:"relationships,omitempty"`
	Presences         []Presence             `json:"presences,omitempty"`

	FriendSuggestionCount int      `json:"friend_suggestion_count,omitempty"`
	GeoOrderedRTCRegions  []string `json:"geo_ordered_rtc_regions,omitempty"`

ReadyEvent is the struct for a READY event.

type ReadySupplementalEvent

type ReadySupplementalEvent struct {
	Guilds          []GuildCreateEvent     `json:"guilds"` // only have ID and VoiceStates
	MergedMembers   [][]SupplementalMember `json:"merged_members"`
	MergedPresences MergedPresences        `json:"merged_presences"`

ReadySupplementalEvent is the struct for a READY_SUPPLEMENTAL event, which is an undocumented event.

type RelationshipAddEvent

type RelationshipAddEvent struct {

type RelationshipRemoveEvent

type RelationshipRemoveEvent struct {

type RequestGuildMembersData

type RequestGuildMembersData struct {
	GuildID []discord.GuildID `json:"guild_id"`
	UserIDs []discord.UserID  `json:"user_ids,omitempty"`

	Query     string `json:"query"`
	Limit     uint   `json:"limit"`
	Presences bool   `json:"presences,omitempty"`
	Nonce     string `json:"nonce,omitempty"`

type ResumeData

type ResumeData struct {
	Token     string `json:"token"`
	SessionID string `json:"session_id"`
	Sequence  int64  `json:"seq"`

type SessionStartLimit

type SessionStartLimit struct {
	Total          int                  `json:"total"`
	Remaining      int                  `json:"remaining"`
	ResetAfter     discord.Milliseconds `json:"reset_after"`
	MaxConcurrency int                  `json:"max_concurrency"`

SessionStartLimit is the information on the current session start limit. It's used in BotData.

type SessionsReplaceEvent

type SessionsReplaceEvent []struct {
	Status    Status `json:"status"`
	SessionID string `json:"session_id"`

	Activities []discord.Activity `json:"activities"`

	ClientInfo struct {
		Version int    `json:"version"`
		OS      string `json:"os"`
		Client  string `json:"client"`
	} `json:"client_info"`

	Active bool `json:"active"`

SessionsReplaceEvent is an undocumented user event. It's likely used for current user's presence updates.

type Shard

type Shard [2]int

Shard is a type for two numbers that represent the Bot's shard configuration. The first number is the shard's ID, which could be obtained through the ShardID method. The second number is the total number of shards, which could be obtained through the NumShards method.

func (Shard) NumShards

func (s Shard) NumShards() int

NumShards returns the total number of shards. It uses the second number.

func (Shard) ShardID

func (s Shard) ShardID() int

ShardID returns the current shard's ID. It uses the first number.

type Status

type Status string

Status is the enumerate type for a user's status.

const (
	UnknownStatus      Status = ""
	OnlineStatus       Status = "online"
	DoNotDisturbStatus Status = "dnd"
	IdleStatus         Status = "idle"
	InvisibleStatus    Status = "invisible"
	OfflineStatus      Status = "offline"

type SupplementalMember

type SupplementalMember struct {
	UserID  discord.UserID   `json:"user_id"`
	Nick    string           `json:"nick,omitempty"`
	RoleIDs []discord.RoleID `json:"roles"`

	GuildID     discord.GuildID `json:"guild_id,omitempty"`
	IsPending   bool            `json:"is_pending,omitempty"`
	HoistedRole discord.RoleID  `json:"hoisted_role"`

	Mute bool `json:"mute"`
	Deaf bool `json:"deaf"`

	// Joined specifies when the user joined the guild.
	Joined discord.Timestamp `json:"joined_at"`

	// BoostedSince specifies when the user started boosting the guild.
	BoostedSince discord.Timestamp `json:"premium_since,omitempty"`

SupplementalMember is the struct for a member in the MergedMembers field of ReadySupplementalEvent. It has slight differences to discord.Member.

type SupplementalPresence

type SupplementalPresence struct {
	UserID discord.UserID `json:"user_id"`

	// Status is either "idle", "dnd", "online", or "offline".
	Status Status `json:"status"`
	// Activities are the user's current activities.
	Activities []discord.Activity `json:"activities"`
	// ClientStaus is the user's platform-dependent status.
	ClientStatus ClientStatus `json:"client_status"`

	// LastModified is only present in Friends.
	LastModified discord.UnixMsTimestamp `json:"last_modified,omitempty"`

SupplementalPresence is a single presence for either a guild member or friend. It is used in MergedPresences and is undocumented.

type TypingStartEvent

type TypingStartEvent struct {
	ChannelID discord.ChannelID     `json:"channel_id"`
	UserID    discord.UserID        `json:"user_id"`
	Timestamp discord.UnixTimestamp `json:"timestamp"`

	GuildID discord.GuildID `json:"guild_id,omitempty"`
	Member  *discord.Member `json:"member,omitempty"`

type UpdateStatusData

type UpdateStatusData struct {
	Since discord.UnixMsTimestamp `json:"since"` // 0 if not idle

	// Activities can be null or an empty slice.
	Activities []discord.Activity `json:"activities"`

	Status Status `json:"status"`
	AFK    bool   `json:"afk"`

UpdateStatusData is sent by this client to indicate a presence or status update.

var DefaultPresence *UpdateStatusData

DefaultPresence is used as the default presence when initializing a new Gateway.

type UpdateVoiceStateData

type UpdateVoiceStateData struct {
	GuildID   discord.GuildID   `json:"guild_id"`
	ChannelID discord.ChannelID `json:"channel_id"` // nullable
	SelfMute  bool              `json:"self_mute"`
	SelfDeaf  bool              `json:"self_deaf"`

type UserChannelOverride

type UserChannelOverride struct {
	Muted         bool              `json:"muted"`
	MuteConfig    *UserMuteConfig   `json:"mute_config"`
	Notifications UserNotification  `json:"message_notifications"`
	ChannelID     discord.ChannelID `json:"channel_id"`

A UserChannelOverride struct describes a channel settings override for a users guild settings.

type UserGuildSetting

type UserGuildSetting struct {
	GuildID discord.GuildID `json:"guild_id"`

	SuppressRoles    bool            `json:"suppress_roles"`
	SuppressEveryone bool            `json:"suppress_everyone"`
	Muted            bool            `json:"muted"`
	MuteConfig       *UserMuteConfig `json:"mute_config"`

	MobilePush    bool             `json:"mobile_push"`
	Notifications UserNotification `json:"message_notifications"`

	ChannelOverrides []UserChannelOverride `json:"channel_overrides"`

UserGuildSetting stores the settings for a single guild. It is undocumented.

type UserGuildSettingsUpdateEvent

type UserGuildSettingsUpdateEvent struct {


type UserMuteConfig

type UserMuteConfig struct {
	SelectedTimeWindow int               `json:"selected_time_window"`
	EndTime            discord.Timestamp `json:"end_time"`

UserMuteConfig seems to describe the mute settings. It belongs to the UserGuildSettingEntry and UserChannelOverride structs and is undocumented.

type UserNoteUpdateEvent

type UserNoteUpdateEvent struct {
	ID   discord.UserID `json:"id"`
	Note string         `json:"note"`


type UserNotification

type UserNotification uint8

UserNotification is the notification setting for a channel or guild.

const (
	AllNotifications UserNotification = iota

type UserSettings

type UserSettings struct {
	ShowCurrentGame         bool  `json:"show_current_game"`
	DefaultGuildsRestricted bool  `json:"default_guilds_restricted"`
	InlineAttachmentMedia   bool  `json:"inline_attachment_media"`
	InlineEmbedMedia        bool  `json:"inline_embed_media"`
	GIFAutoPlay             bool  `json:"gif_auto_play"`
	RenderEmbeds            bool  `json:"render_embeds"`
	RenderReactions         bool  `json:"render_reactions"`
	AnimateEmoji            bool  `json:"animate_emoji"`
	AnimateStickers         int   `json:"animate_stickers"`
	EnableTTSCommand        bool  `json:"enable_tts_command"`
	MessageDisplayCompact   bool  `json:"message_display_compact"`
	ConvertEmoticons        bool  `json:"convert_emoticons"`
	ExplicitContentFilter   uint8 `json:"explicit_content_filter"` // ???
	DisableGamesTab         bool  `json:"disable_games_tab"`
	DeveloperMode           bool  `json:"developer_mode"`
	DetectPlatformAccounts  bool  `json:"detect_platform_accounts"`
	StreamNotification      bool  `json:"stream_notification_enabled"`
	AccessibilityDetection  bool  `json:"allow_accessibility_detection"`
	ContactSync             bool  `json:"contact_sync_enabled"`
	NativePhoneIntegration  bool  `json:"native_phone_integration_enabled"`

	TimezoneOffset int `json:"timezone_offset"`

	Locale string `json:"locale"`
	Theme  string `json:"theme"`

	GuildPositions   []discord.GuildID `json:"guild_positions"`
	GuildFolders     []GuildFolder     `json:"guild_folders"`
	RestrictedGuilds []discord.GuildID `json:"restricted_guilds"`

	FriendSourceFlags FriendSourceFlags `json:"friend_source_flags"`

	Status       Status            `json:"status"`
	CustomStatus *CustomUserStatus `json:"custom_status"`

UserSettings is the struct for (almost) all user settings. It is undocumented.

type UserSettingsUpdateEvent

type UserSettingsUpdateEvent struct {


type VoiceServerUpdateEvent

type VoiceServerUpdateEvent struct {
	Token    string          `json:"token"`
	GuildID  discord.GuildID `json:"guild_id"`
	Endpoint string          `json:"endpoint"`

type WebhooksUpdateEvent

type WebhooksUpdateEvent struct {
	GuildID   discord.GuildID   `json:"guild_id"`
	ChannelID discord.ChannelID `json:"channel_id"`

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL