0

I have deployed my appscript as a form addon and as a web app both. Everything seems to be working fine in the container form. But now I'm facing this issue where doPost function is not running as I have to run the function as other user. I tried this code from this answer, but this is also giving same authorization error.

function merry2script() {
  var url = 'https://script.google.com/macros/s/AKfycbzM97wKyc0en6UrqXnVZuR9KLCf-UZAEpzfzZogbYApD9KChnnM/exec';
  var payload = {payloadToSend : 'string to send'};
  var method = 'post'
  var headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()}
  var response = UrlFetchApp.fetch(url, {method : method, payload: payload, headers: headers}).getContentText();
  Logger.log(response);
  return;
}

Is this the correct way to post to appscript with oauth token? If not how can I send a post request ?

I deployed the web app with these settings

enter image description here

I'm getting this error enter image description here

I've been stuck for 3 days any help is appreciated Thank you

UPDATED QUESTION:

APPSCRIPT DOPOST

function doPost(e) {
 var data = JSON.stringify(e);
 var jsonData = JSON.parse(data);
 let query = jsonData.queryString;
 let params = query.split("&");

 let destinationId = params[0].split("=")[1];

 // code is breaking here saying "you don't have access to the document"
 let ss = SpreadsheetApp.openById(destinationId);

 let sheetName = ss.getActiveSheet().getSheetName();
 let dataSheet = ss.getSheetByName(sheetName);

 var uniqueIdCol = dataSheet.getRange("A1:A").getValues();
 let rowToUpdate;
 // code to update row...
}

BACKEND CODE

// call appscript to update status sheet
  const data = {
    comment
  };
  let scriptId = process.env.DEPLOYMENT_SCRIPT_ID;
  const config = {
    method: "post",
    url: `https://script.google.com/macros/s/${scriptId}/exec?destinationId=${destinationId}&uniqueId=${uniqueId}&status=${status}`,
    data,
    headers: {
      Authorization: `Bearer ${respondent.form.oAuthToken}`,
    },
  };

  await axios(config);

These are the scopes which I requested to user

"https://www.googleapis.com/auth/script.container.ui",
"https://www.googleapis.com/auth/forms.currentonly",
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/script.send_mail",
"https://www.googleapis.com/auth/forms",
"https://www.googleapis.com/auth/script.scriptapp",
"https://www.googleapis.com/auth/drive"

UPDATED QUESTION 2

I had made a script which can write to google sheet with some extra data which I send from my node backend.

So my script has doPost function which is invoked from backend. I send destinationId of the sheet to know in which sheet to write as in the code above.

I have deployed the webapp as Execute as: Me and Who has access to the app: Anyone.

I'm able to run the doPost function but not able to write to sheet.

Hope my question is clear

