How to find and fix errors in your SSML responses
Have you ever gotten a cryptic error message back when developing for Alexa? This is a common frustration when Alexa or Google Assistant doesn’t understand a response. Both platforms expect a response using SSML (Speech Synthesis Markup Language). SSML responses are XML strings adhering to certain tags, attributes, and allowable values. These platforms are sensitive to deviations from this standard. And neither provides details to tell you why your response is bad.
I’ve run into this problem myself many times during development. I’ve even hit this in production for certain edge cases that break some rule such as not including an unescaped ampersand (&).
To solve for this, I created an NPM module called ssml-check. Ssml-check takes an SSML response and checks for valid format, tags, and values. It supports Alexa and Google Assistant specific tags, and will also tell you if a response will work on both platforms. You can check out this module in action by entering SSML strings at this link.
Integrating ssml-check into your code is easy. The library exposes two functions check and verifyAndFix. You pass in the SSML text and an optional structure indicating the platform to check against. Check will validate your SSML, while verifyAndFix will additionally provide a corrected SSML string if it is able. This comes in really handy if you want to dynamically ensure that you are returning a valid response. For example, on Alexa if you’re using the ask-sdk, you can call verifyAndFix from a response interceptor. This lets you do a final validation before returning to Alexa:
The return value from check is a Promise that resolves to an array of errors (or undefined if the SSML is clean). The return value from verifyAndFix is a Promise that resolves to an object containing a new SSML string and an array of errors (or an empty object if the SSML is clean).
For example, suppose that you are trying to slow the rate of speech by using a prosody tag. On Alexa, a valid value for the rate must be at least 20%. The following snippet shows what check returns if you try to set the rate to 5%:
With the error object, the type field tells you the type of error encountered. If set to “tag”, you will get details about which tag has an error in the tag, attribute, and value fields. Type can also be a more generic error like “Invalid & character” or “Too many audio files”.
Suppose you are writing a skill using a framework like Jovo that allows your code to run on both Alexa and Google Assistant. You’re making use of the amazon:effect tag to provide a whispered response. Works great on Alexa, but not supported on Google. The following code will catch this:
Internally, ssml-check uses a core library called ssml-check-core. ssml-check-core is designed to do strictly syntactical checks with minimal dependencies. In fact, in all of the above examples, ssml-check-core could have been substituted for ssml-check. ssml-check builds upon syntactical checks by providing additional checks such as validating that audio files meet the formats required by Amazon or Google. By setting the validateAudioFiles field in the options structure, you will know if you have a valid audio file format (HTTPS, proper bit rate, sample rate, etc). For example, the following code will verify an audio file:
Some of these errors you can correct for in your code, even dynamically with verifyAndFix, based on desired behavior. You can log the response. Or you can return a generic error message to let the user know you encountered a problem.
I hope you find ssml-check and ssml-check-core as useful as I have in improving your responses. The modules are open source, so if you find conditions that aren’t covered, please feel free to contribute!