-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
125 lines (109 loc) Β· 4.34 KB
/
index.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
116
117
118
119
120
121
122
123
124
125
const AWS = require('aws-sdk');
var docClient = new AWS.DynamoDB.DocumentClient();
const tools = require("./tools.js") // π tools
const s3 = new AWS.S3(); // π initialize our instance
require('dotenv').config() // Config enviroment variables.
const { puppeteer, args, defaultViewport, executablePath } = require("chrome-aws-lambda");
const path = require('path')
const ejs = require('ejs')
const fs = require('fs')
const utils = require('util')
const readFile = utils.promisify(fs.readFile)
module.exports.handler = async event => {
let result = null;
let browser = null;
let eventParams = event.params
// Check necessery fields before using them.
try {
tools.checkParameters(eventParams)
} catch (error) {
return tools.createResponse(true, error);
}
const filename = `invoicepdf-${eventParams.invoiceDate}-${eventParams.invoiceId}.pdf` // π make it unique or else the file will be replaced
const pdfPath = `/tmp/${filename}` // NOTE: !! ππ
// whenever we run our function it will generate this temporary directory
// and once the execution of the function is done,
// it will discard it. This provides the perfect environment needed to
// create a pdf file and store it in S3(more permanent storage).
let data = {
address: {
restaurantName: eventParams.restaurantName,
specification: eventParams.specification,
postcode: eventParams.postCode
},
invoice: { // Generate this fields here!
date: eventParams.invoiceDate,
no: eventParams.invoiceNo
},
wasteOil: {
code: eventParams.wasteOilCode,
liters: eventParams.wasteOilLiters,
payment: eventParams.wasteOilPayment
},
products: eventParams.products,
totalPrice: productsTotalPrice(eventParams.products)
};
try {
// console.log("Establishing connection...");
// Initialize and launched puppeteer
browser = await puppeteer.launch({
args,
defaultViewport,
executablePath: await executablePath,
headless: true, // π Very important, to run headless chrome
ignoreHTTPSErrors: true,
});
// console.log("Opening new page...");
// π create a new headless chrome pag
const page = await browser.newPage();
// Now we have the html code of our template in res object
// you can check by logging it on console
// console.log(res)
// console.log("Generating PDF file from HTML template...");
// π Loading template file
let res = await getTemplateHtml()
// console.log("Compiling the template with ejs")
const template = ejs.compile(res);
// we have compile our code with ejs
const r = template(data);
// We can use this to add dyamic data to our ejs template at run time from database or API as per need.
const html = r;
await page.setContent(html, { waitUntil: "networkidle2" });
// π this tells puppeteer to save the webpage as a pdf file
await page.pdf({ format: "A4", path: pdfPath });
const params = {
Key: `invoices/invoicepdf-${eventParams.invoiceDate}-${eventParams.invoiceId}`,
Body: fs.createReadStream(pdfPath),
Bucket: process.env.S3_BUCKET,
ContentType: "application/pdf",
};
// console.log("Uploading PDF...");
// π Pretty self explanatory but this is what uploads
// and store our PDF or file to S3
let wait = await s3.putObject(params).promise();
} catch (error) {
return tools.createResponse(true, error.message);
} finally {
if (browser !== null) {
// console.log("Closing browser...");
browser.close();
}
}
return tools.createResponse(false, "DONE!!");
}
async function getTemplateHtml() {
// console.log("Loading template file in memory")
try {
const invoicePath = path.resolve("./assets/invoice.ejs");
return await readFile(invoicePath, 'utf8');
} catch (err) {
return tools.createResponse(true, err);
}
}
function productsTotalPrice(products) {
let total
products.forEach(price => {
total += price
});
return Number(total)
}