AWS Lambda Proxy Custom Alexa Skill when you don't have https

Create an account on “Serverless Function, FaaS Serverless - AWS Lambda - AWS

Under AWS Service in the Compute category select Lambda

Then Create a new Lambda function
Select a blueprint
In filter search for “alexa-skills-kit-color-expert” nodejs

It should then bring you to configure triggers
Click the box outlined with dashes and from the drop down select Alexa Skills Kit

Than name your function and enter a description

For the runtime select NodeJS (do not select node.js4.3)

Edit inline code and delete everything there then past the code below
You will need to come back to this to update the application ID and your IP address once your skill is setup

var http = require('http');
var URLParser = require('url');
 
exports.handler = function (json, context) {
    try {
        // A list of URL's to call for each applicationId
        var handlers = {
            'appId':'url',
            'amzn1.ask.skill.xxxx-xxxx-xxxx-xxxx-xxxxxx':' http://xxxxxxxx:8123/api/alexa?api_password=password
        };
        
        // Look up the url to call based on the appId
        var url = handlers[json.session.application.applicationId];
        if (!url) { context.fail("No url found for application id"); }
        var parts = URLParser.parse(url);
        
        var post_data = JSON.stringify(json);
        
        // An object of options to indicate where to post to
        var post_options = {
            host: parts.hostname,
            auth: parts.auth,
            port: (parts.port || 80),
            path: parts.path,
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Content-Length': post_data.length
            }
        };
        // Initiate the request to the HTTP endpoint
        var req = http.request(post_options,function(res) {
            var body = "";
            // Data may be chunked
            res.on('data', function(chunk) {
                body += chunk;
            });
            res.on('end', function() {
                // When data is done, finish the request
                context.succeed(JSON.parse(body));
            });
        });
        req.on('error', function(e) {
            context.fail('problem with request: ' + e.message);
        });
        // Send the JSON data
        req.write(post_data);
        req.end();        
    } catch (e) {
        context.fail("Exception: " + e);
    }
};

I was able to use this which I found as a part of an Alexa Nest integration Here

Leave handler as index.handler

Role: Choose Existing Role

Existing Role: Lambda_Basic_Execution

Memory 128

Timeout set to 10 Seconds

No VPC

Then hit Next

Then Create Function

On the next page at the top right you will see ARN
arn:aws:lambda:location:XXXXXXXXXXXXXXXXXXXXX:function:name

Copy this as you will need it to create your alexa skill


Next go to and create an account or sign in if you already have one
https://developer.amazon.com/

Click the Alexa tab

Alexa Skills Kit> Get Started

Add New Skill

Radio button custom interaction model should be selected

Give your skill an name

Then also the name you will use to activate your skill “Alexa ask ‘Skill Name’ to turn on the lights” and click next.

The interaction model you will need HA intents and sample utterance examples and detail
Home Assistant

Once done hit next

Click the AWS Lambda ARN

In my case I chose north america

Now you need to paste the ARN that was copied earlier from you lambda function.

Then hit next

at the top under the name of your skill you will see that you have an ID for you application similar to:
amzn1.ask.skill.xxxxxxx-xxxxx-xxxxx-xxxxxxxxx-xxxxxxxxx

Copy this and go back to your lambda function and to the code section

Paste your ID as a replacement for what is in the code and make sure that your outward facing IP is entered and the port that points back to you HA instance.

So long as you’ve configured your Yaml based on the HA documentation you should be all set.
This is a quick and dirty run through of what I was able to use to get my skill functioning it took me way too long to cobble it together so hopefully this will help someone.

5 Likes

Thank you for sharing!

This helps confirm some of my suspicion that my Nginx reverse proxy might be messing with something… I was unable to get the integration working via self signed cert either.

I’m still getting: “The remote endpoint could not be called, or the response it returned was invalid.” even using the proxy method you just shared.

When I call the /api/alex endpoint locally I get “{“message”: “405: Method Not Allowed”, “result”: “error”}” even when providing the API password. Not sure of this is expected behavior…

I’ll continue to hack away at it and hopefully come up with something.

