github.com/diamondburned/arikawa/v2@v2.1.0/gateway/identify.go (about) 1 package gateway 2 3 import ( 4 "context" 5 "runtime" 6 "time" 7 8 "github.com/pkg/errors" 9 "golang.org/x/time/rate" 10 ) 11 12 // DefaultPresence is used as the default presence when initializing a new 13 // Gateway. 14 var DefaultPresence *UpdateStatusData 15 16 // Identifier is a wrapper around IdentifyData to add in appropriate rate 17 // limiters. 18 type Identifier struct { 19 IdentifyData 20 21 IdentifyShortLimit *rate.Limiter `json:"-"` // optional 22 IdentifyGlobalLimit *rate.Limiter `json:"-"` // optional 23 } 24 25 // DefaultIdentifier creates a new default Identifier 26 func DefaultIdentifier(token string) *Identifier { 27 return NewIdentifier(DefaultIdentifyData(token)) 28 } 29 30 // NewIdentifier creates a new identifier with the given IdentifyData and 31 // default rate limiters. 32 func NewIdentifier(data IdentifyData) *Identifier { 33 return &Identifier{ 34 IdentifyData: data, 35 IdentifyShortLimit: rate.NewLimiter(rate.Every(5*time.Second), 1), 36 IdentifyGlobalLimit: rate.NewLimiter(rate.Every(24*time.Hour), 1000), 37 } 38 } 39 40 // Wait waits for the rate limiters to pass. If a limiter is nil, then it will 41 // not be used to wait. This is useful 42 func (i *Identifier) Wait(ctx context.Context) error { 43 if i.IdentifyShortLimit != nil { 44 if err := i.IdentifyShortLimit.Wait(ctx); err != nil { 45 return errors.Wrap(err, "can't wait for short limit") 46 } 47 } 48 49 if i.IdentifyGlobalLimit != nil { 50 if err := i.IdentifyGlobalLimit.Wait(ctx); err != nil { 51 return errors.Wrap(err, "can't wait for global limit") 52 } 53 } 54 55 return nil 56 } 57 58 // DefaultIdentity is used as the default identity when initializing a new 59 // Gateway. 60 var DefaultIdentity = IdentifyProperties{ 61 OS: runtime.GOOS, 62 Browser: "Arikawa", 63 Device: "Arikawa", 64 } 65 66 // IdentifyData is the struct for a data that's sent over in an Identify 67 // command. 68 type IdentifyData struct { 69 Token string `json:"token"` 70 Properties IdentifyProperties `json:"properties"` 71 72 Compress bool `json:"compress,omitempty"` // true 73 LargeThreshold uint `json:"large_threshold,omitempty"` // 50 74 75 Shard *Shard `json:"shard,omitempty"` // [ shard_id, num_shards ] 76 77 Presence *UpdateStatusData `json:"presence,omitempty"` 78 79 Intents Intents `json:"intents,omitempty"` 80 } 81 82 // DefaultIdentifyData creates a default IdentifyData with the given token. 83 func DefaultIdentifyData(token string) IdentifyData { 84 return IdentifyData{ 85 Token: token, 86 Properties: DefaultIdentity, 87 Presence: DefaultPresence, 88 89 Compress: true, 90 LargeThreshold: 50, 91 } 92 } 93 94 // SetShard is a helper function to set the shard configuration inside 95 // IdentifyData. 96 func (i *IdentifyData) SetShard(id, num int) { 97 if i.Shard == nil { 98 i.Shard = new(Shard) 99 } 100 i.Shard[0], i.Shard[1] = id, num 101 } 102 103 type IdentifyProperties struct { 104 // Required 105 OS string `json:"os"` // GOOS 106 Browser string `json:"browser"` // Arikawa 107 Device string `json:"device"` // Arikawa 108 109 // Optional 110 BrowserUserAgent string `json:"browser_user_agent,omitempty"` 111 BrowserVersion string `json:"browser_version,omitempty"` 112 OSVersion string `json:"os_version,omitempty"` 113 Referrer string `json:"referrer,omitempty"` 114 ReferringDomain string `json:"referring_domain,omitempty"` 115 } 116 117 // Shard is a type for two numbers that represent the Bot's shard configuration. 118 // The first number is the shard's ID, which could be obtained through the 119 // ShardID method. The second number is the total number of shards, which could 120 // be obtained through the NumShards method. 121 type Shard [2]int 122 123 // DefaultShard returns the default shard configuration of 1 shard total, in 124 // which the current shard ID is 0. 125 var DefaultShard = &Shard{0, 1} 126 127 // ShardID returns the current shard's ID. It uses the first number. 128 func (s Shard) ShardID() int { 129 return s[0] 130 } 131 132 // NumShards returns the total number of shards. It uses the second number. 133 func (s Shard) NumShards() int { 134 return s[1] 135 }