mirror of
https://github.com/dillonkearns/elm-pages-v3-beta.git
synced 2024-12-23 20:03:31 +03:00
95 lines
3.2 KiB
JavaScript
95 lines
3.2 KiB
JavaScript
// thanks to Wes Bos for the initial code template https://github.com/wesbos/wesbos/blob/38e7bf5126758d17c10890832fe58542f6d19861/functions/ogimage/ogimage.js
|
|
// https://wesbos.com/new-wesbos-website
|
|
const chrome = require("chrome-aws-lambda");
|
|
const puppeteer = require("puppeteer-core");
|
|
const Airtable = require("airtable");
|
|
const base = new Airtable({ apiKey: process.env.AIRTABLE_TOKEN }).base(
|
|
"appDykQzbkQJAidjt"
|
|
);
|
|
|
|
// const wait = require('waait');
|
|
|
|
const cached = new Map();
|
|
|
|
const exePath = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
|
|
|
|
async function getOptions(isDev) {
|
|
if (isDev) {
|
|
return {
|
|
product: "chrome",
|
|
args: [],
|
|
executablePath: exePath,
|
|
headless: true,
|
|
};
|
|
}
|
|
return {
|
|
product: "chrome",
|
|
args: chrome.args,
|
|
executablePath: await chrome.executablePath,
|
|
headless: chrome.headless,
|
|
defaultViewport: chrome.defaultViewport,
|
|
};
|
|
}
|
|
|
|
async function getScreenshot(url, isDev) {
|
|
console.log({ isDev, url: process.env.URL });
|
|
// first check if this value has been cached
|
|
const cachedImage = cached.get(url);
|
|
if (cachedImage) {
|
|
console.log("Found cached image!");
|
|
return cachedImage;
|
|
}
|
|
const options = await getOptions(isDev);
|
|
const browser = await puppeteer.launch(options);
|
|
const page = await browser.newPage();
|
|
// await page.setViewport({ width: 1600, height: 1600, deviceScaleFactor: 1 });
|
|
await page.setViewport({ width: 1440, height: 1024 });
|
|
|
|
// await page.goto(url, { waitUntil: "networkidle0" });
|
|
await page.goto(url);
|
|
await wait(1000);
|
|
|
|
const buffer = await page.screenshot({ type: "png" });
|
|
const base64Image = buffer.toString("base64");
|
|
cached.set(url, base64Image);
|
|
return base64Image;
|
|
}
|
|
|
|
// Docs on event and context https://www.netlify.com/docs/functions/#the-handler-method
|
|
exports.handler = async (event, context) => {
|
|
const recordId = decodeURIComponent(
|
|
event.path.replace(/^.*\/screenshot\//, "")
|
|
);
|
|
const record = await base("elm-pages showcase").find(recordId);
|
|
const url = record["fields"]["Screenshot URL"];
|
|
|
|
console.log({ url });
|
|
const photoBuffer = await getScreenshot(
|
|
url,
|
|
// Here we need to pass a boolean to say if we are on the server. Netlify has a bug where process.env.NETLIFY is undefined in functions so I'm using one of the only vars I can find
|
|
// !process.env.NETLIFY
|
|
process.env.URL.includes("http://localhost")
|
|
);
|
|
return {
|
|
statusCode: 200,
|
|
body: photoBuffer.toString("base64"),
|
|
// headers: {'Cache-Control': 'public, max-age=600, s-maxage=604800 stale-while-revalidate=31540000'},
|
|
// `stale-while-revalidate=31540000` - we never want to make the user wait to see a screenshot. No matter how stale the cached image is,
|
|
// we will go fetch it in the background but we'd prefer for the user to get a stale screenshot than waiting for a long time for images to load for the showcase
|
|
// see https://www.youtube.com/watch?v=bfLFHp7Sbkg
|
|
headers: {
|
|
"Cache-Control":
|
|
"public, max-age=600, s-maxage=60 stale-while-revalidate=31540000",
|
|
"Content-Length": photoBuffer.length.toString(),
|
|
"Content-Type": "image/png",
|
|
},
|
|
isBase64Encoded: true,
|
|
};
|
|
};
|
|
|
|
function wait(ms) {
|
|
return new Promise((resolve) => {
|
|
setTimeout(resolve, ms);
|
|
});
|
|
}
|