in Blueprints/BlueprintDefinitions/vs2019/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."
}
);
}