Skip to content

Commit

Permalink
Add CanFulfill Predicate and response builder method
Browse files Browse the repository at this point in the history
  • Loading branch information
breedloj committed Nov 5, 2018
1 parent 29db92b commit 954dfdb
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 6 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ target/
*settings.xml
*.iml
*.idea
*.project
*.classpath
*.prefs
4 changes: 1 addition & 3 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,11 @@ schemas from the [developer docs](https://developer.amazon.com/docs/custom-skill
### Preview
* [APL](https://developer.amazon.com/blogs/alexa/post/1dee3fa0-8c5f-4179-ab7a-74545ead24ce/introducing-the-alexa-presentation-language-preview)
* [Connections](https://developer.amazon.com/blogs/alexa/post/7b332b32-893e-4cad-be07-a5877efcbbb4/skill-connections-preview-now-skills-can-work-together-to-help-customers-get-more-done)
* [Name-free Interactions](https://developer.amazon.com/docs/custom-skills/understand-name-free-interaction-for-custom-skills.html)

## Frameworks
To discover frameworks built on top of the ASK SDK for Java, see https://github.com/alexa-labs/ask-sdk-frameworks-java.

## Public Beta SDK
The available [public beta version of the ASK SDK v2 for Java](https://github.com/alexa/alexa-skills-kit-sdk-for-java/tree/2.x_public-beta) may contain one or more Alexa features that are currently in public beta and not included in the production SDK version.

## Other Language Alexa Skills Kit SDKs
<a href="https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs"><img src="https://github.com/konpa/devicon/blob/master/icons/nodejs/nodejs-original.svg?sanitize=true" width="25px" /> Alexa Skills Kit SDK for NodeJS</a>

Expand Down
26 changes: 26 additions & 0 deletions ask-sdk-core/src/com/amazon/ask/request/Predicates.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.amazon.ask.dispatcher.request.handler.HandlerInput;
import com.amazon.ask.model.IntentRequest;
import com.amazon.ask.model.Request;
import com.amazon.ask.model.canfulfill.CanFulfillIntentRequest;
import com.amazon.ask.model.interfaces.display.ElementSelectedRequest;
import com.amazon.ask.request.viewport.ViewportUtils;
import com.amazon.ask.request.viewport.ViewportProfile;
Expand Down Expand Up @@ -52,6 +53,17 @@ public static Predicate<HandlerInput> intentName(String intentName) {
&& intentName.equals(((IntentRequest) i.getRequestEnvelope().getRequest()).getIntent().getName());
}

/**
* Returns a predicate that returns to true if the incoming request is an {@link CanFulfillIntentRequest}
* for the given intent name.
* @param intentName intent name to evaluate against
* @return true if the incoming request is an {@link CanFulfillIntentRequest} for the given intent name
*/
public static Predicate<HandlerInput> canFulfillIntentName(String intentName) {
return i -> i.getRequestEnvelope().getRequest() instanceof CanFulfillIntentRequest
&& intentName.equals(((CanFulfillIntentRequest) i.getRequestEnvelope().getRequest()).getIntent().getName());
}

/**
* Returns a predicate that returns to true if the incoming request is an {@link IntentRequest}
* and contains the given slot name and value.
Expand All @@ -66,6 +78,20 @@ public static Predicate<HandlerInput> slotValue(String slotName, String slotValu
&& slotValue.equals(((IntentRequest) i.getRequestEnvelope().getRequest()).getIntent().getSlots().get(slotName).getValue());
}

/**
* Returns a predicate that returns to true if the incoming request is an {@link CanFulfillIntentRequest}
* and contains the given slot name and value.
* @param slotName expected intent slot name
* @param slotValue expected intent slot value
* @return true if the incoming request is an {@link CanFulfillIntentRequest} and contains the given slot name and value
*/
public static Predicate<HandlerInput> canFulfillSlotValue(String slotName, String slotValue) {
return i -> i.getRequestEnvelope().getRequest() instanceof CanFulfillIntentRequest
&& ((CanFulfillIntentRequest) i.getRequestEnvelope().getRequest()).getIntent().getSlots() != null
&& ((CanFulfillIntentRequest) i.getRequestEnvelope().getRequest()).getIntent().getSlots().containsKey(slotName)
&& slotValue.equals(((CanFulfillIntentRequest) i.getRequestEnvelope().getRequest()).getIntent().getSlots().get(slotName).getValue());
}

/**
* Returns a predicate that returns to true if the incoming request is an {@link ElementSelectedRequest}
* with the given token.
Expand Down
15 changes: 14 additions & 1 deletion ask-sdk-core/src/com/amazon/ask/response/ResponseBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.amazon.ask.model.Directive;
import com.amazon.ask.model.Intent;
import com.amazon.ask.model.Response;
import com.amazon.ask.model.canfulfill.CanFulfillIntent;
import com.amazon.ask.model.dialog.ConfirmIntentDirective;
import com.amazon.ask.model.dialog.ConfirmSlotDirective;
import com.amazon.ask.model.dialog.DelegateDirective;
Expand Down Expand Up @@ -58,13 +59,15 @@ public class ResponseBuilder {
protected List<Directive> directiveList;
protected Boolean shouldEndSession;
protected Reprompt reprompt;
protected CanFulfillIntent canFulfillIntent;

public Optional<Response> build() {
return Optional.of(Response.builder()
.withOutputSpeech(speech)
.withCard(card)
.withReprompt(reprompt)
.withDirectives(directiveList)
.withCanFulfillIntent(canFulfillIntent)
.withShouldEndSession(shouldEndSession)
.build());
}
Expand Down Expand Up @@ -350,6 +353,16 @@ public ResponseBuilder addDirective(Directive directive) {
return this;
}

/**
* Helper method for adding canFulfillIntent to response
* @param canFulfillIntent
* @return response builder
*/
public ResponseBuilder withCanFulfillIntent(CanFulfillIntent canFulfillIntent) {
this.canFulfillIntent = canFulfillIntent;
return this;
}

private boolean isVideoAppLaunchDirectivePresent() {
if (directiveList == null || directiveList.isEmpty()) {
return false;
Expand Down Expand Up @@ -380,4 +393,4 @@ private String trimOutputSpeech(String outputSpeech) {
return trimmedOutputSpeech;
}

}
}
51 changes: 51 additions & 0 deletions ask-sdk-core/tst/com/amazon/ask/request/PredicatesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.amazon.ask.model.Session;
import com.amazon.ask.model.SessionEndedRequest;
import com.amazon.ask.model.Slot;
import com.amazon.ask.model.canfulfill.CanFulfillIntentRequest;
import com.amazon.ask.model.interfaces.display.ElementSelectedRequest;
import com.amazon.ask.model.interfaces.viewport.Shape;
import com.amazon.ask.model.interfaces.viewport.ViewportState;
Expand Down Expand Up @@ -91,6 +92,24 @@ public void intent_name_predicate_non_matching_intent_name_returns_false() {
assertFalse(intentName("bar").test(input));
}

@Test
public void canfulfill_intent_name_predicate_non_canfulfill_intent_request_returns_false() {
HandlerInput input = getInputForRequest(SessionEndedRequest.builder().build());
assertFalse(canFulfillIntentName("foo").test(input));
}

@Test
public void canfulfill_intent_name_predicate_matching_canfulfill_intent_name_returns_true() {
HandlerInput input = getInputForRequest(CanFulfillIntentRequest.builder().withIntent(Intent.builder().withName("foo").build()).build());
assertTrue(canFulfillIntentName("foo").test(input));
}

@Test
public void canfulfill_intent_name_predicate_non_matching_canfulfill_intent_name_returns_false() {
HandlerInput input = getInputForRequest(CanFulfillIntentRequest.builder().withIntent(Intent.builder().withName("foo").build()).build());
assertFalse(canFulfillIntentName("bar").test(input));
}

@Test
public void request_attributes_predicate_request_attributes_missing_key_returns_false() {
HandlerInput input = getInputWithRequestAttributes(Collections.singletonMap("foo", "bar"));
Expand Down Expand Up @@ -195,6 +214,38 @@ public void viewport_profile_predicate_non_matching_viewport_profile_returns_fal
HandlerInput input = getInputWithViewport();
assertFalse(viewportProfile(ViewportProfile.MOBILE_LANDSCAPE_MEDIUM).test(input));
}

public void canfulfill_slot_value_predicate_non_canfulfill_intent_request_returns_false() {
HandlerInput input = getInputForRequest(LaunchRequest.builder().build());
assertFalse(canFulfillSlotValue("foo", "bar").test(input));
}

@Test
public void canfulfill_slot_value_predicate_null_slots_returns_false() {
HandlerInput input = getInputForRequest(CanFulfillIntentRequest.builder().withIntent(Intent.builder().build()).build());
assertFalse(canFulfillSlotValue("foo", "bar").test(input));
}

@Test
public void canfulfill_slot_value_predicate_non_matching_slot_key_returns_false() {
Map<String, Slot> slots = Collections.singletonMap("baz", Slot.builder().withValue("bar").build());
HandlerInput input = getInputForRequest(CanFulfillIntentRequest.builder().withIntent(Intent.builder().withSlots(slots).build()).build());
assertFalse(slotValue("foo", "bar").test(input));
}

@Test
public void canfulfill_slot_value_predicate_non_matching_slot_value_returns_false() {
Map<String, Slot> slots = Collections.singletonMap("foo", Slot.builder().withValue("baz").build());
HandlerInput input = getInputForRequest(CanFulfillIntentRequest.builder().withIntent(Intent.builder().withSlots(slots).build()).build());
assertFalse(canFulfillSlotValue("foo", "bar").test(input));
}

@Test
public void canfulfill_slot_value_predicate_matching_slot_value_returns_true() {
Map<String, Slot> slots = Collections.singletonMap("foo", Slot.builder().withValue("bar").build());
HandlerInput input = getInputForRequest(CanFulfillIntentRequest.builder().withIntent(Intent.builder().withSlots(slots).build()).build());
assertTrue(canFulfillSlotValue("foo", "bar").test(input));
}

private HandlerInput getInputWithSessionAttributes(Map<String, Object> attributes, boolean inSessionRequest) {
AttributesManager manager = mock(AttributesManager.class);
Expand Down
26 changes: 26 additions & 0 deletions ask-sdk-core/tst/com/amazon/ask/response/ResponseBuilderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
import com.amazon.ask.model.Response;
import com.amazon.ask.model.Slot;
import com.amazon.ask.model.SlotConfirmationStatus;
import com.amazon.ask.model.canfulfill.CanFulfillIntent;
import com.amazon.ask.model.canfulfill.CanFulfillIntentValues;
import com.amazon.ask.model.canfulfill.CanFulfillSlot;
import com.amazon.ask.model.canfulfill.CanFulfillSlotValues;
import com.amazon.ask.model.canfulfill.CanUnderstandSlotValues;
import com.amazon.ask.model.dialog.ConfirmIntentDirective;
import com.amazon.ask.model.dialog.ConfirmSlotDirective;
import com.amazon.ask.model.dialog.DelegateDirective;
Expand Down Expand Up @@ -530,6 +535,27 @@ public void build_response_with_empty_speech() {
.build();
assertEquals(responseWithBuilder.get(), response);
}

@Test
public void build_response_with_canFulfillIntent() {
CanFulfillSlot soundSlot = CanFulfillSlot.builder()
.withCanUnderstand(CanUnderstandSlotValues.YES)
.withCanFulfill(CanFulfillSlotValues.YES)
.build();
CanFulfillIntent skillQueryResponse = CanFulfillIntent.builder()
.withCanFulfill(CanFulfillIntentValues.YES)
.putSlotsItem("Sound", soundSlot)
.build();

Response response = Response.builder()
.withCanFulfillIntent(skillQueryResponse)
.build();

Optional<Response> responseWithBuilder = builder
.withCanFulfillIntent(skillQueryResponse)
.build();
assertEquals(responseWithBuilder.get(), response);
}

@Test
public void build_response_testing_trim() {
Expand Down
4 changes: 2 additions & 2 deletions docs/en/SDK-Supported-Alexa-Capabilities.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@ Preview
The following capabilities are released as Preview. The interfaces might change
during a stable release.
* `APL <https://developer.amazon.com/blogs/alexa/post/1dee3fa0-8c5f-4179-ab7a-74545ead24ce/introducing-the-alexa-presentation-language-preview>`__

* `Connections <https://developer.amazon.com/blogs/alexa/post/7b332b32-893e-4cad-be07-a5877efcbbb4/skill-connections-preview-now-skills-can-work-together-to-help-customers-get-more-done>`__
* `Connections <https://developer.amazon.com/blogs/alexa/post/7b332b32-893e-4cad-be07-a5877efcbbb4/skill-connections-preview-now-skills-can-work-together-to-help-customers-get-more-done>`__
* `Name-free Interactions <https://developer.amazon.com/docs/custom-skills/understand-name-free-interaction-for-custom-skills.html>`_

0 comments on commit 954dfdb

Please sign in to comment.