I am working on a "Skill" for the new Amazon ECHO. The skill will allow a user to ask Alexa for information on the status and performance of an Enphase solar system. Alexa will respond with results extracted from the JSON based Enphase API. For example, the user could ask,
"Alexa. Ask Enphase how much solar energy I have produced in the last week."
ALEXA <"Your array has produced 152kWh in the last week.">
Problem is it has been years since I've programmed in JavaScript and this is my first time using AWS Lambda. I have not been very successful finding any information on how to embed a JSON query to a third party server within AWS Lambda function. Here is a relevant section of code in my Lambda function:
/**
* Gets power from Enphase API and prepares speach
*/
function GetPowerFromEnphase(intent, session, callback) {
var Power = 0;
var repromptText = null;
var sessionAttributes = {};
var shouldEndSession = false;
var speechOutput = "";
//////////////////////////////////////////////////////////////////////
// Need code here for sending JSON query to Enphase server to get power
// Request:
// https://api.enphaseenergy.com/api/v2/systems/67/summary
// key=5e01e16f7134519e70e02c80ef61b692&user_id=4d7a45774e6a41320a
// Response:
// HTTP/1.1 200 OK
// Content-Type: application/json; charset=utf-8
// Status: 200
// {"system_id":67,"modules":35,"size_w":6270,"current_power":271,
// "energy_today":30030,"energy_lifetime":59847036,
// "summary_date":"2015-03 04","source":"microinverters",
// "status":"normal","operational_at":1201362300,
// "last_report_at":1425517225}
//////////////////////////////////////////////////////////////////////
speechOutput = "Your array is producing " + Power + " kW, goodbye";
shouldEndSession = true;
// Setting repromptText to null signifies that we do not want to reprompt the user.
// If the user does not respond or says something that is not understood, the session
// will end.
callback(sessionAttributes,
buildSpeechletResponse(intent.name, speechOutput, repromptText,
shouldEndSession));
}
Some guidance would be much appreciated. Even if someone could point me in the right direction. Thanks!
Request is a very popular library for handling http requests in node.js. Here is an example of a POST using your data:
var request = require('request');
request({
url: 'https://api.enphaseenergy.com/api/v2/systems/67/summary',
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
key: '5e01e16f7134519e70e02c80ef61b692',
user_id: '4d7a45774e6a41320a'
})
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log('BODY: ', body);
var jsonResponse = JSON.parse(body); // turn response into JSON
// do stuff with the response and pass it to the callback...
callback(sessionAttributes,
buildSpeechletResponse(intent.name, speechOutput, repromptText,
shouldEndSession));
}
});
I don't have an example of ECHO/Alexa but here is an example of Lambda calling out to get weather data to send it to Slack
Related
I want to fetch data from an URL with SparkAR's networking module
and display it.
I tried the example found in the Spark AR documentation but it doesn't do much: https://developers.facebook.com/docs/ar-studio/reference/classes/networkingmodule/
Don't forget to add "jsonplaceholder.typicode.com"
to Spark AR's whitelisted domains first. :)
// Load in the required modules
const Diagnostics = require('Diagnostics');
const Networking = require('Networking');
//==============================================================================
// Create the request
//==============================================================================
// Store the URL we're sending the request to
const url = 'https://jsonplaceholder.typicode.com/posts';
// Create a request object
const request = {
// The HTTP Method of the request
// (https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods)
method: 'POST',
// The HTTP Headers of the request
// (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers)
headers: {'Content-type': 'application/json; charset=UTF-8'},
// The data to send, in string format
body: JSON.stringify({title: 'Networking Module'})
};
//==============================================================================
// Send the request and log the results
//==============================================================================
// Send the request to the url
Networking.fetch(url, request).then(function(result) {
// Check the status of the result
// (https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)
if ((result.status >= 200) && (result.status < 300)) {
// If the request was successful, chain the JSON forward
return result.json();
}
// If the request was not successful, throw an error
throw new Error('HTTP status code - ' + result.status);
}).then(function(json) {
// Log the JSON obtained by the successful request
Diagnostics.log('Successfully sent - ' + json.title);
}).catch(function(error) {
// Log any errors that may have happened with the request
Diagnostics.log('Error - ' + error.message);
});
All I get is : ">> Successfully sent - Networking Module"
Does anybody know how I could get the json content to be displayed in the console I want to store it and use it in a text object afterwards.
In my case a have a url that give me a random item in json format.
URL: https://gabby-airbus.glitch.me/random
Result: {"item":"Item 14"}
In the code, replace the line:
Diagnostics.log('Successfully sent - ' + json.title);
with this:
// show json data in console
Diagnostics.log(json.item);
// Asign json data to text object
itemText.text = json.item;
First line shows the json data in console.
Second line asign the json data to a text object in the scene, in this case the "itemText" text object.
Full code:
const Diagnostics = require('Diagnostics');
const Scene = require('Scene');
const Networking = require('Networking');
const URL = 'https://gabby-airbus.glitch.me/random';
var itemText = Scene.root.find('itemText');
Networking.fetch(URL).then(function(result){
if( (result.status >=200) && (result.status < 300)){ return result.json(); }
else { throw new Error('HTTP Status Code: ' + result.status); }
}).then(function(json){
// show json data in console
Diagnostics.log(json.item);
// Asign json data to text object
itemText.text = json.item;
}).catch(function(error){
itemText = 'Failed to start';
Diagnostics.log(result.status + error);
});
We need to call JIRA Rest API to get a specific information from the given query in Dialogflow.
We need to provide response to user based on the response from the API. However, the Dialogflow is unable to retrieve any response from JIRA API through the fulfillment in Firebase Cloud function as it's always timeout.
Based on the log in Firebase console, it always take more than 6000 ms for the execution.
Meanwhile if I use postman to call the JIRA REST API, it takes less than 1 second to get the response.
Some said we need to use promise but I does not seem to work as well.
Please help how should I solve this problem?
Please see my code below
function checkcontract(agent){
var parameters = request.body.queryResult.parameters;
var customer_id = parameters.customer_id;
var bodyData = JSON.stringify({"jql": "project = CDB AND 'Customer ID' ~ "+customer_id,
"maxResults": 1,
"fieldsByKeys": false,
"fields": [
"summary",
"customfield_11949", //Customer ID custom field
"customfield_11937", // Contract Start Date
"customfield_11938", //Contract End Date
"customfield_11936", //email
"customfield_11946", //default JSD request id
"customfield_11943", //project id
"customfield_11941" //project key
],
"startAt": 0
});
var options = {
method: 'POST',
url: '/rest/api/3/search',
auth: { bearer: authorization_token },
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: bodyData
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(
'Response: ' + response.statusCode + ' ' + response.statusMessage
);
console.log(body);
});
}
EDIT:
JIRA API returns a response to the function. But the agent.add("message") does not return anything to the chat.
I am working in NodeJS with CouchDB 2.1.1.
I'm using the http.request() method to set various config settings using the CouchDB API.
Here's their API reference, yes, I've read it:
Configuration API
Here's an example of a working request to set the logging level:
const http = require('http');
var configOptions = {
host: 'localhost',
path: '/_node/couchdb#localhost/_config/',
port:5984,
header: {
'Content-Type': 'application/json'
}
};
function setLogLevel(){
configOptions.path = configOptions.path+'log/level';
configOptions.method = 'PUT';
var responseString = '';
var req = http.request(configOptions, function(res){
res.on("data", function (data) {
responseString += data;
});
res.on("end", function () {
console.log("oldLogLevel: " + responseString);
});
});
var data = '\"critical\"';
req.write(data);
req.end();
}
setLogLevel();
I had to escape all the quotes and such, which was expected.
Now I'm trying to get CouchDb to accept a setting for compaction.
The problem is that I'm attempting to replicate this same request to a different setting but that setting doesn't have a simple structure, though it appears to be "just a String" as well.
The CouchDB API is yelling at me about invalid JSON formats and I've tried a boatload of escape sequences and attempts to parse the JSON in various ways to get it to behave the way I think it should.
I can use Chrome's Advanced Rest Client to send this payload, and it is successful:
Request Method: PUT
Request URL: http://localhost:5984/_node/couchdb#localhost/_config/compactions/_default
Request Body: "[{db_fragmentation, \"70%\"}, {view_fragmentation, \"60%\"}, {from, \"23:00\"}, {to, \"04:00\"}]"
This returns a "200 OK"
When I execute the following function in my node app, I get a response of:
{"error":"bad_request","reason":"invalid UTF-8 JSON"}
function setCompaction(){
configOptions.path = configOptions.path+'compactions/_default';
configOptions.method = 'PUT';
var responseString = '';
var req = http.request(configOptions, function(res){
res.on("data", function (data) {
responseString += data;
});
res.on("end", function () {
console.log("oldCompaction: " + responseString);
});
});
var data = "\"[{db_fragmentation, \"70%\"}, {view_fragmentation, \"60%\"}, {from, \"23:00\"}, {to, \"04:00\"}]\"";
req.write(data);
req.end();
}
Can someone point at what I'm missing here?
Thanks in advance.
You need to use node's JSON module to prepare the data for transport:
var data = '[{db_fragmentation, "70%"}, {view_fragmentation, "60%"}, {from, "23:00"}, {to, "04:00"}]';
// Show the formatted data for the requests' payload.
JSON.stringify(data);
> '"[{db_fragmentation, \\"70%\\"}, {view_fragmentation, \\"60%\\"}, {from, \\"23:
00\\"}, {to, \\"04:00\\"}]"'
// Format data for the payload.
req.write(JSON.stringify(data));
I have implemented transactions using ETH, however, I want to exchange tokens between accounts. Here is my code
var postData = {"jsonrpc":"2.0","method":"eth_sendTransaction","params": [{"from":"0x52f273a06a420453aa5b33c4f175395c9a1fddd8", "to": data.ethAddress, "value": 1e18}], "id":1}
var url = 'http://localhost:8545/'
var options = {
method: 'post',
body: postData,
json: true,
url: url
}
request(options, function (err, res, body) {
if (err) {
console.error('error posting json: ', err)
throw err
}
var headers = res.headers
var statusCode = res.statusCode
console.log('headers: ', headers)
console.log('statusCode: ', statusCode)
console.log('body: ', body)
})
This is completing the transaction with 1 ETH being transferred between accounts. However, I want to setup this same action but with my custom token as the currency, not ETH. Any help would be greatly appreciated. Thanks
I am not sure if that is what you need... You can create a class or two either in C# or in JavaScript to reflect all your properties.
var whatever= {};
whatever.jsonrpc="2.0";
whatever.id=1;
whatever.method="eth_sendTransaction";
whatever.params= [];
whatever.params[0].from="0x52f273a06a420453aa5b33c4f175395c9a1fddd8";
whatever.params[0].to=data.ethAddress;
whatever.params[0].value=1e18;
whatever.params[0].currency="xxx";
etc
I understand that you want to send your token (currency) among different accounts. So, I imagine that you have created your own token and that you have developed your code (your Smart Contract).
If not, you should create it.
Then, you should deploy your code and start using it.
You have a tutorial about it here.
I have a middleware function using Node's Express4 to log each request & response for debugging. I use the res.json call in the request handler to send back JSON to the client for all but static files. So I do not want to log the response for static files, but only the JSON responses. I have the following code:
function logRequests(req, res, next) {
// do logging (will show user name before authentication)
logger.reqLog('IN '+req.method+' '+req.url, req);
var oldEnd = res.end,
oldWrite = res.write,
chunks = [];
res.write = function(chunk) {
chunks.push(chunk);
oldWrite.apply(res, arguments);
};
res.end = function(chunk, encoding) {
if(chunk) {
chunks.push(chunk);
}
oldEnd.apply(res, arguments);
// the content-type prints "undefined" in some cases
// even though the browser shows it returned as "application/json"
console.log('type='+res.get('content-type'));
if(res.get('content-type') === 'application/json') {
var body = Buffer.concat(chunks).toString('utf8');
logger.info(body, req);
}
logger.reqLog('OUT '+req.method+' '+req.path, req);
};
next(); // make sure we go to the next routes and don't stop here
}
So why do some requests show the correct content type in the middleware meaning they also print the response fine and others do not? All of them look good in the REST client when inspecting the returned headers.
EDIT: Some more info discovered tonight while trying to figure this out - if I append any character as a dummy request parameter, it logs the response type correctly:
http://localhost:8081/node/ionmed/api/logout?0 WORKS
where
http://localhost:8081/node/ionmed/api/logout DOES NOT
Also, I can always get a response type logging in the middleware function if I replace the .json() call with .end() so this:
res.json({ item: 'logout', success: true });
becomes:
res.set('content-type', 'application/json');
res.end({ item: 'logout', success: true });