Skip to content

Commit

Permalink
Merge pull request #3 from ryanhollander/master
Browse files Browse the repository at this point in the history
Fixed issue #1 
Thanks a lot Ryan!
  • Loading branch information
KayLerch authored Feb 18, 2017
2 parents 1a5100f + 2f217c5 commit c74e150
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,10 @@
import io.klerch.alexa.tellask.model.AlexaOutputSlot;
import io.klerch.alexa.tellask.schema.UtteranceReader;
import io.klerch.alexa.tellask.util.resource.YamlReader;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand Down Expand Up @@ -145,30 +140,36 @@ public Reprompt getReprompt() {
private String resolveSlotsInUtterance(final String utterance) {
final StringBuffer buffer = new StringBuffer();
// extract all the placeholders found in the utterance
final Matcher slots = Pattern.compile("\\{(.*?)\\}").matcher(utterance);
final Matcher slotsInUtterance = Pattern.compile("\\{(.*?)\\}").matcher(utterance);
// for any of the placeholders ...
while (slots.find()) {
while (slotsInUtterance.find()) {
// ... placeholder-name is the slotName to look after in two places of the output
final String slotName = slots.group(1);
final String slotName = slotsInUtterance.group(1);
final AlexaOutputSlot outputSlot = output
// prefer directly set output slots
.getSlots().stream()
// which do have the same name as what is found in the utterance
.filter(slot -> slot.getName().equals(slotName))
.findFirst()
// if not directly applied look in provided models for AlexaSlotSave fields
.orElse(output.getModels()
.stream()
// for those having that AlexaSlotSave field
.filter(model -> model.hasOutputSlot(slotName))
// create a AlexaOutputSlot from attributes in annotation + the field value itself
.map(model -> model.getOutputSlot(slotName).orElse(null))
.findFirst().orElse(null));
.orElse(getSavedSlot(slotName));

Validate.notNull(outputSlot, "Could not replace placeholder with name {" + slotName + "} because no corresponding slot was set in the output.");
slots.appendReplacement(buffer, outputSlot.getSsml());
// RJH - FEB 2017 - Matcher.quoteReplacement on slot input to fix bug
// ~ https://github.com/KayLerch/alexa-skills-kit-tellask-java/issues/1
slotsInUtterance.appendReplacement(buffer, Matcher.quoteReplacement(outputSlot.getSsml()));
}
slots.appendTail(buffer);
slotsInUtterance.appendTail(buffer);
return "<speak>" + buffer.toString() + "</speak>";
}

private AlexaOutputSlot getSavedSlot(String slotName) {
return output.getModels()
.stream()
// for those having that AlexaSlotSave field
.filter(model -> model.hasOutputSlot(slotName))
// create a AlexaOutputSlot from attributes in annotation + the field value itself
.map(model -> model.getOutputSlot(slotName).orElse(null))
.findFirst().orElse(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,24 @@ public void getResponseWithSlots() throws Exception {
((SsmlOutputSpeech)response.getOutputSpeech()).getSsml());
Assert.assertNull(response.getReprompt());
}
// RJH FEB 2017 - added test for issue:
// ~ https://github.com/KayLerch/alexa-skills-kit-tellask-java/issues/1
@Test
public void getResponseWithSlotsMatcherQuoteReplacement() throws Exception {
final AlexaStateModelSample model = new AlexaStateModelSample();
model.setName("Paul");

final AlexaOutput output = AlexaOutput
.ask("IntentWithOneSlotReplacement")
.putSlot("theSlot", "$5.00")
.putState(model).build();

final AlexaSpeechletResponse response = new AlexaSpeechletResponse(output, new ResourceUtteranceReader(), "en-US");
Assert.assertEquals(output, response.getOutput());
Assert.assertEquals("<speak>This is a single slot replacement: $5.00</speak>",
((SsmlOutputSpeech)response.getOutputSpeech()).getSsml());
Assert.assertNull(response.getReprompt());
}

@Test
public void getResponseWithReprompt() throws Exception {
Expand Down
4 changes: 4 additions & 0 deletions src/test/resources/en-US/utterances.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ IntentWithOneUtteranceAndOneReprompt:
Reprompts:
- "This is a reprompt {name} with your score of {credits}"

IntentWithOneSlotReplacement:
Utterances:
- "This is a single slot replacement: {theSlot}"

IntentWithInstantUtterance:
- "Hello there {name}. Your current score is {credits} This is awesome"
- "Welcome {name}. You got a score of {credits} You are awesome"
Expand Down

0 comments on commit c74e150

Please sign in to comment.