diff options
| -rw-r--r-- | go.mod | 5 | ||||
| -rw-r--r-- | go.sum | 6 | ||||
| -rw-r--r-- | main.go | 143 |
3 files changed, 154 insertions, 0 deletions
@@ -0,0 +1,5 @@ +module git.uakci.pl/misc/uniqueglish + +go 1.16 + +require github.com/bwmarrin/discordgo v0.23.2 @@ -0,0 +1,6 @@ +github.com/bwmarrin/discordgo v0.23.2 h1:BzrtTktixGHIu9Tt7dEE6diysEF9HWnXeHuoJEt2fH4= +github.com/bwmarrin/discordgo v0.23.2/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M= +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16 h1:y6ce7gCWtnH+m3dCjzQ1PCuwl28DDIc3VNnvY29DlIA= +golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -0,0 +1,143 @@ +package main + +import ( + "github.com/bwmarrin/discordgo" + "sync" + "os" + "os/signal" + "fmt" + "regexp" + "strings" +) + +var ( + WORD_REGEX = regexp.MustCompile(`[a-z'’]+`) + mu = sync.RWMutex{} + words = map[string]struct{}{} + channel string +) + +func getWords(m *discordgo.Message) []string { + result := WORD_REGEX.FindAllString(strings.ToLower(m.Content), -1) + return result +} + +func add(m *discordgo.Message) { + if m.ChannelID != channel || m.Author.Bot { + return + } + mu.Lock() + for _, word := range getWords(m) { + words[word] = struct{}{} + } + mu.Unlock() +} + +func report() { + mu.RLock() + fmt.Printf("at %d words now\n", len(words)) + mu.RUnlock() +} + +func confer(s *discordgo.Session, m *discordgo.Message) { + if m.ChannelID != channel || m.Author.Bot { + return + } + mu.RLock() + abominable := []string{} + for _, word := range getWords(m) { + if _, ok := words[word]; ok { + abominable = append(abominable, word) + } + } + mu.RUnlock() + if len(abominable) > 0 { + builder := strings.Builder{} + for i, abomination := range abominable { + if i > 0 { + builder.WriteString(", ") + } + fmt.Fprintf(&builder, "**%s**", abomination) + } + _, e := s.ChannelMessageSendReply(m.ChannelID, builder.String(), m.Reference()) + yell(e) + } +} + +func must(e error) { + if e != nil { + panic(e) + } +} + +func yell(e error) { + if e != nil { + fmt.Fprintln(os.Stderr, e) + } +} + +func respond(session *discordgo.Session, message *discordgo.Message) { + switch message.Type { + case discordgo.MessageTypeDefault, discordgo.MessageTypeReply: + confer(session, message) + go func() { + add(message) + report() + }() + } +} + +func main() { + var ok bool + channel, ok = os.LookupEnv("CHANNEL") + if !ok { + panic(ok) + } + session, e := discordgo.New(fmt.Sprintf("Bot %s", os.Getenv("TOKEN"))) + must(e) + + session.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) { + respond(s, m.Message) + }) + + session.AddHandler(func(s *discordgo.Session, m *discordgo.MessageUpdate) { + respond(s, m.Message) + }) + + must(session.Open()) + var ( + last string + count = 0 + ) + for { + got, e := session.ChannelMessages(channel, 100, last, "", "") + if e != nil { + yell(e) + continue + } + if len(got) == 0 { + break + } + last = got[len(got)-1].ID + count += len(got) + fmt.Printf("msgs: %d >= %s\n", count, last) + go func() { + for _, m := range got { + add(m) + } + report() + }() + } + fmt.Printf("done! (%d msgs)\n", count) + mu.RLock() + for k := range words { + fmt.Printf("%s ", k) + } + fmt.Println() + mu.RUnlock() + + broken := make(chan os.Signal, 1) + signal.Notify(broken, os.Interrupt, os.Kill) + <-broken + must(session.Close()) +} |
