Sunday, April 9, 2017

Building Alexa Skills (or apps) through Swift programming language is possible?

Yes, absolutely it’s possible. As we few of many already know that Swift-programming language allow iOS developers to build or develop iOS based applications. Here out of the box, we’ll experience the way of methodology to expand Swift proficiency skill set to include server-side programming and take part in the trend towards voice user interfaces (i.e., Amazon Echo). Please be noted, currently AWS Lambda (i.e., server-less compute) only supports code written in JavaScript (Node.js), Python, C# and Java. But it’s easy to extend this to executable written in any programming language you want.

In this post we will learn and understand about methodology how to build or develop Alexa skills (or app) with the proficiency of ‘Swift’ programming language? Also achieve an idea of integrating created skills with other AWS cloud services too. Before jump into the context, I really recommend here to check it out or follow below highlighted links – will help to explore and understand the basic implementation guidelines. Reading or follow amazon documentation will be plus to achieve the target implementation result.



Important Links:
·       https://docs.docker.com/docker-for-mac/ - Getting started with Docker for Mac

Blog Link:

·       Alexa skills from scratch with AWS Lambda, SSML and Amazon S3

·       Swift Programming (Server-Side) - Kick Start..!

Sample tested on below system-setup:

·       macOS Sierra – 10.12.4
·       XCode – 8.3 (8E162)
·       Swift – 3.1
·       Docker – Community Edition - Version 17.03.0-ce-mac2 (15654)

Objective Target:
Alexa will send created skill a JSON message with the user’s intent and sample code answers with a JSON message that determines what Alexa will answer to the user.

The code for our custom skill can run as either a stand-alone web service (i.e., HTTP) or an AWS Lambda function. Using Lambda, Amazon’s server-less computing platform, Amazon will take care of scaling and running sample Swift code.

1. HTTPS
Stand-alone web service (i.e., HTTP) 
$ cd /Users/ranbijaykumar/Alexa-AVS-Sample/Alexa-Swift-Skills/swift-lambda-app - using {Reference-Implementation} below instead of the mentioned directory path.

2. AWS Lambda ARN (Amazon Resource Name)
AWS Lambda is a server-less compute service that runs code in response to events and automatically manages the underlying compute resources.

Importantly I would like to mention here that I pulled the source sample code from Github – developed by Claus Höfele. Though the sample code is straightforward but I found personally few gap during time of implementation – bridged and tried my best to make it easier from developer perspective.

Either clone or download the sample app from Github account. Else, check out the swift-lambda-app repo on GitHub for the code and scripts to develop and deploy a simple Alexa skill in Swift via Terminal command prompt in MacOS.

·   $ git clone https://github.com/choefele/swift-lambda-app.git
·   $ swift build
·   $ swift package generate-xcodeproj
·   $ open ./AlexaSkill.xcodeproj/

We’ll need to understand the following for our Alexa skill:
·       An implementation of skill’s functionality in Swift using AlexaSkillsKit
·       A Lambda function set up with your Swift code using the AWS Console
·       An Alexa Skill configured in the Alexa Console that triggers your Lambda function
*Note that the Alexa Console and the AWS Console are two separate services that user need to sign up for.

There are three targets:
·       AlexaSkill: this is a library with the code that implements the custom Alexa skill. It’s a separate library so the other two targets can use it. Also, libraries have ENABLE_TESTABILITY enabled by default, which allows user to access internal methods and properties in your unit tests.
·       Lambda: The command line executable for deployment to Lambda. This program uses stdin and stdout for processing data.
·       Server (macOS only): To simplify implementing a custom Alexa Skill, the server provides an HTTP interface to the AlexaSkill target. This HTTP server can be exposed publicly via ngrok and configured in the Alexa console, which enables you to develop and debug an Alexa skill with code running on our development computer. This target is macOS only.

HTTPS:  To run a local HTTPS server
·       Make sure the sample builds by running swift build
·       Generate an Xcode project with swift package generate-xcodeproj
·       Open the generated Xcode project, select the Server scheme and run the product (CMD-R). This will start a server at port 8090

