Skip to content

Commit

Permalink
fix: gateway guild subscriptions in large servers
Browse files Browse the repository at this point in the history
  • Loading branch information
BridgeSenseDev committed Feb 3, 2025
1 parent 16fdace commit 3e1ad21
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 20 deletions.
12 changes: 7 additions & 5 deletions discord/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ func (client *Client) GetCommands(guildID string) (map[string]CommandData, error

commands := make(map[string]CommandData)
for _, cmd := range data.ApplicationCommands {
commands[cmd.Name] = cmd
if cmd.ApplicationID == "270904126974590976" {
commands[cmd.Name] = cmd
}
}

return commands, nil
Expand All @@ -73,7 +75,7 @@ type Channel struct {
GuildID string `json:"guild_id"`
}

func (client *Client) GetGuildID(channelID string) string {
func (client *Client) GetGuildID(channelID string) (string, error) {
url := fmt.Sprintf("https://discord.com/api/v9/channels/%s", channelID)

req := fasthttp.AcquireRequest()
Expand All @@ -89,17 +91,17 @@ func (client *Client) GetGuildID(channelID string) string {

err := fasthttp.Do(req, resp)
if err != nil {
return ""
return "", err
}

body := resp.Body()

var channel Channel
if err := json.Unmarshal(body, &channel); err != nil {
return ""
return "", err
}

return channel.GuildID
return channel.GuildID, nil
}

func (client *Client) RequestWithLockedBucket(method, urlStr string, b []byte, bucket *Bucket, sequence int) ([]byte, error) {
Expand Down
18 changes: 18 additions & 0 deletions gateway/gateway_messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,3 +201,21 @@ type MessageDataHello struct {
}

func (MessageDataHello) messageData() {}

// GuildSubscription represents the subscription settings for a single guild.
type GuildSubscription struct {
Typing bool `json:"typing"`
Threads bool `json:"threads"`
Activities bool `json:"activities"`
Members []int64 `json:"members"`
MemberUpdates bool `json:"member_updates"`
Channels map[string][][2]int `json:"channels"`
ThreadMemberLists []int64 `json:"thread_member_lists"`
}

// MessageDataGuildSubscriptionsBulk is the payload for the bulk guild subscribe (opcode 37)
type MessageDataGuildSubscriptionsBulk struct {
Subscriptions map[string]GuildSubscription `json:"subscriptions"`
}

func (MessageDataGuildSubscriptionsBulk) messageData() {}
1 change: 1 addition & 0 deletions gateway/gateway_opcodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const (
OpcodeInvalidSession
OpcodeHello
OpcodeHeartbeatACK
GUILD_SUBSCRIPTIONS_BULK = Opcode(37)
)

type CloseEventCode struct {
Expand Down
36 changes: 25 additions & 11 deletions instance/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,19 @@ var messageUpdateHandlers = map[string]MessageHandler{
}

func (in *Instance) shouldHandleMessage(message gateway.EventMessage) bool {
return in.Cfg.State && in.AccountCfg.State && message.Author.ID == "270904126974590976" &&
len(message.Embeds) > 0 &&
!strings.Contains(message.Embeds[0].Description, "cooldown is")
if !in.Cfg.State ||
!in.AccountCfg.State ||
message.Author.ID != "270904126974590976" ||
len(message.Embeds) == 0 ||
strings.Contains(message.Embeds[0].Description, "cooldown is") {
return false
}

if message.Interaction.User.ID != "" {
return message.Interaction.User.ID == in.User.ID
}

return true
}

func (in *Instance) getMessageType(message gateway.EventMessage) string {
Expand All @@ -193,7 +203,7 @@ func (in *Instance) getMessageType(message gateway.EventMessage) string {
}

func (in *Instance) handleInteraction(message gateway.EventMessage, handlers map[string]MessageHandler) {
if message.Interaction != (types.MessageInteraction{}) && message.Interaction.User.ID == in.User.ID && message.Flags != 64 {
if message.Interaction != (types.MessageInteraction{}) && message.Flags != 64 {
if handler, ok := handlers[strings.Split(message.Interaction.Name, " ")[0]]; ok {
handler(in, message)
}
Expand All @@ -202,22 +212,26 @@ func (in *Instance) handleInteraction(message gateway.EventMessage, handlers map

func (in *Instance) HandleMessageCreate(message gateway.EventMessage) {
if in.shouldHandleMessage(message) {
// Apply to all messages
if in.Captcha(message) {
return
}

in.Others(message)

messageType := in.getMessageType(message)

if messageType == "channel" {
// Only apply to channel_id channel
if in.Captcha(message) {
return
}
in.Others(message)

in.handleInteraction(message, messageCreateHandlers)
in.MinigamesMessageCreate(message)
in.EventsMessageCreate(message)
in.AutoBuyMessageCreate(message)
} else if messageType == "dm" {
// Only apply to dank dm's
if in.Captcha(message) {
return
}
in.Others(message)

in.AutoBuyMessageCreate(message)
in.AutoUse(message)
}
Expand Down
26 changes: 22 additions & 4 deletions instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ func (d *DmgService) StartInstance(account config.AccountsConfig) {
client.AddHandler(gateway.EventTypeReady, func(e gateway.EventReady) {
readyOnce.Do(func() {
client.ChannelID = account.ChannelID
client.GuildID = client.GetGuildID(account.ChannelID)
if client.GuildID == "" {
utils.Log(utils.Discord, utils.Error, client.SafeGetUsername(), fmt.Sprintf("Failed to fetch GuildID from channelID: %v", account.ChannelID))
guildID, err := client.GetGuildID(account.ChannelID)
if err != nil {
utils.Log(utils.Discord, utils.Error, client.SafeGetUsername(), fmt.Sprintf("Failed to fetch GuildID from channelID %v: %s", account.ChannelID, err.Error()))
in := &instance.Instance{
AccountCfg: account,
Error: "invalidChannelID",
Expand All @@ -45,6 +45,24 @@ func (d *DmgService) StartInstance(account config.AccountsConfig) {
utils.EmitEventIfNotCLI("instancesUpdate", d.GetInstances())
return
}
client.GuildID = guildID

err = client.Gateway.Send(d.ctx, gateway.GUILD_SUBSCRIPTIONS_BULK, gateway.MessageDataGuildSubscriptionsBulk{
Subscriptions: map[string]gateway.GuildSubscription{
client.GuildID: {
Typing: true,
Threads: false,
Activities: false,
Members: []int64{},
MemberUpdates: false,
Channels: map[string][][2]int{},
ThreadMemberLists: []int64{},
},
},
})
if err != nil {
utils.Log(utils.Important, utils.Error, client.SafeGetUsername(), fmt.Sprintf("Failed to send guild subscriptions bulk: %s", err.Error()))
}

commands, err := client.GetCommands(client.GuildID)
if err != nil {
Expand All @@ -62,7 +80,7 @@ func (d *DmgService) StartInstance(account config.AccountsConfig) {
User: client.Gateway.User(),
Client: client,
ChannelID: account.ChannelID,
GuildID: client.GetGuildID(account.ChannelID),
GuildID: client.GuildID,
Cfg: *d.cfg,
AccountCfg: account,
LastRan: make(map[string]time.Time),
Expand Down

0 comments on commit 3e1ad21

Please sign in to comment.