简体   繁体   中英

How to parse JSON in Google Apps Script for Google Spreadsheet

I want to pull data from Bittrex API. I get the data but I can't find a way to display them on my spreadsheet . An error keep coming and it makes me mad !

I'm sure it is really simple stuff but I give up:)

Here is the code:

function main() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var balancesSheet = ss.getSheetByName("BITTREX 2");
  var balancesRange = balancesSheet.getRange("A1:X");
  var balancesListValues = balancesRange.getValues();

  // Add those values to the active sheet in the current
  // spreadsheet. This overwrites any values that already
  // exist there. 
  balancesSheet.getRange(1, 1, balancesRange.getHeight(), balancesRange.getWidth()) 
    .setValues(balancesListValues);

  var apikey = 'My APY Key is here'; // Please input your key.
  var apisecret = 'My API Secret is here'; // Please input your secret.

  var nonce = Number(new Date().getTime() / 1000).toFixed(0);
  var uri = 'https://bittrex.com/api/v1.1/market/getopenorders?apikey=' + apikey + '&nonce=' + nonce;
  var sign = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512, uri, apisecret);
  sign = sign.map(function(e) {return ("0" + (e < 0 ? e + 256 : e).toString(16)).slice(-2);}).join("");
  var params = {
    method: "get",
    headers: {Apisign: sign}
  }

  var response = UrlFetchApp.fetch(uri, params);
  var getContext= response.getContentText();

  var parsedata = JSON.parse(getContext);

  //ss.getRange(1,1).setValue(parsedata.foreach)
  parsedata.data.forEach(function(result, index) {
    balancesListValues.getRange(+3, 1).setValue(result.quantity)
    balancesListValues.getRange(+3, 2).setValue(result.price)
  })
  Logger.log(parsedata.result);
}

And here is the error:

TypeError: Cannot read property 'forEach' of undefined on line 31 (this one: parsedata.data.forEach(function(result, index))

My goal is to transform the raw JSON data in a nice spreadsheet . I'm open to suggestions. I've made that with a lot of Copy/Paste so don't bother the tidyness !

Thank you for your help, NiphtiAe.

EDIT

Awesome: I ended with that code to get the data updating instead of pilling in rows :

 function main() {
      // Retrieve values from API.
      var apikey = '*********'; // Please input your key.
      var apisecret = '**********'; // Please input your secret.
      var nonce = Number(new Date().getTime() / 1000).toFixed(0);
      var uri = 'https://bittrex.com/api/v1.1/account/getbalances?apikey=' + apikey + '&nonce=' + nonce;
      var sign = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512, uri, apisecret);
      sign = sign.map(function(e) {return ("0" + (e < 0 ? e + 256 : e).toString(16)).slice(-2);}).join("");
      var params = {
        method: "get",
        headers: {Apisign: sign}

  }
  var response = UrlFetchApp.fetch(uri, params);
  var getContext= response.getContentText();
  var parsedata = JSON.parse(getContext);
  
  console.log(getContext)  // Here, the response value can be confirmed at the log.

  // Use Spreadsheet
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var balancesSheet = ss.getSheetByName("BITTREX 2");
  var balancesRange = balancesSheet.getRange("A1:X");
  var balancesListValues = balancesRange.getValues();
  balancesSheet.getRange(1, 1, balancesRange.getHeight(), balancesRange.getWidth()).setValues(balancesListValues);

  var values = parsedata.result.map(({Currency, Available}) => [Currency, Available]);
  balancesSheet.getRange(1, 1, values.length, values[0].length).setValues(values);
}

Just have to call prices from CMC or Coingecko or else and voilà !

Huge thanks to @Tanaike !!

Modification points:

  • From your error message of TypeError: Cannot read property 'forEach' of undefined on line 31 (this one: parsedata.data.forEach(function(result, index)) , in this case, I thought that parsedata.data might return null . Because when the property of data is existing as the value except for an array, an error like TypeError: parsedata.data.forEach is not a function occurs.
    • When I saw the official document of "GET /market/getopenorders", the values of Quantity and Price are included in the array of result . Ref I thought that this might be the reason of your issue.
  • And, it seems that the keys of Quantity and Price are not quantity and price .
  • When I saw your script, it seems that balancesListValues is the 2 dimensional array retrieved from var balancesListValues = balancesRange.getValues() . So when balancesListValues.getRange(+3, 1).setValue(result.quantity) is run, an error occurs.
  • In your script, setValue is used in a loop. In this case, the process cost will become high.

When above points are reflected to your script, it becomes as follows.

Modified script:

function main() {
  // Retrieve values from API.
  var apikey = 'My APY Key is here'; // Please input your key.
  var apisecret = 'My API Secret is here'; // Please input your secret.
  var nonce = Number(new Date().getTime() / 1000).toFixed(0);
  var uri = 'https://bittrex.com/api/v1.1/market/getopenorders?apikey=' + apikey + '&nonce=' + nonce;
  var sign = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512, uri, apisecret);
  sign = sign.map(function(e) {return ("0" + (e < 0 ? e + 256 : e).toString(16)).slice(-2);}).join("");
  var params = {
    method: "get",
    headers: {Apisign: sign}
  }
  var response = UrlFetchApp.fetch(uri, params);
  var getContext= response.getContentText();
  var parsedata = JSON.parse(getContext);
  
  console.log(getContext)  // Here, the response value can be confirmed at the log.

  // Use Spreadsheet
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var balancesSheet = ss.getSheetByName("BITTREX 2");
  var balancesRange = balancesSheet.getRange("A1:X");
  var balancesListValues = balancesRange.getValues();
  balancesSheet.getRange(1, 1, balancesRange.getHeight(), balancesRange.getWidth()).setValues(balancesListValues);

  var values = parsedata.result.map(({Quantity, Price}) => [Quantity, Price]);
  balancesSheet.getRange(balancesSheet.getLastRow() + 1, 1, values.length, values[0].length).setValues(values);
}
  • In this modified script, the retrieved values are put to the 1st empty row of the sheet of "BITTREX 2". When you want to put the values to other range, please modify above script.

Note:

  • If above modified script was not the result you expect, can you provide the sample values of console.log(getContext) ? By this, I would like to check it.

Reference:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM