Re-format feedback vs errors and polish commands. Add message role functionality

Signed-off-by: Etzelia <etzelia@hotmail.com>
rate-insult
Etzelia 2020-06-12 00:17:58 -05:00
parent 704373c5cd
commit ddfa449a30
No known key found for this signature in database
GPG Key ID: 708511AE7ABC5314
9 changed files with 89 additions and 54 deletions

View File

@ -25,6 +25,7 @@ type Config struct {
} }
type MessageRole struct { type MessageRole struct {
ChannelID string `toml:"channel_id"`
MessageID string `toml:"message_id"` MessageID string `toml:"message_id"`
RoleID string `toml:"role_id"` RoleID string `toml:"role_id"`
Emoji string `toml:"emoji"` Emoji string `toml:"emoji"`

View File

@ -1,7 +1,6 @@
package discord package discord
import ( import (
"errors"
"strconv" "strconv"
"strings" "strings"
) )
@ -13,7 +12,7 @@ func init() {
validate: func(cmd commandInit) bool { validate: func(cmd commandInit) bool {
return isStaff(cmd.message.Member.Roles, cmd.config.StaffRoles) 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) args := strings.Fields(cmd.message.Content)
var userID string var userID string
@ -25,15 +24,15 @@ func init() {
if userID != "" { if userID != "" {
limitArg = 2 limitArg = 2
if len(args) < 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 { } 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]) limit, err := strconv.Atoi(args[limitArg])
if err != nil { if err != nil {
return err return "", err
} }
if limit < 0 { 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", help: "Clear messages",
} }

View File

@ -11,7 +11,10 @@ import (
) )
// Register commands to this map // 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 { type commandInit struct {
session *discordgo.Session session *discordgo.Session
@ -22,7 +25,7 @@ type commandInit struct {
type command struct { type command struct {
validate func(cmd commandInit) bool validate func(cmd commandInit) bool
run func(cmd commandInit) error run func(cmd commandInit) (string, error)
help string help string
} }
@ -32,10 +35,19 @@ func Bot(cfg *config.Config, db *database.Database) (*discordgo.Session, error)
return nil, err 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(commandHandler(cfg, db))
bot.AddHandler(messageHandler(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") 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]) cmdArg := strings.ToLower(args[0])
isHelp := strings.EqualFold(cmdArg, "help")
cmd, ok := commands[cmdArg] cmd, ok := commands[cmdArg]
if !ok && !isHelp { if !ok {
return
}
if isHelp {
sendMessage(s, m.ChannelID, cmd.help)
return 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.") sendMessage(s, m.ChannelID, "You cannot run this command.")
return return
} }
if err := cmd.run(cmdInit); err != nil { feedback, err := cmd.run(cmdInit)
sendMessage(s, m.ChannelID, err.Error()) 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)
}
}
}
}

View File

@ -9,10 +9,9 @@ func init() {
validate: func(cmd commandInit) bool { validate: func(cmd commandInit) bool {
return true return true
}, },
run: func(cmd commandInit) error { run: func(cmd commandInit) (string, error) {
sendMessage(cmd.session, cmd.message.ChannelID, fmt.Sprintf("Carolyn has been fired **%d** times!", return fmt.Sprintf("Carolyn has been fired **%d** times!",
cmd.database.CheckPing(cmd.config.FiredRole))) cmd.database.CheckPing(cmd.config.FiredRole)), nil
return nil
}, },
help: "Check how many times Carolyn has been fired.", help: "Check how many times Carolyn has been fired.",
} }

View File

@ -10,7 +10,7 @@ func init() {
validate: func(cmd commandInit) bool { validate: func(cmd commandInit) bool {
return true return true
}, },
run: func(cmd commandInit) error { run: func(cmd commandInit) (string, error) {
args := strings.Fields(cmd.message.Content)[1:] args := strings.Fields(cmd.message.Content)[1:]
var resp string var resp string
@ -19,8 +19,7 @@ func init() {
} else { } else {
resp = allHelp() resp = allHelp()
} }
sendMessage(cmd.session, cmd.message.ChannelID, resp) return resp, nil
return nil
}, },
help: "HELP! HEEEEEEEEEELP!", help: "HELP! HEEEEEEEEEELP!",
} }

View File

@ -7,16 +7,15 @@ func init() {
validate: func(cmd commandInit) bool { validate: func(cmd commandInit) bool {
return true return true
}, },
run: func(cmd commandInit) error { run: func(cmd commandInit) (string, error) {
sendTyping(cmd.session, cmd.message.ChannelID) sendTyping(cmd.session, cmd.message.ChannelID)
img, err := inspiro.Generate() img, err := inspiro.Generate()
if err != nil { if err != nil {
return err return "", err
} }
sendMessage(cmd.session, cmd.message.ChannelID, img) return img, nil
return nil
}, },
help: "Get inspired!", help: "Get inspired!",
} }

