Last active
February 2, 2022 18:02
-
-
Save mikaeldui/1df977bfffc18ebc4c02ac3ee164d8bc to your computer and use it in GitHub Desktop.
Riot Games API proxy on Cloudflare Workers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
addEventListener("fetch", (event) => { | |
event.respondWith( | |
handleRequest(event).catch( | |
(err) => new Response(err.stack, { status: 500 }) | |
) | |
); | |
}); | |
/** | |
* Many more examples available at: | |
* https://developers.cloudflare.com/workers/examples | |
* @param {Request} request | |
* @returns {Promise<Response>} | |
*/ | |
async function handleRequest(event) { | |
const request = event.request | |
const cacheUrl = new URL(request.url) | |
const cacheKey = new Request(cacheUrl.toString(), request) | |
let cache = caches.default | |
let response = await cache.match(cacheKey) | |
if (response) { | |
console.log(`Cache hit for: ${request.url}.`) | |
return response | |
} else { | |
console.log(`Response for request url: ${request.url} not present in cache. Fetching and caching request.`) | |
try { | |
response = await sendToRiot(request) | |
// Clone the response so that it's no longer immutable | |
response = new Response(response.body, response) | |
if (response.status == 200 && // Only cache 200 responses (not rate limits etc) | |
!request.url.endsWith('lol/spectator/v4/featured-games')) { // Don't cache featured games | |
response.headers.set("Cache-Control", "max-age=600, stale-while-revalidate=60, stale-if-error=86400, must-revalidate") | |
// NOTE: waitUntil does NOT block / wait | |
event.waitUntil(cache.put(cacheKey, response.clone())) | |
} | |
} catch (e) { | |
return new Response(JSON.stringify({ error: e.message }), { status: 500 }) | |
} | |
} | |
if (request.headers.get('CF-Connecting-IP') == DEVELOPER_IP) { | |
// Allow localhost etc. | |
response.headers.set("Access-Control-Allow-Origin", "*") | |
// Allow whatever headers are set (CORS). | |
response.headers.set("Access-Control-Allow-Headers", request.headers.get("Access-Control-Request-Headers")) | |
} else { | |
response.headers.delete("Access-Control-Allow-Origin") | |
response.headers.delete("Access-Control-Allow-Methods") | |
response.headers.delete("Access-Control-Allow-Headers") | |
response.headers.delete("Access-Control-Expose-Headers") | |
} | |
// Create an identity TransformStream (a.k.a. a pipe). | |
// The readable side will become our new response body. | |
let { readable, writable } = new TransformStream() | |
// Start pumping the body. NOTE: No await! | |
response.body.pipeTo(writable) | |
return new Response(readable, response) | |
} | |
async function sendToRiot(request) { | |
const { pathname } = new URL(request.url) | |
// Assumes the path is in the format /euw1/lol/spectator/v4/featured-games. If /api/euw1/... change both 1's to 2's below. | |
const url = new URL("https://" + pathname.split("/")[1] + ".api.riotgames.com" + pathname.substring(pathname.indexOf('/', 1))) | |
console.log("Riot API URL: " + url.toString()) | |
const newRequest = new Request(url.toString(), request) | |
newRequest.headers.set("X-Riot-Token", RIOT_TOKEN) | |
return await fetch(newRequest) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Set
RIOT_TOKEN
to your token andDEVELOPER_IP
to your IP address, as environment variables in the worker settings.Featured Games will bypass the CF cache.