fix IGDB resolution: drop broken category filter, match by URL prefix
the IGDB external_games category filter returns empty for all values. filter steam/gog entries by URL prefix instead (store.steampowered.com, gog.com). reduce batch size to 50 to stay within 500-result API limit since each uid can return multiple platform entries. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,12 +2,9 @@ import { env } from "../../shared/lib/env.ts"
|
||||
import { getCacheEntry, getCacheSize, saveCache, setCacheEntry } from "./cache.ts"
|
||||
import { type IgdbMetadata, getMetadata, setMetadataBatch } from "./metadata-cache.ts"
|
||||
|
||||
const CATEGORY_STEAM = 1
|
||||
const CATEGORY_GOG = 2
|
||||
|
||||
const SOURCE_TO_CATEGORY: Record<string, number> = {
|
||||
steam: CATEGORY_STEAM,
|
||||
gog: CATEGORY_GOG,
|
||||
const SOURCE_URL_PREFIX: Record<string, string> = {
|
||||
steam: "https://store.steampowered.com/app/",
|
||||
gog: "https://www.gog.com/",
|
||||
}
|
||||
|
||||
let twitchToken: string | null = null
|
||||
@@ -65,22 +62,28 @@ async function igdbRequest(endpoint: string, query: string): Promise<unknown[]>
|
||||
|
||||
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
|
||||
|
||||
async function batchResolve(category: number, sourceIds: string[]): Promise<Map<string, number>> {
|
||||
async function batchResolve(source: string, sourceIds: string[]): Promise<Map<string, number>> {
|
||||
const results = new Map<string, number>()
|
||||
const BATCH_SIZE = 500
|
||||
const urlPrefix = SOURCE_URL_PREFIX[source]
|
||||
if (!urlPrefix) return results
|
||||
|
||||
// Without category filter, each uid may return multiple platform entries,
|
||||
// so keep batches small to stay within the 500-result API limit
|
||||
const BATCH_SIZE = 50
|
||||
|
||||
for (let i = 0; i < sourceIds.length; i += BATCH_SIZE) {
|
||||
const batch = sourceIds.slice(i, i + BATCH_SIZE)
|
||||
const uids = batch.map((id) => `"${id}"`).join(",")
|
||||
const query = `fields game,uid; where category = ${category} & uid = (${uids}); limit ${BATCH_SIZE};`
|
||||
const query = `fields game,uid,url; where uid = (${uids}); limit 500;`
|
||||
|
||||
const data = (await igdbRequest("/external_games", query)) as Array<{
|
||||
game?: number
|
||||
uid?: string
|
||||
url?: string
|
||||
}>
|
||||
|
||||
for (const entry of data) {
|
||||
if (entry.game && entry.uid) {
|
||||
if (entry.game && entry.uid && entry.url?.startsWith(urlPrefix)) {
|
||||
results.set(entry.uid, entry.game)
|
||||
}
|
||||
}
|
||||
@@ -109,7 +112,7 @@ export async function enrichGamesWithIgdb<T extends GameForEnrichment>(
|
||||
const uncachedBySource: Record<string, string[]> = {}
|
||||
for (const game of games) {
|
||||
const cacheKey = `${game.source}:${game.sourceId}`
|
||||
if (!getCacheEntry(cacheKey) && SOURCE_TO_CATEGORY[game.source]) {
|
||||
if (!getCacheEntry(cacheKey) && SOURCE_URL_PREFIX[game.source]) {
|
||||
if (!uncachedBySource[game.source]) {
|
||||
uncachedBySource[game.source] = []
|
||||
}
|
||||
@@ -120,10 +123,9 @@ export async function enrichGamesWithIgdb<T extends GameForEnrichment>(
|
||||
let newEntries = 0
|
||||
try {
|
||||
for (const [source, sourceIds] of Object.entries(uncachedBySource)) {
|
||||
const category = SOURCE_TO_CATEGORY[source]
|
||||
console.log(`[IGDB] Resolving ${sourceIds.length} ${source} games...`)
|
||||
|
||||
const resolved = await batchResolve(category, sourceIds)
|
||||
const resolved = await batchResolve(source, sourceIds)
|
||||
|
||||
for (const [uid, igdbId] of resolved) {
|
||||
setCacheEntry(`${source}:${uid}`, { igdbId })
|
||||
|
||||
Reference in New Issue
Block a user