Ejemplo n.º 1
0
        /// <summary>
        /// Prompt for Restaurant to book.
        /// </summary>
        /// <param name="sc">Waterfall Step Context.</param>
        /// <param name="cancellationToken">Cancellation Token.</param>
        /// <returns>Dialog Turn Result.</returns>
        private async Task <DialogTurnResult> AskForRestaurant(WaterfallStepContext sc, CancellationToken cancellationToken)
        {
            var state = await Accessor.GetAsync(sc.Context);

            var reservation = state.Booking;

            if (reservation.Location != null)
            {
                return(await sc.NextAsync(sc.Values, cancellationToken));
            }

            // Reset the dialog if the user hasn't confirmed the reservation.
            if (!reservation.Confirmed)
            {
                state.Booking = CreateNewReservationInfo();
                return(await sc.ReplaceDialogAsync(Id, cancellationToken : cancellationToken));
            }

            // Prompt for restaurant
            var restaurants = SeedReservationSampleData.GetListOfRestaurants(reservation.Category, "London", _urlResolver);

            state.Restaurants = restaurants;

            var restaurantOptionsForSpeak = new StringBuilder();

            for (var i = 0; i < restaurants.Count; i++)
            {
                restaurantOptionsForSpeak.Append(restaurants[i].Name);
                restaurantOptionsForSpeak.Append(i == restaurants.Count - 2 ? $" {BotStrings.Or} " : ", ");
            }

            var restaurantResponse = RestaurantBookingSharedResponses.BookRestaurantRestaurantSelectionPrompt;

            var tokens = new StringDictionary
            {
                { "RestaurantCount", (restaurants.Count - 1).ToString() },
                { "ServerUrl", _urlResolver.ServerUrl },
                { "RestaurantList", restaurantOptionsForSpeak.ToString() }
            };

            var cardData = new List <TitleImageTextButtonCardData>();

            restaurants.ForEach(r => cardData.Add(
                                    new TitleImageTextButtonCardData
            {
                ImageUrl         = r.PictureUrl,
                ImageSize        = AdaptiveImageSize.Stretch,
                ImageAlign       = AdaptiveHorizontalAlignment.Stretch,
                ButtonTitle      = r.Name,
                ButtonSubtitle   = r.Location,
                SelectedItemData = r.Name
            }));

            var reply = sc.Context.Activity.CreateAdaptiveCardGroupReply(
                restaurantResponse, @"Dialogs\RestaurantBooking\Resources\Cards\TitleImageTextButton.json", AttachmentLayoutTypes.Carousel, cardData, ResponseBuilder, tokens);

            return(await sc.PromptAsync(Actions.RestaurantPrompt, new PromptOptions { Prompt = reply }, cancellationToken));
        }
Ejemplo n.º 2
0
        private async Task <bool> ValidateRestaurantSelection(PromptValidatorContext <FoundChoice> promptContext, CancellationToken cancellationToken)
        {
            var state = await ConversationStateAccessor.GetAsync(promptContext.Context, cancellationToken : cancellationToken);

            // This is a workaround to a known issue with Adaptive Card button responses and prompts whereby the "Text" of the adaptive card button response
            // is put into a Value object not the Text as expected causing prompt validation to fail.
            // If the prompt was about to fail and the Value property is set with Text set to NULL we do special handling.
            if (!promptContext.Recognized.Succeeded && (promptContext.Context.Activity.Value != null) && string.IsNullOrEmpty(promptContext.Context.Activity.Text))
            {
                dynamic value          = promptContext.Context.Activity.Value;
                string  promptResponse = value["selectedItem"];  // The property will be named after your choice set's ID

                if (!string.IsNullOrEmpty(promptResponse))
                {
                    // Override what the prompt has done
                    promptContext.Recognized.Succeeded = true;
                    var foundChoice = new FoundChoice
                    {
                        Value = promptResponse
                    };
                    promptContext.Recognized.Value = foundChoice;
                }
            }

            if (promptContext.Recognized.Succeeded)
            {
                var restaurants = SeedReservationSampleData.GetListOfRestaurants(state.Booking.Category, "London", _urlResolver);
                var restaurant  = restaurants.First(r => r.Name == promptContext.Recognized.Value.Value);
                if (restaurant != null)
                {
                    state.Booking.BookingPlace = restaurant;

                    var reply = TemplateManager.GenerateActivity(RestaurantBookingSharedResponses.BookRestaurantBookingPlaceSelectionEcho, new Dictionary <string, object> {
                        { "BookingPlaceName", restaurant.Name }
                    });
                    await promptContext.Context.SendActivityAsync(reply, cancellationToken);

                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Prompt for Restaurant to book.
        /// </summary>
        /// <param name="sc">Waterfall Step Context.</param>
        /// <param name="cancellationToken">Cancellation Token.</param>
        /// <returns>Dialog Turn Result.</returns>
        private async Task <DialogTurnResult> AskForRestaurantAsync(WaterfallStepContext sc, CancellationToken cancellationToken)
        {
            var state = await ConversationStateAccessor.GetAsync(sc.Context, cancellationToken : cancellationToken);

            var reservation = state.Booking;

            if (state.IsAction)
            {
                return(await sc.NextAsync(cancellationToken : cancellationToken));
            }

            // Reset the dialog if the user hasn't confirmed the reservation.
            if (!reservation.Confirmed)
            {
                state.Booking = CreateNewReservationInfo();
                return(await sc.EndDialogAsync(cancellationToken : cancellationToken));
            }

            // Prompt for restaurant
            var restaurants = SeedReservationSampleData.GetListOfRestaurants(reservation.Category, "London", _urlResolver);

            state.Restaurants = restaurants;

            var restaurantOptionsForSpeak = new StringBuilder();

            for (var i = 0; i < restaurants.Count; i++)
            {
                restaurantOptionsForSpeak.Append(restaurants[i].Name);
                restaurantOptionsForSpeak.Append(i == restaurants.Count - 2 ? $" {TemplateManager.GetString(BotStrings.Or)} " : ", ");
            }

            var tokens = new Dictionary <string, object>
            {
                { "RestaurantCount", restaurants.Count.ToString() },
                { "ServerUrl", _urlResolver.ServerUrl },
                { "RestaurantList", restaurantOptionsForSpeak.ToString() }
            };

            var cards   = new List <Card>();
            var options = new PromptOptions()
            {
                Choices = new List <Choice>(),
            };

            foreach (var restaurant in restaurants)
            {
                cards.Add(new Card(
                              GetDivergedCardName(sc.Context, "RestaurantChoiceCard"),
                              new RestaurantChoiceCardData
                {
                    ImageUrl         = restaurant.PictureUrl,
                    ImageSize        = AdaptiveImageSize.Stretch,
                    ImageAlign       = AdaptiveHorizontalAlignment.Stretch,
                    Name             = restaurant.Name,
                    Title            = restaurant.Name,
                    Location         = restaurant.Location,
                    SelectedItemData = restaurant.Name
                }));

                options.Choices.Add(new Choice(restaurant.Name));
            }

            var replyMessage = TemplateManager.GenerateActivity(RestaurantBookingSharedResponses.BookRestaurantRestaurantSelectionPrompt, cards, tokens);

            return(await sc.PromptAsync(Actions.RestaurantPrompt, new PromptOptions { Prompt = replyMessage, Choices = options.Choices }, cancellationToken));
        }