Skip to content

Instantly share code, notes, and snippets.

@connor11528
Last active September 5, 2023 14:27
Show Gist options
  • Save connor11528/0c787fd42e6f4e17f348771ee5ae8f13 to your computer and use it in GitHub Desktop.
Save connor11528/0c787fd42e6f4e17f348771ee5ae8f13 to your computer and use it in GitHub Desktop.
Lambda function for requesting a Unicorn to come pick us up. Part of the WildRydes AWS application
const randomBytes = require('crypto').randomBytes;
const AWS = require('aws-sdk');
const ddb = new AWS.DynamoDB.DocumentClient();
const fleet = [
{
Name: 'Bucephalus',
Color: 'Golden',
Gender: 'Male',
},
{
Name: 'Shadowfax',
Color: 'White',
Gender: 'Male',
},
{
Name: 'Rocinante',
Color: 'Yellow',
Gender: 'Female',
},
];
exports.handler = (event, context, callback) => {
if (!event.requestContext.authorizer) {
errorResponse('Authorization not configured', context.awsRequestId, callback);
return;
}
const rideId = toUrlString(randomBytes(16));
console.log('Received event (', rideId, '): ', event);
// Because we're using a Cognito User Pools authorizer, all of the claims
// included in the authentication token are provided in the request context.
// This includes the username as well as other attributes.
const username = event.requestContext.authorizer.claims['cognito:username'];
// The body field of the event in a proxy integration is a raw string.
// In order to extract meaningful values, we need to first parse this string
// into an object. A more robust implementation might inspect the Content-Type
// header first and use a different parsing strategy based on that value.
const requestBody = JSON.parse(event.body);
const pickupLocation = requestBody.PickupLocation;
const unicorn = findUnicorn(pickupLocation);
recordRide(rideId, username, unicorn).then(() => {
// You can use the callback function to provide a return value from your Node.js
// Lambda functions. The first parameter is used for failed invocations. The
// second parameter specifies the result data of the invocation.
// Because this Lambda function is called by an API Gateway proxy integration
// the result object must use the following structure.
callback(null, {
statusCode: 201,
body: JSON.stringify({
RideId: rideId,
Unicorn: unicorn,
Eta: '30 seconds',
Rider: username,
}),
headers: {
'Access-Control-Allow-Origin': '*',
},
});
}).catch((err) => {
console.error(err);
// If there is an error during processing, catch it and return
// from the Lambda function successfully. Specify a 500 HTTP status
// code and provide an error message in the body. This will provide a
// more meaningful error response to the end client.
errorResponse(err.message, context.awsRequestId, callback)
});
};
// This is where you would implement logic to find the optimal unicorn for
// this ride (possibly invoking another Lambda function as a microservice.)
// For simplicity, we'll just pick a unicorn at random.
function findUnicorn(pickupLocation) {
console.log('Finding unicorn for ', pickupLocation.Latitude, ', ', pickupLocation.Longitude);
return fleet[Math.floor(Math.random() * fleet.length)];
}
function recordRide(rideId, username, unicorn) {
return ddb.put({
TableName: 'Rides',
Item: {
RideId: rideId,
User: username,
Unicorn: unicorn,
RequestTime: new Date().toISOString(),
},
}).promise();
}
function toUrlString(buffer) {
return buffer.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
function errorResponse(errorMessage, awsRequestId, callback) {
callback(null, {
statusCode: 500,
body: JSON.stringify({
Error: errorMessage,
Reference: awsRequestId,
}),
headers: {
'Access-Control-Allow-Origin': '*',
},
});
}
@adolfo-ajucum
Copy link

Thanks, I was following the tutorial, but the had moved the file.

@robertjsandor
Copy link

In the first line, you have removed the const

Bet it was a copy/paste.

Can you please fix it?

@connor11528
Copy link
Author

done

@orangekiwi-io
Copy link

orangekiwi-io commented Feb 1, 2021

UPDATE: User error. When creating the Table I left my finger on the Caps button too long and created the Partition key RideID.
Going through the tutorial again to see if things have sunk in (which they seem to be) and I noticed the error.

On lines 59 and 91 the RideId key case is incorrect. It should be RideID: rideId.
I was getting the following error when those two lines were rideId: rideId.

Response:
{
  "statusCode": 500,
  "body": "{\"Error\":\"One or more parameter values were invalid: Missing the key RideID in the item\",\"Reference\":\"1da5f798-1f40-4ec4-8aab-58b4798ba7d9\"}",
  "headers": {
    "Access-Control-Allow-Origin": "*"
  }
}

@Jyo31
Copy link

Jyo31 commented Oct 3, 2021

Thanks, I was following the tutorial, but the had moved the file.

Hello, in the tutorial, the link doesn't seem to open

@Kwasu1
Copy link

Kwasu1 commented Jul 19, 2023

Thanks for this. the link doesn't open in the tutorial.

@jfnault-seedbox
Copy link

Thank @connor11528, Is it possible to change the link in the tutorial to point here?

@JoyChudasama
Copy link

JoyChudasama commented Jul 28, 2023

Thank you for this @connor11528

I was having similar issue @orangekiwi-io However in my case I think I named partition key as RideId instead RideId. So creating the table again, solved it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment