Chatbot improvements
This commit is contained in:
parent
591775a34d
commit
af35ac9ed6
|
@ -12,8 +12,17 @@ import (
|
||||||
"github.com/aichaos/rivescript-go"
|
"github.com/aichaos/rivescript-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Number of recent chat messages to hold onto.
|
const (
|
||||||
const ScrollbackBuffer = 500
|
// Number of recent chat messages to hold onto.
|
||||||
|
ScrollbackBuffer = 500
|
||||||
|
|
||||||
|
// How long for the lobby room to be quiet before you'll greet the
|
||||||
|
// next person who joins the room.
|
||||||
|
LobbyDeadThreshold = 30 * time.Minute
|
||||||
|
|
||||||
|
// Default (lobby) channel.
|
||||||
|
LobbyChannel = "lobby"
|
||||||
|
)
|
||||||
|
|
||||||
// BotHandlers holds onto a set of handler functions for the BareBot.
|
// BotHandlers holds onto a set of handler functions for the BareBot.
|
||||||
type BotHandlers struct {
|
type BotHandlers struct {
|
||||||
|
@ -34,6 +43,17 @@ type BotHandlers struct {
|
||||||
// happen immediately, if it does).
|
// happen immediately, if it does).
|
||||||
messageBuf []messages.Message
|
messageBuf []messages.Message
|
||||||
messageBufMu sync.RWMutex
|
messageBufMu sync.RWMutex
|
||||||
|
|
||||||
|
// Main (lobby) channel quiet detector. Record the time of the last
|
||||||
|
// message seen: if the lobby has been quiet for a long time, and
|
||||||
|
// someone new joins the room, greet them - overriding the global
|
||||||
|
// autoGreet cooldown or ignoring the number of chatters in the room.
|
||||||
|
lobbyChannelLastUpdated time.Time
|
||||||
|
|
||||||
|
// Store the reactions we have previously sent by messageID,
|
||||||
|
// so we don't accidentally take back our own reactions.
|
||||||
|
reactions map[int]map[string]interface{}
|
||||||
|
reactionsMu sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetupChatbot configures a sensible set of default handlers for the BareBot application.
|
// SetupChatbot configures a sensible set of default handlers for the BareBot application.
|
||||||
|
@ -49,6 +69,7 @@ func (c *Client) SetupChatbot() error {
|
||||||
}),
|
}),
|
||||||
autoGreet: map[string]time.Time{},
|
autoGreet: map[string]time.Time{},
|
||||||
messageBuf: []messages.Message{},
|
messageBuf: []messages.Message{},
|
||||||
|
reactions: map[int]map[string]interface{}{},
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Initializing RiveScript brain")
|
log.Info("Initializing RiveScript brain")
|
||||||
|
@ -134,6 +155,11 @@ func (h *BotHandlers) OnMessage(msg messages.Message) {
|
||||||
// Cache it in our message buffer.
|
// Cache it in our message buffer.
|
||||||
h.cacheMessage(msg)
|
h.cacheMessage(msg)
|
||||||
|
|
||||||
|
// Record the last seen if this is the lobby channel.
|
||||||
|
if msg.Channel == LobbyChannel {
|
||||||
|
h.lobbyChannelLastUpdated = time.Now()
|
||||||
|
}
|
||||||
|
|
||||||
// Do we send a reply to this?
|
// Do we send a reply to this?
|
||||||
var (
|
var (
|
||||||
sendReply bool
|
sendReply bool
|
||||||
|
@ -227,14 +253,35 @@ func (h *BotHandlers) OnReact(msg messages.Message) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sanity check that we can actually see the message being reacted to: so we don't
|
||||||
|
// upvote reactions posted to messageIDs in other peoples' DM threads.
|
||||||
|
if _, ok := h.getMessageByID(msg.MessageID); !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have already reacted to it, don't react again.
|
||||||
|
h.reactionsMu.Lock()
|
||||||
|
defer h.reactionsMu.Unlock()
|
||||||
|
if _, ok := h.reactions[msg.MessageID]; !ok {
|
||||||
|
h.reactions[msg.MessageID] = map[string]interface{}{}
|
||||||
|
}
|
||||||
|
if _, ok := h.reactions[msg.MessageID][msg.Message]; ok {
|
||||||
|
log.Info("I already reacted %s on message %d", msg.Message, msg.MessageID)
|
||||||
|
return // already upvoted it
|
||||||
|
} else {
|
||||||
|
h.reactions[msg.MessageID][msg.Message] = nil
|
||||||
|
}
|
||||||
|
|
||||||
// Half the time, agree with the reaction.
|
// Half the time, agree with the reaction.
|
||||||
if rand.Intn(100) > 50 {
|
if rand.Intn(100) > 50 {
|
||||||
time.Sleep(2500 * time.Millisecond)
|
go func() {
|
||||||
h.client.Send(messages.Message{
|
time.Sleep(2500 * time.Millisecond)
|
||||||
Action: messages.ActionReact,
|
h.client.Send(messages.Message{
|
||||||
MessageID: msg.MessageID,
|
Action: messages.ActionReact,
|
||||||
Message: msg.Message,
|
MessageID: msg.MessageID,
|
||||||
})
|
Message: msg.Message,
|
||||||
|
})
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,6 +296,9 @@ func (h *BotHandlers) OnPresence(msg messages.Message) {
|
||||||
|
|
||||||
// A join message?
|
// A join message?
|
||||||
if strings.Contains(msg.Message, "has joined the room") {
|
if strings.Contains(msg.Message, "has joined the room") {
|
||||||
|
// Do we force a greeting? (if lobby channel has been quiet)
|
||||||
|
var forceGreeting = time.Now().Sub(h.lobbyChannelLastUpdated) > LobbyDeadThreshold
|
||||||
|
|
||||||
// Global auto-greet cooldown.
|
// Global auto-greet cooldown.
|
||||||
if time.Now().Before(h.autoGreetCooldown) {
|
if time.Now().Before(h.autoGreetCooldown) {
|
||||||
return
|
return
|
||||||
|
@ -258,7 +308,7 @@ func (h *BotHandlers) OnPresence(msg messages.Message) {
|
||||||
// Don't greet the same user too often in case of bouncing.
|
// Don't greet the same user too often in case of bouncing.
|
||||||
h.autoGreetMu.Lock()
|
h.autoGreetMu.Lock()
|
||||||
if timeout, ok := h.autoGreet[msg.Username]; ok {
|
if timeout, ok := h.autoGreet[msg.Username]; ok {
|
||||||
if time.Now().Before(timeout) {
|
if time.Now().Before(timeout) && !forceGreeting {
|
||||||
// Do not greet again.
|
// Do not greet again.
|
||||||
log.Info("Do not auto-greet again: too soon")
|
log.Info("Do not auto-greet again: too soon")
|
||||||
h.autoGreetMu.Unlock()
|
h.autoGreetMu.Unlock()
|
||||||
|
@ -279,11 +329,14 @@ func (h *BotHandlers) OnPresence(msg messages.Message) {
|
||||||
|
|
||||||
// Set their user variables.
|
// Set their user variables.
|
||||||
h.SetUserVariables(msg)
|
h.SetUserVariables(msg)
|
||||||
|
if forceGreeting {
|
||||||
|
h.rs.SetGlobal("numUsersOnline", "0")
|
||||||
|
}
|
||||||
reply, err := h.rs.Reply(msg.Username, "/greet")
|
reply, err := h.rs.Reply(msg.Username, "/greet")
|
||||||
if err == nil && !NoReply(reply) {
|
if err == nil && !NoReply(reply) {
|
||||||
h.client.Send(messages.Message{
|
h.client.Send(messages.Message{
|
||||||
Action: messages.ActionMessage,
|
Action: messages.ActionMessage,
|
||||||
Channel: "lobby",
|
Channel: LobbyChannel,
|
||||||
Username: msg.Username,
|
Username: msg.Username,
|
||||||
Message: reply,
|
Message: reply,
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue
Block a user