APL Standard Commands (APL 1.0)
(This is not the most recent version of APL. Use the Other Versions option to see the documentation for the most recent version of APL)
- Common Properties
- AutoPage command
- Idle command
- Parallel command
- Scroll command
- ScrollToIndex command
- SendEvent command
- Sequential command
- SetPage command
- SetState Command
- SetValue Command
- SpeakItem command
- SpeakList Command
See also: APL Commands.
Common Properties
A single command is encoded as a JSON object. All commands contain the following properties.
Property | Type | Required | Description |
---|---|---|---|
type | String | Yes | Type of the command |
description | String | No | Optional documentation for this command |
delay | Integer | No | Delay time in milliseconds before this command runs. Must be non-negative. Defaults to 0. |
when | Boolean | No | Conditional expression. If this evaluates to false , the command is skipped. Defaults to true . |
type
Specifies the particular command to run. This may be a pre-defined primitive command types or a user-defined command.
delay
The delay
value is the amount of time in milliseconds inserted before running this command. The delay
value must be a non-negative integer, which if not specified, defaults to 0. The delay
value is ignored if the when property resolves to false
, or if the command runs from within an event handler.
when
If when
is set to true
, run the command. If false
, ignore the command.
AutoPage command
The AutoPage
command automatically progresses through a series of pages displayed in a Pager component. The AutoPage
command finishes after the last page has been displayed for the requested time period.
The AutoPage
command has the following properties in addition to the regular command properties.
Property | Type | Required | Description |
---|---|---|---|
componentId | String | Yes | The id of the component to read. |
count | Integer | No | The number of pages to display. Defaults to all of them. |
duration | Integer | No | Time to wait between pages (in milliseconds). Defaults to 0. |
For example, to auto-page through a sports pager:
{
"type": "AutoPage",
"componentId": "mySportsPager",
"duration": 1000
}
The AutoPage
command has no effect if the count is non-positive.
When stopped, the AutoPage
command:
- Moves the display ahead to the target page if the AutoPage command sequence is at least 50% complete.
- Returns the display to the previous page if it is not at least 50% complete.
The onPageChanged
command is run once with the new page if the page has changed.
componentId
The identifier of the Pager component. If omitted, the component issuing the AutoPage
command is used.
count
The number of pages to display. If not specified, this defaults to the number of pages remaining. Wrapping is not supported; the count is internally clipped to fall in the range [0, pager.children.length - pager.currentIndex - 1].
duration
The amount of time to wait and display each page, including the first one. Any animated transition between pages will add to the total amount of time.
Idle command
The Idle
command does nothing. It may be a placeholder or used to insert a calculated delay in a longer series of commands. For example, consider this command.
{
"type": "Parallel",
"commands": [
{
"type": "Idle",
"delay": 3000
},
{
"type": "SpeakItem",
"componentId": "item7"
}
]
}
This command sequence speaks "item7". The use of the Idle
command guarantees that the overall command will last at least 3000 milliseconds even if the speech ends earlier.
The type
of the Idle
command is Idle
.
Parallel command
Run a series of commands in parallel. The Parallel
command starts running all child commands simultaneously. The Parallel
command is considered finished when all of its child commands have finished. When the Parallel
command stops early, all currently running commands stop.
The type of the Parallel
command is Parallel
. The Parallel
command has the following properties in addition to the common command properties.
Property | Type | Required | Description |
---|---|---|---|
commands | Array of commands | Yes | An unordered list of command to run in parallel |
commands
An un-ordered array of commands to run in parallel. Once all commands have finished running, the Parallel
command finishes. The delay
value set for the Parallel
command is added to the delay
value set for each of the commands in the array. In the following example, the first SendEvent
command runs at 1500 milliseconds, and the second SendEvent
command at 750 milliseconds, which means the second SendEvent
command begins to run before the first.
{
"type": "Parallel",
"delay": 500,
"commands": [
{
"type": "SendEvent",
"delay": 1000
},
{
"type": "SendEvent",
"delay": 250
}
]
}
Scroll command
The Scroll
command scrolls a ScrollView or Sequence forward or backward by a set number of pages. The Scroll
command has the following properties in addition to the regular command properties.
Property | Type | Required | Description |
---|---|---|---|
componentId | String | Yes | The id of the component to read. |
distance | Number | No | The number of pages to scroll. Defaults to 1. |
The distance sets how far to scroll, in pages. For example, to scroll a list forward a single page:
{
"type": "Scroll",
"componentId": "myScrollingList",
"distance": 1
}
Scrolling stops when:
- The destination is reached.
- The end of the scrollable content is reached.
- The user touches the screen.
- Alexa sends a new command. Starting a new command ends the
Scroll
command, which stops scrolling immediately.
To smoothly scroll through all available content, set the distance to a large number. For example, to smoothly scroll back to the beginning of a list:
{
"type": "Scroll",
"componentId": "myScrollingList",
"distance": -10000
}
componentId
The ID of the ScrollView or Sequence. If omitted, the component issuing the ScrollPage
command is used.
distance
The scrolling distance, measured in pages. One "page" is the width or height of the ScrollView or Sequence component. Negative numbers scroll backwards. Setting distance
to 0 does not scroll.
ScrollToIndex command
Scroll forward or backward through a ScrollView or Sequence to ensure that a particular child component is in view. The ScrollToIndex
command has the following properties in addition to the regular command properties.
Property | Type | Required | Description |
---|---|---|---|
align | first | last | \center | visible | No | The alignment of the item after scrolling. Defaults to "visible". |
componentId | String | Yes | The id of the component to read. |
index | Integer | Yes | The 0-based index of the child to display. |
For example, to scroll to show the fifth step in a recipe displayed in a
list, set index
to 4.
{
"type": "ScrollToIndex",
"componentId": "recipeSteps",
"index": 4,
"align": "center"
}
The componentId
does not have to be a Sequence
or ScrollView
component. The ScrollToIndex
command looks for the first Sequence
or ScrollView
at or above the componentId
and scrolls that one.
Scrolling stops if the user touches the screen. Stopping the command stops scrolling immediately.
align
The alignment of the item on the screen after scrolling and before speech. Alignment is an enumerated value with the following options.
Alignment | Description |
---|---|
first | The top/left side of the item will be placed at the top/left side of the scrolling container. |
center | The center of the item will be placed in the center of the container. |
last | The bottom/right side of the item will be placed at the bottom/right side of the scrolling container. |
visible | The item will be moved the minimal distance necessary to bring it fully into view. |
componentId
The identifier of the parent container. If omitted, the component issuing the ScrollToIndex
command is used.
index
The 0-based index of the child item in the parent container to scroll into view. Negative values are measured from the end of the parent container. For example, to show the second-to-last item in a list:
{
"type": "ScrollToIndex",
"index": -2,
}
The algorithm for finding the item to display can be described loosely as follows:
let itemIndex = index < 0 ? index + children.length : index;
if (itemIndex >= 0 && itemIndex < children.length) {
let child = children[itemIndex];
scrollIntoView(child);
}
SendEvent command
Use the SendEvent
command to generate and send an event to Alexa. Here is an example of a SendEvent
command::
{
"type": "TouchWrapper",
"id": "buyButton",
"onPress": {
"type": "SendEvent",
"arguments": [
"he bought it"
]
},
"item": {
"type": "Text",
"text": "Buy it now!"
}
}
With SendEvent
, set the following properties in addition to the regular command properties.
Property | Type | Required | Description |
---|---|---|---|
arguments | Array of arguments | No | An array of argument data to pass to Alexa. |
components | Array of strings | No | An array of components to extract value data from and provide to Alexa. |
arguments
An array of data to send to the skill in the UserEvent
request. Data binding applies to each element in the array when SendEvent
runs. This allows an argument to contain data about the event itself, such as ${event.source.value}
. Use this to send arbitrary data to your skill.
components
The components
property is an array of selector strings. The UserEvent
request includes the value
of each component. For example, you can use the components
property to construct a form that sends the contents of each component to your skill.
The value for a given component depends on the type of component:
- A component with a basic press interaction, such as a
TouchWrapper
, reports thechecked
state of the component. - A rich component that supports interaction, such as a
Pager
,Sequence
, orScrollView
, reports component-specific values. For example, aPager
reports the index of the displayed page. Refer to component documentation for what they report. - Other components report
null
, unless stated otherwise the component documentation.
Access the component values in the components
property of the request.
UserEvent
The SendEvent
message is packaged into a TemplateRuntime.UserEvent
message sent to the skill. The TemplateRuntime.UserEvent
message takes the following approximate form.
{
"namespace": "TemplateRuntime",
"name": "UserEvent",
"payload": {
"skillID": "XYZZY",
"directiveID": "PDQBACH",
"arguments": [
ARGUMENT1,
ARGUMENT2,
:
],
"components": {
ID1: VALUE1,
ID2: VALUE2,
:
},
"source": {
"type": "Button",
"handler": "Press",
"id": "buyButton",
"value": false
}
}
}
The APL runtime is responsible for passing the argument data in the larger payload structure, along with source information about the type of component that created the event, the handler called, and the id of the component.
Sequential command
The Sequential
command runs a series of commands in order, waiting for the previous command to finish before running the next. The Sequential
command is finished when all of its child commands have finished. When the Sequential
command is stops early, the currently running command stops and no further commands run.
The type
of the Sequential
command is Sequential
. The Sequential
command has the following properties in addition to the common command properties.
Property | Type | Required | Description |
---|---|---|---|
commands | Array of commands | Yes | An ordered list of command to run in series. |
repeatCount | Integer | No | Defaults to 0. |
commands
An array of commands to run. The array of commands run in order, and each command must finish before the next one can begin. The delay
value of the Sequential
command and the delay
value of the first command in the sequence are additive. In the following example, the first SendEvent
command runs after 3000 milliseconds.
{
"type": "Sequential",
"delay": 1000,
"repeatCount": 2,
"commands": [
{
"type": "SendEvent",
"delay": 2000
},
{
"type": "SendEvent",
"delay": 2000
}
]
}
repeatCount
The number of times to repeat this series of commands. Defaults to 0. Negative values will be ignored.
SetPage command
The SetPage
command changes the page displayed in a Pager
component. The SetPage
command finishes when the item is fully in view. The SetPage
command has the following properties in addition to the regular command properties.
Property | Type | Required | Description |
---|---|---|---|
componentId | String | Yes | The id of the component to read. |
position | relative | absolute | No | Whether the value is a relative or absolute offset. Defaults to absolute . |
value | Integer | Yes | The distance to move. May be an absolute or relative value. |
When there are N pages in the Pager component, the first is index 0
and the last has index N-1
. A relative position offsets from the current page. For example, to move one page forward:
{
"type": "SetPage",
"componentId": "myWeatherPager",
"position": "relative",
"value": 1
}
An absolute position sets the index of the current page. A negative absolute position is an offset from the end of the list. For example, to go to the last page:
{
"type": "SetPage",
"componentId": "myWeatherPager",
"position": "absolute",
"value": -1
}
No intermediate pages display when switching between two pages (unlike a Sequence
). For example, if the current page is 13 and SetPage
runs with "position"="relative","value": 2
, the current page will transition out and page 11 will transition in without showing page 12.
The SetPage
command can set any page for display. It does not respect the allowed navigation direction in the Pager
component. However, wrapping behavior affects page switch calculations, as shown in approximate algorithm.
Stopping a SetPage
command jumps ahead to the target page if the SetPage
command sequence is at least 50% complete, and it returns to the previous page if it is not at least 50% complete. The onPageChanged
command runs one time when the command stops if the page has changed from the last page.
componentId
The identifier of the Pager component. If omitted, the component issuing the
SetPage
command is used.
position
If the position
is relative
, the value
is a relative distance to move from the current page. If the position
is absolute
, the value
is the absolute page number to which the display will move.
value
The value
is either the distance to move or the absolute page number to move to.
The algorithm to calculate final position and direction can be approximated with this pseudo-code.
if (command.position == 'absolute') { // Absolute motion
let index = command.value < 0 ? pager.children.length + command.value : command.value;
index = Math.max(0, Math.min(pager.children.length - 1, index)); // Clamp range
// Return the final index and the direction of motion
if (index == pager.currentIndex)
return NO_MOVE
return (index, index < pager.currentIndex ? "LEFT" : "RIGHT");
}
else { // Relative motion
let index = pager.currentIndex + command.value;
// If relative motion goes out of bounds and we don't support wrapping, ignore the command
if (pager.navigation != "wrap" && (index < 0 || index >= pager.children.length))
return NO_MOVE;
// Wrap appropriately
index = ((index % pager.children.length) + pager.children.length) % pager.children.length;
if (index == pager.currentIndex)
return NO_MOVE;
return (index, command.value < 0 ? "LEFT" : "RIGHT");
}
The pager animation is driven by the returned direction.
This algorithm has these characteristics:
-
Absolute values clamp within the valid range of pages. The direction is relative to the current page.
-
Relative values on a wrapping pager will wrap arbitrarily. The direction is based on the commanded value, and wrapping doesn't change the direction.
-
Relative values on a non-wrapping pager that go out of range are ignored.
SetState Command
SetState
command is deprecated, and isn't the correct way to change state. Use SetValue
, SetFocus
, and ClearFocus
to change the disabled
, checked
, and focused
states respectively. See Component state for details.Each component has a state used to evaluate styles and displaying the component. The SetState
command changes one of the component's state settings.
The SetState
command can be used to change the checked
, disabled
, and focused
states. The focused
state may only be set, and it can't be cleared.
The karaoke
and pressed
states canot be directly set, but you can use the SpeakItem
command to change those states.
The SetState command has the following properties in addition to the regular command properties.
Property | Type | Required | Description |
---|---|---|---|
componentId | String | No | The id of the component whose value should be set. |
state | String | Yes | The name of the state to set. Must be one of checked , disabled , or focused . |
value | Boolean | Yes | The value to set on the state. |
This example sets a TouchWrapper to the checked state.
{
"type": "SetState",
"componentId": "myButton",
"state": "checked",
"value": true
}
componentId
The identifier of the component whose state will change. If this property is omitted, then the component that issues the SetState command is the recipient.
state
The name of the state to change. Currently restricted to checked
, disabled
, and focused
.
value
The value evaluates when the command runs, so it can take advantage of existing component properties. For example, this command toggles the checked state of the current component.
{
"type": "SetState"
"state": "checked",
"value": "${!event.source.value}"
}
SetValue Command
The SetValue
command changes a dynamic property of a component. Refer to the specifies of each component for the values that may be set. With SetValue, the specified property of the component changes, but the screen is not redrawn. See Command evaluation.
The SetValue
command has the following properties in addition to the regular command properties.
Property | Type | Required | Description |
---|---|---|---|
componentId | String | No | The id of the component whose value should be set. |
property | String | Yes | The name of the property to set. |
value | String | Yes | The value to set on the property. |
This example sets a value so that the punchline for a joke appears, because an opacity
value of 1 means the component is fully visible.
{
"type": "SetValue",
"componentId": "jokePunchline",
"property": "opacity",
"value": 1
}
The SetValue command can be used to change the value of various properties, on a per-component basis. The specific properties that are mutable are documented for each component.
componentId
The identifier of the component whose value will change. If this property is omitted, then the component that issues the SetValue
command is the recipient.
property
The name of the property to change.
value
The value
evaluates when the command runs, so it can take advantage of existing component properties. In this example, the SetValue
command sets the opacity of the target component to 50% of its actual value.
{
"type": "SetValue"
"property": "opacity",
"value": "${event.target.opacity * 0.5}"
}
SpeakItem command
The SpeakItem
command reads the contents of a single item on the screen. The item will scroll into view if it is not currently visible. The item should have a speech
property.
The SpeakItem
command has the following properties in addition to the regular command properties.
Property | Type | Required | Description |
---|---|---|---|
align | first | last | center | visible | No | The alignment of the item after scrolling. Defaults to "visible". |
componentId | String | Yes | The id of the component to read. |
highlightMode | line | block | No | How karaoke is applied: on a line-by-line basis, or to the entire block. Defaults to "block". |
For example, to read the contents of a single text component and ensure it is aligned in the center of the screen:
{
"type": "SpeakItem",
"componentId": "myJokeSetup",
"highlightMode": "line",
"align": "center"
}
The karaoke
state of the component is set to true
during the speech and reset to false
after the speech completes. The highlightMode
only applies to Text components. When a Text
component is read in "highlightMode": "line"
mode, individual lines of text are set to the karaoke
state during speech and reset to false
after speech completes.
Note these restrictions:
-
The
SpeakItem
command does not scroll the content during speech inblock
mode. For example, if the component is larger than the scrolling container of the component, those parts of the component that are not visible after scrolling will remain hidden. -
Components on round screens should use center alignment, or much of the content will not be visible.
-
SpeakItem
does not highlight individual words or lines of text during speech whenhighlightMode
isblock
. -
The algorithm used to scroll the item into view assumes there is only a single scrolling component. Nested scrolling components are not supported.
-
Components without a
speech
property will still scroll into view.
When a SpeakItem
command stops early, it clears any visual changes and stops speech immediately.
align
The alignment of the item on the screen after scrolling and before speech. Alignment is an enumerated value with the following options.
Alignment | Description |
---|---|
first | The top/left side of the item will be placed at the top/left side of the scrolling container. |
center | The center of the item will be placed in the center of the container. |
last | The bottom/right side of the item will be placed at the bottom/right side of the scrolling container. |
visible | The item will be moved the minimal distance necessary to bring it fully into view. |
componentId
The ID of the spoken component. If omitted, the component issuing the SpeakItem command is used.
highlightMode
Controls how contents of a Text component are styled during speech. If set to "block", the entire Text component has the karaoke state set to true during speech. If highlightMode is set to "line", the individual lines of the Text component are treated separately. Each line will scroll to match the align property and be styled separately. In line-by-line karaoke mode, the only styling change accept is the color property; other properties are ignored.
SpeakList Command
Read the contents of a range of items inside a common container. Each item will scroll into view before speech. Each item should have a speech
property.
The SpeakList
command has the following properties in addition to the regular command properties.
Property | Type | Required | Description |
---|---|---|---|
align |
Enum. One of: first | center | last | visible |
No | The alignment of the item. Defaults to visible . |
componentId |
String | Yes | The id of the Sequence or Container (or any other hosting component). |
count |
integer | Yes | The number of children to read. |
minimumDwellTime |
number | No | The minimum number of milliseconds that an item will be highlighted for. Defaults to 0. |
start |
integer | Yes | The index of the item to start reading. |
The minimumDwellTime
prevents items with short titles from being read too quickly. For example, a series of movie titles like "Venom", "Fences", and "Dear Zachary: A Letter to a Son About His Father" needs some dwell time for the first two items.
This example reads three components out of the middle of a list and ensures that each aligns in the center of the screen:
{
"type": "SpeakList",
"componentId": "movieList",
"start": 3,
"count": 3,
"minimumDwellTime": 700,
"align": "center"
}
The karaoke
state of the component is set to true
during the speech of each component and reset to false
after that speech completes.
Note these characteristics of the SpeakList
command:
- The
SpeakList
command does not scroll the content during speech. For example, if the component is larger than the scrolling container of the component, those parts of the component that are not visible after scrolling will remain hidden. - Components on round screens should use
center
alignment, or much of the content will not be visible. SpeakList
does not highlight individual words or lines of text during speech.- To scroll the item into view, the component hierarchy is searched upwards to find the first ancestor that can be scrolled.
- The algorithm that used to scroll the item into view assumes there is only a single scrolling component. SpeakList does not support nested scrolling components.
- Components without a speech property will still scroll into view.
- Components without a speech property, but with a positive
minimumDwellTime
, will have karaoke set for that time. - Components without a speech property and no
minimumDwellTime
will not have karaoke set.
align
The alignment of the item on the screen after scrolling and before speech. Alignment is an enumerated value with the following options:
Alignment | Description |
---|---|
first |
The top/left side of the item will be placed at the top/left side of the scrolling container. |
center |
The center of the item will be placed in the center of the container. |
last |
The bottom/right side of the item will be placed at the bottom/right side of the scrolling container. |
visible |
The item will be moved the minimal distance necessary to bring it fully into view. |
componentId
The ID of the parent component. If omitted, the component issuing the SpeakList
command is used.
count
The number of items to speak. The command does not run if the count is less than 1 (no scrolling, no speech). If the count is larger than the number of remaining items in the container, it is trimmed to the maximum number of items that can be spoken from the starting point.
minimumDwellTime
The minimum amount of time in milliseconds that an item will be highlighted (that is, have the karaoke
state set to true
). This defaults to 0.
start
The 0-based index of the first child item in the parent container to scroll into view and speak. Negative values are measured from the end of the parent container. This example the last three items in a list:
{
"type": "SpeakList",
"start": -3,
"count": 3
}
The following algorithm approximates how the reading is done.
let first = start < 0 ? start + children.length : start;
let last = Math.min(first + count, children.length – 1);
first = Math.max(0, first);
for (let index = first ; index <= last ; index++) {
let child = children[index];
scrollIntoView(child);
if (child.speech) {
child.setState("karaoke", true);
speakChildWithMinimumDwell(child, minimumDwellTime);
child.setState("karaoke", false);
}
else if (minimumDwellTime > 0) {
child.setState("karaoke", true);
waitForTimeout(minimumDwellTime);
child.setState("karaoke", false);
}
}
Last updated: Nov 28, 2023