Transformers

Transformers convert data in a data source into alternative representations. You can include an array of transformer objects in the transformers property of an object data source.

Available transformers

There are four available transformers:

  • ssmlToSpeech: Converts the input Speech Synthesis Markup Language (SSML) into speech you can bind to the speech property of an APL component. The speech associated with the component can then be spoken using a SpeakItem APL command. The use of the audio tag with the ssmlToSpeech transformer is not supported. The text passed to this transformer must be valid SSML enclosed within <speak> tags.
  • ssmlToText: Converts the input SSML to plain text.
  • textToHint: Converts the input to a hint with the correct user-configured wake word for the device (Try "Alexa, This is the hint"). Users can choose the wake word for their devices, so avoid hard-coding the word "Alexa" in your hint.
  • textToSpeech: Converts the input plain text into speech you can bind to the speech property of an APL component. The speech associated with the component can then be spoken using a SpeakItem APL command.

Transformer properties and conversion rules

A transformer converts data from a named property inside a data source, performs the transformation and writes the data back to a property in the original data source. If the outputName is not supplied, a transformer overwrites the input property. All transformers have the base properties shown in this table:

Property Type Required Description
transformer String Yes The type of the transformer.
inputPath String Yes Path within the object to the content to transform. This must reference a property within the properties object in the data source.
outputName String No Name of the property to be added to the object. If no outputName is supplied, the transformer overwrites the inputPath with the transformed output.

The inputPath points to either a single entity in the data source object, or a set of entities using wildcard properties or unresolved arrays. Each property that matches the inputPath is transformed. The inputPath pattern is a symbol followed by some number of node and/or wildcard references.

The following rules apply:

  • A symbol name or array index must match an existing object property or array index inside the properties block. If the match fails, the transformation is abandoned.

  • The location where the output is stored is found by replacing the last non-wildcard node with the outputName. If there are no non-wildcard nodes, the symbol is replaced by outputName.

  • The last non-wildcard node cannot be a numeric index. If the last non-wildcard node is numeric, the transformation is abandoned.

These examples demonstrate how referencing works. Consider the sample data shown here:

{
  "myDocumentData": {
    "type": "object",
    "properties": {
      "name": "Sam Lee",
      "address": {
        "street": "301 Charles Way",
        "city": "Bedford"
      },
      "family": [
        {
          "name": "Alex",
          "relation": "wife"
        },
        {
          "name": "Patty",
          "relation": "daughter"
        }
      ],
      "contacts": [
        "Robin Barnes",
        "Betty Barnes"
      ]
    },
    "transformers": [
      {
        "inputPath": ["see examples in table below"],
        "outputName": ["see examples in table below"],
        "transformer": "textToSpeech"
      }
    ]
  }
}

This table shows how different values in inputPath and outputName would transform the data shown in the above data source.

inputPath Item to be transformed Result stored at:
name "Sam Lee" outputName
address.street "301 Charles Way" address.outputName
contacts.* ["Robin Barnes", "Betty Barnes"] outputName[0], outputName[1]
family[0].name "Alex" family[0].outputName
family[*].name "Alex", "Patty" family[0].outputName, family[1].outputName
address.* "301 Charles Way", "Bedford" outputName.street, outputName.city
family[3].name   Does not work: the family array does not have a value at index 3
family[1].names   Does not work: the value at family[1] does not have a names property
family[0] { "name": "Alex", "relation": "wife" } Does not work: the last non-wildcard node cannot be a numeric index

ssmlToSpeech transformer

The ssmlToSpeech transformer converts an SSML string into a speakable entity. The text passed to this transformer must be valid SSML enclosed within <speak> tags. For plain text, use the textToSpeech transformer instead.

In your document, bind ssmlToSpeech transformer output to the speech property of a component. The code below shows a version of a "Cat Facts" skill that associates speech with a Text component bound to the cat fact.

Note that the text property points to catFactData.properties.catFact, while the speech component points to catFactData.properties.catFactSpeech.

