import puppeteer from 'puppeteer-core'; import chromium from 'chrome-aws-lambda'; import middleware from './_common/middleware.js'; const screenshotHandler = async (targetUrl) => { if (!targetUrl) { throw new Error('URL is missing from queryStringParameters'); } if (!targetUrl.startsWith('http://') && !targetUrl.startsWith('https://')) { targetUrl = 'http://' + targetUrl; } try { new URL(targetUrl); } catch (error) { throw new Error('URL provided is invalid'); } let browser = null; try { browser = await puppeteer.launch({ args: [...chromium.args, '--no-sandbox'], // Add --no-sandbox flag defaultViewport: { width: 800, height: 600 }, executablePath: process.env.CHROME_PATH || await chromium.executablePath, headless: chromium.headless, ignoreHTTPSErrors: true, ignoreDefaultArgs: ['--disable-extensions'], }); let page = await browser.newPage(); await page.emulateMediaFeatures([{ name: 'prefers-color-scheme', value: 'dark' }]); page.setDefaultNavigationTimeout(8000); await page.goto(targetUrl, { waitUntil: 'domcontentloaded' }); await page.evaluate(() => { const selector = 'body'; return new Promise((resolve, reject) => { const element = document.querySelector(selector); if (!element) { reject(new Error(`Error: No element found with selector: ${selector}`)); } resolve(); }); }); const screenshotBuffer = await page.screenshot(); const base64Screenshot = screenshotBuffer.toString('base64'); return { image: base64Screenshot }; } finally { if (browser !== null) { await browser.close(); } } }; export const handler = middleware(screenshotHandler); export default handler;