Amazon Lex Model Building Using the Java SDK

As an initial post, we will explore Amazon Lex through the use of Amazon’s Java SDK.  We’ll do this by referring to the OrderFlowers example in the Amazon Lex Developers guide that uses the CLI and show the equivalent calls using only the Java SDK.

Step 1: Use AWS Credenitials to create a Lex Model Building client
// Create LexModelBuilding client
 AWSCredentials awsCreds = new BasicAWSCredentials("YOURACCESSKEY",//IAM user's ACCESS_KEY
                                                   "CORRESPONDINGSeCretKEY");//IAM user's SECRET_KEY

AmazonLexModelBuilding modelBuildingClient = AmazonLexModelBuildingClientBuilder.standard()
 .withRegion(Regions.US_EAST_1)
 .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
 .build();

 

Step 2: Create a Custom Slot Type

We will start with creating a new PutSlotTypeRequest:

 
 PutSlotTypeRequest putSlotTypeRequest = new PutSlotTypeRequest().withName("FlowerTypes")
                                                   .withDescription("Types of flowers to pick up");

For clarity, this example will create the the specified objects in the context of the FlowerTypes.json file used in the CLI example, where FlowerTypes.json is:

{ "enumerationValues": [ {"value": "tulips"}, 
                         {"value": "lilies"}, 
                         {"value": "roses"} ], 
  "name": "FlowerTypes", 
  "description": "Types of flowers to pick up" }
 // create EnumerationValue list 
EnumerationValue enumValue; 
List<EnumerationValue> enumerationValues = new ArrayList<>(); 
enumValue = new EnumerationValue().withValue("tulips"); 
enumerationValues.add(enumValue); 
enumValue = new EnumerationValue().withValue("lilies"); 
enumerationValues.add(enumValue); 
enumValue = new EnumerationValue().withValue("roses"); 
enumerationValues.add(enumValue); 
// add EnumerationValue list to PutSlotTypeRequest 
putSlotTypeRequest.setEnumerationValues(enumerationValues);

PutSlotTypeRequest now complete.  Issue the request to create the FlowerTypes Slot Type.

 PutSlotTypeResult putSlotTypeResult = modelBuildingClient.putSlotType(putSlotTypeRequest);

 

Step 3: Create an Intent

Note: includes specification of slots, sample utterances, confirmation prompts, dialog code hooks, et.al.

We will start with creating a new PutIntentRequest:

PutIntentRequest putIntentRequest = new PutIntentRequest().withName("OrderFlowers");

We create the the specified objects in the context of the OrderFlowers.json file used in the CLI example, where OrderFlowers.json is:

{ 
   "confirmationPrompt": 
      { "maxAttempts": 2, 
        "messages": [ 
                     { "content": "Okay, your {FlowerType} will be ready for pickup by {PickupTime} on {PickupDate}.  Does this sound okay?", 
                       "contentType": "PlainText" } 
                    ] 
      },

 

// configure confirmationPrompt 
Prompt confirmationPrompt = new Prompt(); 
confirmationPrompt.setMaxAttempts(2); 
List<Message> confirmationPromptMessageList = new ArrayList<>(); 
Message confirmationPromptMessage = new Message().withContent("Okay, your {FlowerType} will be ready for pickup by {PickupTime} on {PickupDate}.  Does this sound okay?")
                                                 .withContentType(ContentType.PlainText); 
confirmationPromptMessageList.add(confirmationPromptMessage); 
confirmationPrompt.setMessages(confirmationPromptMessageList); 
// end of confirmationPrompt configuration, add to putIntentRequest 
putIntentRequest.setConfirmationPrompt(confirmationPrompt);

continuing with OrderFlowers.json for the rejection statement definition:

"name": "OrderFlowers", (Note: this was specified at the time of PutIntentRequest creation.  See above.) 
"rejectionStatement": 
        { "messages": [ 
                       { "content": "Okay, I will not place your order.", 
                         "contentType": "PlainText" } 
                      ] 
        },
 // configure rejectionStatement 
Statement rejectionStatement = new Statement(); 
List<Message> rejectionStatementMessageList = new ArrayList<>(); 
Message rejectionStatementMessage = new Message().withContent("Okay, I will not place your order.")
                                                 .withContentType(ContentType.PlainText); 
rejectionStatementMessageList.add(rejectionStatementMessage); 
rejectionStatement.setMessages(rejectionStatementMessageList); 
// end of rejectionStatement configuration, add to putIntentRequest 
putIntentRequest.setRejectionStatement(rejectionStatement);

continuing with OrderFlowers.json:

"sampleUtterances": [ "I would like to pick up flowers", 
                      "I would like to order some flowers" ],
// configure sampleUtterances 
List<String> sampleUtterances = new ArrayList<>(); 
sampleUtterances.add("I would like to pick up flowers"); 
sampleUtterances.add("I would like to order some flowers"); 
// end of sampleUtterances configuration, add to putIntentRequest 
putIntentRequest.setSampleUtterances(sampleUtterances);

back to OrderFlowers.json for the FlowerType slot definition:

 "slots": [ 
           { "slotType": "FlowerTypes", 
             "name": "FlowerType", 
             "slotConstraint": "Required", 
             "valueElicitationPrompt": { 
                       "maxAttempts": 2, 
                       "messages": [ 
                                    { "content": "What type of flowers would you like to order?", 
                                      "contentType": "PlainText" } 
                                   ] 
             }, 
             "priority": 1, 
             "slotTypeVersion": "$LATEST", 
             "sampleUtterances": [ "I would like to order {FlowerType}" ], 
             "description": "The type of flowers to pick up" 
           },

 

// create Slots list 
List<Slot> slots = new ArrayList<>();
// configure FlowerType slot 
Slot flowerTypeSlot = new Slot().withSlotType("FlowerTypes").withName("FlowerType").withConstraint(SlotContraint.Required); 
// configure valueElicitationPrompt for this slot 
Prompt valueElicitationPrompt = new Prompt(); 
valueElicitationPrompt.setMaxAttempts(2); 
List<Message> valueElicitationPromptMessageList = new ArrayList<>(); 
Message valueElicitationPromptMessage = new Message().withContent("What type of flowers would you like to order?")
                                                     .withContentType(ContentType.PlainText); 
valueElicitationPromptMessageList.add(confirmationPromptMessage); 
valueElicitationPrompt.setMessages(confirmationPromptMessageList); 
// add valueElicitationPrompt to slot 
flowerTypeSlot.setValueElicitationPrompt(valueElicitationPrompt); 
flowerTypeSlot.setPriority(1); 
flowerTypeSlot.setSlotTypeVersion("$LATEST"); 
flowerTypeSlot.setDescription("The type of flowers to pick up"); 
// configure sampleUtterances for this slot 
List<String> slotSampleUtterances = new ArrayList<>(); 
slotSampleUtterances.add("I would like to order {FlowerType}"); 
// end of slotSampleUtterances configuration, add to slot 
flowerTypeSlot.setSampleUtterances(slotSampleUtterances); 
// add slot to slots list 
slots.add(flowerTypeSlot);

back to OrderFlowers.json for the PickupDate slot definition:

{ "slotType": "AMAZON.DATE", 
  "name": "PickupDate", 
  "slotConstraint": "Required", 
  "valueElicitationPrompt": { 
               "maxAttempts": 2, 
               "messages": [ 
                    { "content": "What day do you want the {FlowerType} to be picked up?", 
                      "contentType": "PlainText" } 
                ] 
  }, 
  "priority": 2, 
  "description": "The date to pick up the flowers" 
},
// configure slot PickupDate slot
Slot pickupDateSlot = new Slot().withSlotType("AMAZON.DATE").withName("PickupDate")
                                .withConstraint(SlotContraint.Required);
// configure valueElicitationPrompt for this slot 
valueElicitationPrompt = new Prompt(); 
valueElicitationPrompt.setMaxAttempts(2); 
valueElicitationPromptMessageList = new ArrayList<>(); 
valueElicitationPromptMessage = new Message().withContent("What day do you want the {FlowerType} to be picked up?")
                                             .withContentType(ContentType.PlainText); 
valueElicitationPromptMessageList.add(confirmationPromptMessage); 
valueElicitationPrompt.setMessages(confirmationPromptMessageList); 
// add valueElicitationPrompt to slot 
pickupDateSlot.setValueElicitationPrompt(valueElicitationPrompt);
pickupDateSlot.setPriority(2); 
pickupDateSlot.setDescription("The date to pick up the flowers");
// add slot to slots list 
slots.add(pickupDateSlot);

back again to OrderFlowers.json for the PickupTime slot definition:

{ "slotType": "AMAZON.TIME", 
  "name": "PickupTime", 
  "slotConstraint": "Required", 
  "valueElicitationPrompt": { 
            "maxAttempts": 2, 
            "messages": [ 
                 { "content": "Pick up the {FlowerType} at what time on {PickupDate}?", 
                   "contentType": "PlainText" } 
            ] 
  }, 
  "priority": 3, 
  "description": "The time to pick up the flowers" 
} 
], (Note: end of slots definition in OrderFlowers.json)
// Create and configure PickupTime slot 
Slot pickupTimeSlot = new Slot().withSlotType("AMAZON.TIME").withName("PickupTime")
                                .withConstraint(SlotContraint.Required);
 // configure valueElicitationPrompt for this slot 
valueElicitationPrompt = new Prompt(); 
valueElicitationPrompt.setMaxAttempts(2); 
valueElicitationPromptMessageList = new ArrayList<>(); 
valueElicitationPromptMessage = new Message().withContent("Pick up the {FlowerType} at what time on {PickupDate}?")
                                             .withContentType(ContentType.PlainText); 
valueElicitationPromptMessageList.add(confirmationPromptMessage); 
valueElicitationPrompt.setMessages(confirmationPromptMessageList); 
// add valueElicitationPrompt to slot 
pickupTimeSlot.setValueElicitationPrompt(valueElicitationPrompt);
pickupTimeSlot.setPriority(3); 
pickupTimeSlot.setDescription("The time to pick up the flowers");
// add slot to slots list 
slots.add(pickupTimeSlot); 
// finally, add slots list to putIntentRequest 
putIntentRequest.setSlots(slots);

almost done, back to OrderFlowers.json:

"fulfillmentActivity": { 
       "type": "ReturnIntent" 
},

 

// configure fulfillmentActivity and add to putIntentRequest 
FulfillmentActivity fulfillmentActivity = new FulfillmentActivity().withType(FulfillmentActivityType.ReturnIntent); 
putIntentRequest.setFulfillmentActivity(fulfillmentActivity);

last time back to OrderFlowers.json:

 "description": "Intent to order a bouquet of flowers for pick up"
// add description to putIntentRequest 
putIntentRequest.setDescription("Intent to order a bouquet of flowers for pick up");

Whew!  PutIntentRequest now complete.  Finally we can issue the request to create the OrderFlowers intent.

PutIntentResult putIntentResult = modelBuildingClient. putIntent(putIntentRequest);

 

Step 4: Create the Bot (FINALLY!)

We will start with creating a new PutBotRequest:

PutBotRequest putBotRequest = new PutBotRequest().withName("OrderFlowersBot");

Using the specified objects in the context of the OrderFlowersBot.json file used in the CLI example, where OrderFlowersBot.json is:

{ "intents": [ 
              { "intentVersion": "$LATEST", 
                "intentName": "OrderFlowers" } 
             ],
// configure list of intents used in the bot 
List<Intent> intents = new ArrayList<>(); 
Intent intent = new Intent().withIntentName("OrderFlowers").withIntentVersion("$LATEST"); 
// add intent to intent list 
intents.add(intent); 
// add intents to bot request 
putBotRequest.setIntents(intents);

returning to OrderFlowersBot.json:

 "name": "OrderFlowersBot", (Note: this was specified at the time of PutBotRequest creation.  See above.)
 "locale": "en-US",
// set putBotRequest locale 
putBotRequest.setLocale("en-US");

back to OrderFlowersBot.json:

{ "abortStatement": { "messages": [ 
                                   { "content": "Sorry, I'm not able to assist at this time", 
                                     "contentType": "PlainText" } 
                                  ] 
                    },
// configure abortStatement 
Statement abortStatement = new Statement(); 
List<Message> abortStatementMessageList = new ArrayList<>(); 
Message abortStatementMessage = new Message().withContent("Sorry, I'm not able to assist at this time")
                                             .withContentType(ContentType.PlainText); 
abortStatementMessageList.add(abortStatementMessage); 
abortStatement.setMessages(abortStatementMessageList); 
// end of abortStatement configuration, add to putBotRequest 
putBotRequest.setAbortStatement(abortStatement);

again, back to OrderFlowersBot.json:

"clarificationPrompt": { 
          "maxAttempts": 2, 
          "messages": [ 
                       { "content": "I didn't understand you, what would you like to do?", 
                         "contentType": "PlainText" } 
                      ] 
},
// configure clarificationPrompt 
Prompt clarificationPrompt = new Prompt(); 
clarificationPrompt.setMaxAttempts(2); 
List<Message> clarificationPromptMessageList = new ArrayList<>(); 
Message clarificationPromptMessage = new Message().withContent("I didn't understand you, what would you like to do?")
                                                  .withContentType(ContentType.PlainText); 
clarificationPromptMessageList.add(clarificationPromptMessage); 
clarificationPrompt.setMessages(clarificationPromptMessageList); 
// end of clarificationPrompt configuration, add to putBotRequest 
putBotRequest.setClarificationPrompt(clarificationPrompt);

last time back to OrderFlowersBot.json:

"voiceId": "Salli", 
"childDirected": false, 
"idleSessionTTLInSeconds": 600, 
"description": "Bot to order flowers on the behalf of a user" 
}
// add voice id, subject to COPPA, set idle TTL and description 
putBotRequest.setVoiceId("Salli"); 
putBotRequest.setChildDirected(false); 
putBotRequest.setIdleSessionTTLInSeconds(600); 
putBotRequest.setDescription("Bot to order flowers on the behalf of a user");

PutBotRequest now complete!  Finally we can issue the request to create the OrderFlowersBot bot.

 PutBotResult putBotResult = modelBuildingClient.putBot(putBotRequest);

And we’re done!

(Note: full source code can be found here.)