Example #1
0
        private static async Task EvaluateAndRespondToSentimentAsync(ITurnContext <IMessageActivity> context, SentimentBatchResultItem sentiment, string languageCode, CancellationToken cancellationToken)
        {
            // If there's no Sentiment object or score value, quit now.
            if (sentiment?.Score == null)
            {
                return;
            }

            var sentimentResponse = string.Empty;

            try
            {
                // Score ranges from 0.0 to 1, with 4 decimals of precision
                if (sentiment.Score <= 0.1)
                {
                    // If the sentiment is lower than 3%, respond with apologies and recommend to reach out to support
                    sentimentResponse = "I'm sorry you're having problems. If you'd like to talk to a person, please email [email protected] and they will be able to assist further.";
                }
                else if (sentiment.Score >= 0.95)
                {
                    // if the sentiment is in the top 97%, respond with a reminder to leave a review for the app.
                    sentimentResponse = "I'm happy to see you're enjoying our services. Please consider leaving an app review after you're done today!";
                }

                // If there's no response needed, quit now.
                if (string.IsNullOrEmpty(sentimentResponse))
                {
                    return;
                }

                // Check to see if we need to translate the response.
                if (languageCode != "en")
                {
                    using (var translationClient = new TextTranslationServiceClient(SubscriptionKeys.TextTranslationServiceKey))
                    {
                        if (!string.IsNullOrEmpty(sentimentResponse))
                        {
                            var translationResult = await translationClient.TranslateAsync(sentimentResponse, languageCode);

                            var translatedSentimentResponse = translationResult.Translations.FirstOrDefault()?.Text;

                            if (!string.IsNullOrEmpty(translatedSentimentResponse))
                            {
                                // If we were able to translate the message, update the message we're sending.
                                sentimentResponse = translatedSentimentResponse;
                            }
                        }
                    }
                }

                // Reply with the sentiment response.
                await context.SendActivityAsync(MessageFactory.Text(sentimentResponse, sentimentResponse), cancellationToken);
            }
            catch (Exception ex)
            {
                var replyText = $"EvaluateAndRespondToSentimentAsync Exception: {ex.Message}";
                await context.SendActivityAsync(MessageFactory.Text(replyText, replyText), cancellationToken);
            }
        }
Example #2
0
        protected override async Task OnMessageActivityAsync(ITurnContext <IMessageActivity> context, CancellationToken cancellationToken)
        {
            var message = context.Activity;

            // To quickly test the bot after deploy to ensure the version we want is available.
            if (message.Text.ToLower().Equals("bot version"))
            {
                var version = typeof(SupportBot).Assembly.GetName().Version;

                var replyText = $"Art Gallery Support Assistant v{version?.Major}.{version?.Minor}.{version?.Build}.{version?.Revision}";
                await context.SendActivityAsync(MessageFactory.Text(replyText, replyText), cancellationToken);

                return;
            }

            // ******************************* Cognitive Services - Text Analysis API ******************************* //

            using var textAnalyticsClient = new TextAnalyticsClient(new TextAnalysisServiceClientCredentials(SubscriptionKeys.TextAnalysisServiceKey))
                  {
                      Endpoint = "https://eastus.api.cognitive.microsoft.com/"
                  };

            var langResult = await textAnalyticsClient.DetectLanguageAsync(false, new LanguageBatchInput(new List <LanguageInput>
            {
                new LanguageInput(id: "1", text: message.Text)
            }), cancellationToken : cancellationToken);

            await context.TraceActivityAsync("OnMessageActivity Trace", langResult, "LanguageResult", cancellationToken : cancellationToken);

            var languageCode = string.Empty;

            foreach (var document in langResult.Documents)
            {
                // Pick the language with the highest score
                var bestLanguage = document.DetectedLanguages?.OrderByDescending(l => l.Score).FirstOrDefault();

                if (string.IsNullOrEmpty(languageCode) && bestLanguage != null)
                {
                    languageCode = bestLanguage.Iso6391Name.ToLower();
                    await context.TraceActivityAsync("OnMessageActivity Trace", languageCode, "string", cancellationToken : cancellationToken);
                }
            }

            // If we couldn't detect language
            if (string.IsNullOrEmpty(languageCode))
            {
                var replyText = "We could not determine what language you're using. Please try again.";
                await context.SendActivityAsync(MessageFactory.Text(replyText, replyText), cancellationToken);

                return;
            }


            // ******************************* Cognitive Services - Text Translation API ******************************* //

            var query = string.Empty;

            // If the detected language was not English, translate it before sending to LUIS
            if (languageCode != "en")
            {
                try
                {
                    using var translationClient = new TextTranslationServiceClient(SubscriptionKeys.TextTranslationServiceKey);

                    var result = await translationClient.TranslateAsync(message.Text, "en");

                    var translatedQuery = result?.Translations?.FirstOrDefault()?.Text;

                    if (!string.IsNullOrEmpty(translatedQuery))
                    {
                        query = translatedQuery;
                    }
                }
                catch (Exception ex)
                {
                    var replyText = $"RespondWithTranslatedReply Exception: {ex.Message}";
                    await context.SendActivityAsync(MessageFactory.Text(replyText, replyText), cancellationToken);
                }
            }
            else
            {
                query = message.Text;
            }


            // ******************************* Cognitive Services - LUIS (Natural Language Understanding) API ******************************* //

            using var luisClient = new LUISRuntimeClient(new ApiKeyServiceClientCredentials(SubscriptionKeys.LuisPredictionKey));

            luisClient.Endpoint = SubscriptionKeys.LuisEndpoint;

            // Prepare a prediction request
            var predictionRequest = new PredictionRequest
            {
                Query = query
            };

            // Request a prediction, returns a PredictionResponse
            var predictionResponse = await luisClient.Prediction.GetSlotPredictionAsync(
                Guid.Parse(SubscriptionKeys.LuisAppId),
                "production",
                predictionRequest,
                verbose : true,
                showAllIntents : true,
                log : true,
                cancellationToken : cancellationToken);

            // You will get a full list of intents. For the purposes of this demo, we'll just use the highest scoring intent.
            var topScoringIntent = predictionResponse.Prediction.TopIntent;

            // Respond to the user depending on the detected intent of their query
            var respondedToQuery = await RespondWithEnglishAsync(context, topScoringIntent, languageCode, cancellationToken);


            // ******************************* Cognitive Services - Sentiment Analysis  ******************************* //

            // Only evaluate sentiment if we've given a meaningful reply (and not connection or service error messages).
            if (respondedToQuery)
            {
                // Use Text Analytics Sentiment analysis
                var sentimentResult = await textAnalyticsClient.SentimentAsync(
                    multiLanguageBatchInput : new MultiLanguageBatchInput(new List <MultiLanguageInput>
                {
                    new MultiLanguageInput(id: "1", text: query, language: languageCode)
                }),
                    cancellationToken : cancellationToken);


                if (sentimentResult?.Documents?.Count > 0)
                {
                    await context.TraceActivityAsync("SentimentAsync Trace", sentimentResult.Documents[0], "SentimentBatchResultItem", cancellationToken : cancellationToken);

                    SentimentBatchResultItem sentimentItem = sentimentResult.Documents[0];

                    // Use the sentiment score to determine if we need to react, the range is 0 (angriest) to 1 (happiest)
                    await EvaluateAndRespondToSentimentAsync(context, sentimentItem, languageCode, cancellationToken);
                }
            }
        }