Currently attempting to execute a GAS from a Javascript client. The GAS script is as follows:
function findAndReplace() {
var doc = DocumentApp.openById('ID_OMITTED');
}
This executes fine by pressing Play in the GAS editor, however when I try to execute from my Javascript client, I click authorise.
Then I receive a 401.
Error calling API: {
"error": {
"code": 401,
"message": "ScriptError",
"status": "UNAUTHENTICATED",
"details": [{
"@type": "type.googleapis.com/google.apps.script.v1.ExecutionError",
"errorMessage": "Authorization is required to perform that action.",
"errorType": "ScriptError"
}]
}
}
And now when I press Play in the GAS editor, I get a Action not allowed
error. I can then create a new script by copying it, press Play and it works fine. Executing the from the Javascript causes the whole the 401 and then the whole cycle repeats.
However if I execute a simple:
function test() {
return 'hello';
}
It works, and returns
Folders under your root folder:
h (0)
e (1)
l (2)
l (3)
o (4)
(The output looks like this because the program expects an array, as you can see below).
This is the Javascript client, basically copy and paste of the Javascript quickstart.
var CLIENT_ID = 'CLIENT_ID_OMITTED';
var SCOPES = ['https://www.googleapis.com/auth/drive'];
function checkAuth() {
gapi.auth.authorize(
{
'client_id': CLIENT_ID,
'scope': SCOPES.join(' '),
'immediate': true
}, handleAuthResult
);
}
function handleAuthResult(authResult) {
var authorizeDiv = document.getElementById('authorize-div');
if (authResult && !authResult.error) {
authorizeDiv.style.display = 'none';
callScriptFunction();
} else {
authorizeDiv.style.display = 'inline';
}
}
function handleAuthClick(event) {
gapi.auth.authorize(
{client_id: CLIENT_ID, scope: SCOPES, immediate: false},
handleAuthResult
);
return false;
}
function callScriptFunction() {
var scriptId = "SCRIPT_ID_OMITTED";
var request = {
'function': 'findAndReplace'
};
var op = gapi.client.request({
'root': 'https://script.googleapis.com',
'path': 'v1/scripts/' + scriptId + ':run',
'method': 'POST',
'body': request
});
op.execute(function(resp) {
if (resp.error && resp.error.status) {
appendPre('Error calling API:');
appendPre(JSON.stringify(resp, null, 2));
} else if (resp.error) {
var error = resp.error.details[0];
appendPre('Script error message: ' + error.errorMessage);
if (error.scriptStackTraceElements) {
appendPre('Script error stacktrace:');
for (var i = 0; i < error.scriptStackTraceElements.length; i++) {
var trace = error.scriptStackTraceElements[i];
appendPre('\t' + trace.function + ':' + trace.lineNumber);
}
}
} else {
var folderSet = resp.response.result;
if (Object.keys(folderSet).length === 0) {
appendPre('No folders returned!');
} else {
appendPre('Folders under your root folder:');
Object.keys(folderSet).forEach(function(id){
appendPre('\t' + folderSet[id] + ' (' + id + ')');
});
}
}
});
}
function appendPre(message) {
var pre = document.getElementById('output');
var textContent = document.createTextNode(message + '\n');
pre.appendChild(textContent);
}
I made sure to create the permissions for DocumentApp
, by copying it. Which when the copy is ran it gives me this prompt:
Which I obviously accept.
I create a new project on the script each time, enabling the Scripts API
and then creating an OAuth2 client,
copying the client id into the script. I also Deploy as API Executable
on the script, and take the script id.
What am I missing? Why is the code producing a 401? And why is the GAS script then mysteriously returning Action now allowed
in the editor only to work once its copied?
Thanks in advance.