Getting error on hitting Google Vision Api - node.js

const options = {
hostname: 'https://vision.googleapis.com/v1/images:annotate?key=<some key>',
method: 'POST',
headers: {
'Content-Type' : 'application/json'
}
};
const req = http.request(options, (res : any) => {
res.on('data', (chunk : any) => {
console.log(`BODY: ${chunk}`);
});
});
req.on('error', (e) => {
console.log(e)
console.error(`problem with request: ${e.message}`);
});
// Write data to request body
req.write(JSON.stringify(body))
req.end()
I am trying to use one of the google vision feature i.e. Text Detection. But when ever I am hitting that api I am getting this error. I double checked the url and other data.
{ Error: getaddrinfo ENOTFOUND https://vision.googleapis.com/v1/images:annotate?key=<> https://vision.googleapis.
com/v1/images:annotate?key=<key>:80
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:56:26)
errno: 'ENOTFOUND',
code: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname:
'https://vision.googleapis.com/v1/images:annotate?key=<key>',
host:
'https://vision.googleapis.com/v1/images:annotate?key=<key>',
port: 80 }

This code should work, there are only a couple of changes necessary, for example we'll use the https module rather than the http module.
const https = require('https');
const options = {
hostname: 'vision.googleapis.com',
path: '/v1/images:annotate?key=' + API_KEY,
method: 'POST',
headers: {
'Content-Type' : 'application/json'
}
};
let data = "";
const req = https.request(options, (res: any) => {
res.on('data', (chunk: any) => {
data += chunk;
});
res.on('end', (chunk) => {
console.log(`BODY: ${data}`);
});
});
req.on('error', (e) => {
console.log(e)
console.error(`problem with request: ${e.message}`);
});
// Write data to request body
req.write(JSON.stringify(body))
req.end()

Try modifying the request to:
const options = {
method: 'POST',
headers: {
'Content-Type' : 'application/json'
}
};
const req = http.request(`https://vision.googleapis.com/v1/images:annotate?key=<some key>`, options, (res : any) => {
res.on('data', (chunk : any) => {
console.log(`BODY: ${chunk}`);
});
});
because https://vision.googleapis.com/v1/images:annotate?key=<some key> is a full URL, not a valid hostname.

Related

Error: socket hang up - Lambda nodejs function http post request

I have a very simple function in Lambda using Nodejs.
The purpose of that function is to triggered a third party api every 1 minute.
So for that I have setup Cloud Watch Cron based event.
But that Api is throwing this error:
START RequestId: 54d90c9d-0a5b-4e5e-a26a-857d9bb6dd4e Version: $LATEST
2022-08-29T11:11:59.112Z 54d90c9d-0a5b-4e5e-a26a-857d9bb6dd4e ERROR Error: socket hang up
at connResetException (node:internal/errors:692:14)
at TLSSocket.socketOnEnd (node:_http_client:478:23)
at TLSSocket.emit (node:events:539:35)
at endReadableNT (node:internal/streams/readable:1345:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
code: 'ECONNRESET'
It works fine in a simple nodejs code on my local machine.
Here is my Lambda Function code:
const https = require('https');
exports.handler = async (event) => {
var postData = JSON.stringify({
"client_id": "abnbfye9-qtfnf1cj-abhrhzfyf7-m2tup-6x9kk2kc5688",
"client_secret": "fpghfh329-polk80s-ye043465p1yy-45hxnfd874z06",
"inTime": new Date(),
"outTime": new Date()
});
var options = {
hostname: 'example.com',
path: '/api/updateDataLambda',
method: 'POST',
port: 443, // 👈️ replace with 80 for HTTP requests
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiJ0ekpFTlNxcDJXeXh4YlNGbSIsImFjY2Vzc1Rva2VuRXhwIjp7ImRhdGUiOiIyMDIyLTA5LTI4IiwidGltZSI6IjA2OjIwOjQ1IiwidGltZVN0YW1wIjoxNjY0MzQ2MDQ1NjQ2LCJnbXQiOiIrMDAwMCJ9LCJyZWZyZXNoVG9rZW5FeHAiOnsiZGF0ZSI6IjIwMjItMDktMjgiLCJ0aW1lIjoiMDY6MjA6NDUiLCJ0aW1lU3RhbXAiOjE2NjQzNDYwNDU2NDYsImdtdCI6IiswMDAwIn0sImlhdCI6MTY2MTc1NDA0NSwiZXhwIjoxNjYxNzU0MTA1fQ.g1e5S15Q1qxB5_s4j3LFfFf6spU8gwgBUyVNLVuWNWk'
}
};
var req = https.request(options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
});
req.on('error', (e) => {
console.error(e);
});
req.write(postData);
req.end();
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Lambda!'),
};
return response;
};
Am I doing something wrong here?

