diff --git a/bot/bot.go b/bot/bot.go index 491704a..5eb0181 100644 --- a/bot/bot.go +++ b/bot/bot.go @@ -105,10 +105,14 @@ func New(config *config.Config, connector Connector) Bot { return bot } +// DefaultConnector is the main connector used for the bot +// If more than one connector is on, some users may not see all messages if this is used. +// Usage should be limited to out-of-band communications such as timed messages. func (b *bot) DefaultConnector() Connector { return b.conn } +// WhoAmI returns the bot's current registered name func (b *bot) WhoAmI() string { return b.me.Name } @@ -149,6 +153,8 @@ func (b *bot) AddPlugin(h Plugin) { b.pluginOrdering = append(b.pluginOrdering, name) } +// Who returns users for a channel the bot is in +// Check the particular connector for channel values func (b *bot) Who(channel string) []user.User { names := b.conn.Who(channel) users := []user.User{} @@ -263,6 +269,8 @@ func (b *bot) RegisterWeb(root, name string) { b.httpEndPoints = append(b.httpEndPoints, EndPoint{name, root}) } +// GetPassword returns a random password generated for the bot +// Passwords expire in 24h and are used for the web interface func (b *bot) GetPassword() string { if b.passwordCreated.Before(time.Now().Add(-24 * time.Hour)) { adjs := b.config.GetArray("bot.passwordAdjectives", []string{"very"}) @@ -275,10 +283,12 @@ func (b *bot) GetPassword() string { return b.password } +// SetQuiet is called to silence the bot from sending channel messages func (b *bot) SetQuiet(status bool) { b.quiet = status } +// RefreshPluginBlacklist loads data for which plugins are disabled for particular channels func (b *bot) RefreshPluginBlacklist() error { blacklistItems := []struct { Channel string @@ -295,6 +305,7 @@ func (b *bot) RefreshPluginBlacklist() error { return nil } +// GetPluginNames returns an ordered list of plugins loaded (used for blacklisting) func (b *bot) GetPluginNames() []string { names := []string{} for _, name := range b.pluginOrdering { diff --git a/bot/interfaces.go b/bot/interfaces.go index 1a7d629..8e38a81 100644 --- a/bot/interfaces.go +++ b/bot/interfaces.go @@ -44,50 +44,92 @@ type CallbackMap map[string]map[Kind][]Callback type Bot interface { // Config allows access to the bot's configuration system Config() *config.Config + // DB gives access to the current database DB() *sqlx.DB + // Who lists users in a particular channel + // The channel should be represented as an ID for slack (check the connector for details) Who(string) []user.User + // WhoAmI gives a nick for the bot WhoAmI() string + // AddPlugin registers a new plugin handler AddPlugin(Plugin) - // First arg should be one of bot.Message/Reply/Action/etc + + // Send transmits a message to a Connector. + // Kind is listed in the bot's enum, one of bot.Message/Reply/Action/etc + // Usually, the first vararg should be a channel ID, but refer to the Connector for info Send(Connector, Kind, ...interface{}) (string, error) - // First arg should be one of bot.Message/Reply/Action/etc + + // Bot receives from a Connector. + // The Kind arg should be one of bot.Message/Reply/Action/etc Receive(Connector, Kind, msg.Message, ...interface{}) bool - // Register a callback + + // Register a plugin callback + // Kind will be matched to the event for the callback Register(Plugin, Kind, Callback) + // Filter prepares a message to be sent + // This loads the message with things like $variables Filter(msg.Message, string) string + + // LastMessage returns the last message the bot has seen LastMessage(string) (msg.Message, error) + // CheckAdmin returns a user's admin status CheckAdmin(string) bool + + // GetEmojiList returns known emoji GetEmojiList() map[string]string + + // RegisterFilter creates a filter function for message processing RegisterFilter(string, func(string) string) + + // RegisterWeb records a web endpoint for the UI RegisterWeb(string, string) + + // DefaultConnector returns the base connector, which may not be the only connector DefaultConnector() Connector + + // GetWebNavigation returns the current known web endpoints GetWebNavigation() []EndPoint + + // GetPassword generates a unique password for modification commands on the public website GetPassword() string + + // SetQuiet toggles the bot's ability to send messages SetQuiet(bool) + + // GetPluginNames returns an ordered list of registered plugins GetPluginNames() []string + + // RefreshPluginBlacklist reloads the list of plugins disabled per room from the DB RefreshPluginBlacklist() error } // Connector represents a server connection to a chat service type Connector interface { + // RegisterEvent creates a callback to watch Connector events RegisterEvent(Callback) + // Send transmits a message on the connector Send(Kind, ...interface{}) (string, error) + // GetEmojiList returns a connector's known custom emoji GetEmojiList() map[string]string + + // Serve starts a connector's connection routine Serve() error + // Who returns a user list for a channel Who(string) []string + + // Profile returns a user's information given an ID Profile(string) (user.User, error) } // Plugin interface used for compatibility with the Plugin interface // Uhh it turned empty, but we're still using it to ID plugins -type Plugin interface { -} +type Plugin interface{} diff --git a/plugins/beers/beers.go b/plugins/beers/beers.go index f221659..d9b561f 100644 --- a/plugins/beers/beers.go +++ b/plugins/beers/beers.go @@ -442,23 +442,8 @@ func (p *BeersPlugin) sendCheckin(c bot.Connector, channel string, user untappdU log.Debug(). Msgf("user.chanNick: %s, user.untappdUser: %s, checkin.User.User_name: %s", user.chanNick, user.untappdUser, checkin.User.User_name) - p.addBeers(user.chanNick, 1) - drunken := p.getBeers(user.chanNick) - msg := fmt.Sprintf("%s just drank %s by %s%s, bringing his drunkeness to %d", - user.chanNick, beerName, breweryName, venue, drunken) - if checkin.Rating_score > 0 { - msg = fmt.Sprintf("%s. Rating: %.2f", msg, checkin.Rating_score) - } - if checkin.Checkin_comment != "" { - msg = fmt.Sprintf("%s -- %s", - msg, checkin.Checkin_comment) - } - - args := []interface{}{ - channel, - msg, - } + args := []interface{}{} if checkin.Badges.Count > 0 { for _, b := range checkin.Badges.Items { args = append(args, bot.ImageAttachment{ @@ -486,6 +471,22 @@ func (p *BeersPlugin) sendCheckin(c bot.Connector, channel string, user untappdU delete(p.untapdCache, checkin.Checkin_id) } + // Don't add beers till after a photo has been detected (or failed once) + p.addBeers(user.chanNick, 1) + drunken := p.getBeers(user.chanNick) + + msg := fmt.Sprintf("%s just drank %s by %s%s, bringing his drunkeness to %d", + user.chanNick, beerName, breweryName, venue, drunken) + if checkin.Rating_score > 0 { + msg = fmt.Sprintf("%s. Rating: %.2f", msg, checkin.Rating_score) + } + if checkin.Checkin_comment != "" { + msg = fmt.Sprintf("%s -- %s", + msg, checkin.Checkin_comment) + } + + args = append([]interface{}{channel, msg}, args...) + user.lastCheckin = checkin.Checkin_id _, err := p.db.Exec(`update untappd set lastCheckin = ?