Esempio n. 1
0
        public ActionResult <SlashCommandResponse> DoSlashCommand([FromForm] SlackCommandInput input)
        {
            if (!input.TeamDomain.Equals(SlackConfig.Workspace, StringComparison.CurrentCultureIgnoreCase))
            {
                return(Forbid());
            }
            string command = input.Command.ToLower();

            if (!SlackConfig.IsKnownCommand(command))
            {
                return(BadRequest());
            }

            string caseCmd         = input.Text.Trim();
            bool   intParseSuccess = int.TryParse(caseCmd, out int caseNumber);

            if (!intParseSuccess)
            {
                return(SlashCommandResponse.ForBadCommand(
                           errorOrHelpText: "Please enter a single, numeric value."));
            }

            var jobInfo = new FogBugzSlashCommandInfo(
                command: command,
                caseNumber: caseNumber,
                channelId: input.ChannelId,
                triggerId: input.TriggerId,
                responseUrl: input.ResponseUrl.ToString());

            BackgroundJob.Enqueue(() => RespondToSlashCommand(jobInfo));

            return(SlashCommandResponse.ForCommandAcknowledgement());
        }
Esempio n. 2
0
        public async Task RespondToSlashCommand(FogBugzSlashCommandInfo info)
        {
            var request = new FogBugzSearchRequest(
                apiToken: FogBugzConfig.GetApiToken(),
                caseNumber: info.CaseNumber);

            FogBugzSearchResponse responseFromFogBugz;
            SlashCommandResponse  responseToSlack;
            string stepName;

            /* πŸ“œ π•Ύπ–™π–Šπ–• π•Ώπ–π–Š π–…π–Šπ–—π–”π–™π– πŸ“œ */
            {
                responseToSlack = null;
                stepName        = "calling the FogBugz API";
            }
            try
            {
                using (var httpResponse = await WebClient.PostAsJsonAsync(FogBugzConfig.ApiUri, request))
                    using (var message = await httpResponse.Content.ReadAsHttpResponseMessageAsync())
                    {
                        if (!message.IsSuccessStatusCode)
                        {
                            string errorText = GetFriendlyHttpErrorMsg(httpResponse);
                            responseToSlack = SlashCommandResponse.ForFogBugzApiCallResult(
                                text: $"There was an error calling the FogBugz API for Case {info.CaseNumber}.",
                                attachments: new SlashCommandReponseAttachment(errorText, SlackAttachmentColorType.Danger));
                            throw new SlashCommandException(errorText);
                        }

                        {
                            responseToSlack = null;
                            stepName        = "reading the FogBugz API response";
                        }
                        using (var contentStream = await message.Content.ReadAsStreamAsync())
                        {
                            responseFromFogBugz = (FogBugzSearchResponse) new DataContractJsonSerializer(typeof(FogBugzSearchResponse))
                                                  .ReadObject(contentStream);
                        }
                    }

                /* πŸ“œ π•Ύπ–™π–Šπ–• π•Ώπ–π–Š π•±π–Žπ–—π–˜π–™ πŸ“œ */
                {
                    responseToSlack = null;
                    stepName        = "reading the FogBugz API message";
                }
                var theCase = responseFromFogBugz?.ResponseData?.Cases?
                              .FirstOrDefault(c => c.CaseNumber == info.CaseNumber);
                if (theCase == null)
                {
                    if (responseFromFogBugz.Errors?.Any() == true)
                    {
                        var error = responseFromFogBugz.Errors.First();
                        responseToSlack = SlashCommandResponse.ForFogBugzApiCallResult(
                            text: $"There was an error reading the FogBugz API message for Case {info.CaseNumber}.",
                            attachments: new SlashCommandReponseAttachment($"{ error.Code }: { error.Message }", SlackAttachmentColorType.Danger));
                        throw new SlashCommandException($"{ error.Code }: { error.Message }");
                    }
                    else
                    {
                        responseToSlack = SlashCommandResponse.ForFogBugzApiCallResult(
                            text: $"Case {info.CaseNumber} does not seem to exist.");
                    }
                }
                else
                {
                    /* πŸ“œ π•Ύπ–™π–Šπ–• π•Ώπ–π–Š π•Ύπ–Šπ–ˆπ–”π–“π–‰ πŸ“œ */
                    {
                        responseToSlack = null;
                        stepName        = "generating the command response";
                    }
                    (decimal Elapsed, decimal Total)? estimate = null;
                    if (theCase.EstimatedHours > 0)
                    {
                        estimate = (Elapsed : theCase.ElapsedHours, Total : theCase.EstimatedHours);
                    }
                    responseToSlack = GetSuccessfulResponseText(
                        caseNumber: info.CaseNumber.ToString(),
                        title: theCase.Title,
                        estimate: estimate);
                }
            }
            catch (Exception ex)
            {
                if (responseToSlack == null)
                {
                    responseToSlack = SlashCommandResponse.ForFogBugzApiCallResult(
                        text: $"There was an error {stepName} for Case {info.CaseNumber}.",
                        attachments: new SlashCommandReponseAttachment(ex.Message, SlackAttachmentColorType.Danger));
                }
                throw ex;
            }
            finally
            {
                await RespondToSlack(info.ResponseUrl, responseToSlack);
            }
        }