Files
BRETT/server/api/link-preview.get.ts
T
2026-10-03 20:07:49 +02:00

38 lines
1.2 KiB
TypeScript

import { createHash } from 'node:crypto'
import { eq } from 'drizzle-orm'
import { linkPreviews } from '../db/schema'
const CACHE_TTL_MS = 1000 * 60 * 60 * 24
export default defineEventHandler(async (event) => {
const url = String(getQuery(event).url ?? '')
if (!/^https?:\/\//i.test(url) || url.length > 2048) {
throw createError({ statusCode: 400, statusMessage: 'Ungültige URL' })
}
const urlHash = createHash('sha256').update(url).digest('hex')
const db = useDb()
const [cached] = await db
.select()
.from(linkPreviews)
.where(eq(linkPreviews.urlHash, urlHash))
.limit(1)
if (cached && Date.now() - cached.fetchedAt.getTime() < CACHE_TTL_MS) {
return { image: cached.image, title: cached.title }
}
const preview = await fetchLinkPreview(url)
// Vorschaubild lokal speichern — die Remote-URL ist nicht stabil
const image = preview.image
? (await savePreviewImage(`links/${urlHash}`, preview.image)) ?? preview.image
: null
await db
.insert(linkPreviews)
.values({ urlHash, url, image, title: preview.title, fetchedAt: new Date() })
.onDuplicateKeyUpdate({
set: { image, title: preview.title, fetchedAt: new Date() },
})
return { image, title: preview.title }
})