Using Golang (Or Any Language) in Alexa Skills

The officially supported languages for Alexa Skill developer are JavaScript (through Node.js), Python, and Java. You can use any of these three using the ASK CLI.

However, since you can use any AWS Lambda function for your skill, or indeed any web endpoint at all, you can easily bring Alexa development into your team no matter what language you use.

This guide will walk through the process of setting up a Hello World Alexa Skill using Go. Since most of this guide is walking through the various dialogs (with pictures!), it applies to any language that can run on Lambda (which is practically anything at all).

A prerequisite here is that you have an AWS account and a Alexa Developer Console account (these are slightly different). Once you ensure you can sign in to both of these places, please proceed.

Creating a new Skill

From the Alexa Developer Console you should see a list of Alexa Skills. Click Create Skill to be taken to the new skill creation page (shown below).

From there we're going to use the custom model (the default). So the only thing you need to enter is the Skill name. I called mine Go Hello World.

Click Create Skill to proceed to the skill template page.

Page for creating a new Alexa skill

Choosing a template

The developer console has a few predefined skills for different types of things you might want to build. I've never used any of these, to be honest, but you might want to check them out just to see what is possible.

For this exercise stick with the pre-selected Start from scratch template and click on Choose to proceed.

Choosing a template for the new Alexa skill

Skill overview page

At this point you have created an Alexa Skill (congrats!) although it doesn't do anything yet. However if you were to exit out and come back to the Alexa Developer Console you'd see the Go Hello World skill in the list.

Highlighted in red below is the Skill builder checklist. It is all of the steps we need to walk through in order to get a testable version of the skill ready.

So start by clicking on 2. Intents, Samples, and Slots.

The skill overview page which shows the progress of building the Alexa skill

Adding an Intent

So a brief explanation of Intents. An intent is like a function. The function is called based on phrases that the user says.

So for example, if you were a pizza restaurant you might have a skill that had different intents for:

Each of these could be built as separate intents. For each intent you give Sample utterances, which are just things the user says that prompts the intent to be run.

Additionally you can provide slots. A slot is like an argument to a function. If you were a weather skill a slot might be the city the user wants weather for.

For our exercise, click to create a new Intent. Call it SayHello. In the sample utterances type hello world. This will be enough to get us started.

Then click on Build Model at the top which will build the model for this skill.

Creating a new Intent to map utterances to an Intent to launch

The Endpoint page

If you click on the blue Custom link in the sidebar it takes you back to the skill overview page. You should see 2. Intents, Samples, and Slots checked off now. The model is being built already and you don't need to do anything for 3..

Clicking on 4. Endpoint takes you to the page shown below. You can select between using a Lambda function or an HTTPS endpoint. Click on AWS Lambda ARN.

Now you'll see a few fields. You can use a different Lambda for each region if you like, or just use a default, which is what we'll do. Key here is the Skill ID. We'll need this in just a second when we connect the Lambda function.

Keep this browser tab open as we'll need to refer back.

The Alexa endpoints page is how you tell Alexa what to call when a skill's intent is launched

Creating a Lambda function

Having gone through the steps on the Alexa Developer Console side, we now need to build the Lambda function that will be triggered by Alexa. The AWS Lambda page shows a list of functions you have.

Click on Create function to create a new one.

The Lambda overview page shows a list of lambdas you've already created

Basic information

Create function, clicking function takes several seconds.

We need to give our function a name. It's conventional to name these in camel case, so goHelloWorld is the name I went with.

Change the runtime to Go 1.x and then click on Create function. It will take several seconds before you proceed to the next page as the function is being built.

Entering basic information for your lambda such as the name.

Lambda designer

Now we're at the Lambda designer page. If you've never used Lambda before it's worth briefly discussing how it all works.

A Lambda is a container of code that can be triggered by a variety of events. A function could be called from an HTTP request (using API Gateway). It could be called by a message queue (like SQS). Or be triggered when a new row in a database was added (in DynamoDB).

These are called triggers. In our case the trigger is Alexa Skills Kit. When a user utters the phrase that we defined in the developer console, the message is sent to the Alexa Cloud which sees that the skill is controlled by a Lambda function. It then triggers the Lambda to run and receives back a response.

So to set this up, click on Add trigger.

The Lambda designer page

Add trigger

Find Alexa Skills Kit from the dropdown menu. You will need to enter just one parameter, the Skill ID. Remember that we saw this previous in the Alexa Developer Console. Refer back to that tab and copy your Skill ID into this field. It looks like below:

Adding a trigger from the Alexa Skills Kit to call the Lambda function.

Saving this brings you back to the Lambda designer.

Link Lambda to Alexa

Above we linked our Alexa Skill ID to the Lambda function to act as a trigger. We also have to link the other way, and tell the Alexa skill what Lambda function to run.

As shown below, the ARN is listed at the top of the Lambda designer page. The ARN is the unique identifier for the Lambda function. Clicking on the icon to the right will copy it to your clipboard.

Paste this into the Default region field in the Alexa Developer Console Endpoints page and then click Save endpoints.

Copying the Lambda ARN to enter into the Alexa Developer Console

Writing the Code

At this point we've walked through all of the manual UI steps to set up our skill (yay!) and can get to writing some actual code.

For Go there are a few libraries that aid with writing Alexa skills. I like arienmalec/alexa-go which is simple.

From your GOPATH create a new folder, I'm calling mine go-alexa-hello-world. Then run:

go get github.com/arienmalec/alexa-go
go get github.com/aws/aws-lambda-go/lambda

This installs the above mentioned alexa-go library but also AWS Lambda for Go, AWS's official support for Go in Lambda functions. So while Alexa isn't officially supported, Go definitely is.

The code for a Hello World is simple and shown below.

main.go

package main

import (
"github.com/arienmalec/alexa-go"
"github.com/aws/aws-lambda-go/lambda"
)

// Handler is the lambda hander
func Handler() (alexa.Response, error) {
return alexa.NewSimpleResponse("Saying Hello", "Hello, World"), nil
}

func main() {
lambda.Start(Handler)
}

The alexa-go page shows more complex examples. The handler can receive an alexa.Request object which gives you the intent name. Using a switch on the Intent name is the usual method to decide what code is needed to run. This way a single Lambda function is used for every intent you create.

In this case we are just saying Hello, World, and so returning a alexa.NewSimpleResponse is all we need.

In the main calling lambda.Start and giving a Handler kicks everything off.

Packaging it Up

You can deploy a Lambda function in a few ways. The AWS CLI is what I usually use. But for the sake of sticking to the basics, we'll upload the code through the web UI like we've used for every other step in the process so far.

A Go binary needs to be built and a zip file created. Lambda functions are always uploaded as zip files.

You must set the GOOS and GOARCH to cross-compile to the Linux environment Lambdas run on. Run this as your build:

GOOS=linux GOARCH=amd64 go build -o main main.go

This will build the main binary, which you now want to zip up:

zip main.zip main

Now you have a main.zip which you can upload.

Automating a deploy

As mentioned above, using AWS CLI is a bit easier than manually uploading a zip file every time you make a change. Below is the Makefile I typically use in Lambda projects. It will build the binary, zip it up, and deploy it to our Lambda function.

You can skip this step for this tutorial, but it's here for reference:

all: main.zip
.PHONY: all

main: src/main.go
GOOS=linux GOARCH=amd64 go build -o $@ $^

main.zip: main
zip $@ $^

deploy: main.zip
aws --region us-east-1 lambda update-function-code --function-name goHelloWorld --zip-file fileb://./$^
.PHONY: deploy

clean:
@rm -f main main.zip
.PHONY: clean

And deploy with:

make deploy

Uploading the Lambda

Now with the code zipped up we can upload from the Lambda UI and we'll be close to done. From the Lambda designer click on goHelloWorld in the center of the screen and then scroll down to where you see the Function code section.

Change the handler to main, since this is the name of the binary we created above. Then click Upload and select the main.zip file you create. Click Save and you should shortly see a Success message at the top of the page.

Uploading the Lambda code

Testing Your Skill

Now back in the Alexa Developer console click on the Test tab at the top. This takes you to the interactive testing page. The Alexa Simulator allows you to type (or say) commands that will be routed to the Lambda you just built.

Testing might be disabled at first, if so change the dropdown to Development.

From the simulator try typing go hello world. You should get a response back saying Hello, world. If so congratulations, it worked!

Using the Alexa test console to simulate uterrances to see the response.

To test your skill from an Alexa device you simply need to register your device with the same account used to set up the Alexa Developer Console. This page goes over more on how to do that.

Recap

Building an Alexa skill with any language is possible as this guide shows. Although you can use any web endpoint, using AWS Lambda is the easiest way to go.

This is a pretty manual process, but once you get things set up you don't need to continuously use the web UI. In the future I'll be writing about topics such as:

In the meantime feel free to contact me with what you're working on in Alexa, Google Home or any IoT project. If your company needs help setting up any of the above, or general consulting on Alexa development or VUI (Voice User Interface) design, I'd love to chat.