View File

@ -14,25 +14,23 @@ func Links(cfg *config.Config) {
validate: func(cmd commandInit) bool { validate: func(cmd commandInit) bool {
return true return true
}, },
run: func(cmd commandInit) error { run: func(cmd commandInit) (string, error) {
sendMessage(cmd.session, cmd.message.ChannelID, fmt.Sprintf("<%s>", link.URL)) return fmt.Sprintf("<%s>", link.URL), nil
return nil
}, },
help: fmt.Sprintf("Returns the link for %s", link.Name), 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 { for _, alias := range link.Aliases {
commands[alias] = command{ commands[alias] = command{
validate: func(cmd commandInit) bool { validate: func(cmd commandInit) bool {
return true return true
}, },
run: func(cmd commandInit) error { run: func(cmd commandInit) (string, error) {
sendMessage(cmd.session, cmd.message.ChannelID, fmt.Sprintf("<%s>", link.URL)) return fmt.Sprintf("<%s>", link.URL), nil
return nil
}, },
help: fmt.Sprintf("Returns the link for %s", alias), 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 { validate: func(cmd commandInit) bool {
return true return true
}, },
run: func(cmd commandInit) error { run: func(cmd commandInit) (string, error) {
sendMessage(cmd.session, cmd.message.ChannelID, strings.Join(links, "\n")) return strings.Join(links, "\n"), nil
return nil
}, },
help: "Get all dynamic links", help: "Get all dynamic links",
} }

View File

@ -1,7 +1,6 @@
package discord package discord
import ( import (
"errors"
"fmt" "fmt"
"strings" "strings"
@ -14,10 +13,10 @@ func init() {
validate: func(cmd commandInit) bool { validate: func(cmd commandInit) bool {
return len(cmd.message.Member.Roles) == 0 return len(cmd.message.Member.Roles) == 0
}, },
run: func(cmd commandInit) error { run: func(cmd commandInit) (string, error) {
args := strings.Fields(cmd.message.Content) args := strings.Fields(cmd.message.Content)
if len(args) < 2 { 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) sendTyping(cmd.session, cmd.message.ChannelID)
@ -27,12 +26,12 @@ func init() {
players, err := models.Player(models.NewDjangoBuilder().IExact(django.PlayerUsername, args[1])) players, err := models.Player(models.NewDjangoBuilder().IExact(django.PlayerUsername, args[1]))
if err != nil { if err != nil {
return err return "", err
} }
apps, err := models.Application(models.NewDjangoBuilder().IExact(django.ApplicationUsername, args[1])) apps, err := models.Application(models.NewDjangoBuilder().IExact(django.ApplicationUsername, args[1]))
if err != nil { if err != nil {
return err return "", err
} }
var nickname string var nickname string
@ -42,33 +41,35 @@ func init() {
if len(apps) == 0 { if len(apps) == 0 {
apps, err = models.Application(models.NewDjangoBuilder().Eq(django.ApplicationID, players[0].ApplicationID)) apps, err = models.Application(models.NewDjangoBuilder().Eq(django.ApplicationID, players[0].ApplicationID))
if len(apps) == 0 { 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 { } else if len(apps) > 0 {
if apps[0].Accepted != nil && *apps[0].Accepted { 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 { } 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 accepted = apps[0].Accepted
if accepted == nil { 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 { } 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 // Accepted
if err := cmd.session.GuildMemberNickname(cmd.message.GuildID, cmd.message.Author.ID, nickname); err != nil { 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 { 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())) sendMessage(cmd.session, cmd.config.RegisteredChannel, fmt.Sprintf("Welcome, **%s**!", cmd.message.Author.Mention()))
return nil return "", nil
}, },
help: "Register yourself with the Discord", help: "Register yourself with the Discord",
} }

View File

@ -7,7 +7,7 @@ prefix = "!"
# mcm_token is the token for the MCM API # mcm_token is the token for the MCM API
mcm_token = "" mcm_token = ""
# mcm_url is the base URL to MCM # mcm_url is the base URL to the MCM API
mcm_url = "" mcm_url = ""
# db_path is the path to the database (default is next to binary) # 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 are for messages that should toggle a role when a user selects it
[[message_roles]] [[message_roles]]
channel_id = "0"
message_id = "0" message_id = "0"
role_id = "0" role_id = "0"
emoji = "thumbsup" emoji = "thumbsup"