I am new to Apps Script and trying to understand the basics of running/triggering a script in one account using another. With just caveat: I'd like to run the script with the user accessing the script instead of the user owning the script -- in order to assign the run time to the user accessing.
I am however running into the following issues.
Starting with a test SpreadSheet with Sharing set to Anyone With Link can edit and the following code in the script project page:
function doPost(e){
var sheet = SpreadsheetApp.openById('1tWV6ELJEGkWkSXvdf9kQemvH-tDVTx0od4JHht2ZBeU');
var tab = sheet.getSheetByName('ref');
tab.getRange(1,1).setValue(new Date());
return ContentService.createTextOutput(0)
}
function doGet(e){
return doPost(e)
}
and having published the project as a Web App with execution set to user accessing and access enabled for Anyone. Entering the following link in the browser manually fills cell A1 with current time and the page displaying '0', as intended,
https://script.google.com/macros/s/AKfycbwNhYg1BRKi38pNf_z0peGuYt6gsqvauCvo-eiGgCYJJk4QDpjm/exec
IF I enter the link while still signed in with the account that created the test SpreadSheet.
If I enter the link with a different browser without GSuite log-in, I am required to sign in, which is also as expected. After all, a G Suite account is required to run the script per deployment of the Web App .
However, when I tried triggering the script using a different GSuite account and Apps Script project, I still ran into the sign-in page and also other issues. Out of
function test1(){
const scriptURL='https://script.google.com/macros/s/AKfycbwNhYg1BRKi38pNf_z0peGuYt6gsqvauCvo-eiGgCYJJk4QDpjm/exec';
var response = UrlFetchApp.fetch(scriptURL)
Logger.log(response.getContentText())
}
function test2(){
const scriptURL='https://script.google.com/macros/s/AKfycbxay75fTBt3doTyMFUPK0-GpK9hMZ4hVkYdiwYUBMhPfEN6hUJH/exec';
var response = UrlFetchApp.fetch(scriptURL, {
method:'POST',
payload:'nothing'
});
Logger.log(response.getContentText())
}
function test3() {
var sheet = SpreadsheetApp.openById('AKfycbwNhYg1BRKi38pNf_z0peGuYt6gsqvauCvo-eiGgCYJJk4QDpjm');
Logger.log(sheet.getName());
}
function test4() {
var token = ScriptApp.getOAuthToken();
const scriptURL='https://script.google.com/macros/s/AKfycbxay75fTBt3doTyMFUPK0-GpK9hMZ4hVkYdiwYUBMhPfEN6hUJH/exec';
var response = UrlFetchApp.fetch(scriptURL, {
headers: {Authorization:'Bearer '+ token},
method:'GET',
payload:'nothing'
});
Logger.log(response.getContentText())
}
test1()
produces a long body of text in Log starting with
Logging output too large. Truncating output.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta content="width=300, initial-scale=1" name="viewport">
<meta name="google-site-verification" content="LrdTUW9psUAMbh4Ia074-BPEVmcpBxF6Gwf0MSgQXZs">
<title>Sign in - Google Accounts</title>
<style>
and test2()
returns an eror
Exception: Request failed for https://script.google.com returned code 401. Truncated server response: <!DOCTYPE html><html lang="en"><head><meta name="description" content="Web word processing, presentations and spreadsheets"><meta name="viewport" c... (use muteHttpExceptions option to examine full response)
at test2(Code:23:30)
Neither test triggered the script in doPost(e)
since the cell A1 was not updated.
test1()
seems to encounter the sign-in page. Yet, at the same time, test1()
is executed via a sign-in G Suite account.
It may also be worth noting that that test3()
is able to access the Google SpreadSheet file in question. I also tried calling ScriptApp.getOAuthToken()
because why not. test4()
has the same response as test1()
.
I don't know where to begin diagnosing with the error encountered in test2()
.
How do I get around the sign-in page?
In particular, is there a way to make the script accessible by any other GSuite account with access permission to the Google SpreadSheet in question and executed by user accessing as opposed to user owning the SpreadSheet?
What am I doing wrong with the POST version?
Any help is apprecriated!
From your question, I understood your situation as follows.
1tWV6ELJEGkWkSXvdf9kQemvH-tDVTx0od4JHht2ZBeU
.Anyone with the link
of editor
.Execute the app as: User accessing the web apps
and Who has access to the app: Anyone
.This answer supposes my above understanding. So when my understanding is not correct, please tell me.
UrlFetchApp
, when payload:'nothing'
is used, it requests as POST method even when method:'GET'
is used. Please be careful this.https://www.googleapis.com/auth/spreadsheets
. In this case, at first, it is required to authorize the scope by own browser (each user's browser). When this is not done, even when the script and the access token with the scopes of client side are correct, an error of Authorization needed
occurs. Please be careful this. It seems that this is the current specification.test1
to test4
) of your client side is the script in your question, the scopes are https://www.googleapis.com/auth/script.external_request
and https://www.googleapis.com/auth/spreadsheets
. I think that the scope is not enough for requesting the Web Apps. In this case, for example, please add // DriveApp.getFiles()
to the script editor. By this, the scope of https://www.googleapis.com/auth/drive.readonly
is automatically added by the script editor and this scope can be used for requesting to Web Apps. Also, you can use the scope of https://www.googleapis.com/auth/drive
.
https://www.googleapis.com/auth/script.external_request
and https://www.googleapis.com/auth/spreadsheets
, an error of Unauthorized
occurs.When above points are reflected to your situation, it becomes as follows.
In this case, I think that your settings can be used. Please redeploy the Web Apps as new version just in case. And please confirm the URL of Web Apps again.
Please access to https://script.google.com/macros/s/AKfycbxay75fTBt3doTyMFUPK0-GpK9hMZ4hVkYdiwYUBMhPfEN6hUJH/exec
using own browser (user side.) And please authorize the scopes of Web Apps.
I would like to propose to modify test4()
of your script as follows.
function test4() {
var token = ScriptApp.getOAuthToken();
const scriptURL='https://script.google.com/macros/s/AKfycbxay75fTBt3doTyMFUPK0-GpK9hMZ4hVkYdiwYUBMhPfEN6hUJH/exec';
var response = UrlFetchApp.fetch(scriptURL, {
headers: {Authorization:'Bearer '+ token},
method: 'GET',
// payload:'nothing',
muteHttpExceptions: true
});
Logger.log(response.getContentText())
// DriveApp.getFiles() // This is used for adding a scope of https://www.googleapis.com/auth/drive.readonly. This is used for requesting to Web Apps.
}
Please run test4()
. By this, 0
is returned from Web Apps and you can see it at the log.