133 lines
3.0 KiB
JavaScript
133 lines
3.0 KiB
JavaScript
/**
|
|
* Cloudflare Worker: Steam API CORS Proxy
|
|
* Erlaubt iPhone App, Steam Web API aufzurufen
|
|
*/
|
|
|
|
export default {
|
|
async fetch(request, env, ctx) {
|
|
// CORS preflight
|
|
if (request.method === "OPTIONS") {
|
|
return handleCORS();
|
|
}
|
|
|
|
// Nur POST /api/steam/refresh erlauben
|
|
const url = new URL(request.url);
|
|
if (request.method === "POST" && url.pathname === "/api/steam/refresh") {
|
|
return handleSteamRefresh(request);
|
|
}
|
|
|
|
// 404 für alle anderen Routes
|
|
return new Response("Not Found", { status: 404 });
|
|
},
|
|
};
|
|
|
|
/**
|
|
* Handles Steam API refresh request
|
|
*/
|
|
async function handleSteamRefresh(request) {
|
|
try {
|
|
// Parse request body
|
|
const body = await request.json();
|
|
const { apiKey, steamId } = body;
|
|
|
|
if (!apiKey || !steamId) {
|
|
return jsonResponse(
|
|
{ error: "apiKey and steamId are required" },
|
|
{ status: 400 },
|
|
);
|
|
}
|
|
|
|
// Fetch games from Steam API
|
|
const { games, count } = await fetchSteamGames(apiKey, steamId);
|
|
|
|
return jsonResponse({ games, count });
|
|
} catch (error) {
|
|
console.error("Steam API Error:", error);
|
|
return jsonResponse(
|
|
{ error: error.message || "Internal Server Error" },
|
|
{ status: 500 },
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fetches games from Steam Web API
|
|
*/
|
|
async function fetchSteamGames(apiKey, steamId) {
|
|
// Build Steam API URL
|
|
const url = new URL(
|
|
"https://api.steampowered.com/IPlayerService/GetOwnedGames/v1/",
|
|
);
|
|
url.searchParams.set("key", apiKey);
|
|
url.searchParams.set("steamid", steamId);
|
|
url.searchParams.set("include_appinfo", "true");
|
|
url.searchParams.set("include_played_free_games", "true");
|
|
|
|
// Call Steam API
|
|
const response = await fetch(url);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(
|
|
`Steam API Error: ${response.status} ${response.statusText}`,
|
|
);
|
|
}
|
|
|
|
const data = await response.json();
|
|
const rawGames = data.response?.games ?? [];
|
|
|
|
// Format games
|
|
const games = rawGames.map((game) => ({
|
|
id: `steam-${game.appid}`,
|
|
title: game.name,
|
|
source: "steam",
|
|
sourceId: String(game.appid),
|
|
platform: "PC",
|
|
lastPlayed: game.rtime_last_played
|
|
? new Date(game.rtime_last_played * 1000).toISOString().slice(0, 10)
|
|
: null,
|
|
playtimeHours: Math.round((game.playtime_forever / 60) * 10) / 10,
|
|
url: `https://store.steampowered.com/app/${game.appid}`,
|
|
}));
|
|
|
|
return {
|
|
games,
|
|
count: games.length,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* CORS preflight response
|
|
*/
|
|
function handleCORS() {
|
|
return new Response(null, {
|
|
status: 204,
|
|
headers: getCORSHeaders(),
|
|
});
|
|
}
|
|
|
|
/**
|
|
* JSON response with CORS headers
|
|
*/
|
|
function jsonResponse(data, options = {}) {
|
|
return new Response(JSON.stringify(data), {
|
|
...options,
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
...getCORSHeaders(),
|
|
...options.headers,
|
|
},
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get CORS headers for GitHub Pages
|
|
*/
|
|
function getCORSHeaders() {
|
|
return {
|
|
"Access-Control-Allow-Origin": "*", // Allow all origins (user's own worker)
|
|
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
|
|
"Access-Control-Allow-Headers": "Content-Type",
|
|
"Access-Control-Max-Age": "86400", // 24 hours
|
|
};
|
|
}
|