• Announcing The Alexa Skills Kit for Node.js
  • Originally written by David Isbitski
  • The Nuggets translation Project
  • Permanent link to this article: github.com/xitu/gold-m…
  • Translator: Yuhanlolo
  • Proofreader: Yqian1991, DateBro

We are pleased to announce today the release of a new Node.js-based Alexa-SDK designed to make it easier and faster for developers to develop Alexa Skill. Developing Alexa Skill through the Alexa Skills Kit, Node.js, and AWS Lambda has become the most popular skill development method today. The event-driven, non-blocking nature of Node.js makes it ideal for developing Alexa skill, and Node.js is one of the largest open source systems in the world. In addition, Amazon Web Services (AWS) Lambda, which offers a free service for the first 1 million web requests per month, allows most developers to work on Skill. You don’t need to worry about managing any SSL certificates while using AWS Lambda (because the Alexa Skills Kit is a trigger trusted by AWS).

Adding Node.js and the Alexa Skills Kit to create an Alexa skill using AWS Lambda is a simple process, but the code you actually need to write is much more complex than that. We’ve realized that most of the time developing skill is spent dealing with session properties, skill state persistence, creating replies, and behavior patterns. Therefore, the Alexa team set out to develop a Node.js-based Alexa Skills Kit SDK to help you avoid these common worries and focus on developing your skill’s own logic rather than boilerplate coding.

Speed up Alexa Skill development with the Node.js-based Alexa Skills Kit (Alexa-SDK)

With alexa-SDK, our goal is to help you develop skills faster without unnecessary complexity. The latest version of the SDK we are releasing today has the following features:

  • The new SDK is a managed NPM installation package that simplifies development in any Node.js environment
  • Alexa replies can be created from built-in events
  • Helper events are built into the new session and unhandled events are added to catch any exceptions
  • Helper functions for building state machine-based handling of intents
  • This makes it possible to define different event managers based on the current skill state
  • The configuration of property persistence is made easier with the help of Amazon DynamoDB
  • All outgoing voice messages are automatically encapsulated in SSML
  • Lambda events and context objects will be read through this.event, and built-in functions can be rewritten using this.contextAbility to make your state management and response creation more flexible. For example, store state attributes on AWS S3.

Install and debug node.js-based Alexa Skills Kit (Alexa-SDK)

Alexa-sdk has been uploaded to Github and can be installed in your Node.js environment as a Node package with the following commands:

npm install --save alexa-sdk
Copy the code

To get started with alexa-SDK, you need to access its libraries first. You simply create a file called index.js in your project and add the following code:

var Alexa = require('alexa-sdk');

exports.handler = function(event, context, callback){

    var alexa = Alexa.handler(event, context);

};
Copy the code

These lines of code will import the Alexa SDK and create an Alexa object for us to use later. Next, we need to deal with the ️ Intent that interacts with skill. Fortunately, alexa-SDK makes it easy to activate a function on the Intent we want. For example, to create an event manager for the ‘HelloWorldIntent’ service, we simply implement it with the following code:

var handlers = {

    'HelloWorldIntent': function () {

        this.emit(':tell'.'Hello World! '); }};Copy the code

Notice the appearance of a new syntax rule “:tell”? Alexa – SDK to follow the tell/ask The response of the way to generate your (HTTP: / / https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/alexa-skills-kit-interfac E – reference# Response Format). If we want to ask the user a question, we need to change the above code to:

This. Emit (' :ask ', 'What would you like todo? Please say that again. ');Copy the code

In fact, many of the responses your skill generates follow the same grammar rules. Here are some common examples of skill reply generation:

var speechOutput = 'Hello world! ';

var repromptSpeech = 'Hello again! ';

this.emit(':tell', speechOutput);

this.emit(':ask', speechOutput, repromptSpeech);

var cardTitle = 'Hello World Card';

var cardContent = 'This text will be displayed in the companion app card.';

var imageObj = {

    smallImageUrl: 'https://imgs.xkcd.com/comics/standards.png',

    largeImageUrl: 'https://imgs.xkcd.com/comics/standards.png'

};

this.emit(':askWithCard', speechOutput, repromptSpeech, cardTitle, cardContent, imageObj);

this.emit(':tellWithCard', speechOutput, cardTitle, cardContent, imageObj);

this.emit(':tellWithLinkAccountCard', speechOutput);

this.emit(':askWithLinkAccountCard', speechOutput);

this.emit(':responseReady'); // Called before returning to Alexa service after reply creation. Calls: saveState. this.emit(':saveState'.false); // The event manager stores the contents of this. Attributes and the current manager state into DynamoDB, and then sends the previously built-in response to the Alexa service. If you want to handle persistent state in a different way, you can override it. The second property is optional and can be set to 'true'to force storage. this.emit(':saveStateError'); // called when the procedure storing state fails. If you want to handle the exception yourself, you can override it.Copy the code

Once we have created the event managers, in the NewSession (NewSession) scenario we need to register them with the registerHandlers function in the alexa object we created earlier.

exports.handler = function(event, context, callback){

    var alexa = Alexa.handler(event, context);

    alexa.registerHandlers(handlers);

};
Copy the code

You can also register multiple event managers at the same time. Instead of creating a single manager object, we create a new session with a number of different managers that handle different events, and we can register them all at the same time with the following code:

alexa.registerHandlers(handlers, handlers2, handlers3, ...) ;Copy the code

The event managers you define can call each other to ensure that your skill responses are uniform. Here is an example where both LaunchRequest and IntentRequest (in HelloWorldIntent) return a “HelloWorld” message.

var handlers = {

    'LaunchRequest': function () {

        this.emit('HelloWorldIntent');

    },

    'HelloWorldIntent': function () {

        this.emit(':tell'.'Hello World! ');

};
Copy the code

Once you have registered all the intent manager functions, you simply run the skill logic using the execution functions in the Alexa object. The last line of code looks like this:

exports.handler = function(event, context, callback){

    var alexa = Alexa.handler(event, context);

    alexa.registerHandlers(handlers);

    alexa.execute();

};
Copy the code

You can download the full example from Github. We also provide the latest examples of skill developed based on Node.js and Alexa-SDK: Fact, HelloWorld, HighLow, HowTo and Trivia.

Make Skill’s state management easier

Alexa-sdk passes the incoming intent to the correct manager function based on the current state. It’s really just a simple string in the session property that represents the state of the skill. When defining an Intent manager, you can mimic this built-in delivery process by adding a string of states to the name of the intent, but alexa-SDK actually does this for you.

For example, let’s create a simple number guessing game with “start” and “guess” states based on the previous example of managing new session events.

var states = {
    GUESSMODE: '_GUESSMODE', // User is trying to guess the number.
    STARTMODE: '_STARTMODE'// Prompt the user to start or restart the game. }; // The following code will cut off any incoming intents or start requests and pass them to the manager.'NewSession': function() {

    this.handler.state = states.STARTMODE;

    this.emit(':ask'.'Welcome to The Number Game. Would you like to play? . '); }};Copy the code

Note that when a new session is created, we simply set the skill state to STARTMODE via this.handle. state. The skill state is automatically persisted in session properties. If you set the table in DynamoDB, you can choose to persist it across sessions.

It’s worth noting that NewSession is a great manager for capturing various behaviors and is a great skill portal, but it’s not required. NewSession is only awakened in a function named after it. Each state you define can have its own NewSession manager, which is invoked when you use built-in retention. In the example above, we can be more flexible in defining different NewSession behaviors for states.STARTMODE and states.GUESSMODE.

To define the intents of the skill in different states, we need to use the alexa.createstateHandler function. Any intent managers defined here will only work in a specific state, giving us more flexibility in our development!

For example, if we are in the GUESSMODE state defined above, we want to process user responses to a question. This can be done through StateHandlers, like this:

var guessModeHandlers = Alexa.CreateStateHandler(states.GUESSMODE, {

    'NewSession': function () {

        this.handler.state = ' ';

        this.emitWithState('NewSession'); // same as NewSession handler in Start Mode},'NumberGuessIntent': function() {

        var guessNum = parseInt(this.event.request.intent.slots.number.value);

        var targetNum = this.attributes["guessNumber"];

        console.log('user guessed: ' + guessNum);



        if(guessNum > targetNum){

            this.emit('TooHigh', guessNum);

        } else if( guessNum < targetNum){

            this.emit('TooLow', guessNum);

        } else if(guessNum === targetNum){// Use arrow to store the correct 'this' context this.emit('JustRight', () => {

                this.emit(':ask', guessNum.toString() + 'is correct! Would you like to play a new game? '.'Say yes to start a new game, or no to end the game.'); })}else {

            this.emit('NotANum'); }},'AMAZON.HelpIntent': function() {

        this.emit(':ask'.'I am thinking of a number between zero and one hundred, try to guess and I will tell you' +

            ' if it is higher or lower.'.'Try saying a number.');

    },

    'SessionEndedRequest': function () {

        console.log('session ended! ');

        this.attributes['endedSessionCount'] + = 1; this.emit(':saveState'.true);

    },

    'Unhandled': function() {

        this.emit(':ask'.'Sorry, I didn\'t get that. Try saying a number.', 'Try saying a number.'); }});Copy the code

