Hosting an Alexa Skill yourself

Datetime:2016-08-23 03:51:58          Topic: Tomcat           Share

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'
}

The 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.





About List