Problems integrating DynamoBD with API Gateway - javascript

I'm trying to use dynamoDb with API Gateway, but it is not working. This is what I'm trying to do
export async function handler(event: APIGatewayProxyEvent, context: Context): Promise<APIGatewayProxyResult> {
switch (event.httpMethod) {
case "GET":
var params = {
TableName: 'Users',
Key: {
UserID: event.queryStringParameters.UserID
}
};
dynamodb.get(params, function (err, data) {
if (err){
return{
statusCode: 200,
body: JSON.stringify({
message: "Item not found"
})
}
} else {
return {
statusCode: 200,
body: JSON.stringify({
message: data.Item,
})
};
}
})
break;
}
Every time I try to call my gateway I get a
{
"message": "Internal server error"
}
Is it a problem with my integration ?
Another doubt, how can I add other routes to my Gateway ? I'm using CloudFloration Template and it's this:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
UserAPI:
Type: AWS::Serverless::Function
Properties:
Handler: build/userAPI.handler
Runtime: nodejs14.x
Events:
Api:
Type: Api
Properties:
Path: /users
Method: ANY
How can I add a route like /user (GET) or /users (POST) ?
As requested I get the logs so the lambda is no been invoked the error I get is:
2021-06-23T12:08:37.557Z eb945ca9-a4b6-4f8e-add1-774276db2cb7 ERROR Invoke Error {
"errorType": "TypeError",
"errorMessage": "Cannot read property 'UserID' of null",
"stack": [
"TypeError: Cannot read property 'UserID' of null",
" at Runtime.handler (/var/task/build/userAPI.js:12:57)",
" at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"
]
}

Related

Unable to deploy the Node.js AWS Lambda function to Docker

I am developing a REST API with Node.Js. my technology stack is AWS Lambda, API Gateway and RDS (MySQL). Below is my code
roles.js
const mysql = require('mysql');
const con = mysql.createConnection({
host : "*****.rds.amazonaws.com",
user : "*****",
password : "*****",
port : 3306,
database : "******"
});
exports.lambdaHandler = (event, context, callback) => {
// allows for using callbacks as finish/error-handlers
context.callbackWaitsForEmptyEventLoop = false;
const sql = "select * from role";
con.query(sql, function (err, result) {
if (err) throw err;
var response = {
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": JSON.stringify(result),
"isBase64Encoded": false
};
callback(null, response)
});
};
exports.selectRoleByIDHandler = (event, context, callback) => {
const { id } = event.queryStringParameters;
console.log("id", id);
// allows for using callbacks as finish/error-handlers
context.callbackWaitsForEmptyEventLoop = false;
const sql = "select * from role where idRole = "+id;
con.query(sql, function (err, result) {
if (err) throw err;
var response = {
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": JSON.stringify(result),
"isBase64Encoded": false
};
callback(null, response)
});
};
Below is my template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
node2
Sample SAM Template for node2
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 100
VpcConfig:
SecurityGroupIds:
- sg-sdsdsdsd
SubnetIds:
- subnet-ssdsds
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello-world/
Handler: app.lambdaHandler
Runtime: nodejs14.x
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /hello
Method: get
Role: !GetAtt LambdaRole.Arn
RoleFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello-world/
Handler: roles.lambdaHandler
Runtime: nodejs14.x
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /roles
Method: get
Role: !GetAtt LambdaRole.Arn
SelectRolesByIDFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello-world/
Handler: roles.selectRoleByIDHandler
Runtime: nodejs14.x
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /selectRoleByIDHandler
Method: get
Role: !GetAtt LambdaRole.Arn
LambdaRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: root
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- ec2:DescribeNetworkInterfaces
- ec2:CreateNetworkInterface
- ec2:DeleteNetworkInterface
- ec2:DescribeInstances
- ec2:AttachNetworkInterface
Resource: '*'
When I try to execute the sam local invoke, i get the following error
Error: You must provide a function logical ID when there are more than one functions in your template. Possible options in your template: ['HelloWorldFunction', 'RoleFunction', 'SelectRolesByIDFunction']
Now, I have 2 questions.
How to solve this issue?
Is it a bad practice to have more than one function in a single file in AWS Lambda?
Looks like you are trying to build Lambda functions via the AWS SDK for Javascipt. Have you looked at the AWS examples in the AWS SDK for JavaScript V3 DEV Guide. There are end to end instructions on how to build Lambda function using the JS API that can help you.
See this topic and the child topics in the TOC:
Cross-service examples for the AWS SDK for JavaScript
I found the issue, I had to invoke this as sam local invoke HelloWorldFunction . The HelloWorldFunction is the function name I need to deploy.

Node.js - Google Calendar API showing error "Missing end time" when inserting an event

I am using Google Calendar library for Node.js to get calendar ID and events list from API. This is working as expected. But when I'm trying to insert or modify an event, I'm facing the common(!) error message "Missing end time".
I am trying to send a POST request using Request - Simplified HTTP client and not using Google Library or other package.
Here's my code snippet:
const request = require('request');
// Update Event Title
function insertEventIntoCalendar(calendarId,accessToken){
let endDateTime = {
dateTime: '2018-07-03T10:25:00.000-07:00',//end,
timeZone: 'Asia/Dhaka'
},
startDateTime = {
dateTime: '2018-07-03T10:00:00.000-07:00', //start,
timeZone: 'Asia/Dhaka'
},
url = "https://www.googleapis.com/calendar/v3/calendars/primary/events?access_token="+accessToken,
options = {
data: {
end: endDateTime,
start: startDateTime,
summery: 'ARG will win',
location: '800 Howard St., San Francisco, CA 94103',
attendees: [],
reminders: {
useDefault: true,
}
},
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + accessToken,
'Accept': 'application/json'
},
calendarId: 'primary'
}
request.post(url, options, function (err, res, body) {
console.log('err =>', err);
console.log('body =>', body);
})
}
And here is my console.log message:
err => null
body => {
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Missing end time."
}
],
"code": 400,
"message": "Missing end time."
}
}
Note: I've followed all questions and answers related to Google Calendar API and Node.js and still facing the same error. And I've not found any answers where Google Library is not used.
Please share your thoughts if you tried this way, otherwise you can suggest me a better way where I don't need any Config file to get or modify Google Calendar info.
The problem is in declaring the options variable. The documentation of Request - Simplified HTTP client is saying the json data of Request body should be named as 'json'. So the options variable should be,
options = {
url: url
json: {
end: endDateTime,
start: startDateTime,
summery: 'ARG will win',
location: '800 Howard St., San Francisco, CA 94103',
attendees: [],
reminders: {
useDefault: true,
}
}
}
and to send the POST request, the code should be:
request.post(options,function (err, res, body) {
console.log('err =>', err);
// console.log("res =>", res);
console.log("body =>", body);
})
I tried this way and it works :)
bonnopc answer solved it for me. For the people getting here searching for node js + Google Calendar API error, this also works there:
auth.getClient().then(a => {
calendar.events.patch({
json: {
summary: "bablabbla",
start: JSON.stringify(new Date()),
end: JSON.stringify(new Date())
},
auth: a,
calendarId: GOOGLE_CALENDAR_ID,
eventId: changedEvent.id
})
})

