Applying SSML in Skill Responses

There are two places where you’ll likely use SSML in a skill:

  • In a request handler’s response, through the response builder’s speak() or reprompt() methods

  • In the interaction model as one of the values defined in the prompts section

And even though automated tests can’t possibly verify how SSML sounds, you’ll probably want your tests to assert that the SSML returned is what you expect.

In the Star Port 75 skill, we’re going to add SSML in the response from the launch handler to include some audio clips to the launch message. And for fun we’ll also throw a few interjections into the validation prompts in our interaction model.

First, let’s tweak the default response from the launch request handler to include SSML. The new “WELCOME_MSG” string in languageStrings.js will look like this:

 WELCOME_MSG:
 '<speak>'​ +
 '<p><audio src="https://starport75.dev/audio/SP75.mp3"/> '​ +
 'Welcome to Star Port 75 Travel, your source for <audio src= '​ +
 '"soundbank://soundlibrary/scifi/amzn_sfx_scifi_small_zoom_flyby_01"/> '​ +
 'out-of-this world adventures.</p> '​ +
 '<p>Where do you want to blast off to?</p> '​ +
 '</speak>'​,

As you can see, the SSML returned here is quite similar to the SSML we created when learning about the <audio> tag. The tricky part is including multiline SSML as we define a JavaScript variable. Although JavaScript offers several options for working with multiline text, it gets complicated when we try to mirror that multiline value in our YAML-based BST tests. So instead of fumbling around with multiline string of SSML, we’ll just assign a single line of SSML to speakOutput, but split it across multiple lines of JavaScript with string concatenation.

Meanwhile, in the test specification, we can assert that the launch request returns that chunk of SSML with the following test:

 ---
 configuration:
  locales: ​en-US
  filter: ​mock-given-name-filter.js
 
 ---
 - test: ​Launch request
 - LaunchRequest:
  - prompt:
 <speak><p>
 <audio src="https://thetalkingapp.s3.amazonaws.com/SP75.mp3"/>
 Welcome to Star Port 75 Travel, your source for <audio src=
 "soundbank://soundlibrary/scifi/amzn_sfx_scifi_small_zoom_flyby_01"/>
 out-of-this world adventures.</p>
 <p>Where do you want to blast off to?</p></speak>
  - ​response.card.type​: ​AskForPermissionsConsent

Notice how the prompt property in the test specification appears to be a multiline chunk of SSML. In reality, this is interpreted as a single line of SSML that matches the SSML returned from the launch request handler. You can prove it by running the tests:

 $ ​​bst​​ ​​test​​ ​​--jest.collectCoverage=false​​ ​​launch-request-unauthorized
 
 BST: v2.6.0 Node: v17.6.0
 Remember, you can always contact us at https://gitter.im/bespoken/bst.
 
  PASS test/launch-request-unauthorized.yml
  en-US
  Launch request
  ✓ LaunchRequest (409ms)
 
 Test Suites: 1 passed, 1 total
 Tests: 1 passed, 1 total
 Snapshots: 0 total
 Time: 1.22s, estimated 2s

Much like JavaScript, YAML offers several ways of declaring multiline values, but it can be very difficult to write multiline SSML in a YAML test specification that matches multiline SSML expressed in JavaScript. It’s often just easier to flatten the SSML to a single line string.

We can also use SSML in prompts defined in our skill’s interaction model. For example, we can use the <say-as> tag in some of the validation prompts to liven them up a bit:

 {
 "id"​: ​"Slot.Validation.UnknownDestination"​,
 "variations"​: [
  {
 "type"​: ​"SSML"​,
 "value"​: ​"<speak><say-as interpret-as="​​interjection​​">huh?</say-as>
  Star Port 75 Travel doesn't offer travel to {destination}.
  Where else would you like to go?</speak>"
  },
  {
 "type"​: ​"SSML"​,
 "value"​: ​"<speak><say-as interpret-as="​​interjection​​">d'oh!</say-as>
  {destination} sounds like a wonderful trip. Unfortunately, we
  don't serve that destination. Pick another destination.</speak>"
  }
  ]

Now, whenever a user tries to plan a trip to a destination that isn’t one of the planets defined in the PLANETS type, Alexa will either begin her response confused by saying “Huh?” or reply in a manner not unlike Homer Simpson.

Don’t Break JSON Strings

images/aside-icons/warning.png

It’s very important to understand that although the preceding snippet of interaction model JSON appears to show multiple lines for the value property, it must be written as a single line. It was necessary to split those lines so that they’d fit within the margins of the printed page, but JSON does not support splitting values across multiple lines. When you write SSML into your skill’s interaction model, be sure to write it into a single line without any line breaks.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset