Implementing an Alexa skill requires a free developer account with Amazon as well as a secure web service. It is easier by far to let Amazon handle this with Amazon Web Services Lambda. Opening an AWS account requires entering a credit card number, but Amazon says explicitly this service is free for most developers.

Documentation for Alexa Skills Kit (ASK):

https://developer.amazon.com/alexa-skills-kit

Skills can be run by waking Alexa and uttering one of the supported launch words followed by the invocation name. Currently supported launch words include

Ask

Begin

Launch

Load Open

Play

Resume

Run Start

Tell

Use

Basic Steps for Implementing a Skill

Create a Lambda function in Amazon Web Services Enter debugged code in the online form or upload a .ZIP file of code with required Node.js modules Add Alexa Skills Kit as an event source for the function in the event sources tab and enable the source Copy the Amazon Resource Name (ARN) of the function Add a new skill in the Alexa section of apps in the Amazon Developer console Paste in the ARN of the AWS Lambda function when creating the new skill to link it with the AWS Lambda function Include a valid intent schema and sample utterances to enable the skill for testing The skill will appear in the Skills section of the Echo app if your developer account is linked to your main Amazon account

Hello World — Minimal Code

The samples provided by Amazon include a “Hello World” skill, but it is overly dense for what is meant to be the simplest program in any language. Very little code is actually needed to implement a traditional program:

exports.handler = function( event, context ) { var response = { outputSpeech: { type: "PlainText", text: "Hello World" }, card: { type: "Simple", title: "Hello World", content: "Alexa Skills Kit" }, shouldEndSession: true }; context.succeed( { response: response } ); };

This could technically be written on one line by putting the JSON response directly into the Node.js succeed method but would lose legibility.

Every skill requires an intent schema with at least one defined intent. The following minimal schema is sufficient for a functional skill:

{ "intents": [ { "intent": "Help", "slots": [] } ] }

Apparently intents need not include the word “intent” in their names. This minimal schema can be accompanied by the minimal sample utterance

Help help

and Alexa will respond appropriately when the skill is launched.

Who’s Your Daddy Now?

Although Amazon says explicitly to avoid invocation names that overlap with built-in services, it can be fun to do so. The “Hello World” code can be used to return any desired response, as for example in response to the above invocation name:

exports.handler = function( event, context ) { var response = { outputSpeech: { type: "PlainText", text: "(gratuitous response from Alexa)" }, card: { type: "Simple", title: "Who's Your Daddy Now?", content: "(gratuitous response from Alexa)" }, shouldEndSession: true }; context.succeed( { response: response } ); };

The same minimal intent schema and sample utterance can be used for a functional skill. Be aware that deliberately overlapping with built-in services can lead to erratic behavior depending on how well the invocation name is articulated.

Stock Quotes

A skill of this sort needs an online data source. The public Yahoo Query Language endpoint previously used for this skill was shut down in mid 2017, but an alternate Yahoo resource appears viable, easier to use and has more current information. First the appropriate URL is constructed by appending the array of stock symbols, then the data in HTTP GET response is assembled and parsed as JSON that can be used to construct a spoken response. As of early 2019 a secure request is required to avoid redirection errors.

The third-party Node.js request module could be used here for convenience in handling error messages, but that would require uploading a .ZIP file as opposed to this simple solution in a single file. The code for the output is the same as the last two examples, and has been separated as its own function to indicate this.

exports.handler = function( event, context ) { var stocks = [ 'AAPL', 'GOOG', 'AMZN' ]; var https = require( 'https' ); var url = 'https://query1.finance.yahoo.com/v7/finance/quote?symbols=' + stocks; https.get( url, function( response ) { var data = ''; response.on( 'data', function( x ) { data += x; } ); response.on( 'end', function() { var json = JSON.parse( data ); var text = 'Here are your stock quotes: '; for ( var i = 0 ; i < quoteResponse.result.length ; i++ ) { var quote = json.quoteResponse.result[i]; text += quote.longName + ' at ' + quote.regularMarketPrice + ' dollars, a change of ' + Math.round( 100 * quote.regularMarketChange ) / 100 + ' dollars. '; } output( text, context ); } ); } ); }; function output( text, context ) { var response = { outputSpeech: { type: "PlainText", text: text }, card: { type: "Simple", title: "Stocks", content: text }, shouldEndSession: true }; context.succeed( { response: response } ); }

The same minimal intent schema and sample utterance as for the previous two examples can again be used for a functional skill. The format of Alexa’s spoken response can be altered to taste. Having periods at the end of each quote provides a slight pause between quotes.

Financial information from this resource does not appear to be delayed.

Dow Jones Average

Unlike the Yahoo Query Language endpoint previously used for the last skill, the replacement source includes the Dow Jones Industrial Average in what appears to be real time. The code for this skill is mostly the same as for the last one. As of early 2019 a secure request is required to avoid redirection errors.

exports.handler = function( event, context ) { var https = require( 'https' ); var url = 'https://query1.finance.yahoo.com/v7/finance/quote?symbols=^DJI'; https.get( url, function( response ) { var data = ''; response.on( 'data', function( x ) { data += x; } ); response.on( 'end', function() { var json = JSON.parse( data ); var dow = json.quoteResponse.result[0]; var upDown = dow.regularMarketChange > 0 ? 'up' : 'down'; var text = 'The Dow Jones Industrial Average is ' + dow.regularMarketPrice + '. It is ' + upDown + ' ' + Math.abs( Math.round( 100 * dow.regularMarketChange ) / 100 ) + ' points, a change of ' + Math.abs( Math.round( 100 * dow.regularMarketChangePercent ) / 100 ) + ' percent.'; output( text, context ); } ); } ); }; function output( text, context ) { var response = { outputSpeech: { type: "PlainText", text: text }, card: { type: "Simple", title: "Dow Jones", content: text }, shouldEndSession: true }; context.succeed( { response: response } ); }

The same minimal intent schema and sample utterance can again be used for a functional skill.

Ask Wolfram

A PHP version of a skill to request information from WolframAlpha has inspired this version entirely in JavaScript. It uses the WolframAlpha API that is free for 2000 requests per month. It requires a free AppID that can be generated in the My Apps section of the Wolfram developer portal.

The skill can be invoked with and without a question. If no question is initially supplied, one will be prompted. The skill remains active for additional questions.

Node.js code for the AWS Lambda function: