fix: add presence test for OG image assets

This commit is contained in:
Travis Fischer
2022-10-24 23:11:05 -04:00
parent 7092e4d3d2
commit fff575728f
2 changed files with 58 additions and 29 deletions

View File

@@ -1,5 +1,6 @@
import { NextApiRequest, NextApiResponse } from 'next'
import got from 'got'
import { PageBlock } from 'notion-types'
import {
getBlockIcon,
@@ -48,24 +49,6 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
const isBlogPost =
block.type === 'page' && block.parent_table === 'collection'
const title = getBlockTitle(block, recordMap) || libConfig.name
let image = mapImageUrl(
getPageProperty<string>('Social Image', block, recordMap) ||
(block as PageBlock).format?.page_cover ||
libConfig.defaultPageCover,
block
)
if (image) {
const imageUrl = new URL(image)
if (imageUrl.host === 'images.unsplash.com') {
if (!imageUrl.searchParams.has('w')) {
imageUrl.searchParams.set('w', '1200')
imageUrl.searchParams.set('fit', 'max')
image = imageUrl.toString()
}
}
}
const imageCoverPosition =
(block as PageBlock).format?.page_cover_position ??
@@ -74,11 +57,23 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
? `center ${(1 - imageCoverPosition) * 100}%`
: null
const blockIcon = getBlockIcon(block, recordMap)
const authorImage = mapImageUrl(
blockIcon && isUrl(blockIcon) ? blockIcon : libConfig.defaultPageIcon,
const imageBlockUrl = mapImageUrl(
getPageProperty<string>('Social Image', block, recordMap) ||
(block as PageBlock).format?.page_cover,
block
)
const imageFallbackUrl = mapImageUrl(libConfig.defaultPageCover, block)
const blockIcon = getBlockIcon(block, recordMap)
const authorImageBlockUrl = mapImageUrl(
blockIcon && isUrl(blockIcon) ? blockIcon : null,
block
)
const authorImageFallbackUrl = mapImageUrl(libConfig.defaultPageIcon, block)
const [authorImage, image] = await Promise.all([
getCompatibleImageUrl(authorImageBlockUrl, authorImageFallbackUrl),
getCompatibleImageUrl(imageBlockUrl, imageFallbackUrl)
])
const author =
getPageProperty<string>('Author', block, recordMap) || libConfig.author
@@ -119,7 +114,41 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
res.setHeader(
'Cache-Control',
'public, s-maxage=30, max-age=30, stale-while-revalidate=30'
'public, s-maxage=3600, max-age=3600, stale-while-revalidate=3600'
)
res.status(200).json(pageInfo)
}
async function isUrlReachable(url: string | null): Promise<boolean> {
if (!url) {
return false
}
try {
await got.head(url)
return true
} catch (err) {
return false
}
}
async function getCompatibleImageUrl(
url: string | null,
fallbackUrl: string | null
): Promise<string | null> {
const image = (await isUrlReachable(url)) ? url : fallbackUrl
if (image) {
const imageUrl = new URL(image)
if (imageUrl.host === 'images.unsplash.com') {
if (!imageUrl.searchParams.has('w')) {
imageUrl.searchParams.set('w', '1200')
imageUrl.searchParams.set('fit', 'max')
return imageUrl.toString()
}
}
}
return image
}

View File

@@ -3,7 +3,7 @@ import { NextRequest } from 'next/server'
import { ImageResponse } from '@vercel/og'
import { api, apiHost } from '@/lib/config'
import { api, apiHost, rootNotionPageId } from '@/lib/config'
import { NotionPageInfo } from '@/lib/types'
const interRegularFontP = fetch(
@@ -19,13 +19,8 @@ export const config = {
}
export default async function OGImage(req: NextRequest) {
const [interRegularFont, interBoldFont] = await Promise.all([
interRegularFontP,
interBoldFontP
])
const { searchParams } = new URL(req.url)
const pageId = searchParams.get('id')
const pageId = searchParams.get('id') || rootNotionPageId
if (!pageId) {
return new Response('Invalid notion page id', { status: 400 })
}
@@ -43,6 +38,11 @@ export default async function OGImage(req: NextRequest) {
const pageInfo: NotionPageInfo = await pageInfoRes.json()
console.log(pageInfo)
const [interRegularFont, interBoldFont] = await Promise.all([
interRegularFontP,
interBoldFontP
])
return new ImageResponse(
(
<div