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); });