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  }