·       Install ngrok via brew cask install ngrok. This tool allows you to expose a local HTTP server to the internet
§  $ cd {Reference-Implementation}
§  $ brew cask install ngrok   -à Install ngrok
·       Run ngrok http 8090 and copy the HTTPS URL generated by ngrok (it looks similar to https://6ebec3f2.ngrok.io)
§  $ ngrok http 8090  -à ‘Ctrl+C’ to get back to command prompt.
* ngrok exposes your local server to the public internet thus allowing the Alexa Voice Service to call into your custom skill running in Xcode.



Configuring the Alexa Skill

To hook up your custom skill to Alexa:
·       Go to the Alexa console and create a new skill
·       Skill type: Custom Interaction Model
·       Intent: {"intents": [{"intent": "TestIntent"}]}
·       Sample utterances: “TestIntent test Swift”
·       Service endpoint type: HTTPS (use the URL from ngrok) - Copy above created HTTPS URL (i.e., in format of https://6ebec3f2.ngrok.io) and paste into the below endpoint field as depicted below. Press ‘Next’


·       SSL Certificate: Select “My development endpoint is a sub-domain of a domain that has a wildcard certificate from a certificate authority”


Now we can test the skill in the Alexa Console’s Service Simulator using the utterance “test swift”. This will call your local server allowing you to modify and debug your code while interacting with the Alexa service. You can check the status ‘200’ into local running HTTPS server over ngrok terminal. Please check above in diagram.



Running Tests for Your Code


Before uploading to Lambda, it’s worthwhile to run your unit tests in a Linux environment and run integration tests that simulate the execution environment. The sample provides run-unit-tests.sh to do the former and run-integration-tests.sh to do the latter.
run-unit-tests.sh builds and tests the Lambda target inside a Swift Docker container based on Ubuntu because there's currently no Swift compiler for Amazon Linux (based on RHEL). Executables built on different Linux distributions are compatible with each other if you provide all dependencies necessary to run the program. For this reason, the script captures all shared libraries required to run the executable using ldd.
To prove that the resulting package works, run-integration-tests.sh runs a release build of the Swift code inside a Docker container that comes close to Lambda’s execution environment (unfortunately, Amazon only provides a few Docker images that don't necessarily match what Lambda is using).
The integration with Lambda is done via a small Node.js script that uses the child_process module to run the Swift executable. The script follows Amazon's recommendations to run arbitrary executables in AWS Lambda.
*After configuration, we need to run the same integration script again for every commit or possible changes.


Deploying Sample Code to Lambda

To deploy sample code to AWS Lambda:

·       Before jumping to below steps, first run the Docker container, Install Docker S/W in development machine from above link and check the status of Docker container – as depicted above screenshot.

·       Run run-integration-tests.sh to produce a zip file at .build/lambda/lambda.zip with all required files to upload to Lambda
$ cd {Reference-Implementation}
$ mkdir -p .build/lambda/libraries/
$ ./run-unit-tests.sh
$ ./run-integration-tests.sh

It will create the .zip in hidden folder - Hold down CMD-Shift-. (dot) keys in Mac machine --à All the hidden files will become visible. Press same group of keys again to make the hidden files/folder disappear as previous.



·       Create a new Lambda function in the AWS Console in the US East/N. Virginia region (for Europe use EU/Ireland). Select ‘alexa-skill-kit-sdk-factskill’ blueprint
·       Use an Alexa Skills Kit trigger
·       Runtime: NodeJS 4.3 or NodeJS 6.10
·       Code entry type: ZIP file (upload the lambda.zip file from the previous step)
·       Handler: index.handler
·       Role: Create from template or use existing role ‘lambda_basic_execution’
Once we uploaded the Lambda function, we can use the test actions in the AWS Console, for example by using a Start Session action.


Configuring the Alexa Skill for Lambda

After creating the Lambda function, you can now create an Alexa skill. If you have previously created an Alexa skill for the local HTTP server — the only difference is the service endpoint:
·                Go to the Alexa console and create a new skill
·                Skill type: Custom Interaction Model
·                Intent: {"intents": [{"intent": "TestIntent"}]}
·                Sample utterances: “TestIntent test swift”
·             Service endpoint type: AWS Lambda ARN (use the ARN for the Lambda function from the AWS Console) – ARN: arn:aws:lambda:us-east-1:280019173811:function:swiftDeploymentInLambda. See previous of previous image to specified/copied the created ARN value at endpoint field. [Please refer above mentioned blog links as well to understand more into the deep].


Now we can test the skill in the Alexa Console using the utterance “test swift”. More details on configuring Alexa skills can be found on Amazon’s developer portal.


Done J

I hope this post will give you a great kick-of start using Swift programming language in both client and server side on creating of an Alexa skills, also integrating those skills with other AWS cloud services seamlessly. Thanks you and good luck, happy programming!