// © 2013 the CatBase Authors under the WTFPL. See AUTHORS for the list of authors. package fact import ( "fmt" "log" "strings" "time" "github.com/jmoiron/sqlx" "github.com/velour/catbase/bot" "github.com/velour/catbase/bot/msg" ) // This is a skeleton plugin to serve as an example and quick copy/paste for new // plugins. type RememberPlugin struct { Bot bot.Bot Log map[string][]msg.Message db *sqlx.DB } // NewRememberPlugin creates a new RememberPlugin with the Plugin interface func NewRemember(b bot.Bot) *RememberPlugin { p := RememberPlugin{ Bot: b, Log: make(map[string][]msg.Message), db: b.DB(), } b.Register(p, bot.Message, p.message) b.Register(p, bot.Message, p.help) return &p } // 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 *RememberPlugin) message(kind bot.Kind, message msg.Message, args ...interface{}) bool { if strings.ToLower(message.Body) == "quote" && message.Command { q := p.randQuote() p.Bot.Send(bot.Message, message.Channel, q) // is it evil not to remember that the user said quote? return true } user := message.User parts := strings.Fields(message.Body) if message.Command && len(parts) >= 3 && strings.ToLower(parts[0]) == "remember" { // we have a remember! // look through the logs and find parts[1] as a user, if not, // fuck this hoser nick := parts[1] snip := strings.Join(parts[2:], " ") for i := len(p.Log[message.Channel]) - 1; i >= 0; i-- { entry := p.Log[message.Channel][i] log.Printf("Comparing %s:%s with %s:%s", entry.User.Name, entry.Body, nick, snip) if strings.ToLower(entry.User.Name) == strings.ToLower(nick) && strings.Contains( strings.ToLower(entry.Body), strings.ToLower(snip), ) { log.Printf("Found!") var msg string if entry.Action { msg = fmt.Sprintf("*%s* %s", entry.User.Name, entry.Body) } else { msg = fmt.Sprintf("<%s> %s", entry.User.Name, entry.Body) } trigger := fmt.Sprintf("%s quotes", entry.User.Name) fact := factoid{ Fact: strings.ToLower(trigger), Verb: "reply", Tidbit: msg, Owner: user.Name, created: time.Now(), accessed: time.Now(), Count: 0, } if err := fact.save(p.db); err != nil { log.Println("ERROR!!!!:", err) p.Bot.Send(bot.Message, message.Channel, "Tell somebody I'm broke.") } log.Println("Remembering factoid:", msg) // sorry, not creative with names so we're reusing msg msg = fmt.Sprintf("Okay, %s, remembering '%s'.", message.User.Name, msg) p.Bot.Send(bot.Message, message.Channel, msg) p.recordMsg(message) return true } } p.Bot.Send(bot.Message, message.Channel, "Sorry, I don't know that phrase.") p.recordMsg(message) return true } p.recordMsg(message) return false } // Help responds to help requests. Every plugin must implement a help function. func (p *RememberPlugin) help(kind bot.Kind, message msg.Message, args ...interface{}) bool { msg := "!remember will let you quote your idiot friends. Just type " + "!remember to remember what they said. Snippet can " + "be any part of their message. Later on, you can ask for a random " + "!quote." p.Bot.Send(bot.Message, message.Channel, msg) return true } // deliver a random quote out of the db. // Note: this is the same cache for all channels joined. This plugin needs to be // expanded to have this function execute a quote for a particular channel func (p *RememberPlugin) randQuote() string { var f factoid var tmpCreated int64 var tmpAccessed int64 err := p.db.QueryRow(`select * from factoid where fact like '%quotes' order by random() limit 1;`).Scan( &f.id, &f.Fact, &f.Tidbit, &f.Verb, &f.Owner, &tmpCreated, &tmpAccessed, &f.Count, ) if err != nil { log.Println("Error getting quotes: ", err) return "I had a problem getting your quote." } f.created = time.Unix(tmpCreated, 0) f.accessed = time.Unix(tmpAccessed, 0) return f.Tidbit } func (p *RememberPlugin) recordMsg(message msg.Message) { log.Printf("Logging message: %s: %s", message.User.Name, message.Body) p.Log[message.Channel] = append(p.Log[message.Channel], message) }