-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
112 lines (88 loc) · 3.34 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// dependencies
const AWS = require('aws-sdk');
const util = require('util');
const sharp = require('sharp');
// get reference to S3 client
const s3 = new AWS.S3();
const sns = new AWS.SNS({apiVersion: '2010-03-31'});
exports.handler = async (event, context, callback) => {
try {
// Read options from the event parameter.
console.log("Reading options from event:\n", util.inspect(event, {depth: 5}));
const srcBucket = event.Records[0].s3.bucket.name;
// Object key may have spaces or unicode non-ASCII characters.
const srcKey = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " "));
const dstBucket = `${srcBucket}/thumbnails`;
const dstKey = `${srcKey.split('/').pop()}`;
const origImage = await getObject(srcBucket, srcKey);
const bufferThumbnail = await generateThumbnail(origImage);
await publishThumbnailToS3(dstBucket, dstKey, bufferThumbnail);
console.log(`Successfully resized ${srcBucket}/${srcKey} and uploaded to ${dstBucket}/${dstKey}`);
const presignedThumbnailGETURL = await generatePreSignedURL(dstBucket, dstKey);
await publishToSNSTopic(presignedThumbnailGETURL);
} catch (error) {
console.log(error);
return false;
}
};
const getObject = async (srcBucket, srcKey) => {
// Infer the image type from the file suffix.
const typeMatch = srcKey.match(/\.([^.]*)$/);
if (!typeMatch) {
console.log("Could not determine the image type.");
return;
}
// Check that the image type is supported
const imageType = typeMatch[1].toLowerCase();
if (imageType !== "jpg" && imageType !== "png") {
console.log(`Unsupported image type: ${imageType}`);
return;
}
// Download the image from the S3 source bucket.
const params = {
Bucket: srcBucket,
Key: srcKey
};
return await s3.getObject(params).promise();
}
const generateThumbnail = async (origImage) => {
// set thumbnail width. Resize will set the height automatically to maintain aspect ratio.
const width = 200;
// Use the sharp module to resize the image and save in a buffer.
return await sharp(origImage.Body).resize(width).toBuffer();
}
const publishThumbnailToS3 = async (dstBucket, dstKey, bufferThumbnail) => {
// Upload the thumbnail image to the destination bucket
const destParams = {
Bucket: dstBucket,
Key: dstKey,
Body: bufferThumbnail,
ContentType: "image"
};
const putResult = await s3.putObject(destParams).promise();
console.log(putResult);
}
const generatePreSignedURL = async (thumbnailBucket, thumbnailKey) => {
console.log('Generating Pre-Signed URL');
const presignedGETURL = await s3.getSignedUrlPromise('getObject', {
Bucket: thumbnailBucket,
Key: thumbnailKey, //filename
Expires: 86400 //time to expire in seconds
});
console.log(`Generated Pre-Signed URL: ${presignedGETURL}`);
return presignedGETURL;
}
const publishToSNSTopic = async (presignedThumbnailGETURL) => {
const snsPublishParams = {
Message: `
Hello user,
Here's the thumbnail for the image you've sent us through S3: ${presignedThumbnailGETURL}.
Reminder: This URL is valid only for 24 hours, however you can always access the file on AWS Console.
Thanks,
Vinicius Silva
`,
TopicArn: process.env.SNS_THUMBNAILS_TOPIC_ARN
};
const publishResult = await sns.publish(snsPublishParams).promise();
console.log(publishResult);
}