/// <summary> /// Main entry point for the class. /// Takes a message revived from chat, determines what action should be taken, then performs that action. /// </summary> /// <param name="incommingChatMessage">The chat message that was said.</param> /// <param name="chatRoom">The room the chat message was said in.</param> public void ProcessChatMessage(Message incommingChatMessage, Room chatRoom) { // Do this first so I only have to find the result once per chat message. bool isReplyToChatbot = MessageIsReplyToChatbot(incommingChatMessage, chatRoom); // Determine the list of possible actions that work from the message. var possibleChatbotActionsToRun = ChatbotActionRegister.AllChatActions .Where(x => x.DoesChatMessageActiveAction(incommingChatMessage, isReplyToChatbot)) .ToList(); if (possibleChatbotActionsToRun.Count > 1) throw new Exception("More than one possible chat bot action to run for the input '{0}'" .FormatSafely(incommingChatMessage.Content)); if (!possibleChatbotActionsToRun.Any()) { // Didn't find an action to run, what to do next depends of if the message was // a reply to the chatbot or not. if (isReplyToChatbot) { // User was trying to make a command. SendUnrecognizedCommandToDatabase(incommingChatMessage.GetContentsWithStrippedMentions()); chatRoom.PostReplyOrThrow(incommingChatMessage, "Sorry, I don't understand that. Use `{0}` for a list of commands." .FormatInline(ChatbotActionRegister.GetChatBotActionUsage<Commands>())); } // Else it's a trigger, do nothing. return; } // You have a single item to run. var chatbotActionToRun = possibleChatbotActionsToRun.Single(); // Now, do you have permission to run it? If you are a mod the answer is yes, else you need to check. if (incommingChatMessage.Author.IsMod || DoesUserHavePermissionToRunAction(chatbotActionToRun, incommingChatMessage.Author.ID)) { // Have permission, run it. RunChatbotAction(chatbotActionToRun, incommingChatMessage, chatRoom); } else { // Don't have permission, tell the user only if it's a command. if (isReplyToChatbot) { chatRoom.PostReplyOrThrow(incommingChatMessage, "Sorry, you need more permissions to run that command."); } // Don't do anything for triggers. } }
/// <summary> /// Records the end of a review session for a user. Returns true if the session was successfully marked as finished. /// </summary> /// <param name="userMessage"></param> /// <param name="chatRoom"></param> /// <param name="itemsReviewed"></param> /// <returns></returns> protected bool EndSession(Message userMessage, Room chatRoom, int? itemsReviewed, InstallationSettings settings) { var da = new DatabaseAccessor(settings.DatabaseConnectionString); // Find the latest session by that user. var latestSession = da.GetLatestOpenSessionForUser(userMessage.Author.ID); // First, check if there is a session. if (latestSession == null) { chatRoom.PostReplyOrThrow(userMessage, "I don't seem to have the start of your review session on record. I might have not been running when you started, or some error happened."); return false; } // Check if session is greater than [MAX_REVIEW_TIME]. var maxReviewTimeHours = settings.MaxReviewLengthHours; var timeThreshold = DateTimeOffset.Now.AddHours(-maxReviewTimeHours); if (latestSession.SessionStart < timeThreshold) { var timeDelta = DateTimeOffset.Now - latestSession.SessionStart; var message = "Your last uncompleted review session was {0} ago. Because it has exceeded my threshold ({1} hours), I can't mark that session with this information. " .FormatInline(timeDelta.ToUserFriendlyString(), maxReviewTimeHours) + "Use the command '{0}' to forcefully end that session." .FormatInline(ChatbotActionRegister.GetChatBotActionUsage<EndSession>()); chatRoom.PostReplyOrThrow(userMessage, message); return false; } // It's all good, mark the info as done. da.EndReviewSession(latestSession.Id, itemsReviewed); return true; }
public override void RunAction(Message incomingChatMessage, ChatExchangeDotNet.Room chatRoom) { var runningCommands = RunningChatbotActionsManager.GetRunningChatbotActions(); var now = DateTimeOffset.Now; var tableMessage = runningCommands .Select(x => new { Command = x.ChatbotActionName, ForUser = $"{x.RunningForUserName} ({x.RunningForUserId})", Started = (now - x.StartTs).ToUserFriendlyString() + " ago", }) .ToStringTable(new[] { "Command", "For User", "Started" }, x => x.Command, x => x.ForUser, x => x.Started); chatRoom.PostReplyOrThrow(incomingChatMessage, "The following is a list of commands that I'm currently running:"); chatRoom.PostMessageOrThrow(tableMessage); }