Loopback and Stripe Webhooks

I currently have a loopback project setup, and I am trying to receive webhooks from stripe.
My current Remote method looks like the following:-
Stripeconnect.stripeWebhook = function(msg, cb) {
cb(null, msg);
};
Stripeconnect.remoteMethod(
'stripeWebhook', {
description: 'This will insert the description',
http: {
path: '/stripeWebhook',
verb: 'get'
},
accepts:
{arg: 'msg', type: 'any'},
returns: {
arg: 'status',
type: 'any'
}
}
)
But in the response I receive from Stripe is:-
undefined [Function: callback]
I am unable to find any documentation online regarding Loopback and Stripe webhooks.
Would anybody be able to help, or point me in the right direction?
I have setup Stripe to point at this endpoint of the API.
Thanks in advance. If you need anymore info please let me know.
Ok so I was able to get this working by getting the response from the body:-
/**
* Receiving Webhook
* #desc Webhook EP
* #param {data} Object from Stripe.
* #return {response} response code
*/
Stripeconnect.stripeWebhook = function(request, cb) {
console.log(request.type, request.data);
};
Stripeconnect.remoteMethod(
'stripeWebhook', {
accepts: { arg: 'data', type: 'object', http: { source: 'body' } },
returns: [
{arg: 'response', type: 'any', root: true }
]
});
Which you can see from:-
accepts: { arg: 'data', type: 'object', http: { source: 'body' } },
Hopefully this helps anybody else who is having this or a similar issue.

