Skip to content

Commit

Permalink
feat: do not recreate Discord commands (#63)
Browse files Browse the repository at this point in the history
  • Loading branch information
freak12techno authored May 20, 2024
1 parent 29b4d40 commit 6a1e78f
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 11 deletions.
66 changes: 55 additions & 11 deletions pkg/reporters/discord/discord.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,32 @@ func (reporter *Reporter) InitCommands() {
return
}

for _, command := range registeredCommands {
wg.Add(1)
desiredCommands := utils.Map(
utils.MapToArray(reporter.Commands),
func(c *Command) *discordgo.ApplicationCommand { return c.Info },
)

commandsToAdd := utils.Subtract(desiredCommands, registeredCommands, func(v *discordgo.ApplicationCommand) string {
return v.Name
})

commandsToDelete := utils.Subtract(registeredCommands, desiredCommands, func(v *discordgo.ApplicationCommand) string {
return v.Name
})

commandsToUpdate := utils.Union(registeredCommands, desiredCommands, func(v *discordgo.ApplicationCommand) string {
return v.Name
})

reporter.Logger.Info().
Int("commands_to_add", len(commandsToAdd)).
Int("commands_to_delete", len(commandsToDelete)).
Int("commands_to_update", len(commandsToUpdate)).
Msg("Updating Discord slash commands")

wg.Add(len(commandsToAdd) + len(commandsToDelete) + len(commandsToUpdate))

for _, command := range commandsToDelete {
go func(command *discordgo.ApplicationCommand) {
defer wg.Done()

Expand All @@ -131,27 +155,47 @@ func (reporter *Reporter) InitCommands() {
}(command)
}

wg.Wait()

for key, command := range reporter.Commands {
wg.Add(1)
go func(key string, command *Command) {
for _, command := range commandsToAdd {
go func(command *discordgo.ApplicationCommand) {
defer wg.Done()

cmd, err := session.ApplicationCommandCreate(session.State.User.ID, reporter.Guild, command.Info)
cmd, err := session.ApplicationCommandCreate(session.State.User.ID, reporter.Guild, command)
if err != nil {
reporter.Logger.Error().Err(err).Str("command", command.Info.Name).Msg("Could not create command")
reporter.Logger.Error().Err(err).Str("command", command.Name).Msg("Could not create command")
return
}
reporter.Logger.Info().Str("command", cmd.Name).Msg("Created command")

mutex.Lock()
reporter.Commands[key].Info = cmd
reporter.Commands[command.Name].Info = cmd
mutex.Unlock()
}(key, command)
}(command)
}

for _, command := range commandsToUpdate {
go func(command *discordgo.ApplicationCommand) {
defer wg.Done()

cmd, err := session.ApplicationCommandEdit(
session.State.User.ID,
reporter.Guild,
command.ID,
command,
)
if err != nil {
reporter.Logger.Error().Err(err).Str("command", command.Name).Msg("Could not update command")
return
}
reporter.Logger.Info().Str("command", cmd.Name).Msg("Updated command")

mutex.Lock()
reporter.Commands[command.Name].Info = cmd
mutex.Unlock()
}(command)
}

wg.Wait()
reporter.Logger.Info().Msg("All commands updated")
}

func (reporter *Reporter) Enabled() bool {
Expand Down
51 changes: 51 additions & 0 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,57 @@ func Find[T any](slice []T, f func(T) bool) (T, bool) {
return *new(T), false
}

func Subtract[T any, C comparable](first, second []T, predicate func(T) C) []T {
valuesMap := make(map[C]bool, len(second))
for _, value := range second {
valuesMap[predicate(value)] = true
}

newSlice := make([]T, 0)

for _, value := range first {
predicateResult := predicate(value)
_, ok := valuesMap[predicateResult]
if !ok {
newSlice = append(newSlice, value)
}
}

return newSlice
}

func Union[T any, C comparable](first, second []T, predicate func(T) C) []T {
valuesMap := make(map[C]bool, len(second))
for _, value := range second {
valuesMap[predicate(value)] = true
}

newSlice := make([]T, 0)

for _, value := range first {
predicateResult := predicate(value)
_, ok := valuesMap[predicateResult]
if ok {
newSlice = append(newSlice, value)
}
}

return newSlice
}

func MapToArray[K comparable, T any](source map[K]T) []T {
newSlice := make([]T, len(source))

index := 0

for _, value := range source {
newSlice[index] = value
index++
}

return newSlice
}

func SplitStringIntoChunks(msg string, maxLineLength int) []string {
msgsByNewline := strings.Split(msg, "\n")
outMessages := []string{}
Expand Down
63 changes: 63 additions & 0 deletions pkg/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,66 @@ func TestMinInt64(t *testing.T) {
assert.Equal(t, int64(1), MinInt64(1, 2), "Value mismatch!")
assert.Equal(t, int64(1), MinInt64(2, 1), "Value mismatch!")
}

func TestSubtract(t *testing.T) {
t.Parallel()

type TestStruct struct {
Value string
}

first := []TestStruct{
{Value: "1"},
{Value: "2"},
{Value: "3"},
}

second := []TestStruct{
{Value: "2"},
{Value: "4"},
}

result := Subtract(first, second, func(v TestStruct) any { return v.Value })
assert.Len(t, result, 2)
assert.Equal(t, "1", result[0].Value)
assert.Equal(t, "3", result[1].Value)
}

func TestUnion(t *testing.T) {
t.Parallel()

type TestStruct struct {
Value string
}

first := []TestStruct{
{Value: "1"},
{Value: "2"},
{Value: "3"},
}

second := []TestStruct{
{Value: "2"},
{Value: "4"},
}

result := Union(first, second, func(v TestStruct) any { return v.Value })
assert.Len(t, result, 1)
assert.Equal(t, "2", result[0].Value)
}

func TestMapToArray(t *testing.T) {
t.Parallel()

testMap := map[string]string{
"test1": "1",
"test2": "2",
"test3": "3",
}

result := MapToArray(testMap)
assert.Len(t, result, 3)
assert.Equal(t, "1", result[0])
assert.Equal(t, "2", result[1])
assert.Equal(t, "3", result[2])
}

0 comments on commit 6a1e78f

Please sign in to comment.