예제 #1
0
        protected override void Execute(CodeActivityContext context)
        {
            var incomingWebHook = IncomingWebHook.Get(context).Trim();
            var message         = Message.Get(context);

            //Verify channel or person is provided
            if ((Channel.Get(context) == null) & (Person.Get(context) == null))
            {
                throw new System.ArgumentException("Please enter either channel or person");
            }

            //Prepare and post http request
            using (var client = new WebClient())
            {
                //Init the http request value
                var http_post_values = new NameValueCollection();
                http_post_values["payload"] = "{"; // {\"channel\": \"#" + channel + "\",  ,\"username\": \"" + sender + "\", \"text\": \"" + message + " \"}";

                //Start building the payload
                //Add channel or person
                if (Person.Get(context) == null)
                {
                    http_post_values["payload"] += "\"channel\": \"#" + Channel.Get(context).Trim() + "\"";
                }
                else
                {
                    http_post_values["payload"] += "\"channel\": \"@" + Person.Get(context).Trim() + "\"";
                }

                //Add sender if provided
                if (Sender.Get(context) != null)
                {
                    http_post_values["payload"] += ", \"username\": \"" + Sender.Get(context).Trim() + "\"";
                }

                //Add message
                http_post_values["payload"] += ", \"link_names\": \"1\", \"text\": \"" + message + "\"";

                //Wrapping up the payload
                http_post_values["payload"] += "}";

                //Posting http request
                var response = client.UploadValues(incomingWebHook, http_post_values);

                //Getting post response
                var responseString = Encoding.Default.GetString(response);
                Status.Set(context, responseString);
            }
        }
        /// <summary>
        /// Method to get leave Updated from slack button response
        /// </summary>
        /// <param name="leaveResponse">leave update response from slack</param>
        public async Task UpdateLeaveAsync(SlashChatUpdateResponse leaveResponse)
        {
            try
            {
                _logger.Debug("UpdateLeaveAsync Leave update method");
                // method to get leave by its id
                LeaveRequest leave = await _leaveRepository.LeaveByIdAsync(Convert.ToInt32(leaveResponse.CallbackId));

                _logger.Debug("UpdateLeaveAsync leave applied by : " + leave.EmployeeId);
                ApplicationUser user = await _userManagerRepository.FirstOrDefaultAsync(x => x.Id == leave.EmployeeId);

                _logger.Debug("UpdateLeaveAsync User name : " + user.UserName);
                SlackUserDetailAc slackUser = await _slackUserRepository.GetByIdAsync(user.SlackUserId);

                _logger.Debug("UpdateLeaveAsync User slack name : " + slackUser.Name);
                ApplicationUser updaterUser = await _userManagerRepository.FirstOrDefaultAsync(x => x.SlackUserId == leaveResponse.User.Id);

                if (updaterUser != null)
                {
                    _logger.Debug("UpdateLeaveAsync User want to update the leave : " + updaterUser.UserName);
                    // only pending status can be modified
                    if (leave.Status == Condition.Pending)
                    {
                        if (leaveResponse.Actions[0].Value == _stringConstant.Approved)
                        {
                            leave.Status = Condition.Approved;
                        }
                        else
                        {
                            leave.Status = Condition.Rejected;
                        }
                        await _leaveRepository.UpdateLeaveAsync(leave);

                        _logger.Debug("UpdateLeaveAsync leave updated successfully");
                        _logger.Debug("Leave details : " + leave.ToString());
                        replyText = string.Format(_stringConstant.CasualLeaveUpdateMessageForUser,
                                                  leave.Id, leave.FromDate.ToShortDateString(), leave.EndDate.Value.ToShortDateString(),
                                                  leave.Reason, leave.Status, leaveResponse.User.Name);
                        _logger.Debug("Reply text to user : "******"UpdateLeaveAsync user incoming webhook is null : " + string.IsNullOrEmpty(incomingWebHook.IncomingWebHookUrl));
                        // Used to send slack message to the user about leave updation
                        _logger.Debug("UpdateLeaveAsync Client repository - UpdateMessageAsync");
                        await _clientRepository.UpdateMessageAsync(incomingWebHook.IncomingWebHookUrl, replyText);

                        _logger.Debug("Creating Email object");
                        // Used to send email to the user about leave updation
                        EmailApplication email = new EmailApplication();
                        email.To   = new List <string>();
                        email.Body = _emailTemplateRepository.EmailServiceTemplateLeaveUpdate(leave);
                        _logger.Debug("Email body is null : " + email.Body);
                        email.From = updaterUser.Email;
                        _logger.Debug("Email from : " + email.From);
                        email.To.Add(user.Email);
                        _logger.Debug("Email from : " + email.To);
                        email.Subject = string.Format(_stringConstant.LeaveUpdateEmailStringFormat, _stringConstant.Leave, leave.Status);
                        replyText     = string.Format(_stringConstant.ReplyTextForUpdateLeave, leave.Status, slackUser.Name,
                                                      leave.FromDate.ToShortDateString(), leave.EndDate.Value.ToShortDateString(), leave.Reason,
                                                      leave.RejoinDate.Value.ToShortDateString());
                        _logger.Debug("Reply text to updator : " + replyText);
                        _logger.Debug("UpdateLeaveAsync Email sending");
                        _emailService.Send(email);
                        _logger.Debug("UpdateLeaveAsync Email successfully send");
                    }
                    else
                    {
                        _logger.Debug("UpdateLeaveAsync leave already updated");
                        replyText = string.Format(_stringConstant.AlreadyUpdatedMessage, leave.Status);
                    }
                }
                else
                {
                    replyText = _stringConstant.YouAreNotInExistInOAuthServer;
                }
            }
            catch (SmtpException ex)
            {
                replyText += string.Format(_stringConstant.ReplyTextForSMTPExceptionErrorMessage,
                                           _stringConstant.ErrorWhileSendingEmail, ex.Message.ToString());
            }
            _logger.Debug("UpdateLeaveAsync Client Repository - SendMessageAsync");
            // updating leave applied text of slack
            await _clientRepository.SendMessageAsync(leaveResponse.ResponseUrl, replyText);
        }
        /// <summary>
        /// Method to operate leave slack command
        /// </summary>
        /// <param name="leave">slash command object</param>
        public async Task LeaveRequestAsync(SlashCommand leave)
        {
            SlackAction actionType;
            // method to convert slash command to list of string
            List <string> slackText = _attachmentRepository.SlackText(leave.Text);
            // to get user details by slack user name
            ApplicationUser user = await _userManagerRepository.FirstOrDefaultAsync(x => x.SlackUserId == leave.UserId);

            if (user != null)
            {
                _logger.Debug("LeaveRequestAsync leave request user name : " + user.UserName);
                IncomingWebHook incomingWebHook = await _incomingWebHookRepository.FirstOrDefaultAsync(x => x.UserId == user.SlackUserId);

                if (incomingWebHook != null)
                {
                    _logger.Debug("LeaveRequestAsync leave request user incoming webhook is null : " + incomingWebHook.IncomingWebHookUrl);
                    leave.Text.ToLower();
                    // getting access token of user of promact oauth server
                    string accessToken = await _attachmentRepository.UserAccessTokenAsync(user.UserName);

                    // checking whether string ca convert to Slack Action or not, if true then further process will be conduct
                    bool actionConvertorResult = Enum.TryParse(slackText[0], out actionType);
                    if (actionConvertorResult)
                    {
                        switch (actionType)
                        {
                        case SlackAction.apply:
                            replyText = await LeaveApplyAsync(slackText, leave, accessToken, user.Id);

                            break;

                        case SlackAction.list:
                            replyText = await SlackLeaveListAsync(slackText, leave, accessToken);

                            break;

                        case SlackAction.cancel:
                            replyText = await SlackLeaveCancelAsync(slackText, leave, accessToken);

                            break;

                        case SlackAction.status:
                            replyText = await SlackLeaveStatusAsync(slackText, leave, accessToken);

                            break;

                        case SlackAction.balance:
                            replyText = await SlackLeaveBalanceAsync(leave, accessToken);

                            break;

                        case SlackAction.update:
                            replyText = await UpdateSickLeaveAsync(slackText, user, accessToken);

                            break;

                        default:
                            replyText = SlackLeaveHelp(leave);
                            break;
                        }
                    }
                    else
                    {
                        // if error in converting then user will get message to enter proper action command
                        replyText = _stringConstant.RequestToEnterProperAction;
                    }
                }
                else
                {
                    replyText = _stringConstant.RequestToAddSlackApp;
                }
            }
            else
            {
                // if user doesn't exist then will get message of user doesn't exist and ask to externally logic from Oauth server
                replyText = _stringConstant.SorryYouCannotApplyLeave;
            }
            _logger.Debug("LeaveRequestAsync Client Repository - SendMessageAsync");
            await _clientRepository.SendMessageAsync(leave.ResponseUrl, replyText);
        }
        /// <summary>
        /// Method to add/update Slack User,channels and groups information
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public async Task AddSlackUserInformationAsync(string code)
        {
            string slackOAuthRequest  = string.Format(_stringConstant.SlackOauthRequestUrl, _envVariableRepository.SlackOAuthClientId, _envVariableRepository.SlackOAuthClientSecret, code);
            string slackOAuthResponse = await _httpClientService.GetAsync(_stringConstant.OAuthAcessUrl, slackOAuthRequest, null, _stringConstant.Bearer);

            SlackOAuthResponse slackOAuth = JsonConvert.DeserializeObject <SlackOAuthResponse>(slackOAuthResponse);

            _logger.Info("slackOAuth UserID" + slackOAuth.UserId);
            bool checkUserIncomingWebHookExist = _incomingWebHookRepository.Any(x => x.UserId == slackOAuth.UserId);

            if (!checkUserIncomingWebHookExist)
            {
                IncomingWebHook slackItem = new IncomingWebHook()
                {
                    UserId             = slackOAuth.UserId,
                    IncomingWebHookUrl = slackOAuth.IncomingWebhook.Url
                };
                _incomingWebHookRepository.Insert(slackItem);
                await _incomingWebHookRepository.SaveChangesAsync();
            }

            string detailsRequest = string.Format(_stringConstant.SlackUserDetailsUrl, slackOAuth.AccessToken);
            //get all the slack users of the team
            string userDetailsResponse = await _httpClientService.GetAsync(_stringConstant.SlackUserListUrl, detailsRequest, null, _stringConstant.Bearer);

            SlackUserResponse slackUsers = JsonConvert.DeserializeObject <SlackUserResponse>(userDetailsResponse);

            if (slackUsers.Ok)
            {
                SlackUserDetails slackUserDetails = slackUsers.Members?.Find(x => x.UserId == slackOAuth.UserId);
                _logger.Debug("slackUserDetails" + slackUserDetails.UserId);
                if (!string.IsNullOrEmpty(slackUserDetails?.Profile?.Email))
                {
                    //fetch the details of the user who is authenticated with Promact OAuth server with the given slack user's email
                    _logger.Debug("Profile Email" + slackUserDetails.Profile.Email);
                    ApplicationUser applicationUser = await _userManager.FindByEmailAsync(slackUserDetails.Profile.Email);

                    if (applicationUser != null)
                    {
                        _logger.Debug("slackUserDetails UserID" + slackUserDetails.UserId);
                        applicationUser.SlackUserId = slackUserDetails.UserId;
                        _logger.Debug("applicationUser SlackUserId" + applicationUser.SlackUserId);
                        var succeeded = await _userManager.UpdateAsync(applicationUser);

                        _logger.Debug("applicationUser Object:" + JsonConvert.SerializeObject(applicationUser));
                        _logger.Debug("Update Application User succeeded" + succeeded.Succeeded);
                        _logger.Debug("Update Application User Errors" + succeeded.Errors);
                        ApplicationUser testApllicationUser = await _userManager.FindByEmailAsync(applicationUser.Email);

                        _logger.Debug("Test Application Slcak UserId" + testApllicationUser.SlackUserId);
                        _logger.Debug("Test ApplicationUser Object:" + JsonConvert.SerializeObject(testApllicationUser));
                        await _slackUserRepository.AddSlackUserAsync(slackUserDetails);

                        _logger.Debug("Add Slack User Id Done");
                        //the public channels' details
                        string channelDetailsResponse = await _httpClientService.GetAsync(_stringConstant.SlackChannelListUrl, detailsRequest, null, _stringConstant.Bearer);

                        SlackChannelResponse channels = JsonConvert.DeserializeObject <SlackChannelResponse>(channelDetailsResponse);
                        if (channels.Ok)
                        {
                            _logger.Info("Channels error:" + channels.ErrorMessage);
                            foreach (var channel in channels.Channels)
                            {
                                _logger.Info("Channel:" + channel);
                                await AddChannelGroupAsync(channel);
                            }
                        }
                        else
                        {
                            throw new SlackAuthorizeException(_stringConstant.SlackAuthError + channels.ErrorMessage);
                        }
                        _logger.Info("Slack User Id  : " + (await _userManager.FindByEmailAsync(applicationUser.Email)).SlackUserId);
                        //the public groups' details
                        string groupDetailsResponse = await _httpClientService.GetAsync(_stringConstant.SlackGroupListUrl, detailsRequest, null, _stringConstant.Bearer);

                        SlackGroupDetails groups = JsonConvert.DeserializeObject <SlackGroupDetails>(groupDetailsResponse);
                        _logger.Info("Groups:" + groups.ErrorMessage);
                        _logger.Debug("Slack User Id  : " + (await _userManager.FindByEmailAsync(applicationUser.Email)).SlackUserId);
                        if (groups.Ok)
                        {
                            foreach (var channel in groups.Groups)
                            {
                                _logger.Info("Group:" + channel);
                                await AddChannelGroupAsync(channel);

                                _logger.Debug("Slack User Id  : " + (await _userManager.FindByEmailAsync(applicationUser.Email)).SlackUserId);
                            }
                        }
                        else
                        {
                            throw new SlackAuthorizeException(_stringConstant.SlackAuthError + groups.ErrorMessage);
                        }
                    }
                    else
                    {
                        throw new SlackAuthorizeException(string.Format(_stringConstant.NotInSlackOrNotExpectedUser, slackUserDetails.Profile.Email));
                    }
                }
                else
                {
                    throw new SlackAuthorizeException(_stringConstant.UserNotInSlack);
                }
            }
            else
            {
                throw new SlackAuthorizeException(_stringConstant.SlackAuthError + slackUsers.ErrorMessage);
            }
        }