I tried using your method as described but on AWS Lambda for the runtime there is no option for NodeJS, the only options are: node.js 4.3, C#, Java 8, Edge Node.js 4.3, Python 2.7.
Can you please tell me which one to select as I tried it with node.js 4.3 and it did not work.
I am going through the same problem. Could you please share your code as I get an error:
{
“errorMessage”: "Exception: TypeError: Cannot read property ‘application’ of undefined”
}
Home Assistant VMWare not accessible from web (only via VPN)
Is it mandatory to expose the Hass instance to the web in order to use Alexa? I have Hass only accessible via VPN from outside and I would like to keep it this way. (I’m just wondering because in the script in the first post the local IP adress is also listed)
Regarding my VPN setup: Could I run a NodeJS Server in another VMWare communicating with Hass locally?
I followed the walk-through and think I have the “where are we” part working but cannot get “where is corey” to work. I have put-off the whole Alexa intent part of my setup as I keep seeing people have difficulty but I would really like to get it setup, integrated, and expand everything.
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.9c72c728-a69c-44e0-9e4b-2d4d4dc4aade':'http://Redacted:Redacted/api/alexa?api_password=Redacted'
};
// 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);
}
};
apologies for the delay, I was traveling. Here’s my code, hope it helps.
"use strict"
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',
'YOUR_SKILL_ID':'http://YOUR_HA_ADDRESS:8123/api/alexa?api_password=YOUR_PWD'
};
// 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);
}
};
Thanks. I have tested this and it works for custom skills. However, I can’t find a way to make it works for Flash Briefing skill. The Feed URL in Configuration cannot accept arn:aws:lambda:us-east-1:XXXXXXXXXXX:function:YYYYYYYYYY.
If you goto AWS lambda -> functions -> <your_funcation> -> Test and you get the below error, I don’t think that is exactly a true error. I have another working lambda function that spits out the same message.
I am able to make it work using ‘http’, but how do we make this work with ‘https’ Home Assistant URL.
i am getting below avs lambda error while using ‘https’
The remote endpoint could not be called, or the response it returned was invalid.
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-xxx':'https://xxxx.duckdns.org/api/alexa?api_password=xxxx'
};
// 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 got it working by changing ‘http’ to ‘https’ and port to 443.
var https = require('https');
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-xxxx':'https://xxxx.duckdns.org/api/alexa?api_password=xxxx'
};
// 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 || 443),
path: parts.path,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': post_data.length
}
};
// Initiate the request to the HTTPS endpoint
var req = https.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);
}
};
This requires that you have set up SSL and have a signed certificate, I suppose? (In that case, you can also use Home Assistant’s Alexa component directly (see here), right?)
Do you know what the securtiy implications of this approach are? I would think that anyone who could intercept the HTTP request could read your password (since that’s somewhere in the URL that is sent unencrypted), which seems to make it very insecure, but I’m not an expert, so I hope someone can explain why I’m wrong here.
No. It does not require SSL (as the thread title states). I think the security implications are relatively clear when not using SSL. I also think other options require port 443 but I’m not sure so this solution may have that advantage as well.
Thanks for the reply. My question about needing SSL was actually meant for @hareeshmu’s approach, so I edited my question to make that clearer. (Sorry, it wasn’t so clear before. I don’t understand why it is not showing up as a reply to his comment.)
Regarding the security of not using SSL: so I am right in saying that the password is sent in plain text when not using SSL? Then it would be nice to warn people about that.
I dont have any Echo device, I’m using the software Alexa AVS Service
So, I believe HA Alexa built-in component will not work with AVS Service. Hence chose the custom skill method.
I am running HA in SSL using LetsEncrypt certificates.