From ddfa449a307f31b9563f57a53aba67a2010c4833 Mon Sep 17 00:00:00 2001 From: Etzelia Date: Fri, 12 Jun 2020 00:17:58 -0500 Subject: [PATCH] Re-format feedback vs errors and polish commands. Add message role functionality Signed-off-by: Etzelia --- config/config.go | 1 + discord/clear.go | 11 ++++---- discord/discord.go | 63 ++++++++++++++++++++++++++++++++++++--------- discord/fired.go | 7 +++-- discord/help.go | 5 ++-- discord/inspire.go | 7 +++-- discord/links.go | 19 ++++++-------- discord/register.go | 27 +++++++++---------- sedbot.example.toml | 3 ++- 9 files changed, 89 insertions(+), 54 deletions(-) diff --git a/config/config.go b/config/config.go index 20d2246..d3843a9 100644 --- a/config/config.go +++ b/config/config.go @@ -25,6 +25,7 @@ type Config struct { } type MessageRole struct { + ChannelID string `toml:"channel_id"` MessageID string `toml:"message_id"` RoleID string `toml:"role_id"` Emoji string `toml:"emoji"` diff --git a/discord/clear.go b/discord/clear.go index fa7592a..d549868 100644 --- a/discord/clear.go +++ b/discord/clear.go @@ -1,7 +1,6 @@ package discord import ( - "errors" "strconv" "strings" ) @@ -13,7 +12,7 @@ func init() { validate: func(cmd commandInit) bool { return isStaff(cmd.message.Member.Roles, cmd.config.StaffRoles) }, - run: func(cmd commandInit) error { + run: func(cmd commandInit) (string, error) { args := strings.Fields(cmd.message.Content) var userID string @@ -25,15 +24,15 @@ func init() { if userID != "" { limitArg = 2 if len(args) < 2 { - return errors.New("this command takes needs two arguments with a mention") + return "This command takes needs two arguments with a mention", nil } } else if len(args) < 1 { - return errors.New("this command takes one argument without a mention") + return "This command takes one argument without a mention", nil } limit, err := strconv.Atoi(args[limitArg]) if err != nil { - return err + return "", err } if limit < 0 { @@ -62,7 +61,7 @@ func init() { } } - return cmd.session.ChannelMessagesBulkDelete(cmd.message.ChannelID, batch) + return "", cmd.session.ChannelMessagesBulkDelete(cmd.message.ChannelID, batch) }, help: "Clear messages", } diff --git a/discord/discord.go b/discord/discord.go index a6fd265..e6f9cd3 100644 --- a/discord/discord.go +++ b/discord/discord.go @@ -11,7 +11,10 @@ import ( ) // Register commands to this map -var commands = make(map[string]command) +var ( + commands = make(map[string]command) + messageRoleMap = make(map[string]map[string]string) +) type commandInit struct { session *discordgo.Session @@ -22,7 +25,7 @@ type commandInit struct { type command struct { validate func(cmd commandInit) bool - run func(cmd commandInit) error + run func(cmd commandInit) (string, error) help string } @@ -32,10 +35,19 @@ func Bot(cfg *config.Config, db *database.Database) (*discordgo.Session, error) return nil, err } - Links(cfg) + for _, messageRole := range cfg.MessageRoles { + if messageRoleMap[messageRole.MessageID] == nil { + messageRoleMap[messageRole.MessageID] = make(map[string]string) + } + _ = bot.MessageReactionAdd(messageRole.ChannelID, messageRole.MessageID, messageRole.Emoji) + messageRoleMap[messageRole.MessageID][messageRole.Emoji] = messageRole.RoleID + } + Links(cfg) bot.AddHandler(commandHandler(cfg, db)) bot.AddHandler(messageHandler(cfg, db)) + bot.AddHandler(reactionAddHandler()) + bot.AddHandler(reactionRemoveHandler()) beaver.Info("https://discord.com/api/oauth2/authorize?client_id=718905104643784825&permissions=0&redirect_uri=https%3A%2F%2Fbirbmc.com&scope=bot") @@ -87,15 +99,9 @@ func commandHandler(cfg *config.Config, db *database.Database) func(s *discordgo } cmdArg := strings.ToLower(args[0]) - isHelp := strings.EqualFold(cmdArg, "help") cmd, ok := commands[cmdArg] - if !ok && !isHelp { - return - } - - if isHelp { - sendMessage(s, m.ChannelID, cmd.help) + if !ok { return } @@ -109,8 +115,13 @@ func commandHandler(cfg *config.Config, db *database.Database) func(s *discordgo sendMessage(s, m.ChannelID, "You cannot run this command.") return } - if err := cmd.run(cmdInit); err != nil { - sendMessage(s, m.ChannelID, err.Error()) + feedback, err := cmd.run(cmdInit) + if err != nil { + feedback = "Internal error" + beaver.Errorf("error while running %s: %v", cmdArg, err) + } + if len(feedback) > 0 { + sendMessage(s, m.ChannelID, feedback) } } } @@ -132,3 +143,31 @@ func messageHandler(cfg *config.Config, db *database.Database) func(s *discordgo } } } + +func reactionAddHandler() func(s *discordgo.Session, m *discordgo.MessageReactionAdd) { + return func(s *discordgo.Session, m *discordgo.MessageReactionAdd) { + reactionHandler(true, s, m.MessageReaction) + } +} + +func reactionRemoveHandler() func(s *discordgo.Session, m *discordgo.MessageReactionRemove) { + return func(s *discordgo.Session, m *discordgo.MessageReactionRemove) { + reactionHandler(false, s, m.MessageReaction) + } +} + +func reactionHandler(add bool, s *discordgo.Session, m *discordgo.MessageReaction) { + if _, ok := messageRoleMap[m.MessageID]; ok { + if r, ok := messageRoleMap[m.MessageID][m.Emoji.Name]; ok { + var roleCmd func(guildID, userID, roleID string) (err error) + if add { + roleCmd = s.GuildMemberRoleAdd + } else { + roleCmd = s.GuildMemberRoleRemove + } + if err := roleCmd(m.GuildID, m.UserID, r); err != nil { + beaver.Errorf("could not modify role %s for user %s", r, m.UserID) + } + } + } +} diff --git a/discord/fired.go b/discord/fired.go index e85b11b..7247018 100644 --- a/discord/fired.go +++ b/discord/fired.go @@ -9,10 +9,9 @@ func init() { validate: func(cmd commandInit) bool { return true }, - run: func(cmd commandInit) error { - sendMessage(cmd.session, cmd.message.ChannelID, fmt.Sprintf("Carolyn has been fired **%d** times!", - cmd.database.CheckPing(cmd.config.FiredRole))) - return nil + run: func(cmd commandInit) (string, error) { + return fmt.Sprintf("Carolyn has been fired **%d** times!", + cmd.database.CheckPing(cmd.config.FiredRole)), nil }, help: "Check how many times Carolyn has been fired.", } diff --git a/discord/help.go b/discord/help.go index 5d50e1b..cc7170a 100644 --- a/discord/help.go +++ b/discord/help.go @@ -10,7 +10,7 @@ func init() { validate: func(cmd commandInit) bool { return true }, - run: func(cmd commandInit) error { + run: func(cmd commandInit) (string, error) { args := strings.Fields(cmd.message.Content)[1:] var resp string @@ -19,8 +19,7 @@ func init() { } else { resp = allHelp() } - sendMessage(cmd.session, cmd.message.ChannelID, resp) - return nil + return resp, nil }, help: "HELP! HEEEEEEEEEELP!", } diff --git a/discord/inspire.go b/discord/inspire.go index 9f2c06f..0772bcd 100644 --- a/discord/inspire.go +++ b/discord/inspire.go @@ -7,16 +7,15 @@ func init() { validate: func(cmd commandInit) bool { return true }, - run: func(cmd commandInit) error { + run: func(cmd commandInit) (string, error) { sendTyping(cmd.session, cmd.message.ChannelID) img, err := inspiro.Generate() if err != nil { - return err + return "", err } - sendMessage(cmd.session, cmd.message.ChannelID, img) - return nil + return img, nil }, help: "Get inspired!", } diff --git a/discord/links.go b/discord/links.go index d8241ff..6a487ca 100644 --- a/discord/links.go +++ b/discord/links.go @@ -14,25 +14,23 @@ func Links(cfg *config.Config) { validate: func(cmd commandInit) bool { return true }, - run: func(cmd commandInit) error { - sendMessage(cmd.session, cmd.message.ChannelID, fmt.Sprintf("<%s>", link.URL)) - return nil + run: func(cmd commandInit) (string, error) { + return fmt.Sprintf("<%s>", link.URL), nil }, help: fmt.Sprintf("Returns the link for %s", link.Name), } - links = append(links, fmt.Sprintf("%s -> %s", link.Name, link.URL)) + links = append(links, fmt.Sprintf("%s -> <%s>", link.Name, link.URL)) for _, alias := range link.Aliases { commands[alias] = command{ validate: func(cmd commandInit) bool { return true }, - run: func(cmd commandInit) error { - sendMessage(cmd.session, cmd.message.ChannelID, fmt.Sprintf("<%s>", link.URL)) - return nil + run: func(cmd commandInit) (string, error) { + return fmt.Sprintf("<%s>", link.URL), nil }, help: fmt.Sprintf("Returns the link for %s", alias), } - links = append(links, fmt.Sprintf("%s -> %s", alias, link.URL)) + links = append(links, fmt.Sprintf("%s -> <%s>", alias, link.URL)) } } @@ -40,9 +38,8 @@ func Links(cfg *config.Config) { validate: func(cmd commandInit) bool { return true }, - run: func(cmd commandInit) error { - sendMessage(cmd.session, cmd.message.ChannelID, strings.Join(links, "\n")) - return nil + run: func(cmd commandInit) (string, error) { + return strings.Join(links, "\n"), nil }, help: "Get all dynamic links", } diff --git a/discord/register.go b/discord/register.go index b4e0895..1d79152 100644 --- a/discord/register.go +++ b/discord/register.go @@ -1,7 +1,6 @@ package discord import ( - "errors" "fmt" "strings" @@ -14,10 +13,10 @@ func init() { validate: func(cmd commandInit) bool { return len(cmd.message.Member.Roles) == 0 }, - run: func(cmd commandInit) error { + run: func(cmd commandInit) (string, error) { args := strings.Fields(cmd.message.Content) if len(args) < 2 { - return errors.New("you must give this command your application username") + return "You must give this command your application username", nil } sendTyping(cmd.session, cmd.message.ChannelID) @@ -27,12 +26,12 @@ func init() { players, err := models.Player(models.NewDjangoBuilder().IExact(django.PlayerUsername, args[1])) if err != nil { - return err + return "", err } apps, err := models.Application(models.NewDjangoBuilder().IExact(django.ApplicationUsername, args[1])) if err != nil { - return err + return "", err } var nickname string @@ -42,33 +41,35 @@ func init() { if len(apps) == 0 { apps, err = models.Application(models.NewDjangoBuilder().Eq(django.ApplicationID, players[0].ApplicationID)) if len(apps) == 0 { - return errors.New("something went wrong, please contact staff") + return "Something went wrong, please contact staff", nil } } } else if len(apps) > 0 { if apps[0].Accepted != nil && *apps[0].Accepted { - return errors.New("please join the server and then re-try this command") + return "Please join the server and then re-try this command", nil } } else { - return errors.New("no player or applications found for that username") + return "No player or applications found for that username", nil } accepted = apps[0].Accepted if accepted == nil { - return errors.New("your application is still being reviewed, hang tight") + return "Your application is still being reviewed, hang tight", nil } else if !*accepted { - return errors.New("your application was denied, good luck finding a new server") + return "Your application was denied, good luck finding a new server", nil } // Accepted if err := cmd.session.GuildMemberNickname(cmd.message.GuildID, cmd.message.Author.ID, nickname); err != nil { - return err + return "", err } if err := cmd.session.GuildMemberRoleAdd(cmd.message.GuildID, cmd.message.Author.ID, cmd.config.RegisterRole); err != nil { - return err + return "", err } + + // Don't return feedback because this goes in a different channel sendMessage(cmd.session, cmd.config.RegisteredChannel, fmt.Sprintf("Welcome, **%s**!", cmd.message.Author.Mention())) - return nil + return "", nil }, help: "Register yourself with the Discord", } diff --git a/sedbot.example.toml b/sedbot.example.toml index 0a05dfe..6e83c34 100644 --- a/sedbot.example.toml +++ b/sedbot.example.toml @@ -7,7 +7,7 @@ prefix = "!" # mcm_token is the token for the MCM API mcm_token = "" -# mcm_url is the base URL to MCM +# mcm_url is the base URL to the MCM API mcm_url = "" # db_path is the path to the database (default is next to binary) @@ -33,6 +33,7 @@ url = "https://birbmc.com/discord" # message_roles are for messages that should toggle a role when a user selects it [[message_roles]] +channel_id = "0" message_id = "0" role_id = "0" emoji = "thumbsup" \ No newline at end of file