Last active
January 5, 2018 16:40
-
-
Save Slakah/07ac31e96591464e69f76e32b937dcc5 to your computer and use it in GitHub Desktop.
Fetch crypto prices using cryptocompare api (includes retries and caching)
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
// #loljavascript | |
var settings = { | |
cacheExpiresSec: 10, | |
extraParams: "&extraParams=your-id-here", // enter your id here | |
retry: { | |
factor: 2, | |
max: 5, | |
maxRetries: 5, | |
}, | |
syms: [ | |
"BTC", | |
"ETH", | |
"LTC", | |
"BCH", | |
"XRP", | |
"ADA", | |
"VEN", | |
"NEO", | |
"IOT", | |
"XRB" | |
] | |
}; | |
function nowSeconds() { | |
return Date.now() / 1000; | |
} | |
function retry(f) { | |
function loop(count, delay) { | |
try { | |
return f(); | |
} catch (e) { | |
console.error("Error encountered, retrying..."); | |
const newCount = count + 1; | |
if (newCount >= settings.retry.maxRetries) { | |
throw e; | |
} else { | |
const newDelay = Math.min(delay * settings.retry.factor, settings.retry.factor); | |
return loop(newCount, newDelay); | |
} | |
} | |
} | |
return function() { return loop(0, 0.5); }; | |
} | |
function cacheGetOrUpdate(key, f) { | |
const cache = CacheService.getDocumentCache(); | |
const cached = cache.get(key) | |
if (cached != null) { | |
console.log("Found cached data for key: " + key); | |
return JSON.parse(cached); // easiest way to encode type | |
} | |
const value = f(); | |
const valueJs = JSON.stringify(value); // encode type | |
cache.put(key, valueJs, settings.cacheExpiresSec); | |
return value; | |
} | |
function fetchJson(url) { | |
return cacheGetOrUpdate("fetch:" + url, retry(function () { | |
console.log("Fetching url " + url); | |
const response = UrlFetchApp.fetch(url); | |
const result = response.getContentText(); | |
console.log("Response: " + result); | |
const js = JSON.parse(result); | |
const isError = js.Response == "Error"; | |
if (isError) { | |
console.error("Error when fetching url: " + url + ", " + js.Message); | |
throw new Error(js.Message); | |
} | |
return js; | |
})); | |
} | |
var dataEndpoint = "https://min-api.cryptocompare.com/data"; | |
function fetchPrices(toSym) { | |
const syms = settings.syms.join(","); | |
const url = dataEndpoint + "/pricemulti?fsyms=" + syms + "&tsyms=" + toSym + settings.extraParams; | |
return fetchJson(url) | |
} | |
function fetchPrice(sym, toSym) { | |
return fetchPrices(toSym)[sym][toSym]; | |
} | |
function fetchPriceHistorical(sym, toSym, durSec) { | |
const ts = Math.floor(nowSeconds() - durSec); | |
const url = dataEndpoint + "/pricehistorical?fsym=" + sym + "&tsyms=" + toSym + "&ts=" + ts + settings.extraParams; | |
return fetchJson(url)[sym][toSym]; | |
} | |
function fetchRateLimitSecond() { | |
return fetchJson("https://min-api.cryptocompare.com/stats/rate/second/limit"); | |
} | |
function fetchRateLimitMinute() { | |
return fetchJson("https://min-api.cryptocompare.com/stats/rate/minute/limit"); | |
} | |
function fetchRateLimitHour() { | |
return fetchJson("https://min-api.cryptocompare.com/stats/rate/hour/limit"); | |
} | |
function CRYPTOPRICE(sym, toSym) { | |
return fetchPrice(sym, toSym); | |
} | |
function CRYPTOPRICEHOUR(sym, toSym) { | |
return fetchPriceHistorical(sym, toSym, 60 * 60); | |
} | |
function CRYPTOPRICEDAY(sym, toSym) { | |
return fetchPriceHistorical(sym, toSym, 60 * 60 * 24); | |
} | |
function CRYPTORATELIMITSECOND() { | |
return JSON.stringify(fetchRateLimitSecond().CallsLeft); | |
} | |
function CRYPTORATELIMITMINUTE() { | |
return JSON.stringify(fetchRateLimitMinute().CallsLeft); | |
} | |
function CRYPTORATELIMITHOUR() { | |
return JSON.stringify(fetchRateLimitHour().CallsLeft); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment