Esempio n. 1
0
        /// <summary>
        /// Send card to SME channel and storage conversation details in storage.
        /// </summary>
        /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param>
        /// <param name="ticketDetail">Ticket details entered by user.</param>
        /// <param name="logger">Sends logs to the Application Insights service.</param>
        /// <param name="ticketDetailStorageProvider">Provider to store ticket details to Azure Table Storage.</param>
        /// <param name="applicationBasePath">Represents the Application base Uri.</param>
        /// <param name="cardElementMapping">Represents Adaptive card item element {Id, display name} mapping.</param>
        /// <param name="localizer">The current cultures' string localizer.</param>
        /// <param name="teamId">Represents unique id of a Team.</param>
        /// <param name="microsoftAppCredentials">Microsoft Application credentials for Bot/ME.</param>
        /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param>
        /// <returns>Returns message in a conversation.</returns>
        public static async Task <ConversationResourceResponse> SendRequestCardToSMEChannelAsync(
            ITurnContext <IMessageActivity> turnContext,
            TicketDetail ticketDetail,
            ILogger logger,
            ITicketDetailStorageProvider ticketDetailStorageProvider,
            string applicationBasePath,
            Dictionary <string, string> cardElementMapping,
            IStringLocalizer <Strings> localizer,
            string teamId,
            MicrosoftAppCredentials microsoftAppCredentials,
            CancellationToken cancellationToken)
        {
            Attachment smeTeamCard = new SmeTicketCard(ticketDetail).GetTicketDetailsForSMEChatCard(cardElementMapping, ticketDetail, applicationBasePath, localizer);
            ConversationResourceResponse resourceResponse = await SendCardToTeamAsync(turnContext, smeTeamCard, teamId, microsoftAppCredentials, cancellationToken);

            if (resourceResponse == null)
            {
                logger.LogError("Error while sending card to team.");
                return(null);
            }

            // Update SME team conversation details in storage.
            ticketDetail.SmeTicketActivityId = resourceResponse.ActivityId;
            ticketDetail.SmeConversationId   = resourceResponse.Id;
            bool result = await ticketDetailStorageProvider?.UpsertTicketAsync(ticketDetail);

            if (!result)
            {
                logger.LogError("Error while saving SME conversation details in storage.");
            }

            return(resourceResponse);
        }
        // Handle adaptive card submit in 1:1 chat
        // Submits the question or feedback to the SME team
        private async Task OnAdaptiveCardSubmitInPersonalChatAsync(IMessageActivity message, ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            Attachment   smeTeamCard = null;    // Notification to SME team
            Attachment   userCard    = null;    // Acknowledgement to the user
            TicketEntity newTicket   = null;    // New ticket

            this.telemetryClient.TrackTrace($"Otro envio: {message.Text}");

            switch (message.Text)
            {
            case AskAnExpert:
            {
                this.telemetryClient.TrackTrace("Sending user ask an expert card (from answer)");

                var responseCardPayload = ((JObject)message.Value).ToObject <ResponseCardPayload>();
                await turnContext.SendActivityAsync(MessageFactory.Attachment(AskAnExpertCard.GetCard(responseCardPayload)));

                break;
            }

            case ShareFeedback:
            {
                this.telemetryClient.TrackTrace("Sending user share feedback card (from answer)");

                var responseCardPayload = ((JObject)message.Value).ToObject <ResponseCardPayload>();
                await turnContext.SendActivityAsync(MessageFactory.Attachment(ShareFeedbackCard.GetCard(responseCardPayload)));

                break;
            }

            case WelcomeMsg:
                this.telemetryClient.TrackTrace("The user as required the Welcome screen");
                var welcomeText = await this.configurationProvider.GetSavedEntityDetailAsync(ConfigurationEntityTypes.WelcomeMessageText);

                var userWelcomeCardAttachment = WelcomeCard.GetCard(welcomeText);
                await turnContext.SendActivityAsync(MessageFactory.Attachment(userWelcomeCardAttachment));

                break;

            case AskAnExpertCard.AskAnExpertSubmitText:
            {
                this.telemetryClient.TrackTrace($"Received question for expert");

                var askAnExpertPayload = ((JObject)message.Value).ToObject <AskAnExpertCardPayload>();

                // Validate required fields
                if (string.IsNullOrWhiteSpace(askAnExpertPayload.Title))
                {
                    var updateCardActivity = new Activity(ActivityTypes.Message)
                    {
                        Id           = turnContext.Activity.ReplyToId,
                        Conversation = turnContext.Activity.Conversation,
                        Attachments  = new List <Attachment> {
                            AskAnExpertCard.GetCard(askAnExpertPayload)
                        },
                    };
                    await turnContext.UpdateActivityAsync(updateCardActivity, cancellationToken);

                    return;
                }

                var userDetails = await this.GetUserDetailsInPersonalChatAsync(turnContext, cancellationToken);

                newTicket = await this.CreateTicketAsync(message, askAnExpertPayload, userDetails);

                smeTeamCard = new SmeTicketCard(newTicket).ToAttachment(message.LocalTimestamp);
                userCard    = new UserNotificationCard(newTicket).ToAttachment(Resource.NotificationCardContent, message.LocalTimestamp);
                break;
            }

            case ShareFeedbackCard.ShareFeedbackSubmitText:
            {
                this.telemetryClient.TrackTrace($"Received app feedback");

                var shareFeedbackPayload = ((JObject)message.Value).ToObject <ShareFeedbackCardPayload>();

                // Validate required fields
                if (!Enum.TryParse(shareFeedbackPayload.Rating, out FeedbackRating rating))
                {
                    var updateCardActivity = new Activity(ActivityTypes.Message)
                    {
                        Id           = turnContext.Activity.ReplyToId,
                        Conversation = turnContext.Activity.Conversation,
                        Attachments  = new List <Attachment> {
                            ShareFeedbackCard.GetCard(shareFeedbackPayload)
                        },
                    };
                    await turnContext.UpdateActivityAsync(updateCardActivity, cancellationToken);

                    return;
                }

                var userDetails = await this.GetUserDetailsInPersonalChatAsync(turnContext, cancellationToken);

                smeTeamCard = SmeFeedbackCard.GetCard(shareFeedbackPayload, userDetails);
                await turnContext.SendActivityAsync(MessageFactory.Text(Resource.ThankYouTextContent));

                break;
            }

            default:
                this.telemetryClient.TrackTrace($"Unexpected text in submit payload: {message.Text}", SeverityLevel.Warning);
                break;
            }

            // Send message to SME team
            if (smeTeamCard != null)
            {
                var channelId = await this.configurationProvider.GetSavedEntityDetailAsync(ConfigurationEntityTypes.TeamId);

                var resourceResponse = await this.SendCardToTeamAsync(turnContext, smeTeamCard, channelId, cancellationToken);

                // If a ticket was created, update the ticket with the conversation info
                if (newTicket != null)
                {
                    newTicket.SmeCardActivityId       = resourceResponse.ActivityId;
                    newTicket.SmeThreadConversationId = resourceResponse.Id;
                    await this.ticketsProvider.SaveOrUpdateTicketAsync(newTicket);
                }
            }

            // Send acknowledgment to the user
            if (userCard != null)
            {
                await turnContext.SendActivityAsync(MessageFactory.Attachment(userCard), cancellationToken);
            }
        }
        /// <summary>
        /// Handle adaptive card submit in 1:1 chat.
        /// Submits the question or feedback to the SME team.
        /// </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>
        public async Task SendAdaptiveCardInPersonalChatAsync(
            IMessageActivity message,
            ITurnContext <IMessageActivity> turnContext,
            CancellationToken cancellationToken)
        {
            Attachment   smeTeamCard = null;    // Notification to SME team
            Attachment   userCard    = null;    // Acknowledgement to the user
            TicketEntity newTicket   = null;    // New ticket

            string text = (message.Text ?? string.Empty).Trim();

            switch (text)
            {
            // Sends user ask an expert card from the answer card.
            case Constants.AskAnExpert:
                this.logger.LogInformation("Sending user ask an expert card (from answer)");
                var askAnExpertPayload = ((JObject)message.Value).ToObject <ResponseCardPayload>();
                await this.SendActivityInChatAsync(turnContext, MessageFactory.Attachment(AskAnExpertCard.GetCard(askAnExpertPayload)), cancellationToken);

                break;

            // Sends user the feedback card from the answer card.
            case Constants.ShareFeedback:
                this.logger.LogInformation("Sending user share feedback card (from answer)");
                var shareFeedbackPayload = ((JObject)message.Value).ToObject <ResponseCardPayload>();
                await this.SendActivityInChatAsync(turnContext, MessageFactory.Attachment(ShareFeedbackCard.GetCard(shareFeedbackPayload)), cancellationToken);

                break;

            // User submits the ask an expert card.
            case Constants.AskAnExpertSubmitText:
                this.logger.LogInformation("Received question for expert");
                newTicket = await AdaptiveCardHelper.AskAnExpertSubmitText(message, turnContext, cancellationToken, this.ticketsProvider).ConfigureAwait(false);

                if (newTicket != null)
                {
                    smeTeamCard = new SmeTicketCard(newTicket).ToAttachment();
                    userCard    = new UserNotificationCard(newTicket).ToAttachment(Strings.NotificationCardContent);
                }

                break;

            // User submits the share feedback card.
            case Constants.ShareFeedbackSubmitText:
                this.logger.LogInformation("Received app feedback");
                smeTeamCard = await AdaptiveCardHelper.ShareFeedbackSubmitText(message, turnContext, cancellationToken).ConfigureAwait(false);

                if (smeTeamCard != null)
                {
                    await this.SendActivityInChatAsync(turnContext, MessageFactory.Text(Strings.ThankYouTextContent), cancellationToken);
                }

                break;

            default:
                var payload = ((JObject)message.Value).ToObject <ResponseCardPayload>();

                if (payload.IsPrompt)
                {
                    this.logger.LogInformation("Sending input to QnAMaker for prompt");
                    await this.qnaPairServiceFacade.GetReplyToQnAAsync(turnContext, message).ConfigureAwait(false);
                }
                else
                {
                    this.logger.LogWarning($"Unexpected text in submit payload: {message.Text}");
                }

                break;
            }

            string expertTeamId = await this.configurationProvider.GetSavedEntityDetailAsync(ConfigurationEntityTypes.TeamId).ConfigureAwait(false);

            // Send message to SME team.
            if (smeTeamCard != null)
            {
                await this.SendTicketCardToSMETeamAsync(turnContext, smeTeamCard, expertTeamId, cancellationToken, newTicket);
            }

            // Send acknowledgment to the user
            if (userCard != null)
            {
                await this.SendActivityInChatAsync(turnContext, MessageFactory.Attachment(userCard), cancellationToken);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Handle adaptive card submit in 1:1 chat.
        /// Submits the question or feedback to the SME team.
        /// </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 OnAdaptiveCardSubmitInPersonalChatAsync(
            IMessageActivity message,
            ITurnContext <IMessageActivity> turnContext,
            CancellationToken cancellationToken)
        {
            Attachment   smeTeamCard = null;    // Notification to SME team
            Attachment   userCard    = null;    // Acknowledgement to the user
            TicketEntity newTicket   = null;    // New ticket

            switch (message?.Text)
            {
            case Constants.AskAnExpert:
                this.logger.LogInformation("Sending user ask an expert card (from answer)");
                var askAnExpertPayload = ((JObject)message.Value).ToObject <ResponseCardPayload>();
                await turnContext.SendActivityAsync(MessageFactory.Attachment(AskAnExpertCard.GetCard(askAnExpertPayload))).ConfigureAwait(false);

                break;

            case Constants.ShareFeedback:
                this.logger.LogInformation("Sending user share feedback card (from answer)");
                var shareFeedbackPayload = ((JObject)message.Value).ToObject <ResponseCardPayload>();
                await turnContext.SendActivityAsync(MessageFactory.Attachment(ShareFeedbackCard.GetCard(shareFeedbackPayload))).ConfigureAwait(false);

                break;

            case AskAnExpertCard.AskAnExpertSubmitText:
                this.logger.LogInformation("Received question for expert");
                newTicket = await AdaptiveCardHelper.AskAnExpertSubmitText(message, turnContext, cancellationToken, this.ticketsProvider).ConfigureAwait(false);

                if (newTicket != null)
                {
                    smeTeamCard = new SmeTicketCard(newTicket).ToAttachment(message?.LocalTimestamp);
                    userCard    = new UserNotificationCard(newTicket).ToAttachment(Strings.NotificationCardContent, message?.LocalTimestamp);
                }

                break;

            case ShareFeedbackCard.ShareFeedbackSubmitText:
                this.logger.LogInformation("Received app feedback");
                smeTeamCard = await AdaptiveCardHelper.ShareFeedbackSubmitText(message, turnContext, cancellationToken).ConfigureAwait(false);

                if (smeTeamCard != null)
                {
                    await turnContext.SendActivityAsync(MessageFactory.Text(Strings.ThankYouTextContent)).ConfigureAwait(false);
                }

                break;

            default:
                var payload = ((JObject)message.Value).ToObject <ResponseCardPayload>();

                if (payload.IsPrompt)
                {
                    this.logger.LogInformation("Sending input to QnAMaker for prompt");
                    await this.GetQuestionAnswerReplyAsync(turnContext, message).ConfigureAwait(false);
                }
                else
                {
                    this.logger.LogWarning($"Unexpected text in submit payload: {message.Text}");
                }

                break;
            }

            string expertTeamId = await this.configurationProvider.GetSavedEntityDetailAsync(ConfigurationEntityTypes.TeamId).ConfigureAwait(false);

            // Send message to SME team.
            if (smeTeamCard != null)
            {
                var resourceResponse = await this.SendCardToTeamAsync(turnContext, smeTeamCard, expertTeamId, cancellationToken).ConfigureAwait(false);

                // If a ticket was created, update the ticket with the conversation info.
                if (newTicket != null)
                {
                    newTicket.SmeCardActivityId       = resourceResponse.ActivityId;
                    newTicket.SmeThreadConversationId = resourceResponse.Id;
                    await this.ticketsProvider.UpsertTicketAsync(newTicket).ConfigureAwait(false);
                }
            }

            // Send acknowledgment to the user
            if (userCard != null)
            {
                await turnContext.SendActivityAsync(MessageFactory.Attachment(userCard), cancellationToken).ConfigureAwait(false);
            }
        }