screenshot/screenshot.js (68 lines of code) (raw):
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
const puppeteer = require("puppeteer");
const { Storage } = require("@google-cloud/storage");
async function initBrowser() {
console.log("Initializing browser");
return await puppeteer.launch();
}
async function takeScreenshot(browser, url) {
const page = await browser.newPage();
console.log(`Navigating to ${url}`);
await page.goto(url);
console.log(`Taking a screenshot of ${url}`);
return await page.screenshot({
fullPage: true,
});
}
async function createStorageBucketIfMissing(storage, bucketName) {
console.log(
`Checking for Cloud Storage bucket '${bucketName}' and creating if not found`
);
const bucket = storage.bucket(bucketName);
const [exists] = await bucket.exists();
if (exists) {
// Bucket exists, nothing to do here
return bucket;
}
// Create bucket
const [createdBucket] = await storage.createBucket(bucketName);
console.log(`Created Cloud Storage bucket '${createdBucket.name}'`);
return createdBucket;
}
async function uploadImage(bucket, taskIndex, imageBuffer) {
// Create filename using the current time and task index
const date = new Date();
date.setMinutes(date.getMinutes() - date.getTimezoneOffset());
const filename = `${date.toISOString()}-task${taskIndex}.png`;
console.log(`Uploading screenshot as '${filename}'`);
await bucket.file(filename).save(imageBuffer);
}
async function main(urls) {
console.log(`Passed in urls: ${urls}`);
const taskIndex = process.env.CLOUD_RUN_TASK_INDEX || 0;
const url = urls[taskIndex];
if (!url) {
throw new Error(
`No url found for task ${taskIndex}. Ensure at least ${
parseInt(taskIndex, 10) + 1
} url(s) have been specified as command args.`
);
}
const bucketName = process.env.BUCKET_NAME;
if (!bucketName) {
throw new Error(
"No bucket name specified. Set the BUCKET_NAME env var to specify which Cloud Storage bucket the screenshot will be uploaded to."
);
}
const browser = await initBrowser();
const imageBuffer = await takeScreenshot(browser, url).catch(async (err) => {
// Make sure to close the browser if we hit an error.
await browser.close();
throw err;
});
await browser.close();
console.log("Initializing Cloud Storage client");
const storage = new Storage();
const bucket = await createStorageBucketIfMissing(storage, bucketName);
await uploadImage(bucket, taskIndex, imageBuffer);
console.log("Upload complete!");
}
main(process.argv.slice(2)).catch((err) => {
console.error(JSON.stringify({ severity: "ERROR", message: err.message }));
process.exit(1);
});