ENOTFOUND when making API call from Azure Functions NodeJS - node.js

I am trying to make an API call using Azure Functions. But I am getting below error.
{
"errno": "ENOTFOUND",
"code": "ENOTFOUND",
"syscall": "getaddrinfo",
"hostname": "https://jsonplaceholder.typicode.com",
"host": "https://jsonplaceholder.typicode.com",
"port": "80"
}
My Code
var http = require('http');
module.exports = function (context) {
context.log('JavaScript HTTP trigger function processed a request.');
var options = {
host: 'https://jsonplaceholder.typicode.com',
port: '80',
path: '/users',
method: 'GET'
};
// Set up the request
var req = http.request(options, (res) => {
var body = "";
res.on("data", (chunk) => {
body += chunk;
});
res.on("end", () => {
context.res = body;
context.done();
});
}).on("error", (error) => {
context.log('error');
context.res = {
status: 500,
body: error
};
context.done();
});
req.end();
};
How could I solve this?

You made a few common mistakes:
You are using http module for https URL.
Change host value to jsonplaceholder.typicode.com
For https protocol port should be 443
Change options as below:
For http:
var options = {
host: 'jsonplaceholder.typicode.com',
port: '80',
path: '/users',
method: 'GET'
};
For https:
Use https module to make request and options object should be like this
var options = {
host: 'jsonplaceholder.typicode.com',
port: '443',
path: '/users',
method: 'GET'
};
Demo:https://repl.it/repls/RepentantGoldenrodPriority

Related

Error: getaddrinfo ENOTFOUND error when making an HTTPS/HTTP request

Here's the code of my AWS Lambda function:
console.log('Loading function');
const AWS = require('aws-sdk');
const https = require('https');
const data = JSON.stringify({
secretKey:"someSecretKey",
userType:"someCoolUser",
})
const options = {
hostname: "backend-staging.programmingpathshala.com:8080/rest/admin",
path: '/sendEmailToUsers',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length
}
}
exports.handler = function(event, context, callback) {
var dataString = '';
const req = https.request(options, function(res) {
res.on('data', chunk => {
dataString += chunk;
});
res.on('end', () => {
callback(null,dataString);
});
});
req.write(data)
req.end();
req.on('error', (e) => {
console.error(e);
});
}
When I test my API using postman it works fine. But when it is called from lambda function I get the following error:
Also, When I run the same API using ngrok and use its link in my lambda function it works then too.
Based on the comments, the options should be:
const options = {
hostname: "backend-staging.programmingpathshala.com",
port: 8080,
path: '/rest/admin/sendEmailToUsers',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length
}
}

How to send post request to iotdata service with authorization from a node js lambda function

I have the following post request that works in insomnia, but am not sure how to send it in node js lambda function, specifically I don't know how to do the authorization.
Here is my setup in insomnia
post request
https://obsf-ats.iot.us-east-1.amazonaws.com/things/esp8266_7F3B95/shadow
json
{
"state" :{
"desired":{
"on": true
}
}
}
auth
What I would do, but don't know where to put the auth, I am also not sure where to put the body of the message. Any help would be greatly appreciated.
const https = require('https')
const data = JSON.stringify({
todo: 'Buy the milk'
})
const options = {
hostname: 'https://obsf-ats.iot.us-east-1.amazonaws.com',
port: 443,
path: '/things/esp8266_7F3B95/shadow',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length
}
}
const req = https.request(options, res => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', d => {
process.stdout.write(d)
})
})
req.on('error', error => {
console.error(error)
})
req.write(data)
req.end()
UPDATE: I have tried the following but it error with no console, is there a way to get the request error
var load = JSON.stringify({
state: {
desired: {
on: false,
},
},
});
request(
aws4.sign(
{
hostname: "https://obsf-ats.iot.us-east-1.amazonaws.com",
service: "iotdata",
region: "us-east-1",
method: "POST",
path: "/things/esp8266_7F3B95/shadow",
headers: {
"Content-Type": "application/x-amz-json-1.0",
},
body: load,
},
{
secretAccessKey: "obsf/obsf/x5Hpej0I",
accessKeyId: "obsf",
}
)
);
UPDATE: I am getting the following error and a 403
etaddrinfo ENOTFOUND https://obsf-ats.iot.us-east-1.amazonaws.com
Had to change this from
hostname: 'https://obsf-ats.iot.us-east-1.amazonaws.com',
to this
hostname: 'obsf-ats.iot.us-east-1.amazonaws.com',

How to use https module with uri?