On the other hand, if we are in STARTMODE, I can define StateHandlers as follows:

var startGameHandlers = Alexa.CreateStateHandler(states.STARTMODE, {

    'NewSession': function () {

        this.emit('NewSession'); // Use the newSessionHandlers handler},'AMAZON.HelpIntent': function() {

        var message = 'I will think of a number between zero and one hundred, try to guess and I will tell you if it' +

            ' is higher or lower. Do you want to start the game? ';

        this.emit(':ask', message, message);

    },

    'AMAZON.YesIntent': function() {

        this.attributes["guessNumber"] = Math.floor(Math.random() * 100);

        this.handler.state = states.GUESSMODE;

        this.emit(':ask'.'Great! ' + 'Try saying a number to start the game.'.'Try saying a number.');

    },

    'AMAZON.NoIntent': function() {

        this.emit(':tell'.'Ok, see you next time! ');

    },

    'SessionEndedRequest': function () {

        console.log('session ended! ');

        this.attributes['endedSessionCount'] + = 1; this.emit(':saveState'.true);

    },

    'Unhandled': function() {

        var message = 'Say yes to continue, or no to end the game.';

        this.emit(':ask', message, message);

    }
Copy the code

We can see that Amazon. YesIntent and Amazon. NoIntent are not defined in the guessModeHandlers object because yes or no replies are meaningless for that state. Such a reply will be caught by the ‘Unhandled’ manager.

Also, note the different behavior between the NewSession and Unhandled states. In this game, we “reset” the state of skill by calling the NewSession manager in the newSessionHandlers object. You can also skip this step, and alexa-SDK will call the Intent manager for the current state. You just need to remember to register your state managers before calling Alexa.execute () or they won’t be found.

All attributes will be saved automatically when your skill terminates the session, but if the user terminates the current session, you will need to emit the ‘:saveState’ event (this.emit(‘ :saveState ‘, true) to force saving these attributes. You should do this in the SessionEndedRequest manager, because the SessionEndedRequest manager will be called when the user terminates the current session by “exiting” or replying to a timeout. You can check out the code sample above.

We wrote the above example in a high/low guess number game, which you can download here.

Persist Skill attributes through Amazon DynamoDB

Many people like to store session attribute values in a database for later use. Alexa-sdk directly incorporates Amazon DynamoDB (a NoSQL database service) to allow you to store properties with just a few lines of code.

Simply set a name for the DynamoDB table in the Alexa object before you call Alexa.execute.

exports.handler = function(event, context, callback) { var alexa = Alexa.handler(event, context); alexa.appId = appId; Alexa. DynamoDBTableName = YourTableName"'; / / That 's it! alexa.registerHandlers(State1Handlers, State2Handlers); alexa.execute(); };Copy the code

After that, you simply call Attributes of the Alexa object to set a value for your property. No additional input is needed to get a separate function!

This. The attributes [" yourAttribute"] = ’value’;
Copy the code

You can manually create a table ahead of time or give your Lambda function DynamoDB permission to create a table and everything will be generated automatically. Keep in mind, however, that it may take a few minutes to create the form the first time you wake up skill.

Try expanding the number guessing game:

  • Let it store the average of your guesses every time you play
  • Add sound effects
  • Give players a limited amount of time to guess numbers

For more information on learning to develop with the Alexa Skills Kit, check out the following links:

Introduction to Alexa Skills Alexa Skills Kit (ASK) 101 Voice interaction design guidelines Developer forum

-Dave (@TheDaveDev)

If you find any mistakes in your translation or other areas that need to be improved, you are welcome to the Nuggets Translation Program to revise and PR your translation, and you can also get the corresponding reward points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.


The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, front-end, back-end, blockchain, products, design, artificial intelligence and other fields. If you want to see more high-quality translation, please continue to pay attention to the Translation plan of Digging Gold, the official Weibo, Zhihu column.