Home > database >  Why is doGet() failing without posting logs?
Why is doGet() failing without posting logs?

Time:05-20

I suppose my question is twofold: doGet() in the following context will just fail after 0.1~0.2 seconds without posting logs, so I have no idea how to troubleshoot it by myself. Additionally, if I'm having the script execute on my behalf, do I have to push a request with my authorization token to a more "pertinent" area than just the sheet name, such as within the iteration itself? Read further for more details:

I have a source spreadsheet where I am cross-referencing user inputted data to validate the information we have "on file". Most of our clients are over the age of 55, so I am trying to reduce end-user complexity by having the script run on my behalf whenever they need to use it (to bypass the Authorization screen, with the big scary "This application could be unsafe!" message). The way I've read to accomplish this seems to be with doGet(), so I set up a low-level HTTP Get request that just pushes a doGet() with my OAuth token, returning the sheet name. I also set up a masking function specifically to do this, and linked it to the button originally used for the iteration logic. The doGet() looks like this:

const doGet = e => {
  Logger.log(`Recieved HTTP request.`);
  const content = ContentService.createTextOutput(iterator(e));
  Logger.log(content);
  return content;
}

and the button that uses UrlFetchApp looks like:

const runMask = () => {
  const active = SpreadsheetApp.getActiveSheet().getSheetName();
  const v4 = 'https://script.google.com/macros/s/<scriptid>/dev' // ScriptApp.getService().getUrl() posts  404

  UrlFetchApp.fetch(`${v4}?sheetName='${active}'`, {
    headers: { Authorization: `Bearer ${ScriptApp.getOAuthToken()}` },
  });

I have some logs set up within the real runMask() that proceed all the way to the end of the program, giving me real URLs and OAuth tokens, so I know it's making it through runMask() without an issue. However, the doGet() log doesn't post anything, even at the top of the function. I can see that it's executing the trigger in my execution log, but the log itself remains empty.

I've tried:

  • using ScriptApp.getService().getUrl() in place of v4: posts 404 in the log w/ truncated server response
  • replacing ${active} with the name of the sheet: same issue; logging ${active} also returns the correct name of the sheet.

Beyond this, I'm not even sure what to do. I have everything scoped correctly (auth/spreadsheets.currentonly, auth/script.external_request, and auth/userinfo.email), and I have no issues about operational security (as both the spreadsheet and script are written by me, the clients have no need to grant access to their entire drive). Before trying to implement doGet() and bypass the authorization screen, the iterator itself worked just fine. As such, I have chosen not to include it here, as it's hardly relevant (the function that executes the iteration function never makes it to that point).

I understand this has been quite the deluge of information; I'd be happy to provide more information or context as needed.

CodePudding user response:

Getting ReferenceError: iterator is not defined (line 12, file "ag2")

With this:

const doGet = e => {
  Logger.log(`Recieved HTTP request.`);
  const content = ContentService.createTextOutput(iterator(e));
  Logger.log(content);
  return content;
}

Issued with url/exec?option=A

It runs with

const doGet = e => {
  Logger.log(`Recieved HTTP request.`);
  const content = ContentService.createTextOutput(JSON.stringify(e));
  Logger.log(content);
  return content;
}

and returns the appropriate stringified object

CodePudding user response:

Only use the test URL (/dev) for testing the web app from a web browser.

Before doGet from a web browser using a versioned deployment (/exec) remember to publish a new version.

Assign a Google Cloud Project to your Google Apps Script project. For details see https://developers.google.com/apps-script/guides/cloud-platform-projects.

To make it easier to debug your avoid calling functions from a Google Apps Script method like createTextOutput, instead, assign the function result to a variable and use it as the method parameter, i.e. replace

const content = ContentService.createTextOutput(iterator(e));

by

const something = iterator(e);
const content = ContentService.createTextOutput(something);

For debugging purposes, create a function to call your doGet function, and check that it hasn't any problem to run, i.e.

function __test__doGet(){
  const e = {
    parameter: {}
  }

  doGet(e);
}

Related

CodePudding user response:

Issue:

When I saw your question, I'm worried about I have everything scoped correctly (auth/spreadsheets.currentonly, auth/script.external_request, and auth/userinfo.email).

If you are using only the following scopes at oauthScopes of appsscript.json,

  • https://www.googleapis.com/auth/spreadsheets.currentonly
  • https://www.googleapis.com/auth/script.external_request
  • https://www.googleapis.com/auth/userinfo.email

Unfortunately, these scopes cannot be used for access to Web Apps. Although I'm not sure about the method for running your function of runMask, I thought that this might be the reason for your issue.

Solution:

If you want to access Web Apps of https://script.google.com/macros/s/<scriptid>/dev using the access token retrieved by ScriptApp.getOAuthToken(), please include the following scope.

https://www.googleapis.com/auth/drive.readonly

or

https://www.googleapis.com/auth/drive

After you include the above scope, please reauthorize the scopes, and test it again. When your function of iterator has already been declared and the script worked, by running runMask, you can see the log of Logger.log(Recieved HTTP request.) and Logger.log(content) at the log.

Reference:

  • Related