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());
        }
Example #2
0
        // 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());
        }
Example #3
0
        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());
        }
Example #4
0
        // 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);
        }
Example #5
0
        // 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);
        }
Example #6
0
        // 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);
            }
        }
Example #7
0
        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());
        }
Example #8
0
        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);
            }
        }
Example #9
0
        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);
            }
        }
Example #10
0
        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);
            }
        }
Example #12
0
        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());
        }
Example #13
0
        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());
        }
Example #14
0
        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));
        }
Example #15
0
        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());
        }
Example #16
0
        /// <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());
            }
            }
        }