diff --git a/bot/bot.go b/bot/bot.go
index 6a69bb2..c5b237d 100644
--- a/bot/bot.go
+++ b/bot/bot.go
@@ -6,6 +6,7 @@ import (
"html/template"
"log"
"net/http"
+ "reflect"
"strings"
"github.com/jmoiron/sqlx"
@@ -19,7 +20,7 @@ import (
type bot struct {
// Each plugin must be registered in our plugins handler. To come: a map so that this
// will allow plugins to respond to specific kinds of events
- plugins map[string]Handler
+ plugins map[string]Plugin
pluginOrdering []string
// Users holds information about all of our friends
@@ -41,13 +42,16 @@ type bot struct {
// filters registered by plugins
filters map[string]func(string) string
+
+ callbacks CallbackMap
}
+// Variable represents a $var replacement
type Variable struct {
Variable, Value string
}
-// Newbot creates a bot for a given connection and set of handlers.
+// New creates a bot for a given connection and set of handlers.
func New(config *config.Config, connector Connector) Bot {
logIn := make(chan msg.Message)
logOut := make(chan msg.Messages)
@@ -62,7 +66,7 @@ func New(config *config.Config, connector Connector) Bot {
bot := &bot{
config: config,
- plugins: make(map[string]Handler),
+ plugins: make(map[string]Plugin),
pluginOrdering: make([]string, 0),
conn: connector,
users: users,
@@ -71,6 +75,7 @@ func New(config *config.Config, connector Connector) Bot {
logOut: logOut,
httpEndPoints: make(map[string]string),
filters: make(map[string]func(string) string),
+ callbacks: make(CallbackMap),
}
bot.migrateDB()
@@ -79,9 +84,7 @@ func New(config *config.Config, connector Connector) Bot {
addr := config.Get("HttpAddr", "127.0.0.1:1337")
go http.ListenAndServe(addr, nil)
- connector.RegisterMessageReceived(bot.MsgReceived)
- connector.RegisterEventReceived(bot.EventReceived)
- connector.RegisterReplyMessageReceived(bot.ReplyMsgReceived)
+ connector.RegisterEvent(bot.Receive)
return bot
}
@@ -109,7 +112,8 @@ func (b *bot) migrateDB() {
}
// Adds a constructed handler to the bots handlers list
-func (b *bot) AddHandler(name string, h Handler) {
+func (b *bot) AddPlugin(h Plugin) {
+ name := reflect.TypeOf(h).String()
b.plugins[name] = h
b.pluginOrdering = append(b.pluginOrdering, name)
if entry := h.RegisterWeb(); entry != nil {
@@ -126,7 +130,7 @@ func (b *bot) Who(channel string) []user.User {
return users
}
-var rootIndex string = `
+var rootIndex = `
@@ -166,7 +170,7 @@ func (b *bot) serveRoot(w http.ResponseWriter, r *http.Request) {
t.Execute(w, context)
}
-// Checks if message is a command and returns its curtailed version
+// IsCmd checks if message is a command and returns its curtailed version
func IsCmd(c *config.Config, message string) (bool, string) {
cmdcs := c.GetArray("CommandChar", []string{"!"})
botnick := strings.ToLower(c.Get("Nick", "bot"))
@@ -244,3 +248,15 @@ func (b *bot) checkAdmin(nick string) bool {
func (b *bot) RegisterFilter(name string, f func(string) string) {
b.filters[name] = f
}
+
+// Register a callback
+func (b *bot) Register(p Plugin, kind Kind, cb Callback) {
+ t := reflect.TypeOf(p)
+ if _, ok := b.callbacks[t]; !ok {
+ b.callbacks[t] = make(map[Kind][]Callback)
+ }
+ if _, ok := b.callbacks[t][kind]; !ok {
+ b.callbacks[t][kind] = []Callback{}
+ }
+ b.callbacks[t][kind] = append(b.callbacks[t][kind], cb)
+}
diff --git a/bot/handlers.go b/bot/handlers.go
index 39b5d72..2108afc 100644
--- a/bot/handlers.go
+++ b/bot/handlers.go
@@ -8,6 +8,7 @@ import (
"fmt"
"log"
"math/rand"
+ "reflect"
"regexp"
"strconv"
"strings"
@@ -16,22 +17,20 @@ import (
"github.com/velour/catbase/bot/msg"
)
-// Handles incomming PRIVMSG requests
-func (b *bot) MsgReceived(msg msg.Message) {
- log.Println("Received message: ", msg)
+func (b *bot) Receive(kind Kind, msg msg.Message, args ...interface{}) {
+ log.Println("Received event: ", msg)
// msg := b.buildMessage(client, inMsg)
// do need to look up user and fix it
- if strings.HasPrefix(msg.Body, "help ") && msg.Command {
+ if kind == Message && strings.HasPrefix(msg.Body, "help ") && msg.Command {
parts := strings.Fields(strings.ToLower(msg.Body))
b.checkHelp(msg.Channel, parts)
goto RET
}
for _, name := range b.pluginOrdering {
- p := b.plugins[name]
- if p.Message(msg) {
- break
+ if b.runCallback(b.plugins[name], kind, msg, args...) {
+ goto RET
}
}
@@ -40,52 +39,19 @@ RET:
return
}
-// Handle incoming events
-func (b *bot) EventReceived(msg msg.Message) {
- log.Println("Received event: ", msg)
- //msg := b.buildMessage(conn, inMsg)
- for _, name := range b.pluginOrdering {
- p := b.plugins[name]
- if p.Event(msg.Body, msg) { // TODO: could get rid of msg.Body
- break
+func (b *bot) runCallback(plugin Plugin, evt Kind, message msg.Message, args ...interface{}) bool {
+ t := reflect.TypeOf(plugin)
+ for _, cb := range b.callbacks[t][evt] {
+ if cb(evt, message, args...) {
+ return true
}
}
+ return false
}
-// Handle incoming replys
-func (b *bot) ReplyMsgReceived(msg msg.Message, identifier string) {
- log.Println("Received message: ", msg)
-
- for _, name := range b.pluginOrdering {
- p := b.plugins[name]
- if p.ReplyMessage(msg, identifier) {
- break
- }
- }
-}
-
-func (b *bot) SendMessage(channel, message string) string {
- return b.conn.SendMessage(channel, message)
-}
-
-func (b *bot) SendAction(channel, message string) string {
- return b.conn.SendAction(channel, message)
-}
-
-func (b *bot) ReplyToMessageIdentifier(channel, message, identifier string) (string, bool) {
- return b.conn.ReplyToMessageIdentifier(channel, message, identifier)
-}
-
-func (b *bot) ReplyToMessage(channel, message string, replyTo msg.Message) (string, bool) {
- return b.conn.ReplyToMessage(channel, message, replyTo)
-}
-
-func (b *bot) React(channel, reaction string, message msg.Message) bool {
- return b.conn.React(channel, reaction, message)
-}
-
-func (b *bot) Edit(channel, newMessage, identifier string) bool {
- return b.conn.Edit(channel, newMessage, identifier)
+// Send a message to the connection
+func (b *bot) Send(kind Kind, args ...interface{}) (string, error) {
+ return b.conn.Send(kind, args...)
}
func (b *bot) GetEmojiList() map[string]string {
@@ -100,7 +66,7 @@ func (b *bot) checkHelp(channel string, parts []string) {
for name, _ := range b.plugins {
topics = fmt.Sprintf("%s, %s", topics, name)
}
- b.SendMessage(channel, topics)
+ b.Send(Message, channel, topics)
} else {
// trigger the proper plugin's help response
if parts[1] == "about" {
@@ -111,12 +77,12 @@ func (b *bot) checkHelp(channel string, parts []string) {
b.listVars(channel, parts)
return
}
- plugin := b.plugins[parts[1]]
- if plugin != nil {
- plugin.Help(channel, parts)
+ plugin, ok := b.plugins[parts[1]]
+ if ok {
+ b.runCallback(plugin, Help, msg.Message{Channel: channel}, channel, parts)
} else {
msg := fmt.Sprintf("I'm sorry, I don't know what %s is!", parts[1])
- b.SendMessage(channel, msg)
+ b.Send(Message, channel, msg)
}
}
}
@@ -212,14 +178,14 @@ func (b *bot) listVars(channel string, parts []string) {
if len(variables) > 0 {
msg += ", " + strings.Join(variables, ", ")
}
- b.SendMessage(channel, msg)
+ b.Send(Message, channel, msg)
}
func (b *bot) Help(channel string, parts []string) {
msg := fmt.Sprintf("Hi, I'm based on godeepintir version %s. I'm written in Go, and you "+
"can find my source code on the internet here: "+
"http://github.com/velour/catbase", b.version)
- b.SendMessage(channel, msg)
+ b.Send(Message, channel, msg)
}
// Send our own musings to the plugins
@@ -236,9 +202,8 @@ func (b *bot) selfSaid(channel, message string, action bool) {
}
for _, name := range b.pluginOrdering {
- p := b.plugins[name]
- if p.BotMessage(msg) {
- break
+ if b.runCallback(b.plugins[name], SelfMessage, msg) {
+ return
}
}
}
diff --git a/bot/interfaces.go b/bot/interfaces.go
index 42b0980..74eed27 100644
--- a/bot/interfaces.go
+++ b/bot/interfaces.go
@@ -3,56 +3,78 @@
package bot
import (
+ "reflect"
+
"github.com/jmoiron/sqlx"
"github.com/velour/catbase/bot/msg"
"github.com/velour/catbase/bot/user"
"github.com/velour/catbase/config"
)
+const (
+ _ = iota
+
+ // Message any standard chat
+ Message
+ // Reply something containing a message reference
+ Reply
+ // Action any /me action
+ Action
+ // Reaction Icon reaction if service supports it
+ Reaction
+ // Edit message ref'd new message to replace
+ Edit
+ // Not sure what event is
+ Event
+ // Help is used when the bot help system is triggered
+ Help
+ // SelfMessage triggers when the bot is sending a message
+ SelfMessage
+)
+
+type Kind int
+type Callback func(Kind, msg.Message, ...interface{}) bool
+type CallbackMap map[reflect.Type]map[Kind][]Callback
+
+// Bot interface serves to allow mocking of the actual bot
type Bot interface {
+ // Config allows access to the bot's configuration system
Config() *config.Config
+ // DB gives access to the current database
DB() *sqlx.DB
+ // Who lists users in a particular channel
Who(string) []user.User
- AddHandler(string, Handler)
- SendMessage(string, string) string
- SendAction(string, string) string
- ReplyToMessageIdentifier(string, string, string) (string, bool)
- ReplyToMessage(string, string, msg.Message) (string, bool)
- React(string, string, msg.Message) bool
- Edit(string, string, string) bool
- MsgReceived(msg.Message)
- ReplyMsgReceived(msg.Message, string)
- EventReceived(msg.Message)
+ // AddPlugin registers a new plugin handler
+ AddPlugin(Plugin)
+ // First arg should be one of bot.Message/Reply/Action/etc
+ Send(Kind, ...interface{}) (string, error)
+ // First arg should be one of bot.Message/Reply/Action/etc
+ Receive(Kind, msg.Message, ...interface{})
+ // Register a callback
+ Register(Plugin, Kind, Callback)
+
Filter(msg.Message, string) string
LastMessage(string) (msg.Message, error)
+
CheckAdmin(string) bool
GetEmojiList() map[string]string
RegisterFilter(string, func(string) string)
}
+// Connector represents a server connection to a chat service
type Connector interface {
- RegisterEventReceived(func(message msg.Message))
- RegisterMessageReceived(func(message msg.Message))
- RegisterReplyMessageReceived(func(msg.Message, string))
+ RegisterEvent(func(Kind, msg.Message, ...interface{}))
+
+ Send(Kind, ...interface{}) (string, error)
- SendMessage(channel, message string) string
- SendAction(channel, message string) string
- ReplyToMessageIdentifier(string, string, string) (string, bool)
- ReplyToMessage(string, string, msg.Message) (string, bool)
- React(string, string, msg.Message) bool
- Edit(string, string, string) bool
GetEmojiList() map[string]string
Serve() error
Who(string) []string
}
-// Interface used for compatibility with the Plugin interface
-type Handler interface {
- Message(message msg.Message) bool
- Event(kind string, message msg.Message) bool
- ReplyMessage(msg.Message, string) bool
- BotMessage(message msg.Message) bool
- Help(channel string, parts []string)
+// Plugin interface used for compatibility with the Plugin interface
+// Probably can disappear once RegisterWeb gets inverted
+type Plugin interface {
RegisterWeb() *string
}
diff --git a/bot/mock.go b/bot/mock.go
index f3170e4..ea8986e 100644
--- a/bot/mock.go
+++ b/bot/mock.go
@@ -26,68 +26,67 @@ type MockBot struct {
Reactions []string
}
-func (mb *MockBot) Config() *config.Config { return mb.Cfg }
-func (mb *MockBot) DBVersion() int64 { return 1 }
-func (mb *MockBot) DB() *sqlx.DB { return mb.Cfg.DB }
-func (mb *MockBot) Conn() Connector { return nil }
-func (mb *MockBot) Who(string) []user.User { return []user.User{} }
-func (mb *MockBot) AddHandler(name string, f Handler) {}
-func (mb *MockBot) SendMessage(ch string, msg string) string {
- mb.Messages = append(mb.Messages, msg)
- return fmt.Sprintf("m-%d", len(mb.Actions)-1)
+func (mb *MockBot) Config() *config.Config { return mb.Cfg }
+func (mb *MockBot) DB() *sqlx.DB { return mb.Cfg.DB }
+func (mb *MockBot) Who(string) []user.User { return []user.User{} }
+func (mb *MockBot) Send(kind Kind, args ...interface{}) (string, error) {
+ switch kind {
+ case Message:
+ mb.Messages = append(mb.Messages, args[1].(string))
+ return fmt.Sprintf("m-%d", len(mb.Actions)-1), nil
+ case Action:
+ mb.Actions = append(mb.Actions, args[1].(string))
+ return fmt.Sprintf("a-%d", len(mb.Actions)-1), nil
+ case Edit:
+ ch, m, id := args[0].(string), args[1].(string), args[2].(string)
+ return mb.edit(ch, m, id)
+ case Reaction:
+ ch, re, msg := args[0].(string), args[1].(string), args[2].(msg.Message)
+ return mb.react(ch, re, msg)
+ }
+ return "ERR", fmt.Errorf("Mesasge type unhandled")
}
-func (mb *MockBot) SendAction(ch string, msg string) string {
- mb.Actions = append(mb.Actions, msg)
- return fmt.Sprintf("a-%d", len(mb.Actions)-1)
-}
-func (mb *MockBot) ReplyToMessageIdentifier(channel, message, identifier string) (string, bool) {
- return "", false
-}
-func (mb *MockBot) ReplyToMessage(channel, message string, replyTo msg.Message) (string, bool) {
- return "", false
-}
-func (mb *MockBot) MsgReceived(msg msg.Message) {}
-func (mb *MockBot) EventReceived(msg msg.Message) {}
-func (mb *MockBot) Filter(msg msg.Message, s string) string { return s }
-func (mb *MockBot) LastMessage(ch string) (msg.Message, error) { return msg.Message{}, nil }
-func (mb *MockBot) CheckAdmin(nick string) bool { return false }
+func (mb *MockBot) AddPlugin(f Plugin) {}
+func (mb *MockBot) Register(p Plugin, kind Kind, cb Callback) {}
+func (mb *MockBot) Receive(kind Kind, msg msg.Message, args ...interface{}) {}
+func (mb *MockBot) Filter(msg msg.Message, s string) string { return s }
+func (mb *MockBot) LastMessage(ch string) (msg.Message, error) { return msg.Message{}, nil }
+func (mb *MockBot) CheckAdmin(nick string) bool { return false }
-func (mb *MockBot) React(channel, reaction string, message msg.Message) bool {
+func (mb *MockBot) react(channel, reaction string, message msg.Message) (string, error) {
mb.Reactions = append(mb.Reactions, reaction)
- return false
+ return "", nil
}
-func (mb *MockBot) Edit(channel, newMessage, identifier string) bool {
+func (mb *MockBot) edit(channel, newMessage, identifier string) (string, error) {
isMessage := identifier[0] == 'm'
if !isMessage && identifier[0] != 'a' {
- log.Printf("failed to parse identifier: %s", identifier)
- return false
+ err := fmt.Errorf("failed to parse identifier: %s", identifier)
+ log.Println(err)
+ return "", err
}
index, err := strconv.Atoi(strings.Split(identifier, "-")[1])
if err != nil {
- log.Printf("failed to parse identifier: %s", identifier)
- return false
+ err := fmt.Errorf("failed to parse identifier: %s", identifier)
+ log.Println(err)
+ return "", err
}
if isMessage {
if index < len(mb.Messages) {
mb.Messages[index] = newMessage
} else {
- return false
+ return "", fmt.Errorf("No message")
}
} else {
if index < len(mb.Actions) {
mb.Actions[index] = newMessage
} else {
- return false
+ return "", fmt.Errorf("No action")
}
}
- return true
-}
-
-func (mb *MockBot) ReplyMsgReceived(msg.Message, string) {
-
+ return "", nil
}
func (mb *MockBot) GetEmojiList() map[string]string { return make(map[string]string) }
diff --git a/go.mod b/go.mod
index 313d566..45d8122 100644
--- a/go.mod
+++ b/go.mod
@@ -5,21 +5,21 @@ require (
github.com/boltdb/bolt v1.3.1
github.com/chrissexton/leftpad v0.0.0-20181207133115-1e93189d2fff
github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/go-sql-driver/mysql v1.4.1 // indirect
github.com/gorilla/websocket v1.4.0 // indirect
github.com/jmoiron/sqlx v1.2.0
github.com/mattn/go-sqlite3 v1.10.0
github.com/mitchellh/mapstructure v1.1.2 // indirect
github.com/mmcdole/gofeed v1.0.0-beta2
github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf // indirect
- github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d // indirect
github.com/stretchr/objx v0.1.1 // indirect
- github.com/stretchr/testify v1.2.2
+ github.com/stretchr/testify v1.3.0
github.com/velour/chat v0.0.0-20180713122344-fd1d1606cb89
github.com/velour/velour v0.0.0-20160303155839-8e090e68d158
github.com/yuin/gluamapper v0.0.0-20150323120927-d836955830e7
- github.com/yuin/gopher-lua v0.0.0-20181214045814-db9ae37725ec
- golang.org/x/net v0.0.0-20181217023233-e147a9138326 // indirect
+ github.com/yuin/gopher-lua v0.0.0-20190125051437-7b9317363aa9
+ golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 // indirect
golang.org/x/text v0.3.0 // indirect
gopkg.in/sourcemap.v1 v1.0.5 // indirect
)
diff --git a/go.sum b/go.sum
index 187d147..2b566da 100644
--- a/go.sum
+++ b/go.sum
@@ -7,9 +7,11 @@ github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx2
github.com/chrissexton/leftpad v0.0.0-20181207133115-1e93189d2fff h1:+TEqaP0eO1unI7XHHFeMDhsxhLDIb0x8KYuZbqbAmxA=
github.com/chrissexton/leftpad v0.0.0-20181207133115-1e93189d2fff/go.mod h1:QCRjR0b4qiJiNjuP7RFM89bh4UExGJalcWmYeSvlnRc=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
@@ -28,10 +30,13 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d h1:1VUlQbCfkoSGv7qP7Y+ro3ap1P1pPZxgdGVqiTVy5C4=
github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/velour/chat v0.0.0-20180713122344-fd1d1606cb89 h1:3D3M900hEBJJAqyKl70QuRHi5weX9+ptlQI1v+FNcQ8=
github.com/velour/chat v0.0.0-20180713122344-fd1d1606cb89/go.mod h1:ejwOYCjnDMyO5LXFXRARQJGBZ6xQJZ3rgAHE5drSuMM=
github.com/velour/velour v0.0.0-20160303155839-8e090e68d158 h1:p3rTUXxzuKsBOsHlkly7+rj9wagFBKeIsCDKkDII9sw=
@@ -40,10 +45,13 @@ github.com/yuin/gluamapper v0.0.0-20150323120927-d836955830e7 h1:noHsffKZsNfU38D
github.com/yuin/gluamapper v0.0.0-20150323120927-d836955830e7/go.mod h1:bbMEM6aU1WDF1ErA5YJ0p91652pGv140gGw4Ww3RGp8=
github.com/yuin/gopher-lua v0.0.0-20181214045814-db9ae37725ec h1:vpF8Kxql6/3OvGH4y2SKtpN3WsB17mvJ8f8H1o2vucQ=
github.com/yuin/gopher-lua v0.0.0-20181214045814-db9ae37725ec/go.mod h1:fFiAh+CowNFr0NK5VASokuwKwkbacRmHsVA7Yb1Tqac=
+github.com/yuin/gopher-lua v0.0.0-20190125051437-7b9317363aa9/go.mod h1:fFiAh+CowNFr0NK5VASokuwKwkbacRmHsVA7Yb1Tqac=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181217023233-e147a9138326 h1:iCzOf0xz39Tstp+Tu/WwyGjUXCk34QhQORRxBeXXTA4=
golang.org/x/net v0.0.0-20181217023233-e147a9138326/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 h1:ulvT7fqt0yHWzpJwI57MezWnYDVpCAYBVuYst/L+fAY=
+golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
diff --git a/irc/irc.go b/irc/irc.go
index 7a89110..58e1359 100644
--- a/irc/irc.go
+++ b/irc/irc.go
@@ -42,9 +42,7 @@ type Irc struct {
config *config.Config
quit chan bool
- eventReceived func(msg.Message)
- messageReceived func(msg.Message)
- replyMessageReceived func(msg.Message, string)
+ event func(bot.Kind, msg.Message, ...interface{})
}
func New(c *config.Config) *Irc {
@@ -54,16 +52,20 @@ func New(c *config.Config) *Irc {
return &i
}
-func (i *Irc) RegisterEventReceived(f func(msg.Message)) {
- i.eventReceived = f
+func (i *Irc) RegisterEvent(f func(bot.Kind, msg.Message, ...interface{})) {
+ i.event = f
}
-func (i *Irc) RegisterMessageReceived(f func(msg.Message)) {
- i.messageReceived = f
-}
-
-func (i *Irc) RegisterReplyMessageReceived(f func(msg.Message, string)) {
- i.replyMessageReceived = f
+func (i *Irc) Send(kind bot.Kind, args ...interface{}) (string, error) {
+ switch kind {
+ case bot.Reply:
+ case bot.Message:
+ return i.sendMessage(args[0].(string), args[1].(string))
+ case bot.Action:
+ return i.sendAction(args[0].(string), args[1].(string))
+ default:
+ }
+ return "", nil
}
func (i *Irc) JoinChannel(channel string) {
@@ -71,7 +73,7 @@ func (i *Irc) JoinChannel(channel string) {
i.Client.Out <- irc.Msg{Cmd: irc.JOIN, Args: []string{channel}}
}
-func (i *Irc) SendMessage(channel, message string) string {
+func (i *Irc) sendMessage(channel, message string) (string, error) {
for len(message) > 0 {
m := irc.Msg{
Cmd: "PRIVMSG",
@@ -95,42 +97,23 @@ func (i *Irc) SendMessage(channel, message string) string {
i.Client.Out <- m
}
- return "NO_IRC_IDENTIFIERS"
+ return "NO_IRC_IDENTIFIERS", nil
}
// Sends action to channel
-func (i *Irc) SendAction(channel, message string) string {
+func (i *Irc) sendAction(channel, message string) (string, error) {
message = actionPrefix + " " + message + "\x01"
- i.SendMessage(channel, message)
- return "NO_IRC_IDENTIFIERS"
-}
-
-func (i *Irc) ReplyToMessageIdentifier(channel, message, identifier string) (string, bool) {
- return "NO_IRC_IDENTIFIERS", false
-}
-
-func (i *Irc) ReplyToMessage(channel, message string, replyTo msg.Message) (string, bool) {
- return "NO_IRC_IDENTIFIERS", false
-}
-
-func (i *Irc) React(channel, reaction string, message msg.Message) bool {
- //we're not goign to do anything because it's IRC
- return false
-}
-
-func (i *Irc) Edit(channel, newMessage, identifier string) bool {
- //we're not goign to do anything because it's IRC
- return false
+ return i.sendMessage(channel, message)
}
func (i *Irc) GetEmojiList() map[string]string {
- //we're not goign to do anything because it's IRC
+ //we're not going to do anything because it's IRC
return make(map[string]string)
}
func (i *Irc) Serve() error {
- if i.eventReceived == nil || i.messageReceived == nil {
+ if i.event == nil {
return fmt.Errorf("Missing an event handler")
}
@@ -209,53 +192,53 @@ func (i *Irc) handleMsg(msg irc.Msg) {
// OK, ignore
case irc.ERR_NOSUCHNICK:
- i.eventReceived(botMsg)
+ fallthrough
case irc.ERR_NOSUCHCHANNEL:
- i.eventReceived(botMsg)
+ fallthrough
case irc.RPL_MOTD:
- i.eventReceived(botMsg)
+ fallthrough
case irc.RPL_NAMREPLY:
- i.eventReceived(botMsg)
+ fallthrough
case irc.RPL_TOPIC:
- i.eventReceived(botMsg)
+ fallthrough
case irc.KICK:
- i.eventReceived(botMsg)
+ fallthrough
case irc.TOPIC:
- i.eventReceived(botMsg)
+ fallthrough
case irc.MODE:
- i.eventReceived(botMsg)
+ fallthrough
case irc.JOIN:
- i.eventReceived(botMsg)
+ fallthrough
case irc.PART:
- i.eventReceived(botMsg)
+ fallthrough
+
+ case irc.NOTICE:
+ fallthrough
+
+ case irc.NICK:
+ fallthrough
+
+ case irc.RPL_WHOREPLY:
+ fallthrough
+
+ case irc.RPL_ENDOFWHO:
+ i.event(bot.Event, botMsg)
+
+ case irc.PRIVMSG:
+ i.event(bot.Message, botMsg)
case irc.QUIT:
os.Exit(1)
- case irc.NOTICE:
- i.eventReceived(botMsg)
-
- case irc.PRIVMSG:
- i.messageReceived(botMsg)
-
- case irc.NICK:
- i.eventReceived(botMsg)
-
- case irc.RPL_WHOREPLY:
- i.eventReceived(botMsg)
-
- case irc.RPL_ENDOFWHO:
- i.eventReceived(botMsg)
-
default:
cmd := irc.CmdNames[msg.Cmd]
log.Println("(" + cmd + ") " + msg.Raw)
diff --git a/main.go b/main.go
index c3d7ebe..6ab529d 100644
--- a/main.go
+++ b/main.go
@@ -78,32 +78,32 @@ func main() {
b := bot.New(c, client)
- b.AddHandler("admin", admin.New(b))
- b.AddHandler("first", first.New(b))
- b.AddHandler("leftpad", leftpad.New(b))
- b.AddHandler("talker", talker.New(b))
- b.AddHandler("dice", dice.New(b))
- b.AddHandler("picker", picker.New(b))
- b.AddHandler("beers", beers.New(b))
- b.AddHandler("remember", fact.NewRemember(b))
- b.AddHandler("your", your.New(b))
- b.AddHandler("counter", counter.New(b))
- b.AddHandler("reminder", reminder.New(b))
- b.AddHandler("babbler", babbler.New(b))
- b.AddHandler("zork", zork.New(b))
- b.AddHandler("rss", rss.New(b))
- b.AddHandler("reaction", reaction.New(b))
- b.AddHandler("emojifyme", emojifyme.New(b))
- b.AddHandler("twitch", twitch.New(b))
- b.AddHandler("inventory", inventory.New(b))
- b.AddHandler("rpgORdie", rpgORdie.New(b))
- b.AddHandler("sisyphus", sisyphus.New(b))
- b.AddHandler("tell", tell.New(b))
- b.AddHandler("couldashouldawoulda", couldashouldawoulda.New(b))
- b.AddHandler("nedepedia", nerdepedia.New(b))
+ b.AddPlugin(admin.New(b))
+ b.AddPlugin(emojifyme.New(b))
+ b.AddPlugin(first.New(b))
+ b.AddPlugin(leftpad.New(b))
+ b.AddPlugin(talker.New(b))
+ b.AddPlugin(dice.New(b))
+ b.AddPlugin(picker.New(b))
+ b.AddPlugin(beers.New(b))
+ b.AddPlugin(fact.NewRemember(b))
+ b.AddPlugin(your.New(b))
+ b.AddPlugin(counter.New(b))
+ b.AddPlugin(reminder.New(b))
+ b.AddPlugin(babbler.New(b))
+ b.AddPlugin(zork.New(b))
+ b.AddPlugin(rss.New(b))
+ b.AddPlugin(reaction.New(b))
+ b.AddPlugin(twitch.New(b))
+ b.AddPlugin(inventory.New(b))
+ b.AddPlugin(rpgORdie.New(b))
+ b.AddPlugin(sisyphus.New(b))
+ b.AddPlugin(tell.New(b))
+ b.AddPlugin(couldashouldawoulda.New(b))
+ b.AddPlugin(nerdepedia.New(b))
// catches anything left, will always return true
- b.AddHandler("factoid", fact.New(b))
- b.AddHandler("db", db.New(b))
+ b.AddPlugin(fact.New(b))
+ b.AddPlugin(db.New(b))
for {
err := client.Serve()
diff --git a/plugins/admin/admin.go b/plugins/admin/admin.go
index a7e45c8..5de34f0 100644
--- a/plugins/admin/admin.go
+++ b/plugins/admin/admin.go
@@ -25,12 +25,14 @@ type AdminPlugin struct {
}
// NewAdminPlugin creates a new AdminPlugin with the Plugin interface
-func New(bot bot.Bot) *AdminPlugin {
+func New(b bot.Bot) *AdminPlugin {
p := &AdminPlugin{
- Bot: bot,
- db: bot.DB(),
- cfg: bot.Config(),
+ Bot: b,
+ db: b.DB(),
+ cfg: b.Config(),
}
+ b.Register(p, bot.Message, p.message)
+ b.Register(p, bot.Help, p.help)
return p
}
@@ -44,7 +46,7 @@ var forbiddenKeys = map[string]bool{
// Message responds to the bot hook on recieving messages.
// This function returns true if the plugin responds in a meaningful way to the users message.
// Otherwise, the function returns false and the bot continues execution of other plugins.
-func (p *AdminPlugin) Message(message msg.Message) bool {
+func (p *AdminPlugin) message(k bot.Kind, message msg.Message, args ...interface{}) bool {
body := message.Body
if p.quiet {
@@ -62,7 +64,7 @@ func (p *AdminPlugin) Message(message msg.Message) bool {
if strings.ToLower(body) == "shut up" {
dur := time.Duration(p.cfg.GetInt("quietDuration", 5)) * time.Minute
log.Printf("Going to sleep for %v, %v", dur, time.Now().Add(dur))
- p.Bot.SendMessage(message.Channel, "Okay. I'll be back later.")
+ p.Bot.Send(bot.Message, message.Channel, "Okay. I'll be back later.")
p.quiet = true
go func() {
select {
@@ -76,19 +78,19 @@ func (p *AdminPlugin) Message(message msg.Message) bool {
parts := strings.Split(body, " ")
if parts[0] == "set" && len(parts) > 2 && forbiddenKeys[parts[1]] {
- p.Bot.SendMessage(message.Channel, "You cannot access that key")
+ p.Bot.Send(bot.Message, message.Channel, "You cannot access that key")
return true
} else if parts[0] == "set" && len(parts) > 2 {
p.cfg.Set(parts[1], strings.Join(parts[2:], " "))
- p.Bot.SendMessage(message.Channel, fmt.Sprintf("Set %s", parts[1]))
+ p.Bot.Send(bot.Message, message.Channel, fmt.Sprintf("Set %s", parts[1]))
return true
}
if parts[0] == "get" && len(parts) == 2 && forbiddenKeys[parts[1]] {
- p.Bot.SendMessage(message.Channel, "You cannot access that key")
+ p.Bot.Send(bot.Message, message.Channel, "You cannot access that key")
return true
} else if parts[0] == "get" && len(parts) == 2 {
v := p.cfg.Get(parts[1], "")
- p.Bot.SendMessage(message.Channel, fmt.Sprintf("%s: %s", parts[1], v))
+ p.Bot.Send(bot.Message, message.Channel, fmt.Sprintf("%s: %s", parts[1], v))
return true
}
@@ -102,10 +104,10 @@ func (p *AdminPlugin) handleVariables(message msg.Message) bool {
_, err := p.db.Exec(`delete from variables where name=? and value=?`, variable, value)
if err != nil {
- p.Bot.SendMessage(message.Channel, "I'm broke and need attention in my variable creation code.")
+ p.Bot.Send(bot.Message, message.Channel, "I'm broke and need attention in my variable creation code.")
log.Println("[admin]: ", err)
} else {
- p.Bot.SendMessage(message.Channel, "Removed.")
+ p.Bot.Send(bot.Message, message.Channel, "Removed.")
}
return true
@@ -123,43 +125,32 @@ func (p *AdminPlugin) handleVariables(message msg.Message) bool {
row := p.db.QueryRow(`select count(*) from variables where value = ?`, variable, value)
err := row.Scan(&count)
if err != nil {
- p.Bot.SendMessage(message.Channel, "I'm broke and need attention in my variable creation code.")
+ p.Bot.Send(bot.Message, message.Channel, "I'm broke and need attention in my variable creation code.")
log.Println("[admin]: ", err)
return true
}
if count > 0 {
- p.Bot.SendMessage(message.Channel, "I've already got that one.")
+ p.Bot.Send(bot.Message, message.Channel, "I've already got that one.")
} else {
_, err := p.db.Exec(`INSERT INTO variables (name, value) VALUES (?, ?)`, variable, value)
if err != nil {
- p.Bot.SendMessage(message.Channel, "I'm broke and need attention in my variable creation code.")
+ p.Bot.Send(bot.Message, message.Channel, "I'm broke and need attention in my variable creation code.")
log.Println("[admin]: ", err)
return true
}
- p.Bot.SendMessage(message.Channel, "Added.")
+ p.Bot.Send(bot.Message, message.Channel, "Added.")
}
return true
}
// Help responds to help requests. Every plugin must implement a help function.
-func (p *AdminPlugin) Help(channel string, parts []string) {
- p.Bot.SendMessage(channel, "This does super secret things that you're not allowed to know about.")
-}
-
-// Empty event handler because this plugin does not do anything on event recv
-func (p *AdminPlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
-// Handler for bot's own messages
-func (p *AdminPlugin) BotMessage(message msg.Message) bool {
- return false
+func (p *AdminPlugin) help(kind bot.Kind, m msg.Message, args ...interface{}) bool {
+ p.Bot.Send(bot.Message, m.Channel, "This does super secret things that you're not allowed to know about.")
+ return true
}
// Register any web URLs desired
func (p *AdminPlugin) RegisterWeb() *string {
return nil
}
-
-func (p *AdminPlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
diff --git a/plugins/admin/admin_test.go b/plugins/admin/admin_test.go
index f4ce489..069b21d 100644
--- a/plugins/admin/admin_test.go
+++ b/plugins/admin/admin_test.go
@@ -22,12 +22,12 @@ func setup(t *testing.T) (*AdminPlugin, *bot.MockBot) {
return a, mb
}
-func makeMessage(payload string) msg.Message {
+func makeMessage(payload string) (bot.Kind, msg.Message) {
isCmd := strings.HasPrefix(payload, "!")
if isCmd {
payload = payload[1:]
}
- return msg.Message{
+ return bot.Message, msg.Message{
User: &user.User{Name: "tester"},
Channel: "test",
Body: payload,
@@ -38,7 +38,7 @@ func makeMessage(payload string) msg.Message {
func TestSet(t *testing.T) {
a, mb := setup(t)
expected := "test value"
- a.Message(makeMessage("!set test.key " + expected))
+ a.message(makeMessage("!set test.key " + expected))
actual := mb.Config().Get("test.key", "ERR")
assert.Equal(t, expected, actual)
}
@@ -47,7 +47,7 @@ func TestGetValue(t *testing.T) {
a, mb := setup(t)
expected := "value"
mb.Config().Set("test.key", "value")
- a.Message(makeMessage("!get test.key"))
+ a.message(makeMessage("!get test.key"))
assert.Len(t, mb.Messages, 1)
assert.Contains(t, mb.Messages[0], expected)
}
@@ -55,7 +55,7 @@ func TestGetValue(t *testing.T) {
func TestGetEmpty(t *testing.T) {
a, mb := setup(t)
expected := "test.key: "
- a.Message(makeMessage("!get test.key"))
+ a.message(makeMessage("!get test.key"))
assert.Len(t, mb.Messages, 1)
assert.Equal(t, expected, mb.Messages[0])
}
@@ -63,7 +63,7 @@ func TestGetEmpty(t *testing.T) {
func TestGetForbidden(t *testing.T) {
a, mb := setup(t)
expected := "cannot access"
- a.Message(makeMessage("!get slack.token"))
+ a.message(makeMessage("!get slack.token"))
assert.Len(t, mb.Messages, 1)
assert.Contains(t, mb.Messages[0], expected)
}
diff --git a/plugins/babbler/babbler.go b/plugins/babbler/babbler.go
index 78ba647..efc0c63 100644
--- a/plugins/babbler/babbler.go
+++ b/plugins/babbler/babbler.go
@@ -52,24 +52,24 @@ type BabblerArc struct {
Frequency int64 `db:"frequency"`
}
-func New(bot bot.Bot) *BabblerPlugin {
+func New(b bot.Bot) *BabblerPlugin {
log.SetFlags(log.LstdFlags | log.Lshortfile)
- if _, err := bot.DB().Exec(`create table if not exists babblers (
+ if _, err := b.DB().Exec(`create table if not exists babblers (
id integer primary key,
babbler string
);`); err != nil {
log.Fatal(err)
}
- if _, err := bot.DB().Exec(`create table if not exists babblerWords (
+ if _, err := b.DB().Exec(`create table if not exists babblerWords (
id integer primary key,
word string
);`); err != nil {
log.Fatal(err)
}
- if _, err := bot.DB().Exec(`create table if not exists babblerNodes (
+ if _, err := b.DB().Exec(`create table if not exists babblerNodes (
id integer primary key,
babblerId integer,
wordId integer,
@@ -79,7 +79,7 @@ func New(bot bot.Bot) *BabblerPlugin {
log.Fatal(err)
}
- if _, err := bot.DB().Exec(`create table if not exists babblerArcs (
+ if _, err := b.DB().Exec(`create table if not exists babblerArcs (
id integer primary key,
fromNodeId integer,
toNodeId interger,
@@ -89,17 +89,20 @@ func New(bot bot.Bot) *BabblerPlugin {
}
plugin := &BabblerPlugin{
- Bot: bot,
- db: bot.DB(),
+ Bot: b,
+ db: b.DB(),
WithGoRoutines: true,
}
plugin.createNewWord("")
+ b.Register(plugin, bot.Message, plugin.message)
+ b.Register(plugin, bot.Help, plugin.help)
+
return plugin
}
-func (p *BabblerPlugin) Message(message msg.Message) bool {
+func (p *BabblerPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
lowercase := strings.ToLower(message.Body)
tokens := strings.Fields(lowercase)
numTokens := len(tokens)
@@ -141,12 +144,12 @@ func (p *BabblerPlugin) Message(message msg.Message) bool {
}
if saidSomething {
- p.Bot.SendMessage(message.Channel, saidWhat)
+ p.Bot.Send(bot.Message, message.Channel, saidWhat)
}
return saidSomething
}
-func (p *BabblerPlugin) Help(channel string, parts []string) {
+func (p *BabblerPlugin) help(kind bot.Kind, msg msg.Message, args ...interface{}) bool {
commands := []string{
"initialize babbler for seabass",
"merge babbler drseabass into seabass",
@@ -155,15 +158,8 @@ func (p *BabblerPlugin) Help(channel string, parts []string) {
"seabass says-middle-out ...",
"seabass says-bridge ... | ...",
}
- p.Bot.SendMessage(channel, strings.Join(commands, "\n\n"))
-}
-
-func (p *BabblerPlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
-func (p *BabblerPlugin) BotMessage(message msg.Message) bool {
- return false
+ p.Bot.Send(bot.Message, msg.Channel, strings.Join(commands, "\n\n"))
+ return true
}
func (p *BabblerPlugin) RegisterWeb() *string {
@@ -934,5 +930,3 @@ func (p *BabblerPlugin) babbleSeedBookends(babblerName string, start, end []stri
return strings.Join(words, " "), nil
}
-
-func (p *BabblerPlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
diff --git a/plugins/babbler/babbler_test.go b/plugins/babbler/babbler_test.go
index b07b75f..1631257 100644
--- a/plugins/babbler/babbler_test.go
+++ b/plugins/babbler/babbler_test.go
@@ -12,12 +12,12 @@ import (
"github.com/velour/catbase/bot/user"
)
-func makeMessage(payload string) msg.Message {
+func makeMessage(payload string) (bot.Kind, msg.Message) {
isCmd := strings.HasPrefix(payload, "!")
if isCmd {
payload = payload[1:]
}
- return msg.Message{
+ return bot.Message, msg.Message{
User: &user.User{Name: "tester"},
Channel: "test",
Body: payload,
@@ -41,7 +41,7 @@ func TestBabblerNoBabbler(t *testing.T) {
mb := bot.NewMockBot()
bp := newBabblerPlugin(mb)
assert.NotNil(t, bp)
- bp.Message(makeMessage("!seabass2 says"))
+ bp.message(makeMessage("!seabass2 says"))
res := assert.Len(t, mb.Messages, 0)
assert.True(t, res)
// assert.Contains(t, mb.Messages[0], "seabass2 babbler not found")
@@ -51,9 +51,9 @@ func TestBabblerNothingSaid(t *testing.T) {
mb := bot.NewMockBot()
bp := newBabblerPlugin(mb)
assert.NotNil(t, bp)
- res := bp.Message(makeMessage("initialize babbler for seabass"))
+ res := bp.message(makeMessage("initialize babbler for seabass"))
assert.True(t, res)
- res = bp.Message(makeMessage("!seabass says"))
+ res = bp.message(makeMessage("!seabass says"))
assert.True(t, res)
assert.Len(t, mb.Messages, 2)
assert.Contains(t, mb.Messages[0], "okay.")
@@ -64,14 +64,14 @@ func TestBabbler(t *testing.T) {
mb := bot.NewMockBot()
bp := newBabblerPlugin(mb)
assert.NotNil(t, bp)
- seabass := makeMessage("This is a message")
+ k, seabass := makeMessage("This is a message")
seabass.User = &user.User{Name: "seabass"}
- res := bp.Message(seabass)
+ res := bp.message(k, seabass)
seabass.Body = "This is another message"
- res = bp.Message(seabass)
+ res = bp.message(k, seabass)
seabass.Body = "This is a long message"
- res = bp.Message(seabass)
- res = bp.Message(makeMessage("!seabass says"))
+ res = bp.message(k, seabass)
+ res = bp.message(makeMessage("!seabass says"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "this is")
@@ -82,14 +82,14 @@ func TestBabblerSeed(t *testing.T) {
mb := bot.NewMockBot()
bp := newBabblerPlugin(mb)
assert.NotNil(t, bp)
- seabass := makeMessage("This is a message")
+ k, seabass := makeMessage("This is a message")
seabass.User = &user.User{Name: "seabass"}
- res := bp.Message(seabass)
+ res := bp.message(k, seabass)
seabass.Body = "This is another message"
- res = bp.Message(seabass)
+ res = bp.message(k, seabass)
seabass.Body = "This is a long message"
- res = bp.Message(seabass)
- res = bp.Message(makeMessage("!seabass says long"))
+ res = bp.message(k, seabass)
+ res = bp.message(makeMessage("!seabass says long"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "long message")
@@ -99,14 +99,14 @@ func TestBabblerMultiSeed(t *testing.T) {
mb := bot.NewMockBot()
bp := newBabblerPlugin(mb)
assert.NotNil(t, bp)
- seabass := makeMessage("This is a message")
+ k, seabass := makeMessage("This is a message")
seabass.User = &user.User{Name: "seabass"}
- res := bp.Message(seabass)
+ res := bp.message(k, seabass)
seabass.Body = "This is another message"
- res = bp.Message(seabass)
+ res = bp.message(k, seabass)
seabass.Body = "This is a long message"
- res = bp.Message(seabass)
- res = bp.Message(makeMessage("!seabass says This is a long"))
+ res = bp.message(k, seabass)
+ res = bp.message(makeMessage("!seabass says This is a long"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "this is a long message")
@@ -116,14 +116,14 @@ func TestBabblerMultiSeed2(t *testing.T) {
mb := bot.NewMockBot()
bp := newBabblerPlugin(mb)
assert.NotNil(t, bp)
- seabass := makeMessage("This is a message")
+ k, seabass := makeMessage("This is a message")
seabass.User = &user.User{Name: "seabass"}
- res := bp.Message(seabass)
+ res := bp.message(k, seabass)
seabass.Body = "This is another message"
- res = bp.Message(seabass)
+ res = bp.message(k, seabass)
seabass.Body = "This is a long message"
- res = bp.Message(seabass)
- res = bp.Message(makeMessage("!seabass says is a long"))
+ res = bp.message(k, seabass)
+ res = bp.message(makeMessage("!seabass says is a long"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "is a long message")
@@ -133,14 +133,14 @@ func TestBabblerBadSeed(t *testing.T) {
mb := bot.NewMockBot()
bp := newBabblerPlugin(mb)
assert.NotNil(t, bp)
- seabass := makeMessage("This is a message")
+ k, seabass := makeMessage("This is a message")
seabass.User = &user.User{Name: "seabass"}
- bp.Message(seabass)
+ bp.message(k, seabass)
seabass.Body = "This is another message"
- bp.Message(seabass)
+ bp.message(k, seabass)
seabass.Body = "This is a long message"
- bp.Message(seabass)
- bp.Message(makeMessage("!seabass says noooo this is bad"))
+ bp.message(k, seabass)
+ bp.message(makeMessage("!seabass says noooo this is bad"))
assert.Len(t, mb.Messages, 1)
assert.Contains(t, mb.Messages[0], "seabass never said 'noooo this is bad'")
}
@@ -149,14 +149,14 @@ func TestBabblerBadSeed2(t *testing.T) {
mb := bot.NewMockBot()
bp := newBabblerPlugin(mb)
assert.NotNil(t, bp)
- seabass := makeMessage("This is a message")
+ k, seabass := makeMessage("This is a message")
seabass.User = &user.User{Name: "seabass"}
- bp.Message(seabass)
+ bp.message(k, seabass)
seabass.Body = "This is another message"
- bp.Message(seabass)
+ bp.message(k, seabass)
seabass.Body = "This is a long message"
- bp.Message(seabass)
- bp.Message(makeMessage("!seabass says This is a really"))
+ bp.message(k, seabass)
+ bp.message(makeMessage("!seabass says This is a really"))
assert.Len(t, mb.Messages, 1)
assert.Contains(t, mb.Messages[0], "seabass never said 'this is a really'")
}
@@ -165,15 +165,15 @@ func TestBabblerSuffixSeed(t *testing.T) {
mb := bot.NewMockBot()
bp := newBabblerPlugin(mb)
assert.NotNil(t, bp)
- seabass := makeMessage("This is message one")
+ k, seabass := makeMessage("This is message one")
seabass.User = &user.User{Name: "seabass"}
- res := bp.Message(seabass)
+ res := bp.message(k, seabass)
seabass.Body = "It's easier to test with unique messages"
- res = bp.Message(seabass)
+ res = bp.message(k, seabass)
seabass.Body = "hi there"
- res = bp.Message(seabass)
- res = bp.Message(makeMessage("!seabass says-tail message one"))
- res = bp.Message(makeMessage("!seabass says-tail with unique"))
+ res = bp.message(k, seabass)
+ res = bp.message(makeMessage("!seabass says-tail message one"))
+ res = bp.message(makeMessage("!seabass says-tail with unique"))
assert.Len(t, mb.Messages, 2)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "this is message one")
@@ -184,14 +184,14 @@ func TestBabblerBadSuffixSeed(t *testing.T) {
mb := bot.NewMockBot()
bp := newBabblerPlugin(mb)
assert.NotNil(t, bp)
- seabass := makeMessage("This is message one")
+ k, seabass := makeMessage("This is message one")
seabass.User = &user.User{Name: "seabass"}
- res := bp.Message(seabass)
+ res := bp.message(k, seabass)
seabass.Body = "It's easier to test with unique messages"
- res = bp.Message(seabass)
+ res = bp.message(k, seabass)
seabass.Body = "hi there"
- res = bp.Message(seabass)
- res = bp.Message(makeMessage("!seabass says-tail anything true"))
+ res = bp.message(k, seabass)
+ res = bp.message(makeMessage("!seabass says-tail anything true"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "seabass never said 'anything true'")
@@ -201,10 +201,10 @@ func TestBabblerBookendSeed(t *testing.T) {
mb := bot.NewMockBot()
bp := newBabblerPlugin(mb)
assert.NotNil(t, bp)
- seabass := makeMessage("It's easier to test with unique messages")
+ k, seabass := makeMessage("It's easier to test with unique messages")
seabass.User = &user.User{Name: "seabass"}
- res := bp.Message(seabass)
- res = bp.Message(makeMessage("!seabass says-bridge It's easier | unique messages"))
+ res := bp.message(k, seabass)
+ res = bp.message(makeMessage("!seabass says-bridge It's easier | unique messages"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "it's easier to test with unique messages")
@@ -214,10 +214,10 @@ func TestBabblerBookendSeedShort(t *testing.T) {
mb := bot.NewMockBot()
bp := newBabblerPlugin(mb)
assert.NotNil(t, bp)
- seabass := makeMessage("It's easier to test with unique messages")
+ k, seabass := makeMessage("It's easier to test with unique messages")
seabass.User = &user.User{Name: "seabass"}
- res := bp.Message(seabass)
- res = bp.Message(makeMessage("!seabass says-bridge It's easier to test with | unique messages"))
+ res := bp.message(k, seabass)
+ res = bp.message(makeMessage("!seabass says-bridge It's easier to test with | unique messages"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "it's easier to test with unique messages")
@@ -227,10 +227,10 @@ func TestBabblerBadBookendSeed(t *testing.T) {
mb := bot.NewMockBot()
bp := newBabblerPlugin(mb)
assert.NotNil(t, bp)
- seabass := makeMessage("It's easier to test with unique messages")
+ k, seabass := makeMessage("It's easier to test with unique messages")
seabass.User = &user.User{Name: "seabass"}
- res := bp.Message(seabass)
- res = bp.Message(makeMessage("!seabass says-bridge It's easier | not unique messages"))
+ res := bp.message(k, seabass)
+ res = bp.message(makeMessage("!seabass says-bridge It's easier | not unique messages"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "seabass never said 'it's easier ... not unique messages'")
@@ -240,10 +240,10 @@ func TestBabblerMiddleOutSeed(t *testing.T) {
mb := bot.NewMockBot()
bp := newBabblerPlugin(mb)
assert.NotNil(t, bp)
- seabass := makeMessage("It's easier to test with unique messages")
+ k, seabass := makeMessage("It's easier to test with unique messages")
seabass.User = &user.User{Name: "seabass"}
- res := bp.Message(seabass)
- res = bp.Message(makeMessage("!seabass says-middle-out test with"))
+ res := bp.message(k, seabass)
+ res = bp.message(makeMessage("!seabass says-middle-out test with"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "it's easier to test with unique messages")
@@ -253,10 +253,10 @@ func TestBabblerBadMiddleOutSeed(t *testing.T) {
mb := bot.NewMockBot()
bp := newBabblerPlugin(mb)
assert.NotNil(t, bp)
- seabass := makeMessage("It's easier to test with unique messages")
+ k, seabass := makeMessage("It's easier to test with unique messages")
seabass.User = &user.User{Name: "seabass"}
- res := bp.Message(seabass)
- res = bp.Message(makeMessage("!seabass says-middle-out anything true"))
+ res := bp.message(k, seabass)
+ res = bp.message(makeMessage("!seabass says-middle-out anything true"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Equal(t, mb.Messages[0], "seabass never said 'anything true'")
@@ -266,10 +266,10 @@ func TestBabblerBatch(t *testing.T) {
mb := bot.NewMockBot()
bp := newBabblerPlugin(mb)
assert.NotNil(t, bp)
- seabass := makeMessage("batch learn for seabass This is a message! This is another message. This is not a long message? This is not a message! This is not another message. This is a long message?")
- res := bp.Message(seabass)
+ k, seabass := makeMessage("batch learn for seabass This is a message! This is another message. This is not a long message? This is not a message! This is not another message. This is a long message?")
+ res := bp.message(k, seabass)
assert.Len(t, mb.Messages, 1)
- res = bp.Message(makeMessage("!seabass says"))
+ res = bp.message(makeMessage("!seabass says"))
assert.Len(t, mb.Messages, 2)
assert.True(t, res)
assert.Contains(t, mb.Messages[1], "this is")
@@ -281,23 +281,23 @@ func TestBabblerMerge(t *testing.T) {
bp := newBabblerPlugin(mb)
assert.NotNil(t, bp)
- seabass := makeMessage(" This is a message")
+ k, seabass := makeMessage(" This is a message")
seabass.User = &user.User{Name: "seabass"}
- res := bp.Message(seabass)
+ res := bp.message(k, seabass)
assert.Len(t, mb.Messages, 0)
seabass.Body = " This is another message"
- res = bp.Message(seabass)
+ res = bp.message(k, seabass)
seabass.Body = " This is a long message"
- res = bp.Message(seabass)
+ res = bp.message(k, seabass)
- res = bp.Message(makeMessage("!merge babbler seabass into seabass2"))
+ res = bp.message(makeMessage("!merge babbler seabass into seabass2"))
assert.True(t, res)
assert.Len(t, mb.Messages, 1)
assert.Contains(t, mb.Messages[0], "mooooiggged")
- res = bp.Message(makeMessage("!seabass2 says"))
+ res = bp.message(makeMessage("!seabass2 says"))
assert.True(t, res)
assert.Len(t, mb.Messages, 2)
@@ -309,24 +309,10 @@ func TestHelp(t *testing.T) {
mb := bot.NewMockBot()
bp := newBabblerPlugin(mb)
assert.NotNil(t, bp)
- bp.Help("channel", []string{})
+ bp.help(bot.Help, msg.Message{Channel: "channel"}, []string{})
assert.Len(t, mb.Messages, 1)
}
-func TestBotMessage(t *testing.T) {
- mb := bot.NewMockBot()
- bp := newBabblerPlugin(mb)
- assert.NotNil(t, bp)
- assert.False(t, bp.BotMessage(makeMessage("test")))
-}
-
-func TestEvent(t *testing.T) {
- mb := bot.NewMockBot()
- bp := newBabblerPlugin(mb)
- assert.NotNil(t, bp)
- assert.False(t, bp.Event("dummy", makeMessage("test")))
-}
-
func TestRegisterWeb(t *testing.T) {
mb := bot.NewMockBot()
bp := newBabblerPlugin(mb)
diff --git a/plugins/beers/beers.go b/plugins/beers/beers.go
index d4da158..7736936 100644
--- a/plugins/beers/beers.go
+++ b/plugins/beers/beers.go
@@ -38,8 +38,8 @@ type untappdUser struct {
}
// New BeersPlugin creates a new BeersPlugin with the Plugin interface
-func New(bot bot.Bot) *BeersPlugin {
- if _, err := bot.DB().Exec(`create table if not exists untappd (
+func New(b bot.Bot) *BeersPlugin {
+ if _, err := b.DB().Exec(`create table if not exists untappd (
id integer primary key,
untappdUser string,
channel string,
@@ -49,19 +49,21 @@ func New(bot bot.Bot) *BeersPlugin {
log.Fatal(err)
}
p := BeersPlugin{
- Bot: bot,
- db: bot.DB(),
+ Bot: b,
+ db: b.DB(),
}
- for _, channel := range bot.Config().GetArray("Untappd.Channels", []string{}) {
+ for _, channel := range b.Config().GetArray("Untappd.Channels", []string{}) {
go p.untappdLoop(channel)
}
+ b.Register(p, bot.Message, p.message)
+ b.Register(p, bot.Help, p.help)
return &p
}
// Message responds to the bot hook on recieving messages.
// This function returns true if the plugin responds in a meaningful way to the users message.
// Otherwise, the function returns false and the bot continues execution of other plugins.
-func (p *BeersPlugin) Message(message msg.Message) bool {
+func (p *BeersPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
parts := strings.Fields(message.Body)
if len(parts) == 0 {
@@ -81,13 +83,13 @@ func (p *BeersPlugin) Message(message msg.Message) bool {
count, err := strconv.Atoi(parts[2])
if err != nil {
// if it's not a number, maybe it's a nick!
- p.Bot.SendMessage(channel, "Sorry, that didn't make any sense.")
+ p.Bot.Send(bot.Message, channel, "Sorry, that didn't make any sense.")
}
if count < 0 {
// you can't be negative
msg := fmt.Sprintf("Sorry %s, you can't have negative beers!", nick)
- p.Bot.SendMessage(channel, msg)
+ p.Bot.Send(bot.Message, channel, msg)
return true
}
if parts[1] == "+=" {
@@ -101,14 +103,14 @@ func (p *BeersPlugin) Message(message msg.Message) bool {
p.randomReply(channel)
}
} else {
- p.Bot.SendMessage(channel, "I don't know your math.")
+ p.Bot.Send(bot.Message, channel, "I don't know your math.")
}
} else if len(parts) == 2 {
if p.doIKnow(parts[1]) {
p.reportCount(parts[1], channel, false)
} else {
msg := fmt.Sprintf("Sorry, I don't know %s.", parts[1])
- p.Bot.SendMessage(channel, msg)
+ p.Bot.Send(bot.Message, channel, msg)
}
} else if len(parts) == 1 {
p.reportCount(nick, channel, true)
@@ -132,7 +134,7 @@ func (p *BeersPlugin) Message(message msg.Message) bool {
channel := message.Channel
if len(parts) < 2 {
- p.Bot.SendMessage(channel, "You must also provide a user name.")
+ p.Bot.Send(bot.Message, channel, "You must also provide a user name.")
} else if len(parts) == 3 {
chanNick = parts[2]
} else if len(parts) == 4 {
@@ -154,7 +156,7 @@ func (p *BeersPlugin) Message(message msg.Message) bool {
log.Println("Error registering untappd: ", err)
}
if count > 0 {
- p.Bot.SendMessage(channel, "I'm already watching you.")
+ p.Bot.Send(bot.Message, channel, "I'm already watching you.")
return true
}
_, err = p.db.Exec(`insert into untappd (
@@ -170,11 +172,11 @@ func (p *BeersPlugin) Message(message msg.Message) bool {
)
if err != nil {
log.Println("Error registering untappd: ", err)
- p.Bot.SendMessage(channel, "I can't see.")
+ p.Bot.Send(bot.Message, channel, "I can't see.")
return true
}
- p.Bot.SendMessage(channel, "I'll be watching you.")
+ p.Bot.Send(bot.Message, channel, "I'll be watching you.")
p.checkUntappd(channel)
@@ -190,17 +192,13 @@ func (p *BeersPlugin) Message(message msg.Message) bool {
return false
}
-// Empty event handler because this plugin does not do anything on event recv
-func (p *BeersPlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
// Help responds to help requests. Every plugin must implement a help function.
-func (p *BeersPlugin) Help(channel string, parts []string) {
+func (p *BeersPlugin) help(kind bot.Kind, message msg.Message, args ...interface{}) bool {
msg := "Beers: imbibe by using either beers +=,=,++ or with the !imbibe/drink " +
"commands. I'll keep a count of how many beers you've had and then if you want " +
"to reset, just !puke it all up!"
- p.Bot.SendMessage(channel, msg)
+ p.Bot.Send(bot.Message, message.Channel, msg)
+ return true
}
func getUserBeers(db *sqlx.DB, user string) counter.Item {
@@ -239,13 +237,13 @@ func (p *BeersPlugin) reportCount(nick, channel string, himself bool) {
msg = fmt.Sprintf("You've had %d beers so far, %s.", beers, nick)
}
}
- p.Bot.SendMessage(channel, msg)
+ p.Bot.Send(bot.Message, channel, msg)
}
func (p *BeersPlugin) puke(user string, channel string) {
p.setBeers(user, 0)
msg := fmt.Sprintf("Ohhhhhh, and a reversal of fortune for %s!", user)
- p.Bot.SendMessage(channel, msg)
+ p.Bot.Send(bot.Message, channel, msg)
}
func (p *BeersPlugin) doIKnow(nick string) bool {
@@ -260,7 +258,7 @@ func (p *BeersPlugin) doIKnow(nick string) bool {
// Sends random affirmation to the channel. This could be better (with a datastore for sayings)
func (p *BeersPlugin) randomReply(channel string) {
replies := []string{"ZIGGY! ZAGGY!", "HIC!", "Stay thirsty, my friend!"}
- p.Bot.SendMessage(channel, replies[rand.Intn(len(replies))])
+ p.Bot.Send(bot.Message, channel, replies[rand.Intn(len(replies))])
}
type checkin struct {
@@ -421,7 +419,7 @@ func (p *BeersPlugin) checkUntappd(channel string) {
}
log.Println("checkin id:", checkin.Checkin_id, "Message:", msg)
- p.Bot.SendMessage(channel, msg)
+ p.Bot.Send(bot.Message, channel, msg)
}
}
@@ -439,14 +437,7 @@ func (p *BeersPlugin) untappdLoop(channel string) {
}
}
-// Handler for bot's own messages
-func (p *BeersPlugin) BotMessage(message msg.Message) bool {
- return false
-}
-
// Register any web URLs desired
-func (p *BeersPlugin) RegisterWeb() *string {
+func (p BeersPlugin) RegisterWeb() *string {
return nil
}
-
-func (p *BeersPlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
diff --git a/plugins/beers/beers_test.go b/plugins/beers/beers_test.go
index 99964e3..bb34008 100644
--- a/plugins/beers/beers_test.go
+++ b/plugins/beers/beers_test.go
@@ -13,12 +13,12 @@ import (
"github.com/velour/catbase/plugins/counter"
)
-func makeMessage(payload string) msg.Message {
+func makeMessage(payload string) (bot.Kind, msg.Message) {
isCmd := strings.HasPrefix(payload, "!")
if isCmd {
payload = payload[1:]
}
- return msg.Message{
+ return bot.Message, msg.Message{
User: &user.User{Name: "tester"},
Channel: "test",
Body: payload,
@@ -31,8 +31,8 @@ func makeBeersPlugin(t *testing.T) (*BeersPlugin, *bot.MockBot) {
counter.New(mb)
mb.DB().MustExec(`delete from counter; delete from counter_alias;`)
b := New(mb)
- b.Message(makeMessage("!mkalias beer :beer:"))
- b.Message(makeMessage("!mkalias beers :beer:"))
+ b.message(makeMessage("!mkalias beer :beer:"))
+ b.message(makeMessage("!mkalias beers :beer:"))
return b, mb
}
@@ -49,9 +49,9 @@ func TestCounter(t *testing.T) {
func TestImbibe(t *testing.T) {
b, mb := makeBeersPlugin(t)
- b.Message(makeMessage("!imbibe"))
+ b.message(makeMessage("!imbibe"))
assert.Len(t, mb.Messages, 1)
- b.Message(makeMessage("!imbibe"))
+ b.message(makeMessage("!imbibe"))
assert.Len(t, mb.Messages, 2)
it, err := counter.GetItem(mb.DB(), "tester", itemName)
assert.Nil(t, err)
@@ -59,7 +59,7 @@ func TestImbibe(t *testing.T) {
}
func TestEq(t *testing.T) {
b, mb := makeBeersPlugin(t)
- b.Message(makeMessage("!beers = 3"))
+ b.message(makeMessage("!beers = 3"))
assert.Len(t, mb.Messages, 1)
it, err := counter.GetItem(mb.DB(), "tester", itemName)
assert.Nil(t, err)
@@ -68,7 +68,7 @@ func TestEq(t *testing.T) {
func TestEqNeg(t *testing.T) {
b, mb := makeBeersPlugin(t)
- b.Message(makeMessage("!beers = -3"))
+ b.message(makeMessage("!beers = -3"))
assert.Len(t, mb.Messages, 1)
it, err := counter.GetItem(mb.DB(), "tester", itemName)
assert.Nil(t, err)
@@ -77,8 +77,8 @@ func TestEqNeg(t *testing.T) {
func TestEqZero(t *testing.T) {
b, mb := makeBeersPlugin(t)
- b.Message(makeMessage("beers += 5"))
- b.Message(makeMessage("!beers = 0"))
+ b.message(makeMessage("beers += 5"))
+ b.message(makeMessage("!beers = 0"))
assert.Len(t, mb.Messages, 2)
assert.Contains(t, mb.Messages[1], "reversal of fortune")
it, err := counter.GetItem(mb.DB(), "tester", itemName)
@@ -88,9 +88,9 @@ func TestEqZero(t *testing.T) {
func TestBeersPlusEq(t *testing.T) {
b, mb := makeBeersPlugin(t)
- b.Message(makeMessage("beers += 5"))
+ b.message(makeMessage("beers += 5"))
assert.Len(t, mb.Messages, 1)
- b.Message(makeMessage("beers += 5"))
+ b.message(makeMessage("beers += 5"))
assert.Len(t, mb.Messages, 2)
it, err := counter.GetItem(mb.DB(), "tester", itemName)
assert.Nil(t, err)
@@ -99,11 +99,11 @@ func TestBeersPlusEq(t *testing.T) {
func TestPuke(t *testing.T) {
b, mb := makeBeersPlugin(t)
- b.Message(makeMessage("beers += 5"))
+ b.message(makeMessage("beers += 5"))
it, err := counter.GetItem(mb.DB(), "tester", itemName)
assert.Nil(t, err)
assert.Equal(t, 5, it.Count)
- b.Message(makeMessage("puke"))
+ b.message(makeMessage("puke"))
it, err = counter.GetItem(mb.DB(), "tester", itemName)
assert.Nil(t, err)
assert.Equal(t, 0, it.Count)
@@ -111,30 +111,20 @@ func TestPuke(t *testing.T) {
func TestBeersReport(t *testing.T) {
b, mb := makeBeersPlugin(t)
- b.Message(makeMessage("beers += 5"))
+ b.message(makeMessage("beers += 5"))
it, err := counter.GetItem(mb.DB(), "tester", itemName)
assert.Nil(t, err)
assert.Equal(t, 5, it.Count)
- b.Message(makeMessage("beers"))
+ b.message(makeMessage("beers"))
assert.Contains(t, mb.Messages[1], "5 beers")
}
func TestHelp(t *testing.T) {
b, mb := makeBeersPlugin(t)
- b.Help("channel", []string{})
+ b.help(bot.Help, msg.Message{Channel: "channel"}, []string{})
assert.Len(t, mb.Messages, 1)
}
-func TestBotMessage(t *testing.T) {
- b, _ := makeBeersPlugin(t)
- assert.False(t, b.BotMessage(makeMessage("test")))
-}
-
-func TestEvent(t *testing.T) {
- b, _ := makeBeersPlugin(t)
- assert.False(t, b.Event("dummy", makeMessage("test")))
-}
-
func TestRegisterWeb(t *testing.T) {
b, _ := makeBeersPlugin(t)
assert.Nil(t, b.RegisterWeb())
diff --git a/plugins/couldashouldawoulda/csw.go b/plugins/couldashouldawoulda/csw.go
index 455c45d..9d2d7a3 100644
--- a/plugins/couldashouldawoulda/csw.go
+++ b/plugins/couldashouldawoulda/csw.go
@@ -17,13 +17,15 @@ type CSWPlugin struct {
Config *config.Config
}
-func New(bot bot.Bot) *CSWPlugin {
- return &CSWPlugin{
- Bot: bot,
+func New(b bot.Bot) *CSWPlugin {
+ csw := &CSWPlugin{
+ Bot: b,
}
+ b.Register(csw, bot.Message, csw.message)
+ return csw
}
-func (p *CSWPlugin) Message(message msg.Message) bool {
+func (p *CSWPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
if !message.Command {
return false
}
@@ -63,25 +65,13 @@ func (p *CSWPlugin) Message(message msg.Message) bool {
}
}
- p.Bot.SendMessage(message.Channel, responses[rand.Intn(len(responses))])
+ p.Bot.Send(bot.Message, message.Channel, responses[rand.Intn(len(responses))])
return true
}
return false
}
-func (p *CSWPlugin) Help(channel string, parts []string) {}
-
-func (p *CSWPlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
-func (p *CSWPlugin) BotMessage(message msg.Message) bool {
- return false
-}
-
-func (p *CSWPlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
-
func (p *CSWPlugin) RegisterWeb() *string {
return nil
}
diff --git a/plugins/couldashouldawoulda/csw_test.go b/plugins/couldashouldawoulda/csw_test.go
index 73b5261..de60dc9 100644
--- a/plugins/couldashouldawoulda/csw_test.go
+++ b/plugins/couldashouldawoulda/csw_test.go
@@ -12,12 +12,12 @@ import (
"github.com/velour/catbase/bot/user"
)
-func makeMessage(payload string) msg.Message {
+func makeMessage(payload string) (bot.Kind, msg.Message) {
isCmd := strings.HasPrefix(payload, "!")
if isCmd {
payload = payload[1:]
}
- return msg.Message{
+ return bot.Message, msg.Message{
User: &user.User{Name: "tester"},
Channel: "test",
Body: payload,
@@ -29,7 +29,7 @@ func Test0(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("!should I drink a beer?"))
+ res := c.message(makeMessage("!should I drink a beer?"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
possibilities := []string{"Yes.", "No.", "Maybe.", "For fucks sake, how should I know?"}
@@ -47,7 +47,7 @@ func Test1(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("!should I drink a beer or a bourbon?"))
+ res := c.message(makeMessage("!should I drink a beer or a bourbon?"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
possibilities := []string{"The former.", "The latter.", "Obviously the former.", "Clearly the latter.", "Can't it be both?"}
@@ -65,7 +65,7 @@ func Test2(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("!could I drink a beer or a bourbon?"))
+ res := c.message(makeMessage("!could I drink a beer or a bourbon?"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
possibilities := []string{"Yes.", "No.", "Maybe.", "For fucks sake, how should I know?"}
@@ -83,7 +83,7 @@ func Test3(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("!would I die if I drank too much bourbon?"))
+ res := c.message(makeMessage("!would I die if I drank too much bourbon?"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
possibilities := []string{"Yes.", "No.", "Maybe.", "For fucks sake, how should I know?"}
@@ -101,7 +101,7 @@ func Test4(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("!would I die or be sick if I drank all the bourbon?"))
+ res := c.message(makeMessage("!would I die or be sick if I drank all the bourbon?"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
possibilities := []string{"The former.", "The latter.", "Obviously the former.", "Clearly the latter.", "Can't it be both?"}
@@ -119,7 +119,7 @@ func Test5(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("!should I have another beer or bourbon or tequila?"))
+ res := c.message(makeMessage("!should I have another beer or bourbon or tequila?"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
possibilities := []string{"I'd say option", "You'd be an idiot not to choose the"}
diff --git a/plugins/counter/counter.go b/plugins/counter/counter.go
index 2c7668a..6d0e0ed 100644
--- a/plugins/counter/counter.go
+++ b/plugins/counter/counter.go
@@ -172,31 +172,34 @@ func (i *Item) Delete() error {
}
// NewCounterPlugin creates a new CounterPlugin with the Plugin interface
-func New(bot bot.Bot) *CounterPlugin {
- tx := bot.DB().MustBegin()
- bot.DB().MustExec(`create table if not exists counter (
+func New(b bot.Bot) *CounterPlugin {
+ tx := b.DB().MustBegin()
+ b.DB().MustExec(`create table if not exists counter (
id integer primary key,
nick string,
item string,
count integer
);`)
- bot.DB().MustExec(`create table if not exists counter_alias (
+ b.DB().MustExec(`create table if not exists counter_alias (
id integer PRIMARY KEY AUTOINCREMENT,
item string NOT NULL UNIQUE,
points_to string NOT NULL
);`)
tx.Commit()
- return &CounterPlugin{
- Bot: bot,
- DB: bot.DB(),
+ cp := &CounterPlugin{
+ Bot: b,
+ DB: b.DB(),
}
+ b.Register(cp, bot.Message, cp.message)
+ b.Register(cp, bot.Help, cp.help)
+ return cp
}
// Message responds to the bot hook on recieving messages.
// This function returns true if the plugin responds in a meaningful way to the
// users message. Otherwise, the function returns false and the bot continues
// execution of other plugins.
-func (p *CounterPlugin) Message(message msg.Message) bool {
+func (p *CounterPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
// This bot does not reply to anything
nick := message.User.Name
channel := message.Channel
@@ -211,7 +214,7 @@ func (p *CounterPlugin) Message(message msg.Message) bool {
log.Println(err)
return false
}
- p.Bot.SendMessage(channel, fmt.Sprintf("Created alias %s -> %s",
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("Created alias %s -> %s",
parts[1], parts[2]))
return true
} else if strings.ToLower(parts[0]) == "leaderboard" {
@@ -241,7 +244,7 @@ func (p *CounterPlugin) Message(message msg.Message) bool {
it.Item,
)
}
- p.Bot.SendMessage(channel, out)
+ p.Bot.Send(bot.Message, channel, out)
return true
} else if match := teaMatcher.MatchString(message.Body); match {
// check for tea match TTT
@@ -250,14 +253,14 @@ func (p *CounterPlugin) Message(message msg.Message) bool {
items, err := GetItems(p.DB, strings.ToLower(nick))
if err != nil {
log.Printf("Error getting items to reset %s: %s", nick, err)
- p.Bot.SendMessage(channel, "Something is technically wrong with your counters.")
+ p.Bot.Send(bot.Message, channel, "Something is technically wrong with your counters.")
return true
}
log.Printf("Items: %+v", items)
for _, item := range items {
item.Delete()
}
- p.Bot.SendMessage(channel, fmt.Sprintf("%s, you are as new, my son.", nick))
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("%s, you are as new, my son.", nick))
return true
} else if message.Command && parts[0] == "inspect" && len(parts) == 2 {
var subject string
@@ -273,7 +276,7 @@ func (p *CounterPlugin) Message(message msg.Message) bool {
items, err := GetItems(p.DB, subject)
if err != nil {
log.Fatalf("Error retrieving items for %s: %s", subject, err)
- p.Bot.SendMessage(channel, "Something went wrong finding that counter;")
+ p.Bot.Send(bot.Message, channel, "Something went wrong finding that counter;")
return true
}
@@ -293,11 +296,11 @@ func (p *CounterPlugin) Message(message msg.Message) bool {
resp += "."
if count == 0 {
- p.Bot.SendMessage(channel, fmt.Sprintf("%s has no counters.", subject))
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("%s has no counters.", subject))
return true
}
- p.Bot.SendMessage(channel, resp)
+ p.Bot.Send(bot.Message, channel, resp)
return true
} else if message.Command && len(parts) == 2 && parts[0] == "clear" {
subject := strings.ToLower(nick)
@@ -306,17 +309,17 @@ func (p *CounterPlugin) Message(message msg.Message) bool {
it, err := GetItem(p.DB, subject, itemName)
if err != nil {
log.Printf("Error getting item to remove %s.%s: %s", subject, itemName, err)
- p.Bot.SendMessage(channel, "Something went wrong removing that counter;")
+ p.Bot.Send(bot.Message, channel, "Something went wrong removing that counter;")
return true
}
err = it.Delete()
if err != nil {
log.Printf("Error removing item %s.%s: %s", subject, itemName, err)
- p.Bot.SendMessage(channel, "Something went wrong removing that counter;")
+ p.Bot.Send(bot.Message, channel, "Something went wrong removing that counter;")
return true
}
- p.Bot.SendAction(channel, fmt.Sprintf("chops a few %s out of his brain",
+ p.Bot.Send(bot.Action, channel, fmt.Sprintf("chops a few %s out of his brain",
itemName))
return true
@@ -339,7 +342,7 @@ func (p *CounterPlugin) Message(message msg.Message) bool {
item, err := GetItem(p.DB, subject, itemName)
switch {
case err == sql.ErrNoRows:
- p.Bot.SendMessage(channel, fmt.Sprintf("I don't think %s has any %s.",
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("I don't think %s has any %s.",
subject, itemName))
return true
case err != nil:
@@ -348,7 +351,7 @@ func (p *CounterPlugin) Message(message msg.Message) bool {
return true
}
- p.Bot.SendMessage(channel, fmt.Sprintf("%s has %d %s.", subject, item.Count,
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("%s has %d %s.", subject, item.Count,
itemName))
return true
@@ -379,7 +382,7 @@ func (p *CounterPlugin) Message(message msg.Message) bool {
}
log.Printf("About to update item: %#v", item)
item.UpdateDelta(1)
- p.Bot.SendMessage(channel, fmt.Sprintf("%s has %d %s.", subject,
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("%s has %d %s.", subject,
item.Count, item.Item))
return true
} else if strings.HasSuffix(parts[0], "--") {
@@ -391,7 +394,7 @@ func (p *CounterPlugin) Message(message msg.Message) bool {
return false
}
item.UpdateDelta(-1)
- p.Bot.SendMessage(channel, fmt.Sprintf("%s has %d %s.", subject,
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("%s has %d %s.", subject,
item.Count, item.Item))
return true
}
@@ -420,7 +423,7 @@ func (p *CounterPlugin) Message(message msg.Message) bool {
n, _ := strconv.Atoi(parts[2])
log.Printf("About to update item by %d: %#v", n, item)
item.UpdateDelta(n)
- p.Bot.SendMessage(channel, fmt.Sprintf("%s has %d %s.", subject,
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("%s has %d %s.", subject,
item.Count, item.Item))
return true
} else if parts[1] == "-=" {
@@ -434,7 +437,7 @@ func (p *CounterPlugin) Message(message msg.Message) bool {
n, _ := strconv.Atoi(parts[2])
log.Printf("About to update item by -%d: %#v", n, item)
item.UpdateDelta(-n)
- p.Bot.SendMessage(channel, fmt.Sprintf("%s has %d %s.", subject,
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("%s has %d %s.", subject,
item.Count, item.Item))
return true
}
@@ -444,21 +447,12 @@ func (p *CounterPlugin) Message(message msg.Message) bool {
}
// Help responds to help requests. Every plugin must implement a help function.
-func (p *CounterPlugin) Help(channel string, parts []string) {
- p.Bot.SendMessage(channel, "You can set counters incrementally by using "+
+func (p *CounterPlugin) help(kind bot.Kind, message msg.Message, args ...interface{}) bool {
+ p.Bot.Send(bot.Message, message.Channel, "You can set counters incrementally by using "+
"++ and --. You can see all of your counters using "+
"\"inspect\", erase them with \"clear\", and view single counters with "+
"\"count\".")
-}
-
-// Empty event handler because this plugin does not do anything on event recv
-func (p *CounterPlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
-// Handler for bot's own messages
-func (p *CounterPlugin) BotMessage(message msg.Message) bool {
- return false
+ return true
}
// Register any web URLs desired
@@ -466,8 +460,6 @@ func (p *CounterPlugin) RegisterWeb() *string {
return nil
}
-func (p *CounterPlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
-
func (p *CounterPlugin) checkMatch(message msg.Message) bool {
nick := message.User.Name
channel := message.Channel
@@ -487,7 +479,7 @@ func (p *CounterPlugin) checkMatch(message msg.Message) bool {
}
log.Printf("About to update item: %#v", item)
item.UpdateDelta(1)
- p.Bot.SendMessage(channel, fmt.Sprintf("bleep-bloop-blop... %s has %d %s",
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("bleep-bloop-blop... %s has %d %s",
nick, item.Count, itemName))
return true
}
diff --git a/plugins/counter/counter_test.go b/plugins/counter/counter_test.go
index f1c673c..1cbec0c 100644
--- a/plugins/counter/counter_test.go
+++ b/plugins/counter/counter_test.go
@@ -22,12 +22,12 @@ func setup(t *testing.T) (*bot.MockBot, *CounterPlugin) {
return mb, c
}
-func makeMessage(payload string) msg.Message {
+func makeMessage(payload string) (bot.Kind, msg.Message) {
isCmd := strings.HasPrefix(payload, "!")
if isCmd {
payload = payload[1:]
}
- return msg.Message{
+ return bot.Message, msg.Message{
User: &user.User{Name: "tester"},
Channel: "test",
Body: payload,
@@ -38,8 +38,8 @@ func makeMessage(payload string) msg.Message {
func TestThreeSentencesExists(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
- c.Message(makeMessage(":beer:++"))
- c.Message(makeMessage(":beer:. Earl Grey. Hot."))
+ c.message(makeMessage(":beer:++"))
+ c.message(makeMessage(":beer:. Earl Grey. Hot."))
item, err := GetItem(mb.DB(), "tester", ":beer:")
assert.Nil(t, err)
assert.Equal(t, 2, item.Count)
@@ -49,7 +49,7 @@ func TestThreeSentencesNotExists(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
item, err := GetItem(mb.DB(), "tester", ":beer:")
- c.Message(makeMessage(":beer:. Earl Grey. Hot."))
+ c.message(makeMessage(":beer:. Earl Grey. Hot."))
item, err = GetItem(mb.DB(), "tester", ":beer:")
assert.Nil(t, err)
assert.Equal(t, 0, item.Count)
@@ -58,8 +58,8 @@ func TestThreeSentencesNotExists(t *testing.T) {
func TestTeaEarlGreyHot(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
- c.Message(makeMessage("Tea. Earl Grey. Hot."))
- c.Message(makeMessage("Tea. Earl Grey. Hot."))
+ c.message(makeMessage("Tea. Earl Grey. Hot."))
+ c.message(makeMessage("Tea. Earl Grey. Hot."))
item, err := GetItem(mb.DB(), "tester", ":tea:")
assert.Nil(t, err)
assert.Equal(t, 2, item.Count)
@@ -68,8 +68,8 @@ func TestTeaEarlGreyHot(t *testing.T) {
func TestTeaTwoPeriods(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
- c.Message(makeMessage("Tea. Earl Grey."))
- c.Message(makeMessage("Tea. Earl Grey."))
+ c.message(makeMessage("Tea. Earl Grey."))
+ c.message(makeMessage("Tea. Earl Grey."))
item, err := GetItem(mb.DB(), "tester", ":tea:")
assert.Nil(t, err)
assert.Equal(t, 0, item.Count)
@@ -78,8 +78,8 @@ func TestTeaTwoPeriods(t *testing.T) {
func TestTeaMultiplePeriods(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
- c.Message(makeMessage("Tea. Earl Grey. Spiked. Hot."))
- c.Message(makeMessage("Tea. Earl Grey. Spiked. Hot."))
+ c.message(makeMessage("Tea. Earl Grey. Spiked. Hot."))
+ c.message(makeMessage("Tea. Earl Grey. Spiked. Hot."))
item, err := GetItem(mb.DB(), "tester", ":tea:")
assert.Nil(t, err)
assert.Equal(t, 2, item.Count)
@@ -88,9 +88,9 @@ func TestTeaMultiplePeriods(t *testing.T) {
func TestTeaGreenHot(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
- c.Message(makeMessage("Tea. Green. Hot."))
- c.Message(makeMessage("Tea. Green. Hot"))
- c.Message(makeMessage("Tea. Green. Iced."))
+ c.message(makeMessage("Tea. Green. Hot."))
+ c.message(makeMessage("Tea. Green. Hot"))
+ c.message(makeMessage("Tea. Green. Iced."))
item, err := GetItem(mb.DB(), "tester", ":tea:")
assert.Nil(t, err)
assert.Equal(t, 3, item.Count)
@@ -99,8 +99,8 @@ func TestTeaGreenHot(t *testing.T) {
func TestTeaUnrelated(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
- c.Message(makeMessage("Tea."))
- c.Message(makeMessage("Tea. It's great."))
+ c.message(makeMessage("Tea."))
+ c.message(makeMessage("Tea. It's great."))
item, err := GetItem(mb.DB(), "tester", ":tea:")
assert.Nil(t, err)
assert.Equal(t, 0, item.Count)
@@ -109,7 +109,7 @@ func TestTeaUnrelated(t *testing.T) {
func TestTeaSkieselQuote(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
- c.Message(makeMessage("blah, this is a whole page of explanation where \"we did local search and used a tabu list\" would have sufficed"))
+ c.message(makeMessage("blah, this is a whole page of explanation where \"we did local search and used a tabu list\" would have sufficed"))
item, err := GetItem(mb.DB(), "tester", ":tea:")
assert.Nil(t, err)
assert.Equal(t, 0, item.Count)
@@ -117,7 +117,7 @@ func TestTeaSkieselQuote(t *testing.T) {
func TestTeaUnicodeJapanese(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
- c.Message(makeMessage("Tea. おちや. Hot."))
+ c.message(makeMessage("Tea. おちや. Hot."))
item, err := GetItem(mb.DB(), "tester", ":tea:")
assert.Nil(t, err)
assert.Equal(t, 1, item.Count)
@@ -126,8 +126,8 @@ func TestTeaUnicodeJapanese(t *testing.T) {
func TestResetMe(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
- c.Message(makeMessage("test++"))
- c.Message(makeMessage("!reset me"))
+ c.message(makeMessage("test++"))
+ c.message(makeMessage("!reset me"))
items, err := GetItems(mb.DB(), "tester")
assert.Nil(t, err)
assert.Len(t, items, 0)
@@ -136,7 +136,7 @@ func TestResetMe(t *testing.T) {
func TestCounterOne(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
- c.Message(makeMessage("test++"))
+ c.message(makeMessage("test++"))
assert.Len(t, mb.Messages, 1)
assert.Equal(t, mb.Messages[0], "tester has 1 test.")
}
@@ -144,7 +144,7 @@ func TestCounterOne(t *testing.T) {
func TestCounterOneWithSpace(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
- c.Message(makeMessage(":test: ++"))
+ c.message(makeMessage(":test: ++"))
assert.Len(t, mb.Messages, 1)
assert.Equal(t, mb.Messages[0], "tester has 1 :test:.")
}
@@ -153,7 +153,7 @@ func TestCounterFour(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
for i := 0; i < 4; i++ {
- c.Message(makeMessage("test++"))
+ c.message(makeMessage("test++"))
}
assert.Len(t, mb.Messages, 4)
assert.Equal(t, mb.Messages[3], "tester has 4 test.")
@@ -163,10 +163,10 @@ func TestCounterDecrement(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
for i := 0; i < 4; i++ {
- c.Message(makeMessage("test++"))
+ c.message(makeMessage("test++"))
assert.Equal(t, mb.Messages[i], fmt.Sprintf("tester has %d test.", i+1))
}
- c.Message(makeMessage("test--"))
+ c.message(makeMessage("test--"))
assert.Len(t, mb.Messages, 5)
assert.Equal(t, mb.Messages[4], "tester has 3 test.")
}
@@ -175,10 +175,10 @@ func TestFriendCounterDecrement(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
for i := 0; i < 4; i++ {
- c.Message(makeMessage("other.test++"))
+ c.message(makeMessage("other.test++"))
assert.Equal(t, mb.Messages[i], fmt.Sprintf("other has %d test.", i+1))
}
- c.Message(makeMessage("other.test--"))
+ c.message(makeMessage("other.test--"))
assert.Len(t, mb.Messages, 5)
assert.Equal(t, mb.Messages[4], "other has 3 test.")
}
@@ -187,12 +187,12 @@ func TestDecrementZero(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
for i := 0; i < 4; i++ {
- c.Message(makeMessage("test++"))
+ c.message(makeMessage("test++"))
assert.Equal(t, mb.Messages[i], fmt.Sprintf("tester has %d test.", i+1))
}
j := 4
for i := 4; i > 0; i-- {
- c.Message(makeMessage("test--"))
+ c.message(makeMessage("test--"))
assert.Equal(t, mb.Messages[j], fmt.Sprintf("tester has %d test.", i-1))
j++
}
@@ -204,10 +204,10 @@ func TestClear(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
for i := 0; i < 4; i++ {
- c.Message(makeMessage("test++"))
+ c.message(makeMessage("test++"))
assert.Equal(t, mb.Messages[i], fmt.Sprintf("tester has %d test.", i+1))
}
- res := c.Message(makeMessage("!clear test"))
+ res := c.message(makeMessage("!clear test"))
assert.True(t, res)
assert.Len(t, mb.Actions, 1)
assert.Equal(t, mb.Actions[0], "chops a few test out of his brain")
@@ -217,10 +217,10 @@ func TestCount(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
for i := 0; i < 4; i++ {
- c.Message(makeMessage("test++"))
+ c.message(makeMessage("test++"))
assert.Equal(t, mb.Messages[i], fmt.Sprintf("tester has %d test.", i+1))
}
- res := c.Message(makeMessage("!count test"))
+ res := c.message(makeMessage("!count test"))
assert.True(t, res)
assert.Len(t, mb.Messages, 5)
assert.Equal(t, mb.Messages[4], "tester has 4 test.")
@@ -230,18 +230,18 @@ func TestInspectMe(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
for i := 0; i < 4; i++ {
- c.Message(makeMessage("test++"))
+ c.message(makeMessage("test++"))
assert.Equal(t, mb.Messages[i], fmt.Sprintf("tester has %d test.", i+1))
}
for i := 0; i < 2; i++ {
- c.Message(makeMessage("fucks++"))
+ c.message(makeMessage("fucks++"))
assert.Equal(t, mb.Messages[i+4], fmt.Sprintf("tester has %d fucks.", i+1))
}
for i := 0; i < 20; i++ {
- c.Message(makeMessage("cheese++"))
+ c.message(makeMessage("cheese++"))
assert.Equal(t, mb.Messages[i+6], fmt.Sprintf("tester has %d cheese.", i+1))
}
- res := c.Message(makeMessage("!inspect me"))
+ res := c.message(makeMessage("!inspect me"))
assert.True(t, res)
assert.Len(t, mb.Messages, 27)
assert.Equal(t, mb.Messages[26], "tester has the following counters: test: 4, fucks: 2, cheese: 20.")
@@ -250,22 +250,10 @@ func TestInspectMe(t *testing.T) {
func TestHelp(t *testing.T) {
mb, c := setup(t)
assert.NotNil(t, c)
- c.Help("channel", []string{})
+ c.help(bot.Help, msg.Message{Channel: "channel"}, []string{})
assert.Len(t, mb.Messages, 1)
}
-func TestBotMessage(t *testing.T) {
- _, c := setup(t)
- assert.NotNil(t, c)
- assert.False(t, c.BotMessage(makeMessage("test")))
-}
-
-func TestEvent(t *testing.T) {
- _, c := setup(t)
- assert.NotNil(t, c)
- assert.False(t, c.Event("dummy", makeMessage("test")))
-}
-
func TestRegisterWeb(t *testing.T) {
_, c := setup(t)
assert.NotNil(t, c)
diff --git a/plugins/dice/dice.go b/plugins/dice/dice.go
index 104e016..721a652 100644
--- a/plugins/dice/dice.go
+++ b/plugins/dice/dice.go
@@ -19,10 +19,13 @@ type DicePlugin struct {
}
// NewDicePlugin creates a new DicePlugin with the Plugin interface
-func New(bot bot.Bot) *DicePlugin {
- return &DicePlugin{
- Bot: bot,
+func New(b bot.Bot) *DicePlugin {
+ dp := &DicePlugin{
+ Bot: b,
}
+ b.Register(dp, bot.Message, dp.message)
+ b.Register(dp, bot.Help, dp.help)
+ return dp
}
func rollDie(sides int) int {
@@ -32,7 +35,7 @@ func rollDie(sides int) int {
// Message responds to the bot hook on recieving messages.
// This function returns true if the plugin responds in a meaningful way to the users message.
// Otherwise, the function returns false and the bot continues execution of other plugins.
-func (p *DicePlugin) Message(message msg.Message) bool {
+func (p *DicePlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
if !message.Command {
return false
}
@@ -46,7 +49,7 @@ func (p *DicePlugin) Message(message msg.Message) bool {
}
if sides < 2 || nDice < 1 || nDice > 20 {
- p.Bot.SendMessage(channel, "You're a dick.")
+ p.Bot.Send(bot.Message, channel, "You're a dick.")
return true
}
@@ -61,29 +64,18 @@ func (p *DicePlugin) Message(message msg.Message) bool {
}
}
- p.Bot.SendMessage(channel, rolls)
+ p.Bot.Send(bot.Message, channel, rolls)
return true
}
// Help responds to help requests. Every plugin must implement a help function.
-func (p *DicePlugin) Help(channel string, parts []string) {
- p.Bot.SendMessage(channel, "Roll dice using notation XdY. Try \"3d20\".")
-}
-
-// Empty event handler because this plugin does not do anything on event recv
-func (p *DicePlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
-// Handler for bot's own messages
-func (p *DicePlugin) BotMessage(message msg.Message) bool {
- return false
+func (p *DicePlugin) help(kind bot.Kind, message msg.Message, args ...interface{}) bool {
+ p.Bot.Send(bot.Message, message.Channel, "Roll dice using notation XdY. Try \"3d20\".")
+ return true
}
// Register any web URLs desired
func (p *DicePlugin) RegisterWeb() *string {
return nil
}
-
-func (p *DicePlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
diff --git a/plugins/dice/dice_test.go b/plugins/dice/dice_test.go
index ec060de..bcb7a26 100644
--- a/plugins/dice/dice_test.go
+++ b/plugins/dice/dice_test.go
@@ -12,12 +12,12 @@ import (
"github.com/velour/catbase/bot/user"
)
-func makeMessage(payload string) msg.Message {
+func makeMessage(payload string) (bot.Kind, msg.Message) {
isCmd := strings.HasPrefix(payload, "!")
if isCmd {
payload = payload[1:]
}
- return msg.Message{
+ return bot.Message, msg.Message{
User: &user.User{Name: "tester"},
Channel: "test",
Body: payload,
@@ -29,7 +29,7 @@ func TestDie(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("!1d6"))
+ res := c.message(makeMessage("!1d6"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "tester, you rolled:")
@@ -39,7 +39,7 @@ func TestDice(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("!5d6"))
+ res := c.message(makeMessage("!5d6"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "tester, you rolled:")
@@ -49,7 +49,7 @@ func TestNotCommand(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("1d6"))
+ res := c.message(makeMessage("1d6"))
assert.False(t, res)
assert.Len(t, mb.Messages, 0)
}
@@ -58,7 +58,7 @@ func TestBadDice(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("!aued6"))
+ res := c.message(makeMessage("!aued6"))
assert.False(t, res)
assert.Len(t, mb.Messages, 0)
}
@@ -67,7 +67,7 @@ func TestBadSides(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("!1daoeu"))
+ res := c.message(makeMessage("!1daoeu"))
assert.False(t, res)
assert.Len(t, mb.Messages, 0)
}
@@ -76,7 +76,7 @@ func TestLotsOfDice(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("!100d100"))
+ res := c.message(makeMessage("!100d100"))
assert.True(t, res)
assert.Len(t, mb.Messages, 1)
assert.Contains(t, mb.Messages[0], "You're a dick.")
@@ -86,24 +86,10 @@ func TestHelp(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- c.Help("channel", []string{})
+ c.help(bot.Help, msg.Message{Channel: "channel"}, []string{})
assert.Len(t, mb.Messages, 1)
}
-func TestBotMessage(t *testing.T) {
- mb := bot.NewMockBot()
- c := New(mb)
- assert.NotNil(t, c)
- assert.False(t, c.BotMessage(makeMessage("test")))
-}
-
-func TestEvent(t *testing.T) {
- mb := bot.NewMockBot()
- c := New(mb)
- assert.NotNil(t, c)
- assert.False(t, c.Event("dummy", makeMessage("test")))
-}
-
func TestRegisterWeb(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
diff --git a/plugins/downtime/downtime.go b/plugins/downtime/downtime.go
index e50df61..335886e 100644
--- a/plugins/downtime/downtime.go
+++ b/plugins/downtime/downtime.go
@@ -142,9 +142,9 @@ func (p *DowntimePlugin) Message(message msg.Message) bool {
}
if !entry.id.Valid {
// couldn't find em
- p.Bot.SendMessage(channel, fmt.Sprintf("Sorry, I don't know %s.", nick))
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("Sorry, I don't know %s.", nick))
} else {
- p.Bot.SendMessage(channel, fmt.Sprintf("%s has been idle for: %s",
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("%s has been idle for: %s",
nick, time.Now().Sub(entry.lastSeen)))
}
ret = true
@@ -165,7 +165,7 @@ func (p *DowntimePlugin) Message(message msg.Message) bool {
tops = fmt.Sprintf("%s%s: %s ", tops, e.nick, time.Now().Sub(e.lastSeen))
}
}
- p.Bot.SendMessage(channel, tops)
+ p.Bot.Send(bot.Message, channel, tops)
ret = true
}
@@ -197,7 +197,7 @@ func (p *DowntimePlugin) remove(user string) error {
// Help responds to help requests. Every plugin must implement a help function.
func (p *DowntimePlugin) Help(channel string, parts []string) {
- p.Bot.SendMessage(channel, "Ask me how long one of your friends has been idele with, \"idle \"")
+ p.Bot.Send(bot.Message, channel, "Ask me how long one of your friends has been idele with, \"idle \"")
}
// Empty event handler because this plugin does not do anything on event recv
diff --git a/plugins/emojifyme/emojifyme.go b/plugins/emojifyme/emojifyme.go
index 26b5b72..03b7fbb 100644
--- a/plugins/emojifyme/emojifyme.go
+++ b/plugins/emojifyme/emojifyme.go
@@ -20,7 +20,7 @@ type EmojifyMePlugin struct {
Emoji map[string]string
}
-func New(bot bot.Bot) *EmojifyMePlugin {
+func New(b bot.Bot) *EmojifyMePlugin {
resp, err := http.Get("https://raw.githubusercontent.com/github/gemoji/master/db/emoji.json")
if err != nil {
log.Fatalf("Error generic emoji list: %s", err)
@@ -48,14 +48,16 @@ func New(bot bot.Bot) *EmojifyMePlugin {
}
}
- return &EmojifyMePlugin{
- Bot: bot,
+ ep := &EmojifyMePlugin{
+ Bot: b,
GotBotEmoji: false,
Emoji: emojiMap,
}
+ b.Register(ep, bot.Message, ep.message)
+ return ep
}
-func (p *EmojifyMePlugin) Message(message msg.Message) bool {
+func (p *EmojifyMePlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
if !p.GotBotEmoji {
p.GotBotEmoji = true
emojiMap := p.Bot.GetEmojiList()
@@ -90,31 +92,17 @@ func (p *EmojifyMePlugin) Message(message msg.Message) bool {
if emojied > 0 && rand.Float64() <= p.Bot.Config().GetFloat64("Emojify.Chance", 0.02)*emojied {
for _, e := range emojys {
- p.Bot.React(message.Channel, e, message)
+ p.Bot.Send(bot.Reaction, message.Channel, e, message)
}
- return true
+ return false
}
return false
}
-func (p *EmojifyMePlugin) Help(channel string, parts []string) {
-
-}
-
-func (p *EmojifyMePlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
-func (p *EmojifyMePlugin) BotMessage(message msg.Message) bool {
- return false
-}
-
func (p *EmojifyMePlugin) RegisterWeb() *string {
return nil
}
-func (p *EmojifyMePlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
-
func stringsContain(haystack []string, needle string) bool {
for _, s := range haystack {
if s == needle {
diff --git a/plugins/fact/factoid.go b/plugins/fact/factoid.go
index c53c934..b8b40c2 100644
--- a/plugins/fact/factoid.go
+++ b/plugins/fact/factoid.go
@@ -314,6 +314,9 @@ func New(botInst bot.Bot) *Factoid {
}(channel)
}
+ botInst.Register(p, bot.Message, p.message)
+ botInst.Register(p, bot.Help, p.help)
+
return p
}
@@ -405,13 +408,13 @@ func (p *Factoid) sayFact(message msg.Message, fact factoid) {
}
if fact.Verb == "action" {
- p.Bot.SendAction(message.Channel, msg)
+ p.Bot.Send(bot.Action, message.Channel, msg)
} else if fact.Verb == "react" {
- p.Bot.React(message.Channel, msg, message)
+ p.Bot.Send(bot.Reaction, message.Channel, msg, message)
} else if fact.Verb == "reply" {
- p.Bot.SendMessage(message.Channel, msg)
+ p.Bot.Send(bot.Message, message.Channel, msg)
} else {
- p.Bot.SendMessage(message.Channel, full)
+ p.Bot.Send(bot.Message, message.Channel, full)
}
}
@@ -457,7 +460,7 @@ func (p *Factoid) tellThemWhatThatWas(message msg.Message) bool {
msg = fmt.Sprintf("That was (#%d) '%s <%s> %s'",
fact.id.Int64, fact.Fact, fact.Verb, fact.Tidbit)
}
- p.Bot.SendMessage(message.Channel, msg)
+ p.Bot.Send(bot.Message, message.Channel, msg)
return true
}
@@ -475,21 +478,21 @@ func (p *Factoid) learnAction(message msg.Message, action string) bool {
action = strings.TrimSpace(action)
if len(trigger) == 0 || len(fact) == 0 || len(action) == 0 {
- p.Bot.SendMessage(message.Channel, "I don't want to learn that.")
+ p.Bot.Send(bot.Message, message.Channel, "I don't want to learn that.")
return true
}
if len(strings.Split(fact, "$and")) > 4 {
- p.Bot.SendMessage(message.Channel, "You can't use more than 4 $and operators.")
+ p.Bot.Send(bot.Message, message.Channel, "You can't use more than 4 $and operators.")
return true
}
strippedaction := strings.Replace(strings.Replace(action, "<", "", 1), ">", "", 1)
if err := p.learnFact(message, trigger, strippedaction, fact); err != nil {
- p.Bot.SendMessage(message.Channel, err.Error())
+ p.Bot.Send(bot.Message, message.Channel, err.Error())
} else {
- p.Bot.SendMessage(message.Channel, fmt.Sprintf("Okay, %s.", message.User.Name))
+ p.Bot.Send(bot.Message, message.Channel, fmt.Sprintf("Okay, %s.", message.User.Name))
}
return true
@@ -509,7 +512,7 @@ func changeOperator(body string) string {
// an admin, it may be deleted
func (p *Factoid) forgetLastFact(message msg.Message) bool {
if p.LastFact == nil {
- p.Bot.SendMessage(message.Channel, "I refuse.")
+ p.Bot.Send(bot.Message, message.Channel, "I refuse.")
return true
}
@@ -519,7 +522,7 @@ func (p *Factoid) forgetLastFact(message msg.Message) bool {
}
fmt.Printf("Forgot #%d: %s %s %s\n", p.LastFact.id.Int64, p.LastFact.Fact,
p.LastFact.Verb, p.LastFact.Tidbit)
- p.Bot.SendAction(message.Channel, "hits himself over the head with a skillet")
+ p.Bot.Send(bot.Action, message.Channel, "hits himself over the head with a skillet")
p.LastFact = nil
return true
@@ -539,7 +542,7 @@ func (p *Factoid) changeFact(message msg.Message) bool {
if len(parts) == 4 {
// replacement
if parts[0] != "s" {
- p.Bot.SendMessage(message.Channel, "Nah.")
+ p.Bot.Send(bot.Message, message.Channel, "Nah.")
}
find := parts[1]
replace := parts[2]
@@ -554,10 +557,10 @@ func (p *Factoid) changeFact(message msg.Message) bool {
}
// make the changes
msg := fmt.Sprintf("Changing %d facts.", len(result))
- p.Bot.SendMessage(message.Channel, msg)
+ p.Bot.Send(bot.Message, message.Channel, msg)
reg, err := regexp.Compile(find)
if err != nil {
- p.Bot.SendMessage(message.Channel, "I don't really want to.")
+ p.Bot.Send(bot.Message, message.Channel, "I don't really want to.")
return false
}
for _, fact := range result {
@@ -574,12 +577,12 @@ func (p *Factoid) changeFact(message msg.Message) bool {
result, err := getFacts(p.db, trigger, parts[1])
if err != nil {
log.Println("Error getting facts: ", trigger, err)
- p.Bot.SendMessage(message.Channel, "bzzzt")
+ p.Bot.Send(bot.Message, message.Channel, "bzzzt")
return true
}
count := len(result)
if count == 0 {
- p.Bot.SendMessage(message.Channel, "I didn't find any facts like that.")
+ p.Bot.Send(bot.Message, message.Channel, "I didn't find any facts like that.")
return true
}
if parts[2] == "g" && len(result) > 4 {
@@ -599,9 +602,9 @@ func (p *Factoid) changeFact(message msg.Message) bool {
if count > 4 {
msg = fmt.Sprintf("%s | ...and %d others", msg, count)
}
- p.Bot.SendMessage(message.Channel, msg)
+ p.Bot.Send(bot.Message, message.Channel, msg)
} else {
- p.Bot.SendMessage(message.Channel, "I don't know what you mean.")
+ p.Bot.Send(bot.Message, message.Channel, "I don't know what you mean.")
}
return true
}
@@ -609,7 +612,7 @@ func (p *Factoid) changeFact(message msg.Message) bool {
// Message responds to the bot hook on recieving messages.
// This function returns true if the plugin responds in a meaningful way to the users message.
// Otherwise, the function returns false and the bot continues execution of other plugins.
-func (p *Factoid) Message(message msg.Message) bool {
+func (p *Factoid) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
if strings.ToLower(message.Body) == "what was that?" {
return p.tellThemWhatThatWas(message)
}
@@ -625,14 +628,14 @@ func (p *Factoid) Message(message msg.Message) bool {
m := strings.TrimPrefix(message.Body, "alias ")
parts := strings.SplitN(m, "->", 2)
if len(parts) != 2 {
- p.Bot.SendMessage(message.Channel, "If you want to alias something, use: `alias this -> that`")
+ p.Bot.Send(bot.Message, message.Channel, "If you want to alias something, use: `alias this -> that`")
return true
}
a := aliasFromStrings(strings.TrimSpace(parts[1]), strings.TrimSpace(parts[0]))
if err := a.save(p.db); err != nil {
- p.Bot.SendMessage(message.Channel, err.Error())
+ p.Bot.Send(bot.Message, message.Channel, err.Error())
} else {
- p.Bot.SendAction(message.Channel, "learns a new synonym")
+ p.Bot.Send(bot.Action, message.Channel, "learns a new synonym")
}
return true
}
@@ -664,19 +667,15 @@ func (p *Factoid) Message(message msg.Message) bool {
}
// We didn't find anything, panic!
- p.Bot.SendMessage(message.Channel, p.NotFound[rand.Intn(len(p.NotFound))])
+ p.Bot.Send(bot.Message, message.Channel, p.NotFound[rand.Intn(len(p.NotFound))])
return true
}
// Help responds to help requests. Every plugin must implement a help function.
-func (p *Factoid) Help(channel string, parts []string) {
- p.Bot.SendMessage(channel, "I can learn facts and spit them back out. You can say \"this is that\" or \"he $5\". Later, trigger the factoid by just saying the trigger word, \"this\" or \"he\" in these examples.")
- p.Bot.SendMessage(channel, "I can also figure out some variables including: $nonzero, $digit, $nick, and $someone.")
-}
-
-// Empty event handler because this plugin does not do anything on event recv
-func (p *Factoid) Event(kind string, message msg.Message) bool {
- return false
+func (p *Factoid) help(kind bot.Kind, message msg.Message, args ...interface{}) bool {
+ p.Bot.Send(bot.Message, message.Channel, "I can learn facts and spit them back out. You can say \"this is that\" or \"he $5\". Later, trigger the factoid by just saying the trigger word, \"this\" or \"he\" in these examples.")
+ p.Bot.Send(bot.Message, message.Channel, "I can also figure out some variables including: $nonzero, $digit, $nick, and $someone.")
+ return true
}
// Pull a fact at random from the database
@@ -737,11 +736,6 @@ func (p *Factoid) factTimer(channel string) {
}
}
-// Handler for bot's own messages
-func (p *Factoid) BotMessage(message msg.Message) bool {
- return false
-}
-
// Register any web URLs desired
func (p *Factoid) RegisterWeb() *string {
http.HandleFunc("/factoid/req", p.serveQuery)
@@ -784,5 +778,3 @@ func (p *Factoid) serveQuery(w http.ResponseWriter, r *http.Request) {
log.Println(err)
}
}
-
-func (p *Factoid) ReplyMessage(message msg.Message, identifier string) bool { return false }
diff --git a/plugins/fact/remember.go b/plugins/fact/remember.go
index 1038eb7..87485f1 100644
--- a/plugins/fact/remember.go
+++ b/plugins/fact/remember.go
@@ -29,6 +29,8 @@ func NewRemember(b bot.Bot) *RememberPlugin {
Log: make(map[string][]msg.Message),
db: b.DB(),
}
+ b.Register(p, bot.Message, p.message)
+ b.Register(p, bot.Message, p.help)
return &p
}
@@ -36,11 +38,11 @@ func NewRemember(b bot.Bot) *RememberPlugin {
// This function returns true if the plugin responds in a meaningful way to the
// users message. Otherwise, the function returns false and the bot continues
// execution of other plugins.
-func (p *RememberPlugin) Message(message msg.Message) bool {
+func (p *RememberPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
if strings.ToLower(message.Body) == "quote" && message.Command {
q := p.randQuote()
- p.Bot.SendMessage(message.Channel, q)
+ p.Bot.Send(bot.Message, message.Channel, q)
// is it evil not to remember that the user said quote?
return true
@@ -87,7 +89,7 @@ func (p *RememberPlugin) Message(message msg.Message) bool {
}
if err := fact.save(p.db); err != nil {
log.Println("ERROR!!!!:", err)
- p.Bot.SendMessage(message.Channel, "Tell somebody I'm broke.")
+ p.Bot.Send(bot.Message, message.Channel, "Tell somebody I'm broke.")
}
log.Println("Remembering factoid:", msg)
@@ -95,14 +97,14 @@ func (p *RememberPlugin) Message(message msg.Message) bool {
// sorry, not creative with names so we're reusing msg
msg = fmt.Sprintf("Okay, %s, remembering '%s'.",
message.User.Name, msg)
- p.Bot.SendMessage(message.Channel, msg)
+ p.Bot.Send(bot.Message, message.Channel, msg)
p.recordMsg(message)
return true
}
}
- p.Bot.SendMessage(message.Channel, "Sorry, I don't know that phrase.")
+ p.Bot.Send(bot.Message, message.Channel, "Sorry, I don't know that phrase.")
p.recordMsg(message)
return true
}
@@ -111,14 +113,15 @@ func (p *RememberPlugin) Message(message msg.Message) bool {
}
// Help responds to help requests. Every plugin must implement a help function.
-func (p *RememberPlugin) Help(channel string, parts []string) {
+func (p *RememberPlugin) help(kind bot.Kind, message msg.Message, args ...interface{}) bool {
msg := "!remember will let you quote your idiot friends. Just type " +
"!remember to remember what they said. Snippet can " +
"be any part of their message. Later on, you can ask for a random " +
"!quote."
- p.Bot.SendMessage(channel, msg)
+ p.Bot.Send(bot.Message, message.Channel, msg)
+ return true
}
// deliver a random quote out of the db.
@@ -150,19 +153,8 @@ func (p *RememberPlugin) randQuote() string {
return f.Tidbit
}
-// Empty event handler because this plugin does not do anything on event recv
-func (p *RememberPlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
-// Record what the bot says in the log
-func (p *RememberPlugin) BotMessage(message msg.Message) bool {
- p.recordMsg(message)
- return false
-}
-
// Register any web URLs desired
-func (p *RememberPlugin) RegisterWeb() *string {
+func (p RememberPlugin) RegisterWeb() *string {
return nil
}
@@ -170,5 +162,3 @@ func (p *RememberPlugin) recordMsg(message msg.Message) {
log.Printf("Logging message: %s: %s", message.User.Name, message.Body)
p.Log[message.Channel] = append(p.Log[message.Channel], message)
}
-
-func (p *RememberPlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
diff --git a/plugins/fact/remember_test.go b/plugins/fact/remember_test.go
index 6e8c8a1..a3ded28 100644
--- a/plugins/fact/remember_test.go
+++ b/plugins/fact/remember_test.go
@@ -42,7 +42,7 @@ func TestCornerCaseBug(t *testing.T) {
p, _, mb := makePlugin(t)
for _, m := range msgs {
- p.Message(m)
+ p.message(bot.Message, m)
}
assert.Len(t, mb.Messages, 1)
assert.Contains(t, mb.Messages[0], "horse dick")
@@ -59,7 +59,7 @@ func TestReact(t *testing.T) {
_, p, mb := makePlugin(t)
for _, m := range msgs {
- p.Message(m)
+ p.message(bot.Message, m)
}
assert.Len(t, mb.Reactions, 1)
assert.Contains(t, mb.Reactions[0], "jesus")
@@ -72,7 +72,7 @@ func TestReactCantLearnSpaces(t *testing.T) {
_, p, mb := makePlugin(t)
for _, m := range msgs {
- p.Message(m)
+ p.message(bot.Message, m)
}
assert.Len(t, mb.Messages, 1)
assert.Contains(t, mb.Messages[0], "not a valid")
diff --git a/plugins/first/first.go b/plugins/first/first.go
index a70f6e7..9771dbf 100644
--- a/plugins/first/first.go
+++ b/plugins/first/first.go
@@ -66,11 +66,14 @@ func New(b bot.Bot) *FirstPlugin {
log.Fatal("Could not initialize first plugin: ", err)
}
- return &FirstPlugin{
+ fp := &FirstPlugin{
Bot: b,
db: b.DB(),
First: first,
}
+ b.Register(fp, bot.Message, fp.message)
+ b.Register(fp, bot.Help, fp.help)
+ return fp
}
func getLastFirst(db *sqlx.DB) (*FirstEntry, error) {
@@ -123,7 +126,7 @@ func isToday(t time.Time) bool {
// Message responds to the bot hook on recieving messages.
// This function returns true if the plugin responds in a meaningful way to the users message.
// Otherwise, the function returns false and the bot continues execution of other plugins.
-func (p *FirstPlugin) Message(message msg.Message) bool {
+func (p *FirstPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
// This bot does not reply to anything
if p.First == nil && p.allowed(message) {
@@ -195,7 +198,7 @@ func (p *FirstPlugin) recordFirst(message msg.Message) {
func (p *FirstPlugin) announceFirst(message msg.Message) {
c := message.Channel
if p.First != nil {
- p.Bot.SendMessage(c, fmt.Sprintf("%s had first at %s with the message: \"%s\"",
+ p.Bot.Send(bot.Message, c, fmt.Sprintf("%s had first at %s with the message: \"%s\"",
p.First.nick, p.First.time.Format("15:04"), p.First.body))
}
}
@@ -208,23 +211,12 @@ func (p *FirstPlugin) LoadData() {
}
// Help responds to help requests. Every plugin must implement a help function.
-func (p *FirstPlugin) Help(channel string, parts []string) {
- p.Bot.SendMessage(channel, "Sorry, First does not do a goddamn thing.")
-}
-
-// Empty event handler because this plugin does not do anything on event recv
-func (p *FirstPlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
-// Handler for bot's own messages
-func (p *FirstPlugin) BotMessage(message msg.Message) bool {
- return false
+func (p *FirstPlugin) help(kind bot.Kind, message msg.Message, args ...interface{}) bool {
+ p.Bot.Send(bot.Message, message.Channel, "Sorry, First does not do a goddamn thing.")
+ return true
}
// Register any web URLs desired
func (p *FirstPlugin) RegisterWeb() *string {
return nil
}
-
-func (p *FirstPlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
diff --git a/plugins/inventory/inventory.go b/plugins/inventory/inventory.go
index 708639f..50fb6f3 100644
--- a/plugins/inventory/inventory.go
+++ b/plugins/inventory/inventory.go
@@ -24,8 +24,8 @@ type InventoryPlugin struct {
}
// New creates a new InventoryPlugin with the Plugin interface
-func New(bot bot.Bot) *InventoryPlugin {
- config := bot.Config()
+func New(b bot.Bot) *InventoryPlugin {
+ config := b.Config()
nick := config.Get("nick", "bot")
r1, err := regexp.Compile("take this (.+)")
checkerr(err)
@@ -38,15 +38,15 @@ func New(bot bot.Bot) *InventoryPlugin {
r5, err := regexp.Compile(fmt.Sprintf("gives (.+) to %s([^a-zA-Z].*)?", nick))
checkerr(err)
- p := InventoryPlugin{
- DB: bot.DB(),
- bot: bot,
+ p := &InventoryPlugin{
+ DB: b.DB(),
+ bot: b,
config: config,
r1: r1, r2: r2, r3: r3, r4: r4, r5: r5,
}
- bot.RegisterFilter("$item", p.itemFilter)
- bot.RegisterFilter("$giveitem", p.giveItemFilter)
+ b.RegisterFilter("$item", p.itemFilter)
+ b.RegisterFilter("$giveitem", p.giveItemFilter)
_, err = p.DB.Exec(`create table if not exists inventory (
item string primary key
@@ -56,7 +56,9 @@ func New(bot bot.Bot) *InventoryPlugin {
log.Fatal(err)
}
- return &p
+ b.Register(p, bot.Message, p.message)
+
+ return p
}
func (p *InventoryPlugin) giveItemFilter(input string) string {
@@ -75,7 +77,7 @@ func (p *InventoryPlugin) itemFilter(input string) string {
return input
}
-func (p *InventoryPlugin) Message(message msg.Message) bool {
+func (p *InventoryPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
m := message.Body
log.Printf("inventory trying to read %+v", message)
if message.Command {
@@ -86,7 +88,7 @@ func (p *InventoryPlugin) Message(message msg.Message) bool {
log.Printf("I think I have more than 0 items: %+v, len(items)=%d", items, len(items))
say = fmt.Sprintf("I'm currently holding %s", strings.Join(items, ", "))
}
- p.bot.SendMessage(message.Channel, say)
+ p.bot.Send(bot.Message, message.Channel, say)
return true
}
@@ -197,7 +199,7 @@ func (p *InventoryPlugin) remove(i string) {
func (p *InventoryPlugin) addItem(m msg.Message, i string) bool {
if p.exists(i) {
- p.bot.SendMessage(m.Channel, fmt.Sprintf("I already have %s.", i))
+ p.bot.Send(bot.Message, m.Channel, fmt.Sprintf("I already have %s.", i))
return true
}
var removed string
@@ -210,9 +212,9 @@ func (p *InventoryPlugin) addItem(m msg.Message, i string) bool {
log.Printf("Error inserting new inventory item: %s", err)
}
if removed != "" {
- p.bot.SendAction(m.Channel, fmt.Sprintf("dropped %s and took %s from %s", removed, i, m.User.Name))
+ p.bot.Send(bot.Action, m.Channel, fmt.Sprintf("dropped %s and took %s from %s", removed, i, m.User.Name))
} else {
- p.bot.SendAction(m.Channel, fmt.Sprintf("takes %s from %s", i, m.User.Name))
+ p.bot.Send(bot.Action, m.Channel, fmt.Sprintf("takes %s from %s", i, m.User.Name))
}
return true
}
@@ -223,20 +225,7 @@ func checkerr(e error) {
}
}
-func (p *InventoryPlugin) Event(e string, message msg.Message) bool {
- return false
-}
-
-func (p *InventoryPlugin) BotMessage(message msg.Message) bool {
- return false
-}
-
-func (p *InventoryPlugin) Help(e string, m []string) {
-}
-
func (p *InventoryPlugin) RegisterWeb() *string {
// nothing to register
return nil
}
-
-func (p *InventoryPlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
diff --git a/plugins/leftpad/leftpad.go b/plugins/leftpad/leftpad.go
index cf5327e..e005b46 100644
--- a/plugins/leftpad/leftpad.go
+++ b/plugins/leftpad/leftpad.go
@@ -20,19 +20,20 @@ type LeftpadPlugin struct {
}
// New creates a new LeftpadPlugin with the Plugin interface
-func New(bot bot.Bot) *LeftpadPlugin {
- p := LeftpadPlugin{
- bot: bot,
- config: bot.Config(),
+func New(b bot.Bot) *LeftpadPlugin {
+ p := &LeftpadPlugin{
+ bot: b,
+ config: b.Config(),
}
- return &p
+ b.Register(p, bot.Message, p.message)
+ return p
}
type leftpadResp struct {
Str string
}
-func (p *LeftpadPlugin) Message(message msg.Message) bool {
+func (p *LeftpadPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
if !message.Command {
return false
}
@@ -42,40 +43,27 @@ func (p *LeftpadPlugin) Message(message msg.Message) bool {
padchar := parts[1]
length, err := strconv.Atoi(parts[2])
if err != nil {
- p.bot.SendMessage(message.Channel, "Invalid padding number")
+ p.bot.Send(bot.Message, message.Channel, "Invalid padding number")
return true
}
maxLen, who := p.config.GetInt("LeftPad.MaxLen", 50), p.config.Get("LeftPad.Who", "Putin")
if length > maxLen && maxLen > 0 {
msg := fmt.Sprintf("%s would kill me if I did that.", who)
- p.bot.SendMessage(message.Channel, msg)
+ p.bot.Send(bot.Message, message.Channel, msg)
return true
}
text := strings.Join(parts[3:], " ")
res := leftpad.LeftPad(text, length, padchar)
- p.bot.SendMessage(message.Channel, res)
+ p.bot.Send(bot.Message, message.Channel, res)
return true
}
return false
}
-func (p *LeftpadPlugin) Event(e string, message msg.Message) bool {
- return false
-}
-
-func (p *LeftpadPlugin) BotMessage(message msg.Message) bool {
- return false
-}
-
-func (p *LeftpadPlugin) Help(e string, m []string) {
-}
-
func (p *LeftpadPlugin) RegisterWeb() *string {
// nothing to register
return nil
}
-
-func (p *LeftpadPlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
diff --git a/plugins/leftpad/leftpad_test.go b/plugins/leftpad/leftpad_test.go
index 21e4af4..1d97488 100644
--- a/plugins/leftpad/leftpad_test.go
+++ b/plugins/leftpad/leftpad_test.go
@@ -13,12 +13,12 @@ import (
"github.com/velour/catbase/plugins/counter"
)
-func makeMessage(payload string) msg.Message {
+func makeMessage(payload string) (bot.Kind, msg.Message) {
isCmd := strings.HasPrefix(payload, "!")
if isCmd {
payload = payload[1:]
}
- return msg.Message{
+ return bot.Message, msg.Message{
User: &user.User{Name: "tester"},
Channel: "test",
Body: payload,
@@ -37,28 +37,28 @@ func makePlugin(t *testing.T) (*LeftpadPlugin, *bot.MockBot) {
func TestLeftpad(t *testing.T) {
p, mb := makePlugin(t)
- p.Message(makeMessage("!leftpad test 8 test"))
+ p.message(makeMessage("!leftpad test 8 test"))
assert.Contains(t, mb.Messages[0], "testtest")
assert.Len(t, mb.Messages, 1)
}
func TestBadNumber(t *testing.T) {
p, mb := makePlugin(t)
- p.Message(makeMessage("!leftpad test fuck test"))
+ p.message(makeMessage("!leftpad test fuck test"))
assert.Contains(t, mb.Messages[0], "Invalid")
assert.Len(t, mb.Messages, 1)
}
func TestNotCommand(t *testing.T) {
p, mb := makePlugin(t)
- p.Message(makeMessage("leftpad test fuck test"))
+ p.message(makeMessage("leftpad test fuck test"))
assert.Len(t, mb.Messages, 0)
}
func TestNoMaxLen(t *testing.T) {
p, mb := makePlugin(t)
p.config.Set("LeftPad.MaxLen", "0")
- p.Message(makeMessage("!leftpad dicks 100 dicks"))
+ p.message(makeMessage("!leftpad dicks 100 dicks"))
assert.Len(t, mb.Messages, 1)
assert.Contains(t, mb.Messages[0], "dicks")
}
@@ -67,7 +67,7 @@ func Test50Padding(t *testing.T) {
p, mb := makePlugin(t)
p.config.Set("LeftPad.MaxLen", "50")
assert.Equal(t, 50, p.config.GetInt("LeftPad.MaxLen", 100))
- p.Message(makeMessage("!leftpad dicks 100 dicks"))
+ p.message(makeMessage("!leftpad dicks 100 dicks"))
assert.Len(t, mb.Messages, 1)
assert.Contains(t, mb.Messages[0], "kill me")
}
@@ -75,33 +75,17 @@ func Test50Padding(t *testing.T) {
func TestUnder50Padding(t *testing.T) {
p, mb := makePlugin(t)
p.config.Set("LeftPad.MaxLen", "50")
- p.Message(makeMessage("!leftpad dicks 49 dicks"))
+ p.message(makeMessage("!leftpad dicks 49 dicks"))
assert.Len(t, mb.Messages, 1)
assert.Contains(t, mb.Messages[0], "dicks")
}
func TestNotPadding(t *testing.T) {
p, mb := makePlugin(t)
- p.Message(makeMessage("!lololol"))
+ p.message(makeMessage("!lololol"))
assert.Len(t, mb.Messages, 0)
}
-func TestHelp(t *testing.T) {
- p, mb := makePlugin(t)
- p.Help("channel", []string{})
- assert.Len(t, mb.Messages, 0)
-}
-
-func TestBotMessage(t *testing.T) {
- p, _ := makePlugin(t)
- assert.False(t, p.BotMessage(makeMessage("test")))
-}
-
-func TestEvent(t *testing.T) {
- p, _ := makePlugin(t)
- assert.False(t, p.Event("dummy", makeMessage("test")))
-}
-
func TestRegisterWeb(t *testing.T) {
p, _ := makePlugin(t)
assert.Nil(t, p.RegisterWeb())
diff --git a/plugins/nerdepedia/nerdepedia.go b/plugins/nerdepedia/nerdepedia.go
index 1da2514..eb040a7 100644
--- a/plugins/nerdepedia/nerdepedia.go
+++ b/plugins/nerdepedia/nerdepedia.go
@@ -27,17 +27,20 @@ type NerdepediaPlugin struct {
}
// NewNerdepediaPlugin creates a new NerdepediaPlugin with the Plugin interface
-func New(bot bot.Bot) *NerdepediaPlugin {
- return &NerdepediaPlugin{
- bot: bot,
- config: bot.Config(),
+func New(b bot.Bot) *NerdepediaPlugin {
+ np := &NerdepediaPlugin{
+ bot: b,
+ config: b.Config(),
}
+ b.Register(np, bot.Message, np.message)
+ b.Register(np, bot.Help, np.help)
+ return np
}
// Message responds to the bot hook on recieving messages.
// This function returns true if the plugin responds in a meaningful way to the users message.
// Otherwise, the function returns false and the bot continues execution of other plugins.
-func (p *NerdepediaPlugin) Message(message msg.Message) bool {
+func (p *NerdepediaPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
lowerCase := strings.ToLower(message.Body)
query := ""
if lowerCase == "may the force be with you" || lowerCase == "help me obi-wan" {
@@ -78,7 +81,7 @@ func (p *NerdepediaPlugin) Message(message msg.Message) bool {
}
if description != "" && link != "" {
- p.bot.SendMessage(message.Channel, fmt.Sprintf("%s (%s)", description, link))
+ p.bot.Send(bot.Message, message.Channel, fmt.Sprintf("%s (%s)", description, link))
return true
}
}
@@ -87,23 +90,12 @@ func (p *NerdepediaPlugin) Message(message msg.Message) bool {
}
// Help responds to help requests. Every plugin must implement a help function.
-func (p *NerdepediaPlugin) Help(channel string, parts []string) {
- p.bot.SendMessage(channel, "nerd stuff")
-}
-
-// Empty event handler because this plugin does not do anything on event recv
-func (p *NerdepediaPlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
-// Handler for bot's own messages
-func (p *NerdepediaPlugin) BotMessage(message msg.Message) bool {
- return false
+func (p *NerdepediaPlugin) help(kind bot.Kind, message msg.Message, args ...interface{}) bool {
+ p.bot.Send(bot.Message, message.Channel, "nerd stuff")
+ return true
}
// Register any web URLs desired
func (p *NerdepediaPlugin) RegisterWeb() *string {
return nil
}
-
-func (p *NerdepediaPlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
diff --git a/plugins/nerdepedia/nerdepeida_test.go b/plugins/nerdepedia/nerdepeida_test.go
index 5cba343..eb59807 100644
--- a/plugins/nerdepedia/nerdepeida_test.go
+++ b/plugins/nerdepedia/nerdepeida_test.go
@@ -12,12 +12,12 @@ import (
"github.com/velour/catbase/bot/user"
)
-func makeMessage(payload string) msg.Message {
+func makeMessage(payload string) (bot.Kind, msg.Message) {
isCmd := strings.HasPrefix(payload, "!")
if isCmd {
payload = payload[1:]
}
- return msg.Message{
+ return bot.Message, msg.Message{
User: &user.User{Name: "tester"},
Channel: "test",
Body: payload,
@@ -29,7 +29,7 @@ func TestWars(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("help me obi-wan"))
+ res := c.message(makeMessage("help me obi-wan"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
}
@@ -38,7 +38,7 @@ func TestTrek(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("live long and prosper"))
+ res := c.message(makeMessage("live long and prosper"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
}
@@ -47,7 +47,7 @@ func TestDune(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("bless the maker"))
+ res := c.message(makeMessage("bless the maker"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
}
@@ -56,7 +56,7 @@ func TestPoke(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("gotta catch em all"))
+ res := c.message(makeMessage("gotta catch em all"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
}
diff --git a/plugins/picker/picker.go b/plugins/picker/picker.go
index 53b5f4b..3a1c320 100644
--- a/plugins/picker/picker.go
+++ b/plugins/picker/picker.go
@@ -20,30 +20,33 @@ type PickerPlugin struct {
}
// NewPickerPlugin creates a new PickerPlugin with the Plugin interface
-func New(bot bot.Bot) *PickerPlugin {
- return &PickerPlugin{
- Bot: bot,
+func New(b bot.Bot) *PickerPlugin {
+ pp := &PickerPlugin{
+ Bot: b,
}
+ b.Register(pp, bot.Message, pp.message)
+ b.Register(pp, bot.Help, pp.help)
+ return pp
}
// Message responds to the bot hook on recieving messages.
// This function returns true if the plugin responds in a meaningful way to the users message.
// Otherwise, the function returns false and the bot continues execution of other plugins.
-func (p *PickerPlugin) Message(message msg.Message) bool {
+func (p *PickerPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
if !strings.HasPrefix(message.Body, "pick") {
return false
}
n, items, err := p.parse(message.Body)
if err != nil {
- p.Bot.SendMessage(message.Channel, err.Error())
+ p.Bot.Send(bot.Message, message.Channel, err.Error())
return true
}
if n == 1 {
item := items[rand.Intn(len(items))]
out := fmt.Sprintf("I've chosen %q for you.", strings.TrimSpace(item))
- p.Bot.SendMessage(message.Channel, out)
+ p.Bot.Send(bot.Message, message.Channel, out)
return true
}
@@ -59,7 +62,7 @@ func (p *PickerPlugin) Message(message msg.Message) bool {
fmt.Fprintf(&b, ", %q", item)
}
b.WriteString(" }")
- p.Bot.SendMessage(message.Channel, b.String())
+ p.Bot.Send(bot.Message, message.Channel, b.String())
return true
}
@@ -108,18 +111,9 @@ func (p *PickerPlugin) parse(body string) (int, []string, error) {
}
// Help responds to help requests. Every plugin must implement a help function.
-func (p *PickerPlugin) Help(channel string, parts []string) {
- p.Bot.SendMessage(channel, "Choose from a list of options. Try \"pick {a,b,c}\".")
-}
-
-// Empty event handler because this plugin does not do anything on event recv
-func (p *PickerPlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
-// Handler for bot's own messages
-func (p *PickerPlugin) BotMessage(message msg.Message) bool {
- return false
+func (p *PickerPlugin) help(kind bot.Kind, message msg.Message, args ...interface{}) bool {
+ p.Bot.Send(bot.Message, message.Channel, "Choose from a list of options. Try \"pick {a,b,c}\".")
+ return true
}
// Register any web URLs desired
diff --git a/plugins/picker/picker_test.go b/plugins/picker/picker_test.go
index 0c2dd60..b01684a 100644
--- a/plugins/picker/picker_test.go
+++ b/plugins/picker/picker_test.go
@@ -12,12 +12,12 @@ import (
"github.com/velour/catbase/bot/user"
)
-func makeMessage(payload string) msg.Message {
+func makeMessage(payload string) (bot.Kind, msg.Message) {
isCmd := strings.HasPrefix(payload, "!")
if isCmd {
payload = payload[1:]
}
- return msg.Message{
+ return bot.Message, msg.Message{
User: &user.User{Name: "tester"},
Channel: "test",
Body: payload,
@@ -29,7 +29,7 @@ func TestPick2(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("!pick 2 { a, b,c}"))
+ res := c.message(makeMessage("!pick 2 { a, b,c}"))
assert.Len(t, mb.Messages, 1)
if !res {
t.Fatalf("expected a successful choice, got %q", mb.Messages[0])
@@ -40,7 +40,7 @@ func TestPickDefault(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- _ = c.Message(makeMessage("!pick { a}"))
+ _ = c.message(makeMessage("!pick { a}"))
assert.Len(t, mb.Messages, 1)
assert.Equal(t, `I've chosen "a" for you.`, mb.Messages[0])
}
diff --git a/plugins/reaction/reaction.go b/plugins/reaction/reaction.go
index 6f98d55..c964022 100644
--- a/plugins/reaction/reaction.go
+++ b/plugins/reaction/reaction.go
@@ -15,14 +15,16 @@ type ReactionPlugin struct {
Config *config.Config
}
-func New(bot bot.Bot) *ReactionPlugin {
- return &ReactionPlugin{
- Bot: bot,
- Config: bot.Config(),
+func New(b bot.Bot) *ReactionPlugin {
+ rp := &ReactionPlugin{
+ Bot: b,
+ Config: b.Config(),
}
+ b.Register(rp, bot.Message, rp.message)
+ return rp
}
-func (p *ReactionPlugin) Message(message msg.Message) bool {
+func (p *ReactionPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
harrass := false
for _, nick := range p.Config.GetArray("Reaction.HarrassList", []string{}) {
if message.User.Name == nick {
@@ -56,26 +58,12 @@ func (p *ReactionPlugin) Message(message msg.Message) bool {
reaction = p.Config.GetArray("Reaction.NegativeReactions", []string{})[index]
}
- p.Bot.React(message.Channel, reaction, message)
+ p.Bot.Send(bot.Reaction, message.Channel, reaction, message)
}
return false
}
-func (p *ReactionPlugin) Help(channel string, parts []string) {
-
-}
-
-func (p *ReactionPlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
-func (p *ReactionPlugin) BotMessage(message msg.Message) bool {
- return false
-}
-
func (p *ReactionPlugin) RegisterWeb() *string {
return nil
}
-
-func (p *ReactionPlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
diff --git a/plugins/reminder/reminder.go b/plugins/reminder/reminder.go
index 4e00e9c..93d4dec 100644
--- a/plugins/reminder/reminder.go
+++ b/plugins/reminder/reminder.go
@@ -38,9 +38,9 @@ type Reminder struct {
channel string
}
-func New(bot bot.Bot) *ReminderPlugin {
+func New(b bot.Bot) *ReminderPlugin {
log.SetFlags(log.LstdFlags | log.Lshortfile)
- if _, err := bot.DB().Exec(`create table if not exists reminders (
+ if _, err := b.DB().Exec(`create table if not exists reminders (
id integer primary key,
fromWho string,
toWho string,
@@ -56,21 +56,24 @@ func New(bot bot.Bot) *ReminderPlugin {
timer.Stop()
plugin := &ReminderPlugin{
- Bot: bot,
- db: bot.DB(),
+ Bot: b,
+ db: b.DB(),
mutex: &sync.Mutex{},
timer: timer,
- config: bot.Config(),
+ config: b.Config(),
}
plugin.queueUpNextReminder()
go reminderer(plugin)
+ b.Register(plugin, bot.Message, plugin.message)
+ b.Register(plugin, bot.Help, plugin.help)
+
return plugin
}
-func (p *ReminderPlugin) Message(message msg.Message) bool {
+func (p *ReminderPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
channel := message.Channel
from := message.User.Name
@@ -85,7 +88,7 @@ func (p *ReminderPlugin) Message(message msg.Message) bool {
dur, err := time.ParseDuration(parts[3])
if err != nil {
- p.Bot.SendMessage(channel, "Easy cowboy, not sure I can parse that duration.")
+ p.Bot.Send(bot.Message, channel, "Easy cowboy, not sure I can parse that duration.")
return true
}
@@ -113,7 +116,7 @@ func (p *ReminderPlugin) Message(message msg.Message) bool {
//remind who every dur for dur2 blah
dur2, err := time.ParseDuration(parts[5])
if err != nil {
- p.Bot.SendMessage(channel, "Easy cowboy, not sure I can parse that duration.")
+ p.Bot.Send(bot.Message, channel, "Easy cowboy, not sure I can parse that duration.")
return true
}
@@ -124,7 +127,7 @@ func (p *ReminderPlugin) Message(message msg.Message) bool {
max := p.config.GetInt("Reminder.MaxBatchAdd", 10)
for i := 0; when.Before(endTime); i++ {
if i >= max {
- p.Bot.SendMessage(channel, "Easy cowboy, that's a lot of reminders. I'll add some of them.")
+ p.Bot.Send(bot.Message, channel, "Easy cowboy, that's a lot of reminders. I'll add some of them.")
doConfirm = false
break
}
@@ -141,14 +144,14 @@ func (p *ReminderPlugin) Message(message msg.Message) bool {
when = when.Add(dur)
}
} else {
- p.Bot.SendMessage(channel, "Easy cowboy, not sure I comprehend what you're asking.")
+ p.Bot.Send(bot.Message, channel, "Easy cowboy, not sure I comprehend what you're asking.")
return true
}
if doConfirm && from == who {
- p.Bot.SendMessage(channel, fmt.Sprintf("Okay. I'll remind you."))
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("Okay. I'll remind you."))
} else if doConfirm {
- p.Bot.SendMessage(channel, fmt.Sprintf("Sure %s, I'll remind %s.", from, who))
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("Sure %s, I'll remind %s.", from, who))
}
p.queueUpNextReminder()
@@ -168,22 +171,22 @@ func (p *ReminderPlugin) Message(message msg.Message) bool {
}
}
if err != nil {
- p.Bot.SendMessage(channel, "listing failed.")
+ p.Bot.Send(bot.Message, channel, "listing failed.")
} else {
- p.Bot.SendMessage(channel, response)
+ p.Bot.Send(bot.Message, channel, response)
}
return true
} else if len(parts) == 3 && strings.ToLower(parts[0]) == "cancel" && strings.ToLower(parts[1]) == "reminder" {
id, err := strconv.ParseInt(parts[2], 10, 64)
if err != nil {
- p.Bot.SendMessage(channel, fmt.Sprintf("couldn't parse id: %s", parts[2]))
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("couldn't parse id: %s", parts[2]))
} else {
err := p.deleteReminder(id)
if err == nil {
- p.Bot.SendMessage(channel, fmt.Sprintf("successfully canceled reminder: %s", parts[2]))
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("successfully canceled reminder: %s", parts[2]))
} else {
- p.Bot.SendMessage(channel, fmt.Sprintf("failed to find and cancel reminder: %s", parts[2]))
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("failed to find and cancel reminder: %s", parts[2]))
}
}
return true
@@ -192,16 +195,9 @@ func (p *ReminderPlugin) Message(message msg.Message) bool {
return false
}
-func (p *ReminderPlugin) Help(channel string, parts []string) {
- p.Bot.SendMessage(channel, "Pester someone with a reminder. Try \"remind in message\".\n\nUnsure about duration syntax? Check https://golang.org/pkg/time/#ParseDuration")
-}
-
-func (p *ReminderPlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
-func (p *ReminderPlugin) BotMessage(message msg.Message) bool {
- return false
+func (p *ReminderPlugin) help(kind bot.Kind, message msg.Message, args ...interface{}) bool {
+ p.Bot.Send(bot.Message, message.Channel, "Pester someone with a reminder. Try \"remind in message\".\n\nUnsure about duration syntax? Check https://golang.org/pkg/time/#ParseDuration")
+ return true
}
func (p *ReminderPlugin) RegisterWeb() *string {
@@ -353,7 +349,7 @@ func reminderer(p *ReminderPlugin) {
message = fmt.Sprintf("Hey %s, %s wanted you to be reminded: %s", reminder.who, reminder.from, reminder.what)
}
- p.Bot.SendMessage(reminder.channel, message)
+ p.Bot.Send(bot.Message, reminder.channel, message)
if err := p.deleteReminder(reminder.id); err != nil {
log.Print(reminder.id)
@@ -365,5 +361,3 @@ func reminderer(p *ReminderPlugin) {
p.queueUpNextReminder()
}
}
-
-func (p *ReminderPlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
diff --git a/plugins/reminder/reminder_test.go b/plugins/reminder/reminder_test.go
index d3c6155..c4a4e9e 100644
--- a/plugins/reminder/reminder_test.go
+++ b/plugins/reminder/reminder_test.go
@@ -14,25 +14,16 @@ import (
"github.com/velour/catbase/bot/user"
)
-func makeMessage(payload string) msg.Message {
- isCmd := strings.HasPrefix(payload, "!")
- if isCmd {
- payload = payload[1:]
- }
- return msg.Message{
- User: &user.User{Name: "tester"},
- Channel: "test",
- Body: payload,
- Command: isCmd,
- }
+func makeMessage(payload string) (bot.Kind, msg.Message) {
+ return makeMessageBy(payload, "tester")
}
-func makeMessageBy(payload, by string) msg.Message {
+func makeMessageBy(payload, by string) (bot.Kind, msg.Message) {
isCmd := strings.HasPrefix(payload, "!")
if isCmd {
payload = payload[1:]
}
- return msg.Message{
+ return bot.Message, msg.Message{
User: &user.User{Name: by},
Channel: "test",
Body: payload,
@@ -49,7 +40,7 @@ func setup(t *testing.T) (*ReminderPlugin, *bot.MockBot) {
func TestMeReminder(t *testing.T) {
c, mb := setup(t)
- res := c.Message(makeMessage("!remind me in 1s don't fail this test"))
+ res := c.message(makeMessage("!remind me in 1s don't fail this test"))
time.Sleep(2 * time.Second)
assert.Len(t, mb.Messages, 2)
assert.True(t, res)
@@ -59,7 +50,7 @@ func TestMeReminder(t *testing.T) {
func TestReminder(t *testing.T) {
c, mb := setup(t)
- res := c.Message(makeMessage("!remind testuser in 1s don't fail this test"))
+ res := c.message(makeMessage("!remind testuser in 1s don't fail this test"))
time.Sleep(2 * time.Second)
assert.Len(t, mb.Messages, 2)
assert.True(t, res)
@@ -69,9 +60,9 @@ func TestReminder(t *testing.T) {
func TestReminderReorder(t *testing.T) {
c, mb := setup(t)
- res := c.Message(makeMessage("!remind testuser in 2s don't fail this test 2"))
+ res := c.message(makeMessage("!remind testuser in 2s don't fail this test 2"))
assert.True(t, res)
- res = c.Message(makeMessage("!remind testuser in 1s don't fail this test 1"))
+ res = c.message(makeMessage("!remind testuser in 1s don't fail this test 1"))
assert.True(t, res)
time.Sleep(5 * time.Second)
assert.Len(t, mb.Messages, 4)
@@ -83,7 +74,7 @@ func TestReminderReorder(t *testing.T) {
func TestReminderParse(t *testing.T) {
c, mb := setup(t)
- res := c.Message(makeMessage("!remind testuser in unparseable don't fail this test"))
+ res := c.message(makeMessage("!remind testuser in unparseable don't fail this test"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "Easy cowboy, not sure I can parse that duration.")
@@ -91,7 +82,7 @@ func TestReminderParse(t *testing.T) {
func TestEmptyList(t *testing.T) {
c, mb := setup(t)
- res := c.Message(makeMessage("!list reminders"))
+ res := c.message(makeMessage("!list reminders"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "no pending reminders")
@@ -99,11 +90,11 @@ func TestEmptyList(t *testing.T) {
func TestList(t *testing.T) {
c, mb := setup(t)
- res := c.Message(makeMessage("!remind testuser in 5m don't fail this test 1"))
+ res := c.message(makeMessage("!remind testuser in 5m don't fail this test 1"))
assert.True(t, res)
- res = c.Message(makeMessage("!remind testuser in 5m don't fail this test 2"))
+ res = c.message(makeMessage("!remind testuser in 5m don't fail this test 2"))
assert.True(t, res)
- res = c.Message(makeMessage("!list reminders"))
+ res = c.message(makeMessage("!list reminders"))
assert.True(t, res)
assert.Len(t, mb.Messages, 3)
assert.Contains(t, mb.Messages[2], "1) tester -> testuser :: don't fail this test 1 @ ")
@@ -112,11 +103,11 @@ func TestList(t *testing.T) {
func TestListBy(t *testing.T) {
c, mb := setup(t)
- res := c.Message(makeMessageBy("!remind testuser in 5m don't fail this test 1", "testuser"))
+ res := c.message(makeMessageBy("!remind testuser in 5m don't fail this test 1", "testuser"))
assert.True(t, res)
- res = c.Message(makeMessageBy("!remind testuser in 5m don't fail this test 2", "testuser2"))
+ res = c.message(makeMessageBy("!remind testuser in 5m don't fail this test 2", "testuser2"))
assert.True(t, res)
- res = c.Message(makeMessage("!list reminders from testuser"))
+ res = c.message(makeMessage("!list reminders from testuser"))
assert.True(t, res)
assert.Len(t, mb.Messages, 3)
assert.Contains(t, mb.Messages[2], "don't fail this test 1 @ ")
@@ -125,11 +116,11 @@ func TestListBy(t *testing.T) {
func TestListTo(t *testing.T) {
c, mb := setup(t)
- res := c.Message(makeMessageBy("!remind testuser2 in 5m don't fail this test 1", "testuser"))
+ res := c.message(makeMessageBy("!remind testuser2 in 5m don't fail this test 1", "testuser"))
assert.True(t, res)
- res = c.Message(makeMessageBy("!remind testuser in 5m don't fail this test 2", "testuser2"))
+ res = c.message(makeMessageBy("!remind testuser in 5m don't fail this test 2", "testuser2"))
assert.True(t, res)
- res = c.Message(makeMessage("!list reminders to testuser"))
+ res = c.message(makeMessage("!list reminders to testuser"))
assert.True(t, res)
assert.Len(t, mb.Messages, 3)
assert.NotContains(t, mb.Messages[2], "don't fail this test 1 @ ")
@@ -138,11 +129,11 @@ func TestListTo(t *testing.T) {
func TestToEmptyList(t *testing.T) {
c, mb := setup(t)
- res := c.Message(makeMessageBy("!remind testuser2 in 5m don't fail this test 1", "testuser"))
+ res := c.message(makeMessageBy("!remind testuser2 in 5m don't fail this test 1", "testuser"))
assert.True(t, res)
- res = c.Message(makeMessageBy("!remind testuser in 5m don't fail this test 2", "testuser2"))
+ res = c.message(makeMessageBy("!remind testuser in 5m don't fail this test 2", "testuser2"))
assert.True(t, res)
- res = c.Message(makeMessage("!list reminders to test"))
+ res = c.message(makeMessage("!list reminders to test"))
assert.True(t, res)
assert.Len(t, mb.Messages, 3)
assert.Contains(t, mb.Messages[2], "no pending reminders")
@@ -150,11 +141,11 @@ func TestToEmptyList(t *testing.T) {
func TestFromEmptyList(t *testing.T) {
c, mb := setup(t)
- res := c.Message(makeMessageBy("!remind testuser2 in 5m don't fail this test 1", "testuser"))
+ res := c.message(makeMessageBy("!remind testuser2 in 5m don't fail this test 1", "testuser"))
assert.True(t, res)
- res = c.Message(makeMessageBy("!remind testuser in 5m don't fail this test 2", "testuser2"))
+ res = c.message(makeMessageBy("!remind testuser in 5m don't fail this test 2", "testuser2"))
assert.True(t, res)
- res = c.Message(makeMessage("!list reminders from test"))
+ res = c.message(makeMessage("!list reminders from test"))
assert.True(t, res)
assert.Len(t, mb.Messages, 3)
assert.Contains(t, mb.Messages[2], "no pending reminders")
@@ -164,9 +155,9 @@ func TestBatchMax(t *testing.T) {
c, mb := setup(t)
c.config.Set("Reminder.MaxBatchAdd", "10")
assert.NotNil(t, c)
- res := c.Message(makeMessage("!remind testuser every 1h for 24h yikes"))
+ res := c.message(makeMessage("!remind testuser every 1h for 24h yikes"))
assert.True(t, res)
- res = c.Message(makeMessage("!list reminders"))
+ res = c.message(makeMessage("!list reminders"))
assert.True(t, res)
time.Sleep(6 * time.Second)
assert.Len(t, mb.Messages, 2)
@@ -180,11 +171,11 @@ func TestBatchMax(t *testing.T) {
func TestCancel(t *testing.T) {
c, mb := setup(t)
assert.NotNil(t, c)
- res := c.Message(makeMessage("!remind testuser in 1m don't fail this test"))
+ res := c.message(makeMessage("!remind testuser in 1m don't fail this test"))
assert.True(t, res)
- res = c.Message(makeMessage("!cancel reminder 1"))
+ res = c.message(makeMessage("!cancel reminder 1"))
assert.True(t, res)
- res = c.Message(makeMessage("!list reminders"))
+ res = c.message(makeMessage("!list reminders"))
assert.True(t, res)
assert.Len(t, mb.Messages, 3)
assert.Contains(t, mb.Messages[0], "Sure tester, I'll remind testuser.")
@@ -195,7 +186,7 @@ func TestCancel(t *testing.T) {
func TestCancelMiss(t *testing.T) {
c, mb := setup(t)
assert.NotNil(t, c)
- res := c.Message(makeMessage("!cancel reminder 1"))
+ res := c.message(makeMessage("!cancel reminder 1"))
assert.True(t, res)
assert.Len(t, mb.Messages, 1)
assert.Contains(t, mb.Messages[0], "failed to find and cancel reminder: 1")
@@ -208,13 +199,13 @@ func TestLimitList(t *testing.T) {
assert.NotNil(t, c)
//Someone can redo this with a single batch add, but I can't locally due to an old version of sqllite (maybe).
- res := c.Message(makeMessage("!remind testuser every 1h for 10h don't fail this test"))
+ res := c.message(makeMessage("!remind testuser every 1h for 10h don't fail this test"))
assert.True(t, res)
- res = c.Message(makeMessage("!remind testuser every 1h for 10h don't fail this test"))
+ res = c.message(makeMessage("!remind testuser every 1h for 10h don't fail this test"))
assert.True(t, res)
- res = c.Message(makeMessage("!remind testuser every 1h for 10h don't fail this test"))
+ res = c.message(makeMessage("!remind testuser every 1h for 10h don't fail this test"))
assert.True(t, res)
- res = c.Message(makeMessage("!list reminders"))
+ res = c.message(makeMessage("!list reminders"))
assert.True(t, res)
assert.Len(t, mb.Messages, 4)
assert.Contains(t, mb.Messages[0], "Sure tester, I'll remind testuser.")
@@ -232,22 +223,10 @@ func TestLimitList(t *testing.T) {
func TestHelp(t *testing.T) {
c, mb := setup(t)
assert.NotNil(t, c)
- c.Help("channel", []string{})
+ c.help(bot.Help, msg.Message{Channel: "channel"}, []string{})
assert.Len(t, mb.Messages, 1)
}
-func TestBotMessage(t *testing.T) {
- c, _ := setup(t)
- assert.NotNil(t, c)
- assert.False(t, c.BotMessage(makeMessage("test")))
-}
-
-func TestEvent(t *testing.T) {
- c, _ := setup(t)
- assert.NotNil(t, c)
- assert.False(t, c.Event("dummy", makeMessage("test")))
-}
-
func TestRegisterWeb(t *testing.T) {
c, _ := setup(t)
assert.NotNil(t, c)
diff --git a/plugins/rpgORdie/rpgORdie.go b/plugins/rpgORdie/rpgORdie.go
index 48394d4..8b5a40e 100644
--- a/plugins/rpgORdie/rpgORdie.go
+++ b/plugins/rpgORdie/rpgORdie.go
@@ -98,44 +98,38 @@ func (b *board) checkAndMove(dx, dy int) int {
}
func New(b bot.Bot) *RPGPlugin {
- return &RPGPlugin{
+ rpg := &RPGPlugin{
Bot: b,
listenFor: map[string]*board{},
}
+ b.Register(rpg, bot.Message, rpg.message)
+ b.Register(rpg, bot.Reply, rpg.replyMessage)
+ b.Register(rpg, bot.Help, rpg.help)
+ return rpg
}
-func (p *RPGPlugin) Message(message msg.Message) bool {
+func (p *RPGPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
if strings.ToLower(message.Body) == "start rpg" {
b := NewRandomBoard()
- ts := p.Bot.SendMessage(message.Channel, b.toMessageString())
+ ts, _ := p.Bot.Send(bot.Message, message.Channel, b.toMessageString())
p.listenFor[ts] = b
- p.Bot.ReplyToMessageIdentifier(message.Channel, "Over here.", ts)
+ p.Bot.Send(bot.Reply, message.Channel, "Over here.", ts)
return true
}
return false
}
-func (p *RPGPlugin) LoadData() {
-
-}
-
-func (p *RPGPlugin) Help(channel string, parts []string) {
- p.Bot.SendMessage(channel, "Go find a walkthrough or something.")
-}
-
-func (p *RPGPlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
-func (p *RPGPlugin) BotMessage(message msg.Message) bool {
- return false
+func (p *RPGPlugin) help(kind bot.Kind, message msg.Message, args ...interface{}) bool {
+ p.Bot.Send(bot.Message, message.Channel, "Go find a walkthrough or something.")
+ return true
}
func (p *RPGPlugin) RegisterWeb() *string {
return nil
}
-func (p *RPGPlugin) ReplyMessage(message msg.Message, identifier string) bool {
+func (p *RPGPlugin) replyMessage(kind bot.Kind, message msg.Message, args ...interface{}) bool {
+ identifier := args[0].(string)
if strings.ToLower(message.User.Name) != strings.ToLower(p.Bot.Config().Get("Nick", "bot")) {
if b, ok := p.listenFor[identifier]; ok {
@@ -155,12 +149,12 @@ func (p *RPGPlugin) ReplyMessage(message msg.Message, identifier string) bool {
switch res {
case OK:
- p.Bot.Edit(message.Channel, b.toMessageString(), identifier)
+ p.Bot.Send(bot.Edit, message.Channel, b.toMessageString(), identifier)
case WIN:
- p.Bot.Edit(message.Channel, b.toMessageString(), identifier)
- p.Bot.ReplyToMessageIdentifier(message.Channel, "congratulations, you beat the easiest level imaginable.", identifier)
+ p.Bot.Send(bot.Edit, message.Channel, b.toMessageString(), identifier)
+ p.Bot.Send(bot.Reply, message.Channel, "congratulations, you beat the easiest level imaginable.", identifier)
case INVALID:
- p.Bot.ReplyToMessageIdentifier(message.Channel, fmt.Sprintf("you can't move %s", message.Body), identifier)
+ p.Bot.Send(bot.Reply, message.Channel, fmt.Sprintf("you can't move %s", message.Body), identifier)
}
return true
}
diff --git a/plugins/rss/rss.go b/plugins/rss/rss.go
index 37a5b1d..b25d749 100644
--- a/plugins/rss/rss.go
+++ b/plugins/rss/rss.go
@@ -49,28 +49,31 @@ func (c *cacheItem) getCurrentPage(maxLines int) string {
return page
}
-func New(bot bot.Bot) *RSSPlugin {
- return &RSSPlugin{
- Bot: bot,
+func New(b bot.Bot) *RSSPlugin {
+ rss := &RSSPlugin{
+ Bot: b,
cache: map[string]*cacheItem{},
- shelfLife: time.Minute * 20,
- maxLines: 5,
+ shelfLife: time.Minute * time.Duration(b.Config().GetInt("rss.shelfLife", 20)),
+ maxLines: b.Config().GetInt("rss.maxLines", 5),
}
+ b.Register(rss, bot.Message, rss.message)
+ b.Register(rss, bot.Help, rss.help)
+ return rss
}
-func (p *RSSPlugin) Message(message msg.Message) bool {
+func (p *RSSPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
tokens := strings.Fields(message.Body)
numTokens := len(tokens)
if numTokens == 2 && strings.ToLower(tokens[0]) == "rss" {
if item, ok := p.cache[strings.ToLower(tokens[1])]; ok && time.Now().Before(item.expiration) {
- p.Bot.SendMessage(message.Channel, item.getCurrentPage(p.maxLines))
+ p.Bot.Send(bot.Message, message.Channel, item.getCurrentPage(p.maxLines))
return true
} else {
fp := gofeed.NewParser()
feed, err := fp.ParseURL(tokens[1])
if err != nil {
- p.Bot.SendMessage(message.Channel, fmt.Sprintf("RSS error: %s", err.Error()))
+ p.Bot.Send(bot.Message, message.Channel, fmt.Sprintf("RSS error: %s", err.Error()))
return true
}
item := &cacheItem{
@@ -86,7 +89,7 @@ func (p *RSSPlugin) Message(message msg.Message) bool {
p.cache[strings.ToLower(tokens[1])] = item
- p.Bot.SendMessage(message.Channel, item.getCurrentPage(p.maxLines))
+ p.Bot.Send(bot.Message, message.Channel, item.getCurrentPage(p.maxLines))
return true
}
}
@@ -94,28 +97,13 @@ func (p *RSSPlugin) Message(message msg.Message) bool {
return false
}
-func (p *RSSPlugin) LoadData() {
- // This bot has no data to load
-}
-
// Help responds to help requests. Every plugin must implement a help function.
-func (p *RSSPlugin) Help(channel string, parts []string) {
- p.Bot.SendMessage(channel, "try '!rss http://rss.cnn.com/rss/edition.rss'")
-}
-
-// Empty event handler because this plugin does not do anything on event recv
-func (p *RSSPlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
-// Handler for bot's own messages
-func (p *RSSPlugin) BotMessage(message msg.Message) bool {
- return false
+func (p *RSSPlugin) help(kind bot.Kind, message msg.Message, args ...interface{}) bool {
+ p.Bot.Send(bot.Message, message.Channel, "try '!rss http://rss.cnn.com/rss/edition.rss'")
+ return true
}
// Register any web URLs desired
func (p *RSSPlugin) RegisterWeb() *string {
return nil
}
-
-func (p *RSSPlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
diff --git a/plugins/rss/rss_test.go b/plugins/rss/rss_test.go
index 7c20fd1..900031a 100644
--- a/plugins/rss/rss_test.go
+++ b/plugins/rss/rss_test.go
@@ -11,12 +11,12 @@ import (
"github.com/velour/catbase/bot/user"
)
-func makeMessage(payload string) msg.Message {
+func makeMessage(payload string) (bot.Kind, msg.Message) {
isCmd := strings.HasPrefix(payload, "!")
if isCmd {
payload = payload[1:]
}
- return msg.Message{
+ return bot.Message, msg.Message{
User: &user.User{Name: "tester"},
Channel: "test",
Body: payload,
@@ -28,7 +28,7 @@ func TestRSS(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("!rss http://rss.cnn.com/rss/edition.rss"))
+ res := c.message(makeMessage("!rss http://rss.cnn.com/rss/edition.rss"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
}
@@ -38,7 +38,7 @@ func TestRSSPaging(t *testing.T) {
c := New(mb)
assert.NotNil(t, c)
for i := 0; i < 20; i++ {
- res := c.Message(makeMessage("!rss http://rss.cnn.com/rss/edition.rss"))
+ res := c.message(makeMessage("!rss http://rss.cnn.com/rss/edition.rss"))
assert.True(t, res)
}
diff --git a/plugins/sisyphus/sisyphus.go b/plugins/sisyphus/sisyphus.go
index 91a9fbc..5a0a8b8 100644
--- a/plugins/sisyphus/sisyphus.go
+++ b/plugins/sisyphus/sisyphus.go
@@ -37,17 +37,17 @@ type game struct {
nextAns int
}
-func NewRandomGame(bot bot.Bot, channel, who string) *game {
+func NewRandomGame(b bot.Bot, channel, who string) *game {
size := rand.Intn(9) + 2
g := game{
channel: channel,
- bot: bot,
+ bot: b,
who: who,
start: time.Now(),
size: size,
current: size / 2,
}
- g.id = bot.SendMessage(channel, g.toMessageString())
+ g.id, _ = b.Send(bot.Message, channel, g.toMessageString())
g.schedulePush()
g.scheduleDecrement()
@@ -98,11 +98,11 @@ func (g *game) endGame() {
func (g *game) handleDecrement() {
g.current++
- g.bot.Edit(g.channel, g.toMessageString(), g.id)
+ g.bot.Send(bot.Edit, g.channel, g.toMessageString(), g.id)
if g.current > g.size-2 {
- g.bot.ReplyToMessageIdentifier(g.channel, "you lose", g.id)
+ g.bot.Send(bot.Reply, g.channel, "you lose", g.id)
msg := fmt.Sprintf("%s just lost the game after %s", g.who, time.Now().Sub(g.start))
- g.bot.SendMessage(g.channel, msg)
+ g.bot.Send(bot.Message, g.channel, msg)
g.endGame()
} else {
g.scheduleDecrement()
@@ -110,7 +110,7 @@ func (g *game) handleDecrement() {
}
func (g *game) handleNotify() {
- g.bot.ReplyToMessageIdentifier(g.channel, "You can push now.\n"+g.generateQuestion(), g.id)
+ g.bot.Send(bot.Reply, g.channel, "You can push now.\n"+g.generateQuestion(), g.id)
}
func (g *game) generateQuestion() string {
@@ -162,39 +162,37 @@ func (g *game) toMessageString() string {
}
func New(b bot.Bot) *SisyphusPlugin {
- return &SisyphusPlugin{
+ sp := &SisyphusPlugin{
Bot: b,
listenFor: map[string]*game{},
}
+ b.Register(sp, bot.Message, sp.message)
+ b.Register(sp, bot.Reply, sp.replyMessage)
+ b.Register(sp, bot.Help, sp.help)
+ return sp
}
-func (p *SisyphusPlugin) Message(message msg.Message) bool {
+func (p *SisyphusPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
if strings.ToLower(message.Body) == "start sisyphus" {
b := NewRandomGame(p.Bot, message.Channel, message.User.Name)
p.listenFor[b.id] = b
- p.Bot.ReplyToMessageIdentifier(message.Channel, "Over here.", b.id)
+ p.Bot.Send(bot.Reply, message.Channel, "Over here.", b.id)
return true
}
return false
}
-func (p *SisyphusPlugin) Help(channel string, parts []string) {
- p.Bot.SendMessage(channel, "https://en.wikipedia.org/wiki/Sisyphus")
-}
-
-func (p *SisyphusPlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
-func (p *SisyphusPlugin) BotMessage(message msg.Message) bool {
- return false
+func (p *SisyphusPlugin) help(kind bot.Kind, message msg.Message, args ...interface{}) bool {
+ p.Bot.Send(bot.Message, message.Channel, "https://en.wikipedia.org/wiki/Sisyphus")
+ return true
}
func (p *SisyphusPlugin) RegisterWeb() *string {
return nil
}
-func (p *SisyphusPlugin) ReplyMessage(message msg.Message, identifier string) bool {
+func (p *SisyphusPlugin) replyMessage(kind bot.Kind, message msg.Message, args ...interface{}) bool {
+ identifier := args[0].(string)
if strings.ToLower(message.User.Name) != strings.ToLower(p.Bot.Config().Get("Nick", "bot")) {
if g, ok := p.listenFor[identifier]; ok {
@@ -211,18 +209,18 @@ func (p *SisyphusPlugin) ReplyMessage(message msg.Message, identifier string) bo
if time.Now().After(g.nextPush) {
if g.checkAnswer(message.Body) {
- p.Bot.Edit(message.Channel, g.toMessageString(), identifier)
+ p.Bot.Send(bot.Edit, message.Channel, g.toMessageString(), identifier)
g.schedulePush()
msg := fmt.Sprintf("Ok. You can push again in %s", g.nextPush.Sub(time.Now()))
- p.Bot.ReplyToMessageIdentifier(message.Channel, msg, identifier)
+ p.Bot.Send(bot.Reply, message.Channel, msg, identifier)
} else {
- p.Bot.ReplyToMessageIdentifier(message.Channel, "you lose", identifier)
+ p.Bot.Send(bot.Reply, message.Channel, "you lose", identifier)
msg := fmt.Sprintf("%s just lost the sisyphus game after %s", g.who, time.Now().Sub(g.start))
- p.Bot.SendMessage(message.Channel, msg)
+ p.Bot.Send(bot.Message, message.Channel, msg)
g.endGame()
}
} else {
- p.Bot.ReplyToMessageIdentifier(message.Channel, "you cannot push yet", identifier)
+ p.Bot.Send(bot.Reply, message.Channel, "you cannot push yet", identifier)
}
return true
}
diff --git a/plugins/talker/talker.go b/plugins/talker/talker.go
index b96866f..46ba61a 100644
--- a/plugins/talker/talker.go
+++ b/plugins/talker/talker.go
@@ -43,13 +43,16 @@ type TalkerPlugin struct {
sayings []string
}
-func New(bot bot.Bot) *TalkerPlugin {
- return &TalkerPlugin{
- Bot: bot,
+func New(b bot.Bot) *TalkerPlugin {
+ tp := &TalkerPlugin{
+ Bot: b,
}
+ b.Register(tp, bot.Message, tp.message)
+ b.Register(tp, bot.Help, tp.help)
+ return tp
}
-func (p *TalkerPlugin) Message(message msg.Message) bool {
+func (p *TalkerPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
channel := message.Channel
body := message.Body
lowermessage := strings.ToLower(body)
@@ -57,7 +60,7 @@ func (p *TalkerPlugin) Message(message msg.Message) bool {
// TODO: This ought to be space split afterwards to remove any punctuation
if message.Command && strings.HasPrefix(lowermessage, "say") {
msg := strings.TrimSpace(body[3:])
- p.Bot.SendMessage(channel, msg)
+ p.Bot.Send(bot.Message, channel, msg)
return true
}
@@ -73,30 +76,19 @@ func (p *TalkerPlugin) Message(message msg.Message) bool {
line = strings.Replace(line, "{nick}", nick, 1)
output += line + "\n"
}
- p.Bot.SendMessage(channel, output)
+ p.Bot.Send(bot.Message, channel, output)
return true
}
return false
}
-func (p *TalkerPlugin) Help(channel string, parts []string) {
- p.Bot.SendMessage(channel, "Hi, this is talker. I like to talk about FredFelps!")
-}
-
-// Empty event handler because this plugin does not do anything on event recv
-func (p *TalkerPlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
-// Handler for bot's own messages
-func (p *TalkerPlugin) BotMessage(message msg.Message) bool {
- return false
+func (p *TalkerPlugin) help(kind bot.Kind, message msg.Message, args ...interface{}) bool {
+ p.Bot.Send(bot.Message, message.Channel, "Hi, this is talker. I like to talk about FredFelps!")
+ return true
}
// Register any web URLs desired
func (p *TalkerPlugin) RegisterWeb() *string {
return nil
}
-
-func (p *TalkerPlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
diff --git a/plugins/talker/talker_test.go b/plugins/talker/talker_test.go
index dd45ec1..2408f45 100644
--- a/plugins/talker/talker_test.go
+++ b/plugins/talker/talker_test.go
@@ -12,12 +12,12 @@ import (
"github.com/velour/catbase/bot/user"
)
-func makeMessage(payload string) msg.Message {
+func makeMessage(payload string) (bot.Kind, msg.Message) {
isCmd := strings.HasPrefix(payload, "!")
if isCmd {
payload = payload[1:]
}
- return msg.Message{
+ return bot.Message, msg.Message{
User: &user.User{Name: "tester"},
Channel: "test",
Body: payload,
@@ -29,7 +29,7 @@ func TestGoatse(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("goatse"))
+ res := c.message(makeMessage("goatse"))
assert.Len(t, mb.Messages, 0)
assert.False(t, res)
}
@@ -38,7 +38,7 @@ func TestGoatseCommand(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("!goatse"))
+ res := c.message(makeMessage("!goatse"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "g o a t s e")
@@ -48,7 +48,7 @@ func TestGoatseWithNickCommand(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("!goatse seabass"))
+ res := c.message(makeMessage("!goatse seabass"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "g o a t s e")
@@ -59,7 +59,7 @@ func TestSay(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("say hello"))
+ res := c.message(makeMessage("say hello"))
assert.Len(t, mb.Messages, 0)
assert.False(t, res)
}
@@ -68,7 +68,7 @@ func TestSayCommand(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- res := c.Message(makeMessage("!say hello"))
+ res := c.message(makeMessage("!say hello"))
assert.Len(t, mb.Messages, 1)
assert.True(t, res)
assert.Contains(t, mb.Messages[0], "hello")
@@ -78,24 +78,10 @@ func TestHelp(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
assert.NotNil(t, c)
- c.Help("channel", []string{})
+ c.help(bot.Help, msg.Message{Channel: "channel"}, []string{})
assert.Len(t, mb.Messages, 1)
}
-func TestBotMessage(t *testing.T) {
- mb := bot.NewMockBot()
- c := New(mb)
- assert.NotNil(t, c)
- assert.False(t, c.BotMessage(makeMessage("test")))
-}
-
-func TestEvent(t *testing.T) {
- mb := bot.NewMockBot()
- c := New(mb)
- assert.NotNil(t, c)
- assert.False(t, c.Event("dummy", makeMessage("test")))
-}
-
func TestRegisterWeb(t *testing.T) {
mb := bot.NewMockBot()
c := New(mb)
diff --git a/plugins/tell/tell.go b/plugins/tell/tell.go
index 05bab8a..c852141 100644
--- a/plugins/tell/tell.go
+++ b/plugins/tell/tell.go
@@ -16,23 +16,25 @@ type TellPlugin struct {
}
func New(b bot.Bot) *TellPlugin {
- return &TellPlugin{b, make(map[string][]string)}
+ tp := &TellPlugin{b, make(map[string][]string)}
+ b.Register(tp, bot.Message, tp.message)
+ return tp
}
-func (t *TellPlugin) Message(message msg.Message) bool {
+func (t *TellPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
if strings.HasPrefix(strings.ToLower(message.Body), "tell") {
parts := strings.Split(message.Body, " ")
target := strings.ToLower(parts[1])
newMessage := strings.Join(parts[2:], " ")
newMessage = fmt.Sprintf("Hey, %s. %s said: %s", target, message.User.Name, newMessage)
t.users[target] = append(t.users[target], newMessage)
- t.b.SendMessage(message.Channel, fmt.Sprintf("Okay. I'll tell %s.", target))
+ t.b.Send(bot.Message, message.Channel, fmt.Sprintf("Okay. I'll tell %s.", target))
return true
}
uname := strings.ToLower(message.User.Name)
if msg, ok := t.users[uname]; ok && len(msg) > 0 {
for _, m := range msg {
- t.b.SendMessage(message.Channel, string(m))
+ t.b.Send(bot.Message, message.Channel, string(m))
}
t.users[uname] = []string{}
return true
@@ -40,8 +42,4 @@ func (t *TellPlugin) Message(message msg.Message) bool {
return false
}
-func (t *TellPlugin) Event(kind string, message msg.Message) bool { return false }
-func (t *TellPlugin) ReplyMessage(msg.Message, string) bool { return false }
-func (t *TellPlugin) BotMessage(message msg.Message) bool { return false }
-func (t *TellPlugin) Help(channel string, parts []string) {}
-func (t *TellPlugin) RegisterWeb() *string { return nil }
+func (t *TellPlugin) RegisterWeb() *string { return nil }
diff --git a/plugins/twitch/twitch.go b/plugins/twitch/twitch.go
index 9b2c2b7..0c17a24 100644
--- a/plugins/twitch/twitch.go
+++ b/plugins/twitch/twitch.go
@@ -51,10 +51,10 @@ type stream struct {
} `json:"pagination"`
}
-func New(bot bot.Bot) *TwitchPlugin {
+func New(b bot.Bot) *TwitchPlugin {
p := &TwitchPlugin{
- Bot: bot,
- config: bot.Config(),
+ Bot: b,
+ config: b.Config(),
twitchList: map[string]*Twitcher{},
}
@@ -70,13 +70,10 @@ func New(bot bot.Bot) *TwitchPlugin {
go p.twitchLoop(ch)
}
+ b.Register(p, bot.Message, p.message)
return p
}
-func (p *TwitchPlugin) BotMessage(message msg.Message) bool {
- return false
-}
-
func (p *TwitchPlugin) RegisterWeb() *string {
http.HandleFunc("/isstreaming/", p.serveStreaming)
tmp := "/isstreaming"
@@ -114,7 +111,7 @@ func (p *TwitchPlugin) serveStreaming(w http.ResponseWriter, r *http.Request) {
}
}
-func (p *TwitchPlugin) Message(message msg.Message) bool {
+func (p *TwitchPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
if strings.ToLower(message.Body) == "twitch status" {
channel := message.Channel
if users := p.config.GetArray("Twitch."+channel+".Users", []string{}); len(users) > 0 {
@@ -130,17 +127,10 @@ func (p *TwitchPlugin) Message(message msg.Message) bool {
return false
}
-func (p *TwitchPlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
-func (p *TwitchPlugin) LoadData() {
-
-}
-
-func (p *TwitchPlugin) Help(channel string, parts []string) {
+func (p *TwitchPlugin) help(kind bot.Kind, message msg.Message, args ...interface{}) bool {
msg := "There's no help for you here."
- p.Bot.SendMessage(channel, msg)
+ p.Bot.Send(bot.Message, message.Channel, msg)
+ return true
}
func (p *TwitchPlugin) twitchLoop(channel string) {
@@ -224,21 +214,19 @@ func (p *TwitchPlugin) checkTwitch(channel string, twitcher *Twitcher, alwaysPri
streamWord := p.config.Get("Twitch.StreamWord", "streaming")
if alwaysPrintStatus {
if game == "" {
- p.Bot.SendMessage(channel, fmt.Sprintf("%s is not %s.", twitcher.name, streamWord))
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("%s is not %s.", twitcher.name, streamWord))
} else {
- p.Bot.SendMessage(channel, fmt.Sprintf("%s is %s %s at %s", twitcher.name, streamWord, game, twitcher.URL()))
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("%s is %s %s at %s", twitcher.name, streamWord, game, twitcher.URL()))
}
} else if game == "" {
if twitcher.game != "" {
- p.Bot.SendMessage(channel, fmt.Sprintf("%s just stopped %s.", twitcher.name, streamWord))
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("%s just stopped %s.", twitcher.name, streamWord))
}
twitcher.game = ""
} else {
if twitcher.game != game {
- p.Bot.SendMessage(channel, fmt.Sprintf("%s is %s %s at %s", twitcher.name, streamWord, game, twitcher.URL()))
+ p.Bot.Send(bot.Message, channel, fmt.Sprintf("%s is %s %s at %s", twitcher.name, streamWord, game, twitcher.URL()))
}
twitcher.game = game
}
}
-
-func (p *TwitchPlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
diff --git a/plugins/twitch/twitch_test.go b/plugins/twitch/twitch_test.go
index 728fe00..b3d88ec 100644
--- a/plugins/twitch/twitch_test.go
+++ b/plugins/twitch/twitch_test.go
@@ -12,12 +12,12 @@ import (
"github.com/velour/catbase/bot/user"
)
-func makeMessage(payload string) msg.Message {
+func makeMessage(payload string) (bot.Kind, msg.Message) {
isCmd := strings.HasPrefix(payload, "!")
if isCmd {
payload = payload[1:]
}
- return msg.Message{
+ return bot.Message, msg.Message{
User: &user.User{Name: "tester"},
Channel: "test",
Body: payload,
@@ -44,6 +44,6 @@ func makeTwitchPlugin(t *testing.T) (*TwitchPlugin, *bot.MockBot) {
func TestTwitch(t *testing.T) {
b, mb := makeTwitchPlugin(t)
- b.Message(makeMessage("!twitch status"))
+ b.message(makeMessage("!twitch status"))
assert.NotEmpty(t, mb.Messages)
}
diff --git a/plugins/your/your.go b/plugins/your/your.go
index c7c8b45..a319039 100644
--- a/plugins/your/your.go
+++ b/plugins/your/your.go
@@ -17,17 +17,20 @@ type YourPlugin struct {
}
// NewYourPlugin creates a new YourPlugin with the Plugin interface
-func New(bot bot.Bot) *YourPlugin {
- return &YourPlugin{
- bot: bot,
- config: bot.Config(),
+func New(b bot.Bot) *YourPlugin {
+ yp := &YourPlugin{
+ bot: b,
+ config: b.Config(),
}
+ b.Register(yp, bot.Message, yp.message)
+ b.Register(yp, bot.Help, yp.help)
+ return yp
}
// Message responds to the bot hook on recieving messages.
// This function returns true if the plugin responds in a meaningful way to the users message.
// Otherwise, the function returns false and the bot continues execution of other plugins.
-func (p *YourPlugin) Message(message msg.Message) bool {
+func (p *YourPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
maxLen := p.config.GetInt("your.maxlength", 140)
if len(message.Body) > maxLen {
return false
@@ -43,30 +46,19 @@ func (p *YourPlugin) Message(message msg.Message) bool {
}
}
if msg != message.Body {
- p.bot.SendMessage(message.Channel, msg)
+ p.bot.Send(bot.Message, message.Channel, msg)
return true
}
return false
}
// Help responds to help requests. Every plugin must implement a help function.
-func (p *YourPlugin) Help(channel string, parts []string) {
- p.bot.SendMessage(channel, "Your corrects people's grammar.")
-}
-
-// Empty event handler because this plugin does not do anything on event recv
-func (p *YourPlugin) Event(kind string, message msg.Message) bool {
- return false
-}
-
-// Handler for bot's own messages
-func (p *YourPlugin) BotMessage(message msg.Message) bool {
- return false
+func (p *YourPlugin) help(kind bot.Kind, message msg.Message, args ...interface{}) bool {
+ p.bot.Send(bot.Message, message.Channel, "Your corrects people's grammar.")
+ return true
}
// Register any web URLs desired
func (p *YourPlugin) RegisterWeb() *string {
return nil
}
-
-func (p *YourPlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
diff --git a/plugins/your/your_test.go b/plugins/your/your_test.go
index 75a0ace..3c6136a 100644
--- a/plugins/your/your_test.go
+++ b/plugins/your/your_test.go
@@ -12,12 +12,12 @@ import (
"github.com/velour/catbase/bot/user"
)
-func makeMessage(payload string) msg.Message {
+func makeMessage(payload string) (bot.Kind, msg.Message) {
isCmd := strings.HasPrefix(payload, "!")
if isCmd {
payload = payload[1:]
}
- return msg.Message{
+ return bot.Message, msg.Message{
User: &user.User{Name: "tester"},
Channel: "test",
Body: payload,
@@ -39,7 +39,7 @@ func TestReplacement(t *testing.T) {
c.config.Set("your.replacements.0.freq", "1.0")
c.config.Set("your.replacements.0.this", "fuck")
c.config.Set("your.replacements.0.that", "duck")
- res := c.Message(makeMessage("fuck a duck"))
+ res := c.message(makeMessage("fuck a duck"))
assert.True(t, res)
assert.Len(t, mb.Messages, 1)
assert.Contains(t, mb.Messages[0], "duck a duck")
@@ -60,6 +60,6 @@ func TestNoReplacement(t *testing.T) {
c.config.Set("your.replacements.2.freq", "1.0")
c.config.Set("your.replacements.2.this", "Fuck")
c.config.Set("your.replacements.2.that", "duck")
- c.Message(makeMessage("fuck a duck"))
+ c.message(makeMessage("fuck a duck"))
assert.Len(t, mb.Messages, 0)
}
diff --git a/plugins/zork/zork.go b/plugins/zork/zork.go
index 7e5d0af..b5ac682 100644
--- a/plugins/zork/zork.go
+++ b/plugins/zork/zork.go
@@ -26,11 +26,14 @@ type ZorkPlugin struct {
zorks map[string]io.WriteCloser
}
-func New(b bot.Bot) bot.Handler {
- return &ZorkPlugin{
+func New(b bot.Bot) bot.Plugin {
+ z := &ZorkPlugin{
bot: b,
zorks: make(map[string]io.WriteCloser),
}
+ b.Register(z, bot.Message, z.message)
+ b.Register(z, bot.Help, z.help)
+ return z
}
func (p *ZorkPlugin) runZork(ch string) error {
@@ -75,7 +78,7 @@ func (p *ZorkPlugin) runZork(ch string) error {
m := strings.Replace(s.Text(), ">", "", -1)
m = strings.Replace(m, "\n", "\n>", -1)
m = ">" + m + "\n"
- p.bot.SendMessage(ch, m)
+ p.bot.Send(bot.Message, ch, m)
}
}()
go func() {
@@ -91,7 +94,7 @@ func (p *ZorkPlugin) runZork(ch string) error {
return nil
}
-func (p *ZorkPlugin) Message(message msg.Message) bool {
+func (p *ZorkPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool {
m := strings.ToLower(message.Body)
log.Printf("got message [%s]\n", m)
if ts := strings.Fields(m); len(ts) < 1 || ts[0] != "zork" {
@@ -104,7 +107,7 @@ func (p *ZorkPlugin) Message(message msg.Message) bool {
defer p.Unlock()
if p.zorks[ch] == nil {
if err := p.runZork(ch); err != nil {
- p.bot.SendMessage(ch, "failed to run zork: "+err.Error())
+ p.bot.Send(bot.Message, ch, "failed to run zork: "+err.Error())
return true
}
}
@@ -113,14 +116,9 @@ func (p *ZorkPlugin) Message(message msg.Message) bool {
return true
}
-func (p *ZorkPlugin) Event(_ string, _ msg.Message) bool { return false }
-
-func (p *ZorkPlugin) BotMessage(_ msg.Message) bool { return false }
-
-func (p *ZorkPlugin) Help(ch string, _ []string) {
- p.bot.SendMessage(ch, "Play zork using 'zork '.")
+func (p *ZorkPlugin) help(kind bot.Kind, message msg.Message, args ...interface{}) bool {
+ p.bot.Send(bot.Message, message.Channel, "Play zork using 'zork '.")
+ return true
}
func (p *ZorkPlugin) RegisterWeb() *string { return nil }
-
-func (p *ZorkPlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
diff --git a/slack/slack.go b/slack/slack.go
index 3c1049b..dcf616b 100644
--- a/slack/slack.go
+++ b/slack/slack.go
@@ -44,9 +44,7 @@ type Slack struct {
emoji map[string]string
- eventReceived func(msg.Message)
- messageReceived func(msg.Message)
- replyMessageReceived func(msg.Message, string)
+ event func(bot.Kind, msg.Message, ...interface{})
}
var idCounter uint64
@@ -177,7 +175,31 @@ func New(c *config.Config) *Slack {
}
}
-func checkReturnStatus(response *http.Response) bool {
+func (s *Slack) Send(kind bot.Kind, args ...interface{}) (string, error) {
+ switch kind {
+ case bot.Message:
+ return s.sendMessage(args[0].(string), args[1].(string))
+ case bot.Action:
+ return s.sendAction(args[0].(string), args[1].(string))
+ case bot.Edit:
+ return s.edit(args[0].(string), args[1].(string), args[2].(string))
+ case bot.Reply:
+ switch args[2].(type) {
+ case msg.Message:
+ return s.replyToMessage(args[0].(string), args[1].(string), args[2].(msg.Message))
+ case string:
+ return s.replyToMessageIdentifier(args[0].(string), args[1].(string), args[2].(string))
+ default:
+ return "", fmt.Errorf("Invalid types given to Reply")
+ }
+ case bot.Reaction:
+ return s.react(args[0].(string), args[1].(string), args[2].(msg.Message))
+ default:
+ }
+ return "", fmt.Errorf("No handler for message type %d", kind)
+}
+
+func checkReturnStatus(response *http.Response) error {
type Response struct {
OK bool `json:"ok"`
}
@@ -185,32 +207,24 @@ func checkReturnStatus(response *http.Response) bool {
body, err := ioutil.ReadAll(response.Body)
response.Body.Close()
if err != nil {
- log.Printf("Error reading Slack API body: %s", err)
- return false
+ err := fmt.Errorf("Error reading Slack API body: %s", err)
+ return err
}
var resp Response
err = json.Unmarshal(body, &resp)
if err != nil {
- log.Printf("Error parsing message response: %s", err)
- return false
+ err := fmt.Errorf("Error parsing message response: %s", err)
+ return err
}
- return resp.OK
+ return nil
}
-func (s *Slack) RegisterEventReceived(f func(msg.Message)) {
- s.eventReceived = f
+func (s *Slack) RegisterEvent(f func(bot.Kind, msg.Message, ...interface{})) {
+ s.event = f
}
-func (s *Slack) RegisterMessageReceived(f func(msg.Message)) {
- s.messageReceived = f
-}
-
-func (s *Slack) RegisterReplyMessageReceived(f func(msg.Message, string)) {
- s.replyMessageReceived = f
-}
-
-func (s *Slack) SendMessageType(channel, message string, meMessage bool) (string, error) {
+func (s *Slack) sendMessageType(channel, message string, meMessage bool) (string, error) {
postUrl := "https://slack.com/api/chat.postMessage"
if meMessage {
postUrl = "https://slack.com/api/chat.meMessage"
@@ -262,19 +276,19 @@ func (s *Slack) SendMessageType(channel, message string, meMessage bool) (string
return mr.Timestamp, err
}
-func (s *Slack) SendMessage(channel, message string) string {
+func (s *Slack) sendMessage(channel, message string) (string, error) {
log.Printf("Sending message to %s: %s", channel, message)
- identifier, _ := s.SendMessageType(channel, message, false)
- return identifier
+ identifier, err := s.sendMessageType(channel, message, false)
+ return identifier, err
}
-func (s *Slack) SendAction(channel, message string) string {
+func (s *Slack) sendAction(channel, message string) (string, error) {
log.Printf("Sending action to %s: %s", channel, message)
- identifier, _ := s.SendMessageType(channel, "_"+message+"_", true)
- return identifier
+ identifier, err := s.sendMessageType(channel, "_"+message+"_", true)
+ return identifier, err
}
-func (s *Slack) ReplyToMessageIdentifier(channel, message, identifier string) (string, bool) {
+func (s *Slack) replyToMessageIdentifier(channel, message, identifier string) (string, error) {
nick := s.config.Get("Nick", "bot")
icon := s.config.Get("IconURL", "https://placekitten.com/128/128")
@@ -288,15 +302,15 @@ func (s *Slack) ReplyToMessageIdentifier(channel, message, identifier string) (s
})
if err != nil {
- log.Printf("Error sending Slack reply: %s", err)
- return "", false
+ err := fmt.Errorf("Error sending Slack reply: %s", err)
+ return "", err
}
body, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
- log.Printf("Error reading Slack API body: %s", err)
- return "", false
+ err := fmt.Errorf("Error reading Slack API body: %s", err)
+ return "", err
}
log.Println(string(body))
@@ -309,22 +323,22 @@ func (s *Slack) ReplyToMessageIdentifier(channel, message, identifier string) (s
var mr MessageResponse
err = json.Unmarshal(body, &mr)
if err != nil {
- log.Printf("Error parsing message response: %s", err)
- return "", false
+ err := fmt.Errorf("Error parsing message response: %s", err)
+ return "", err
}
if !mr.OK {
- return "", false
+ return "", fmt.Errorf("Got !OK from slack message response")
}
- return mr.Timestamp, err == nil
+ return mr.Timestamp, err
}
-func (s *Slack) ReplyToMessage(channel, message string, replyTo msg.Message) (string, bool) {
- return s.ReplyToMessageIdentifier(channel, message, replyTo.AdditionalData["RAW_SLACK_TIMESTAMP"])
+func (s *Slack) replyToMessage(channel, message string, replyTo msg.Message) (string, error) {
+ return s.replyToMessageIdentifier(channel, message, replyTo.AdditionalData["RAW_SLACK_TIMESTAMP"])
}
-func (s *Slack) React(channel, reaction string, message msg.Message) bool {
+func (s *Slack) react(channel, reaction string, message msg.Message) (string, error) {
log.Printf("Reacting in %s: %s", channel, reaction)
resp, err := http.PostForm("https://slack.com/api/reactions.add",
url.Values{"token": {s.token},
@@ -332,13 +346,13 @@ func (s *Slack) React(channel, reaction string, message msg.Message) bool {
"channel": {channel},
"timestamp": {message.AdditionalData["RAW_SLACK_TIMESTAMP"]}})
if err != nil {
- log.Printf("reaction failed: %s", err)
- return false
+ err := fmt.Errorf("reaction failed: %s", err)
+ return "", err
}
- return checkReturnStatus(resp)
+ return "", checkReturnStatus(resp)
}
-func (s *Slack) Edit(channel, newMessage, identifier string) bool {
+func (s *Slack) edit(channel, newMessage, identifier string) (string, error) {
log.Printf("Editing in (%s) %s: %s", identifier, channel, newMessage)
resp, err := http.PostForm("https://slack.com/api/chat.update",
url.Values{"token": {s.token},
@@ -346,10 +360,10 @@ func (s *Slack) Edit(channel, newMessage, identifier string) bool {
"text": {newMessage},
"ts": {identifier}})
if err != nil {
- log.Printf("edit failed: %s", err)
- return false
+ err := fmt.Errorf("edit failed: %s", err)
+ return "", err
}
- return checkReturnStatus(resp)
+ return "", checkReturnStatus(resp)
}
func (s *Slack) GetEmojiList() map[string]string {
@@ -441,11 +455,11 @@ func (s *Slack) Serve() error {
log.Printf("Ignoring message: %+v\nlastRecieved: %v msg: %v", msg.ID, s.lastRecieved, m.Time)
} else {
s.lastRecieved = m.Time
- s.messageReceived(m)
+ s.event(bot.Message, m)
}
} else if msg.ThreadTs != "" {
//we're throwing away some information here by not parsing the correct reply object type, but that's okay
- s.replyMessageReceived(s.buildLightReplyMessage(msg), msg.ThreadTs)
+ s.event(bot.Reply, s.buildLightReplyMessage(msg), msg.ThreadTs)
} else {
log.Printf("THAT MESSAGE WAS HIDDEN: %+v", msg.ID)
}