I am trying to use native https module in nodejs.
The code sample below works fine with request-promise-native library
var apiver = '2017-09-01';
var resource = 'https://management.azure.com/';
const rp = require('request-promise-native');
var options = {
uri: `${process.env["MSI_ENDPOINT"]}/?resource=${resource}&api-version=${apiver}`,
headers: {
'Secret': process.env["MSI_SECRET"]
}
};
return rp(options);
Here the uri = "http://127.0.0.1:41437/MSI/token//?resource=https://management.azure.com/&api-version=2017-09-01"
But if I try to do the same thing using https module it throws error
return new Promise( (resolve,reject) => {
var apiver = '2017-09-01';
var resource = 'https://management.azure.com/';
var options = {
"method": "GET",
"hostname": "localhost",
"port": 41437,
"protocol": "https:",
"path": `/MSI/token/?resource=${resource}&api-version=${apiver}`,
headers: {
'Secret': process.env["MSI_SECRET"]
}
};
var req = https.request(options, function (res) {
var body = '';
res.setEncoding('utf8');
res.on('data', function (chunk) {
body += chunk;
});
res.on('end', function () {
if (res.statusCode == 200) {
resolve(body);
} else {
reject({'error':null,'res':res});
}
});
});
req.on('error', function (e) {
reject({'error':e,'res':null});
});
req.end();
});
Following error is thrown
{
hostname: 'localhost',
port: 41437,
protocol: 'https:',
path: '/MSI/token/?resource=https://management.azure.com/&api-version=2017-09-01',
headers: { Secret: '41A1BDD07D4B42159F71353FCCE2F0EB' } }
2018-10-05T11:36:12.395 [Info] { error: {
Error: connect EACCES 127.0.0.1:41437
at Object.exports._errnoException (util.js:1020:11)
at exports._exceptionWithHostPort (util.js:1043:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1086:14)
code: 'EACCES',
errno: 'EACCES',
syscall: 'connect',
address: '127.0.0.1',
port: 41437
},
res: null
}
Is it not possible to do this request with native https module?

One Signal Push Notification

How to include small icon and big icon url while creating a push notification in node js, I know that we need to send image url while sending push notification, i need code sample in node js.. I have this code..
sendNotificationToSpecific =function (token,messages) {
var sendNotification = function (data) {
var headers = {
"Content-Type": "application/json; charset=utf-8",
"Authorization": "Basic MDNlMTNjYWMTgy"
};
var options = {
host: "onesignal.com",
port: 443,
path: "/api/v1/notifications",
method: "POST",
headers: headers
};
var https = require('https');
var req = https.request(options, function (res) {
res.on('data', function (data) {
console.log("Response:");
console.log(JSON.parse(data));
});
});
req.on('error', function (e) {
console.log("ERROR:");
console.log(e);
});
req.write(JSON.stringify(data));
req.end();
};
var message = {
app_id: "awer342-d744-4787-b59a-f55c6215c491",
contents: {"en": messages},
include_player_ids: [token],
};
sendNotification(message);
};
As you can see in the docs https://documentation.onesignal.com/reference#section-appearance you can simply extend your message object like
var message = {
app_id: "xxxx",
contents: {"en": messages},
include_player_ids: [token],
small_icon: "resource_name", // can not be an url
large_icon: "http://url/ or resource_name"
}

Socket hang up error on https request to external API?

I'm receiving a socket hang up error when attempting to access an external API. The external API can be reached manually (click here) and returns results even when using my API key (that's a development API key used to demonstrate the API on the site).
The code I'm using looks like the following. Please note when you see my_api_key the real key exists.
var zipCodeApiPath = '/rest/my_api_key/radius.json/{{zip}}/15/mile';
...
var https = require('https');
...
var options = {
hostname: 'zipcodedistanceapi.redline13.com',
port: 443,
path: zipCodeApiPath.replace('{{zip}}', zipCode),
method: 'GET',
secureProtocol: 'SSLv3_method'
};
options.agent = new https.Agent(options);
console.log(options);
https.request(options, function(res) {
console.log(res);
...
});
When logging out the options to the console I get this:
{ hostname: 'zipcodedistanceapi.redline13.com',
port: 443,
path: '/rest/my_api_key/radius.json/80549/15/mile',
method: 'GET',
secureProtocol: 'SSLv3_method',
agent:
{ domain: null,
_events: { free: [Function] },
_maxListeners: 10,
options: [Circular],
requests: {},
sockets: {},
maxSockets: 5,
createConnection: [Function: createConnection] } }
Why won't it respond?
Code in Progress
Below is the code in progress based off of the answer by mscdex.
var req = https.request(options, function(res) {
var response = '';
res.on('data', function(chunk) {
response += chunk;
});
res.on('end', function() {
var newObj = {
zip: zipCode,
codes: JSON.parse(response).zip_codes
};
coll.insert(newObj, function(err, item) {
if (err) {
callback(err);
}
else {
console.log(item.codes);
callback(null, item.codes);
}
});
});
});
req.end();
req.on('error', function(e) {
console.log(e);
});
There's a couple of things missing here:
You are not calling .end() on your request object so that the request can be sent to the server.
You should read from the response stream.

Resources