Alexa Skill with NodeJs, Part III : Rapid Development tools
I asked, Alexa, how can I develop your skills locally? She kept mum.
Amazon has provided us with everything we need from very helpful Alexa Skill Console to cloud service like lambda. The only thing it failed to do is providing tools for developing Alexa skills locally.
When I first started out, I was very much frustrated than excited. I had to make changes to my interaction model in Alexa Skill Console. Zip my code and upload that big chunk of a file to lambda. Then use test simulator to send a request to lambda. After that, if code breaks, go to CloudWatch logs and check for all the console logs I’ve put in my code. Any If anything is failing, repeat all these steps again.What’s in this article?
In this article, I will discuss some tools which I’ve found and created during my frustration phase.
Then I will talk about alexa-skill-local, a tool to make a local server on your system which Alexa can directly talk with. This way you can use the debugger in your favorite editor for rapid development.
This is the part in series “Alexa Skill with NodeJs”. I already discussed the flow of a basic Alexa Skill in my previous article with FlashCards. If you want to follow along with, clone this project from my GitHub repo.
Writing test cases
Mocha require test folder in root directory of your project.
Test cases are written in invocation.js and practiceIntent.js. Request event JSON are in events folder and are classified according to intent it belongs.
You can grab these JSON files from Alexa Skill Console’s test simulator. Say “open flash cards”. Then Copied JSON input and pasted it in invocationEvent.json file.
Similarly I’ve have done this for PracticeIntent. Pasted JSON input in practiceEvent.json file.
Setting up dependencies
Now before we move on to write test cases, we need to setup few things:
- DynamoDB Local
- chai and mocha
DynamoDB Local lets you develop your application locally without the need of accessing DynamoDB’s web service. Download any of the archives from here. Unzip. Now enter root directory, where you have extracted the archive. Open terminal and type following command (Make sure you have latest JDK or JRE):
java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb -port 3333
If you see something like this in your terminal, your DynamoDB service is now running on port 3333.
You need to adjust your code like this to tell your code to talk to local DynamoDB in the development environment.
You will also need to set value of NODE_ENV as production in lambda console to make sure it won’t break while attempting to connect DynamoDB’s web service.
Now install aws-lambda-mock-context.
npm install aws-lambda-mock-context --save-dev
This package provides you with the mock context of lambda wrapped in a promise. We will need it to pass context object to our lambda handler function.
Install chai and mocha.
npm install chai mocha --save-dev
Understanding the code
We have imported context from aws-lambda-mock-context. In before hook, handler function is called. Handler function is the exported in index.js file. It is the first thing lamda calls and provides event request object and context. In our case, we have given the content of invocationEvent.json as a first parameter and ctx object as a second parameter. Then we are completing the before hook by calling done function after getting response or error.
speechResponse contains a response object after successful execution of handler function or else if the execution fails, speechError is populated with the error produced.
Similar steps are followed for practiceIntent.js.
You can find full code here.
Make sure you have added test script in package.json as follows.
Run following command in root directory.
npm run test
If everything goes well you will have following output:
And there, you have written your test cases successfully and everything works on local just fine. Be sure to mock other things in development just like we did with DynamoDB Local.
Necessity is the mother of invention.
Test cases come real handy when dealing with the big project. But what about debugging. You can’t just run all your test cases to debug a small issue.
Wouldn’t it be amazing, if Alexa can talk to your code on the local system? Well, it’s possible with alexa-skill-local. I developed alexa-skill-local to get rid of all the problems associated with not being able to test and debug rapidly on AWS Lambda.
Here’s how alexa-skill-local works.
Install globally (recommended) or use it as a dev-dependency in you project (in this case you might want to use it in a npm script).
Update: In case of mac and ubuntu, if you are facing EAccess error, install it locally and use it in npm script.
npm install -g alexa-skill-local
Also add asl-config.json file in your root directory with following contents (in most cases stage is development):
Make sure you have main field in a package.json indicating your lambda entry file or at least index.js file in root directory. If you don’t have both, specify entry file with
Then go to the root directory of our lambda code and run following command.
You will be prompted to open
http://localhost:3001 in your browser. Go there and login with Amazon. This gives alexa-skill-local a permission to update Alexa Skill Endpoint.
After your authentication, alexa-skill-local will start ngrok.
Your Alexa Skill Endpoint will be automatically updated with ngrok URL. After that, a mock lambda service will run on local host on the same port ngrok is listening to. All the traffic to and fro on local host will be tunneled through ngrok.
Whenever you make any changes in your project files, mock lambda service will restart in response to those changes in respective files. This enables you to develop your skills rapidly.
You can also inspect these files with your favorite editor. Just add
--inspect-brk while running alexa-skill-local. Debugger will listen on default port 9229.
I prefer VSCode to attach debugger. You can use something of your choice. For VSCode, add this configuration to your launch.json file under .vscode folder.
Press ctrl+shift+D. It will open a debugger window. Make sure debugger configuration is selected as alexa-skill-local in top left corner. Click on green arrow and select process which starts with something like this:
Now set your breakpoints. Whenever request comes on your mock lambda service these breakpoints will be hit.
That’s all! Hope this articles will help you speed up your development. Check out alexa-skill-local’s documentation for more options.
This is the final article in the series “Alexa Skill with NodeJs”. First part was about setting up Alexa Skill and AWS Lambda. In the second part, I discussed ASK CLI functionalities and the basic flow of how Alexa Skill works. Check them out if you haven’t already.
Questions? Feedback? Comments? Leave a note here or contact me on twitter @Akshay_Milmile.