public override LexResponse Process()

in Blueprints/BlueprintDefinitions/vs2017/LexBookTripSample/template/src/BlueprintBaseName.1/BookCarIntentProcessor.cs [30:215]


        public override LexResponse Process(LexEvent lexEvent, ILambdaContext context)
        {

            var slots = lexEvent.CurrentIntent.Slots;
            var sessionAttributes = lexEvent.SessionAttributes ?? new Dictionary<string, string>();

            Reservation reservation = new Reservation
            {
                ReservationType = "Car",
                PickUpCity = slots.ContainsKey(PICK_UP_CITY_SLOT) ? slots[PICK_UP_CITY_SLOT] : null,
                PickUpDate = slots.ContainsKey(PICK_UP_DATE_SLOT) ? slots[PICK_UP_DATE_SLOT] : null,
                ReturnDate = slots.ContainsKey(RETURN_DATE_SLOT) ? slots[RETURN_DATE_SLOT] : null,
                DriverAge = slots.ContainsKey(DRIVER_AGE_SLOT) ? slots[DRIVER_AGE_SLOT] : null,
                CarType = slots.ContainsKey(CAR_TYPE_SLOT) ? slots[CAR_TYPE_SLOT] : null,
            };

            string confirmationStaus = lexEvent.CurrentIntent.ConfirmationStatus;

            Reservation lastConfirmedReservation = null;
            if (slots.ContainsKey(LAST_CONFIRMED_RESERVATION_SESSION_ATTRIBUTE))
            {
                lastConfirmedReservation = DeserializeReservation(slots[LAST_CONFIRMED_RESERVATION_SESSION_ATTRIBUTE]);
            }

            string confirmationContext = sessionAttributes.ContainsKey("confirmationContext") ? sessionAttributes["confirmationContext"] : null;

            sessionAttributes[CURRENT_RESERVATION_SESSION_ATTRIBUTE] = SerializeReservation(reservation);

            var validateResult = Validate(reservation);
            context.Logger.LogLine($"Has required fields: {reservation.HasRequiredCarFields}, Has valid values {validateResult.IsValid}");
            if(!validateResult.IsValid)
            {
                context.Logger.LogLine($"Slot {validateResult.ViolationSlot} is invalid: {validateResult.Message?.Content}");
            }

            if (reservation.HasRequiredCarFields && validateResult.IsValid)
            {
                var price = GeneratePrice(reservation);
                context.Logger.LogLine($"Generated price: {price}");

                sessionAttributes[CURRENT_RESERVATION_PRICE_SESSION_ATTRIBUTE] = price.ToString(CultureInfo.InvariantCulture);
            }
            else
            {
                sessionAttributes.Remove(CURRENT_RESERVATION_PRICE_SESSION_ATTRIBUTE);
            }

            if (string.Equals(lexEvent.InvocationSource, "DialogCodeHook", StringComparison.Ordinal))
            {
                // If any slots are invalid, re-elicit for their value
                if (!validateResult.IsValid)
                {
                    slots[validateResult.ViolationSlot] = null;
                    return ElicitSlot(sessionAttributes, lexEvent.CurrentIntent.Name, slots, validateResult.ViolationSlot, validateResult.Message);
                }

                // Determine if the intent (and current slot settings) have been denied.  The messaging will be different
                // if the user is denying a reservation they initiated or an auto-populated suggestion.
                if (string.Equals(lexEvent.CurrentIntent.ConfirmationStatus, "Denied", StringComparison.Ordinal))
                {
                    sessionAttributes.Remove("confirmationContext");
                    sessionAttributes.Remove(CURRENT_RESERVATION_SESSION_ATTRIBUTE);

                    if (string.Equals(confirmationContext, "AutoPopulate", StringComparison.Ordinal))
                    {
                        return ElicitSlot(sessionAttributes,
                                            lexEvent.CurrentIntent.Name,
                                            new Dictionary<string, string>
                                            {
                                                {PICK_UP_CITY_SLOT, null },
                                                {PICK_UP_DATE_SLOT, null },
                                                {RETURN_DATE_SLOT, null },
                                                {DRIVER_AGE_SLOT, null },
                                                {CAR_TYPE_SLOT, null }
                                            },
                                            PICK_UP_CITY_SLOT,
                                            new LexResponse.LexMessage
                                            {
                                                ContentType = MESSAGE_CONTENT_TYPE,
                                                Content = "Where would you like to make your car reservation?"
                                            }
                                        );
                    }

                    return Delegate(sessionAttributes, slots);
                }

                if (string.Equals(lexEvent.CurrentIntent.ConfirmationStatus, "None", StringComparison.Ordinal))
                {
                    // If we are currently auto-populating but have not gotten confirmation, keep requesting for confirmation.
                    if ((!string.IsNullOrEmpty(reservation.PickUpCity)
                        && !string.IsNullOrEmpty(reservation.PickUpDate)
                        && !string.IsNullOrEmpty(reservation.ReturnDate)
                        && !string.IsNullOrEmpty(reservation.DriverAge)
                        && !string.IsNullOrEmpty(reservation.CarType)) || string.Equals(confirmationContext, "AutoPopulate", StringComparison.Ordinal))
                    {
                        if (lastConfirmedReservation != null &&
                            string.Equals(lastConfirmedReservation.ReservationType, "Hotel", StringComparison.Ordinal))
                        {
                            // If the user's previous reservation was a hotel - prompt for a rental with
                            // auto-populated values to match this reservation.
                            sessionAttributes["confirmationContext"] = "AutoPopulate";
                            return ConfirmIntent(
                                    sessionAttributes,
                                    lexEvent.CurrentIntent.Name,
                                    new Dictionary<string, string>
                                    {
                                        {PICK_UP_CITY_SLOT, lastConfirmedReservation.PickUpCity },
                                        {PICK_UP_DATE_SLOT, lastConfirmedReservation.CheckInDate },
                                        {RETURN_DATE_SLOT, DateTime.Parse(lastConfirmedReservation.CheckInDate).AddDays(int.Parse(lastConfirmedReservation.Nights)).ToUniversalTime().ToString(CultureInfo.InvariantCulture) },
                                        {CAR_TYPE_SLOT, null },
                                        {DRIVER_AGE_SLOT, null },
                                    },
                                    new LexResponse.LexMessage
                                    {
                                        ContentType = MESSAGE_CONTENT_TYPE,
                                        Content = $"Is this car rental for your {lastConfirmedReservation.Nights} night stay in {lastConfirmedReservation.Location} on {lastConfirmedReservation.CheckInDate}?"
                                    }
                                );
                        }
                    }

                    // Otherwise, let native DM rules determine how to elicit for slots and/or drive confirmation.
                    return Delegate(sessionAttributes, slots);
                }

                // If confirmation has occurred, continue filling any unfilled slot values or pass to fulfillment.
                if (string.Equals(lexEvent.CurrentIntent.ConfirmationStatus, "Confirmed", StringComparison.Ordinal))
                {
                    // Remove confirmationContext from sessionAttributes so it does not confuse future requests
                    sessionAttributes.Remove("confirmationContext");
                    if (string.Equals(confirmationContext, "AutoPopulate", StringComparison.Ordinal))
                    {
                        if (!string.IsNullOrEmpty(reservation.DriverAge))
                        {
                            return ElicitSlot(sessionAttributes,
                                                lexEvent.CurrentIntent.Name,
                                                slots,
                                                DRIVER_AGE_SLOT,
                                                new LexResponse.LexMessage
                                                {
                                                    ContentType = MESSAGE_CONTENT_TYPE,
                                                    Content = "How old is the driver of this car rental?"
                                                }
                                             );
                        }
                        else if (string.IsNullOrEmpty(reservation.CarType))
                        {
                            return ElicitSlot(sessionAttributes,
                                                lexEvent.CurrentIntent.Name,
                                                slots,
                                                CAR_TYPE_SLOT,
                                                new LexResponse.LexMessage
                                                {
                                                    ContentType = MESSAGE_CONTENT_TYPE,
                                                    Content = "What type of car would you like? Popular models are economy, midsize, and luxury."
                                                }
                                             );
                        }
                    }

                    return Delegate(sessionAttributes, slots);
                }
            }

            context.Logger.LogLine($"Book car at = {SerializeReservation(reservation)}");

            if (sessionAttributes.ContainsKey(CURRENT_RESERVATION_PRICE_SESSION_ATTRIBUTE))
            {
                context.Logger.LogLine($"Book car price = {sessionAttributes[CURRENT_RESERVATION_PRICE_SESSION_ATTRIBUTE]}");
            }

            sessionAttributes.Remove(CURRENT_RESERVATION_PRICE_SESSION_ATTRIBUTE);
            sessionAttributes.Remove(CURRENT_RESERVATION_SESSION_ATTRIBUTE);
            sessionAttributes[LAST_CONFIRMED_RESERVATION_SESSION_ATTRIBUTE] = SerializeReservation(reservation);

            return Close(
                        sessionAttributes,
                        "Fulfilled",
                        new LexResponse.LexMessage
                        {
                            ContentType = MESSAGE_CONTENT_TYPE,
                            Content = "Thanks, I have placed your reservation."
                        }
                    );
        }