diff --git a/backend/app/slack/slack.go b/backend/app/slack/slack.go index 44da869..9e9852f 100644 --- a/backend/app/slack/slack.go +++ b/backend/app/slack/slack.go @@ -24,11 +24,13 @@ import ( ) var ( - BOT *Bot - GRAMMAR_CHECK_REACTION = "eyeglasses" - PROCESSED_REACTION = "white_check_mark" - HOME_TAB_MESSAGE = "I'm Gienji, your intelligent chatbot. I'm here to help you with any questions or problems you might have. Just type your question or request, and I'll do my best to provide you with the information you need. You can direct message me or add me to a public channel. Just tag me to talk with me with @gienji." - TIMEOUT = 2 * time.Minute + BOT *Bot + GRAMMAR_CHECK_REACTION = "eyeglasses" + SUMMARIZE_REACTION = "memo" + PROCESSED_REACTION = "white_check_mark" + HOME_TAB_MESSAGE = "I'm Gienji, your intelligent chatbot. I'm here to help you with any questions or problems you might have. Just type your question or request, and I'll do my best to provide you with the information you need. You can direct message me or add me to a public channel. Just tag me to talk with me with @gienji." + TIMEOUT = 2 * time.Minute + THREAD_MESSAGES_LIMIT_FOR_SUMMARIZE = 100 ) type Bot struct { @@ -107,17 +109,21 @@ func slackEventsHandler(ctx *fasthttp.RequestCtx) { } return case *slackevents.ReactionAddedEvent: - if ev.Reaction != GRAMMAR_CHECK_REACTION || ev.Item.Type != "message" { + if (ev.Reaction != GRAMMAR_CHECK_REACTION && ev.Reaction != SUMMARIZE_REACTION) || ev.Item.Type != "message" { return } - log.Infof("Received slack reaction event in channel %s, ts: %s", ev.Item.Channel, ev.Item.Timestamp) + log.Infof("Received slack `%s` reaction event in channel %s, ts: %s", ev.Reaction, ev.Item.Channel, ev.Item.Timestamp) message := fetchMessage(ev.Item.Channel, ev.Item.Timestamp) if message.User != "" && message.BotID == "" { - handleMessageEvent("slack:"+ev.User, ev.Item.Channel, ev.Item.Timestamp, message.Text, true) - BOT.AddReaction(PROCESSED_REACTION, slack.ItemRef{ - Channel: ev.Item.Channel, - Timestamp: message.Timestamp, - }) + if ev.Reaction == GRAMMAR_CHECK_REACTION { + handleMessageEvent("slack:"+ev.User, ev.Item.Channel, ev.Item.Timestamp, message.Text, true) + BOT.AddReaction(PROCESSED_REACTION, slack.ItemRef{ + Channel: ev.Item.Channel, + Timestamp: message.Timestamp, + }) + } else if ev.Reaction == SUMMARIZE_REACTION { + summarizeThread(ev.User, message.Timestamp, ev.Item.Channel) + } } return case *slackevents.AppHomeOpenedEvent: @@ -163,7 +169,7 @@ func slackCommandsHandler(ctx *fasthttp.RequestCtx) { lib.SaveMode(userId, lib.ChatGPT) BOT.SendMessage(command.ChannelID, slack.MsgOptionText("ChatGPT mode enabled", false), slack.MsgOptionPostEphemeral(command.UserID)) case "/summarize": - summarizeThread(userId, "", command) + summarizeThread(userId, "", command.ChannelID) } }() } @@ -352,17 +358,17 @@ func fetchMessage(channelId string, messageTS string) slack.Message { return slack.Message{} } - log.Infof("Found message: %+v", messages.Messages[0]) + log.Infof("Found message: %s", messages.Messages[0].Timestamp) return messages.Messages[0] } -func summarizeThread(userId string, messageTS string, command slack.SlashCommand) { +func summarizeThread(userId string, messageTS string, channelId string) { // throw err if current user doesn't start with "slack:" if !strings.HasPrefix(userId, "slack:") { log.Errorf("Invalid user: %s", userId) return } - _, currentContext, cancelFunc, err := lib.SetupUserAndContext(userId, lib.SlackClientName, command.ChannelID) + _, currentContext, cancelFunc, err := lib.SetupUserAndContext(userId, lib.SlackClientName, channelId) if err != nil { if err == lib.ErrUserBanned { log.Infof("User %s is banned", userId) @@ -377,7 +383,7 @@ func summarizeThread(userId string, messageTS string, command slack.SlashCommand // user usage exceeded monthly limit, send message and return ok := lib.ValidateUserUsage(currentContext) if !ok { - BOT.SendMessage(command.ChannelID, slack.MsgOptionText("Your monthly usage limit has been exceeded. Please /upgrade your plan.", false), slack.MsgOptionPostEphemeral(userId)) + BOT.SendMessage(channelId, slack.MsgOptionText("Your monthly usage limit has been exceeded. Please /upgrade your plan.", false), slack.MsgOptionPostEphemeral(userId)) config.CONFIG.DataDogClient.Incr("usage_exceeded", []string{"client:slack"}, 1) return } @@ -386,18 +392,22 @@ func summarizeThread(userId string, messageTS string, command slack.SlashCommand var seedData []models.Message var userMessagePrimer string seedData, userMessagePrimer = lib.GetSeedDataAndPrimer(lib.Summarize) - messageText := fetchMessageThread(command.ChannelID, messageTS) + messageText := fetchMessageThread(channelId, messageTS) if messageText == "" { - log.Errorf("Error fetching message in channel %s, ts: %s", command.ChannelID, messageTS) - BOT.SendMessage(command.ChannelID, slack.MsgOptionText("Error fetching message thread", false), slack.MsgOptionPostEphemeral(userId)) + log.Errorf("Error fetching message in channel %s, ts: %s", channelId, messageTS) + BOT.SendMessage(channelId, slack.MsgOptionText("Error fetching message thread", false), slack.MsgOptionPostEphemeral(userId)) return } - log.Infof("Received summarize request in slack chat: %s, user: %s, initiating request to OpenAI", command.ChannelID, userId) + log.Infof("Received summarize request in slack chat: %s, user: %s, initiating request to OpenAI", channelId, userId) engineModel := redis.GetChatEngine(userId) - ProcessStreamingMessage(currentContext, command.ChannelID, messageTS, messageText, seedData, userMessagePrimer, lib.Summarize, engineModel, cancelFunc, false) + summarizeInThread := true + if messageTS == "" { + summarizeInThread = false + } + ProcessStreamingMessage(currentContext, channelId, messageTS, messageText, seedData, userMessagePrimer, lib.Summarize, engineModel, cancelFunc, summarizeInThread) } func fetchMessageThread(channelId string, messageTS string) string { @@ -405,7 +415,7 @@ func fetchMessageThread(channelId string, messageTS string) string { &slack.GetConversationHistoryParameters{ ChannelID: channelId, Latest: messageTS, - Limit: 100, + Limit: THREAD_MESSAGES_LIMIT_FOR_SUMMARIZE, Inclusive: true, }, ) @@ -419,11 +429,15 @@ func fetchMessageThread(channelId string, messageTS string) string { return "" } - log.Infof("Found message: %+v", messages.Messages) + log.Infof("Found %d messages", len(messages.Messages)) messageText := "" for _, message := range messages.Messages { - messageText += fmt.Sprintf("@%s: %s\n\n", message.Username, message.Text) + username := message.User + if message.Username != "" { + username = "@" + message.Username + } + messageText += fmt.Sprintf("%s: %s\n\n", username, message.Text) } return messageText