Voxa

class Voxa(config)
Arguments:
  • config – Configuration for your skill, it should include Views and Variables and optionally a model and a list of appIds.

If appIds is present then the framework will check every alexa event and enforce the application id to match one of the specified application ids.

const skill = new Voxa({ Model, variables, views, appIds });
Voxa.lambda()
Returns:A lambda handler that will call your skill.execute method
exports.handler = skill.lambda();
Voxa.execute(event)

The main entry point for the Skill execution

Arguments:
  • event – The event sent by alexa.
  • context – The context of the lambda function
Returns Promise:
 

A response resolving to a javascript object to be sent as a result to Alexa.

skill.execute(event, context)
  .then(result => callback(null, result))
  .catch(callback);
Voxa.onState(stateName, handler)

Maps a handler to a state

Arguments:
  • stateName (string) – The name of the state
  • handler (function/object) – The controller to handle the state
Returns:

An object or a promise that resolves to an object that specifies a transition to another state and/or a view to render

skill.onState('entry', {
  LaunchIntent: 'launch',
  'AMAZON.HelpIntent': 'help',
});

skill.onState('launch', (alexaEvent) => {
  return { reply: 'LaunchIntent.OpenResponse', to: 'die' };
});
Voxa.onIntent(intentName, handler)

A shortcut for definining state controllers that map directly to an intent

Arguments:
  • intentName (string) – The name of the intent
  • handler (function/object) – The controller to handle the state
Returns:

An object or a promise that resolves to an object that specifies a transition to another state and/or a view to render

skill.onIntent('HelpIntent', (alexaEvent) => {
  return { reply: 'HelpIntent.HelpAboutSkill' };
});
Voxa.onIntentRequest(callback[, atLast])

This is executed for all IntentRequest events, default behavior is to execute the State Machine machinery, you generally don’t need to override this.

Arguments:
  • callback (function) –
  • last (bool) –
Returns:

Promise

Voxa.onLaunchRequest(callback[, atLast])

Adds a callback to be executed when processing a LaunchRequest, the default behavior is to fake the alexa event as an IntentRequest with a LaunchIntent and just defer to the onIntentRequest handlers. You generally don’t need to override this.

Voxa.onBeforeStateChanged(callback[, atLast])

This is executed before entering every state, it can be used to track state changes or make changes to the alexa event object

Voxa.onBeforeReplySent(callback[, atLast])

Adds a callback to be executed just before sending the reply, internally this is used to add the serialized model and next state to the session.

It can be used to alter the reply, or for example to track the final response sent to a user in analytics.

skill.onBeforeReplySent((alexaEvent, reply) => {
  const rendered = reply.write();
  analytics.track(alexaEvent, rendered)
});
Voxa.onAfterStateChanged(callback[, atLast])

Adds callbacks to be executed on the result of a state transition, this are called after every transition and internally it’s used to render the transition reply using the views and variables

The callbacks get alexaEvent, reply and transition params, it should return the transition object

skill.onAfterStateChanged((alexaEvent, reply, transition) => {
  if (transition.reply === 'LaunchIntent.PlayTodayLesson') {
    transition.reply = _.sample(['LaunchIntent.PlayTodayLesson1', 'LaunchIntent.PlayTodayLesson2']);
  }

  return transition;
});
Voxa.onUnhandledState(callback[, atLast])

Adds a callback to be executed when a state transition fails to generate a result, this usually happens when redirecting to a missing state or an entry call for a non configured intent, the handlers get a alexa event parameter and should return a transition the same as a state controller would.

Voxa.onSessionStarted(callback[, atLast])

Adds a callback to the onSessinStarted event, this executes for all events where alexaEvent.session.new === true

This can be useful to track analytics

skill.onSessionStarted((alexaEvent, reply) => {
  analytics.trackSessionStarted(alexaEvent);
});
Voxa.onRequestStarted(callback[, atLast])

Adds a callback to be executed whenever there’s a LaunchRequest, IntentRequest or a SessionEndedRequest, this can be used to initialize your analytics or get your account linking user data. Internally it’s used to initialize the model based on the event session

skill.onRequestStarted((alexaEvent, reply) => {
  alexaEvent.model = this.config.Model.fromEvent(alexaEvent);
});
Voxa.onSessionEnded(callback[, atLast])

Adds a callback to the onSessionEnded event, this is called for every SessionEndedRequest or when the skill returns a transition to a state where isTerminal === true, normally this is a transition to the die state. You would normally use this to track analytics

Voxa.onSystem.ExceptionEncountered(callback[, atLast])

This handles System.ExceptionEncountered event that are sent to your skill when a response to an AudioPlayer event causes an error

return Promise.reduce(errorHandlers, (result, errorHandler) => {
  if (result) {
    return result;
  }
  return Promise.resolve(errorHandler(alexaEvent, error));
}, null);

Error handlers