Chirag Gupta
  • 469
  • 1
  • 7
  • 16
  • In your situation, the owner of Web Apps and the user for running `merry2script()` are the same? And, can you provide the detailed information of `but this is also giving same authorization error.`? And, in your Google Apps Script project, only your showing script is included? – Tanaike Jun 21 '22 at 05:39
  • No, both users are different merry2script() is running from my backend . I saved the token from ScriptApp.getOAuthToken()} in my db and sent a POST request but it give a response saying unauthorized. No it's just a mock code it's not part of my project – Chirag Gupta Jun 21 '22 at 05:42
  • Thank you for replying. In this case, please do the following flow. 1. Added the scope of Drive API. 2. Share the Google Apps Script project including your Web Apps script with the user you want to make access. And, test your script again. [Ref](https://github.com/tanaikech/taking-advantage-of-Web-Apps-with-google-apps-script) – Tanaike Jun 21 '22 at 05:43
  • 1. Is there any way to do this without giving access to my scripts project? 2. Why the drive API access? Thanks for the reference I'm looking into it – Chirag Gupta Jun 21 '22 at 05:46
  • About your additional 2 questions, Q1: `Is there any way to do this without giving access to my scripts project?` A1: If you want to access to the Web Apps with the script with your current condition, it's no because of the current specification. Q2: `Why the drive API access?` A2. It seems that this is the current specification. This specification has given at April 11, 2018. – Tanaike Jun 21 '22 at 05:50
  • What I want is to write to the sheet of the user who calls the doPost function. I gave access to the drive API still no luck. This gives the error "You do not have permission to access the requested document" I cannot share the project with the person. What changes I can do to run doPost? TIA – Chirag Gupta Jun 21 '22 at 07:01
  • Thank you for replying. In the current specification, I think that when your situation is `I cannot share the project with the person.`, it is required to set the Web Apps as `Execute as: Me` and `Who has access to the app: Anyone` with new IDE. – Tanaike Jun 21 '22 at 07:05
  • Thanks for replying. I tried with this specification I was able to run the doPost function . But was not able to still write to sheet and got the same error "You do not have permission to access the requested document" – Chirag Gupta Jun 21 '22 at 07:09
  • Thank you for replying. I cannot understand the situation of `I tried with this specification I was able to run the doPost function .`. Can I ask you about the detail of your current situation? Can you add the detail of your current situation including the current script? – Tanaike Jun 21 '22 at 07:12
  • Specification means Execute as: Me and Who has access to the app: Anyone. Yes so I want to write some data into the sheet of the owner from my node backend. How can I do it ? How will the appscript know that I have to write to this particular sheet? – Chirag Gupta Jun 21 '22 at 07:17
  • Thank you for replying. Can you add the detail of your current situation including the current script? – Tanaike Jun 21 '22 at 07:20
  • Please have a look at the updated question. TIA – Chirag Gupta Jun 21 '22 at 07:38
  • Thank you for replying and adding information. When I saw your updated question, it seems that the script of your client-side is changed from Google Apps Script to Javascript or Node.js. So, in the current stage, I cannot understand your question. I apologize for this. Can I ask you about the detail of your question? – Tanaike Jun 21 '22 at 07:45
  • Thank you for replying. About `Hi can you come to this google meet if that's ok meet.google.com/wvs-adei-hsa?authuser=0 . Won't take much of your time. TIA`, I cannot do it now. I apologize for this. – Tanaike Jun 21 '22 at 07:48
  • No worries. Let me try to explain the question here properly – Chirag Gupta Jun 21 '22 at 07:49
  • I would like to support you. So, I think that in the current stage, it is required to correctly understand your current situation and your actual goal. Because, from your updated question, it seems that your goal has been changed. By correctly understanding your question, I would like to think of a solution. I understand that this is due to my poor skill. I deeply apologize for this. – Tanaike Jun 21 '22 at 07:52
  • Please see the updated ques 2 . hope it helps – Chirag Gupta Jun 21 '22 at 08:07
  • Thank you for replying. In your situation, who is the owner of the Spreadsheet? – Tanaike Jun 21 '22 at 08:08
  • Owner is the other person who installed the addon. Script is also deployed as an addon too for google forms – Chirag Gupta Jun 21 '22 at 08:08
  • Thank you for replying. In the case of `Owner is the other person who installed the addon`, in order to access to the Spredsheet using Web Apps, the setting of `Execute as: Me and Who has access to the app: Anyone` cannot be used. Because in this case, the owner runs the script. In order to confirm your situation, as one more question, the user can retrieve the user's access token including the multiple scopes? – Tanaike Jun 21 '22 at 08:11
  • If each user can retrieve their own access token, I expected that another workaround might be able to be used. – Tanaike Jun 21 '22 at 08:13
  • 1. should I change to Execute as: User accessing the webapp and Who has access to the app: Anyone 2. how to get user access tokens using `ScriptApp.getOAuthToken()` does not seems to be working or I'm getting the incorrect token – Chirag Gupta Jun 21 '22 at 08:17
  • Thank you for replying. I have to apologize for my poor English skill. Unfortunately, it seems that my reply is not reflected in your reply. But, when I could correctly understand your situation, I would like to think of a solution. I would be grateful if you can forgive my poor English skill. – Tanaike Jun 21 '22 at 08:19
  • That backend code is indeed the method `doPost` of the main script a 3rd party user would run, correct? In the effort to isolate the issue here, if you comment out the HTTP call to the other webapp, `doPost` runs as expected? If so, passing `oAuthToken` as `Bearer` of this "sub-request" means that the owner of the OAuth token (in this case the user executing the top-level `doPost`) also must have enough access to execute that sub-webapp. It's a chain of access permissions but the credentials token used for the request must match the file (actual Sheets being updated) and app permissions set. – Gustavo Jun 21 '22 at 15:11
  • @Gustavo `but the credentials token used for the request must match the file (actual Sheets being updated) and app permissions set.` Can you elaborate a little? – Chirag Gupta Jun 21 '22 at 17:26
  • As far as I understood, the OAuth token is being retrieved from the “top-level script” and being used/forwarded to authenticate the call for the “sub-script” (as in `Authorization: `Bearer ${respondent.form.oAuthToken}``). Excuse the analogy, it’s like using the same key to open 2 (or more) different locks. If the following locks (scripts and/or files) are not expecting that key being used, it won’t open. TLDR; any subsequent call reusing that same OAuth key, must be allowing that user (owner of the token) access one way or another. – Gustavo Jun 22 '22 at 12:05
  • If I'm understanding correctly. You are saying that the Oauth token which I am passing is not the correct way to call appscript? `OAuth key, must be allowing that user (owner of the token) access one way or another.` But this Oauth key is not allowing that user to call the doPost method. I am missing one thing or other – Chirag Gupta Jun 22 '22 at 12:45
  • An Oauth token is generated and directly related to one user’s identity. If you are reusing a token to authorize several requests, you must make sure that the other endpoints like Scripts and Google Drive Files allow the owner of the token access. For example, within a Webapp, I capture the accessing user’s Oauth token, within this same Webapp I make a HTTP call to retrieve information from a Drive file using Drive API. I have to make sure that this Drive file allows access to the user which I’ve captured the Oauth token from the top-level Webapp. – Gustavo Jun 24 '22 at 15:21
  • yes you are correct I was able to made the request – Chirag Gupta Jun 25 '22 at 07:14

1 Answers1

0

So after struggling for 4 days I was able to send email and write to spreadsheet with users OAuth token by directly interacting with Sheets API and Gmail API instead of doing it through ScriptApp doPost method

Chirag Gupta
  • 469
  • 1
  • 7
  • 16