-
Notifications
You must be signed in to change notification settings - Fork 2
/
handler.js
115 lines (100 loc) · 2.55 KB
/
handler.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
113
114
115
'use strict';
const chromium = require('chrome-aws-lambda');
const path = require('path');
const { S3 } = require('aws-sdk');
const puppeteer = chromium.puppeteer;
const cache = {};
const s3 = new S3();
const returnImageFromS3 = async (key) => {
const params = {
Bucket: process.env.BUCKET_NAME,
Key: key,
};
try {
const item = await s3.getObject(params).promise();
return item.Body;
} catch (error) {
return undefined;
}
};
const saveImageToS3 = async (buffer, key) => {
const params = {
Bucket: process.env.BUCKET_NAME,
Key: key,
Body: buffer,
};
try {
await s3.upload(params).promise();
} catch (error) {
console.error('Failed to upload image to S3', { error });
}
};
module.exports.index = async (event, context) => {
let browser = null;
const template = event.queryStringParameters.template || 'index.html';
const queryString = Object.keys(event.queryStringParameters)
.map((key) => key + '=' + event.queryStringParameters[key])
.join('&');
const url = path.join('file://', __dirname, `${template}?${queryString}`);
const width = event.queryStringParameters.width
? parseInt(event.queryStringParameters.width, 10)
: 1200;
const height = event.queryStringParameters.height
? parseInt(event.queryStringParameters.height, 10)
: 630;
if (cache[queryString]) {
return {
statusCode: 200,
body: cache[queryString],
headers: {
'Content-Type': 'image/png',
},
isBase64Encoded: true,
};
}
const s3Key = `${event.queryStringParameters.title}-${template}`;
const s3Item = await returnImageFromS3(s3Key);
if (s3Item) {
return {
statusCode: 200,
body: s3Item,
headers: {
'Content-Type': 'image/png',
},
isBase64Encoded: true,
};
}
try {
browser = await puppeteer.launch({
defaultViewport: { width, height },
headless: true,
executablePath: await chromium.executablePath,
args: chromium.args,
});
const page = await browser.newPage();
await page.goto(url);
const image = await page.screenshot({
clip: { x: 0, y: 0, width, height },
encoding: 'base64',
});
cache[queryString] = image;
await saveImageToS3(image, s3Key);
return {
statusCode: 200,
body: image,
headers: {
'Content-Type': 'image/png',
},
isBase64Encoded: true,
};
} catch (error) {
console.error(error);
return {
statusCode: 500,
};
} finally {
if (browser) {
await browser.close();
}
}
};