add netlify builder to capture social images
plus also added an invalidator that should invalidate the image each month
This commit is contained in:
@@ -3,11 +3,15 @@
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@netlify/functions": "^0.7.2",
|
||||
"@redwoodjs/api": "^0.34.1",
|
||||
"@sentry/node": "^6.5.1",
|
||||
"chrome-aws-lambda": "^10.1.0",
|
||||
"cloudinary": "^1.23.0",
|
||||
"human-id": "^2.0.1",
|
||||
"nodemailer": "^6.6.2"
|
||||
"nodemailer": "^6.6.2",
|
||||
"puppeteer": "^10.1.0",
|
||||
"puppeteer-core": "^10.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/nodemailer": "^6.4.2"
|
||||
|
||||
63
app/api/src/functions/og-image-generator.ts
Normal file
63
app/api/src/functions/og-image-generator.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { builder } from '@netlify/functions'
|
||||
import type { HandlerResponse } from '@netlify/functions'
|
||||
import chromium from 'chrome-aws-lambda'
|
||||
|
||||
const captureWidth = 1200
|
||||
const captureHeight = 630
|
||||
const clipY = 0
|
||||
|
||||
async function unwrappedHandler (event, context): Promise<HandlerResponse> {
|
||||
let path = event.path
|
||||
.replace(/.+\/og-image-generator/, '')
|
||||
.replace(/\/og-image-.+\.jpg/, '')
|
||||
|
||||
const url = `${process.env.URL}/u${path}/social-card`
|
||||
|
||||
const browser = await chromium.puppeteer.launch({
|
||||
executablePath: process.env.URL?.includes('localhost')
|
||||
? null
|
||||
: await chromium.executablePath,
|
||||
args: ['--no-sandbox','--disable-web-security','--disable-gpu', '--hide-scrollbars', '--disable-setuid-sandbox'],
|
||||
// args: chromium.args,
|
||||
defaultViewport: {
|
||||
width: captureWidth,
|
||||
height: captureHeight + clipY
|
||||
},
|
||||
headless: chromium.headless
|
||||
})
|
||||
const page = await browser.newPage()
|
||||
|
||||
await page.goto(url, {"waitUntil" : "networkidle0"});
|
||||
|
||||
const screenshot = await page.screenshot({
|
||||
type: 'jpeg',
|
||||
// netlify functions can only return strings, so base64 it is
|
||||
encoding: 'base64',
|
||||
quality: 70,
|
||||
clip: {
|
||||
x: 0,
|
||||
y: clipY,
|
||||
width: captureWidth,
|
||||
height: captureHeight
|
||||
}
|
||||
})
|
||||
|
||||
await browser.close()
|
||||
|
||||
if (typeof screenshot !== 'string') {
|
||||
return {
|
||||
statusCode: 400,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
headers: {
|
||||
'Content-Type': 'image/jpg'
|
||||
},
|
||||
body: screenshot,
|
||||
isBase64Encoded: true
|
||||
}
|
||||
}
|
||||
|
||||
export const handler = builder(unwrappedHandler)
|
||||
Reference in New Issue
Block a user