AWS Lambda web service calls - web-services

I managed to get the following working in Lambda (not throwing errors) but how can I see the actual response json?
var https = require('https');
exports.handler = function (event, context) {
https.get('https://www.quandl.com/api/v3/datasets/FRED/M12015USM144NNBR.json? api_key=XXXXXXXXXXXXXXXX', function (result) {
console.log('Success, with: ' + result.statusCode);
context.done(null);
}).on('error', function (err) {
console.log('Error, with: ' + err.message);
context.done("Failed");
});
};

HMMM... isn't (result) comes back with the object contains with the request response from data event?
Where is body in a nodejs http.get response?

Related

Amazon Lambda & API Gateway - 'event.source_ip' returns 'null'

I'm trying to grab the IP of users.
I followed guides on how to do this, and found answers that use event.source_ip in the lambda function, which connects to the API Gateway.
The result returns 'null' in my Lex & Facebook bots, and returns 'test-invoke-source-ip' in the API Gateway Test.
Lambda:
exports.handler = (event, context, callback) => {
callback(null, event.source_ip);
};
API Gateway: Integration Request
Use lambda proxy integration, then you can handle the event and context from the lamda function yourself. You can read more here. https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
You will need to return expected output for it to work.
Example using node (untested):
exports.handler = (event, context, callback) => {
var res = {
"statusCode": 200,
"body": context.identity.sourceIp,
"isBase64Encoded": false,
}
callback(null, res);
}

How do you pass query string parameters to the AWS API Gateway client with the Javascript SDK?

I have an endpoint defined in AWS API Gateway that uses a Lambda integration. The Lambda function expects query string parameters that would be available in the event object passed to it.
My API is at example.execute-api.us-east-1.amazonaws.com/dev/my-resource and I have query string parameters like foo=test.
So the full endpoint would be
example.execute-api.us-east-1.amazonaws.com/dev/my-resource?foo=test
I can visit this endpoint in a browser or request it in postman, and get the expected response, so I know that the API Gateway is configured properly. However when I use the Javascript SDK, I can't seem to pass query string parameters.
According to the last part of this page from the docs, I should be able to just pass in a JSON object that will be interpreted as query string parameters, like so:
var apiClient = apigClientFactory.newClient();
var requestParams = {"foo": "test"};
apiClient.myResourceGet(requestParams).then(function(result) {
// Do something with the response
});
However, in my case requestParams seems to be ignored. In the Lambda function, the event has an empty queryStringParameters field. How can I pass the key/values defined in the requestParams object as query string parameters to this endpoint?
since your following end point passing query param , you really no need json objet
example.execute-api.us-east-1.amazonaws.com/dev/my-resource?foo=test
create variable
var test = <assign value>
now
var params = {
host: "execute-api.us-east-1.amazonaws.com",
path: "/dev/my-resource?foo="+test
};
Example :
var https = require('https');
exports.handler = (event, context, callback) => {
var params = {
host: "bittrex.com",
path: "/api/v1.1/public/getmarketsummaries"
};
var req = https.request(params, function(res) {
let data = '';
console.log('STATUS: ' + res.statusCode);
res.setEncoding('utf8');
res.on('data', function(chunk) {
data += chunk;
});
res.on('end', function() {
console.log("DONE");
console.log(JSON.parse(data));
});
});
req.end();
};

Get PDF from API using AWS API gateway and Lambda

I have an internal API that provides data in different formats by just passing the id + format. For Example if I want to get a PDF of a produc with ID = 1 I will just make a call to the app with apiurl/latest/1.pdf.
This works fine when I am in the internal network since the host is only available internally. To access it publicly, we have implemented an authorization using API gateway and Lambda. Lambda takes are of the authorization and return the result just fine :
When I request JSON data
When I request XML data
Here a sample version of the lambda:
var request = require('request');
exports.handler = function(event, context, callback) {
var fUrl = event.fUrl + event.pid;
if(event.fsUrl.indexOf('product') >-1){
fUrl = fUrl + '.' + event.format
}
request({
url: fUrl,
}, function(error, response, body) {
if(error){
return callback(error);
}else{
return callback(null, response.body);
}
});
}
but not PDF. Some screens from the postman. I used both Send and Download in Postman.
Any thoughts?

How do I get response headers for AWS JavaScript SDK calls?

I have a simple AWS Lambda function which makes an S3.getObject() call as follows:
const AWS = require('aws-sdk');
AWS.config.logger = console;
const s3 = new AWS.S3();
exports.handler = async (event) => {
return await getObject({
Bucket: "<MY-BUCKET>",
Key: "<MY-KEY>"
}).then( (res) => {
console.log('Retrieved object from S3');
console.log(res);
return res.Body.toString('ascii');
})
};
async function getObject(params){
return await s3.getObject(params).promise();
}
I've enabled logging SDK calls as per this document.
How do I get response headers for the s3.getObject() SDK call that was made? I am basically trying to retrieve the S3 request ID and extended request ID.
The in-built logger added via the "AWS.config.logger = console;" line does not seem to log response headers. How else do I get response headers for AWS JavaScript SDK calls?
P.S: Bonus points if you can let me know whether or not I need two await keywords in the code above.
Listen to httpHeaders event.
var requestObject = s3.getObject(params);
requestObject.on('httpHeaders', (statusCode, headers, response, statusMessage) => {
// your code here.
});
requestObject.promise()
.then(response => { ... })

How to make SSL-Requests with AWS-Lambda-Function?

I have a AWS-Lambda function that gots triggered after a file was placed into an S3-Bucket.
This is my lambda-function:
var http = require('http');
exports.handler = function (event, context) {
var bucket = event.Records[0].s3.bucket.name;
var key = event.Records[0].s3.object.key;
var newKey = key.split('.')[0].slice(8);
var url = 'https://xxxxx.herokuapp.com/api/messages/'+newKey+'/processingFinished'
console.log("URL:" + url)
http.get(url, function (result) {
console.log('!!!! Success, with: ' + result.statusCode);
context.done(null);
}).on('error', function (err) {
console.log('Error, with: ' + err.message);
context.done("Failed");
});
};
In CloudWatch Logfiles i see complaints that https is not supported:
2017-07-27T10:38:04.735Z 8428136e-72b7-11e7-a5b9-bd0562c862a0 Error: Protocol "https:" not supported. Expected "http:"
at new ClientRequest (_http_client.js:54:11)
at Object.exports.request (http.js:31:10)
at Object.exports.get (http.js:35:21)
at exports.handler (/var/task/index.js:18:8)
But the listed URL can be opened with any webbrowser. The Server accepts SSL and the whole API is working per SSL.
Why is AWS denying SSL-Requests? How to solve this?
Per the node documentation: (https://nodejs.org/api/https.html)
HTTPS is the HTTP protocol over TLS/SSL. In Node.js this is implemented as a separate module.
Use
http = require('https');