github.com/starshine-sys/bcr@v0.21.0/slash.go (about) 1 package bcr 2 3 import ( 4 "strings" 5 6 "github.com/diamondburned/arikawa/v3/discord" 7 "github.com/starshine-sys/snowflake/v2" 8 ) 9 10 // SyncCommands syncs slash commands in the given guilds. 11 // If no guilds are given, slash commands are synced globally. 12 // Router.Bot *must* be set before calling this function or it will panic! 13 func (r *Router) SyncCommands(guildIDs ...discord.GuildID) (err error) { 14 r.cmdMu.Lock() 15 cmds := []*Command{} 16 for _, cmd := range r.cmds { 17 if cmd.Options != nil && !inCmds(cmds, cmd.id) { 18 cmds = append(cmds, cmd) 19 } 20 } 21 r.cmdMu.Unlock() 22 23 slashCmds := []discord.Command{} 24 for _, cmd := range cmds { 25 slashCmds = append(slashCmds, discord.Command{ 26 Name: strings.ToLower(cmd.Name), 27 Description: cmd.Summary, 28 Options: *cmd.Options, 29 }) 30 } 31 for _, g := range r.slashGroups { 32 slashCmds = append(slashCmds, g.Command()) 33 } 34 35 if len(guildIDs) > 0 { 36 return r.syncCommandsIn(slashCmds, guildIDs) 37 } 38 return r.syncCommandsGlobal(slashCmds) 39 } 40 41 func inCmds(cmds []*Command, id snowflake.ID) bool { 42 for _, cmd := range cmds { 43 if cmd.id == id { 44 return true 45 } 46 } 47 return false 48 } 49 50 func (r *Router) syncCommandsGlobal(cmds []discord.Command) (err error) { 51 appID := discord.AppID(r.Bot.ID) 52 s, _ := r.StateFromGuildID(0) 53 54 deleted := []discord.CommandID{} 55 current, err := s.Commands(appID) 56 if err != nil { 57 return err 58 } 59 60 for _, c := range current { 61 if !in(cmds, c.Name) { 62 deleted = append(deleted, c.ID) 63 } 64 } 65 66 for _, id := range deleted { 67 err = s.DeleteCommand(appID, id) 68 if err != nil { 69 return err 70 } 71 } 72 73 _, err = s.BulkOverwriteCommands(appID, cmds) 74 return 75 } 76 77 func in(cmds []discord.Command, name string) bool { 78 for _, cmd := range cmds { 79 if cmd.Name == name { 80 return true 81 } 82 } 83 return false 84 } 85 86 func (r *Router) syncCommandsIn(cmds []discord.Command, guildIDs []discord.GuildID) (err error) { 87 appID := discord.AppID(r.Bot.ID) 88 89 for _, guild := range guildIDs { 90 s, _ := r.StateFromGuildID(guild) 91 92 deleted := []discord.CommandID{} 93 current, err := s.GuildCommands(appID, guild) 94 if err != nil { 95 return err 96 } 97 98 for _, c := range current { 99 if !in(cmds, c.Name) { 100 deleted = append(deleted, c.ID) 101 } 102 } 103 104 for _, id := range deleted { 105 err = s.DeleteGuildCommand(appID, guild, id) 106 if err != nil { 107 return err 108 } 109 } 110 111 _, err = s.BulkOverwriteGuildCommands(appID, guild, cmds) 112 if err != nil { 113 return err 114 } 115 } 116 117 return 118 }