Documentation
¶
Index ¶
- Constants
- func CmdNameToOpCode(command string, t ClientType) (op opcode.OpCode)
- func ConfigureShardConfig(ctx context.Context, client GatewayBotGetter, conf *ShardConfig) error
- func GetShardForGuildID(guildID Snowflake, shardCount uint) (shardID uint)
- func NewShardMngr(conf ShardManagerConfig) *shardMngr
- type ClientType
- type CloseErr
- type CmdPayload
- type Conn
- type DiscordPacket
- type Event
- type EvtClient
- func (c EvtClient) AllowedToStartPulsating(serviceID uint8) bool
- func (c *EvtClient) Connect() (err error)
- func (c EvtClient) Disconnect() (err error)
- func (c *EvtClient) Emit(command string, data CmdPayload) (err error)
- func (c EvtClient) HeartbeatLatency() (duration time.Duration, err error)
- func (c EvtClient) IsDisconnected() bool
- func (c *EvtClient) SetPresence(data interface{}) (err error)
- func (c EvtClient) StopPulsating(serviceID uint8)
- type EvtConfig
- type Gateway
- type GatewayBot
- type GatewayBotGetter
- type IdentifyMetric
- type Intent
- type Link
- type RequestGuildMembersPayload
- type ShardConfig
- type ShardManager
- type ShardManagerConfig
- type Snowflake
- type UniqueStringSlice
- type UpdateStatusPayload
- type UpdateVoiceStatePayload
- type VoiceClient
- func (c *VoiceClient) Active() <-chan interface{}
- func (c VoiceClient) AllowedToStartPulsating(serviceID uint8) bool
- func (c *VoiceClient) Connect() (rdy *VoiceReady, err error)
- func (c VoiceClient) Disconnect() (err error)
- func (c *VoiceClient) Emit(name string, data interface{}) error
- func (c VoiceClient) HeartbeatLatency() (duration time.Duration, err error)
- func (c VoiceClient) IsDisconnected() bool
- func (c *VoiceClient) SendUDPInfo(data *VoiceSelectProtocol) (ret *VoiceSessionDescription, err error)
- func (c VoiceClient) StopPulsating(serviceID uint8)
- type VoiceConfig
- type VoiceReady
- type VoiceSelectProtocol
- type VoiceSessionDescription
- type WebsocketErr
Constants ¶
const ( StatusOnline = "online" StatusDND = "dnd" StatusIdle = "idle" StatusInvisible = "invisible" StatusOffline = "offline" )
const DefaultIdentifyRateLimit = 1000
const MetricReconnectPeriod = time.Hour * 48
const SaveIncomingPackets = false
Variables ¶
This section is empty.
Functions ¶
func CmdNameToOpCode ¶
func CmdNameToOpCode(command string, t ClientType) (op opcode.OpCode)
func ConfigureShardConfig ¶
func ConfigureShardConfig(ctx context.Context, client GatewayBotGetter, conf *ShardConfig) error
func GetShardForGuildID ¶
GetShardForGuildID converts a GuildID into a ShardID for correct retrieval of guild information
func NewShardMngr ¶
func NewShardMngr(conf ShardManagerConfig) *shardMngr
Types ¶
type ClientType ¶
type ClientType int
type CmdPayload ¶
type CmdPayload interface {
// contains filtered or unexported methods
}
type DiscordPacket ¶
type DiscordPacket struct {
Op opcode.OpCode `json:"op"`
Data json.RawMessage `json:"d"`
SequenceNumber uint32 `json:"s,omitempty"`
EventName string `json:"t,omitempty"`
}
DiscordPacket is packets sent by Discord over the socket connection
type Event ¶
Event is dispatched by the socket layer after parsing and extracting Discord data from a incoming packet. This is the data structure used by Disgord for triggering handlers and channels with an event.
type EvtClient ¶
type EvtClient struct {
ReadyCounter uint
// contains filtered or unexported fields
}
func NewEventClient ¶
NewManager creates a new socket client manager for handling behavior and Discord events. Note that this function initiates a go routine.
func (EvtClient) AllowedToStartPulsating ¶
AllowedToStartPulsating you must notify when you are done pulsating!
func (*EvtClient) Connect ¶
////////////////////////////////////////////////////
GENERAL: unique to event
////////////////////////////////////////////////////
func (EvtClient) Disconnect ¶
func (c EvtClient) Disconnect() (err error)
Disconnect disconnects the socket connection
func (EvtClient) HeartbeatLatency ¶
HeartbeatLatency get the time diff between sending a heartbeat and Discord replying with a heartbeat ack
func (EvtClient) IsDisconnected ¶ added in v0.16.4
func (c EvtClient) IsDisconnected() bool
////////////////////////////////////////////////////
LINKING: CONNECTING / DISCONNECTING / RECONNECTING
////////////////////////////////////////////////////
func (*EvtClient) SetPresence ¶
func (EvtClient) StopPulsating ¶
func (c EvtClient) StopPulsating(serviceID uint8)
StopPulsating stops sending heartbeats to Discord
type EvtConfig ¶
type EvtConfig struct {
// BotToken Discord bot token
BotToken string
HTTPClient *http.Client
Intents Intent
// EventChan can be used to inject a channel instead of letting the ws client construct one
// useful in sharding to avoid complicated patterns to handle N channels.
EventChan chan<- *Event
Presence *UpdateStatusPayload
// Endpoint for establishing socket connection. Either endpoints, `Gateway` or `Gateway Bot`, is used to retrieve
// a valid socket endpoint from Discord
Endpoint string
// Encoding make sure we support the correct encoding
Encoding string
// Version make sure we support the correct Discord version
Version int
// for identify packets
Browser string
Device string
GuildLargeThreshold uint
ShardCount uint
DiscordPktPool *sync.Pool
// MessageQueueLimit number of outgoing messages that can be queued and sent correctly.
MessageQueueLimit uint
Logger logger.Logger
SystemShutdown chan interface{}
// contains filtered or unexported fields
}
EvtConfig ws
type Gateway ¶
type Gateway struct {
URL string `json:"url"`
}
Gateway is for parsing the Gateway endpoint response
type GatewayBot ¶
type GatewayBot struct {
Gateway
Shards uint `json:"shards"`
SessionStartLimit struct {
Total uint `json:"total"`
Remaining uint `json:"remaining"`
ResetAfter uint `json:"reset_after"`
} `json:"session_start_limit"`
}
GatewayBot is for parsing the Gateway Bot endpoint response
type GatewayBotGetter ¶
type GatewayBotGetter interface {
GetGatewayBot(context.Context) (gateway *GatewayBot, err error)
}
type IdentifyMetric ¶ added in v0.15.0
type IdentifyMetric struct {
sync.Mutex
Reconnects []time.Time // last 48h or (see const ReconnectPeriod)
}
TODO-1: make it specific to individual shards for more insight TODO-2: Limit storage period
func (*IdentifyMetric) ReconnectsSince ¶ added in v0.15.0
func (s *IdentifyMetric) ReconnectsSince(d time.Duration) (counter uint)
ReconnectsSince counts the number of reconnects since t, where t can be no more than ReconnectPeriod (48h?)
type Intent ¶ added in v0.17.0
type Intent uint64
const ( // IntentGuilds // - GUILD_CREATE // - GUILD_UPDATE // - GUILD_DELETE // - GUILD_ROLE_CREATE // - GUILD_ROLE_UPDATE // - GUILD_ROLE_DELETE // - CHANNEL_CREATE // - CHANNEL_UPDATE // - CHANNEL_DELETE // - CHANNEL_PINS_UPDATE // - THREAD_CREATE // - THREAD_UPDATE // - THREAD_DELETE // - THREAD_LIST_SYNC // - THREAD_MEMBER_UPDATE IntentGuilds Intent = 1 << iota // IntentGuildMembers // - GUILD_MEMBER_ADD // - GUILD_MEMBER_UPDATE // - GUILD_MEMBER_REMOVE // assumption#1: put thread member update event intent into here for now. // ref - https://discord.com/developers/docs/topics/gateway#thread-members-update // - THREAD_MEMBERS_UPDATE IntentGuildMembers // IntentGuildBans // - GUILD_BAN_ADD // - GUILD_BAN_REMOVE IntentGuildBans // IntentGuildEmojisAndStickers // - GUILD_EMOJIS_UPDATE IntentGuildEmojisAndStickers // IntentGuildIntegrations // - GUILD_INTEGRATIONS_UPDATE IntentGuildIntegrations IntentGuildWebhooks IntentGuildInvites IntentGuildVoiceStates IntentGuildPresences IntentGuildMessages IntentGuildMessageReactions IntentGuildMessageTyping IntentDirectMessages IntentDirectMessageReactions IntentDirectMessageTyping IntentGuildScheduledEvents )
func EventToIntent ¶ added in v0.20.0
type Link ¶
Link is used to establish basic commands to create and destroy a link. See client.Disconnect() and client.Connect() for linking to the Discord servers
type RequestGuildMembersPayload ¶
type RequestGuildMembersPayload struct {
// GuildID id of the guild(s) to get offline members for
GuildIDs []Snowflake `json:"guild_id"`
// Query string that username starts with, or an empty string to return all members
Query string `json:"query"`
// Limit maximum number of members to send or 0 to request all members matched
Limit uint `json:"limit"`
Presences bool `json:"presences"`
// UserIDs used to specify which users you wish to fetch
UserIDs []Snowflake `json:"user_ids,omitempty"`
Nonce string `json:"nonce,omitempty"`
}
type ShardConfig ¶
type ShardConfig struct {
// Specify the shard ids that can be used by this instance.
// eg. ShardIds = []uint{0,1,2,3,11,12,13,14,32}
//
// This control is only useful if you have more than once instance of your bot duo to
// high traffic or whatever reason you might possess.
//
// This also allows you to manually specify the number of shards, you just have to
// specify their ID as well. You start from 0 until the number of shards you desire.
//
// Default value is populated by discord if this slice is nil.
ShardIDs []uint
// ShardCount should reflect the "total number of shards" across all
// instances for your bot. If you run 3 containers with 2 shards each, then
// the ShardCount should be 6, while the length of shardIDs would be
// two on each container.
//
// defaults to len(shardIDs) if 0
ShardCount uint
// Large bots only. If Discord did not give you a custom rate limit, do not touch this.
ShardRateLimit time.Duration
// ConnectQueue is used to control how often shards can connect by sending an identify command.
// For distributed systems, this must be overwritten as, by default, you can only send one identify
// every five seconds. The default implementation can be found in shard_sync.go.
ConnectQueue connectQueue
// DisableAutoScaling is triggered when at least one shard gets a 4011 websocket
// error from Discord. This causes all the shards to disconnect and new ones are created.
//
// default value is false unless shardIDs or ShardCount is set.
DisableAutoScaling bool
// OnScalingRequired is triggered when Discord closes the websocket connection
// with a 4011 websocket error. It may run multiple times per session. You should
// immediately call disconnect and scale your shards, unless you know what you're doing.
//
// This is triggered when DisableAutoScaling is true. If DisableAutoScaling is true and
// OnScalingRequired is nil, this is considered an user error and will panic.
//
// You must return the new number of total shards and additional shard ids this instance
// should setup. If you do not want this instance to gain extra shards, set AdditionalShardIDs
// to nil.
OnScalingRequired func(shardIDs []uint) (TotalNrOfShards uint, AdditionalShardIDs []uint)
// OnScalingDiscardedRequests When scaling is triggered, some of the guilds might have moved to other shards
// that do not exist on this disgord instance. This callback will return a list of guild ID that exists in
// outgoing requests that were discarded due to no local shard match.
//
// Note: only regards systems with multiple disgord instances
// TODO: return a list of outgoing requests instead such that people can re-trigger these on other instances.
OnScalingDiscardedRequests func(unhandledGuildIDs []Snowflake)
// IdentifiesPer24H regards how many identify packets a bot can send per a 24h period. Normally this
// is 1000, but in some cases discord might allow you to increase it.
//
// Setting it to 0 will default it to 1000.
IdentifiesPer24H uint
// URL is fetched from the gateway before initialising a connection
URL string
}
type ShardManager ¶
type ShardManager interface {
Connect() error
Disconnect() error
Emit(string, CmdPayload) (unhandledGuildIDs []Snowflake, err error)
LocalShardCount() uint
ShardCount() uint
ShardIDs() (shardIDs []uint)
GetShard(shardID shardID) (shard *EvtClient, err error)
HeartbeatLatencies() (latencies map[shardID]time.Duration, err error)
}
ShardManager regards websocket shards.
type ShardManagerConfig ¶
type ShardManagerConfig struct {
ShardConfig
DisgordInfo string
BotToken string
HTTPClient *http.Client
Logger logger.Logger
ShutdownChan chan interface{}
// ...
IgnoreEvents []string
Intents Intent
// sync ---
EventChan chan<- *Event
RESTClient GatewayBotGetter
// user specific
DefaultBotPresence *UpdateStatusPayload
ProjectName string
// contains filtered or unexported fields
}
ShardManagerConfig all fields, except proxy.Dialer, is required
type UniqueStringSlice ¶
type UniqueStringSlice struct {
// contains filtered or unexported fields
}
UniqueStringSlice a thread safe string slice that does not allow duplicate strings to be stored
func (*UniqueStringSlice) Add ¶
func (s *UniqueStringSlice) Add(id string)
func (*UniqueStringSlice) Contains ¶
func (s *UniqueStringSlice) Contains(id string) (exists bool)
func (*UniqueStringSlice) Len ¶
func (s *UniqueStringSlice) Len() int
func (*UniqueStringSlice) Remove ¶
func (s *UniqueStringSlice) Remove(id string)
type UpdateStatusPayload ¶
type UpdateStatusPayload struct {
// Since unix time (in milliseconds) of when the Client went idle, or null if the Client is not idle
Since *uint `json:"since"`
// Game null, or the user's new activity
Game interface{} `json:"activities"`
// Status the user's new status
Status string `json:"status"`
// AFK whether or not the Client is afk
AFK bool `json:"afk"`
}
type UpdateVoiceStatePayload ¶
type UpdateVoiceStatePayload struct {
// GuildID id of the guild
GuildID Snowflake `json:"guild_id"`
// ChannelID id of the voice channel Client wants to join
// (set to 0 if disconnecting)
ChannelID Snowflake `json:"channel_id"`
// SelfMute is the Client mute
SelfMute bool `json:"self_mute"`
// SelfDeaf is the Client deafened
SelfDeaf bool `json:"self_deaf"`
}
type VoiceClient ¶
type VoiceClient struct {
SystemShutdown chan interface{}
// contains filtered or unexported fields
}
func NewVoiceClient ¶
func NewVoiceClient(conf *VoiceConfig) (client *VoiceClient, err error)
func (*VoiceClient) Active ¶ added in v0.17.0
func (c *VoiceClient) Active() <-chan interface{}
func (VoiceClient) AllowedToStartPulsating ¶
AllowedToStartPulsating you must notify when you are done pulsating!
func (*VoiceClient) Connect ¶
func (c *VoiceClient) Connect() (rdy *VoiceReady, err error)
Connect establishes a socket connection with the Discord API
func (VoiceClient) Disconnect ¶
func (c VoiceClient) Disconnect() (err error)
Disconnect disconnects the socket connection
func (*VoiceClient) Emit ¶
func (c *VoiceClient) Emit(name string, data interface{}) error
Emit for voice client needs to bypass the normal Emit restrictions. TODO: put more of the code flow of disgord/voiceclient.go into the websocket pkg.
func (VoiceClient) HeartbeatLatency ¶
HeartbeatLatency get the time diff between sending a heartbeat and Discord replying with a heartbeat ack
func (VoiceClient) IsDisconnected ¶ added in v0.16.4
func (c VoiceClient) IsDisconnected() bool
////////////////////////////////////////////////////
LINKING: CONNECTING / DISCONNECTING / RECONNECTING
////////////////////////////////////////////////////
func (*VoiceClient) SendUDPInfo ¶
func (c *VoiceClient) SendUDPInfo(data *VoiceSelectProtocol) (ret *VoiceSessionDescription, err error)
func (VoiceClient) StopPulsating ¶
func (c VoiceClient) StopPulsating(serviceID uint8)
StopPulsating stops sending heartbeats to Discord
type VoiceConfig ¶
type VoiceConfig struct {
// Guild ID to connect to
GuildID Snowflake
// User ID that is connecting
UserID Snowflake
// Session ID
SessionID string
// Token to connect with the voice websocket
Token string
// proxy allows for use of a custom proxy
HTTPClient *http.Client
// Endpoint for establishing voice connection
Endpoint string
// MessageQueueLimit number of outgoing messages that can be queued and sent correctly.
MessageQueueLimit uint
Logger logger.Logger
SystemShutdown chan interface{}
}
type VoiceReady ¶
type VoiceSelectProtocol ¶ added in v0.30.0
type VoiceSessionDescription ¶
type WebsocketErr ¶
type WebsocketErr struct {
ID uint
// contains filtered or unexported fields
}
WebsocketErr is used internally when the websocket package returns an error. It does not represent a Discord error!
func (*WebsocketErr) Error ¶
func (e *WebsocketErr) Error() string