diff --git a/discord/commands/handler.go b/discord/commands/handler.go index 0834d6c..79404f5 100644 --- a/discord/commands/handler.go +++ b/discord/commands/handler.go @@ -123,6 +123,8 @@ func OnDiscordMessage(s *discordgo.Session, m *discordgo.MessageCreate) { Archive(args, s, m) case "unarchive": Unarchive(args, s, m) + case "say": + Say(args, s, m) default: logger.SugarLogger.Infof("Unknown command: %s", command) } diff --git a/discord/commands/say.go b/discord/commands/say.go new file mode 100644 index 0000000..ec0ff77 --- /dev/null +++ b/discord/commands/say.go @@ -0,0 +1,32 @@ +package commands + +import ( + "fmt" + "strings" + + "github.com/bwmarrin/discordgo" + "github.com/gaucho-racing/sentinel/discord/config" + "github.com/gaucho-racing/sentinel/discord/pkg/logger" + "github.com/gaucho-racing/sentinel/discord/service" +) + +// Say reposts a message as the bot, so announcements come from Sentinel +// rather than whoever typed them. The command message is always deleted, +// including when access is denied, so a failed attempt doesn't linger. +func Say(args []string, s *discordgo.Session, m *discordgo.MessageCreate) { + defer s.ChannelMessageDelete(m.ChannelID, m.ID) + if !requireGroupMembership(m, "say", []string{"Admins", "DevopsMembers"}) { + return + } + // Cut from the raw content rather than joining args, so line breaks and + // spacing in the announcement survive. + message := strings.TrimSpace(strings.TrimPrefix(m.Content, config.DiscordPrefix+"say")) + if message == "" { + service.SendDisappearingMessage(m.ChannelID, fmt.Sprintf("<@%s> usage: `%ssay `", m.Author.ID, config.DiscordPrefix), commandReplyTTL) + return + } + if _, err := s.ChannelMessageSend(m.ChannelID, message); err != nil { + logger.SugarLogger.Errorf("say: failed to send in %s: %v", m.ChannelID, err) + service.SendDisappearingMessage(m.ChannelID, fmt.Sprintf("<@%s> couldn't send that message — check the logs.", m.Author.ID), commandReplyTTL) + } +}