If experimenting with the Amazon Echo / Alexa Skill Kit or running a so-called Skill in production, you generally have two choices:
- AWS Lambda functions on AWS Lambda (a service offering by Amazon Web Services)
- Hosting the Web service yourself.
If you decide against AWS Lambda, you can build the Web service, using
- Java
- Node
- 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.
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