Hosting an Alexa Skill yourself

If experimenting with the Amazon Echo / Alexa Skill Kit or running a so-called Skill in production, you generally have two choices:

  1. AWS Lambda functions on AWS Lambda (a service offering by Amazon Web Services)
  2. Hosting the Web service yourself.

If you decide against AWS Lambda, you can build the Web service, using

  1. Java
  2. Node
  3. anything else that can consume and produce JSON documents

However, Amazon provides good support libraries and sample code for Java and Node, making those options preferable.

Building a basic skill, using the Alexa Skill Kit is really not all that hard and reasonably well documented. I’m preferring JAX-RS and building with Gradle, over the older servlet model and Maven and therefore, my build.gradle file, looks something like this (simplified):

group 'com.techcasita.alexa'
version ''
apply plugin: 'java'
apply plugin: 'war'

war.dependsOn 'generateInteractionModel'
war.archiveName = 'lucy.war'

repositories {
    mavenCentral()
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])

    // Jersey
    providedCompile 'javax.servlet:javax.servlet-api:3.1.0'

    compile "javax.ws.rs:javax.ws.rs-api:2.0.1"
    compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.22.2'
    compile 'org.glassfish.jersey.ext:jersey-proxy-client:2.22.2'
    compile 'org.glassfish.jersey.bundles:jaxrs-ri:2.22.2'

    //  CORS filter
    providedCompile 'org.apache.tomcat:tomcat-catalina:8.0.30'

    //  Alexa
    compile 'com.amazon.alexa:alexa-skills-kit:1.1.3'
    compile 'org.apache.commons:commons-lang3:3.4'
    compile 'commons-codec:commons-codec:1.10'
    compile 'commons-io:commons-io:2.4'

    //  Alexa is currently incompatible with jackson 2.7
    compile 'com.fasterxml.jackson.core:jackson-annotations:2.6.2'
    compile 'com.fasterxml.jackson.core:jackson-core:2.6.2'
    compile 'com.fasterxml.jackson.core:jackson-databind:2.6.2'

    //  Logger
    compile 'log4j:log4j:1.2.17'
    compile 'org.slf4j:slf4j-api:1.7.13'
    compile 'org.slf4j:slf4j-log4j12:1.7.13'

    // App specific.
    compile 'org.json:json:20151123'
    compile 'com.google.code.gson:gson:2.5'
    compile 'org.mapdb:mapdb:1.0.9'
    compile 'joda-time:joda-time:2.9.1'

    // Tests
    testCompile 'javax.servlet:javax.servlet-api:3.1.0'
    testCompile 'org.apache.httpcomponents:httpclient:4.5.1'
    testCompile 'junit:junit:4.12'
}

he gradle build will create a war file, that can be deployed in a container like Tomcat. However, Amazon’s Alexa server will only talk to that server, using the HTTPS protocol. Additionally, the web server needs to have a valid certificate and unfortunately not every valid certificate gets accepted by the Alexa Server.

Certificates from StartSSL for instance can be validated on sites like https://www.ssllabs.com/ssltest/ but still are not accepted by Amazon. While not free, I have had good results with certificates from COMODO RSA Domain Validation and used sslmate for the generation process.

Here are the details:

Goto https://sslmate.com/ and create a user account; you will have to provide a Credit Card number.

sslmate provides you with a short list of commands to execute, based on the Linux distribution installed on the server. E.g.: for my host name ‘alpha.techcasita.com’ running on debian linux:

sudo su
wget -P /etc/apt/sources.list.d https://sslmate.com/apt/jessie/sslmate.list
wget -P /etc/apt/trusted.gpg.d https://sslmate.com/apt/jessie/sslmate.gpg
apt-get update
apt-get install sslmate
sslmate buy alpha.techcasita.com

After ssh into your web server and executing the commands, you will now receive an verification email, sent to an email address that is associated with the domain name. Once you reply to that email, sslmate will generate a private key and certificates, which can then be found in the /etc/sslmate directory.

Private key: /etc/sslmate/alpha.techcasita.com.key
Bare Certificate: /etc/sslmate/alpha.techcasita.com.crt
Certificate Chain: /etc/sslmate/alpha.techcasita.com.chain.crt
Certificate w/ Chain: /etc/sslmate/alpha.techcasita.com.chained.crt

Key and certificates are all what is needed to configure SSL for Apache or NGINX. For Tomcat however, a Java keystore needs to be configured:

Creating a Java keystore from existing certificates and key files

Think of a password (at least 6 characters long) and use it for the following steps

Step1: Creating a PKCS#12 file using OpenSSL

openssl pkcs12 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES -inkey alpha.techcasita.com.key -in alpha.techcasita.com.chained.crt -export -out alpha.techcasita.com.pkcs12 -name tomcat

Step2: Create a keystore and import the PKCS#12 file, using KeyTool

keytool -importkeystore -destkeystore tomcat.jks -srckeystore alpha.techcasita.com.pkcs12 -srcstoretype PKCS12 -alias tomcat

Step3: Move the keystore into postion (e.g. tomcat directory)

mv ./tomcat.jks /usr/share/tomcat

Step4: Configure Tomcat (/usr/share/tomcat/conf/server.xml)

Stop and restart Tomcat and you should be good to go to deploy a war file containing your Alexa Skill.

 

 

 

One Reply to “Hosting an Alexa Skill yourself”

  1. I am working with Alexa Apps from last 4 months. People have uploaded java alexa applications(WebService) using Lambda to internet but i don’t see sample applications made using java hosted on local( to my own machine at home ).

    Could you please help me on that

Leave a Reply to shishir Cancel reply