public override LexResponse Process()

in Blueprints/BlueprintDefinitions/vs2022/LexBookTripSample/template/src/BlueprintBaseName.1/BookCarIntentProcessor.cs [28:213]


    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.LogInformation($"Has required fields: {reservation.HasRequiredCarFields}, Has valid values {validateResult.IsValid}");
        if(!validateResult.IsValid)
        {
            context.Logger.LogInformation($"Slot {validateResult.ViolationSlot} is invalid: {validateResult.Message?.Content}");
        }

        if (reservation.HasRequiredCarFields && validateResult.IsValid)
        {
            var price = GeneratePrice(reservation);
            context.Logger.LogInformation($"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.LogInformation($"Book car at = {SerializeReservation(reservation)}");

        if (sessionAttributes.ContainsKey(CURRENT_RESERVATION_PRICE_SESSION_ATTRIBUTE))
        {
            context.Logger.LogInformation($"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."
                    }
                );
    }