bot: hook connectors up to events

This includes a full test of `admin`
This commit is contained in:
Chris Sexton 2019-02-05 13:33:18 -05:00
parent d85c855d47
commit 82dcf410f2
11 changed files with 149 additions and 199 deletions

View File

@ -83,9 +83,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
}
@ -249,10 +247,14 @@ func (b *bot) RegisterFilter(name string, f func(string) string) {
b.filters[name] = f
}
// Send a message to the connection
func (b *bot) Send(kind Kind, args ...interface{}) (error, string) { return nil, "" }
// Register a callback
func (b *bot) Register(name string, kind Kind, cb Callback) {
name = strings.ToLower(name)
if _, ok := b.callbacks[name]; !ok {
b.callbacks[name] = make(map[Kind][]Callback)
}
if _, ok := b.callbacks[name][kind]; !ok {
b.callbacks[name][kind] = []Callback{}
}
b.callbacks[name][kind] = append(b.callbacks[name][kind], cb)
}

View File

@ -17,23 +17,18 @@ import (
)
func (b *bot) Receive(kind Kind, msg msg.Message, args ...interface{}) {
panic("I don't know what to do here yet")
}
// Handles incomming PRIVMSG requests
func (b *bot) MsgReceived(msg msg.Message) {
log.Println("Received message: ", msg)
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 {
if b.runCallback(name, Message, msg) {
if b.runCallback(name, kind, msg, args) {
goto RET
}
}
@ -43,59 +38,18 @@ 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 {
if b.runCallback(name, Event, msg) {
return
}
}
}
func (b *bot) runCallback(plugin string, evt Kind, message msg.Message, args ...interface{}) bool {
for _, cb := range b.callbacks[plugin][evt] {
if cb(evt, message) {
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 {
if b.runCallback(name, Reply, msg, identifier) {
break
}
}
}
func (b *bot) SendMessage(channel, message string) (error, string) {
return b.conn.Send(Message, channel, message)
}
func (b *bot) SendAction(channel, message string) (error, string) {
return b.conn.Send(Action, channel, message)
}
func (b *bot) ReplyToMessageIdentifier(channel, message, identifier string) (error, string) {
return b.conn.Send(Reply, channel, message, identifier)
}
func (b *bot) ReplyToMessage(channel, message string, replyTo msg.Message) (error, string) {
return b.conn.Send(Reply, channel, message, replyTo)
}
func (b *bot) React(channel, reaction string, message msg.Message) (error, string) {
return b.conn.Send(Reaction, channel, reaction, message)
}
func (b *bot) Edit(channel, newMessage, identifier string) (error, string) {
return b.conn.Send(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 {
@ -110,7 +64,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" {
@ -127,7 +81,7 @@ func (b *bot) checkHelp(channel string, parts []string) {
b.runCallback(parts[1], 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)
}
}
}
@ -223,14 +177,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

View File

@ -45,7 +45,7 @@ type Bot interface {
// AddPlugin registers a new plugin handler
AddPlugin(string, Plugin)
// First arg should be one of bot.Message/Reply/Action/etc
Send(Kind, ...interface{}) (error, string)
Send(Kind, ...interface{}) (string, error)
// First arg should be one of bot.Message/Reply/Action/etc
Receive(Kind, msg.Message, ...interface{})
// Register a callback
@ -61,11 +61,9 @@ type Bot interface {
// 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{}) (error, string)
Send(Kind, ...interface{}) (string, error)
GetEmojiList() map[string]string
Serve() error

View File

@ -29,14 +29,14 @@ type MockBot struct {
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{}) (error, string) {
func (mb *MockBot) Send(kind Kind, args ...interface{}) (string, error) {
switch kind {
case Message:
mb.Messages = append(mb.Messages, args[1].(string))
return nil, fmt.Sprintf("m-%d", len(mb.Actions)-1)
return fmt.Sprintf("m-%d", len(mb.Actions)-1), nil
case Action:
mb.Actions = append(mb.Actions, args[1].(string))
return nil, fmt.Sprintf("a-%d", len(mb.Actions)-1)
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)
@ -44,7 +44,7 @@ func (mb *MockBot) Send(kind Kind, args ...interface{}) (error, string) {
ch, re, msg := args[0].(string), args[1].(string), args[2].(msg.Message)
return mb.react(ch, re, msg)
}
return fmt.Errorf("Mesasge type unhandled"), "ERROR"
return "ERR", fmt.Errorf("Mesasge type unhandled")
}
func (mb *MockBot) AddPlugin(name string, f Plugin) {}
func (mb *MockBot) Register(name string, kind Kind, cb Callback) {}
@ -53,40 +53,40 @@ func (mb *MockBot) Filter(msg msg.Message, s string) string { re
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) (error, string) {
func (mb *MockBot) react(channel, reaction string, message msg.Message) (string, error) {
mb.Reactions = append(mb.Reactions, reaction)
return nil, ""
return "", nil
}
func (mb *MockBot) edit(channel, newMessage, identifier string) (error, string) {
func (mb *MockBot) edit(channel, newMessage, identifier string) (string, error) {
isMessage := identifier[0] == 'm'
if !isMessage && identifier[0] != 'a' {
err := fmt.Errorf("failed to parse identifier: %s", identifier)
log.Println(err)
return err, ""
return "", err
}
index, err := strconv.Atoi(strings.Split(identifier, "-")[1])
if err != nil {
err := fmt.Errorf("failed to parse identifier: %s", identifier)
log.Println(err)
return err, ""
return "", err
}
if isMessage {
if index < len(mb.Messages) {
mb.Messages[index] = newMessage
} else {
return fmt.Errorf("No message"), ""
return "", fmt.Errorf("No message")
}
} else {
if index < len(mb.Actions) {
mb.Actions[index] = newMessage
} else {
return fmt.Errorf("No action"), ""
return "", fmt.Errorf("No action")
}
}
return nil, ""
return "", nil
}
func (mb *MockBot) GetEmojiList() map[string]string { return make(map[string]string) }

View File

@ -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,19 +52,11 @@ 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{}) (error, string) {
func (i *Irc) Send(kind bot.Kind, args ...interface{}) (string, error) {
switch kind {
case bot.Reply:
case bot.Message:
@ -75,7 +65,7 @@ func (i *Irc) Send(kind bot.Kind, args ...interface{}) (error, string) {
return i.sendAction(args[0].(string), args[1].(string))
default:
}
return nil, ""
return "", nil
}
func (i *Irc) JoinChannel(channel string) {
@ -83,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) (error, string) {
func (i *Irc) sendMessage(channel, message string) (string, error) {
for len(message) > 0 {
m := irc.Msg{
Cmd: "PRIVMSG",
@ -107,11 +97,11 @@ func (i *Irc) sendMessage(channel, message string) (error, string) {
i.Client.Out <- m
}
return nil, "NO_IRC_IDENTIFIERS"
return "NO_IRC_IDENTIFIERS", nil
}
// Sends action to channel
func (i *Irc) sendAction(channel, message string) (error, string) {
func (i *Irc) sendAction(channel, message string) (string, error) {
message = actionPrefix + " " + message + "\x01"
return i.sendMessage(channel, message)
@ -123,7 +113,7 @@ func (i *Irc) GetEmojiList() 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")
}
@ -202,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)

View File

@ -35,6 +35,7 @@ import (
"github.com/velour/catbase/plugins/twitch"
"github.com/velour/catbase/plugins/your"
"github.com/velour/catbase/plugins/zork"
"github.com/velour/catbase/slack"
)
var (
@ -70,7 +71,7 @@ func main() {
case "irc":
client = irc.New(c)
case "slack":
//client = slack.New(c)
client = slack.New(c)
default:
log.Fatalf("Unknown connection type: %s", c.Get("type", "UNSET"))
}

View File

@ -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("admin", bot.Message, p.message)
b.Register("admin", 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 {
@ -143,23 +145,12 @@ func (p *AdminPlugin) handleVariables(message msg.Message) bool {
}
// Help responds to help requests. Every plugin must implement a help function.
func (p *AdminPlugin) Help(channel string, parts []string) {
p.Bot.Send(bot.Message, 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 }

View File

@ -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: <unknown>"
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)
}

View File

@ -107,7 +107,7 @@ func New(b bot.Bot) *RPGPlugin {
func (p *RPGPlugin) Message(message msg.Message) bool {
if strings.ToLower(message.Body) == "start rpg" {
b := NewRandomBoard()
_, ts := p.Bot.Send(bot.Message, message.Channel, b.toMessageString())
ts, _ := p.Bot.Send(bot.Message, message.Channel, b.toMessageString())
p.listenFor[ts] = b
p.Bot.Send(bot.Reply, message.Channel, "Over here.", ts)
return true

View File

@ -47,7 +47,7 @@ func NewRandomGame(b bot.Bot, channel, who string) *game {
size: size,
current: size / 2,
}
_, g.id = b.Send(bot.Message, channel, g.toMessageString())
g.id, _ = b.Send(bot.Message, channel, g.toMessageString())
g.schedulePush()
g.scheduleDecrement()

View File

@ -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)
}