theTANCO

CoinCap.gs

Jun 5th, 2021 (edited)
769
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // This library is for getting cryptocurrency market data from the CoinCap API 2.0 using Javascript - Fetch.
  2. // Check the documentation here under the RESTful API section for details on the control flow: https://docs.coincap.io/
  3. // Comments like this are used to divide this script into sections. Each comment explains what each section is, how it works and how to use it, as well as any known bugs.
  4. // This script was designed for Google Sheets and uses the UrlFetchApp class from Google's API to get data from CoinCap. Therefore, this script will likely not work outside of Google Sheets.
  5. // I made this to work similar GOOGLEFINANCE() to get the current market price for cryptos, and that was my main use case and initial intention for this script.
  6. // It should be noted that all of the other functionality is an afterthought and might not be super concerned about minor bugs in the code.
  7. // This is also a work in progress. I will be adding functionality from the rest of the CoinCap API soon enough.
  8.  
  9.  
  10.  
  11. // Modular functions. These functions were not made specifically for this script and can be reused in any program.
  12. // These private functions are meant to be used by the utility and spreadsheet functions, but not meant to be imported and used in the spreadsheet.
  13.  
  14. var modular = {
  15.   stringTo2dArray: function(str, d1, d2){
  16.     str = str.split(d1).map(function(x){ return x.split(d2) });
  17.     for(var a = 0; a < str.length; a++){
  18.       for(var b = 0; b < str[a].length; b++){
  19.         if(!isNaN(Number(str[a][b]))){
  20.           str[a][b] = Number(str[a][b]);
  21.         }
  22.       }
  23.     }
  24.     return str;
  25.   },
  26.  
  27.   gsub: function(str, oldChar, newChar){
  28.     for(var a = 0; a < str.length; a++){
  29.       if(str.substring(a, a+oldChar.length) == oldChar){
  30.         str = str.substring(0, a) + newChar + str.substring(a+oldChar.length, str.length);
  31.       }
  32.     }
  33.     return str;
  34.   }
  35. }
  36.  
  37.  
  38.  
  39. // Utility functions. These private functions are meant to be used by spreadsheet functions, but not meant to be imported and used in the spreadsheet.
  40.  
  41. var utility = {
  42.   separateKeys: function(str, newChar){
  43.     return modular.gsub(modular.gsub(str, "\":", newChar), "\"", "");
  44.   },
  45.  
  46.   structTable: function(arr){
  47.     var header = ["Index"];
  48.     var newArr = [];
  49.     for(var a = 0; a < arr.length; a++){
  50.       var newDat = [a];
  51.       for(var b = 0; b < arr.length; b+=2){
  52.         if(a == 0){
  53.           header.push(arr[a][b]);
  54.         }
  55.         newDat.push(arr[a][b+1]);
  56.       }
  57.       newArr.push(newDat);
  58.     }
  59.     newArr.splice(0, 0, header);
  60.     return newArr;
  61.   },
  62.  
  63.   requestOptions: function(){
  64.     return {
  65.       method: 'GET',
  66.       redirect: 'follow'
  67.     };
  68.   },
  69.  
  70.   processArray: function(fetchData){
  71.     var returnData = JSON.stringify(fetchData);
  72.     return utility.structTable(modular.stringTo2dArray(utility.separateKeys(returnData.substring(2, returnData.length-2), ","), "},{", ","));
  73.   },
  74.  
  75.   processObject: function(fetchData){
  76.     var returnData = JSON.stringify(fetchData);
  77.     return modular.stringTo2dArray(utility.separateKeys(returnData.substring(1, returnData.length-1), ";"), ",", ";");
  78.   },
  79.  
  80.   processKey: function(fetchData){
  81.     var returnData = fetchData;
  82.     if(returnData == undefined){
  83.       throw new Error('Invalid Key.');
  84.     }else if(isNaN(Number(returnData))){
  85.       return returnData;
  86.     }else{
  87.       return Number(returnData);
  88.     }
  89.   }
  90. }
  91.  
  92.  
  93.  
  94. // Spreadsheet functions. These are the public functions meant to be imported and used in the spreadsheet.
  95.  
  96. /** COINCAP() searches and returns current or historical data about a given crypto. Check the CoinCap API 2.0 documentation under the RESTful API section for details on the control flow: https://docs.coincap.io/
  97.  * @param {string} coinSymbol
  98.  * Required. A valid symbol, id or name of Crypto ("BTC", "bitcoin", "Bitcoin", etc.). This alone will return the current market price in USD.
  99.  * Example: =COINCAP("Bitcoin") -> Current average price of "Bitcoin".
  100.  *
  101.  * @param {string} searchType
  102.  * Required if 'index' is used. Otherwise optional. Default value is "". "history", "markets", or "". If your array returns a "Result too large" error, set 'startTime' and 'endTime'.
  103.  * Example: =COINCAP("bitcoin", "markets") -> Array containing all markets with "bitcoin".
  104.  *
  105.  * @param {number|string} index
  106.  * Required if 'key' is used. Otherwise optional. Default value is -1. Index of an array. Set to -1 to get whole array. Acts as 'key' if 'searchType' == "".
  107.  * Example: =COINCAP("BTC", "", "name") -> Name of "BTC".
  108.  *
  109.  * @param {string} key
  110.  * Required if 'interval' is used. Otherwise optional. Default value is "priceUsd". Property of an object. Set to "" to get all properties.
  111.  * Example: =COINCAP("BTC", "markets", 1, "exchangeId") -> Exchange ID of element 1 (the 2nd element) of the market list of "BTC".
  112.  *
  113.  * @param {string} interval
  114.  * Required if 'startTime' is used. Otherwise optional. Default value is "d1". String for history interval. Only used when 'searchType' == "history". Does nothing otherwise.
  115.  * Example: =COINCAP(B4, "history", 1, "", "m1") ->  Object data of element 1 (the 2nd element) of the minutely history of the crypto in cell 'B4'.
  116.  *
  117.  * @param {Time|Date} startTime
  118.  * endTime is required if used. Otherwise optional. Time value. Timezone is UTC. Only used when 'searchType' == "history". Does nothing otherwise.
  119.  *
  120.  * @param {Time|Date} endTime
  121.  * Required if startTime is used. Otherwise optional. Time value. Timezone is UTC. Only used when 'searchType' == "history". Does nothing otherwise.
  122.  * Example: =COINCAP(B5, "history", -1, "", "d1", DATEVALUE(TODAY())-5, DATEVALUE(TODAY())) -> Array containing the daily history of the crypto in cell 'B5' between 5 days ago and today.
  123.  *
  124.  * @customfunction
  125.  */
  126. function COINCAP(coinSymbol, searchType, index, key, interval, startTime, endTime) {
  127.   if(searchType == "" || index == "timestamp"){ key = index; }
  128.  
  129.   if(searchType == undefined){ searchType = ""; }
  130.   if(index == undefined){ index = -1; }
  131.   if(key == undefined){ key = "priceUsd"; }
  132.   if(interval == undefined){ interval = "d1"; }
  133.   if(startTime != undefined){
  134.     if(typeof(startTime) != "number" || typeof(endTime) != "number"){ throw new Error('Start and end date must be in number format.'); }
  135.     if(startTime >= endTime){ throw new Error('Start date must be before end date.'); }
  136.     startTime = (startTime - 25569) * 86400000;
  137.     endTime = (endTime - 25569) * 86400000;
  138.   }
  139.  
  140.  
  141.   var getData = UrlFetchApp.fetch("api.coincap.io/v2/assets?search=" + coinSymbol, utility.requestOptions());
  142.   var allData = JSON.parse(getData.getContentText());
  143.   if(allData.data.length == 0){ throw new Error('No cryptocurrency found.'); }
  144.  
  145.   for(var a = 0; a < allData.data.length; a++){
  146.     if(allData.data[a].symbol == coinSymbol || allData.data[a].id == coinSymbol || allData.data[a].name == coinSymbol){
  147.       allData.data = allData.data[a];
  148.       foundIt = true;
  149.     }
  150.   }
  151.   if(allData.data.length > 0){ throw new Error('No cryptocurrency found.'); }
  152.  
  153.  
  154.   if(searchType == "history"){
  155.     if(startTime == undefined){
  156.       getData = "api.coincap.io/v2/assets/" + allData.data.id + "/history?interval=" + interval;
  157.     }else{
  158.       getData = "api.coincap.io/v2/assets/" + allData.data.id + "/history?interval=" + interval + "&start=" + startTime + "&end=" + endTime;
  159.     }
  160.   }else if(searchType == "markets"){
  161.     getData = "api.coincap.io/v2/assets/" + allData.data.id + "/markets";
  162.   }
  163.   if(searchType != ""){
  164.     allData = JSON.parse(UrlFetchApp.fetch(getData, utility.requestOptions()).getContentText());
  165.   }
  166.  
  167.   if(key == "timestamp"){
  168.     return allData[key];
  169.   }else{
  170.     if(searchType == ""){
  171.       if(key != ""){
  172.         return utility.processKey(allData.data[key]);
  173.       }else{
  174.         return utility.processObject(allData.data);
  175.       }
  176.  
  177.     }else{
  178.       if(index < 0){
  179.         return utility.processArray(allData.data);
  180.       }else{
  181.         if(key != ""){
  182.           return utility.processKey(allData.data[index][key]);
  183.         }else{
  184.           return utility.processObject(allData.data[index]);
  185.         }
  186.       }
  187.     }
  188.   }
  189. }
  190.  
  191. //function COINCAPRATES(){}
  192.  
  193. //function COINCAPEXCHANGES(){}
  194.  
  195. //function COINCAPMARKETS(){}
  196.  
  197. //function COINCAPCANDLES(){}
RAW Paste Data