You can register many error handlers to be used for the different kind of errors the application could generate. They all follow the same logic where if the first error type is not handled then the default is to be deferred to the more general error handler that ultimately just returns a default error reply.

They’re executed sequentially and will stop when the first handler returns a reply.

Voxa.onStateMachineError(callback[, atLast])

This handler will catch all errors generated when trying to make transitions in the stateMachine, this could include errors in the state machine controllers, , the handlers get (alexaEvent, reply, error) parameters

skill.onStateMachineError((alexaEvent, reply, error) => {
  // it gets the current reply, which could be incomplete due to an error.
  return new Reply(alexaEvent, { tell: 'An error in the controllers code' })
    .write();
});
Voxa.onError(callback[, atLast])

This is the more general handler and will catch all unhandled errors in the framework, it gets (alexaEvent, error) parameters as arguments

skill.onError((alexaEvent, error) => {
  return new Reply(alexaEvent, { tell: 'An unrecoverable error occurred.' })
    .write();
});

Playback Controller handlers

Handle events from the AudioPlayer interface

audioPlayerCallback(alexaEvent, reply)

All audio player middleware callbacks get a alexa event and a reply object

Arguments:
  • alexaEvent (AlexaEvent) – The alexa event sent by Alexa
  • reply (object) – A reply to be sent as a response
Returns object write:
 

Your alexa event handler should return an appropriate response according to the event type, this generally means appending to the reply object

In the following example the alexa event handler returns a REPLACE_ENQUEUED directive to a PlaybackNearlyFinished() event.

skill['onAudioPlayer.PlaybackNearlyFinished']((alexaEvent, reply) => {
  const directives = {
    type: 'AudioPlayer.Play',
    playBehavior: 'REPLACE_ENQUEUED',
    token: "",
    url: 'https://www.dl-sounds.com/wp-content/uploads/edd/2016/09/Classical-Bed3-preview.mp3',
    offsetInMilliseconds: 0,
  };

  return reply.append({ directives });
});
Voxa.onAudioPlayer.PlaybackStarted(callback[, atLast])
Voxa.onAudioPlayer.PlaybackFinished(callback[, atLast])
Voxa.onAudioPlayer.PlaybackStopped(callback[, atLast])
Voxa.onAudioPlayer.PlaybackFailed(callback[, atLast])
Voxa.onAudioPlayer.PlaybackNearlyFinished(callback[, atLast])
Voxa.onPlaybackController.NextCommandIssued(callback[, atLast])
Voxa.onPlaybackController.PauseCommandIssued(callback[, atLast])
Voxa.onPlaybackController.PlayCommandIssued(callback[, atLast])
Voxa.onPlaybackController.PreviousCommandIssued(callback[, atLast])

Alexa Skill Event handlers

Handle request for the Alexa Skill Events

alexaSkillEventCallback(alexaEvent)

All the alexa skill event callbacks get a alexa event and a reply object

Arguments:
  • alexaEvent (AlexaEvent) – The alexa event sent by Alexa
  • reply (object) – A reply to be sent as the response
Returns object reply:
 

Alexa only needs an acknowledgement that you received and processed the event so it doesn’t need to resend the event. Just returning the reply object is enough

This is an example on how your skill can process a SkillEnabled() event.

skill['onAlexaSkillEvent.SkillEnabled']((alexaEvent, reply) => {
  const userId = alexaEvent.user.userId;
  console.log(`skill was enabled for user: ${userId}`);
  return reply;
});
Voxa.onAlexaSkillEvent.SkillAccountLinked(callback[, atLast])
Voxa.onAlexaSkillEvent.SkillEnabled(callback[, atLast])
Voxa.onAlexaSkillEvent.SkillDisabled(callback[, atLast])
Voxa.onAlexaSkillEvent.SkillPermissionAccepted(callback[, atLast])
Voxa.onAlexaSkillEvent.SkillPermissionChanged(callback[, atLast])

Alexa List Event handlers

Handle request for the Alexa List Events

alexaListEventCallback(alexaEvent)

All the alexa list event callbacks get a alexa event and a reply object

Arguments:
  • alexaEvent (AlexaEvent) – The alexa event sent by Alexa
  • reply (object) – A reply to be sent as the response
Returns object reply:
 

Alexa only needs an acknowledgement that you received and processed the event so it doesn’t need to resend the event. Just returning the reply object is enough

This is an example on how your skill can process a ItemsCreated() event.

skill['onAlexaHouseholdListEvent.ItemsCreated']((alexaEvent, reply) => {
  const listId = alexaEvent.request.body.listId;
  const userId = alexaEvent.user.userId;
  console.log(`Items created for list: ${listId}` for user ${userId});
  return reply;
});
Voxa.onAlexaHouseholdListEvent.ItemsCreated(callback[, atLast])
Voxa.onAlexaHouseholdListEvent.ItemsUpdated(callback[, atLast])
Voxa.onAlexaHouseholdListEvent.ItemsDeleted(callback[, atLast])