11

I have the following code in Google Apps Script which retrieves CSV data from a webpage via HTTP using basic authentication and places it into a spreadsheet:

CSVImport.gs

function parseCSVtoSheet(sheetName, url)
{
  // Credentials
  var username = "myusername";
  var password = "mypassword";
  var header = "Basic " + Utilities.base64Encode(username + ":" + password);
  
  // Setting the authorization header for basic HTTP authentication
  var options = {
    "headers": {
      "Authorization": header
    }
  };
  
  // Getting the ID of the sheet with the name passed as parameter
  var spreadsheet = SpreadsheetApp.getActive();
  var sheet = spreadsheet.getSheetByName(sheetName);
  var sheetId = sheet.getSheetId();
  
  // Getting the CSV data and placing it into the spreadsheet
  var csvContent = UrlFetchApp.fetch(url, options).getContentText();
  var resource = {requests: [{pasteData: {data: csvContent, coordinate: {sheetId: sheetId}, delimiter: ","}}]};
  Sheets.Spreadsheets.batchUpdate(resource, spreadsheet.getId());
}

This has been working up until recently where randomly I get the following error on the UrlFetchApp.fetch line:

Exception: Unexpected error: http://www.myurl.com/data/myfile.csv (line 21, file "CSVImport")

I have tried:

  • Putting the credentials directly in the URL instead of in an Authorization header (I received a different error saying "Login information disallowed").
  • Encoding the credentials to base64 right when I pass it into the headers object (didn't work, same error).
  • Removing authentication altogether (predictably I received a 401 response from the HTTP page).

I'm not sure what else to try and why this randomly broke down all of a sudden. Any advice?

Rubén
  • 34,714
  • 9
  • 70
  • 166
Step
  • 463
  • 1
  • 4
  • 19
  • I am experiencing the same issue, but specifically with CSV files. It's also not random, it's been consistent for me since 05:16 UTC today. –  Dec 10 '20 at 17:22
  • As an aside, you might want to split `var csvContent = UrlFetchApp.fetch(url, options).getContentText();` into two lines for debugging purposes, although I have that already and it's crashing on the `fetch()` call so there's not much to glean in this case. –  Dec 10 '20 at 17:24
  • 5
    I am having the same issue on a script that uses UrlFetchApp in the early morning to grab some stock info from a data source. Has been working flawlessly for months and suddenly on Dec 7 started getting the "unexpected error" which points to this line. I can confirm that when I used the same exact URL to manually fetch using importhtml, I get the data. Something changed on Google's end...but what? OK so it turns out this is a [Google issue](https://issuetracker.google.com/issues/175141974) which is affecting lots of folks. At least we are not alone... – MountainCat Dec 10 '20 at 22:36
  • @Ploni I forgot to mention in the post but I did actually split those lines while debugging too to see if there was any problem but the problem is indeed with the `fetch()`. Seems to be a Google issue - let's hope it gets fixed soon. – Step Dec 11 '20 at 09:00
  • I recommend everyone to "star" the issue, see link in @ziganotschka's response – Peter Thoeny Dec 12 '20 at 01:13
  • Although, unfortunately, I cannot test your URL, I proposed a current workaround as an answer. Could you please confirm it? If that was not useful for your situation, I apologize. – Tanaike Dec 14 '20 at 11:04

4 Answers4

8

This is related to a new bug, see here

Many users are affected, I recommend you to "star" the issue to increase visibility and hopefully accelerate the process.

ziganotschka
  • 25,866
  • 2
  • 16
  • 33
  • As per #346 from the official issue tracker https://issuetracker.google.com/issues/175141974 hey guys I have found a possible solution that is working for me try inputting empty {} like this UrlFetchApp.fetch(apiLink, {}); it worked for me I tried this, and it too is working for me. Works even when using the "new Apps Script runtime powered by Chrome V8". – BaconCatBug Dec 15 '20 at 13:35
  • 1
    Marked Fixed. #377 – TheMaster Dec 16 '20 at 15:09
2

I had the same situation. At that time, I could noticed that when the built-in function of Google Spreadsheet is used for the URL, the values can be retrieved. In that case, as the current workaround, I used the following flow.

  1. Put a formula of =IMPORTDATA(URL).
  2. Retrieve the values from the sheet.

When above flow is reflected to your URL of http://www.myurl.com/data/myfile.csv, it becomes as follows.

About basic authorization for URL:

When I saw your script, I confirmed that you are using the basic authorization. In this case, the user name and password can be used for the URL like http://username:password@www.myurl.com/data/myfile.csv.

From your script, when the values of username and password are myusername and mypassword, respectively, you can use the URL as http://myusername:mypassword@www.myurl.com/data/myfile.csv.

Here, there is an important point. If the specific characters are included in username and password, please do the url encode for them.

Sample script:

function myFunction() {
  const url = "http://myusername:mypassword@www.myurl.com/data/myfile.csv";  // This is your URL.

  // Retrieve the values from URL.
  var spreadsheet = SpreadsheetApp.getActive();
  var sheet = spreadsheet.getSheetByName(sheetName);
  sheet.clear();
  var range = sheet.getRange("A1");
  range.setFormula(`=IMPORTDATA("${url}")`);
  
  // Retrieve the values from sheet to an array.
  SpreadsheetApp.flush();
  var values = sheet.getDataRange().getValues();
  range.clear();
  console.log(values)
}
  • When above script is run, the values from the URL are put to the sheet, and the values are retrieved as 2 dimensional array for values. If you want to leave only values without the formula, I think that you can copy and paste the values.
  • In this answer, I used IMPORTDATA. But for each situation, other functions might be suitable. In that case, please check them.

Note:

  • This is the current workaround. So when this issue was removed, I think that you can use your original script.

References:

Tanaike
  • 181,128
  • 11
  • 97
  • 165
1

Disable Chrome V8 Runtime Engine until Google fix this.

To disable: From Menu click on Run > Disable new Apps Script runtime powered by Chrome V8

Irfan Alam
  • 476
  • 3
  • 9
  • 25
  • 1
    See my post at #297 at https://issuetracker.google.com/issues/175141974 and multiple people confirmed there that disabling V8 worked for them. If it is not working for you then you need to wait until Google fixes this. – Irfan Alam Dec 15 '20 at 07:02
  • @IrfanAlam After a few hours, deactivating the V8 version made it really work again, when I commented it still wasn't having a positive feedback, I will delete my old comment. – Digital Farmer Dec 15 '20 at 22:52
0

As per #346 from the official issue tracker https://issuetracker.google.com/issues/175141974

hey guys I have found a possible solution that is working for me try inputting empty {} like this

UrlFetchApp.fetch(apiLink, {});

it worked for me

I tried this, and it too is working for me. Works even when using the "new Apps Script runtime powered by Chrome V8".

BaconCatBug
  • 137
  • 9
  • To add basic authentication or any authentication, options part is needed and making it empty wouldn't help many. – TheMaster Dec 15 '20 at 13:39