private async Task <DialogTurnResult> SearchAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { // Add state so we can update it throughout the turn var state = await _accessors.PictureState.GetAsync(stepContext.Context); // If we haven't stored what they want to search for if (state.Search == "") { // Store it and update the ConversationState state.Search = (string)stepContext.Result; await _accessors.ConversationState.SaveChangesAsync(stepContext.Context); } var searchText = state.Search; // Confirm with the user what you're searching for await SearchResponses.ReplyWithSearchConfirmation(stepContext.Context, searchText); // Process the search request and send the results to the user await StartAsync(stepContext.Context, searchText); // Clear out Search or future searches, set the searching state to no, // update the conversation state state.Search = ""; state.Searching = "no"; await _accessors.ConversationState.SaveChangesAsync(stepContext.Context); return(await stepContext.EndDialogAsync()); }
// You can start this from the parent using the dialog's ID. public SearchDialog() : base(Id) { // add search dialog contents here // Define the conversation flow using a waterfall model. this.Dialogs.Add(Id, new WaterfallStep[] { async(dc, args, next) => { // Prompt the user for what they want to search for. // Instead of using SearchResponses.ReplyWithSearchRequest, // we're experimenting with using text prompts await dc.Prompt("textPrompt", "What would you like to search for?"); }, async(dc, args, next) => { // Save search request as 'facet' var facet = args["Value"] as string; await SearchResponses.ReplyWithSearchConfirmation(dc.Context, facet); // Process the search request and send the results to the user await StartAsync(dc.Context, facet); // End the dialog await dc.End(); } }); // Define the prompts used in this conversation flow. this.Dialogs.Add("textPrompt", new TextPrompt()); }
private async Task <DialogTurnResult> SearchForModeratedContentRequestAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { await SearchResponses.ReplyWithSearchForModeratedContentConfirmation(stepContext.Context); await ExecuteSearchAsync(stepContext.Context, "*", "moderatedText eq true"); return(await stepContext.EndDialogAsync()); }
// below tasks are required to process the search text and return the results public async Task <bool> ProceedWithSearchAsync(ITurnContext context, string facet) { var userState = context.GetUserState <UserData>(); await SearchResponses.ReplyWithSearchConfirmation(context, facet); await StartAsync(context, facet); //end topic return(true); }
// Add ProcessSearchAsync below // below tasks are required to process the search text and return the results public async Task <bool> ProcessSearchAsync(ITurnContext context) { // store the users response searchText = (context.Activity.Text ?? "").Trim(); var userState = context.GetUserState <UserData>(); await SearchResponses.ReplyWithSearchConfirmation(context, searchText); await StartAsync(context); return(true); }
// Add SearchBing public async Task SearchBing(ITurnContext context, string searchText) { // Step 1: Call the Bing Image Search API //IMPORTANT: replace this variable with your Cognitive Services subscription key. string subscriptionKey = "YourBingKey"; //initialize the client var client = new ImageSearchAPI(new ApiKeyServiceClientCredentials(subscriptionKey)); //images to be returned by the Bing Image Search API Images imageResults = null; try { // Call the API and store the results imageResults = client.Images.SearchAsync(query: searchText).Result; //search query } catch (Exception ex) { // If there's an exception, return the error in the chat window await context.SendActivityAsync("Encountered exception. " + ex.Message); } // Step 2: Process the results and send to the user // If the API returns images if (imageResults != null) { // Parse out the first five images from ImageResults // Add the content URL to a simple message attachment var activity = MessageFactory.Attachment(new Attachment[] { new Attachment { ContentUrl = imageResults.Value[0].ContentUrl, ContentType = "image/png" }, new Attachment { ContentUrl = imageResults.Value[1].ContentUrl, ContentType = "image/png" }, new Attachment { ContentUrl = imageResults.Value[2].ContentUrl, ContentType = "image/png" }, new Attachment { ContentUrl = imageResults.Value[3].ContentUrl, ContentType = "image/png" }, new Attachment { ContentUrl = imageResults.Value[4].ContentUrl, ContentType = "image/png" } }); // Send the activity to the user. await SearchResponses.ReplyWithBingResults(context, searchText); await context.SendActivityAsync(activity); } else // If the API doesn't return any images { await SearchResponses.ReplyWithNoResults(context, searchText); } }
public List <SearchResultObject> ParseSearch(String Content) { // Parse search json DataContractJsonSerializer searchResponseJsonSerializer = new DataContractJsonSerializer(typeof(SearchResponse[])); SearchResponse[] SearchResponses; using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(Content))) { SearchResponses = searchResponseJsonSerializer.ReadObject(ms) as SearchResponse[]; } return((from mangaItem in ApiMangaList.Manga where SearchResponses.Count(sr => Equals(sr.URL, LanguageUrl(mangaItem.Alias))) > 0 select ToSearchResultObject(mangaItem)).ToList()); }
public async Task SendResultsAsync(ITurnContext context, DocumentSearchResult results) { IMessageActivity activity = context.Activity.CreateReply(); if (results.Results.Count == 0) { await SearchResponses.ReplyWithNoResults(context, facet); } else { SearchHitStyler searchHitStyler = new SearchHitStyler(); searchHitStyler.Apply( ref activity, "Here are the results that I found:", results.Results.Select(r => ImageMapper.ToSearchHit(r)).ToList().AsReadOnly()); await context.SendActivity(activity); } }
private async Task SendResultsAsync(ITurnContext context, string searchText, DocumentSearchResult results) { IMessageActivity activity = context.Activity.CreateReply(); if (!results.Results.Any()) { await SearchResponses.ReplyWithNoResults(context, searchText); } else { SearchHitStyler searchHitStyler = new SearchHitStyler(); searchHitStyler.Apply(ref activity, "Here are the results that i found", results.Results.Select(r => ImageMapper.ToSearchHit(r)).ToList().AsReadOnly()); await context.SendActivityAsync(activity); } }
private async Task <DialogTurnResult> SearchAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { // Add state so we can update it throughout the turn var state = await _accessors.PictureState.GetAsync(stepContext.Context); // If we haven't stored what they want to search for if (state.Search == "") { // Store it and update the ConversationState state.Search = (string)stepContext.Result; await _accessors.ConversationState.SaveChangesAsync(stepContext.Context); } var searchText = state.Search; // Confirm with the user what you're searching for await SearchResponses.ReplyWithSearchConfirmation(stepContext.Context, searchText); // Process the search request and send the results to the user await StartAsync(stepContext.Context, searchText); // Check if they want to search Bing if (state.Searching == "yes") { // update the searching state to "bing" state.Searching = "bing"; await _accessors.ConversationState.SaveChangesAsync(stepContext.Context); return(await stepContext.PromptAsync("bingPrompt", new PromptOptions { Prompt = MessageFactory.Text("Would you like to view the web results from Bing?"), Choices = ChoiceFactory.ToChoices(new List <string> { "Yes", "No" }), }, cancellationToken)); } else //if (state.Searching == "bing") // This means they just told us if they want to search Bing or not { // Go to the next step in the dialog, which is "SearchBingAsync" return(await stepContext.NextAsync()); } }
public async Task SendResultsAsync(ITurnContext context, string searchText, DocumentSearchResult results) { IMessageActivity activity = context.Activity.CreateReply(); // if the search returns no results if (results.Results.Count == 0) { await SearchResponses.ReplyWithNoResults(context, searchText); } else // this means there was at least one hit for the search { // create the response with the result(s) and send to the user SearchHitStyler searchHitStyler = new SearchHitStyler(); searchHitStyler.Apply( ref activity, "Here are the results that I found:", results.Results.Select(r => ImageMapper.ToSearchHit(r)).ToList().AsReadOnly()); await context.SendActivityAsync(activity); } }
private async Task <DialogTurnResult> SearchBingAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { // Add state so we can update it throughout the turn var state = await _accessors.PictureState.GetAsync(stepContext.Context); var searchText = state.Search; var searchbing = (string)stepContext.Result; switch (searchbing) { case "Yes": await SearchResponses.ReplyWithBingConfirmation(stepContext.Context, searchText); // add Bing Search await SearchBing(stepContext.Context, searchText); break; case "No": // End the dialog and wait for a response await SearchResponses.ReplyWithDontBing(stepContext.Context); break; default: await MainResponses.ReplyWithConfused(stepContext.Context); await MainResponses.ReplyWithHelp(stepContext.Context); break; } // Clear out Search or future searches, set the searching state to no, // update the conversation state state.Search = ""; state.Searching = "no"; await _accessors.ConversationState.SaveChangesAsync(stepContext.Context); return(await stepContext.EndDialogAsync()); }
private async Task <DialogTurnResult> SearchAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { PictureState state = await _accessors.PictureState.GetAsync(stepContext.Context); if (state.Search == string.Empty) { state.Search = (string)stepContext.Result; await _accessors.ConversationState.SaveChangesAsync(stepContext.Context); } var searchText = state.Search; await SearchResponses.ReplyWithSearchConfirmation(stepContext.Context, searchText); await StartAsync(stepContext.Context, searchText); state.Search = string.Empty; state.Searching = "no"; await _accessors.ConversationState.SaveChangesAsync(stepContext.Context); return(await stepContext.EndDialogAsync()); }
public async Task <bool> StartTopic(ITurnContext context) { switch (context.Activity.Type) { case ActivityTypes.Message: { // Ask them what they want to search for if we haven't already if (!RequestedForSearch) { await SearchResponses.ReplyWithSearchRequest(context); // Now that we've asked, set to true, so we don't ask again this.RequestedForSearch = true; return(true); } return(true); } default: break; } return(await this.ContinueTopic(context)); }
private async Task <DialogTurnResult> SearchAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { //Here is the main event! This method will utilize Azure Search //to find results that the user asked for. var state = await _accessors.PictureState.GetAsync(stepContext.Context, () => new PictureState()); //We can find the user's search two ways: // - As part of the state // - As the result coming to this step from a previous (Prompt) dialog //First, see if the query can be found on the "Search" property //of the state. If not, apply this stepcontext's result (as a string) //and update the conversation state var q = state.Search; if (string.IsNullOrWhiteSpace(q)) { q = stepContext.Result as string; state.Search = q; await _accessors.ConversationState.SaveChangesAsync(stepContext.Context); } //Next, establish a client using the helper method. //CTRL and click on this helper method to adjust for your service. var client = CreateSearchIndexClient(); //Call SearchAsync on this client's Documents property //to retrieve the search results var searchResponse = await client.Documents.SearchAsync(q); //If the response's results have a count of 0... // - Either give a failure message // - Or keep going and search on Bing if (searchResponse.Results.Count == 0) { await SearchResponses.ReplyWithNoResults(stepContext.Context, q); return(await stepContext.PromptAsync("bingPrompt", new PromptOptions { Prompt = MessageFactory.Text("Would you like to search on bing?") }, cancellationToken)); } else { //Otherwise, create a new activity to reply with IMessageActivity activity = stepContext.Context.Activity.CreateReply(); //Use the provided SearchHitStyler() class to apply //formatted results to the activity. //You will want to map the search response Results to a //list of SearchHit objects using the ImageMapper.ToSearchHit method var styler = new SearchHitStyler(); var options = searchResponse.Results.Select(r => ImageMapper.ToSearchHit(r)).ToList().AsReadOnly(); styler.Apply(ref activity, "Here are the results:", options); //Send the activity to the user await stepContext.Context.SendActivityAsync(activity, cancellationToken); } //In any case, reset the search flags //(be sure to save the conversation state!) //and end the dialog. We are done! This dialog pops //off of the stack and we are left with the main dialog. state.IsSearching = false; state.Search = string.Empty; await _accessors.ConversationState.SaveChangesAsync(stepContext.Context); return(await stepContext.EndDialogAsync()); }
/// <summary> /// Composes a main dialog for our bot. /// </summary> /// <returns>A new main dialog.</returns> private static DialogSet ComposeMainDialog() { var dialogs = new DialogSet(); dialogs.Add(RootDialog, new WaterfallStep[] { // Duplicate the following row if your dialog will have // multiple turns. In this case, we just have one async(dc, args, next) => { // Get the state of the conversation var conversation = ConversationState <ConversationInfo> .Get(dc.Context); // If Regex picks up on anything, store it var recognizedIntents = dc.Context.Services.Get <IRecognizedIntents>(); // Based on the recognized intent, direct the conversation switch (recognizedIntents.TopIntent?.Name) { case "search": // switch to SearchDialog await dc.Begin(SearchDialog.Id); break; case "share": // respond that you're sharing the photo await RootResponses.ReplyWithShareConfirmation(dc.Context); break; case "order": // respond that you're ordering await RootResponses.ReplyWithOrderConfirmation(dc.Context); break; case "help": // show help await RootResponses.ReplyWithHelp(dc.Context); break; default: // adding app logic when Regex doesn't find an intent - consult LUIS var result = dc.Context.Services.Get <RecognizerResult>(LuisRecognizerMiddleware.LuisRecognizerResultKey); var topIntent = result?.GetTopScoringIntent(); switch ((topIntent != null) ? topIntent.Value.intent : null) { case null: // Add app logic when there is no result. await RootResponses.ReplyWithConfused(dc.Context); break; case "None": await RootResponses.ReplyWithConfused(dc.Context); await RootResponses.ReplyWithLuisScore(dc.Context, topIntent.Value.intent, topIntent.Value.score); break; case "Greeting": await RootResponses.ReplyWithGreeting(dc.Context); await RootResponses.ReplyWithHelp(dc.Context); await RootResponses.ReplyWithLuisScore(dc.Context, topIntent.Value.intent, topIntent.Value.score); break; case "OrderPic": await RootResponses.ReplyWithOrderConfirmation(dc.Context); await RootResponses.ReplyWithLuisScore(dc.Context, topIntent.Value.intent, topIntent.Value.score); break; case "SharePic": await RootResponses.ReplyWithShareConfirmation(dc.Context); await RootResponses.ReplyWithLuisScore(dc.Context, topIntent.Value.intent, topIntent.Value.score); break; case "SearchPics": // Check if LUIS has identified the search term that we should look for. var entity = result?.Entities; var obj = JObject.Parse(JsonConvert.SerializeObject(entity)).SelectToken("facet"); // if no entities are picked up on by LUIS, go through SearchDialog if (obj == null) { await dc.Begin(SearchDialog.Id); await RootResponses.ReplyWithLuisScore(dc.Context, topIntent.Value.intent, topIntent.Value.score); } // if entities are picked up by LUIS, skip SearchDialog and process the search else { var facet = obj.ToString().Replace("\"", "").Trim(']', '[', ' '); await RootResponses.ReplyWithLuisScore(dc.Context, topIntent.Value.intent, topIntent.Value.score); await SearchResponses.ReplyWithSearchConfirmation(dc.Context, facet); await StartAsync(dc.Context, facet); break; } break; default: await RootResponses.ReplyWithConfused(dc.Context); break; } break; } } }); // Add our child dialogs (in this case just one) dialogs.Add(SearchDialog.Id, SearchDialog.Instance); return(dialogs); }
// This step routes the user to different dialogs // In this case, there's only one other dialog, so it is more simple, // but in more complex scenarios you can go off to other dialogs in a similar public async Task <DialogTurnResult> MainMenuAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { // Check if we are currently processing a user's search var state = await _accessors.PictureState.GetAsync(stepContext.Context); // If Regex picks up on anything, store it var recognizedIntents = stepContext.Context.TurnState.Get <IRecognizedIntents>(); // Based on the recognized intent, direct the conversation switch (recognizedIntents.TopIntent?.Name) { case "search": // switch to the search dialog return(await stepContext.BeginDialogAsync("searchDialog", null, cancellationToken)); case "share": // respond that you're sharing the photo await MainResponses.ReplyWithShareConfirmation(stepContext.Context); return(await stepContext.EndDialogAsync()); case "order": // respond that you're ordering await MainResponses.ReplyWithOrderConfirmation(stepContext.Context); return(await stepContext.EndDialogAsync()); case "help": // show help await MainResponses.ReplyWithHelp(stepContext.Context); return(await stepContext.EndDialogAsync()); default: { // Call LUIS recognizer var result = await _recognizer.RecognizeAsync(stepContext.Context, cancellationToken); // Get the top intent from the results var topIntent = result?.GetTopScoringIntent(); // Based on the intent, switch the conversation, similar concept as with Regex above switch ((topIntent != null) ? topIntent.Value.intent : null) { case null: // Add app logic when there is no result. await MainResponses.ReplyWithConfused(stepContext.Context); break; case "None": await MainResponses.ReplyWithConfused(stepContext.Context); // with each statement, we're adding the LuisScore, purely to test, so we know whether LUIS was called or not await MainResponses.ReplyWithLuisScore(stepContext.Context, topIntent.Value.intent, topIntent.Value.score); break; case "Greeting": await MainResponses.ReplyWithGreeting(stepContext.Context); await MainResponses.ReplyWithHelp(stepContext.Context); await MainResponses.ReplyWithLuisScore(stepContext.Context, topIntent.Value.intent, topIntent.Value.score); break; case "OrderPic": await MainResponses.ReplyWithOrderConfirmation(stepContext.Context); await MainResponses.ReplyWithLuisScore(stepContext.Context, topIntent.Value.intent, topIntent.Value.score); break; case "SharePic": await MainResponses.ReplyWithShareConfirmation(stepContext.Context); await MainResponses.ReplyWithLuisScore(stepContext.Context, topIntent.Value.intent, topIntent.Value.score); break; case "SearchPics": var seachCriteria = result.Entities["facet"].HasValues? result.Entities["facet"].First.ToString() : ""; await SearchResponses.ReplyWithSearchConfirmation(stepContext.Context, seachCriteria); await MainResponses.ReplyWithLuisScore(stepContext.Context, topIntent.Value.intent, topIntent.Value.score); break; default: await MainResponses.ReplyWithConfused(stepContext.Context); break; } return(await stepContext.EndDialogAsync()); } } }