/// <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;
        }
Пример #3
0
        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);
        }