I got "Internal server error" Status: 502 on AWS API Gateway. Searched solutions this post says need to handle callback with a callback function. Would anyone please advise how to incorporate the callback codes with my AWS-Lambda function below? Thank you so much.
message: "Internal server error" when try to access aws gateway api
callback(null, {
statusCode: 200,
body: JSON.stringify(message),
headers: {'Content-Type': 'application/json'}
});
My AWS-Lambda function
'use strict';
const AWS = require('aws-sdk');
exports.handler = async (event, context) => {
const documentClient = new AWS.DynamoDB.documentClient();
let responseBody = "";
let statusCode = 0;
const {
id,
productname
} = JSON.parse(event.body);
const params = {
TableName: "Products",
Item: {
id: id,
productname: productname
}
};
try {
const data = await documentClient.put(params).promise();
responseBody = JSON.stringify(data);
statusCode = 201;
} catch (err) {
responseBody = `Unable to put product: ${err}`;
statusCode = 403;
}
const response = {
statusCode: statusCode,
headers: {
"Content-Type": "application/json"
},
body: responseBody
};
return response
};
Related
I was just having fun in sending me SMS from a Lambda called via API Gateway (REST API). No problem at all until it suddendly stopped sending SMS. I'm actually using a free tier level on my AWS account, but in no way I have reached the maximum sendable SMS limit.
Permissions and roles have not been modified from yesterday when text messages still were arriving to my verified mobile number.
As you can see, inside my code, I used a "test2" variable to return the result for SMS sending but it's barely useless.
Is there any way to better undestand the error behind this problem? And why am I getting it all of a sudden?
My lambda code:
const AWS = require("aws-sdk");
const dynamo = new AWS.DynamoDB.DocumentClient();
const SNS = new AWS.SNS();
const tableName = "Testing";
const smsMessage = {
PhoneNumber: '+39#mynumber#',
Message: 'Someone called your api!'
};
const httpMethodConverter = 'http-method';
const pathRequestConverter = "resource-path";
const headers = {
"Access-Control-Allow-Origin":"https://#myaccount#.github.io",
"Content-Type": "application/json",
"Access-Control-Allow-Methods": "GET, POST, PATCH, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "Origin, Content-Type, X-Auth-Token"
};
let body;
let statusCode = 200;
let test2;
exports.handler = async (event, context) => {
try {
let test = JSON.stringify(event);
let callContext = event.context;
let httpMethod = callContext[httpMethodConverter];
let path = callContext[pathRequestConverter];
let methodAndPath = httpMethod + " "+ path;
test2= await SNS.publish(smsMessage).promise();
switch (methodAndPath) {
case "DELETE /items/{id}":
await dynamo
.delete({
TableName: tableName,
Key: {
Id: parseInt(JSON.parse(test).params.path.id)
}
})
.promise();
body = `Deleted item ${JSON.parse(test).params.path.id}`;
break;
case "GET /items/{id}":
body = await dynamo
.get({
TableName: tableName,
Key: {
Id: parseInt(JSON.parse(test).params.path.id)
}
})
.promise();
break;
case "GET /items":
body = await dynamo.scan({ TableName: tableName }).promise();
break;
case "POST /items":
var bodyParser = "body-json";
var bodyPassed = JSON.parse(test)[bodyParser];
await dynamo
.put({
TableName: tableName,
Item: {
Id: parseInt(bodyPassed.Id),
Type: bodyPassed.Type
}
})
.promise();
body = "Put item "+ bodyPassed.Type+ " id: " + parseInt(bodyPassed.Id);
break;
default:
throw new Error(`Unsupported route: "${event.context}"`);
}
} catch (err) {
statusCode = 400;
body = err.message;
} finally {
body = JSON.stringify(body);
}
return {
statusCode,
body,
headers,
test2
};
};
This is the answer for my SNS.publish(message).promise
"test2": {
"ResponseMetadata": {
"RequestId": "b2fbd9fc-4cc0-54e8-a660-82#########"
},
"MessageId": "c94393bf-cbb3-5cb9-8155-c#########"
}
If you enable delivery status logging through e.g. https://docs.aws.amazon.com/sns/latest/dg/sms_stats_cloudwatch.html, you should receive an error message detailing why the message could not be delivered. Most likely, you've hit the default monthly $1 spend limit quota.
I'm very new to Lambda.
My goal is to have an API endpoint where I can include an URL as argument (and probably a password), and have Lambda retrieve the file on that url, and save it into an S3 bucket.
I have the bucket ready, and have been reading all tutorials and examples I could find regarding lambda, but so far I can't figure out the pieces needed to get this to work.
Any guidance would be appreciated.
EDIT 1:
I got this far. This receives the url parameters from the API and checks the password, but it doesn't execute the get:
exports.handler = async (event) => {
let url = '';
let key = '';
let out = 'empty';
url = event["queryStringParameters"]['url'];
key = event["queryStringParameters"]['key'];
if (key != 'secret')
{
const response = {
statusCode: 200,
body: JSON.stringify('Unauthorized')
};
return response;
}
console.log("START");
var https = require('https');
https.get(url, function(res) {
console.log("Got response: " + res.statusCode);
const response = {
statusCode: 200,
body: JSON.stringify("success")
};
return response;
}).on('error', function(e) {
console.log("Got error: " + e.message);
const response = {
statusCode: 200,
body: JSON.stringify("fail")
};
return response;
}).end();
const response = {
statusCode: 200,
body: JSON.stringify(out)
};
return response;
};
I am working on a custom auth solution, I backend is on NODE (lambda) and calling that lambda by API gateway (it's a post-call).
For every thin is working fine if I use no-Proxy APIs, but in my case in need to pass custom additional headers. And when I tried with prox it is not responding. (it look like Cognito async call takes time or response is not resolving)
I am not sure I am missing some configuration or something wrong with code (code is working fine individual lambda and with API without Proxy).
here is my Lambda code.
// const AWS = require("aws-sdk");
// var crypto = require("crypto-js");
var CryptoJS = require("crypto-js");
var Crypto = require("crypto");
const { CognitoIdentityServiceProvider } = require("aws-sdk");
const hashSecret = (clientSecret, username, clientId) =>
Crypto.createHmac("SHA256", clientSecret)
.update(username + clientId)
.digest("base64");
async function isUserValid() {
const USER_POOL_ID = "poolid";
const CLIENT_ID = "clidntID";
const CLIENT_SECRET = "secreteCode";
const Password = "userName";
const Username = "password";
const cognito = new CognitoIdentityServiceProvider({
region: "ap-southeast-2",
});
try {
const payload = {
UserPoolId: USER_POOL_ID,
AuthFlow: "ADMIN_NO_SRP_AUTH",
ClientId: CLIENT_ID,
AuthParameters: {
USERNAME: "username",
PASSWORD: "password",
SECRET_HASH: hashSecret(CLIENT_SECRET, Username, CLIENT_ID),
},
};
const response = await cognito.adminInitiateAuth(payload).promise();
// // console.log("respone :", response)
// console.log("before response node js lambda ::: ")
return response;
} catch (e) {
console.log("error : ", e.message);
}
}
async function test() {
return "test ";
}
exports.handler = async (event) => {
// TODO implement
console.log("event : ", event);
'
const response = {
statusCode: 200,
headers: {
"Content-Type" : "application/json",
"Access-Control-Allow-Origin" : "*",
"X-Content-Type-Option" : "nosniff",
"Content-Security-Policy" : "default-src self",
"X-frame-options" : "DENY",
"Cache-Control" : "max-age=86400",
"X-XSS-protection" : 0,
"X-rate-limit": 600,
"Strict-Transport-Security": "max-age=31536000; includeSubDomains",
},
// body: await test() // (this response is working fine
body: await isUserValid(),
};
return response;
};
Errors when tested from API gateway with proxy setting on :
{
"message": "Internal server error"
}
Response Headers
{"x-amzn-ErrorType":"InternalServerErrorException"}
I tried multiple options but nothing is working for me.
The 'body' property must be a JSON string.
await cognito.adminInitiateAuth(payload).promise() is returning an object. You need to JSON.stringify() that response. Be sure to take care of the error case , too.
Goal: Get real-time stock data from IEX API, store it in DynamoDB, use data in DynamoDB to display on site.
Edit: I want to use the pull mechanism from the API where I can pull data periodically.
Currently, on API gateway, I created a get method for my stocks resource where I set the integration type to HTTP and entered the IEX Endpoint URL as the Endpoint URL. For now, I just got the data for one stock and the JSON Response Body looks like:
{
"symbol": "AAPL",
"companyName": "Apple Inc",
"primaryExchange": "NASDAQ/NGS (GLOBAL SELECT MARKET)",
"calculationPrice": "close",
"open": 132.5,
"openTime": 1610116201607,
"openSource": "official",
"close": 132.05,
"closeTime": 1610139600449,
"closeSource": "official"
}
I want to integrate Lambda here somehow so that it can get this API data and store it in DynamoDB. So far this is what my Lambda function looks like:
'use strict';
const AWS = require('aws-sdk');
exports.handler = async (event, context) => {
const documentClient = new AWS.DynamoDB.DocumentClient();
let responseBody = "";
let statusCode = 0;
const { symbol, companyName } = JSON.parse(event.body);
const params = {
TableName: "Stocks",
Item: {
symbol: symbol,
companyName: companyName
}
};
try {
const data = await documentClient.put(params).promise();
responseBody = JSON.stringify(data);
statusCode = 201;
} catch(err) {
responseBody = `Unable to put product: ${err}`;
statusCode = 403;
}
const response = {
statusCode: statusCode,
headers: {
"Content-Type": "application/json"
},
body: responseBody
};
return response
};
How do I get the API data from API Gateway and integrate it with a Lambda function that stores this data to DynamoDB?
I have a Lambda which looks like so:
module.exports.handler = (event, context, callback) => {
AWS.config.setPromisesDependency(null);
const uploadPromise = s3.upload(params).promise();
uploadPromise.then((data) => {
const response = {
...
};
return response;
}).catch((error) => {
console.log(error);
});
};
Calling it from Postman results in server error in Postman. CloudWatch logs have no further info.
Doing:
s3.upload(params, (error, data) => {
if (error) {
console.error("error occurred storing to s3: ", error);
return;
}
const response = {
...
};
return response;
});
does not result in a server error.
I am trying to follow the information from AWS that can be found here:
https://aws.amazon.com/blogs/developer/support-for-promises-in-the-sdk/
Postman is able to upload to Lambda by doing the following with async/await and try/catch:
exports.handler = async function(event, context) {
const s3 = new AWS.S3();
const encodedImage = util.inspect(event.body);
const decodedImage = Buffer.from(encodedImage, "base64");
const filePath = "test.png";
const params = {
Body: decodedImage,
Bucket: "my bucket",
Key: filePath,
ACL: "public-read",
ContentType: "mime/png"
};
try {
const result = await s3.upload(params).promise();
const response = {
statusCode: 200,
headers: {
my_header: "my_value"
},
body: JSON.stringify(result),
isBase64Encoded: false
};
return response;
} catch (error) {
console.log('error')
}
};