feat: add image validation and SteamGridDB fallback to game stub creation

This commit is contained in:
2026-04-29 11:36:38 +08:00
parent caae92ca4f
commit a4cf2636e7
2 changed files with 16 additions and 3 deletions
+14 -1
View File
@@ -2,6 +2,7 @@ import { Elysia, t } from "elysia"
import { db } from "@/lib/db/index" import { db } from "@/lib/db/index"
import { games } from "@/lib/db/schema" import { games } from "@/lib/db/schema"
import { eq } from "drizzle-orm" import { eq } from "drizzle-orm"
import { validateImageUrl, fetchSteamGridDBCover } from "@/lib/steam/sync"
interface SteamAppDetails { interface SteamAppDetails {
type?: string type?: string
@@ -77,6 +78,18 @@ export const gameStubRoutes = new Elysia({ prefix: "/games" }).post(
const capsuleImage = const capsuleImage =
`https://cdn.akamai.steamstatic.com/steam/apps/${body.steamAppId}/library_600x900.jpg` `https://cdn.akamai.steamstatic.com/steam/apps/${body.steamAppId}/library_600x900.jpg`
let finalCapsuleImage: string | null = capsuleImage
const imageValid = await validateImageUrl(capsuleImage)
if (!imageValid) {
const fallbackImage = await fetchSteamGridDBCover(title)
if (fallbackImage) {
finalCapsuleImage = fallbackImage
} else {
finalCapsuleImage = null
}
}
const [game] = await db const [game] = await db
.insert(games) .insert(games)
.values({ .values({
@@ -87,7 +100,7 @@ export const gameStubRoutes = new Elysia({ prefix: "/games" }).post(
publisher, publisher,
genres, genres,
headerImage, headerImage,
capsuleImage, capsuleImage: finalCapsuleImage,
storeUrl: `https://store.steampowered.com/app/${body.steamAppId}`, storeUrl: `https://store.steampowered.com/app/${body.steamAppId}`,
systemRequirements: details?.pc_requirements systemRequirements: details?.pc_requirements
? { minimum: details.pc_requirements.minimum || null, recommended: details.pc_requirements.recommended || null } ? { minimum: details.pc_requirements.minimum || null, recommended: details.pc_requirements.recommended || null }
+2 -2
View File
@@ -30,7 +30,7 @@ export function isSyncStale(lastSync: Date | null): boolean {
return Date.now() - new Date(lastSync).getTime() > SEVEN_DAYS_MS return Date.now() - new Date(lastSync).getTime() > SEVEN_DAYS_MS
} }
async function validateImageUrl(url: string): Promise<boolean> { export async function validateImageUrl(url: string): Promise<boolean> {
try { try {
const res = await fetch(url, { method: "HEAD", signal: AbortSignal.timeout(5000) }); const res = await fetch(url, { method: "HEAD", signal: AbortSignal.timeout(5000) });
return res.ok; return res.ok;
@@ -39,7 +39,7 @@ async function validateImageUrl(url: string): Promise<boolean> {
} }
} }
async function fetchSteamGridDBCover(gameTitle: string): Promise<string | null> { export async function fetchSteamGridDBCover(gameTitle: string): Promise<string | null> {
try { try {
const apiKey = process.env.STEAMGRIDDB_API_KEY; const apiKey = process.env.STEAMGRIDDB_API_KEY;
if (!apiKey) return null; if (!apiKey) return null;