public SlackResponseDoc SubmitQuestion(SlackRequestDoc requestDoc, string question) { try { _workflowService.OnQuestionSubmitted(requestDoc.ChannelId, requestDoc.UserId, question); } catch (GameNotStartedException) { return(SlackResponseDoc.Failure(String.Format(GAME_NOT_STARTED_FORMAT, requestDoc.Command))); } catch (WorkflowException e) { return(SlackResponseDoc.Failure(e.Message)); } SlackResponseDoc delayedResponseDoc = new SlackResponseDoc { ResponseType = SlackResponseType.IN_CHANNEL, Text = String.Format("<@{0}> asked the following question:\n\n{1}", requestDoc.UserId, question) }; _delayedSlackService.sendResponse(requestDoc.ResponseUrl, delayedResponseDoc); return(new SlackResponseDoc { ResponseType = SlackResponseType.EPHEMERAL, Text = "Question posted." }); }
public SlackResponseDoc Join(SlackRequestDoc requestDoc) { SlackUser user = new SlackUser(requestDoc.UserId, requestDoc.Username); bool userCreated = _scoreService.CreateUserIfNotExists(requestDoc.ChannelId, user); SlackResponseDoc responseDoc = new SlackResponseDoc { ResponseType = SlackResponseType.EPHEMERAL }; if (userCreated) { responseDoc.Text = "Joining game."; SlackResponseDoc delayedResponseDoc = new SlackResponseDoc { ResponseType = SlackResponseType.IN_CHANNEL, Text = String.Format("<@{0}> has joined the game!", user.UserId) }; _delayedSlackService.sendResponse(requestDoc.ResponseUrl, delayedResponseDoc); } else { responseDoc.Text = "You're already in the game."; } return(responseDoc); }
public SlackResponseDoc MarkAnswerIncorrect(SlackRequestDoc requestDoc, string target) { string userId = SlackUtils.NormalizeId(target); try { _workflowService.OnIncorrectAnswerSelected(requestDoc.ChannelId, requestDoc.UserId, userId); } catch (GameNotStartedException e) { return(SlackResponseDoc.Failure(String.Format(GAME_NOT_STARTED_FORMAT, requestDoc.Command))); } catch (WorkflowException e) { return(SlackResponseDoc.Failure(e.Message)); } SlackResponseDoc delayedResponseDoc = new SlackResponseDoc { ResponseType = SlackResponseType.IN_CHANNEL, Text = String.Format("You couldn't be more wrong, <@{0}>", userId) }; _delayedSlackService.sendResponse(requestDoc.ResponseUrl, delayedResponseDoc); return(new SlackResponseDoc { ResponseType = SlackResponseType.EPHEMERAL, Text = "Marked answer incorrect." }); }
private string generateScoreText(SlackRequestDoc requestDoc) { Dictionary <SlackUser, long> scoresByUser = _scoreService.GetAllScoresByUser(requestDoc.ChannelId); string scoreText; if (!scoresByUser.Any()) { scoreText = "No scores yet..."; } else { int maxUsernameLength = 1 + scoresByUser.Keys .Select(e => e.Username.Length) .Max(); //sort by score desc, username var scoresByUserSorted = from pair in scoresByUser orderby pair.Value descending, pair.Key.Username ascending select pair; scoreText = scoresByUserSorted .Select(e => String.Format("@{0,-" + maxUsernameLength + "} {1,3}", e.Key.Username + ":", e.Value)) .Aggregate((a, b) => a + "\n" + b); } return(String.Format(SCORES_FORMAT, scoreText)); }
public SlackResponseDoc Stop(SlackRequestDoc requestDoc) { try { _workflowService.OnGameStopped(requestDoc.ChannelId, requestDoc.UserId); } catch (GameNotStartedException) { return(SlackResponseDoc.Failure(String.Format(GAME_NOT_STARTED_FORMAT, requestDoc.Command))); } catch (WorkflowException e) { return(SlackResponseDoc.Failure(e.Message)); } return(new SlackResponseDoc { ResponseType = SlackResponseType.IN_CHANNEL, Text = String.Format( "The game has been stopped but scores have not been cleared. If you'd like to start a new game, try `{0} start`.", requestDoc.Command, requestDoc.UserId ) }); }
public SlackResponseDoc GetScores(SlackRequestDoc requestDoc) { return(new SlackResponseDoc { ResponseType = SlackResponseType.EPHEMERAL, Text = generateScoreText(requestDoc) }); }
public SlackResponseDoc GetStatus(SlackRequestDoc requestDoc) { GameState gameState = _workflowService.GetCurrentGameState(requestDoc.ChannelId); return(new SlackResponseDoc { ResponseType = SlackResponseType.EPHEMERAL, Text = generateStatusText(requestDoc, gameState) }); }
public SlackResponseDoc ResetScores(SlackRequestDoc requestDoc) { _scoreService.ResetScores(requestDoc.ChannelId); return(new SlackResponseDoc { ResponseType = SlackResponseType.IN_CHANNEL, Text = "Scores have been reset!", Attachments = new List <SlackAttachment> { new SlackAttachment(generateScoreText(requestDoc)) } }); }
public void TestMarkCorrectCommandWithAnswer() { SlackRequestDoc requestDoc = new SlackRequestDoc { Text = "correct <@12345> I do not know" }; SlackResponseDoc responseDoc = new SlackResponseDoc(); triviaGameService.Setup(x => x.MarkAnswerCorrect(It.IsAny <SlackRequestDoc>(), It.IsAny <string>(), It.IsAny <string>())).Returns(responseDoc); SlackResponseDoc result = cut.ProcessSlashCommand(requestDoc); Assert.AreSame(responseDoc, result); triviaGameService.Verify(x => x.MarkAnswerCorrect(requestDoc, "<@12345>", "I do not know")); }
public void TestAnswerCommand() { SlackRequestDoc requestDoc = new SlackRequestDoc { Text = " answer I do not know " }; SlackResponseDoc responseDoc = new SlackResponseDoc(); triviaGameService.Setup(x => x.SubmitAnswer(It.IsAny <SlackRequestDoc>(), It.IsAny <string>())).Returns(responseDoc); SlackResponseDoc result = cut.ProcessSlashCommand(requestDoc); Assert.AreSame(responseDoc, result); triviaGameService.Verify(x => x.SubmitAnswer(requestDoc, "I do not know")); }
public void TestQuestionCommand() { SlackRequestDoc requestDoc = new SlackRequestDoc { Text = " question What does ATM stand for? " }; SlackResponseDoc responseDoc = new SlackResponseDoc(); triviaGameService.Setup(x => x.SubmitQuestion(It.IsAny <SlackRequestDoc>(), It.IsAny <string>())).Returns(responseDoc); SlackResponseDoc result = cut.ProcessSlashCommand(requestDoc); Assert.AreSame(responseDoc, result); triviaGameService.Verify(x => x.SubmitQuestion(requestDoc, "What does ATM stand for?")); }
public void TestStopCommand() { SlackRequestDoc requestDoc = new SlackRequestDoc { Text = " stop " }; SlackResponseDoc responseDoc = new SlackResponseDoc(); triviaGameService.Setup(x => x.Stop(It.IsAny <SlackRequestDoc>())).Returns(responseDoc); SlackResponseDoc result = cut.ProcessSlashCommand(requestDoc); Assert.AreSame(responseDoc, result); triviaGameService.Verify(x => x.Stop(requestDoc)); }
public void TestStartCommandWithTopic() { SlackRequestDoc requestDoc = new SlackRequestDoc { Text = " start movie quotes" }; SlackResponseDoc responseDoc = new SlackResponseDoc(); triviaGameService.Setup(x => x.Start(It.IsAny <SlackRequestDoc>(), It.IsAny <string>())).Returns(responseDoc); SlackResponseDoc result = cut.ProcessSlashCommand(requestDoc); Assert.AreSame(responseDoc, result); triviaGameService.Verify(x => x.Start(requestDoc, "movie quotes")); }
private string generateStatusText(SlackRequestDoc requestDoc, GameState gameState) { if (gameState == null || gameState.ControllingUserId == null) { return(String.Format(GAME_NOT_STARTED_FORMAT, requestDoc.Command)); } bool isControllingUser = gameState.ControllingUserId == requestDoc.UserId; string topic = gameState.Topic == null ? "None" : gameState.Topic; string turn = isControllingUser ? "Yours" : "<@" + gameState.ControllingUserId + ">"; string question = gameState.Question == null ? " Waiting..." : ("\n\n" + gameState.Question); string statusText = String.Format(BASE_STATUS_FORMAT, topic, turn, question); if (gameState.Question != null) { string answerText; if (gameState.Answers == null || !gameState.Answers.Any()) { answerText = " Waiting..."; } else { int maxUsernameLength = 1 + gameState.Answers .Select(a => a.Username.Length) .Max(); answerText = "\n\n```" + gameState.Answers .OrderBy(answer => answer.CreatedDate) .Select(answer => String.Format( SINGLE_ANSWER_FORMAT, TimeZoneInfo.ConvertTimeFromUtc(answer.CreatedDate, TimeZoneInfo.FindSystemTimeZoneById(LOCAL_TIMEZONE_NAME)).ToString(DATE_FORMAT), String.Format("@{0,-" + maxUsernameLength + "}", answer.Username), answer.Text ) ) .Aggregate((a, b) => a + "\n" + b) + "```"; } statusText += String.Format(ANSWERS_FORMAT, answerText); } return(statusText); }
public void TestQuestionCommandWithTooFewArguments() { SlackRequestDoc requestDoc = new SlackRequestDoc { Command = "/command", Text = "question" }; SlackResponseDoc result = cut.ProcessSlashCommand(requestDoc); Assert.IsNotNull(result); Assert.AreEqual(SlackResponseType.EPHEMERAL, result.ResponseType); Assert.AreEqual("To submit a question, use `/command question <QUESTION_TEXT>`.\n\nFor example, `/command question In what year did WWII officially begin?`", result.Text); Assert.IsNull(result.Attachments); triviaGameService.VerifyNoOtherCalls(); }
public void TestAnswerCommandWithTooFewArguments() { SlackRequestDoc requestDoc = new SlackRequestDoc { Command = "/command", Text = "answer" }; SlackResponseDoc result = cut.ProcessSlashCommand(requestDoc); Assert.IsNotNull(result); Assert.AreEqual(SlackResponseType.EPHEMERAL, result.ResponseType); Assert.AreEqual("To submit an answer, use `/command answer <ANSWER_TEXT>`.\n\nFor example, `/command answer Blue skies`", result.Text); Assert.IsNull(result.Attachments); triviaGameService.VerifyNoOtherCalls(); }
public SlackResponseDoc Pass(SlackRequestDoc requestDoc, string target) { string userId = SlackUtils.NormalizeId(target); try { bool userExists = _scoreService.DoesUserExist(requestDoc.ChannelId, userId); if (!userExists) { SlackResponseDoc responseDoc = SlackResponseDoc.Failure("User " + target + " does not exist. Please choose a valid user."); responseDoc.Attachments = new List <SlackAttachment> { new SlackAttachment("Usage: `" + requestDoc.Command + " pass @jsmith`") }; return(responseDoc); } _workflowService.OnTurnChanged(requestDoc.ChannelId, requestDoc.UserId, userId); } catch (GameNotStartedException) { return(SlackResponseDoc.Failure(String.Format(GAME_NOT_STARTED_FORMAT, requestDoc.Command))); } catch (WorkflowException e) { return(SlackResponseDoc.Failure(e.Message)); } SlackResponseDoc delayedResponseDoc = new SlackResponseDoc { ResponseType = SlackResponseType.IN_CHANNEL, Text = String.Format("<@{0}> has decided to pass his/her turn to <@{1}>.\n\nOK, <@{1}>, it's your turn to ask a question!", requestDoc.UserId, userId) }; _delayedSlackService.sendResponse(requestDoc.ResponseUrl, delayedResponseDoc); return(new SlackResponseDoc { ResponseType = SlackResponseType.EPHEMERAL, Text = "Turn passed to <@" + userId + ">." }); }
public SlackResponseDoc SubmitAnswer(SlackRequestDoc requestDoc, string answer) { try { _workflowService.OnAnswerSubmitted( requestDoc.ChannelId, requestDoc.UserId, requestDoc.Username, answer, requestDoc.RequestTime ); } catch (GameNotStartedException) { return(SlackResponseDoc.Failure(String.Format(GAME_NOT_STARTED_FORMAT, requestDoc.Command))); } catch (WorkflowException e) { return(SlackResponseDoc.Failure(e.Message)); } SlackUser user = new SlackUser(requestDoc.UserId, requestDoc.Username); _scoreService.CreateUserIfNotExists(requestDoc.ChannelId, user); SlackResponseDoc delayedResponseDoc = new SlackResponseDoc { ResponseType = SlackResponseType.IN_CHANNEL, Text = String.Format("<@{0}> answers:", requestDoc.UserId), Attachments = new List <SlackAttachment> { new SlackAttachment(answer, false) } }; _delayedSlackService.sendResponse(requestDoc.ResponseUrl, delayedResponseDoc); return(new SlackResponseDoc { ResponseType = SlackResponseType.EPHEMERAL, Text = "Answer submitted." }); }
public void TestMarkCorrectCommandWithTooFewArguments() { SlackRequestDoc requestDoc = new SlackRequestDoc { Command = "/command", Text = "correct" }; SlackResponseDoc result = cut.ProcessSlashCommand(requestDoc); Assert.IsNotNull(result); Assert.AreEqual(SlackResponseType.EPHEMERAL, result.ResponseType); Assert.AreEqual( "To mark an answer correct, use `/command correct <USERNAME>`.\n" + "Optional: To include the correct answer, use `/command correct <USERNAME> <CORRECT_ANSWER>`.\n\n" + "For example, `/command correct @jsmith Chris Farley`", result.Text ); Assert.IsNull(result.Attachments); triviaGameService.VerifyNoOtherCalls(); }
public SlackResponseDoc Start(SlackRequestDoc requestDoc, string topic) { string channelId = requestDoc.ChannelId; string userId = requestDoc.UserId; try { _workflowService.OnGameStarted(channelId, userId, topic); } catch (GameNotStartedException) { return(SlackResponseDoc.Failure(String.Format(GAME_NOT_STARTED_FORMAT, requestDoc.Command))); } catch (WorkflowException e) { return(SlackResponseDoc.Failure(e.Message)); } return(new SlackResponseDoc { ResponseType = SlackResponseType.IN_CHANNEL, Text = String.Format("OK, <@{0}>, please ask a question.", userId) }); }
public SlackResponseDoc SlackSlashCommand([FromForm] SlackRequestDoc requestDoc) { return(_slackSlashCommandService.ProcessSlashCommand(requestDoc)); }
public SlackResponseDoc ProcessSlashCommand(SlackRequestDoc requestDoc) { //First thing, capture the timestamp requestDoc.RequestTime = DateTime.Now; string commandText = requestDoc.Text == null ? "" : requestDoc.Text.Trim(); string[] commandParts = Regex.Split(commandText, "\\s+"); string operatorText = null; if (commandParts.Length >= 1) { operatorText = commandParts[0]; commandText = commandText.Substring(operatorText.Length).Trim(); } switch (operatorText) { case "start": return(_triviaGameService.Start(requestDoc, String.IsNullOrEmpty(commandText) ? null : commandText)); case "stop": return(_triviaGameService.Stop(requestDoc)); case "join": return(_triviaGameService.Join(requestDoc)); case "pass": if (commandParts.Length < 2) { return(getPassFormat(requestDoc.Command)); } return(_triviaGameService.Pass(requestDoc, commandText)); case "question": if (commandParts.Length < 2) { return(getSubmitQuestionFormat(requestDoc.Command)); } return(_triviaGameService.SubmitQuestion(requestDoc, commandText)); case "answer": if (commandParts.Length < 2) { return(getSubmitAnswerFormat(requestDoc.Command)); } return(_triviaGameService.SubmitAnswer(requestDoc, commandText)); case "incorrect": if (commandParts.Length < 2) { return(getMarkAnswerIncorrectFormat(requestDoc.Command)); } return(_triviaGameService.MarkAnswerIncorrect(requestDoc, commandText)); case "correct": if (commandParts.Length < 2) { return(getMarkAnswerCorrectFormat(requestDoc.Command)); } return(_triviaGameService.MarkAnswerCorrect( requestDoc, commandParts[1], commandParts.Length > 2 ? commandText.Substring(commandParts[1].Length).Trim() : null )); case "status": return(_triviaGameService.GetStatus(requestDoc)); case "scores": return(_triviaGameService.GetScores(requestDoc)); case "reset": return(_triviaGameService.ResetScores(requestDoc)); } return(getUsageFormat(requestDoc.Command)); }
public SlackResponseDoc MarkAnswerCorrect(SlackRequestDoc requestDoc, string target, string answer) { string text; try { _workflowService.OnCorrectAnswerSelected(requestDoc.ChannelId, requestDoc.UserId); if (target.Equals(NO_CORRECT_ANSWER_TARGET, StringComparison.InvariantCultureIgnoreCase)) { //"Change" back to the original host to reset the workflow state _workflowService.OnTurnChanged(requestDoc.ChannelId, requestDoc.UserId, requestDoc.UserId); if (answer == null) { text = String.Format( "It looks like no one was able to answer that one!\n\n{0}\n\nOK, <@{1}>, let's try another one!", generateScoreText(requestDoc), requestDoc.UserId ); } else { text = String.Format( "It looks like no one was able to answer that one! The correct answer was {0}.\n\n{1}\n\nOK, <@{2}>, let's try another one!", answer, generateScoreText(requestDoc), requestDoc.UserId ); } } else { string userId = SlackUtils.NormalizeId(target); _scoreService.IncrementScore(requestDoc.ChannelId, userId); _workflowService.OnTurnChanged(requestDoc.ChannelId, requestDoc.UserId, userId); if (answer == null) { text = String.Format( "<@{1}> is correct!\n\n{0}\n\nOK, <@{1}>, you're up!", generateScoreText(requestDoc), userId ); } else { text = String.Format( "<@{2}> is correct with {0}!\n\n{1}\n\nOK, <@{2}>, you're up!", answer, generateScoreText(requestDoc), userId ); } } } catch (GameNotStartedException) { return(SlackResponseDoc.Failure(String.Format(GAME_NOT_STARTED_FORMAT, requestDoc.Command))); } catch (WorkflowException e) { return(SlackResponseDoc.Failure(e.Message)); } catch (ScoreException) { SlackResponseDoc responseDoc = SlackResponseDoc.Failure("User " + target + " does not exist. Please choose a valid user."); responseDoc.Attachments = new List <SlackAttachment> { new SlackAttachment("Usage: `" + requestDoc.Command + " correct @jsmith Blue skies`") }; return(responseDoc); } SlackResponseDoc delayedResponseDoc = new SlackResponseDoc { ResponseType = SlackResponseType.IN_CHANNEL, Text = text }; _delayedSlackService.sendResponse(requestDoc.ResponseUrl, delayedResponseDoc); return(new SlackResponseDoc { ResponseType = SlackResponseType.EPHEMERAL, Text = "Score updated." }); }