Build Your Web App with Web API for Games
You can use the Alexa Web API for Games to build voice-enabled games with JavaScript, HTML5, CSS, and Web Audio. You can use well-known techniques and tools to manage graphics and audio. Add animation with HTML and CSS, Canvas, SVG, and WebGL. Developers have numerous JavaScript game frameworks and libraries from which to choose. The following list shows some popular options:
- Phaser – game framework for Canvas and WebGL
- Pixi.js – game framework and 2D graphics using WebGL
- three.js – 3D library and app framework using WebGL
- Howler.js – audio library
Build with the Alexa Web API for Games
To create a game with the Alexa Web API for Games, your web app must be able to display in a browser and interact with users.
Host your web app and associated assets at an internet-accessible HTTPS
endpoint. The web server must present a valid and trusted SSL certificate to the Alexa device. To decrease latency and enhance the gaming experience, use a storage solution and a content delivery network with edge locations around the world. For example, Amazon S3, Amazon CloudFront, or any web server that hosts HTTPS.
You can design your game to include game logic in either the web app or in the skill backend. To communicate with the skill, use the Alexa JavaScript API in your app .
Add the Alexa JavaScript library to your app
To load the Alexa JavaScript library, include the URL in a script tag on your HTML page, as shown in the following example.
<head>
<script src="https://cdn.html.games.alexa.a2z.com/alexa-html/latest/alexa-html.js"></script>
</head>
Create the Alexa client
Your app communicates with the device and with your skill with the Alexa Client
object. To prevent the client from being available before it's ready to serve requests, create the Alexa Client
object with a static factory function. Invoke the function one time on each page.
The following example shows Alexa Client
object initialization.
var alexaClient;
Alexa.create({version: '1.1'})
.then((args) => {
const {
alexa,
message
} = args;
alexaClient = alexa;
document.getElementById('debugElement').innerHTML = 'Alexa is ready :)';
})
.catch(error => {
document.getElementById('debugElement').innerHTML = 'Alexa not ready :(';
});
Communication between your skill and your web app
While the user interacts with your web app, you can send messages between your web app running on the device and the skill back end. This communication allows the Alexa skill to hold some game logic, send local inputs, receive voice inputs, and incorporate in-skill purchases. Use the Alexa.Presentation.HTML.Message
directive and the Alexa.Presentation.HTML.HandleMessage
event in your skill to communicate with the web app.
In your web app, use the Alexa client
and the sendMessage
and onMessage
JavaScript APIs to communicate with your skill. The Alexa JavaScript API lets your web app register additional handlers to listen for other events, such as when Alexa begins and ends speech. You can use these handlers to build the flow between on-screen events, for example, button presses and voice commands. For details, see Add Voice Control and Speech to the Web App.
End the web app session
When the device displays your game, your app remains active on the screen until one of the following actions occurs:
- The user ends the skill session or the game.
- The skill ends the session.
- The skill uses an interface other than
Alexa.Presentation.HTML
.
Test your skill and the web app
You can use Chrome DevTools on your development computer to debug your skill's web app that's running on an Amazon Fire TV device. For details, see Using Web App Tester and DevTools.
Best practices
General best practices for building websites apply to the web app used with your Alexa skill.
- Use a storage solution and a content delivery network to store and cache your assets across servers worldwide, close to where your players are. Keeping your web server at edge locations greatly reduces potential latency associated with your players' experience.
- The device displays an initial flash of white when the WebView browser starts. You can't control the flash.
- Set a background color or page style while your assets load to let the user know that your game is getting ready to use.
- To avoid a "flashing" effect, keep the background color consistent during loading and when your app is ready for use.
- The device caches assets according to the cache-control header. Make sure to account for the cache in development and use it in production.
- Players might prefer to use their voice for some interactions and touch for others. Consider adding optional corresponding touch interactions for some core game controls. You have full control over most Document Object Model (DOM) events in your web app.
- You can design your game to include game logic either in the web app or in the skill backend. To communicate with the skill, use the Alexa JavaScript API in your app.
- Use web audio to have dynamic control over the playback of your sounds over multiple turns in the conversation.
- If you are using web audio, consider that it doesn't reduce volume by default. Be sure to listen to the voice events to reduce the volume so it doesn't interrupt your player when they're trying to speak. Also, listen to the speech events, so you can reduce the volume of web audio when Alexa is speaking
- If your skill uses both Web API for Games and Alexa Presentation Language (APL), make sure to save any state information needed for your game. Both APL and the web app can't run on the device at the same time. You incur the startup latency cost to your web app every time you transition from APL to the web app.
For a sample project, see the My Cactus Simulation Alexa Game on github.com.
Restrictions of the HTML environment
The Web API runtime on the device disables the following browser capabilities:
- Content URL access
- Geolocation in the browser
- Loading a URL from a file,
file://</path>
- Local file API
- Local storage
- Non-HTTP assets/URI. HTTPS is required.
- SpeechRecognition with the Web Speech API
- Web SQL database
- alert(), prompt(), confirm() with JavaScript
- getUserMedia (camera, mic)
The Web API runtime on the device allows the following browser capabilities:
- Automatic media playback
- Cookies
- Form data
- History
The runtime clears cookies, form data, and history at the end of the skill session.
Alexa Objects
Client
The Alexa Client
object provides interfaces to communicate with your skill and with the device. See the Alexa JavaScript API for more details.
Client object details
Property | Description | Type |
---|---|---|
capabilities |
The device capabilities. | A Capability object |
performance |
Provides the interface to get the available memory on the device. For details, see performance |
A Performance object. |
skill |
Provides the interfaces to communicate with your skill. For details, see onMessage and sendMessage . |
A Skill object. |
speech |
Provides the interfaces to receive Alexa speech events. For details, see Alexa Speech Input. |
A Speech object. |
version |
Version of the Alexa client. If you don't specify a version, the latest version is used. |
string |
voice |
Provides the interfaces to open the microphone on the device to receive user utterances. For details, see Alexa Voice. |
A Voice object. |
Capability
The Capability
object provides information about the device.
Capability object details
Property | Description | Type |
---|---|---|
microphone |
Capabilities of the microphone on the device. | A Microphone object |
Microphone
The Microphone
object provides information about the device.
Microphone object details
Property | Description | Type |
---|---|---|
supportsPushToTalk |
Specifies whether the microphone activates when a user presses a physical button on the device or when a user uses a remote. | boolean |
supportsWakeWord |
Specifies whether the microphone activates when a users says a wake word. When set to true , the web app can use the Voice interface to initiate microphone events. |
boolean |
AlexaReadyPayload
The promise resolve result from a successful create
invocation.
AlexaReadyPayload details
Property | Description | Type |
---|---|---|
alexa |
The initialized and ready Alexa client. | An Alexa client object |
message |
Start up information provided by the skill. The JSON value from the data property of the Start directive. |
any |
SendResponse
The callback receives the response to the sendMessage
interface in a SendResponse
object. For details, see sendMessage
.
SendResponse details
Property | Description | Type |
---|---|---|
statusCode |
The HTTP status code that indicates the status of the received message from the skill. Valid values: 200 (OK), 401 (Unauthorized), 429(Too Many Requests), 500 (Internal Server Error/Unknown Error) |
integer |
reason |
A text string that describes the error value found in the statusCode property. |
string |
rateLimit |
The limit on the number of outgoing requests from your web app. | A RateLimit object |
RateLimit
The RateLimit
object defines the limit on the number of outgoing requests from your web app.
RateLimit details
Property | Description | Type |
---|---|---|
maxRequestsPerSecond |
The maximum allowed requests per second. | integer |
remainingRequests |
The number of requests that might be delivered before the rate limiter blocks messages. 0 indicates no more messages are allowed. |
integer |
timeUntilNextRequestMs |
The number of milliseconds until your app can send the next message. | integer |
timeUntilResetMs |
The number of milliseconds until remainingRequests equals maxRequestsPerSecond. | integer |
Alexa interfaces
capabilities
Check the device capabilities using the capabilities
interface.
The following example shows a check for PushToTalk capability using a Microphone
object.
if (alexaClient.capabilities.microphone.supportsPushToTalk) {
// Prompt the user to press the microphone button
...
};
create
Establish the connection to Alexa on the device using the create
interface as shown. create
invokes the success
function and returns a promise fulfilled by AlexaReadyPayload
or rejects the promise and invokes the failure
function.
let client;
Alexa.create({version?: "1.1", messageProvider?: new Alexa.DefaultMessageProvider()})
.then(success)
.catch(failure);
create interface details
Property | Description | Type |
---|---|---|
version |
(Optional) Version of the Alexa client. Requesting an invalid version is rejected with no-such-version error code. |
string |
messageProvider |
(Optional) Used for simulation or testing. | A MessageProvider object |
AlexaReadyPayload |
Fulfilled with an AlexaReadyPayload object. |
promise |
success |
Invoked when create() is successful. |
The success method |
failure |
Invoked when create() fails. |
The failure method |
The create
method invokes the success
function when it successfully creates the Alexa client in AlexaReadPayload
as shown. The message
contains data sent from the skill.
const success = function(result) {
const {alexa, message} = result;
// Actions after Alexa client initialization is complete
};
The create
method invokes the failure
function when it fails to create the Alexa client as shown.
const failure = function(error) {
const {
code,
message
} = error;
// Actions for failure to initialize
};
failure interface details
Property | Description | Type |
---|---|---|
code |
Error code that shows the reason to fail to create the Alexa client . Valid values: no-such-version , unauthorized-access , too-many-requests , unknown |
string |
message |
A text string that describes the error value found in the code property. |
string |
performance
Use the performance interface to get the available memory on the device. This interface is useful in development for optimizing assets and debugging across device types.
The following example shows logging the available memory.
alexaClient.performance.getMemoryInfo().then((memInfo) => {
// log memInfo
});
onMessage
Use the alexaClient.skill.onMessage
to register a listener to handle messages sent from your skill. The messages sent to your listener are independent of the messages your app sends to your skill. The format of the message
sent from the skill is agreed on between the app and the skill. The app can only register one callback, so the callback function should include logic to handle different messages based on the data provided within the message
.
Messages can't be received until you register the listener. If you need information from the skill on start-up, use the message
returned in the successful create
interface.
The following example shows registering a listener function called messageReceivedCallback
.
// Register a listener to receive a message from your skill
alexaClient.skill.onMessage(messageReceivedCallback);
// Implement the listener
const messageReceivedCallback = function(message) {
// Process message (JavaScript object) from your skill
};
onMessage interface details
Property | Description | Type |
---|---|---|
messageReceivedCallback |
The callback function used to process the received message . |
function |
message |
Any arbitrary data formatted by your skill. The JSON value from the data property of the HandleMessage directive. |
any |
sendMessage
To send a message to your skill from your web app, use alexaClient.skill.sendMessage
interface. The interface takes a data payload and an optional callback for handling the response. The API results in an Alexa.Presentation.HTML.Message
to your skill.
alexa.skill.sendMessage()
to catch throttling errors caused when your app exceeds this limit. The MessageSendResponse
returns error 429 (Too Many Requests) to your callback.The following example shows sending a message to the skill.
// Send a message to your skill
alexaClient.skill.sendMessage(message, messageSentCallback);
// Check the results of the SendMessage
const messageSentCallback = function(sendResponse) {
const {
statusCode,
reason,
rateLimit,
} = sendResponse;
// Handle response codes
};
sendMessage interface details
Property | Description | Type |
---|---|---|
message |
Any arbitrary data formatted by your app. The JSON value sent in the data property of the Message directive. |
any |
messageSentCallback |
The callback function used to process the results of the sendMessage . |
function |