{
  "type": "Container",
  "item": {
    "type": "Text",
    "id": "catFactText",
    "text": "${payload.catFactData.properties.catFact}",
    "speech": "${payload.catFactData.properties.catFactSpeech}"
  }
}

This example shows the corresponding catFactData data source. Note that the properties object has a property catFactSsml that contains the actual text to use in the component. This property is used as input for both the ssmlToSpeech and ssmlToText transformers:

  • The ssmlToSpeech transformer transforms the value of catFactSsml into speech and places the output in a new property called catFactSpeech. Recall that the catFactSpeech property is bound to the speech property in the Text component shown earlier.
  • The ssmlToText transformer transforms the value of catFactSsml into plain text and places the output in a new property called catFact. Recall that the catFact property is bound to the text property in the Text component shown earlier.
{
  "catFactData": {
    "type": "object",
    "properties": {
      "backgroundImage": "https://.../catfacts.png",
      "title": "Cat Fact #9",
      "logoUrl": "https://.../logo.png",
      "image": "https://.../catfact9.png",
      "catFactSsml": "<speak>Not all cats like <emphasis level='strong'>catnip</emphasis>.</speak>"
    },
    "transformers": [
      {
        "inputPath": "catFactSsml",
        "outputName": "catFactSpeech",
        "transformer": "ssmlToSpeech"
      },
      {
        "inputPath": "catFactSsml",
        "outputName": "catFact",
        "transformer": "ssmlToText"
      }
    ]
  }
}

Finally, to read the cat fact, you send Alexa the Alexa.Presentation.APL.ExecuteCommands directive with the SpeakItem command. The code below shows the Alexa.Presentation.APL.ExecuteCommands directive you can use to read the cat fact. Note that the token supplied in the ExecuteCommands directive is required and must match the token provided by the skill in the RenderDocument directive used to render the APL document.

{
  "type": "Alexa.Presentation.APL.ExecuteCommands",
  "token": "[SkillProvidedToken]",
  "commands": [
    {
      "type": "SpeakItem",
      "componentId": "catFactText",
      "highlightMode": "line",
      "align": "center"
    }
  ]
}

ssmlToText transformer

The SSML to text transformer converts a full SSML text string into text that is more appropriate for human reading by removing the SSML markup.

textToHint transformer

The textToHint transformer converts the input to a hint with the correct user-configured wake word for the device (Try "Alexa, This is the hint"). Users can choose the wake word for their devices, so avoid hard-coding the word "Alexa" in your hint. You typically use this transformer with the AlexaFooter responsive component.

For an example of displaying a hint, see Use the textToHint transformer.

textToSpeech transformer

The textToSpeech transformer converts a plain text string into a speakable entity. The text passed to this transformer must be plain text. For SSML text, use the ssmlToSpeech transformer instead.

This transformer works just like the ssmlToSpeech transformer. You bind the textToSpeech transformer output to the speech property of a component, then use the SpeakItem command to speak the text.

This example data source shows the same catFactData data source shown earlier, but with plain text for the catFactText property. In this case, since the catFactText property is already plain text, there is no need for the ssmlToText transformer.

{
  "catFactData": {
    "type": "object",
    "properties": {
      "backgroundImage": "https://.../catfacts.png",
      "title": "Cat Fact #9",
      "logoUrl": "https://.../logo.png",
      "image": "https://.../catfact9.png",
      "catFactText": "Not all cats like catnip."
    },
    "transformers": [
      {
        "inputPath": "catFactText",
        "outputName": "catFactSpeech",
        "transformer": "textToSpeech"
      }
    ]
  }
}

You can then reference this data source in the Text component like this:

{
  "type": "Container",
  "item": {
    "type": "Text",
    "id": "catFactText",
    "text": "${payload.catFactData.properties.catFactText}",
    "speech": "${payload.catFactData.properties.catFactSpeech}"
  }
}

The text property binds to the un-transformed, plain text catFactText property. The speech property binds to the output of the transformer.