ottomate/main.go

187 lines
3.7 KiB
Go

package main
import (
"github.com/diamondburned/arikawa/discord"
"github.com/diamondburned/arikawa/gateway"
"github.com/diamondburned/arikawa/state"
log "github.com/sirupsen/logrus"
"github.com/spf13/viper"
"os"
"os/signal"
"strings"
"time"
)
var (
s *state.State
channels []discord.ChannelID
prohibitedPhrases []string
)
func setupConfiguration() {
viper.SetDefault("prohibitedPhrases", "")
viper.SetDefault("channels", "")
viper.SetDefault("message", "Hi {username}, you've posted a message that was automatically removed for matching a filter. If you need help, please use the correct channel.")
viper.AutomaticEnv()
viper.SetConfigName("ottomate")
viper.SetConfigType("yaml")
viper.AddConfigPath("/etc/ottomate/")
viper.AddConfigPath("$HOME/.ottomate")
viper.AddConfigPath(".")
viper.ReadInConfig()
}
func main() {
setupConfiguration()
var token = viper.GetString("token")
if token == "" {
log.Fatalln("Invalid token/token is not set")
}
var channelStrs []string
if viper.ConfigFileUsed() != "" {
channelStrs = viper.GetStringSlice("channels")
} else {
channelStrs = strings.Split(viper.GetString("channels"), ",")
}
channels = make([]discord.ChannelID, len(channelStrs))
for i, channelStr := range channelStrs {
sf, err := discord.ParseSnowflake(channelStr)
if err != nil {
continue
}
channels[i] = discord.ChannelID(sf)
}
if viper.ConfigFileUsed() != "" {
prohibitedPhrases = viper.GetStringSlice("phohibitedPhrases")
} else {
prohibitedPhrases = strings.Split(viper.GetString("prohibitedPhrases"), ",")
}
var err error
s, err = state.New("Bot " + token)
if err != nil {
log.WithError(err).Fatalln("Session failed")
}
s.AddHandler(messageCreate)
if err := s.Open(); err != nil {
log.WithError(err).Fatalln("Failed to connect")
}
defer s.Close()
u, err := s.Me()
if err != nil {
log.WithError(err).Fatalln("Failed to get myself")
}
log.WithField("username", u.Username).Info("Started bot")
ch := make(chan os.Signal)
signal.Notify(ch, os.Kill, os.Interrupt)
<-ch
}
func messageCreate(e *gateway.MessageCreateEvent) {
if e.Content == "" {
return
}
found := false
for _, channel := range channels {
if channel == e.ChannelID {
found = true
break
}
}
if !found {
return
}
found = false
for _, phrase := range prohibitedPhrases {
if strings.Contains(e.Content, phrase) {
// Send message
found = true
break
}
}
if !found {
return
}
member, err := s.Member(e.GuildID, e.Author.ID)
if err != nil || !member.Joined.IsValid() {
log.WithFields(log.Fields{
"guildId": e.GuildID,
"userId": e.Author.ID,
}).Debug("Unable to retrieve guild member")
return
}
joinTime := member.Joined.Time()
if joinTime.Before(time.Now().AddDate(0, 0, -7)) {
log.WithFields(log.Fields{
"guildId": e.GuildID,
"userId": e.Author.ID,
}).Debug("Join date below cutoff")
return
}
err = s.DeleteMessage(e.ChannelID, e.ID)
if err != nil {
log.WithFields(log.Fields{
"guildId": e.GuildID,
"userId": e.Author.ID,
"messageId": e.ID,
}).Debug("Unable to delete message")
return
}
ch, err := s.CreatePrivateChannel(e.Author.ID)
if err != nil {
log.WithFields(log.Fields{
"guildId": e.GuildID,
"userId": e.Author.ID,
}).Debug("Unable to create private channel with member")
return
}
message := viper.GetString("message")
replacer := strings.NewReplacer("{username}", e.Author.Username, "{message}", e.Content)
_, err = s.SendText(ch.ID, replacer.Replace(message))
if err != nil {
// Unable to send message
log.WithFields(log.Fields{
"guildId": e.GuildID,
"userId": e.Author.ID,
}).Debug("Unable to send message in private channel")
}
}