I'm trying to set the Gmail signature of the user executing the script (Execute the app as: "User accessing the web app"; Who has access to the app: "Anyone within my domain") using the following function:
function setSignature(signature) {
var newSig = Gmail.newSendAs();
newSig.signature = signature;
Gmail.Users.Settings.SendAs.patch(newSig, "me", Session.getActiveUser().getEmail());
}
where signature is some html. This function is called from a client-side script when a form is submitted:
google.script.run.withSuccessHandler(signatureSuccess).setSignature($("#signatureParent").html());
The user is served a web app using the HtmlService containing the form. The Gmail API has been enabled in both the Advanced Google Services window as well as the Google API Console.
My issue is that when the I try and execute the function I receive the following console error message:
The message states that the auth scope gmail.settings.basic is missing. This is despite the user authorizing the web app before any html is served:
How do I fix or work around this issue?? The strange thing is I've had this working previously so I don't know what I'm doing wrong.
EDIT:
I've noticed that if I create a simple Apps Script with just the function:
function testSet() {
var testSig = "signature";
var newSig = Gmail.newSendAs();
newSig.signature = testSig;
Gmail.Users.Settings.SendAs.patch(newSig, "me", Session.getActiveUser().getEmail());
}
And leave out everything else I get presented with these permissions to authorize:
If I click Allow it works! So clearly "Manage your basic mail settings" a.k.a. auth scope gmail.settings.basic is required and isn't being asked for in the more involved script.
So how do I force that permission to be acquired or how do I rewrite my script to get the correct set of permissions needed?
After extensive testing I've determined that this issue is a bug in Google Apps Script in determining what scopes are required.
A basic version of my script requires these scopes (File > Project Properties > Scopes):
Extending the script to interact with Google Drive modifies the scopes to this:
By dropping the required gmail.settings.basic scope a critical function within the script is denied permission to run. Infuriating.
I was also facing the same issue on nodejs application, the solution is to generate referesh token using this required scope which is mentioned in the rest api documentation find below.
rest apis documentation
you can create refresh token using required scopes on this link if you're logged in developer account.
https://developers.google.com/oauthplayground:
Related
Quite new in the apps script world. Trying to create "google form generator" with dynamically created questions/attachment.
All worked well until I noticed that whenever I create the form, users have to "sign in by google account". This was not requested so I found setRequreLogin().
Whatever I set (false or true) I receive the error: "Script error message: Exception: This operation is not supported"
I did some googleing around and it seems the solution is to have the "google suite gmail account".
I use my personal #gmail.com email.
Do anybody have got the same error?
Or is there anybody who is not having the same error using the "regular" gmail?
How I do it (because it might be a bit different than default):
I use python to execute function that is created in appscript
The apps script had to be linked to "standard GCP project" otherwise I would not be able to execute from python (external API call)
I publish the apps script "deploy as API executable" so I can execute (and pass couple of parameters) the script from Python
Thanks for help
function createForm(ordernumber,surname, country, data_list) {
var form = FormApp.create(ordernumber);
form.setTitle(ordernumber +" | " + surname)
.setDescription('anything')
.setConfirmationMessage('you are welcome...');
// .setAllowResponseEdits(true)
// .setLimitOneResponsePerUser(true)
// .requiresLogin(false);
.setRequireLogin(true);
// .setAcceptingResponses(true);
}
According to the setRequireLogin() documentation:
setRequireLogin() - Sets whether the form requires respondents to log in to an account in the same domain or a subdomain before responding. The default for new forms is false unless a domain administrator changes the default.
This feature is available only for forms created by Google Workspace users. Users of other types of Google accounts can't be required to log in.
Therefore, if you posses a gmail account, you cannot use this method.
However, since your script is creating a new form, the users who use this API executable will have to authorize this operation, hence the login screen they are receiving.
Reference
Apps Script Form Class.
I'm creating a Google Docs add-on in Google Apps Script, and some of the functionality requires that I use the Google Drive advanced service as described in https://developers.google.com/apps-script/guides/services/advanced. After enabling the advanced service, my script is now requesting the https://www.googleapis.com/auth/drive scope, which is way overbroad for what I'm trying to do - I only want to touch the files that the user is actually using this add-on with, not their whole drive! I'd much rather be using https://www.googleapis.com/auth/drive.file, which is restricted to files the user is actively using with the script.
I've tried setting the #OnlyCurrentDoc JSDoc tag as mentioned in https://developers.google.com/gsuite/add-ons/concepts/scopes#editor_add-on_scopes, but that only changes the broad https://www.googleapis.com/auth/documents scope to https://www.googleapis.com/auth/documents.currentonly - it doesn't change the Drive API scope.
Also, I've verified that the script does actually need the auth/drive scope, because when I went into the project manifest and explicitly requested auth/drive.file, I got a 404 response with API call to drive.revisions.list failed with error: File not found: 1Sj_oq93ny5q9348ncyo8934nyc at getAuthors(Code:54) at showSidebar(Code:20). That's exactly what I'd expect for a file that hasn't been "tagged" for use with this script.
Here's a very minimal gdocs addon that shows the issue:
function onOpen(e) {
var menu = DocumentApp.getUi().createAddonMenu();
menu.addItem("Get revisions", "getRevisions");
menu.addToUi();
}
function getRevisions() {
var docId = DocumentApp.getActiveDocument().getId();
Logger.log("Document id: "+docId);
var revs = Drive.Revisions.list(docId);
Logger.log("Found revisions: "+revs.items.length);
}
Again, this works just fine with the default auth/drive scope, but not with auth/drive.file.
The documentation for https://www.googleapis.com/auth/drive.file specifies that it grants "Per-file access to files created or opened by the app. File authorization is granted on a per-user basis and is revoked when the user deauthorizes the app." according to the docs at https://developers.google.com/drive/api/v2/about-auth#OAuth2Authorizing. What isn't clear is: how does Google determine what files have been "created or opened by the app", especially when it comes to editor addons? I would think that any document that has had the add-on enabled would count as "opened by the app", but I guess not. Is there any way to make this scope work?
I've written a Google Apps Script web app to allow users to change their gmail signature using a html form template via the Gmail API. This has been working for a few months but has suddenly stopped working. The console error I get is:
mae_html_user_bin_i18n_mae_html_user.js:40 Uncaught Error: Missing required scope "https://www.googleapis.com/auth/gmail.settings.basic" for modifying primary SendAs
at setSignature (Code:151) (Email Signature Generator:21)
This error refers to the use of this line of code:
Gmail.Users.Settings.SendAs.patch(newSig, "me", Session.getActiveUser().getEmail());
SendAs.patch requires the following authorization:
https://developers.google.com/gmail/api/v1/reference/users/settings/sendAs/patch
https://www.googleapis.com/auth/gmail.settings.basic
https://www.googleapis.com/auth/gmail.settings.sharing
After deleting the previously stored permissions and re-running the app the authorization window lists the following permissions:
Note that "Manage your basic email settings" (gmail.settings.basic) is missing. So, what am I doing wrong? Can I rectify this, or is this a gmail-api auth bug?
According to https://developers.google.com/apps-script/guides/services/authorization :
Apps Script determines the authorization scopes (like access your
Google Sheets files or Gmail) automatically, based on a scan of the
code. Code that is commented out can still generate an authorization
request. If a script needs authorization, you'll see one of the
authorization dialogs shown here when it is run.
Is there any way to manually request an auth permission?
use this scope:
https://mail.google.com/
to have full access. You shouldn't have problem with scopes/authorization with that.
I'm hoping to automate some HR work by running a Google App Script via the Execution API. Without getting too much into the details, I'd like to pass employee evaluation data as a parameter into the App Script. The script will then use this data to compile an "Employee Review" GDoc.
So far, I have ran a simple test App Script using the Execution API. For example, I can successfully run a simple function which logs a string or interacts with spreadsheets. So far so good.
But I run into problems when trying to write to a GDoc (which is unfortunately integral to my task). Here's my paired down script:
// TODO: Eventually, we'll pass these variables as arguments
var docId = "MY-DOC-ID";
// Find the team member review doc
var doc = DocumentApp.openById(docId);
// Replace placeholder text
var docBody = doc.getActiveSection();
docBody.replaceText('{{DATE}}', "Date set by App Script!!!");
doc.saveAndClose();
This script works when I press the "Run" button in the App Scripts web UI. But when I try to run via the Execution API, I get:
{
"error": "unauthorized_client",
"error_description": "Unauthorized client or scope in request."
}
So apparently I haven't provided the correct scope? Following the docs, I can find the necessary scope(s) in Project Properties > Scopes which says:
But when I try adding that scope, it wont work. As I said other scopes (e.g. https://www.googleapis.com/auth/spreadsheets) work just fine. Perhaps the auth/documents scope is no longer supported or there's a bug in their API?
Questions
What is the correct scope? I can see a big list here but I don't see https://www.googleapis.com/auth/documents, so?
Any other suggestions? For example, is it possible to write to a Google Doc using the Google Client API directly (i.e. without using App Scripts)?
Doh. I figured out the solution to my problem. While it was a dumb mistake, it's nevertheless worth posting as it may save others confusion in the future.
First, a little context about my setup. I'm authenticating to the Google Client API using a Service Account. Furthermore, as is common when using a service account setup, I am impersonating a user within our organization (specifically my own account).
My missing step (obvious in hindsight)...
Log into the App Script web UI as the person you are impersonating.
Manually run the script by pressing the play button
If the impersonated user has not already granted permissions to access the required scopes, you will be prompted to do so.
After granting access (specifically for the https://www.googleapis.com/auth/documents scope), my authorization error disappeared.
So the lesson: Make sure the account you are impersonating has granted access for all the scopes which your script requires.
I have some technical question about using apps script.
A third party server is sending me parameters in POST method and the request looks like this: https://script.google.com/macros/s/AKfycbyJYVLO46T1LnQKktaMrROclCOqgawcVfZaRbm_oXfJaMIYcPj8/exec?value=$postback_params_test$ (so I need to receive $postback_params_test$ as value)
I used doPost(e) function but with no success, I thing the problem is because apps script is based on client java script and it c'ant talk with server language, am I right? or there is an option to do it anyway through apps script?
my code:
function doPost(e){
var param = e.parameter.value;
var doc = SpreadsheetApp.openById("106jpepwZZWXtpO4Id45qmJovV68q_DIqpEmTQ0khf4E");
var cell = doc.getRange('a1');
cell.setValue(param);
}
8.6
Image added:
enter image description here
When deployed as a web app with settings "execute as: me" and "who has access to the app: anyone, even anonymous" your example code works.
Did you authorize the code? Before you can run it as a web app, you must run doPost() (or another function) once manually from within the script editor, so you can grant the appropriate permissions to the script.
If it's not the authorization issue, you can add a MailApp.sendemail() call to help you troubleshoot.
function doPost(e) {
MailApp.sendEmail('YOUR-EMAIL HERE','TEST doPost()',JSON.stringify(e));
This way you'll receive an email showing the raw request coming from the other server.
Be sure to re-run the script manually after adding the MailApp line so you can authorize it to send email, and update the published version.