Using Web API JSON Response from AngularJS - Error: expected and array but got an object

I have a Web API which is returning a response in JSON, in this format:
{
"email": "john#google.com",
"password": null,
"accessLevel": 2
}
I am trying to access the accessLevel field within that response, but I am getting this Angular error:
Error in resource configuration for action `query`. Expected response to contain an array but got an object (Request: GET http://localhost:51608/api/UserRole?email=john#google.com...)
This is my Angular resource code (below), I just added the isArray false to attempt to solve the issue:
function userRoleResource($resource, appSettings) {
return $resource(appSettings.serverPath + "/api/UserRole?email=:email", { email: '#email' },
{
get: {
method: 'GET',
isArray: false
}
});
}
And this is how I am attempting to use the data:
userRoleResource.query({ email: vm.userData.email },
function (data) {
vm.userData.accessLevel = data.AccessLevel;
});
you're specifying that the 'get' function is not an array, but you're using the 'query' function.
try this:
userRoleResource.get({ email: vm.userData.email },
function (data) {
vm.userData.accessLevel = data.AccessLevel;
});

Internal Server Error when using Meteor.loginWithFacebook

Using the service-configuration and accounts-facebook packages, after clicking on the facebook button and logging in from the Facebook authorization window that pops up, we're getting an Internal server error when performing a Meteor.loginWithFacebook.
This was tested on a very basic example, what is causing this error?
Template.login.events({
'click .btn-facebook': function (ev) {
Meteor.loginWithFacebook({}, function(error) {
if(error) {
throw new Meteor.Error('Facebook login failed: ', error);
}
})
}
});
/server/lib/config/social.js
Meteor.startup(function() {
ServiceConfiguration.configurations.update(
{ service: "facebook" },
{ $set: {
appId: "xxx",
secret: "xxx"
}
},
{ upsert: true }
);
})
Error (server side)
Exception while invoking method 'login' undefined
Error (client side)
Error: Internal server error [500]
at _.extend._livedata_result (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:4964:23)
at onMessage (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:3725:12)
at http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:2717:11
at Array.forEach (native)
at Function._.each._.forEach (http://localhost:3000/packages/underscore.js?0a80a8623e1b40b5df5a05582f288ddd586eaa18:156:11)
at _.extend._launchConnection.self.socket.onmessage (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:2716:11)
at REventTarget.dispatchEvent (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:156:22)
at SockJS._dispatchMessage (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:1141:10)
at SockJS._didMessage (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:1199:18)
at WebSocket.SockJS.websocket.that.ws.onmessage (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:1346:17)
I had the same issue, and solved it like this :
After checking that you have configured your schema as described here :
Schema.User = new SimpleSchema({
_id: {
type: String
}
...
});
You should add the second part into an Accounts.onCreateUser like this, into server/accounts.js for example :
Accounts.onCreateUser(function (options, user) {
if (user.services.facebook) {
user.emails = [{
address: user.services.facebook.email,
verified: true
}];
}
return user;
});
It will append the facebook email to the newly created account. The error should disapear.

Categories