Last active
July 6, 2021 12:43
-
-
Save justincavery/2c29c054b864726719839ca194979974 to your computer and use it in GitHub Desktop.
CloudFlare Reverse Proxy Worker Opensea
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)) | |
}) | |
async function handleRequest(event) { | |
let request = event.request | |
if (request.method === "OPTIONS") { | |
return new Response("OK", { | |
headers: corsHeaders | |
}) | |
} | |
if (request.method === "GET") { | |
return getNFTAsset(event) // changed from request | |
} | |
} | |
// | |
// Set the URL for the OpenSea request | |
const openSeaApiUrl = 'https://api.opensea.io/api/v1' | |
const allowedOrigins = [ // need to update this based on https://egghead.io/lessons/cloudflare-secure-an-api-with-access-control-allow-headers | |
"app.nftx.org", | |
"v1.nftx.org", | |
"v2.nftx.org", | |
] | |
// Set the generic cors headers to be included for all responses. | |
const corsHeaders = { | |
'Access-Control-Allow-Headers': '*', | |
'Access-Control-Allow-Methods': 'GET', | |
'Access-Control-Allow-Origin': '*' // we will want the origin to be from our sites/ | |
} | |
const getNFTAsset = async event => { | |
let request = event.request | |
// Get the URL that is being reqeusted and set it to requesturl | |
const requesturl = new URL(request.url) | |
// Get the newurl and grab the path name from the URL. So https://example.com/asset/contractid/assetid path is /asset/blah/blah | |
const nftid = requesturl.pathname | |
const thirdPartyRequest = new Request(`https://api.opensea.io/api/v1${nftid}`,{ headers: {'X-API-KEY': `${OPENSEA_API_KEY}` }}) | |
const cache = caches.default | |
const match = await cache.match(thirdPartyRequest) | |
if (match) { | |
return match | |
} | |
// Use the nftid to append to the end of the OpenSea API request | |
const resp = await fetch(thirdPartyRequest, { | |
headers: { | |
// Send over the API key to opensea. The API key is set using Wranger Secrets with cloudflare so it can't be snooped. | |
'X-API-KEY': `${OPENSEA_API_KEY}` | |
}, | |
}) | |
// This section will remap the response to reduce the fields coming back, it's a TBD. | |
const data = await resp.json() | |
// I want to remap the request so that only the required data is passed on and thus | |
// saving the user from some usless data. | |
// const nftdata = data.map(nft => ({ | |
// id: nft.id, | |
// token_id: nft.token_id, | |
// background_color: nft.background_color, | |
// img_url: nft.img_url, | |
// img_preview_url: nft.img_preview_url, | |
// animation_url: nft.animation_url, | |
// })) | |
// If the response from Cloudflare is a 429 status | |
if (resp.status === 429) { | |
// include a new response to say the rate is limited and try again | |
return new Response("Rate limited, try again sooooon Mr Quag!",{ | |
// Set the status of the response to 429 so the front end can try again | |
status: 429, | |
// Set cloudflare specific settings | |
// cf: { | |
// // Set the cache TTL to -1 so nothing is cached. | |
// cacheTtl: -1, | |
// // turn off caching for everything because we don't want this cached. | |
// cacheEverything : false, | |
// }, | |
headers: { | |
// Set the header for the response to be application/json so it is in the proper format | |
'Content-type': 'application/json', | |
// Checking that the worker is working, this helped for debugging | |
'Worker-working': '429 from Opensea', | |
// Include the response status as a custom header, again just for tsting | |
'Response-Status-Check': resp.status, | |
// Pass through the corsHeaders set at the top. | |
...corsHeaders | |
}, | |
}) | |
} else { // if it's not a 429 we're assuming it's a 200. | |
const response = new Response(JSON.stringify(data), { | |
headers: { | |
// Set the headers as above, but with alternative checks and debugging comments | |
'Content-Type': 'application/json', | |
'cache-control': 'max-age=600', | |
'Worker-working': 'yeah it is', | |
'Response-Status-Check': resp.status, | |
...corsHeaders | |
} | |
}) | |
event.waitUntil(cache.put(thirdPartyRequest, response.clone())) | |
return response | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment