I am sending http request from script editor in google spreadsheets, but I keep getting the following error message:
`Google Apps Script: You do not have permission to call UrlFetchApp.fetch. Required permissions: https://www.googleapis.com/auth/script.external_request`
I am using onEdit function:
function onEdit(e){
var ui = SpreadsheetApp.getUi();
var response = UrlFetchApp.fetch('http://www.eur-api.idomoo.com/');
Logger.log(response.getContentText());
}
I don't know Why am I getting this error? and I also gave permission to script.external_request scope, Any help would be appreciated.
onEdit is invoked by a Simple Trigger when a user changes a value in a spreadsheet.
However, simple triggers cannot access services that require authorization, such as UrlFetchApp.fetch. See the Google Apps Script guide
What you can do is to simply rename the function onEdit to something else, such as atEdit, so as to remove the simple trigger. Then follow the Current project's triggers menu...
and add a trigger to be called in the event of On edit.
And when creating the trigger, you will follow the Wizard to grant your apps script permission to connect to an external service.
There are two ways to solve this
I. Update your manifest and add the line "https://www.googleapis.com/auth/script.external_request" to oauthScopes
{
"timeZone": "Europe/Moscow",
"oauthScopes": [
...
"https://www.googleapis.com/auth/script.external_request"
],
"dependencies": {
...
},
"exceptionLogging": "STACKDRIVER"
}
II. Or remove oauthScopes key from your manifest totally
You can find how to edit the manifest here Manifests
I know its an old thread, but I find it weird of having to rename the method to something else, e.g. from onEdit to onEditHandler just to make it work. It turns out that I can make it work by:
Remove the trigger.
Re-add the trigger.
This is possible probably due to previously the handler doesn't have the fetch url, therefore it doesn't have to ask for authorization to access external request. Once it is re-added, then it has the proper authorization because you are asked to re-authorize the handler.
You'll need to authorize your script to access the external_request service. If you're the owner of the project, you should be able to grant access by running and confirming with the oauth page.
Read more about authentification here: https://developers.google.com/apps-script/guides/services/authorization
I experienced this error after adding the onEdit function without also explicitly adding a trigger. This was resolved by adding an onEdit trigger that calls the function. Triggers -> Add Trigger, On edit event type.
Try changing the link https.
Looking at their api documentation:
API Endpoints
Idomoo’s API 2.0 has several endpoints all starting from one of several roots, depending on the territory in which you want your data sent to and processed:
USA https://usa-api.idomoo.com/api/v2
EU https://eur-api.idomoo.com/api/v2
You should
Remove Current triggers
and then
create new trigger by selecting event "OnEdit"
Related
As far as I've read google app script is supposed to show you a prompt to review permissions automatically if you have not authorized your app yet. However this is not happening and I also cannot find a way to manually trigger such a prompt that can be used within onOpen(e).
What I would like to achieve is my app prompting users to review permissions when they have not authorized the app yet.
What I have tried:
Letting GAS automatically detect used scopes.
Manually setting scopes using the appscript.json file.
Using Ui.showModalDialog() and ScriptApp.getAuthorizationInfo().getAuthorizationUrl() to manually guide the user to permissions. However, this results in the error:
Google Apps Script: Exception: You do not have permission to call Ui.showModalDialog.
Required permissions: https://www.googleapis.com/auth/script.container.ui
Issue:
You are using a simple trigger (onOpen). Simple triggers cannot access services that require authorization.
Solution:
Install your trigger, either manually, following these steps, or programmatically, executing this:
function installTrigger() {
ScriptApp.newTrigger("yourOnOpenFunction") // Don't call it onOpen
.forSpreadsheet(SpreadsheetApp.getActive())
.onOpen()
.create();
}
The authorization is given when installing the trigger.
Note:
The installed trigger will run under the account who installed it. Therefore, this is not a good approach if the actions made by the trigger depend on who is executing it, and I'd suggest displaying the dialog through other means, like clicking a button, or similar.
Reference:
Simple triggers: Restrictions
I'm new to GAS and I struggle with the permission system.
I'm a normal Google drive user and I started a spreadsheet and tried to add some code to it. My code is working, but only if I'm in the code editor. I want to use the onEdit() function so it's important for me that it works within the sheet as well. When I ran my code in the editor for the first time it opened a new window where I needed to enter my credentials to allow the script, then it worked. If I do some changes to a cell in my sheet and the onEdit() function is triggered I receive an error message that says something like this(translated):
Exception: You are not permitted to call UrlFetchApp.fetch. Required permission: https://www.googleapis.com/auth/script.external_request
In the editor I displayed the manifest file and added the permission to the oauthScopes but within the sheet I still receive the message. This is how my code looks like (simplified):
function onEdit(e)
{
var data = {
'key1': 'value1',
'key2': 'value2'
};
var options = {
'method' : 'post',
'contentType': 'application/json',
'payload' : JSON.stringify(data)
};
try{
var response = UrlFetchApp.fetch('https://a-working-url.com', options); //error happening in this line
//some more data wizardry
}catch(error)
{
Browser.msgBox(error)
}
}
Any ideas how I can open this permission screen in my sheet or any hints how to solve it in a different way? I want to create a sheet with some code running in the back online. I want to share the sheet with some friends, tried it with Excel and VBA before until I realized that it's not working with Excel Online, so I switched to GAS.
onEdit(), like all simple triggers, is bound by the following restrictions (see official documentation):
The script must be bound to a Google Sheets, Slides, Docs, or Forms file, or else be an add-on that extends one of those
applications.
They do not run if a file is opened in read-only (view or comment) mode.
Script executions and API requests do not cause triggers to run. For example, calling Range.setValue() to edit a cell does not cause
the spreadsheet's onEdit trigger to run.
They cannot access services that require authorization. For example, a simple trigger cannot send an email because the Gmail
service requires authorization, but a simple trigger can translate
a phrase with the Language service, which is anonymous.
They can modify the file they are bound to, but cannot access other files because that would require authorization.
They may or may not be able to determine the identity of the current user, depending on a complex set of security restrictions.
They cannot run for longer than 30 seconds.
In certain circumstances, editor add-ons run their onOpen(e) and onEdit(e) simple triggers in a no-authorization mode that presents some additional complications. For more information, see the guide
to the add-on authorization lifecycle.
Simple triggers are subject to Apps Script trigger quota limits.
The ones highlighted in bold apply to your question.
Basically, it boils down to this - UrlFetchApp.fetch() is a service that requires authorization, so you won't be able to execute it from your onEdit(e) trigger, even if you have its associated scope set in your manifest file.
Use installable trigger instead and write your own "onEdit" function (with a different name) that you bind to your installable trigger.
https://developers.google.com/apps-script/guides/triggers/installable#g_suite_application_triggers
This solved the issue for me.
I am trying to create a trigger for a Google Form to send the responses to an API endpoint when the form is submitted, but even before I get to the API call, I am having trouble accessing the form responses with a trigger. I have the below in my code.gs but I am getting the following error message:
You do not have permission to call Form.getResponses
function onFormSubmit(e) {
Logger.log(e)
Logger.log(e.source.getResponses())
}
The form, the trigger and the script were all made by the same account. There are a lot of posts about issues similar to this, but I have not found a simple, clear answer on how to solve it.
I am not exactly sure why, but I deleted the trigger and recreated it and now it works fine. One thing I noticed, was there was a pop-up (which was originally blocked by Chrome) asking for permissions. I allowed the permissions - perhaps that was the blocker, although I am fairly certain I did that the first time as well.
Before deleting and recreating the script, I did add:
"oauthScopes": [
"https://www.googleapis.com/auth/forms",
"https://www.googleapis.com/auth/forms.currentonly"
]
to the appsscripts.json in the Google Scripts project. Remember to "View -> Show Manifests File" if you can't see it
Why is my add-on asking for this permission? Tried looking through the docs and couldn't find anything.
As far as I know, my application doesn't run when the user isn't present! (It requires the user to select a range in Google Sheets, press a button in custom UI, and call an external API). Are there any tips for what I should look for to find the offending code or configuration that's triggering such a permission request?
How about this answer?
1. Quick confirming
Allow this application to run when you are not present
When above authorization message is displayed, it means that the methods which use the scope of https://www.googleapis.com/auth/script.scriptapp is used in the project. You can see the scope in the project at File -> Project properties -> Scopes. The methods which need such scope are in especially ScriptApp. When getProjectTriggers(), getUserTriggers(), deleteTrigger(), newTrigger() are used in the project, such scope is automatically detected.
If you have already noticed that such methods are used in your project, this section might be an answer.
2. Investigating
If you have already noticed that such methods are NOT used in your project, please check this section.
When the GAS project is saved, the scopes which are used in the project are detected by the automatic detection. This automatic detection also works for commented out methods. Furthermore, even when each word is separated, the word is detected, because the automatic detection works for the special words, as follows.
ScriptApp.getOAuthToken()
// .... do something
// newTrigger <--- this is put as a comment
When above script is in the project, the automatic detection says that https://www.googleapis.com/auth/script.scriptapp is required. But in this sample, ScriptApp.getOAuthToken() doesn't require https://www.googleapis.com/auth/script.scriptapp.
If you want to confirm whether the authorization which uses such scope is required to run your script, you can do it using "Manifests". Recently, "Manifests" was added to GAS project. Using "Manifests", the automatic detection of scopes can be stopped. By this, you can know whether the detected scopes are actually required to the project. In order to confirm this, please do the following flow.
On the script editor.
File -> Project properties -> Scopes
Copy current scopes.
View -> Show Manifest file
appsscript.json appears.
Please add the copied scopes to appsscript.json as follows.
The default appsscript.json is
{
"timeZone": "### your timezone ###",
"dependencies": {
},
"exceptionLogging": "STACKDRIVER"
}
For this, please add the copied scopes as follows. And please save this.
{
"timeZone": "### your timezone ###",
"dependencies": {
},
"exceptionLogging": "STACKDRIVER",
"oauthScopes": [
"https://www.googleapis.com/auth/script.scriptapp",
"scope2",
"scope3",
...
]
}
After added oauthScopes, at first, please confirm whether your script works fine. And then, remove https://www.googleapis.com/auth/script.scriptapp from oauthScopes, and run again. At this time, if there is an error, it is indicated that the errored line uses the scope of https://www.googleapis.com/auth/script.scriptapp.
Note :
Also there is a possibility that the authorization Allow this application to run when you are not present is not related to https://www.googleapis.com/auth/script.scriptapp.
When you see the scopes in your project, if https://www.googleapis.com/auth/script.scriptapp is not included, after added the scopes to appsscript.json, please confirm the error line by removing scopes one by one.
References :
ScriptApp
Manifests
If this was not useful for you, I'm sorry.
I had this problem with my add-on, and realised the script.scriptapp scope was being automatically detected because I had implemented the onOpen and onInstall methods (to install the add-on menu items).
If you want to see the scopes detected for your google app scripts, in the Script Editor, select Project Properties and then the Scopes tab.
This code is directly from the Google Add-on's tutorial - and it's a pity it causes such a scary looking permission request.
/**
* Creates a menu entry in the Google Docs UI when the document is opened.
* This method is only used by the regular add-on, and is never called by
* the mobile add-on version.
*
* #param {object} e The event parameter for a simple onOpen trggr. To
* determine which authorization mode (ScriptApp.AuthMode) the trggr is
* running in, inspect e.authMode.
*/
function onOpen(e) {
DocumentApp.getUi().createAddonMenu()
.addItem('Start', 'showSidebar')
.addToUi();
}
/**
* Runs when the add-on is installed.
* This method is only used by the regular add-on, and is never called by
* the mobile add-on version.
*
* #param {object} e The event parameter for a simple onInstall trggr. To
* determine which authorization mode (ScriptApp.AuthMode) the trggr is
* running in, inspect e.authMode. (In practice, onInstall trggrs always
* run in AuthMode.FULL, but onOpen may be AuthMode.LIMITED or
* AuthMode.NONE.)
*/
function onInstall(e) {
onOpen(e);
}
I had the same issue in one of Addons. The problem was that the default Google template has some comments that will trigger this scope to be detected.
#param {object} e The event parameter for a simple onOpen trigger. To
determine which authorization mode (ScriptApp.AuthMode) the trigger is
running in, inspect e.authMode.
#param {object} e The event parameter for a simple onInstall trigger. To
determine which authorization mode (ScriptApp.AuthMode) the trigger is
running in, inspect e.authMode. (In practice, onInstall triggers always
run in AuthMode.FULL, but onOpen triggers may be AuthMode.LIMITED or
AuthMode.NONE.)
If you are sure that you are not using this scope anywhere else in your project (using programmatic triggers, using ScriptApp etc), then remove these comments and the scope will be removed.
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.