This commit is contained in:
skkiesel 2017-10-31 09:40:03 -04:00
parent 34e2404e8b
commit d6c35b94ec
8 changed files with 113 additions and 95 deletions

View File

@ -110,10 +110,6 @@ func (b *bot) DB() *sqlx.DB {
return b.db return b.db
} }
func (b *bot) Conn() Connector {
return b.conn
}
// Create any tables if necessary based on version of DB // Create any tables if necessary based on version of DB
// Plugins should create their own tables, these are only for official bot stuff // Plugins should create their own tables, these are only for official bot stuff
// Note: This does not return an error. Database issues are all fatal at this stage. // Note: This does not return an error. Database issues are all fatal at this stage.

View File

@ -55,20 +55,20 @@ func (b *bot) EventReceived(msg msg.Message) {
} }
} }
func (b *bot) SendMessage(channel, message string) { func (b *bot) SendMessage(channel, message string) string {
b.conn.SendMessage(channel, message) return b.conn.SendMessage(channel, message)
} }
func (b *bot) SendAction(channel, message string) { func (b *bot) SendAction(channel, message string) string {
b.conn.SendAction(channel, message) return b.conn.SendAction(channel, message)
} }
func (b *bot) React(channel, reaction string, message msg.Message) { func (b *bot) React(channel, reaction string, message msg.Message) bool {
b.conn.React(channel, reaction, message) return b.conn.React(channel, reaction, message)
} }
func (b *bot) Edit(channel, newMessage, identifier string) { func (b *bot) Edit(channel, newMessage, identifier string) bool {
b.conn.Edit(channel, newMessage, identifier) return b.conn.Edit(channel, newMessage, identifier)
} }
func (b *bot) GetEmojiList() map[string]string { func (b *bot) GetEmojiList() map[string]string {

View File

@ -13,13 +13,12 @@ type Bot interface {
Config() *config.Config Config() *config.Config
DBVersion() int64 DBVersion() int64
DB() *sqlx.DB DB() *sqlx.DB
Conn() Connector
Who(string) []user.User Who(string) []user.User
AddHandler(string, Handler) AddHandler(string, Handler)
SendMessage(string, string) SendMessage(string, string) string
SendAction(string, string) SendAction(string, string) string
React(string, string, msg.Message) React(string, string, msg.Message) bool
Edit(string, string, string) Edit(string, string, string) bool
MsgReceived(msg.Message) MsgReceived(msg.Message)
EventReceived(msg.Message) EventReceived(msg.Message)
Filter(msg.Message, string) string Filter(msg.Message, string) string
@ -33,10 +32,10 @@ type Connector interface {
RegisterEventReceived(func(message msg.Message)) RegisterEventReceived(func(message msg.Message))
RegisterMessageReceived(func(message msg.Message)) RegisterMessageReceived(func(message msg.Message))
SendMessage(channel, message string) SendMessage(channel, message string) string
SendAction(channel, message string) SendAction(channel, message string) string
React(string, string, msg.Message) React(string, string, msg.Message) bool
Edit(string, string, string) Edit(string, string, string) bool
GetEmojiList() map[string]string GetEmojiList() map[string]string
Serve() error Serve() error

View File

@ -3,7 +3,10 @@
package bot package bot
import ( import (
"fmt"
"log" "log"
"strconv"
"strings"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
"github.com/stretchr/testify/mock" "github.com/stretchr/testify/mock"
@ -28,11 +31,13 @@ func (mb *MockBot) DB() *sqlx.DB { return mb.db }
func (mb *MockBot) Conn() Connector { return nil } func (mb *MockBot) Conn() Connector { return nil }
func (mb *MockBot) Who(string) []user.User { return []user.User{} } func (mb *MockBot) Who(string) []user.User { return []user.User{} }
func (mb *MockBot) AddHandler(name string, f Handler) {} func (mb *MockBot) AddHandler(name string, f Handler) {}
func (mb *MockBot) SendMessage(ch string, msg string) { func (mb *MockBot) SendMessage(ch string, msg string) string {
mb.Messages = append(mb.Messages, msg) mb.Messages = append(mb.Messages, msg)
return fmt.Sprintf("m-%d", len(mb.Actions)-1)
} }
func (mb *MockBot) SendAction(ch string, msg string) { func (mb *MockBot) SendAction(ch string, msg string) string {
mb.Actions = append(mb.Actions, msg) mb.Actions = append(mb.Actions, msg)
return fmt.Sprintf("a-%d", len(mb.Actions)-1)
} }
func (mb *MockBot) MsgReceived(msg msg.Message) {} func (mb *MockBot) MsgReceived(msg msg.Message) {}
func (mb *MockBot) EventReceived(msg msg.Message) {} func (mb *MockBot) EventReceived(msg msg.Message) {}
@ -40,8 +45,36 @@ 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) LastMessage(ch string) (msg.Message, error) { return msg.Message{}, nil }
func (mb *MockBot) CheckAdmin(nick string) bool { return false } func (mb *MockBot) CheckAdmin(nick string) bool { return false }
func (mb *MockBot) React(channel, reaction string, message msg.Message) {} func (mb *MockBot) React(channel, reaction string, message msg.Message) bool { return false }
func (mb *MockBot) Edit(channel, newMessage, identifier string) {}
func (mb *MockBot) Edit(channel, newMessage, identifier string) bool {
isMessage := identifier[0] == 'm'
if !isMessage && identifier[0] != 'a' {
log.Printf("failed to parse identifier: %s", identifier)
return false
}
index, err := strconv.Atoi(strings.Split(identifier, "-")[1])
if err != nil {
log.Printf("failed to parse identifier: %s", identifier)
return false
}
if isMessage {
if index < len(mb.Messages) {
mb.Messages[index] = newMessage
} else {
return false
}
} else {
if index < len(mb.Actions) {
mb.Actions[index] = newMessage
} else {
return false
}
}
return true
}
func (mb *MockBot) GetEmojiList() map[string]string { return make(map[string]string) } func (mb *MockBot) GetEmojiList() map[string]string { return make(map[string]string) }
func (mb *MockBot) RegisterFilter(s string, f func(string) string) {} func (mb *MockBot) RegisterFilter(s string, f func(string) string) {}

View File

@ -66,7 +66,7 @@ func (i *Irc) JoinChannel(channel string) {
i.Client.Out <- irc.Msg{Cmd: irc.JOIN, Args: []string{channel}} i.Client.Out <- irc.Msg{Cmd: irc.JOIN, Args: []string{channel}}
} }
func (i *Irc) SendMessage(channel, message string) { func (i *Irc) SendMessage(channel, message string) string {
for len(message) > 0 { for len(message) > 0 {
m := irc.Msg{ m := irc.Msg{
Cmd: "PRIVMSG", Cmd: "PRIVMSG",
@ -90,21 +90,25 @@ func (i *Irc) SendMessage(channel, message string) {
i.Client.Out <- m i.Client.Out <- m
} }
return "NO_IRC_IDENTIFIERS"
} }
// Sends action to channel // Sends action to channel
func (i *Irc) SendAction(channel, message string) { func (i *Irc) SendAction(channel, message string) string {
message = actionPrefix + " " + message + "\x01" message = actionPrefix + " " + message + "\x01"
i.SendMessage(channel, message) i.SendMessage(channel, message)
return "NO_IRC_IDENTIFIERS"
} }
func (i *Irc) React(channel, reaction string, message msg.Message) { func (i *Irc) React(channel, reaction string, message msg.Message) bool {
//we're not goign to do anything because it's IRC //we're not goign to do anything because it's IRC
return false
} }
func (i *Irc) Edit(channel, newMessage, identifier string) { func (i *Irc) Edit(channel, newMessage, identifier string) bool {
//we're not goign to do anything because it's IRC //we're not goign to do anything because it's IRC
return false
} }
func (i *Irc) GetEmojiList() map[string]string { func (i *Irc) GetEmojiList() map[string]string {

View File

@ -7,25 +7,21 @@ import (
"github.com/velour/catbase/bot" "github.com/velour/catbase/bot"
"github.com/velour/catbase/bot/msg" "github.com/velour/catbase/bot/msg"
"github.com/velour/catbase/slack"
) )
type RPGPlugin struct { type RPGPlugin struct {
Bot bot.Bot Bot bot.Bot
Slack *slack.Slack //nasty
} }
func New(b bot.Bot) *RPGPlugin { func New(b bot.Bot) *RPGPlugin {
return &RPGPlugin{ return &RPGPlugin{
Bot: b, Bot: b,
Slack: b.Conn().(*slack.Slack), //oh boy, this is just filthy
} }
} }
func (p *RPGPlugin) Message(message msg.Message) bool { func (p *RPGPlugin) Message(message msg.Message) bool {
if strings.ToLower(message.Body) == "start rpg" { if strings.ToLower(message.Body) == "start rpg" {
p.Bot.SendMessage(message.Channel, "I'll edit this.") ts := p.Bot.SendMessage(message.Channel, "I'll edit this.")
ts := p.Slack.GetLastMessageId()
time.Sleep(2 * time.Second) time.Sleep(2 * time.Second)

View File

@ -1,4 +1,3 @@
package rpgORdie package rpgORdie
import ( import ()
)

View File

@ -38,8 +38,6 @@ type Slack struct {
emoji map[string]string emoji map[string]string
lastMessageId string
eventReceived func(msg.Message) eventReceived func(msg.Message)
messageReceived func(msg.Message) messageReceived func(msg.Message)
} }
@ -162,10 +160,30 @@ func New(c *config.Config) *Slack {
lastRecieved: time.Now(), lastRecieved: time.Now(),
users: make(map[string]string), users: make(map[string]string),
emoji: make(map[string]string), emoji: make(map[string]string),
lastMessageId: "",
} }
} }
func checkReturnStatus(response *http.Response) bool {
type Response struct {
OK bool `json:"ok"`
}
body, err := ioutil.ReadAll(response.Body)
response.Body.Close()
if err != nil {
log.Printf("Error reading Slack API body: %s", err)
return false
}
var resp Response
err = json.Unmarshal(body, &resp)
if err != nil {
log.Printf("Error parsing message response: %s", err)
return false
}
return resp.OK
}
func (s *Slack) RegisterEventReceived(f func(msg.Message)) { func (s *Slack) RegisterEventReceived(f func(msg.Message)) {
s.eventReceived = f s.eventReceived = f
} }
@ -174,7 +192,7 @@ func (s *Slack) RegisterMessageReceived(f func(msg.Message)) {
s.messageReceived = f s.messageReceived = f
} }
func (s *Slack) SendMessageType(channel, messageType, subType, message string) error { func (s *Slack) SendMessageType(channel, messageType, subType, message string) (string, error) {
resp, err := http.PostForm("https://slack.com/api/chat.postMessage", resp, err := http.PostForm("https://slack.com/api/chat.postMessage",
url.Values{"token": {s.config.Slack.Token}, url.Values{"token": {s.config.Slack.Token},
"channel": {channel}, "channel": {channel},
@ -194,9 +212,9 @@ func (s *Slack) SendMessageType(channel, messageType, subType, message string) e
log.Println(string(body)) log.Println(string(body))
type MessageResponse struct { type MessageResponse struct {
OK bool `json:ok` OK bool `json:"ok"`
Channel string `json:channel` Channel string `json:"channel"`
Timestamp string `json:ts` Timestamp string `json:"ts"`
} }
var mr MessageResponse var mr MessageResponse
@ -212,24 +230,22 @@ func (s *Slack) SendMessageType(channel, messageType, subType, message string) e
mr.Timestamp = strings.Split(strings.Split(bodyAsString, "\"ts\":\"")[1], "\"")[0] mr.Timestamp = strings.Split(strings.Split(bodyAsString, "\"ts\":\"")[1], "\"")[0]
} }
s.lastMessageId = mr.Timestamp return mr.Timestamp, err
log.Println(mr)
return err
} }
func (s *Slack) SendMessage(channel, message string) { func (s *Slack) SendMessage(channel, message string) string {
log.Printf("Sending message to %s: %s", channel, message) log.Printf("Sending message to %s: %s", channel, message)
s.SendMessageType(channel, "message", "", message) identifier, _ := s.SendMessageType(channel, "message", "", message)
return identifier
} }
func (s *Slack) SendAction(channel, message string) { func (s *Slack) SendAction(channel, message string) string {
log.Printf("Sending action to %s: %s", channel, message) log.Printf("Sending action to %s: %s", channel, message)
s.SendMessageType(channel, "message", "me_message", "_"+message+"_") identifier, _ := s.SendMessageType(channel, "message", "me_message", "_"+message+"_")
return identifier
} }
func (s *Slack) React(channel, reaction string, message msg.Message) { func (s *Slack) React(channel, reaction string, message msg.Message) bool {
log.Printf("Reacting in %s: %s", channel, reaction) log.Printf("Reacting in %s: %s", channel, reaction)
resp, err := http.PostForm("https://slack.com/api/reactions.add", resp, err := http.PostForm("https://slack.com/api/reactions.add",
url.Values{"token": {s.config.Slack.Token}, url.Values{"token": {s.config.Slack.Token},
@ -237,33 +253,13 @@ func (s *Slack) React(channel, reaction string, message msg.Message) {
"channel": {channel}, "channel": {channel},
"timestamp": {message.AdditionalData["RAW_SLACK_TIMESTAMP"]}}) "timestamp": {message.AdditionalData["RAW_SLACK_TIMESTAMP"]}})
if err != nil { if err != nil {
log.Printf("Error sending Slack reaction: %s", err) log.Println("reaction failed: %s", err)
return false
} }
log.Print(resp) return checkReturnStatus(resp)
} }
func (s* Slack) GetLastMessageId() string { func (s *Slack) Edit(channel, newMessage, identifier string) bool {
return s.lastMessageId
}
func (s* Slack) PrintHistory(channel string, howMany int) {
resp, err := http.PostForm("https://slack.com/api/channels.history",
url.Values{"token": {s.config.Slack.Token},
"channel": {channel},
"count": {fmt.Sprintf("%d", howMany)}})
if err != nil {
log.Printf("Error getting slack history: %s", err)
}
body, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
log.Fatalf("Error reading Slack API body: %s", err)
}
log.Println(string(body))
}
func (s *Slack) Edit(channel, newMessage, identifier string) {
log.Printf("Editing in (%s) %s: %s", identifier, channel, newMessage) log.Printf("Editing in (%s) %s: %s", identifier, channel, newMessage)
resp, err := http.PostForm("https://slack.com/api/chat.update", resp, err := http.PostForm("https://slack.com/api/chat.update",
url.Values{"token": {s.config.Slack.Token}, url.Values{"token": {s.config.Slack.Token},
@ -271,15 +267,10 @@ func (s *Slack) Edit(channel, newMessage, identifier string) {
"text": {newMessage}, "text": {newMessage},
"ts": {identifier}}) "ts": {identifier}})
if err != nil { if err != nil {
log.Printf("Error sending Slack reaction: %s", err) log.Println("edit failed: %s", err)
return false
} }
body, err := ioutil.ReadAll(resp.Body) return checkReturnStatus(resp)
resp.Body.Close()
if err != nil {
log.Fatalf("Error reading Slack API body: %s", err)
}
log.Println(string(body))
} }
func (s *Slack) GetEmojiList() map[string]string { func (s *Slack) GetEmojiList() map[string]string {