private async Task <Activity> GetQnAResponse(string query, ITurnContext turnContext) { Activity outputActivity = null; var newState = new QnABotState(); var qnaState = await _qnaStateAccessor.GetAsync(turnContext, () => new QnABotState()); var qnaResult = await this.qnAServiceHelper.QueryQnAService(query, qnaState, turnContext); var qnaAnswer = qnaResult[0].Answer; if (string.Equals(qnaAnswer, "No good match found in KB.", StringComparison.OrdinalIgnoreCase)) { qnaAnswer = "I didn't understand what you just said to me."; } var prompts = qnaResult[0].Context?.Prompts; if (prompts == null || prompts.Length < 1) { outputActivity = MessageFactory.Text(qnaAnswer); InQnaMaker = false; } else { // Set bot state only if prompts are found in QnA result newState.PreviousQnaId = qnaResult[0].Id; newState.PreviousUserQuery = query; outputActivity = CardHelper.GetHeroCard(qnaAnswer, prompts); } await _qnaStateAccessor.SetAsync(turnContext, newState); return(outputActivity); }
/// <summary> /// Run every turn of the conversation. Handles orchestration of messages. /// </summary> /// <param name="turnContext">Bot Turn Context.</param> /// <param name="cancellationToken">Task CancellationToken.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken) { var activity = turnContext.Activity; // Create a dialog context var dc = await Dialogs.CreateContextAsync(turnContext); if (activity.Type == ActivityTypes.Message) { // Checks if status is currently inside QnA Maker multi turn situation if (InQnaMaker) { var qnaResponse = await this.GetQnAResponse(activity.Text, turnContext); await turnContext.SendActivityAsync(qnaResponse); await _conversationState.SaveChangesAsync(turnContext); await _userState.SaveChangesAsync(turnContext); return; } // Perform a call to LUIS to retrieve results for the current activity message. // Until LUIS API v3 is integrated, we will call the v3 endpoint directly using a created service var luisResults = await luisServiceV3.PredictLUIS(turnContext.Activity.Text, dc.Context); // Continue the current dialog var dialogResult = await dc.ContinueDialogAsync(); // if no one has responded, if (!dc.Context.Responded) { // loop through all the LUIS predictions, these can be single or multiple if multi-intent is enabled foreach (var response in luisResults) { var topIntent = response.Intent; // examine results from active dialog switch (dialogResult.Status) { case DialogTurnStatus.Empty: switch (topIntent) { case PurchaseTicket: var purchaseTicketResponse = laLigaBL.PurchaseTicket(response); await turnContext.SendActivityAsync(CardHelper.GetLUISHeroCard(purchaseTicketResponse, LaLigaBL.PictureType.Ticket)); break; case FindMatchIntent: var findMatchResponse = laLigaBL.FindMatch(response); await turnContext.SendActivityAsync(CardHelper.GetLUISHeroCard(findMatchResponse.ResponseText, findMatchResponse.PictureType)); break; // Redirect to QnA if None intent is detected case NoneIntent: default: var qnaResponse = await GetQnAResponse(activity.Text, turnContext); await turnContext.SendActivityAsync(qnaResponse); InQnaMaker = true; break; } break; case DialogTurnStatus.Waiting: // The active dialog is waiting for a response from the user, so do nothing. break; case DialogTurnStatus.Complete: await dc.EndDialogAsync(); break; default: await dc.CancelAllDialogsAsync(); break; } } } } else if (activity.Type == ActivityTypes.ConversationUpdate) { if (activity.MembersAdded != null) { // Iterate over all new members added to the conversation. foreach (var member in activity.MembersAdded) { // Greet anyone that was not the target (recipient) of this message. // To learn more about Adaptive Cards, see https://aka.ms/msbot-adaptivecards for more details. if (member.Id != activity.Recipient.Id) { var welcomeCard = CreateAdaptiveCardAttachment(); var response = CreateResponse(activity, welcomeCard); await dc.Context.SendActivityAsync(response); } } } InQnaMaker = false; // Reset QnA Maker } await _conversationState.SaveChangesAsync(turnContext); await _userState.SaveChangesAsync(turnContext); }