11import { NextApiRequest , NextApiResponse } from 'next'
22
3+ import got from 'got'
34import { PageBlock } from 'notion-types'
45import {
56 getBlockIcon ,
@@ -48,24 +49,6 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
4849 const isBlogPost =
4950 block . type === 'page' && block . parent_table === 'collection'
5051 const title = getBlockTitle ( block , recordMap ) || libConfig . name
51- let image = mapImageUrl (
52- getPageProperty < string > ( 'Social Image' , block , recordMap ) ||
53- ( block as PageBlock ) . format ?. page_cover ||
54- libConfig . defaultPageCover ,
55- block
56- )
57-
58- if ( image ) {
59- const imageUrl = new URL ( image )
60-
61- if ( imageUrl . host === 'images.unsplash.com' ) {
62- if ( ! imageUrl . searchParams . has ( 'w' ) ) {
63- imageUrl . searchParams . set ( 'w' , '1200' )
64- imageUrl . searchParams . set ( 'fit' , 'max' )
65- image = imageUrl . toString ( )
66- }
67- }
68- }
6952
7053 const imageCoverPosition =
7154 ( block as PageBlock ) . format ?. page_cover_position ??
@@ -74,11 +57,23 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
7457 ? `center ${ ( 1 - imageCoverPosition ) * 100 } %`
7558 : null
7659
60+ const imageBlockUrl = mapImageUrl (
61+ getPageProperty < string > ( 'Social Image' , block , recordMap ) ||
62+ ( block as PageBlock ) . format ?. page_cover ,
63+ block
64+ )
65+ const imageFallbackUrl = mapImageUrl ( libConfig . defaultPageCover , block )
66+
7767 const blockIcon = getBlockIcon ( block , recordMap )
78- const authorImage = mapImageUrl (
79- blockIcon && isUrl ( blockIcon ) ? blockIcon : libConfig . defaultPageIcon ,
68+ const authorImageBlockUrl = mapImageUrl (
69+ blockIcon && isUrl ( blockIcon ) ? blockIcon : null ,
8070 block
8171 )
72+ const authorImageFallbackUrl = mapImageUrl ( libConfig . defaultPageIcon , block )
73+ const [ authorImage , image ] = await Promise . all ( [
74+ getCompatibleImageUrl ( authorImageBlockUrl , authorImageFallbackUrl ) ,
75+ getCompatibleImageUrl ( imageBlockUrl , imageFallbackUrl )
76+ ] )
8277
8378 const author =
8479 getPageProperty < string > ( 'Author' , block , recordMap ) || libConfig . author
@@ -119,7 +114,41 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
119114
120115 res . setHeader (
121116 'Cache-Control' ,
122- 'public, s-maxage=30 , max-age=30 , stale-while-revalidate=30 '
117+ 'public, s-maxage=3600 , max-age=3600 , stale-while-revalidate=3600 '
123118 )
124119 res . status ( 200 ) . json ( pageInfo )
125120}
121+
122+ async function isUrlReachable ( url : string | null ) : Promise < boolean > {
123+ if ( ! url ) {
124+ return false
125+ }
126+
127+ try {
128+ await got . head ( url )
129+ return true
130+ } catch ( err ) {
131+ return false
132+ }
133+ }
134+
135+ async function getCompatibleImageUrl (
136+ url : string | null ,
137+ fallbackUrl : string | null
138+ ) : Promise < string | null > {
139+ const image = ( await isUrlReachable ( url ) ) ? url : fallbackUrl
140+
141+ if ( image ) {
142+ const imageUrl = new URL ( image )
143+
144+ if ( imageUrl . host === 'images.unsplash.com' ) {
145+ if ( ! imageUrl . searchParams . has ( 'w' ) ) {
146+ imageUrl . searchParams . set ( 'w' , '1200' )
147+ imageUrl . searchParams . set ( 'fit' , 'max' )
148+ return imageUrl . toString ( )
149+ }
150+ }
151+ }
152+
153+ return image
154+ }
0 commit comments