question

Arlo Rose avatar image
Arlo Rose asked

My server never gets called.

I have a bit of a crazy setup for a personal project.

I have a Raspberry Pi that does various monitoring things for me, and it runs a web server that handles the various requests I throw at it.

In order to get the Pi to into a place to handle requests from the Echo, I did the following: - Got a 3 year SSL Cert for a subdomain. - Port forward my Pi to the outside world. - Have my router using a dynamic IP service. - CNAME my dynamic IP to the subdomain I'm using.

After doing this, I can access my domain via https://house.mydomain.com and it's secure with a valid cert.

Now... when I go to the endpoint I enter into my setup: https://house.mydomain.com/echo/index.php

... in a web browser, I get my temporary canned response back and my ssl_access.log file is written to. When I try and use either the test portal or my Echo, I get back "Unable to call remote endpoint or the response is invalid" in the portal, and "I am unable to reach the requested skill" via the echo. Looking at the logs, it was never attempted. Only access in my logs is from my browser.

Is there anywhere at all to see where the failure point is here? Those errors don't do me much good, and all my checkmarks are lit up in green, so I assume the info I've entered is valid.

Thoughts?

alexa skills kitsubmission testing certification
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

jjaquinta avatar image
jjaquinta answered
I've steered clear of certs because they cost money, things are really fuzzy about what exactly works and what does not, and everyone has problems with them. If I were you I would consider using a pass thru Lambda Function. It can pass Alexa requests on to any web endpoint, http or https, cert or no cert. Just adds a little latency. If you prefer Javascript, have a look around the forums for Matt's function. If you prefer Java, there's one by me.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Jim Brychka avatar image
Jim Brychka answered
Can I get your code for the pass threw Java Lambda function? Message was edited by: Jim Brychka Message was edited by: Jim Brychka
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Arlo Rose avatar image
Arlo Rose answered
Cool. I'll wait and see if anyone else has ever tried my approach. In the mean time I have to wait on Amazon support to re-enable my AWS account. Seems it was sitting unused too long and was suspended. Thanks Amazon.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Steve A avatar image
Steve A answered
I have the same setup...endpoint set to point at a webserver running on a Pi on my local network. (Though I just set up a self-signed cert.) I hate to say it, but I think that jjauinta is right...just do the lambda passthrough. It takes 20 seconds to set up: https://forums.developer.amazon.com/forums/thread.jspa?threadID=5857&start=0&tstart=0 I realize you just paid for a 3 year cert but, you know, sunk cost fallacy and all that. I would just do it the easy way... Steve
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

jjaquinta avatar image
jjaquinta answered
Here's the thread pointing at my general Java Lambda Function for Alexa: https://forums.developer.amazon.com/forums/thread.jspa?messageID=22822夦 I can't find the thread with the pass-thru example. But I use it all over the place. Here's my boiler-plate code. Just replace [b] http://foo.elasticbeanstalk.com/bar[/b] with your own URL. [code] import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.security.GeneralSecurityException; import java.security.cert.X509Certificate; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import com.amazonaws.services.lambda.runtime.Context; public class LambdaFunctionHandler { public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); for (;;) { int ch = inputStream.read(); if (ch == -1) break; baos.write(ch); } byte[] inbuf = baos.toByteArray(); disableCertificateValidation(); byte[] output = makeRequest(inbuf); outputStream.write(output); } private byte[] makeRequest(byte[] body) throws IOException { URL serviceURL = new URL(" http://foo.elasticbeanstalk.com/bar"); HttpURLConnection con = (HttpURLConnection)serviceURL.openConnection(); con.setDoOutput(true); con.setRequestMethod("POST"); con.setRequestProperty("Content-Type", "application/json;charset=UTF-8"); con.setRequestProperty("Accept", "application/json"); con.setRequestProperty("Accept-Charset", "utf-8"); con.setRequestProperty("Content-Length", String.valueOf(body.length)); OutputStream os = con.getOutputStream(); os.write(body); os.close(); InputStream is = con.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); for (;;) { int ch = is.read(); if (ch == -1) break; baos.write(ch); } is.close(); byte[] data = baos.toByteArray(); return data; } private void disableCertificateValidation() { // Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) { } public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) { } } }; // Install the all-trusting trust manager try { SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (GeneralSecurityException e) { } // Now you can access an https URL without having the certificate in the truststore } } [/code]
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Jim Brychka avatar image
Jim Brychka answered
Thanks for the code. What gets returned to Alexa after this calls my web service?
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

jjaquinta avatar image
jjaquinta answered
It's a [i]pass-thru[/i]. Whatever it is sent, gets sent to your skill. Whatever you skill returns, gets returned to Alexa. Like a proxy.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Jim Brychka avatar image
Jim Brychka answered
Perfect. I'll give it a shot. Thanks again.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Branson Blair avatar image
Branson Blair answered
Arlo, When I read your question yesterday it reminded me of where I started a week ago. The good news is that within a week I was totally able to write a skill which turned on/off my TV. The bad news is there are many ways to do this, and many different approaches. After reading your question I thought if I took a minute to write up my weeks adventure, maybe it will help you or some others in the future. First off I want to thank a few people who have posted some great stuff: - jjaquinta: great posts in this forum and congrats on putting a book out. I do need to finish reading it though. - Matt Kruse: your alexa-app and alexia-app-server are the backbone of my Raspberry Pi - Matt Farley: Jarvis https://www.youtube.com/watch?v=9f5XTynrbAA This proved to me that what I wanted to do was possible. Thanks, good work. - Singh http://sushilks.blogspot.com/2015/07/connecting-alexa-to-logitech-harmony.html: You really motivated me, although I took a completely different approach, I may also use write a version with your CLI. Nice work! - swissManu: if you were to happen to read this your github harmonyhubjs-client is really cool. You should get Harmony to write a native controller for Amazon Echo. https://github.com/swissmanu/harmonyhubjs-client - Amazon Sample Kit: https://github.com/swissmanu/harmonyhubjs-client - Gary Anderson: Looks like a great class you are teaching https://www.youtube.com/watch?v=bYTCSvbuK3I you inspired my wife to buy an Echo for her 5th grade STEM class and maybe write some apps. If you happen to read this and have the Eliza code one of your students wrote and could share that would be much appreciated. https://www.youtube.com/watch?v=u9_WoMMQ-10 but then again might be fun to figure out. Starting out I had a simple task. Turn on my TV with Alexa. So I wrote a IFTTT recipe with todo list, okay very slow and bad voice structure but works and simple by just adding an item to the todo and then calling out an activity on the harmony hub. Next I did a similar thing with a Wemo switch and IFTTT and harmony Hub, this sounds nicer but still can be really slow. So finally when I saw the Jarvis video I knew this could be done but I needed to break all the parts down and learn how they would fit together. -Raspberry Pi -NodeJS -AWS Lambda -Amazon Skill Kit -OpenSSL -Github The first major mistake I made was I thought I would need to setup the Raspberry Pi with Apache and PHP and MySQL, etc but after doing that I realized that these web services could completely be hosted in NodeJS. Totally different server concept for me at the time but really nice and simple now that I've implemented it, so no need for Apache or traditional web server. I could just add Express to NodeJs but this mean I had to do a lot more reading about NodeJS. Next once I had NodeJS working and understood express, I tried Harmony-Hub from github. This worked but the versions on RaspberryPi proved problematic until I added Adafruit to my repository. This however led me down a path of compiling the CEC client for Raspberry which was a challenge in itself but once compiled I could now turn on and off the TV via the HDMI plugged into the Raspberry and connected to the TV. So I figured I need to add this to a shell script, check, then add to a NodeJS app, check, then add as a request page under NodeJS Express, check. This turned out surprisingly easy and now I could go to a URL to turn on the tv and another URL to turn off the TV. So now I needed to see how a NodeJS app was implemented with Amazon Skills. This is a lot harder to start out with the Raspberry but very easy to do with AWS Lambda, nice service Amazon and free. I implemented My Favorite Color in no time and then re-wrote it into My Fight Club because I thought it would be fun to tell Alexa my favorite Fight Club Rules and to have her read them. I could post the code but basically a very simple re-write of My Favorite Color. This really taught me Intent and Slots and Utterances. At this point I decided to re-write this on Raspberry but I needed to create an SSL, which is where your question starts I think. I created several SSL certs before I realized that the DNS name had to match the DNS name in the cert. So https://pi.domain.com needed to be a valid DNS, so I used Zoneedit to forward to Comcast modem then a NAT to forward to port 443 to the Pi. This worked fine but when I tested with the Amazon tester I got no feedback to woking but when I invoked it via voice I could see it hit the NodeJS Express server and log output. I found this page to be the most valuable info on making my OpenSSL work https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/testing-an-alexa-skill Which makes me wonder all the fuss with forwarding an AWS Lamda service to something less secure but neat idea too and definitely has its uses. Either way both methods are free so unfortunately you may have gotten ahead of yourself purchasing a cert, hopefully you will be able to use it with the DNS name matching. Finally after studying what Matt Kruse wrote with Alexa-App and Alexa-App-Server, I found this much easier than the Lamda style and it took no time to turn my two webpages into an tvapp and I took guess a number and re-wrote it to call the CEC-client shell and within seconds it turns on my tv. As fast as a tv remote and off as well. So now I can Alexa, start TV. She says welcome and you say, turn my tv on/off. Several other variations now work as you learn how people say things and I've toyed with having the app first check to see the TV is on, etc. and be a little smarter. The virtual Wemo switch might be worth exploring too ( http://www.makermusings.com/2015/07/18/virtual-wemo-code-for-amazon-echo/) since the statements do not require saying the name of your skill.. Neat idea. I will also probably rewrite a version like Jarvis to use my Harmony Hub for more features but for $75 you could buy a Raspberry Pi, case, cables and power it from usb port and recreate turning on and off almost any modern tv that supports HDMI CEC. Not to mention learning how to do this and cheaper than buying a Harmony Hub or SmartThings (probably need one of these next) So I apologize for the long post but hopefully one of these links will help give someone ideas or help others figure it out quicker. Please post cool ideas if or lessons learned if you have the time. Thanks, -Branson
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Arlo Rose avatar image
Arlo Rose answered
Branson, Thanks for the long and thoughtful reply. The salient points to me are: 1) Doing the 1:1 match of the full FQDN and cert are important (which I have set up correctly). (By the way, I didn't pay for the cert, it's a Level 1 cert from StartSSL, so maybe the type of cert is an issue? But it's signed, and works without issues.) 2) It seems possible (from your experience) that you can port forward via your cable modem and not have that be an issue. The only difference in my flow is that I assume that my Cable's IP address will change so I'm using a dynamic IP address service, and a CNAME DNS record to forward me.asusdynip.com to home.mydomain.com. Perhaps that's my issue, and I instead should just be ready to change that IP address when needed. I'd jump on the Lambda approach in a heartbeat if I could get Amazon to let me know why my AWS account (which hasn't been touched in almost three years) is suspended (no support response, and not a past billing issue). I'd also wonder if using the Node example could be part of a handshake I'm missing (I love Node, it's my preferred server tinkering language), except that as-is I should still see [i]some[/i] sort of request from Amazon's servers when testing, at a minimum with voice directly. I like that the Jarvis project is what inspired you and your TV is what you're controlling. I ran the TV and Home Automation group at Nuance doing this very stuff, and loved the job, but I realized that I wanted to build the products that used voice control, not the platforms for them. Cheers, Arlo
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.