diff --git a/bot/handlers.go b/bot/handlers.go index bb4c340..81e9154 100644 --- a/bot/handlers.go +++ b/bot/handlers.go @@ -63,6 +63,10 @@ func (b *bot) SendAction(channel, message string) string { return b.conn.SendAction(channel, message) } +func (b *bot) ReplyToMessage(channel, message, identifier string) (string, bool) { + return b.conn.ReplyToMessage(channel, message, identifier) +} + func (b *bot) React(channel, reaction string, message msg.Message) bool { return b.conn.React(channel, reaction, message) } diff --git a/bot/interfaces.go b/bot/interfaces.go index 2fc783d..d1e374a 100644 --- a/bot/interfaces.go +++ b/bot/interfaces.go @@ -17,6 +17,7 @@ type Bot interface { AddHandler(string, Handler) SendMessage(string, string) string SendAction(string, string) string + ReplyToMessage(channel, message, identifier string) (string, bool) React(string, string, msg.Message) bool Edit(string, string, string) bool MsgReceived(msg.Message) @@ -34,6 +35,7 @@ type Connector interface { SendMessage(channel, message string) string SendAction(channel, message string) string + ReplyToMessage(channel, message, identifier string) (string, bool) React(string, string, msg.Message) bool Edit(string, string, string) bool GetEmojiList() map[string]string diff --git a/bot/mock.go b/bot/mock.go index 1e51bb9..fdb5178 100644 --- a/bot/mock.go +++ b/bot/mock.go @@ -39,6 +39,7 @@ 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) ReplyToMessage(channel, message, identifier string) (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 "" } diff --git a/irc/irc.go b/irc/irc.go index 65de1a7..4d7b3bf 100644 --- a/irc/irc.go +++ b/irc/irc.go @@ -101,6 +101,10 @@ func (i *Irc) SendAction(channel, message string) string { return "NO_IRC_IDENTIFIERS" } +func (i *Irc) ReplyToMessage(channel, message, identifier string) (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 diff --git a/plugins/rpgORdie/rpgORdie.go b/plugins/rpgORdie/rpgORdie.go index 17418c8..5c5b619 100644 --- a/plugins/rpgORdie/rpgORdie.go +++ b/plugins/rpgORdie/rpgORdie.go @@ -32,6 +32,8 @@ func (p *RPGPlugin) Message(message msg.Message) bool { time.Sleep(2 * time.Second) } p.Bot.Edit(message.Channel, "HECK YES", ts) + + p.Bot.ReplyToMessage(message.Channel, "How's this reply?", ts) } return false } diff --git a/slack/slack.go b/slack/slack.go index 9808e2c..29e5ef9 100644 --- a/slack/slack.go +++ b/slack/slack.go @@ -5,6 +5,7 @@ package slack import ( "encoding/json" + "errors" "fmt" "html" "io" @@ -192,15 +193,20 @@ func (s *Slack) RegisterMessageReceived(f func(msg.Message)) { s.messageReceived = f } -func (s *Slack) SendMessageType(channel, messageType, subType, message string) (string, error) { - resp, err := http.PostForm("https://slack.com/api/chat.postMessage", +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" + } + + resp, err := http.PostForm(postUrl, url.Values{"token": {s.config.Slack.Token}, "channel": {channel}, "text": {message}, }) if err != nil { - log.Printf("Error sending Slack reaction: %s", err) + log.Printf("Error sending Slack message: %s", err) } body, err := ioutil.ReadAll(resp.Body) @@ -213,7 +219,6 @@ func (s *Slack) SendMessageType(channel, messageType, subType, message string) ( type MessageResponse struct { OK bool `json:"ok"` - Channel string `json:"channel"` Timestamp string `json:"ts"` } @@ -223,21 +228,66 @@ func (s *Slack) SendMessageType(channel, messageType, subType, message string) ( log.Fatalf("Error parsing message response: %s", err) } + if !mr.OK { + return "", errors.New("failure response received") + } + return mr.Timestamp, err } func (s *Slack) SendMessage(channel, message string) string { log.Printf("Sending message to %s: %s", channel, message) - identifier, _ := s.SendMessageType(channel, "message", "", message) + identifier, _ := s.SendMessageType(channel, message, false) return identifier } func (s *Slack) SendAction(channel, message string) string { log.Printf("Sending action to %s: %s", channel, message) - identifier, _ := s.SendMessageType(channel, "message", "me_message", "_"+message+"_") + identifier, _ := s.SendMessageType(channel, "_"+message+"_", true) return identifier } +func (s *Slack) ReplyToMessage(channel, message, identifier string) (string, bool) { + resp, err := http.PostForm("https://slack.com/api/chat.postMessage", + url.Values{"token": {s.config.Slack.Token}, + "channel": {channel}, + "text": {message}, + "thread_ts": {identifier}, + }) + + if err != nil { + log.Printf("Error sending Slack reply: %s", err) + return "", false + } + + body, err := ioutil.ReadAll(resp.Body) + resp.Body.Close() + if err != nil { + log.Printf("Error reading Slack API body: %s", err) + return "", false + } + + log.Println(string(body)) + + type MessageResponse struct { + OK bool `json:"ok"` + Timestamp string `json:"ts"` + } + + var mr MessageResponse + err = json.Unmarshal(body, &mr) + if err != nil { + log.Printf("Error parsing message response: %s", err) + return "", false + } + + if !mr.OK { + return "", false + } + + return mr.Timestamp, err == nil +} + func (s *Slack) React(channel, reaction string, message msg.Message) bool { log.Printf("Reacting in %s: %s", channel, reaction) resp, err := http.PostForm("https://slack.com/api/reactions.add",