Closed apiontek closed 6 years ago
This was my solution. Not sure which one is more useful as I'm new to this.
function fetch(currencyId){
var cache = CacheService.getPublicCache();
var cachedUSD = cache.get('price_usd');
var cachedBTC = cache.get('price_btc');
var myarray = new Array();
if(cachedUSD != null){
ssRates.getRange('B5').setValue('cache');
myarray[0] = cachedUSD;
myarray[1] = cachedBTC;
return myarray
}
var url = 'https://api.coinmarketcap.com/v1/ticker/' + currencyId + '/';
var response = UrlFetchApp.fetch(url, {'muteHttpExceptions': true});
var json = response.getContentText();
var data = JSON.parse(json);
cache.put('price_usd', parseFloat(data[0].price_usd));
cache.put('price_btc', parseFloat(data[0].price_btc));
myarray[0] = parseFloat(data[0].price_usd);
myarray[1] = parseFloat(data[0].price_btc);
return myarray
}
@LeMoise does that work for multiple currencies? Reading the code it looks like it caches the values for whatever currency it's checking in the same two keys. I haven't had time to test it but it looks like it would provide the same initially cached values each time, regardless of currencyId?
I'm new to the CacheService, though, too. Trying to read more about it because it seems like my solution and your solution would work even better together.
Should be even simpler. Just make the first call to initialize the array with everything from ticker/currencyId
.
var ARK = getCoin('ark');
function getCoin(currencyId) {
var url = 'https://api.coinmarketcap.com/v1/ticker/' + currencyId + '/?convert=' + targetCurrency;
var response = UrlFetchApp.fetch(url, {'muteHttpExceptions': true});
var json = response.getContentText();
return JSON.parse(json);
}
All of these other commands then can just reference the JSON object stored in the variable.
function getRate(currencyId) {
return parseFloat(currencyId[0]['price_' + targetCurrency]);
}
I might be confused about what you're suggesting but I think I get it. I'll make an attempt and see what you think. This would help with pulling other data from the web page if the api fails as one could parse data from the web page, construct json object and add it to the global array, so other functions like a getMarketCap function could just grab from the stored object.
What I'm confused about is: your quick code suggests saving the API data object in variables per coin, where my solution saves the entire API output in one array object. Personally I prefer the latter since it reduces API calls for coins that are in the main ticker. No need to poll the API for each individual coin.
But would you rather poll for each coin and store each in its own little object?
My method is saving the array as well. You're just writing a lot more code to do it. Turn on debugging for the current getRate
function and step through the data. You'll see that when it gets to the data = JSON.parse(json);
part, it already has the JSON array there. That will allow you to do a single API call per coin that you want, and then access that object to pull any data you want.
This person already did something similar. I'd just to break all of the data access into different functions. https://www.reddit.com/r/cryptosheets/comments/7mlpga/improvements_for_automation/
Yes, your current getRate function does pull down the whole json result for a single coin. I see that.
But it's too many requests, I think. If we want bitcoin, we must make a UrlFetchApp request for the bitcoin data. If we then want zcoin, we must make a new UrlFetchApp request.
I had a goal of reducing these requests. My solution initially fetches everything at https://api.coinmarketcap.com/v1/ticker/ giving us the top 100 coins with one request. That's 100 coins we don't need to do any more requests for.
I agree that it's an improvement to save other coins back to the saved array of coins, for retrieval of other data such as Market Cap without again doing a UrlFetchApp request. That's the direction I'm moving in.
Ah, yeah. I agree then. I'd say go straight to ?limit=0
and pull everything in at the beginning. In my browser it's fast, so hopefully it's fast in the script as well.
And that's what I get for not checking into their API. I'll rebase off develop to get the targetCurrency stuff and re-do what I'm doing with the ?limit=0
and see how it goes.
😆 Hahah, all good. I had the same slap in the face when I made a currency conversion function while pulling in data for another API, when CMC had it in their API all along.
I streamlined things as discussed. Haven't done anything to make "getWebRate" work, yet. At the moment I want to add in getMarketCap, but more than that I want to do it all in a loop, rather than defining a variable for every coin.
Which means either creating an array that user can enter coin info (and cell locations), or ideally reading it all from a range in a sheet. Has anyone already done work on that?
@apiontek This should be fixed in 2156e552ea4314d65c61a141257285d03fba2d75
Also, just a reminder to target PRs against develop
branch now. I need to figure out a good way to handle people using PRs to a new feature branch.
Added getApiObj() function to get all API data one time Modified getRate function and coin variable declarations to use apiObj object This should reduce API fetch to once per script run rather than fetching for every coin
I'm new to pull requests so apologies if I'm doing something wrong! I think this would help with issue 12