Using AWS4 Signature via Postman for CRUD Elastic operations - javascript

I'm trying to post data to Elasticsearch managed by AWS using AWS4 signing method. I would like to achieve this via postman pre-script. I tried using below script which worked perfectly for GET operation of Elastic search but its not working for POST or PUT or DELETE operation & keep giving me error message that the signature does not match for POST operation. Can someone help me in fixing below pre-script in postman?
var date = new Date().toISOString();
var amzdate = date.replace(/[:\-]|\.\d{3}/g, "");
var dateStamp = amzdate.slice(0, -8);
pm.environment.set('authorization', getAuthHeader(request.method, request.url, request.data));
pm.environment.set('xAmzDate', amzdate);
function getPath(url) {
var pathRegex = /.+?\:\/\/.+?(\/.+?)(?:#|\?|$)/;
var result = url.match(pathRegex);
return result && result.length > 1 ? result[1] : '';
}
function getQueryString(url) {
var arrSplit = url.split('?');
return arrSplit.length > 1 ? url.substring(url.indexOf('?') + 1) : '';
}
function getSignatureKey(secretKey, dateStamp, regionName, serviceName) {
var kDate = sign("AWS4" + secretKey, dateStamp);
var kRegion = sign(kDate, regionName);
var kService = sign(kRegion, serviceName);
var kSigning = sign(kService, "aws4_request");
return kSigning;
}
function sign(key, message) {
return CryptoJS.HmacSHA256(message, key);
}
function getAuthHeader(httpMethod, requestUrl, requestBody) {
var ACCESS_KEY = pm.globals.get("access_key");
var SECRET_KEY = pm.globals.get("secret_key");
var REGION = 'us-east-1';
var SERVICE = 'es';
var ALGORITHM = 'AWS4-HMAC-SHA256';
var canonicalUri = getPath(requestUrl);
var canonicalQueryString = getQueryString(requestUrl);
if (httpMethod == 'GET' || !requestBody) {
requestBody = '';
} else {
requestBody = JSON.stringify(requestBody);
}
var hashedPayload = CryptoJS.enc.Hex.stringify(CryptoJS.SHA256(requestBody));
var canonicalHeaders = 'host:' + pm.environment.get("ESHost") + '\n' + 'x-amz-date:' + amzdate + '\n';
var signedHeaders = 'host;x-amz-date';
var canonicalRequestData = [httpMethod, canonicalUri, canonicalQueryString, canonicalHeaders, signedHeaders, hashedPayload].join("\n");
var hashedRequestData = CryptoJS.enc.Hex.stringify(CryptoJS.SHA256(canonicalRequestData));
var credentialScope = dateStamp + '/' + REGION + '/' + SERVICE + '/' + 'aws4_request';
var stringToSign = ALGORITHM + '\n' + amzdate + '\n' + credentialScope + '\n' + hashedRequestData;
var signingKey = getSignatureKey(SECRET_KEY, dateStamp, REGION, SERVICE);
var signature = CryptoJS.HmacSHA256(stringToSign, signingKey).toString(CryptoJS.enc.Hex);
var authHeader = ALGORITHM + ' ' + 'Credential=' + ACCESS_KEY + '/' + credentialScope + ', ' + 'SignedHeaders=' + signedHeaders + ', ' + 'Signature=' + signature;
return authHeader;
}

The code from the OP is almost accurate just has a few bugs
1) getPath should return "/" when path=''
2) check if request.data is empty object if so requestBody = ''
3) no need to do JSON.stringify(request.data) since request.data returns a json string
The fixed snippet is below:
var date = new Date().toISOString();
var amzdate = date.replace(/[:\-]|\.\d{3}/g, "");
var dateStamp = amzdate.slice(0, -8);
pm.environment.set('authorization', getAuthHeader(request.method, request.url, request.data));
pm.environment.set('xAmzDate', amzdate);
function getPath(url) {
var pathRegex = /.+?\:\/\/.+?(\/.+?)(?:#|\?|$)/;
var result = url.match(pathRegex);
return result && result.length > 1 ? result[1] : '/';
}
function getQueryString(url) {
var arrSplit = url.split('?');
return arrSplit.length > 1 ? url.substring(url.indexOf('?') + 1) : '';
}
function getSignatureKey(secretKey, dateStamp, regionName, serviceName) {
var kDate = sign("AWS4" + secretKey, dateStamp);
var kRegion = sign(kDate, regionName);
var kService = sign(kRegion, serviceName);
var kSigning = sign(kService, "aws4_request");
return kSigning;
}
function sign(key, message) {
return CryptoJS.HmacSHA256(message, key);
}
function getAuthHeader(httpMethod, requestUrl, requestBody) {
var ACCESS_KEY = pm.globals.get("access_key");
var SECRET_KEY = pm.globals.get("secret_key");
var REGION = 'us-east-1';
var SERVICE = 'es';
var ALGORITHM = 'AWS4-HMAC-SHA256';
var canonicalUri = getPath(requestUrl);
var canonicalQueryString = getQueryString(requestUrl);
if (httpMethod == 'GET' || !requestBody || Object.keys(requestBody).length === 0) {
requestBody = '';
}
var hashedPayload = CryptoJS.enc.Hex.stringify(CryptoJS.SHA256(requestBody));
var canonicalHeaders = 'host:' + pm.environment.get("ESHost") + '\n' + 'x-amz-date:' + amzdate + '\n';
var signedHeaders = 'host;x-amz-date';
var canonicalRequestData = [httpMethod, canonicalUri, canonicalQueryString, canonicalHeaders, signedHeaders, hashedPayload].join("\n");
var hashedRequestData = CryptoJS.enc.Hex.stringify(CryptoJS.SHA256(canonicalRequestData));
var credentialScope = dateStamp + '/' + REGION + '/' + SERVICE + '/' + 'aws4_request';
var stringToSign = ALGORITHM + '\n' + amzdate + '\n' + credentialScope + '\n' + hashedRequestData;
var signingKey = getSignatureKey(SECRET_KEY, dateStamp, REGION, SERVICE);
var signature = CryptoJS.HmacSHA256(stringToSign, signingKey).toString(CryptoJS.enc.Hex);
var authHeader = ALGORITHM + ' ' + 'Credential=' + ACCESS_KEY + '/' + credentialScope + ', ' + 'SignedHeaders=' + signedHeaders + ', ' + 'Signature=' + signature;
return authHeader;
}

When setting up a CloudWatch Logs to Amazon Elasticsearch stream, AWS creates a Node.js Lambda function which does proper AWS SigV4 URL signing. Here's the relevant part from that script that you could reuse to properly generate your postman request:
function buildRequest(endpoint, body) {
var endpointParts = endpoint.match(/^([^\.]+)\.?([^\.]*)\.?([^\.]*)\.amazonaws\.com$/);
var region = endpointParts[2];
var service = endpointParts[3];
var datetime = (new Date()).toISOString().replace(/[:\-]|\.\d{3}/g, '');
var date = datetime.substr(0, 8);
var kDate = hmac('AWS4' + process.env.AWS_SECRET_ACCESS_KEY, date);
var kRegion = hmac(kDate, region);
var kService = hmac(kRegion, service);
var kSigning = hmac(kService, 'aws4_request');
var request = {
host: endpoint,
method: 'POST',
path: '/_bulk',
body: body,
headers: {
'Content-Type': 'application/json',
'Host': endpoint,
'Content-Length': Buffer.byteLength(body),
'X-Amz-Security-Token': process.env.AWS_SESSION_TOKEN,
'X-Amz-Date': datetime
}
};
var canonicalHeaders = Object.keys(request.headers)
.sort(function(a, b) { return a.toLowerCase() < b.toLowerCase() ? -1 : 1; })
.map(function(k) { return k.toLowerCase() + ':' + request.headers[k]; })
.join('\n');
var signedHeaders = Object.keys(request.headers)
.map(function(k) { return k.toLowerCase(); })
.sort()
.join(';');
var canonicalString = [
request.method,
request.path, '',
canonicalHeaders, '',
signedHeaders,
hash(request.body, 'hex'),
].join('\n');
var credentialString = [ date, region, service, 'aws4_request' ].join('/');
var stringToSign = [
'AWS4-HMAC-SHA256',
datetime,
credentialString,
hash(canonicalString, 'hex')
] .join('\n');
request.headers.Authorization = [
'AWS4-HMAC-SHA256 Credential=' + process.env.AWS_ACCESS_KEY_ID + '/' + credentialString,
'SignedHeaders=' + signedHeaders,
'Signature=' + hmac(kSigning, stringToSign, 'hex')
].join(', ');
return request;
}
function hmac(key, str, encoding) {
return crypto.createHmac('sha256', key).update(str, 'utf8').digest(encoding);
}
function hash(str, encoding) {
return crypto.createHash('sha256').update(str, 'utf8').digest(encoding);
}

Related

Google Ads scripts - how to do customised or long rolling date ranges

I'm using the following script to export Google Ads data from my account, but I am stuck with Google's pre-set date ranges and can't figure out how/if it's possible to jimmy these. Ideal date range would be year to date, with the report refreshing each day and adding on a fresh day's data, but would also be interested if we can get all time to work.
I'm a coding novice, so apologies in advance.
Script:
function main() {
var currentSetting = new Object();
currentSetting.ss = SPREADSHEET_URL;
// Read Settings Sheet
var settingsSheet = SpreadsheetApp.openByUrl(currentSetting.ss).getSheetByName(SETTINGS_SHEET_NAME);
var rows = settingsSheet.getDataRange();
var numRows = rows.getNumRows();
var numCols = rows.getNumColumns();
var values = rows.getValues();
var numSettingsRows = numRows - 1;
var sortString = "";
var filters = new Array();
for(var i = 0; i < numRows; i++) {
var row = values[i];
var settingName = row[0];
var settingOperator = row[1];
var settingValue = row[2];
var dataType = row[3];
debug(settingName + " " + settingOperator + " " + settingValue);
if(settingName.toLowerCase().indexOf("report type") != -1) {
var reportType = settingValue;
} else if(settingName.toLowerCase().indexOf("date range") != -1) {
var dateRange = settingValue;
} else if(settingName.toLowerCase().indexOf("sort order") != -1) {
var sortDirection = dataType || "DESC";
if(settingValue) var sortString = "ORDER BY " + settingValue + " " + sortDirection;
var sortColumnIndex = 1;
}else {
if(settingOperator && settingValue) {
if(dataType.toLowerCase().indexOf("long") != -1 || dataType.toLowerCase().indexOf("double") != -1 || dataType.toLowerCase().indexOf("money") != -1 || dataType.toLowerCase().indexOf("integer") != -1) {
var filter = settingName + " " + settingOperator + " " + settingValue;
} else {
if(settingValue.indexOf("'") != -1) {
var filter = settingName + " " + settingOperator + ' "' + settingValue + '"';
} else if(settingValue.indexOf("'") != -1) {
var filter = settingName + " " + settingOperator + " '" + settingValue + "'";
} else {
var filter = settingName + " " + settingOperator + " '" + settingValue + "'";
}
}
debug("filter: " + filter)
filters.push(filter);
}
}
}
// Process the report sheet and fill in the data
var reportSheet = SpreadsheetApp.openByUrl(currentSetting.ss).getSheetByName(REPORT_SHEET_NAME);
var rows = reportSheet.getDataRange();
var numRows = rows.getNumRows();
var numCols = rows.getNumColumns();
var values = rows.getValues();
var numSettingsRows = numRows - 1;
// Read Header Row and match names to settings
var headerNames = new Array();
var row = values[0];
for(var i = 0; i < numCols; i++) {
var value = row[i];
headerNames.push(value);
//debug(value);
}
if(reportType.toLowerCase().indexOf("performance") != -1) {
var dateString = ' DURING ' + dateRange;
} else {
var dateString = "";
}
if(filters.length) {
var query = 'SELECT ' + headerNames.join(",") + ' FROM ' + reportType + ' WHERE ' + filters.join(" AND ") + dateString + " " + sortString;
} else {
var query = 'SELECT ' + headerNames.join(",") + ' FROM ' + reportType + dateString + " " + sortString;
}
debug(query);
var report = AdWordsApp.report(query);
try {
report.exportToSheet(reportSheet);
var subject = "Your " + reportType + " for " + dateRange + " for " + AdWordsApp.currentAccount().getName() + " is ready";
var body = currentSetting.ss + "<br>You can now add this data to <a href='https://www.optmyzr.com'>Optmyzr</a> or another reporting system.";
MailApp.sendEmail(EMAIL_ADDRESSES, subject, body);
Logger.log("Your report is ready at " + currentSetting.ss);
Logger.log("You can include this in your scheduled Optmyzr reports or another reporting tool.");
} catch (e) {
debug("error: " + e);
}
}
function debug(text) {
if(DEBUG) Logger.log(text);
}
I've tried overwriting the data validation in the host spreadsheet, but think I need to amend the script itself also.

Converting rdl to pdf using javascript

I want to convert my rdl report to pdf using javascript. It will be really good if I can only use OpenReport() and convert the pdf file there because then I have to convert it into ppt. I am using CRM online.
here is my code.
function OpenReport() {
debugger;
var formType = Xrm.Page.ui.getFormType();
if(formType != 1){
Xrm.Page.ui.setFormNotification("Please wait while system is generating pdf...", "INFO", "pdfGen");
var rdlName = "KalorikBrandPresentationv4.rdl"; //Replace with your report name
var entityType = "10060"; //Replace
var entityGuid = Xrm.Page.data.entity.getId();
var recordId = entityGuid.replace("{","").replace("}","");
var reportGuid = "ea721b27-44a6-ea11-9688-005056ba540f"; //Replace with your report guid
var url = Xrm.Page.context.getClientUrl() + "/crmreports/viewer/viewer.aspx?action=run&context=records&helpID=" + rdlName + "&id=%7b" + reportGuid + "%7d&records=%7b" + recordId + "%7d&recordstype=" + entityType;
var responseSession = getReportingSession(reportGuid,rdlName,recordId);
convertResponseToPDF(responseSession,rdlName);
}
function convertResponseToPDF(responseSession,reportName) {
debugger;
var pth = encodeURI(Xrm.Page.context.getClientUrl() + "/Reserved.ReportViewerWebControl.axd?
ReportSession=" + responseSession[0]+"&Culture=1033&CultureOverrides=True&UICulture=1033&UICultureOverrides=True&ReportStack=1&ControlID=" + responseSession[1] +"&OpType=Export&FileName=Public&ContentDisposition=OnlyHtmlInline&Format=PDF");
var base64PDFString;
var retrieveEntityReq = new XMLHttpRequest();
retrieveEntityReq.open("GET", pth, true);
retrieveEntityReq.setRequestHeader("Accept", "*/*");
retrieveEntityReq.responseType = "arraybuffer";
retrieveEntityReq.onreadystatechange = function () {
if (retrieveEntityReq.readyState == 4 && retrieveEntityReq.status == 200) {
var binary = "";
var bytes = new Uint8Array(this.response);
for (var i = 0; i < bytes.byteLength; i++) {
binary += String.fromCharCode(bytes[i]);
}
base64PDFString = btoa(binary);
console.log(base64PDFString);
createNotesAttachment(base64PDFString,reportName);
}
};
retrieveEntityReq.send();
}
Did you followed the code/steps mentioned here
I remembers I worked on 2016 online for downloading report as PDF. This shall help.
You might want to change code a bit.
function runReportToPrint() {
var invoicenumber = Xrm.Page.getAttribute("invoicenumber").getValue()
if (invoicenumber != null) {
invoicenumber = invoicenumber.substring(4, 9);
var params = getReportingSession();
var newPth = Xrm.Page.context.getClientUrl() + "/Reserved.ReportViewerWebControl.axd?ReportSession=" + params[0] + "&Culture=1033&CultureOverrides=True&UICulture=1033&UICultureOverrides=True&ReportStack=1&ControlID=" + params[1] + "&OpType=Export&FileName=" + invoicenumber + "&ContentDisposition=OnlyHtmlInline&Format=PDF";
window.open(newPth, "_self");
encodePdf(params);
} else {
alert("Invoice ID is Missing");
}
}
function getReportingSession() {
var recordId = Xrm.Page.data.entity.getId();
recordId = recordId.replace('{', '').replace('}', '');
var strParameterXML = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'><entity name='invoice'><all-attributes /><filter type='and'><condition attribute='invoiceid' operator='eq' value='" + recordId + "' /> </filter></entity></fetch>";
var pth = Xrm.Page.context.getClientUrl() + "/CRMReports/rsviewer/QuirksReportViewer.aspx";
var retrieveEntityReq = new XMLHttpRequest();
retrieveEntityReq.open("POST", pth, false);
retrieveEntityReq.setRequestHeader("Accept", "*/*");
retrieveEntityReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
retrieveEntityReq.send("id=%7B" + reportGuid + "%7D&uniquename=" + Xrm.Page.context.getOrgUniqueName() + "&iscustomreport=true&reportnameonsrs=&reportName=" + reportName + "&isScheduledReport=false&p:CRM_invoice=" + strParameterXML);
var x = retrieveEntityReq.responseText.lastIndexOf("ReportSession=");
var y = retrieveEntityReq.responseText.lastIndexOf("ControlID=");
var ret = new Array();
ret[0] = retrieveEntityReq.responseText.substr(x + 14, 24);
ret[1] = retrieveEntityReq.responseText.substr(x + 10, 32);
return ret;
}
function encodePdf(responseSession) {
var retrieveEntityReq = new XMLHttpRequest();
var pth = Xrm.Page.context.getClientUrl() + "/Reserved.ReportViewerWebControl.axd?ReportSession=" + responseSession[0] + "&Culture=1033&CultureOverrides=True&UICulture=1033&UICultureOverrides=True&ReportStack=1&ControlID=" + responseSession[1] + "&OpType=Export&FileName=Public&ContentDisposition=OnlyHtmlInline&Format=PDF";
retrieveEntityReq.open("GET", pth, true);
retrieveEntityReq.setRequestHeader("Accept", "*/*");
retrieveEntityReq.responseType = "arraybuffer";
retrieveEntityReq.onreadystatechange = function () {
if (retrieveEntityReq.readyState == 4 && retrieveEntityReq.status == 200) {
var binary = "";
var bytes = new Uint8Array(this.response);
for (var i = 0; i < bytes.byteLength; i++) {
binary += String.fromCharCode(bytes[i]);
}
var bdy = btoa(binary);
createNote(bdy);
}
};
retrieveEntityReq.send();
}
function createNote(data) {
var note = {};
var recordId = Xrm.Page.data.entity.getId();
recordId = recordId.replace('{', '').replace('}', '');
var invoicenumber = Xrm.Page.getAttribute("invoicenumber").getValue()
invoicenumber = invoicenumber.substring(4, 9);
var refInvoice = new Object();
refInvoice.LogicalName = "invoice";
refInvoice.Id = recordId;
note.ObjectId = refInvoice;
note.ObjectTypeCode = refInvoice.LogicalName;
note.Subject = "Invoice: " + invoicenumber;
note.MimeType = "application/pdf";
note.DocumentBody = data;
note.FileName = invoicenumber + ".pdf";
XrmServiceToolkit.Rest.Create(
note,
"AnnotationSet",
function (result) {
//Alert user
alert("Note Created");
//Refresh data so user sees newly created note
Xrm.Page.data.refresh(false);
},
function (error) {
alert(error.message);
},
true);
}

array value is not updating in for loop in nodejs

I am trying to push data in an array after downloading the image from download function. It's a problem in nodejs promise. How can I fix this issue.
current output:
[
{
sku: 99104942591,
retailer: 'JCREWFCT',
images: []
}
]
expected output:
[
{
sku: 99103497136,
retailer: 'JCREWFCT',
images: [
"http://localhost:4001/JCREWFCT/99103497136.png",
"http://localhost:4001/JCREWFCT/99103497136_1.png"
]
}
]
in outputArr I am trying to store data
var downloadImages = async function() {
var outputArr = [];
for(var i=0; i<excelJsonArr.length; i++) {
var d = excelJsonArr[i];
var out = {
sku : d.sku,
retailer : d.retailer,
images : []
}
if(d.image_link_1) {
var saveDir = path.join('./public', d.retailer, d.sku+'.png');
var imgUrl = properties.get('protocol') + '://' + properties.get('hostname') + ':' + properties.get('port') + '/' + d.retailer + '/' + d.sku + '.png';
await download(d.image_link_1, saveDir, function(){
out.images.push(imgUrl);
});
}
if(d.image_link_2) {
var saveDir = path.join('./public', d.retailer, d.sku+'_2.png');
await download(d.image_link_1, saveDir, function(){
var imgUrl = properties.get('protocol') + '://' + properties.get('hostname') + ':' + properties.get('port') + '/' + d.retailer + '/' + d.sku + '_2.png';
out.images.push(imgUrl);
});
}
outputArr.push(out);
}
console.log(outputArr);
}
var download = async function(uri, filename, callback){
await request.head(uri, function(err, res, body){
console.log('content-type:', res.headers['content-type']);
console.log('content-length:', res.headers['content-length']);
request(uri).pipe(fs.createWriteStream(filename)).on('close', callback);
});
};
I don't know what your download-function actually does but normally, when working with asnyc, you would do this:
await download(d.image_link_1, saveDir);
out.images.push(imgUrl);
and I you should try to work with try to catch any errors coming from download, see: Correct Try…Catch Syntax Using Async/Await
FYI, next time, share more of your code and if possible a reproduceable code or example GitHub repo, so we can see the error by ourself.
Since you are using async await you don't need to use callback function. Just call the desired functions after await
var downloadImages = async function () {
var outputArr = [];
for (var i = 0; i < excelJsonArr.length; i++) {
var d = excelJsonArr[i];
var out = {
sku: d.sku,
retailer: d.retailer,
images: []
}
if (d.image_link_1) {
var saveDir = path.join('./public', d.retailer, d.sku + '.png');
var imgUrl = properties.get('protocol') + '://' + properties.get('hostname') + ':' + properties
.get('port') + '/' + d.retailer + '/' + d.sku + '.png';
await download(d.image_link_1, saveDir, function () {
// out.images.push(imgUrl);// <-- not here
});
out.images.push(imgUrl); // <-- here
}
if (d.image_link_2) {
var saveDir = path.join('./public', d.retailer, d.sku + '_2.png');
await download(d.image_link_1, saveDir, function () {
/* var imgUrl = properties.get('protocol') + '://' + properties.get('hostname') + ':' +
properties.get('port') + '/' + d.retailer + '/' + d.sku + '_2.png';
out.images.push(imgUrl); */ // <-- not here
});
var imgUrl = properties.get('protocol') + '://' + properties.get('hostname') + ':' +
properties.get('port') + '/' + d.retailer + '/' + d.sku + '_2.png';
out.images.push(imgUrl); // <-- here
}
outputArr.push(out);
}
console.log(outputArr);
}

Click and swap data using a javascript callback handler

var tempreture = document.getElementById("temp")
var requestWeather = new XMLHttpRequest();
requestWeather.open('GET', 'https://fcc-weather-api.glitch.me/api/current?lat=-31&lon=150');
requestWeather.onload = function () {
var weatherData = JSON.parse(requestWeather.responseText);
console.log(weatherData);
getTemp(weatherData);
}; requestWeather.send();
function getTemp(data) {
var tempString = "";
var temp = data.main.temp;
tempString += "<p class='weather'>" + temp + '℃' + "</p>";
tempreture.innerHTML = tempString;
tempreture.addEventListener("click", function( ) {
var ftemp = "<p class='weather'>" + changeTemp(temp) + '° F' + "</p>";
tempreture.innerHTML = ftemp;
},false);
}
function changeTemp(temp){
var tp = temp * 1.8 + 32;
var cel =Math.round(tp);
return cel;
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="temp" onclick="getTemp()"></a>
How do I use the click callback handler to swap text from a different string
I want to switch between Fahrenheit and Celsius when a user clicks an element.
This is what I have done so far:
function getTemp(data) {
var tempString = "";
var temp = data.main.temp;
tempreture.addEventListener("click", function( ) {
tempString += "<p class='weather'>" + temp + '℃' + "</p>";
},false)
tempString += "<p class='weather'>" + changeTemp(temp) + '° F' + "</p>";
tempreture.insertAdjacentHTML("beforeend", tempString);
}
function changeTemp(temp){
var tp = (temp - 32) * 5/9;
var cel =Math.round(tp);
return cel;
};
I have only tried this using pure javascript. It would be great if someone can give me a hint as to what I'm doing incorrectly.
var temp = data.main.temp;
The temp is where I got the data from and is passed down to the HTML. I have done the conversion, but I don't know how to pass it back from the conversion function.
ADD the temperature data are come from
var requestWeather = new XMLHttpRequest();
requestWeather.open('GET', 'https://fcc-weather-api.glitch.me/api/current?lat=' + data.lat + '&lon=' + data.lon);
requestWeather.onload = function () {
var weatherData = JSON.parse(requestWeather.responseText);
console.log(weatherData);
getTemp(weatherData);
}
Edit I had tried the click function, now. however, I found same issues with the return back to old value after the click.
I recommend that you validate the data that the API returns.
var tempreture = document.getElementById("temp")
var requestWeather = new XMLHttpRequest();
// global cache
var currentTemp,
currentUnit;
requestWeather.open('GET', 'https://fcc-weather-api.glitch.me/api/current?lat=-31&lon=150');
requestWeather.onload = function() {
var weatherData = JSON.parse(requestWeather.responseText);
console.log(weatherData);
getTemp(weatherData);
};
requestWeather.send();
function getTemp(data) {
currentTemp = typeof data === 'object' ? data.main.temp : null; // save new value in global cache
currentUnit = 'celcius';
tempreture.innerHTML = currentTemp + '℃';
}
tempreture.addEventListener("click", function() {
tempreture.innerHTML = changeTemp();
}, false);
function changeTemp() {
if(currentUnit === 'celcius') {
var tp = currentTemp * 1.8 + 32;
var fh = Math.round(tp);
currentUnit = 'fahrenheit';
return fh + '° F';
} else {
currentUnit = 'celcius';
return currentTemp + '℃';
}
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="temp" class='weather'></span>

node-red.js HTTP POST with API key

I am trying to POST JSOn data to a cloud with this function in function node.
var accx = 15;
var accy = 45;
var accz = 12;
//JSON FORMING BY JAVASCRIPT OBJECT
var output = [];
output[0] = {
name: "Accel_X",
value: accx.toString(), // retrieve x
};
output[1] = {
name: "Accel_Y",
value: accy.toString(), // retrieve y
};
output[2] = {
name: "Accel_Z",
value: accz.toString() // retrieve z
};
var record = [];
record[0] = {
starttime: formatDate(new Date()),
output: output,
};
var observations = [];
observations[0] = {
sensor: "C2105",
record: record,
};
var fromData = {};
fromData.version = "1.0.1";
fromData.observations = observations;
//MONTH NAME FUNCTION
function show_now(){
var my_month=new Date()
var month_name=new Array(12);
month_name[0]="JAN"
month_name[1]="FEB"
month_name[2]="MAR"
month_name[3]="APR"
month_name[4]="MAY"
month_name[5]="JUN"
month_name[6]="JUL"
month_name[7]="AUG"
month_name[8]="SEP"
month_name[9]="OCT"
month_name[10]="NOV"
month_name[11]="DEC"
return month_name[my_month.getMonth()];
}
//RETURN DATE AT FORMATTED WAY THAT IS ACCEPTED BY CLOUD
function formatDate(d) {
return d.getDate() + '-' + (show_now()) + "-" + d.getFullYear() + " " + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + " IST";
}
var fromDatan = JSON.stringify(fromData);
//alert(fromDatan);
//POST JSON SENSOR DATA
fromDatan.headers = {
"x-api-key": "ucrFr234r23rrxfAIH2L4=",
"content-type": "application/json;charset=UTF-8"
}
return fromDatan;
I have given correct url in url node but it is returning no response and I am not seing any data is being post
Anyone please worked with node-red.js please help.
Your function node needs to return an object with a payload property containing the data you want to send in the http request. It is also not necessary to stringify the object as the http request node will do that for you.
var fromDatan = {};
fromDatan.payload = fromData;
fromDatan.headers = ...
return fromDatan

Categories