Alexa Project Name Generator on OpenWhisk

I’m having lots of fun with my Amazon echo and echo dots, creating skills for them. Initially I used Amazon’s lambda platform since that’s a very easy way to get started – but I’m an advocate for IBM and was looking for an excuse to play with OpenWhisk (an open source serverless offering that Bluemix has a hosted version of) anyway so this was a great opportunity!

Configuring Skills

There are a bunch of good resources around for setting up skills, picking the name, configuring the “invocation” which is what to say to make the code happen, and so on. I’ll skip this section and instead just share a couple of tutorials that I rely on a lot:

Once your skill is configured, it’s time to write the code (note: UK users need to pick English (UK) and not English (US) as otherwise your skill will mysteriously fail in your home region. Guess how I learned that??)

Writing The Code

I made a very simple project, just something I could play with and see it working: it’s a project name generator. When you start a new project, what’s the first thing you need? A project codename, of course! There’s already a library for it so I am using that to get me started quickly, and all my code is on GitHub if you want to grab it, use it, whatever. Note that since my skill isn’t published, I don’t need the certificate verification steps – Jordan’s blog post that I linked above has good info on how that process works.

To deploy code to OpenWhisk (I’m using NodeJS again in this example), we need to have some kind of entry point so it knows what to call. I’ve got a function called main that is then exported. The file is called index.js – it doesn’t have to be but if it isn’t, then set the “main” property in package.json to say which file to use, and include package.json in the zip file you upload to openwhisk.

function main(args) {
  var generate = require('project-name-generator');
  var random = generate().spaced;

  console.log(random);

  var response = {
    "version": "1.0",
    "response" :{
      "shouldEndSession": true,
      "outputSpeech": {
        "type": "PlainText",
        "text": "project codename. " + random
      }
    }
  }

  console.log(response);

  return(response);
}

exports.main = main;

This code simply requires the library we’re going to use, generates a project codename, logs it, and returns a formatted response as the Alexa skill expects it to be.

Managing Dependencies

OpenWhisk has a selection of pre-installed dependencies, but it doesn’t run npm install itself as usually happens when deploying NodeJS to a cloud runtime. Instead, we need to include the node_modules folder if we want to include dependencies that aren’t already offered. To achieve this, we upload a zip file instead of a simple JS file as you might have seen in the beginner tutorials. I use a shell script called build.sh to make sure I always get the right files in the zip and update the correct action every time:

#!/bin/bash

zip -r project-codename.zip index.js node_modules

wsk action update --kind nodejs:6 alexa/project-codename project-codename.zip

The zip line creates a file called project-codename.zip and puts both index.js and (recursively with the -r switch) the node_modules folder into it. Then we use the OpenWhisk CLI to update the action (and if you try to do this to an action that doesn’t exist, it will kindly create it instead!). The --kind switch is needed with all zip files so OpenWhisk knows what to run the code with, and my action name is made up of a package called alexa and then the action that I want to create inside my package.

What I find with this setup is that:

  • I can edit locally using my chosen tools
  • It’s one step to put a new version of packaged code onto the server

Developing on the cloud can be annoying and slow but this works pretty well for me. See also: my script for inspecting the logs of the action that just ran.

Create a Web Route To OpenWhisk

This action is great but right now we can only invoke it from the commandline (try it! wsk action invoke --blocking alexa/project-codename) and Alexa sends POST requests to skills. We need to create a route to our action, and we’ll use the OpenWhisk API for that.

wsk api-experimental create /api /codename post alexa/project-codename

What just happened? We’re using the CLI tool to create a route, the arguments are:

  • /api a base path that we can group things together by
  • /codename a name for this specific endpoint
  • post the verb(s) to support
  • alexa/project-codename the action to call (in this case in the format [package name] / [action name].

The response from this command will give you the URL that you can call – I like to give mine a quick test with cURL:

curl -X POST https://1dce54ec-5105-4093-a098-85a84c725364-gws.api-gw.mybluemix.net/api/codename

Put the URL in the Configuration Tab in the Alexa Developer Console and now when your Alexa skill is triggered, the openwhisk action will be invoked and the response returned, yay! From my sample code (way up the page somewhere), you can see that the response returned from this example code simply has Alexa say “project name” and then whatever random combination of words we just generated. Try it (lots of times, she’s pretty funny).

This was quite a lightweight (and not terribly useful) example but hopefully it shows you how to setup an Alexa skill and an OpenWhisk action, then make your action web-requestable and wire it up to the Alexa skill. I’m sure you can think of your own more useful actions that could be called by a skill as well – leave me a comment and let me know what you build!

Leave a Reply

Please use [code] and [/code] around any source code you wish to share.

This site uses Akismet to reduce spam. Learn how your comment data is processed.