There used to be a link on AWS from the docs that showed how to do this but they took it down, so your explanation on this setup is very much appreciated. @fabaff, can we change the link on the Alexa components page to point to this explanation?

Link is updated now. Thanks.

No, thank you!

Could you do one of these to forward commands to IFTTT, to use the Maker channel since in the UK IFTTT isnt supported.

I’m getting this too.

However, I had it working with HTTPS previously. I have since turned that off as it caused problems for ha-bridge. I can’t remember what I had to do when setting this up with HTTPS but I am fairly sure I had this exact same problem and found a solution somewhere online but can’t find it again. Stupidly, I tried to edit my working https skill to http and have lost the working config to check against.

Could this be something going on in the Dev branch? Could anyone confirm if they have this proxy media working on the latest Dev build of HaSS?

Cheers!

This is definity working at the minute I set it up last night. If you at getting invalid responses chech your HA config and make sure port is open.

Well just for eliminating a few things… I’m on a raspberry pi 3, using AIO install method, and updated HAss to 0.31 just before trying this. Usually when something like this doesn’t work for me it is because I have missed a character, or space or something else very obvious that my eyes refuse to see. Things that are very much my fault.

I’m waiting on some dots to show up and will probably use Ha-Bridge when they do but wanted to try this out more as an exercise as I try to learn some basic programming and understand how all this stuff ties together better.

Oh, and the only line I edited in the code was “amzn1.ask.skill.xxxx-xxxx-xxxx-xxxx-xxxxxx’:’ http://xxxxxxxx:8123/api/alexa?api_password=password” - I can see there are bits below that with port 80 mentioned - I’m using the default 8123, port 80 is blocked by my ISP.

don’t need to worry about the port 80 part… of you edited the xxxxx link I’d check your Amazon Skill and HA config.

I might delete everything and start again tomorrow, I am sure it’s some small thing I’ve missed.

don’t use everything start just with the wherearewe and part and copy and paste don’t change anything then test from the amazon skill.

Thanks for the help @josephdouce

I only have a scene intent set up copied from my HTTPS version - nothing else.

When I try a fresh start tomorrow I’ll try with the wherearewe and see if it gets through.

Hey tarnfeather!

Thanks for posting this! This has been very useful thus far.

My only problem is that I can’t use a public IP address. I have a router and admin access but this is running under my college’s network via ethernet to my router. Is there anything I can do to get around this? I originally looked into PageKite, a VPN of some sort, or something to do with Hamachi, but I’m not quite sure.

All help is greatly appreciated!!!

I have pagekite as well. I am not able to figure out how to get it working. Even testing the HTTPS call I get “405:Method not allowed” when I try to access https://HOMEASSISTANT.pagekite.me:8000/api/alexa?api_password=PASSWORD

I get {“message”: “API running.”} when accessing https://HOMEASSISTANT.pagekite.me:8000/api/?api_password=PASSWORD

So I think there is something wrong with the alexa plugin.

Any idea of why that is? HA Version 34.4 I tested it with


Free valid certificate for https, in case someone has missed it.

Hi guys, anyone have solution about this issue? “The remote endpoint could not be called, or the response it returned was invalid.”

1 Like

Ok, I got it working.

I added “use strict” in the first line and fixed the spacing issue here:

The part in bold in the original code has a space between the quote and the http part of the URL, which also need to be closed quotes (close the quotes after the api_password=YOURPWD )

Hope that helps. I resorted to this proxy as I couldn’t set up the encryption for whatever reason.

D.

Is this still working? I’ve developed a fair few Alexa skills and should have the knowledge but I just can’t get it working.

Response invalid from the Alexa Skills kit test tool and trying to test with a sample intent through the Lambda console doesn’t work either - I get the error ‘no url found for application id’ ?

Also you can only choose NodeJS 4.3 now ? Not sure if this breaks your code?

I was considering writing an updated Lambda function using the official Amazon NodeJS SDK to do it but I don’t have experience of the HA Alexa API. Is this documented anywhere? I’d like to test it using Postman.

Or if anyone could help me to get this working that would be good.