/// <summary>
        /// Add a new suggestion in company response entity in Microsoft Azure Table storage.
        /// </summary>
        /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param>
        /// <param name="userRequestDetails">User response new request details object used to send new request data.</param>
        /// <param name="customAPIAuthenticationToken">Generate JWT token used by client application to authenticate HTTP calls with API.</param>
        /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        private async Task <MessagingExtensionActionResponse> AddNewSuggestionResultAsync(
            ITurnContext <IInvokeActivity> turnContext,
            AddUserResponseRequestDetail userRequestDetails,
            string customAPIAuthenticationToken,
            CancellationToken cancellationToken)
        {
            var activity = turnContext.Activity;
            var companyResponseEntity = await this.companyStorageHelper.AddNewSuggestionAsync(activity, userRequestDetails);

            // Parse team channel deep link URL and get team id.
            var teamId = AdaptiveCardHelper.ParseTeamIdFromDeepLink(this.botSetting.Value.TeamIdDeepLink);

            if (string.IsNullOrEmpty(teamId))
            {
                throw new NullReferenceException("Provided team details seems to incorrect, please reach out to the Admin.");
            }

            var isAddSuggestionSuccess = await this.companyResponseStorageProvider.UpsertConverationStateAsync(companyResponseEntity);

            if (isAddSuggestionSuccess)
            {
                // Tracking for company response suggested request.
                this.RecordEvent(RecordSuggestCompanyResponse, turnContext);
                var attachment       = AdminCard.GetNewResponseRequestCard(companyResponseEntity, localizer: this.localizer);
                var resourceResponse = await this.SendCardToTeamAsync(turnContext, attachment, teamId, cancellationToken);

                companyResponseEntity.ActivityId = resourceResponse.ActivityId;
                await this.companyResponseStorageProvider.UpsertConverationStateAsync(companyResponseEntity);

                return(new MessagingExtensionActionResponse
                {
                    Task = new TaskModuleContinueResponse
                    {
                        Value = new TaskModuleTaskInfo
                        {
                            Url = $"{this.options.Value.AppBaseUri}/response-message?token={customAPIAuthenticationToken}&status=addSuccess&isCompanyResponse=true&message={this.localizer.GetString("AddNewSuggestionSuccessMessage")}&telemetry=${this.telemetrySettings.Value.InstrumentationKey}&theme=" + "{theme}&locale=" + "{locale}",
                            Height = TaskModuleHeight,
                            Width = TaskModuleWidth,
                            Title = this.localizer.GetString("ManageYourResponsesTitleText"),
                        },
                    },
                });
            }
            else
            {
                return(new MessagingExtensionActionResponse
                {
                    Task = new TaskModuleContinueResponse
                    {
                        Value = new TaskModuleTaskInfo
                        {
                            Url = $"{this.options.Value.AppBaseUri}/response-message?token={customAPIAuthenticationToken}&status=editFailed&isCompanyResponse=true&message={this.localizer.GetString("AddNewSuggestionFailedMessage")}&theme=" + "{theme}&locale=" + "{locale}",
                            Height = TaskModuleHeight,
                            Width = TaskModuleWidth,
                            Title = this.localizer.GetString("ManageYourResponsesTitleText"),
                        },
                    },
                });
            }
        }
        /// <summary>
        /// Handle message activity in channel.
        /// </summary>
        /// <param name="message">A message in a conversation.</param>
        /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param>
        /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        private async Task OnMessageActivityInChannelAsync(
            IMessageActivity message,
            ITurnContext <IMessageActivity> turnContext,
            CancellationToken cancellationToken)
        {
            try
            {
                if (message.Value == null)
                {
                    await turnContext.SendActivityAsync(this.localizer.GetString("ErrorWhenMessageInChannel"));

                    return;
                }

                IMessageActivity      userNotification      = null;
                CompanyResponseEntity companyResponseEntity = null;
                var cardPostedData = ((JObject)message.Value).ToObject <AdaptiveSubmitActionData>();
                var text           = cardPostedData.AdaptiveCardActions.Text;
                var activity       = turnContext.Activity;

                switch (text)
                {
                case Constants.ApproveCommand:

                    if (string.IsNullOrEmpty(cardPostedData.UpdatedQuestionCategory) || string.IsNullOrEmpty(cardPostedData.UpdatedQuestionText) || string.IsNullOrEmpty(cardPostedData.UpdatedResponseText))
                    {
                        companyResponseEntity = this.companyResponseStorageProvider.GetCompanyResponseEntityAsync(cardPostedData.ResponseId).GetAwaiter().GetResult();
                        var attachment = AdminCard.GetNewResponseRequestCard(companyResponseEntity, localizer: this.localizer, emptyApproveField: true);
                        await AdaptiveCardHelper.RefreshCardAsync(turnContext, companyResponseEntity.ActivityId, attachment);

                        return;
                    }

                    companyResponseEntity = this.companyStorageHelper.AddApprovedData(cardPostedData, activity.From.Name, activity.From.AadObjectId);
                    var approveRequestResult = this.companyResponseStorageProvider.UpsertConverationStateAsync(companyResponseEntity).GetAwaiter().GetResult();

                    if (approveRequestResult)
                    {
                        // Refresh the approved card in channel.
                        var attachment = AdminCard.GetRefreshedCardForApprovedRequest(companyResponseEntity, activity.From.Name, localizer: this.localizer);
                        await AdaptiveCardHelper.RefreshCardAsync(turnContext, companyResponseEntity.ActivityId, attachment);

                        // Get user notification attachment and send it to user for approved request.
                        userNotification = MessageFactory.Attachment(UserCard.GetNotificationCardForApprovedRequest(companyResponseEntity, localizer: this.localizer));

                        var result = await this.conversationStorageProvider.GetConversationEntityAsync(companyResponseEntity.UserId);

                        if (result != null)
                        {
                            await AdaptiveCardHelper.SendNotificationCardAsync(turnContext, userNotification, result.ConversationId, cancellationToken);

                            // Tracking for number of requests approved.
                            this.RecordEvent(ApprovedRequestEventName, turnContext);
                        }
                        else
                        {
                            this.logger.LogInformation("Unable to send notification card for approved request because conversation id is null.");
                        }
                    }
                    else
                    {
                        this.logger.LogInformation("Unable to approve the request.");
                    }

                    break;

                case Constants.RejectCommand:

                    companyResponseEntity = this.companyStorageHelper.AddRejectedData(cardPostedData, activity.From.Name, activity.From.AadObjectId);
                    var rejectRequestResult = this.companyResponseStorageProvider.UpsertConverationStateAsync(companyResponseEntity).GetAwaiter().GetResult();

                    if (rejectRequestResult)
                    {
                        // Get user notification rejected card attachment.
                        var attachment = AdminCard.GetRefreshedCardForRejectedRequest(companyResponseEntity, activity.From.Name, localizer: this.localizer);
                        await AdaptiveCardHelper.RefreshCardAsync(turnContext, companyResponseEntity.ActivityId, attachment);

                        // Send end user notification for approved request.
                        userNotification = MessageFactory.Attachment(UserCard.GetNotificationCardForRejectedRequest(companyResponseEntity, localizer: this.localizer));

                        var result = await this.conversationStorageProvider.GetConversationEntityAsync(companyResponseEntity.UserId);

                        if (result != null)
                        {
                            await AdaptiveCardHelper.SendNotificationCardAsync(turnContext, userNotification, result.ConversationId, cancellationToken);

                            // Tracking for number of requests rejected.
                            this.RecordEvent(RejectedRequestEventName, turnContext);
                        }
                        else
                        {
                            this.logger.LogInformation("Unable to send notification card for rejected request because conversation id is null.");
                        }
                    }
                    else
                    {
                        this.logger.LogInformation("Unable to reject the request.");
                    }

                    return;

                default:
                    this.logger.LogInformation("Unrecognized input in channel");
                    break;
                }
            }
            catch (Exception ex)
            {
                this.logger.LogError(ex, $"Error processing message: {ex.Message}", SeverityLevel.Error);
                throw;
            }
        }