diff --git a/bot/handlers.go b/bot/handlers.go index 18bb052..730f076 100644 --- a/bot/handlers.go +++ b/bot/handlers.go @@ -65,6 +65,10 @@ func (b *bot) React(channel, reaction string, message msg.Message) { b.conn.React(channel, reaction, message) } +func (b *bot) GetEmojiList() map[string]string { + return b.conn.GetEmojiList() +} + // 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 b1c74f6..e80fdb1 100644 --- a/bot/interfaces.go +++ b/bot/interfaces.go @@ -23,6 +23,7 @@ type Bot interface { Filter(msg.Message, string) string LastMessage(string) (msg.Message, error) CheckAdmin(string) bool + GetEmojiList() map[string]string } type Connector interface { @@ -32,6 +33,7 @@ type Connector interface { SendMessage(channel, message string) SendAction(channel, message string) React(string, string, msg.Message) + GetEmojiList() map[string]string Serve() Who(string) []string diff --git a/irc/irc.go b/irc/irc.go index 42775a1..3df0015 100644 --- a/irc/irc.go +++ b/irc/irc.go @@ -102,6 +102,11 @@ func (i *Irc) React(channel, reaction string, message msg.Message) { //we're not goign to do anything because it's IRC } +func (i *Irc) GetEmojiList() map[string]string { + //we're not goign to do anything because it's IRC + return make(map[string]string) +} + 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 d2e87d9..6ba3cca 100644 --- a/main.go +++ b/main.go @@ -14,6 +14,7 @@ import ( "github.com/velour/catbase/plugins/beers" "github.com/velour/catbase/plugins/counter" "github.com/velour/catbase/plugins/dice" + "github.com/velour/catbase/plugins/emojifyme" "github.com/velour/catbase/plugins/fact" "github.com/velour/catbase/plugins/leftpad" "github.com/velour/catbase/plugins/reaction" @@ -62,6 +63,7 @@ func main() { b.AddHandler("zork", zork.New(b)) b.AddHandler("rss", rss.New(b)) b.AddHandler("reaction", reaction.New(b)) + b.AddHandler("emojifyme", emojifyme.New(b)) // catches anything left, will always return true b.AddHandler("factoid", fact.New(b)) diff --git a/plugins/emojifyme/emojifyme.go b/plugins/emojifyme/emojifyme.go new file mode 100644 index 0000000..2d02f75 --- /dev/null +++ b/plugins/emojifyme/emojifyme.go @@ -0,0 +1,102 @@ +// © 2013 the CatBase Authors under the WTFPL. See AUTHORS for the list of authors. + +package emojifyme + +import ( + "encoding/json" + "io/ioutil" + "log" + "math/rand" + "net/http" + "strings" + "time" + + "github.com/velour/catbase/bot" + "github.com/velour/catbase/bot/msg" +) + +type EmojifyMePlugin struct { + Bot bot.Bot + GotBotEmoji bool + Emoji map[string]string +} + +func New(bot bot.Bot) *EmojifyMePlugin { + rand.Seed(time.Now().Unix()) + + 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) + } + body, err := ioutil.ReadAll(resp.Body) + resp.Body.Close() + if err != nil { + log.Fatalf("Error generic emoji list body: %s", err) + } + + type Emoji struct { + Aliases []string `json:aliases` + } + + var emoji []Emoji + err = json.Unmarshal(body, &emoji) + if err != nil { + log.Fatalf("Error parsing emoji list: %s", err) + } + + emojiMap := map[string]string{} + for _, e := range emoji { + for _, alias := range e.Aliases { + emojiMap[alias] = alias + } + } + + return &EmojifyMePlugin{ + Bot: bot, + GotBotEmoji: false, + Emoji: emojiMap, + } +} + +func (p *EmojifyMePlugin) Message(message msg.Message) bool { + if !p.GotBotEmoji { + p.GotBotEmoji = true + emojiMap := p.Bot.GetEmojiList() + for e := range emojiMap { + p.Emoji[e] = e + } + } + + if rand.Intn(10) == 0 { + tokens := strings.Fields(strings.ToLower(message.Body)) + sendMessage := false + for i, token := range tokens { + if _, ok := p.Emoji[token]; ok { + sendMessage = true + tokens[i] = ":" + token + ":" + } + } + if sendMessage { + modified := strings.Join(tokens, " ") + p.Bot.SendMessage(message.Channel, modified) + return true + } + } + 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 +} diff --git a/slack/slack.go b/slack/slack.go index 93ca185..abd3a8e 100644 --- a/slack/slack.go +++ b/slack/slack.go @@ -34,6 +34,8 @@ type Slack struct { users map[string]string + emoji map[string]string + eventReceived func(msg.Message) messageReceived func(msg.Message) } @@ -100,7 +102,8 @@ type rtmStart struct { func New(c *config.Config) *Slack { return &Slack{ config: c, - users: make(map[string]string), + users: make(map[string]string), + emoji: make(map[string]string), } } @@ -150,6 +153,37 @@ func (s *Slack) React(channel, reaction string, message msg.Message) { log.Print(resp) } +func (s *Slack) GetEmojiList() map[string]string { + return s.emoji +} + +func (s *Slack) populateEmojiList() { + resp, err := http.PostForm("https://slack.com/api/emoji.list", + url.Values{ "token": {s.config.Slack.Token}}) + if err != nil { + log.Printf("Error retrieving emoji list from Slack: %s", err) + return + } + + body, err := ioutil.ReadAll(resp.Body) + resp.Body.Close() + if err != nil { + log.Fatalf("Error reading Slack API body: %s", err) + } + + type EmojiListResponse struct { + OK bool `json:ok` + Emoji map[string]string `json:emoji` + } + + var list EmojiListResponse + err = json.Unmarshal(body, &list) + if err != nil { + log.Fatalf("Error parsing emoji list: %s", err) + } + s.emoji = list.Emoji +} + func (s *Slack) receiveMessage() (slackMessage, error) { var msg []byte m := slackMessage{} @@ -166,6 +200,7 @@ func (s *Slack) receiveMessage() (slackMessage, error) { func (s *Slack) Serve() { s.connect() + s.populateEmojiList() for { msg, err := s.receiveMessage() if err != nil && err == io.EOF {