This repository has been archived on 2019-11-22. You can view files and clone it, but cannot push or open issues or pull requests.
aocbot/aocbot.go

174 lines
4.3 KiB
Go

package main
import (
"encoding/json"
"fmt"
"os"
"time"
"gogs.bullercodeworks.com/brian/boltease"
)
const programName = "aocbot"
// Message Processors are interfaces for interacting.
type messageProcessor interface {
GetName() string
GetHelp() string
ProcessMessage(s *Slack, m *Message)
ProcessAdminMessage(s *Slack, m *Message)
ProcessBotMessage(s *Slack, m *Message)
ProcessUserMessage(s *Slack, m *Message)
ProcessAdminUserMessage(s *Slack, m *Message)
ProcessBotUserMessage(s *Slack, m *Message)
ProcessChannelMessage(s *Slack, m *Message)
ProcessAdminChannelMessage(s *Slack, m *Message)
ProcessBotChannelMessage(s *Slack, m *Message)
}
var messageProcessors []messageProcessor
// Message Processors are interfaces for accumulating statistics.
type statProcessor interface {
GetName() string
GetStatKeys() []string
Initialize()
ProcessMessage(m *Message)
ProcessBotMessage(m *Message)
ProcessUserMessage(m *Message)
ProcessBotUserMessage(m *Message)
ProcessChannelMessage(m *Message)
ProcessBotChannelMessage(m *Message)
}
var statProcessors []statProcessor
var db *boltease.DB
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "usage: "+programName+" <slack-bot-token>\n")
os.Exit(1)
}
var err error
var slack *Slack
if db, err = getDatabase(); err != nil {
panic(err)
}
if slack, err = CreateSlack(os.Args[1]); err != nil {
panic(err)
}
statBotMain(slack)
}
// This is the main function for the statbot
func statBotMain(slack *Slack) {
// start a websocket-based Real Time API session
registerMessageProcessor(new(generalProcessor))
fmt.Println("aoc-bot ready, ^C exits")
writeToLog("== " + time.Now().Format(time.RFC3339) + " - Bot Started ==\n")
for {
// read each incoming message
m, err := slack.getMessage()
if err == nil {
writeToLog(" " + time.Now().Format(time.RFC3339) + " - Received Message\n")
processMessage(slack, &m)
}
}
writeToLog("== " + time.Now().Format(time.RFC3339) + " - Bot Stopped ==\n\n")
}
func processMessage(slack *Slack, m *Message) {
if mb, me := json.Marshal(m); me == nil {
// Write the JSON representation to the log
writeToLog(string(mb) + "\n")
}
if m.Type == "message" || m.Type == "reaction_added" {
var err error
var usr *User
// Check if we know who the user is
usr, err = getUserInfo(m.User)
// If the user information hasn't been updated in the last day, update it.
if err != nil || usr.LastUpdated.IsZero() || time.Since(usr.LastUpdated) > (time.Hour*24) {
if u, ue := slack.getUserInfo(m.User); ue == nil {
saveUserInfo(u)
}
}
for _, stats := range statProcessors {
if usr.IsBot {
stats.ProcessBotMessage(m)
} else {
stats.ProcessMessage(m)
}
}
for _, proc := range messageProcessors {
if isAdmin(m.User) {
proc.ProcessAdminMessage(slack, m)
}
if usr.IsBot {
proc.ProcessBotMessage(slack, m)
} else {
proc.ProcessMessage(slack, m)
}
}
if m.Channel != "" {
// Check if we know what the channel is
chnl, err := getChannelInfo(m.Channel)
var isDirectMessage bool
// If the channel information hasn't been updated in the last day, update it.
if err != nil || chnl.LastUpdated.IsZero() || time.Since(chnl.LastUpdated) > (time.Hour*24) {
// Either we don't have this channel, or it's a direct message
if c, ce := slack.getChannelInfo(m.Channel); ce == nil {
// Save channel info
saveChannelInfo(c)
} else {
isDirectMessage = true
}
}
if isDirectMessage {
for _, proc := range messageProcessors {
if isAdmin(m.User) {
proc.ProcessAdminUserMessage(slack, m)
}
proc.ProcessUserMessage(slack, m)
}
} else {
for _, proc := range messageProcessors {
proc.ProcessChannelMessage(slack, m)
}
}
}
}
}
func registerMessageProcessor(b messageProcessor) {
// Register a Message Processor
// Make sure that we haven't already registered it
for _, proc := range messageProcessors {
if proc.GetName() == b.GetName() {
panic(fmt.Errorf("Attempted to Re-register Message Processor %s", b.GetName()))
}
}
messageProcessors = append(messageProcessors, b)
}
func writeToLog(d string) {
f, err := os.OpenFile("statbot.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0664)
if err != nil {
panic(err)
}
f.WriteString(d)
f.Close()
}