From 1bf6997144ddb0abccaa67c734f357dfc51191f6 Mon Sep 17 00:00:00 2001 From: skkiesel Date: Sat, 17 Jun 2017 16:20:06 -0400 Subject: [PATCH 1/3] initial implementation and POC to getting reactions pushed into slack via catbase --- bot/handlers.go | 4 ++++ bot/interfaces.go | 2 ++ bot/msg/message.go | 1 + irc/irc.go | 4 ++++ main.go | 2 ++ plugins/reaction/reaction.go | 46 ++++++++++++++++++++++++++++++++++++ slack/slack.go | 22 +++++++++++++++++ 7 files changed, 81 insertions(+) create mode 100644 plugins/reaction/reaction.go diff --git a/bot/handlers.go b/bot/handlers.go index ba4c5b1..18bb052 100644 --- a/bot/handlers.go +++ b/bot/handlers.go @@ -61,6 +61,10 @@ func (b *bot) SendAction(channel, message string) { b.conn.SendAction(channel, message) } +func (b *bot) React(channel, reaction string, message msg.Message) { + b.conn.React(channel, reaction, message) +} + // Checks to see if the user is asking for help, returns true if so and handles the situation. func (b *bot) checkHelp(channel string, parts []string) { if len(parts) == 1 { diff --git a/bot/interfaces.go b/bot/interfaces.go index 43362f3..b1c74f6 100644 --- a/bot/interfaces.go +++ b/bot/interfaces.go @@ -17,6 +17,7 @@ type Bot interface { AddHandler(string, Handler) SendMessage(string, string) SendAction(string, string) + React(string, string, msg.Message) MsgReceived(msg.Message) EventReceived(msg.Message) Filter(msg.Message, string) string @@ -30,6 +31,7 @@ type Connector interface { SendMessage(channel, message string) SendAction(channel, message string) + React(string, string, msg.Message) Serve() Who(string) []string diff --git a/bot/msg/message.go b/bot/msg/message.go index 28f0038..88e61f6 100644 --- a/bot/msg/message.go +++ b/bot/msg/message.go @@ -19,4 +19,5 @@ type Message struct { Action bool Time time.Time Host string + AdditionalData map[string]string } diff --git a/irc/irc.go b/irc/irc.go index 62f1ed7..42775a1 100644 --- a/irc/irc.go +++ b/irc/irc.go @@ -98,6 +98,10 @@ func (i *Irc) SendAction(channel, message string) { i.SendMessage(channel, message) } +func (i *Irc) React(channel, reaction string, message msg.Message) { + //we're not goign to do anything because it's IRC +} + func (i *Irc) Serve() { if i.eventReceived == nil || i.messageReceived == nil { log.Fatal("Missing an event handler") diff --git a/main.go b/main.go index ad3c375..d2e87d9 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,7 @@ import ( "github.com/velour/catbase/plugins/dice" "github.com/velour/catbase/plugins/fact" "github.com/velour/catbase/plugins/leftpad" + "github.com/velour/catbase/plugins/reaction" "github.com/velour/catbase/plugins/reminder" "github.com/velour/catbase/plugins/rss" "github.com/velour/catbase/plugins/stats" @@ -60,6 +61,7 @@ func main() { b.AddHandler("babbler", babbler.New(b)) b.AddHandler("zork", zork.New(b)) b.AddHandler("rss", rss.New(b)) + b.AddHandler("reaction", reaction.New(b)) // catches anything left, will always return true b.AddHandler("factoid", fact.New(b)) diff --git a/plugins/reaction/reaction.go b/plugins/reaction/reaction.go new file mode 100644 index 0000000..dc75b96 --- /dev/null +++ b/plugins/reaction/reaction.go @@ -0,0 +1,46 @@ +// © 2013 the CatBase Authors under the WTFPL. See AUTHORS for the list of authors. + +package reaction + +import ( + "time" + "math/rand" + + "github.com/velour/catbase/bot" + "github.com/velour/catbase/bot/msg" +) + +type ReactionPlugin struct { + Bot bot.Bot +} + +func New(bot bot.Bot) *ReactionPlugin { + rand.Seed(time.Now().Unix()) + + return &ReactionPlugin{ + Bot: bot, + } +} + +func (p *ReactionPlugin) Message(message msg.Message) bool { + if rand.Intn(100) == 0 { + p.Bot.React(message.Channel, "+1", 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 +} diff --git a/slack/slack.go b/slack/slack.go index 9dc9a8c..93ca185 100644 --- a/slack/slack.go +++ b/slack/slack.go @@ -82,6 +82,12 @@ type slackMessage struct { } `json:"error"` } +type slackReaction struct { + Reaction string `json:"name"` + Channel string `json:"channel"` + Timestamp float64 `json:"timestamp"` +} + type rtmStart struct { Ok bool `json:"ok"` Error string `json:"error"` @@ -131,6 +137,19 @@ func (s *Slack) SendAction(channel, message string) { s.SendMessageType(channel, "message", "me_message", "_"+message+"_") } +func (s *Slack) React(channel, reaction string, message msg.Message) { + log.Printf("Reacting in %s: %s", channel, reaction) + resp, err := http.PostForm("https://slack.com/api/reactions.add", + url.Values{ "token": {s.config.Slack.Token}, + "name": {reaction}, + "channel": {channel}, + "timestamp": {message.AdditionalData["RAW_SLACK_TIMESTAMP"]}}) + if err != nil { + log.Printf("Error sending Slack reaction: %s", err) + } + log.Print(resp) +} + func (s *Slack) receiveMessage() (slackMessage, error) { var msg []byte m := slackMessage{} @@ -212,6 +231,9 @@ func (s *Slack) buildMessage(m slackMessage) msg.Message { Action: isAction, Host: string(m.Id), Time: tstamp, + AdditionalData: map[string]string{ + "RAW_SLACK_TIMESTAMP": m.Ts, + }, } } From d5bc4d8f45880fcc38cb80f8a0c542de5634a0ac Mon Sep 17 00:00:00 2001 From: cws Date: Mon, 24 Jul 2017 07:37:10 -0400 Subject: [PATCH 2/3] bot: add missing mock func to fix tests skiesel forgot. --- bot/mock.go | 1 + 1 file changed, 1 insertion(+) diff --git a/bot/mock.go b/bot/mock.go index 193c5ee..89a1bfc 100644 --- a/bot/mock.go +++ b/bot/mock.go @@ -38,6 +38,7 @@ func (mb *MockBot) EventReceived(msg msg.Message) {} func (mb *MockBot) Filter(msg msg.Message, s string) string { return "" } 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(string, string, msg.Message) {} func NewMockBot() *MockBot { db, err := sqlx.Open("sqlite3_custom", ":memory:") From 148f9635a0943358dbafc898725114578367adad Mon Sep 17 00:00:00 2001 From: cws Date: Mon, 24 Jul 2017 07:37:33 -0400 Subject: [PATCH 3/3] counter: Change regex to be more accepting Fixes #66 --- plugins/counter/counter.go | 2 +- plugins/counter/counter_test.go | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/plugins/counter/counter.go b/plugins/counter/counter.go index cac69d0..ebe51b0 100644 --- a/plugins/counter/counter.go +++ b/plugins/counter/counter.go @@ -136,7 +136,7 @@ func (p *CounterPlugin) Message(message msg.Message) bool { return false } - if tea, _ := regexp.MatchString("(?i)^tea\\. [0-9A-Za-z_ ]*\\. ((hot)|(iced))\\.?$", message.Body); tea { + if tea, _ := regexp.MatchString("(?i)^tea\\. [^.]*\\. ((hot)|(iced))\\.?$", message.Body); tea { item, err := GetItem(p.DB, nick, ":tea:") if err != nil { log.Printf("Error finding item %s.%s: %s.", nick, ":tea:", err) diff --git a/plugins/counter/counter_test.go b/plugins/counter/counter_test.go index b0b233a..868de7b 100644 --- a/plugins/counter/counter_test.go +++ b/plugins/counter/counter_test.go @@ -69,6 +69,15 @@ func TestTeaSkieselQuote(t *testing.T) { assert.Nil(t, err) assert.Equal(t, 0, item.Count) } +func TestTeaUnicodeJapanese(t *testing.T) { + mb := bot.NewMockBot() + c := New(mb) + assert.NotNil(t, c) + c.Message(makeMessage("Tea. おちや. Hot.")) + item, err := GetItem(mb.DB(), "tester", ":tea:") + assert.Nil(t, err) + assert.Equal(t, 1, item.Count) +} func TestResetMe(t *testing.T) { mb := bot.NewMockBot()