I'm currently developing an Editor Add-on for Google Sheets using Apps Script. There's an onOpen function that sets up the menu items.
I also have a CONFIG variable in the root (not in any function) like this:
const CONFIG = {}
function setProperties_(){
CONFIG.tmpSheetId = PropertiesService.getScriptProperties().getProperty('TMP_SHEET_ID');
}
setProperties_();
If I run any functions from within the script editor, everything runs fine. No issues. However, when I do a test deployment I get the error below from the moment the onOpen() runs:
You do not have permission to call getScriptProperties
I've tried adding various script scopes from here but nothing works.
When you first install the add-on (the entry for the add-on becomes visible in the sheet menu), it runs in AuthMode.NONE that allows you to inspect only the current user's locale. Please refer to the table here Google Add-On Authorization Lifecycle
As Cooper pointed out, calling setProperties_() in global scope occurs before your add-on is authorized by the user. Move the function call to a nested function and make sure you are through with the authorization flow first.
Related
I have google-sheet which is utilizing the app-script to do somethings within the sheet itself, (i.e. it is not doing any operation on the google-drive folders). But when I share the sheet with someone else (lets call that person client) then, when that person attempts to run the script, there is prompt which asks to grant app-script the access to the his/her google drive. Even though the script is not performing any operations on the client's google drive.
Is there some way in which the client doesn't see the "Provide access to your google drive" - prompt? I am not even doing anything on the google drive.
No there is no way to suppress the message
The reason for this is because Apps Script, every time you run one function, even if the function were a simple console.log(""), the whole script is compiled and checked. This is why you can run this function from the script editor with not problems.
const globalVar = "Hello"
function test(){
console.log(globalVar)
}
It is for this reason, that all potential OAuth scopes must be approved before using any part of the script, it is for security as much as anything.
You can set explicit scopes if you want, but if you don't want any OAuth scope authorization, then you will need to remove all references to Drive methods from the script.
Reference
Scopes
I would like to read the Active spreadsheet and add menu items based on that. Below is the code in OnOpen(e) trigger:
function onOpen(e) {
var sheet = SpreadsheetApp.getActive().getSheetByName(sheetName);
//add menus based on values of sheet
}
I am getting below exception:
[Exception: You do not have permission to perform that action.]
I have gone through the documentation and found that the AuthMode is None in OnOpen trigger which does not allow access to any services that require authorization.
Please suggest if there is any other way to accomplish my task.
Thanks.
It's not possible to access the spreadsheet unless the owner or editor of the spreadsheet uses the add-on in that spreadsheet. As written in the official document,
However, because an editor add-on automatically runs its onOpen(e) function to add menu items when a document opens, the behavior above adds some complexity to Apps Script's authorization rules. After all, users wouldn't be comfortable with an add-on accessing personal data every time they open a document.
The add-on needs to be enabled for the document for the addon to get access to the document. When it's enabled, onOpen() runs in AuthMode.LIMITED, where you get access to the bound document. This "enabled" state is caused by
Getting an add-on from the store while using that document, or
Using a previously installed add-on in that document
In all other cases, add on runs in AuthMode.NONE. In this mode, You are only able to add menu items without access to any data including the bound spreadsheet. Add Menu items to request access to such data. Then, after getting AuthMode.FULL, the rest of the workflow can be done.
References:
The complete lifecycle
I have a spreadsheet that is editable by everyone with a protected sheet with some ranges unprotected.
I want cells that can be altered by a script run by any user (from a menu), but not manually.
When I run the script not as the owner it gives an error message when I try to temporarily remove the protection.
There seems to be no easy way to do this, because functions run from the menu is always executed as "user at the keyboard".
One workaround is to publish a Web App to always "Execute as" Owner. This web app will then write to protected ranges on doPost(). The function linked to Menu UI will then use UrlFetch to POST to the published Web App. You can also use some basic authentication with a password/randomly generated numbers to reject requests from outside your script.
Also, If you don't trust editors not to mess with your bound script, It's better to publish it as a private add-on, where the source code is not easily accessible.
Problem: When I run the script, Google tells me,
You do not have permission to call openById
I had copied a script from another one of my Google spreadsheets and changed the target_ssKey variable's cell reference and created properly-sized Named Ranges in both the Source and Target spreadsheets.
Google Apps Script documentation says nothing about reasons why it might not be working:
https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app#openById%28String%29
Another Google Apps Script documentation says that it should work for me because I invoke it from a custom menu:
https://developers.google.com/apps-script/guides/sheets/functions#using_apps_script_services
The second link above says:
If your custom function throws the error message You do not have
permission to call X service., the service requires user authorization
and thus cannot be used in a custom function.
To use a service other than those listed above, create a custom menu
that runs an Apps Script function instead of writing a custom
function. A function that is triggered from a menu will ask the user
for authorization if necessary and can consequently use all Apps
Script services.
I tried putting the function into a "Custom Functions" project and then into an "Add-on" project, but still got the same error message.
Any ideas on what I am doing wrong and how to make this work?
Here is my exact code:
function exportData_SStoSS() {
// Get the source data.
var source_ss = SpreadsheetApp.getActiveSpreadsheet();
var data = source_ss.getRangeByName("exportData").getValues();
// Identify the target.
var controls_sh = source_ss.getSheetByName("Controls");
var target_ssKey = controls_sh.getRange('C2').getValue();
var target_ss = SpreadsheetApp.openById(target_ssKey);
// Paste the data to the target.
target_ss.getRangeByName("importData").setValues(data);
};
I thought that I would throw in a similar issue that I had which brought me to this question, where I received the error You don't have permission to call by openById.
In my case I was trying to call functions from translate.gs which I copied from this example:
https://developers.google.com/apps-script/quickstart/docs
Note that at the top of translate.gs
/**
* #OnlyCurrentDoc
*
* The above comment directs Apps Script to limit the scope of file
* access for this add-on. It specifies that this add-on will only
* attempt to read or modify the files in which the add-on is used,
* and not all of the user's files. The authorization request message
* presented to users will reflect this limited scope.
*/
The culprit here is the #OnlyCurrentDoc comment. See here for reference:
https://developers.google.com/apps-script/guides/services/authorization
Removing #OnlyCurrentDoc fixed this issue for me
I could resolved this issue with this autorization guide of google developers.
https://developers.google.com/apps-script/concepts/scopes#setting_explicit_scopes
This entry It's necesary in json file.
"oauthScopes": [
"https://www.googleapis.com/auth/spreadsheets.readonly",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/spreadsheets"
],
I found this official note which I believe clears up what caused the issue.
If your function is a custom function, that is one which can be used like a regular spreadsheet function in the sheet itself, then it has limited access to things and cannot open other spreadsheets.
The same script can however open other spreadsheets from a menu button or similar.
Link: Documentation at developers.google.com
The method openById can be called from a "Blank Project" but not a "Custom Functions in Sheets" nor a "Google Sheets Add-on" project.
I thought a "Blank Project" would create a project that was not connected to my spreadsheet, but I was wrong. The Blank Project is connected to my spreadsheet. The other types of projects that I tried to use seem to be limited-scope versions of script projects, not able to carry out some GAS methods.
Had this same issue and came to share my solution. In my case I had two spreadsheets, call them A and B. Both used scripts bound to each respective spreadsheet. Spreadsheet B was able to write data to a tab of spreadsheet A. But Spreadsheet A kept getting the "You do not have permission to call openById" error when trying to read from spreadsheet B. I then tried adding it as a custom menu item but still the same issue.
The solution in my case turned out to be really simple. I created a new unbound script in script.google.com that calls both spreadsheets using openById. The first time running put a smile on my face as it asked for authorization. Thereafter smooth sailing.
I followed the app script guide to create a menu for my spreadsheet.
I was tested during development in the spreadsheet running it by going to:
Tools -> Script manager...
But now I want to permanently add it to the spreadsheet, but I don't know hot to deploy it.
I deployed it as a webapp, but when I click the test link i get:
Script function not found: doGet
I can not find documentation to complete that doGet function.
Any help on the last step to use my first Google App Script?
if the function that create your menu is called onOpen(e) it should automatically do the job for you when the document is opened, you don't need to publish the app or anything like that.
But in order to be executed the onOpen function must not call personnal data for the user this function onOpen (when triggered automatically, when you open the sheet) has limited rights:
in the doc https://developers.google.com/apps-script/guides/menus,
it say:
Warning: Note that the add-on menu sample above compares the
e.authMode property to values from the ScriptApp.AuthMode enum. This
is because an add-on that has not been used in the current document
runs its onOpen(e) function with severe restrictions, as explained in
the guide to the add-on authorization lifecycle. If your published
add-on fails to add its menu items, look in the browser's JavaScript
console to see if an error was thrown, then examine your script to see
whether the onOpen(e) function or global variables call services that
aren't allowed in AuthMode.NONE.