Send request with equivalent to Python's bytes() in Node.js

I'm looking to send a request in Node.js which requires sending the data in byte format.
In python, I've implemented it as follow:
r = requests.post(url="https://example.com",headers=headers, data=bytes(exampleArray))
The type of exampleArray is uint8 array
Is it possible to do this same post in Node.js, potentially with axios or another module?
Axios accepts a variety of formats as payload. This is an example with an Uint8Array array:
const axios = require('axios');
const data = new TextEncoder().encode(
JSON.stringify({
foo: 'bar',
})
);
axios
.post('http://localhost:3001', data)
.then((res) => {
console.log(`Status: ${res.status}`);
console.log('Body: ', res.data);
})
.catch((err) => {
console.error(err);
});
The same applies to the http(s) module
const http = require('http');
const data = new TextEncoder().encode(
JSON.stringify({
foo: 'bar',
})
);
const options = {
hostname: 'localhost',
port: 3001,
path: '/',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length,
},
};
const req = http.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();

How to send the result of a GET request in a POST request?

I need to send a GET request to https://random.dog/woof.json. It generate a random image and returns a json like this {
"fileSizeBytes": 1133380,
"url": "https://random.dog/8aff4e84-260d-4af0-9dc1-438d07ba3884.jpg"
} and I need save an image to my database. How can I take "url" and send it with POST request?
you can use node-fetch for server side requests.
It's similar to js' fetch api:
const fetch = require('node-fetch');
fetch('https://random.dog/woof.json')
.then(res => res.json())
.then(json => {
console.log("URL:", json[0].url);
fetch('<url for your post request>', {
method: 'POST',
body: { url: json[0].url },
headers: { 'Content-Type': 'application/json' }
}).then(postRes => postRes.json())
.then(postJson => console.log(postJson));
})
You can do something like that
const https = require('https')
function getData(url: String) {
const options = {
hostname: 'exemple.com',
path: '/your-endpoint',
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
}
const req = https.request(options, (response: any) => {
let body = '';
response.on("data", (data: String) => {
body += data;
})
response.on("end", () => {
console.log(body)
})
response.on("error", (error: String) => {
console.error(error)
})
})
req.write(JSON.stringify({
url
}));
req.end()
}
https.get("https://random.dog/woof.json", (response: any) => {
let body = '';
response.on("data", (chunk: String) => {
body += chunk;
})
response.on("end", () => {
const obj = JSON.parse(body);
getData(obj.url)
})
});

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
}
}

error using nodejs to do http post request

I have followed some instructions to do http request in nodejs and I am doing it in TypeScript in the following way:
code that calls the function to do http post call:
const getCaseInfoRequest: GetCaseInfoRequest = {
emailAddress: 'some-email-address#amazon.com'
};
makeCardinalCall('/SalesforceCaseService/1.0/GetCaseInfoFromEmail', getCaseInfoRequest, process.env.STAGE)
.then((data) => {
...
}).catch(...);
the function that does http post call:
export function makeCardinalCall(path: string, requestBody: GetCaseInfoRequest, stage?: string) {
return new Promise((resolve, reject) => {
const data = JSON.stringify(requestBody);
const options: http.RequestOptions = {
host: 'my-service.google.com',
port: 443,
path: path,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length,
}
};
const req = http.request(options, (res: http.IncomingMessage) => {
res.setEncoding("utf8");
let data = '';
res.on('data', chunk => {
data += chunk;
});
res.on('end', () => {
resolve(data);
})
});
req.on('error', (e: any) => {
reject(e);
});
req.end(data);
});
}
but i always got the following error:
{"bytesParsed":0,"code":"HPE_INVALID_CONSTANT","reason":"Expected HTTP/","rawPacket":{"type":"Buffer","data":[21,0,0,0,2,1,0]}}
any hint / help would be greatly appreciated!
You're attempting to use the raw http module with an HTTPS endpoint (as evident from the port 443). The HTTP parser fails to parse the TLS bytes coming over the wire.
For your own sanity's sake, use a wrapper module for requests -- such as node-fetch...

Resources