/// <summary> /// Every conversation turn for our Echo Bot will call this method. /// There are no dialogs used, since it's "single turn" processing, meaning a single /// request and response. /// </summary> /// <param name="turnContext">A <see cref="ITurnContext"/> containing all the data needed /// for processing this conversation turn. </param> /// <param name="cancellationToken">(Optional) A <see cref="CancellationToken"/> that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A <see cref="Task"/> that represents the work queued to execute.</returns> /// <seealso cref="BotStateSet"/> /// <seealso cref="ConversationState"/> /// <seealso cref="IMiddleware"/> public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) { var activity = turnContext.Activity; var dc = await Dialogs.CreateContextAsync(turnContext); if (activity.Type == ActivityTypes.Message) { //wit.ai var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer HOIR6SSBSW2D65ZVRL274P2JQRR5ZTHD"); var date = DateTime.Now.ToString("yyyyMMdd"); var message = HttpUtility.UrlEncode(activity.Text); var url = $"https://api.wit.ai/message?v={date}&q={message}"; var json = await httpClient.GetStringAsync(new Uri(url)); var witResults = JsonConvert.DeserializeObject <WitResult>(json); var topIntent = GetWitIntent(witResults); await UpdateOrderingState(witResults, dc.Context); var interrupted = await IsTurnInterruptedAsync(dc, topIntent); if (interrupted) { await _conversationState.SaveChangesAsync(turnContext); await _userState.SaveChangesAsync(turnContext); return; } var dialogResult = await dc.ContinueDialogAsync(); if (!dc.Context.Responded) { switch (dialogResult.Status) { case DialogTurnStatus.Empty: switch (topIntent) { case OrderingIntent: await dc.BeginDialogAsync(nameof(OrderingDialog)); break; case NoneIntent: default: await dc.Context.SendActivityAsync("I didn't understand what you just said to me."); break; } break; case DialogTurnStatus.Waiting: break; case DialogTurnStatus.Complete: await dc.EndDialogAsync(); break; default: await dc.CancelAllDialogsAsync(); break; } } } else if (activity.Type == ActivityTypes.ConversationUpdate) { if (activity.MembersAdded != null) { foreach (var member in activity.MembersAdded) { if (member.Id != activity.Recipient.Id) { var welcomeCard = GetHeroCard().ToAttachment(); // CreateAdaptiveCardAttachment(); var response = CreateResponse(activity, welcomeCard); await dc.Context.SendActivityAsync(response); } } } } await _conversationState.SaveChangesAsync(turnContext); await _userState.SaveChangesAsync(turnContext); }
protected async Task ExitTurnAsync(ITurnContext turnContext) { await _conversationState.SaveChangesAsync(turnContext); await _userState.SaveChangesAsync(turnContext); }
public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) { var activity = turnContext.Activity; await UpdateUserState(turnContext); // Create a dialog context var dc = await Dialogs.CreateContextAsync(turnContext); if (activity.Type == ActivityTypes.Message) { var luisResults = await services.LuisServices[LuisConfiguration] .RecognizeAsync(dc.Context, cancellationToken); var topScoringIntent = luisResults?.GetTopScoringIntent(); var topIntent = topScoringIntent.Value.intent; await UpdatePriceState(luisResults, dc.Context); await UpdateUpdaterState(luisResults, dc.Context); var interrupted = await IsTurnInterruptedAsync(dc, topIntent); if (interrupted) { // Bypass the dialog. Save state before the next turn. await conversationState.SaveChangesAsync(turnContext); await userState.SaveChangesAsync(turnContext); return; } // Continue the current dialog var dialogResult = await dc.ContinueDialogAsync(); // if no one has responded, if (!dc.Context.Responded) { // examine results from active dialog switch (dialogResult.Status) { case DialogTurnStatus.Empty: switch (topIntent) { case PriceIntent: await dc.BeginDialogAsync(nameof(PriceDialog)); break; case TermsIntent: await dc.BeginDialogAsync(nameof(PrivacyDialog)); break; case PortfolioIntent: await dc.BeginDialogAsync(nameof(PortfolioDialog)); break; case UpdaterIntent: await dc.BeginDialogAsync(nameof(UpdaterDialog)); break; case NoneIntent: default: // Help or no intent identified, either way, let's provide some help. // to the user await dc.Context.SendActivityAsync("I didn't understand what you just said to me."); break; } break; case DialogTurnStatus.Waiting: break; // The active dialog is waiting for a response from the user, so do nothing. case DialogTurnStatus.Complete: await dc.EndDialogAsync(); break; default: await dc.CancelAllDialogsAsync(); break; } } } else if (activity.Type == ActivityTypes.ConversationUpdate) { if (activity.MembersAdded != null) { foreach (var member in activity.MembersAdded) { if (member.Id != activity.Recipient.Id) { await GreetNewUser(dc); } } } } await conversationState.SaveChangesAsync(turnContext); await userState.SaveChangesAsync(turnContext); }
public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) { // If user come from webchat bot should get user info if (turnContext.Activity.Name == "webchat/join") { await turnContext.SendActivityAsync( $"{Messages.Greetings}, {turnContext.Activity.From.Id}. {Environment.NewLine} {Messages.IntroducingMessage}", cancellationToken : cancellationToken); await turnContext.SendActivityAsync(Messages.HelpMessage, cancellationToken : cancellationToken); await turnContext.SendActivityAsync(Messages.WhatCanIDo, cancellationToken : cancellationToken); } // Classic reaction to message if (turnContext.Activity.Type == ActivityTypes.Message) { // Found intent from the input var luisResults = await _services.LuisServices[LuisConfiguration] .RecognizeAsync(turnContext, cancellationToken); var entities = luisResults.Entities.ToString(); var topScoringIntent = luisResults?.GetTopScoringIntent(); var topIntent = topScoringIntent.Value.intent; var onTurnState = new OnTurnState(topIntent, luisResults.Entities); await _onTurnAccessor.SetAsync(turnContext, onTurnState); // Create dialog context. var dc = await Dialogs.CreateContextAsync(turnContext); // Continue outstanding dialogs. await dc.ContinueDialogAsync(); // Begin main dialog if no outstanding dialogs/ no one responded. if (!dc.Context.Responded) { await dc.BeginDialogAsync(nameof(MainDispatcher)); } } else if (turnContext.Activity.ChannelId == "emulator" && turnContext.Activity.Type == ActivityTypes.ConversationUpdate) { if (turnContext.Activity.MembersAdded != null) { // Iterate over all new members added to the conversation foreach (var member in turnContext.Activity.MembersAdded) { // Greet anyone that was not the target (recipient) of this message // the 'bot' is the recipient for events from the channel, // turnContext.Activity.MembersAdded == turnContext.Activity.Recipient.Id indicates the // bot was added to the conversation. if (member.Id != turnContext.Activity.Recipient.Id) { await turnContext.SendActivityAsync( $"{Messages.Greetings}, {turnContext.Activity.From.Id}. {Environment.NewLine} {Messages.IntroducingMessage}", cancellationToken : cancellationToken); await turnContext.SendActivityAsync(Messages.HelpMessage, cancellationToken : cancellationToken); await turnContext.SendActivityAsync(Messages.WhatCanIDo, cancellationToken : cancellationToken); } } } } await _conversationState.SaveChangesAsync(turnContext); await _userState.SaveChangesAsync(turnContext); }
public Task SaveUserStateChangesAsync(ITurnContext turnContext) => UserState.SaveChangesAsync(turnContext);
public async Task ScenarioWithInspectionMiddlwareOpenAttach() { // Arrange // any bot state should be returned as trace messages per turn var storage = new MemoryStorage(); var inspectionState = new InspectionState(storage); var userState = new UserState(storage); var conversationState = new ConversationState(storage); // set up the middleware with an http client that will just record the traffic - we are expecting the trace activities here var recordingHttpClient = new RecordingHttpMessageHandler(); var inspectionMiddleware = new TestInspectionMiddleware( inspectionState, userState, conversationState, new HttpClient(recordingHttpClient)); // Act // (1) send the /INSPECT open command from the emulator to the middleware var openActivity = MessageFactory.Text("/INSPECT open"); var inspectionAdapter = new TestAdapter(Channels.Test, true); await inspectionAdapter.ProcessActivityAsync(openActivity, async (turnContext, cancellationToken) => { await inspectionMiddleware.ProcessCommandAsync(turnContext); }); var inspectionOpenResultActivity = inspectionAdapter.ActiveQueue.Dequeue(); // (2) send the resulting /INSPECT attach command from the channel to the middleware var applicationAdapter = new TestAdapter(Channels.Test, true); applicationAdapter.Use(inspectionMiddleware); var attachCommand = inspectionOpenResultActivity.Value.ToString(); await applicationAdapter.ProcessActivityAsync(MessageFactory.Text(attachCommand), async (turnContext, cancellationToken) => { // nothing happens - just attach the inspector await Task.CompletedTask; }); var attachResponse = applicationAdapter.ActiveQueue.Dequeue(); // (3) send an application messaage from the channel, it should get the reply and then so should the emulator http endpioint await applicationAdapter.ProcessActivityAsync(MessageFactory.Text("hi"), async (turnContext, cancellationToken) => { await turnContext.SendActivityAsync(MessageFactory.Text($"echo: {turnContext.Activity.Text}")); (await userState.CreateProperty <Scratch>("x").GetAsync(turnContext, () => new Scratch())).Property = "hello"; (await conversationState.CreateProperty <Scratch>("y").GetAsync(turnContext, () => new Scratch())).Property = "world"; await userState.SaveChangesAsync(turnContext); await conversationState.SaveChangesAsync(turnContext); }); // Assert var outboundActivity = applicationAdapter.ActiveQueue.Dequeue(); Assert.AreEqual("echo: hi", outboundActivity.Text); Assert.AreEqual(3, recordingHttpClient.Requests.Count); var inboundTrace = JObject.Parse(recordingHttpClient.Requests[0]); Assert.AreEqual("trace", inboundTrace["type"].ToString()); Assert.AreEqual("ReceivedActivity", inboundTrace["name"].ToString()); Assert.AreEqual("message", inboundTrace["value"]["type"].ToString()); Assert.AreEqual("hi", inboundTrace["value"]["text"].ToString()); var outboundTrace = JObject.Parse(recordingHttpClient.Requests[1]); Assert.AreEqual("trace", outboundTrace["type"].ToString()); Assert.AreEqual("SentActivity", outboundTrace["name"].ToString()); Assert.AreEqual("message", outboundTrace["value"]["type"].ToString()); Assert.AreEqual("echo: hi", outboundTrace["value"]["text"].ToString()); var stateTrace = JObject.Parse(recordingHttpClient.Requests[2]); Assert.AreEqual("trace", stateTrace["type"].ToString()); Assert.AreEqual("BotState", stateTrace["name"].ToString()); Assert.AreEqual("hello", stateTrace["value"]["userState"]["x"]["Property"].ToString()); Assert.AreEqual("world", stateTrace["value"]["conversationState"]["y"]["Property"].ToString()); }
public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default) { if (turnContext.Activity.Type == ActivityTypes.Message) { var dialogContext = await _dialogs.CreateContextAsync(turnContext, cancellationToken); var results = await dialogContext.ContinueDialogAsync(cancellationToken); var channelData = JObject.Parse(turnContext.Activity.ChannelData.ToString()); if (channelData.ContainsKey("postBack")) { // This is from an adaptive card postback var activity = turnContext.Activity; activity.Text = activity.Value.ToString(); } var userChoice = turnContext.Activity.Text; var responseMessage = $"You chose: '{turnContext.Activity.Text}'\n"; switch (results.Status) { case DialogTurnStatus.Empty: if (!string.IsNullOrWhiteSpace(userChoice)) { switch (userChoice) { case "1": await dialogContext.BeginDialogAsync("dummy", null, cancellationToken); break; case "2": await dialogContext.BeginDialogAsync("whenNextIntent", null, cancellationToken); break; case "3": await dialogContext.BeginDialogAsync("dummy", null, cancellationToken); break; case "4": await dialogContext.BeginDialogAsync("setTimezoneIntent", null, cancellationToken); break; default: await turnContext.SendActivityAsync("Please select a menu option"); await DisplayMainMenuAsync(turnContext, cancellationToken); break; } } break; case DialogTurnStatus.Cancelled: await DisplayMainMenuAsync(turnContext, cancellationToken); break; case DialogTurnStatus.Waiting: await dialogContext.ContinueDialogAsync(cancellationToken); break; case DialogTurnStatus.Complete: await _userState.SaveChangesAsync(turnContext, false, cancellationToken); await DisplayMainMenuAsync(turnContext, cancellationToken); break; } // Save the new turn count into the conversation state. await _converationState.SaveChangesAsync(turnContext); await _userState.SaveChangesAsync(turnContext, false, cancellationToken); // var userSelections = await UserSelectionsState.GetAsync(turnContext, () => new UserSelections(), cancellationToken); } else if (turnContext.Activity.Type == ActivityTypes.ConversationUpdate) { if (turnContext.Activity.MembersAdded != null) { await SendWelcomeMessageAsync(turnContext, cancellationToken); } } else { await turnContext.SendActivityAsync($"{turnContext.Activity.Type} event detected"); } }
/// <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) { // Perform a call to LUIS to retrieve results for the current activity message. var luisResults = await _services.LuisServices[LuisConfiguration].RecognizeAsync(dc.Context, cancellationToken).ConfigureAwait(false); // If any entities were updated, treat as interruption. // For example, "no my name is tony" will manifest as an update of the name to be "tony". var topScoringIntent = luisResults?.GetTopScoringIntent(); var topIntent = topScoringIntent.Value.intent; // update greeting state with any entities captured await UpdateGreetingState(luisResults, dc.Context); // Handle conversation interrupts first. var interrupted = await IsTurnInterruptedAsync(dc, topIntent); if (interrupted) { // Bypass the dialog. // Save state before the next turn. await _conversationState.SaveChangesAsync(turnContext); await _userState.SaveChangesAsync(turnContext); return; } // Continue the current dialog var dialogResult = await dc.ContinueDialogAsync(); // if no one has responded, if (!dc.Context.Responded) { // examine results from active dialog switch (dialogResult.Status) { case DialogTurnStatus.Empty: switch (topIntent) { case GreetingIntent: await dc.BeginDialogAsync(nameof(GreetingDialog)); break; case NoneIntent: default: // Help or no intent identified, either way, let's provide some help. // to the user await dc.Context.SendActivityAsync("I didn't understand what you just said to me."); 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.Any()) { // 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).ConfigureAwait(false); } } } } await _conversationState.SaveChangesAsync(turnContext); await _userState.SaveChangesAsync(turnContext); }
public async Task SaveChangesAsync(ITurnContext turnContext) { await _userState.SaveChangesAsync(turnContext); }
public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken) { var activity = turnContext.Activity; var dc = await Dialogs.CreateContextAsync(turnContext); var conversationReference = activity.GetConversationReference(); await _activeConversationsStore.Check(conversationReference); if (activity.Type == ActivityTypes.Message) { var luisResults = await _services.LuisServices[LuisConfiguration].RecognizeAsync(dc.Context, cancellationToken); var topScoringIntent = luisResults?.GetTopScoringIntent(); var topIntent = topScoringIntent.Value.intent; await _greetingStateStore.UpdateGreetingState(luisResults, dc.Context); if (await AcceptCommand(dc, topIntent)) { await _conversationState.SaveChangesAsync(turnContext); await _userState.SaveChangesAsync(turnContext); return; // Bypass the dialog. } var dialogResult = await dc.ContinueDialogAsync(); // if no one has responded, if (!dc.Context.Responded) // TODO: Check if we need `else` block { switch (dialogResult.Status) { case DialogTurnStatus.Empty: switch (topIntent) { case Intents.Greeting: var greetingState = await _greetingStateAccessor.GetAsync(turnContext, () => new GreetingState()); if (!greetingState.SayingGreetingRecently()) { await dc.BeginDialogAsync(nameof(GreetingDialog)); } if (greetingState.Completed()) { await dc.BeginDialogAsync(nameof(AnswerDialog)); } break; case Intents.Start: await dc.BeginDialogAsync(nameof(AnswerDialog)); break; case Intents.Target: await dc.BeginDialogAsync(nameof(TargetSetupDialog)); break; case Intents.Advice: await dc.BeginDialogAsync(nameof(AdviceDialog)); break; default: await dc.Context.Senddd("I didn't understand what you just said to me."); 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) { foreach (var member in activity.MembersAdded) { if (member.Id != activity.Recipient.Id) { await dc.Context.Senddd("Welcome new user"); await dc.Context.Senddd("Please, type **?** or **help** to list available commands"); } else { await _activeConversationsStore.RemoveOldConversations(conversationReference.User.Id); } } } await _activeConversationsStore.SaveReference(conversationReference); } await _conversationState.SaveChangesAsync(turnContext); await _userState.SaveChangesAsync(turnContext); }
/// <summary> /// Every conversation turn for our Echo Bot will call this method. /// There are no dialogs used, since it's "single turn" processing, meaning a single /// request and response. /// </summary> /// <param name="turnContext">A <see cref="ITurnContext"/> containing all the data needed /// for processing this conversation turn. </param> /// <param name="cancellationToken">(Optional) A <see cref="CancellationToken"/> that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A <see cref="Task"/> that represents the work queued to execute.</returns> /// <seealso cref="BotStateSet"/> /// <seealso cref="ConversationState"/> /// <seealso cref="IMiddleware"/> public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) { var activity = turnContext.Activity; var dc = await Dialogs.CreateContextAsync(turnContext); if (activity.Type == ActivityTypes.Message) { var luisResults = await _services.LuisServices[LuisConfiguration].RecognizeAsync(dc.Context, cancellationToken); var topScoringIntent = luisResults?.GetTopScoringIntent(); var topIntent = topScoringIntent.Value.intent; await UpdateOrderingState(luisResults, dc.Context); var interrupted = await IsTurnInterruptedAsync(dc, topIntent); if (interrupted) { await _conversationState.SaveChangesAsync(turnContext); await _userState.SaveChangesAsync(turnContext); return; } var dialogResult = await dc.ContinueDialogAsync(); if (!dc.Context.Responded) { switch (dialogResult.Status) { case DialogTurnStatus.Empty: switch (topIntent) { case OrderingIntent: await dc.BeginDialogAsync(nameof(OrderingDialog)); break; case NoneIntent: default: await dc.Context.SendActivityAsync("I didn't understand what you just said to me."); break; } break; case DialogTurnStatus.Waiting: break; case DialogTurnStatus.Complete: await dc.EndDialogAsync(); break; default: await dc.CancelAllDialogsAsync(); break; } } } else if (activity.Type == ActivityTypes.ConversationUpdate) { if (activity.MembersAdded != null) { foreach (var member in activity.MembersAdded) { if (member.Id != activity.Recipient.Id) { var welcomeCard = GetHeroCard().ToAttachment(); // CreateAdaptiveCardAttachment(); var response = CreateResponse(activity, welcomeCard); await dc.Context.SendActivityAsync(response); } } } } await _conversationState.SaveChangesAsync(turnContext); await _userState.SaveChangesAsync(turnContext); }
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) { // Perform a call to LUIS to retrieve results for the current activity message. var luisResults = await _services.LuisServices[LuisConfiguration].RecognizeAsync(dc.Context, cancellationToken); // If any entities were updated, treat as interruption. // For example, "no my name is tony" will manifest as an update of the name to be "tony". var topScoringIntent = luisResults?.GetTopScoringIntent(); var topIntent = topScoringIntent.Value.intent; // update greeting state with any entities captured await UpdateGreetingState(luisResults, dc.Context); string LuisEntity = luisResults.Entities.ToString(); LuisEntityModel cityToFind = JsonConvert.DeserializeObject <LuisEntityModel>(LuisEntity); // Handle conversation interrupts first. var interrupted = await IsTurnInterruptedAsync(dc, topIntent); if (interrupted) { // Bypass the dialog. // Save state before the next turn. await _conversationState.SaveChangesAsync(turnContext); await _userState.SaveChangesAsync(turnContext); return; } // Continue the current dialog var dialogResult = await dc.ContinueDialogAsync(); // if no one has responded, if (!dc.Context.Responded) { // examine results from active dialog switch (dialogResult.Status) { case DialogTurnStatus.Empty: switch (topIntent.ToString()) { case "Greeting": await dc.BeginDialogAsync(nameof(GreetingDialog)); break; case "Weather_GetCondition": OWeatherMap weathergetter = new OWeatherMap(); string weatherResult = await weathergetter.GetWeatherData(cityToFind.Weather_Location[0]); await turnContext.SendActivityAsync(weatherResult); break; case "None": default: // Help or no intent identified, either way, let's provide some help. // to the user await dc.Context.SendActivityAsync("I didn't understand what you just said to me."); 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) { foreach (var member in activity.MembersAdded) { if (member.Id != activity.Recipient.Id) { var welcomeCard = CreateAdaptiveCardAttachment(); var response = CreateResponse(activity, welcomeCard); await dc.Context.SendActivityAsync(response); } } } } await _conversationState.SaveChangesAsync(turnContext); await _userState.SaveChangesAsync(turnContext); }
/// <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) { // Perform a call to LUIS to retrieve results for the current activity message. var luisResults = await _services.LuisServices[LuisConfiguration].RecognizeAsync(dc.Context, cancellationToken).ConfigureAwait(false); var qnaResult = await _services.QnAServices[QnAMakerKey].GetAnswersAsync(turnContext).ConfigureAwait(false); if (qnaResult != null && qnaResult.Length > 0) { await turnContext.SendActivityAsync(qnaResult[0].Answer, cancellationToken : cancellationToken); } //else //{ // var msg = @"No QnA Maker answers were found. This example uses a QnA Maker Knowledge Base that focuses on smart light bulbs. // To see QnA Maker in action, ask the bot questions like 'Why won't it turn on?' or 'I need help'."; // await turnContext.SendActivityAsync(msg, cancellationToken: cancellationToken); //} // If any entities were updated, treat as interruption. // For example, "no my name is tony" will manifest as an update of the name to be "tony". var topScoringIntent = luisResults?.GetTopScoringIntent(); var topIntent = topScoringIntent.Value.intent; // update greeting state with any entities captured //await UpdatePresentazioneState(luisResults, dc.Context); // Handle conversation interrupts first. var interrupted = await IsTurnInterruptedAsync(dc, topScoringIntent.Value.intent, topScoringIntent.Value.score); if (interrupted) { // Bypass the dialog. // Save state before the next turn. await _conversationState.SaveChangesAsync(turnContext); await _userState.SaveChangesAsync(turnContext); return; } // Continue the current dialog var dialogResult = await dc.ContinueDialogAsync(); // if no one has responded, if (!dc.Context.Responded) { // examine results from active dialog switch (dialogResult.Status) { case DialogTurnStatus.Empty: switch (topIntent) { case PrenotazioneIntent: await dc.BeginDialogAsync(nameof(Prenotazione)); break; case CancellaPrenotazioneIntent: await dc.BeginDialogAsync(nameof(CancellaPrenotazione)); break; case TempoRimanentePrenotazioneIntent: await dc.BeginDialogAsync(nameof(VisualizzaTempo)); break; case VerificaPrenotazioneIntent: await dc.BeginDialogAsync(nameof(VisualizzaPrenotazione)); break; case NoneIntent: default: // Help or no intent identified, either way, let's provide some help. // to the user string[] responses = { "Non capisco ciò che mi stai dicendo, mi spiace.", "Scusa? Non ti capisco mica...", "Ma che hai detto?!?", "Boh! Non ci ho capito nulla..", }; //rispsote possibili Random rnd = new Random(); //crea new Random class int i = rnd.Next(0, responses.Length); await dc.Context.SendActivityAsync(responses[i]); 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.Any()) { // 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).ConfigureAwait(false); } } } } await _conversationState.SaveChangesAsync(turnContext); await _userState.SaveChangesAsync(turnContext); }
/// <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) { // Perform a call to LUIS to retrieve results for the current activity message. var luisResults = await _services.LuisServices[LuisConfiguration].RecognizeAsync(dc.Context, cancellationToken); // If any entities were updated, treat as interruption. // For example, "no my name is tony" will manifest as an update of the name to be "tony". var topIntent = luisResults?.GetTopScoringIntent(); if (topIntent != null && topIntent.HasValue && topIntent.Value.intent != "None") { switch (topIntent.Value.intent) { case GetDocumentsForTagIntent: var topic = LUISDataUtilities.GetEntityAsString(luisResults, "Topic"); if (topic != null && topic.Length > 0) { await turnContext.SendActivityAsync(string.Format("You seem to be looking documents associated with {0}. Let me see what I can find.\n", topic)); var documentsGraphModel = GraphAnalysisBusinessLogic.GetDocumentsForTag(this, topic); if (documentsGraphModel.Count > 0) { await turnContext.SendActivityAsync(string.Format("I found the following documents associated with {0}:", topic)); var reply = turnContext.Activity.CreateReply(); reply.Attachments = new List <Attachment>(); //Put the most recent documents at the head of the list //documentsGraphModel.Reverse(); foreach (var document in documentsGraphModel) { // var attachment = new Attachment // { // ContentUrl = string.Format("{0}{1}/{2}?web=1", document.properties.library[0].value, document.properties.path[0].value, document.properties.name[0].value), // Name = document.properties.name[0].value, // }; // reply.Attachments.Add(attachment); //await turnContext.SendActivityAsync(string.Format("{1}{2}/{3}?web=1", document.properties.name[0].value, document.properties.library[0].value, document.properties.path[0].value, document.properties.name[0].value).Replace(" ", "%20")); List <CardAction> cardButtons = new List <CardAction>(); CardAction plButton = new CardAction() { Value = string.Format("{1}{2}/{3}?web=1", document.properties.name[0].value, document.properties.library[0].value, document.properties.path[0].value, document.properties.name[0].value).Replace(" ", "%20"), Type = "openUrl", Title = document.properties.name[0].value, }; cardButtons.Add(plButton); HeroCard plCard = new HeroCard() { //Title = document.properties.name[0].value, Buttons = cardButtons }; Attachment plAttachment = plCard.ToAttachment(); reply.Attachments.Add(plAttachment); } await turnContext.SendActivityAsync(reply); //var replyToConversation = turnContext.Activity.CreateReply(); //replyToConversation.AttachmentLayout = AttachmentLayoutTypes.Carousel; //replyToConversation.Attachments = new List<Attachment>(); //Dictionary<string, string> cardContentList = new Dictionary<string, string>(); //cardContentList.Add("PigLatin", "https://<ImageUrl1>"); //cardContentList.Add("Pork Shoulder", "https://<ImageUrl2>"); //cardContentList.Add("Bacon", "https://<ImageUrl3>"); ////Put the most recent entries first //foreach (var document in documentsGraphModel) //{ //} //foreach (KeyValuePair<string, string> cardContent in cardContentList) //{ // List<CardImage> cardImages = new List<CardImage>(); // cardImages.Add(new CardImage(url: cardContent.Value)); // List<CardAction> cardButtons = new List<CardAction>(); // CardAction plButton = new CardAction() // { // Value = $"https://en.wikipedia.org/wiki/{cardContent.Key}", // Type = "openUrl", // Title = "WikiPedia Page" // }; // cardButtons.Add(plButton); // HeroCard plCard = new HeroCard() // { // Title = $"I'm a hero card about {cardContent.Key}", // Subtitle = $"{cardContent.Key} Wikipedia Page", // Images = cardImages, // Buttons = cardButtons // }; // Attachment plAttachment = plCard.ToAttachment(); // replyToConversation.Attachments.Add(plAttachment); //} //await turnContext.SendActivityAsync(replyToConversation); } else { await turnContext.SendActivityAsync(string.Format("I did not find any documents associated with {0}.", topic)); } } break; case GetMattersIntent: await turnContext.SendActivityAsync($"Getting your matters. This may take a moment.\n"); var matterGraphModel = GraphAnalysisBusinessLogic.GetMatters(this); if (matterGraphModel.Count > 0) { await turnContext.SendActivityAsync("I found the following matters:"); foreach (var matter in matterGraphModel) { await turnContext.SendActivityAsync(matter.properties.name[0].value); } } else { await turnContext.SendActivityAsync("I did not find any matters."); } break; case GetRecentDocumentsIntent: await turnContext.SendActivityAsync($"Getting your recent documents. This may take a moment.\n"); break; case GreetingIntent: await turnContext.SendActivityAsync($"Hello, I'm Tagulous, CELA's knowledge management assistant. If you want to know what I can do as a question like \"How can you help me?\"\n"); break; case HelpIntent: await turnContext.SendActivityAsync($"You seem to be looking for some help. I am can do some basic things for you.\n"); await turnContext.SendActivityAsync($"Specifically, I can do the following, and I provide some examples of how you can ask for that service.\n"); await turnContext.SendActivityAsync($"Identifying the person who sends communications with the prescribed tag the most: _Who is our expert on privacy?_\n"); await turnContext.SendActivityAsync($"Listing the matters engaged through this system: _Please get my matters._\n"); await turnContext.SendActivityAsync($"Listing the documents associated with a tag: _Please get me documents associated with testing._\n"); break; case NoneIntent: break; case TagUsersIntent: await turnContext.SendActivityAsync($"Getting recent user activity. This may take a moment.\n"); break; case TopTagsIntent: //CommunicationProcessingBL.TransactGraphQuery(client, ) //await QueryAzureTableForMostUsedTags(turnContext, recognizerResult); break; case TopicExpert: await FindTopicExpert(turnContext, luisResults); break; default: await turnContext.SendActivityAsync($"==>LUIS Top Scoring Intent: {topIntent.Value.intent}, Score: {topIntent.Value.score}\n"); break; } } else { var msg = @"No LUIS intents were found. This sample is about identifying two user intents: 'Calendar.Add' 'Calendar.Find' Try typing 'Add Event' or 'Show me tomorrow'."; await turnContext.SendActivityAsync(msg); } } else if (activity.Type == ActivityTypes.ConversationUpdate) { await SendWelcomeMessageAsync(turnContext, cancellationToken); } await _conversationState.SaveChangesAsync(turnContext); await _userState.SaveChangesAsync(turnContext); }