Currently my code only modifies my signature, because when I put the email of the other person in my domain, the error: Not Found (line 9, file "Code") appears.
My current code:
function myFunction() {
var newSignature = Gmail.newSendAs();
newSignature.signature = "signature";
var listEmails = [
"leticia#domain.com"]
var updateSignature = Gmail.Users.Settings.SendAs.update(newSignature, "me", listEmails)
}
I am developing using APPS SCRIPT.
Any suggestions for me to be able to change the signature of someone else in my domain?
To change other people Gmail settings in your domain you'll need to be a domain Admin, then create a service account with domain-wide authority, then whitelist it in the Admin Console. Then use said service account and authentication token generated to authenticate your requests to the Gmail API.
This built-in Apps Script Gmail integration was not made for that use-case. The intended usage is to setup your own settings, or individual users that explicitly authorize your application to run on their behalf. This sendAs is there because one might have multiple Gmail signatures, depending on their selected send-as/from alias.
Note that simply authorizing an script with your GSuite admin account won't allow to the script to perform domain-wide operations. That'd be too dangerous, therefore the somewhat convoluted service-account setup is required.
Link to the relevant documentation
Related
Context:
I have a service account that updates a Google Sheet on a daily basis and I want to add functionalities to the Sheet by extending it with Apps Script. I developed the script with my own personal account (same I used to create the service account) and it seems I can't access the service-account information when it's making changes to the Spreadsheet. What I mean is that I set up a trigger for changes on the spreadsheet but when I try to verify who made the changes I get a blank string.
Quoting the docs:
The circumstances in which the email address is available vary: for example, the user's email address is not available in any context that allows a script to run without that user's authorization, like a simple onOpen(e) or onEdit(e) trigger, a custom function in Google Sheets
How do I fix this? Is there a different design I should use?
Service accounts are not real users, this can be noted in this documentation. Please note the following:
Service accounts do not belong to your Google Workspace domain, unlike user accounts. If you share Google Workspace assets, like docs or events, with your entire Google Workspace domain, they are not shared with service accounts. Similarly, Google Workspace assets created by a service account are not created in your Google Workspace domain. As a result, your Google Workspace and Cloud Identity admins can't own or manage these assets.
Service accounts do not have passwords, and cannot log in via browsers or cookies.
The triggers that are setup on your script would require them to be logged in to the browser in order to capture the email address, a service account can't do that so that would be the reason why you are unable to gather this information.
We're using Gsuite Enterprise/Piazzaweb at work. I'm using basic scripts to get information from my own mailbox, no problems there. But I want to pull information from a couple of shared mailboxes in which I'm delegated. For example billing#mycompany.com. But I can't find any information regarding this and if it's even possible to reach a delegated mailbox with App script.
I've been sending e-mails from the delegated mailbox with app script without any problem.
Hopefully somebody can tell me more about this.
Thanks in advance.
In order to use Service Accounts in Apps Script, you have to do the following:
Build the OAuth service for your Service Account with the following library: OAuth2 for Apps Script.
Call the corresponding API by making the corresponding HTTP request via UrlFetchApp.fetch(url, params).
1. Build the OAuth service:
Once you have added the specified library to your script, you have to do this in order to build the OAuth service with delegated credentials, :
const PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----\nxxxxxxxxxxxxxxxxxxxxx\n-----END PRIVATE KEY-----\n';
const CLIENT_EMAIL = 'xxxxxxxxxxxxxxxxxxxxx.iam.gserviceaccount.com'; // Service account email
const USER_EMAIL = 'email_address_to_impersonate'; // Account to impersonate
const SCOPE = 'https://www.googleapis.com/auth/gmail.readonly' // Change according to your preferences
function getGmailService() {
return OAuth2.createService('Gmail: ' + USER_EMAIL)
.setTokenUrl('https://oauth2.googleapis.com/token')
.setPrivateKey(PRIVATE_KEY)
.setIssuer(CLIENT_EMAIL)
.setSubject(USER_EMAIL)
.setPropertyStore(PropertiesService.getScriptProperties())
.setScope(SCOPE);
}
Where PRIVATE_KEY refers to the key found in the Service Account JSON credentials, CLIENT_EMAIL is the Service Account email, and USER_EMAIL refers to the email address whose INBOX you want to access.
It's important to note that SCOPE should be one of the scopes you specified when delegating authority.
2. Access the API:
Once the OAuth service is built, you use it to retrieve an access token with which you can access the desired resource. Of course, GmailApp service and the Advanced Gmail Service won't be of use here, since you have to access the API using the service you just built. Because of this, the way to access the API will be making the corresponding HTTP request via UrlFetch.
I'm not sure what you want to do exactly, and the exact request would depend on that, but for example, if you wanted to list the messages from the impersonated user, you could do this:
function readInbox() {
var service = getGmailService();
console.log(service.getAccessToken());
if (service.hasAccess()) {
var url = 'https://www.googleapis.com/gmail/v1/users/me/messages';
var response = UrlFetchApp.fetch(url, {
headers: {
Authorization: 'Bearer ' + service.getAccessToken()
}
});
var result = JSON.parse(response.getContentText());
console.log(JSON.stringify(result, null, 2));
}
}
Note:
I'm assuming here that you have already created a Service Account and granted domain-wide authority, and that your issue was just using it in Apps Script.
In Gmail API Reference, check the HTTP request, Parameters and Request body sections corresponding to the API method you want to use, if you need information on how to make the HTTP request (URL to access, HTTP method, request parameters, etc.).
Reference:
OAuth2 for Apps Script
Apps Script OAuth2 > GoogleServiceAccount.gs
You cant use delegation from apps script as apps script doesn't support using service accounts. You would need to make an oauth2 flow and have that user authorize it. Answer provided by #Zig Mandel
On top of what #ZigMandel said: unless this is a google domains or google for work account to my knowledge you cant use service accounts with gmail. you need to use Oauth2. Answer provided by #DalmTo
I don't know if this would solve the problem, but a feature request has been placed on Google Cloud Community and on Google Issue Tracker to enable access to Gmail Apps Script add-ons from delegated mailboxes.
The more upvotes, the more chances Google seriously looks at this issue ;).
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:
I want to authorize non-admin users to use AdminDirectory (part of Google apps Admin SDK) as a part of a google apps script. Basically I want the users to get a list of other users' full names based on their user name.
I understand I can do this using OAuth2 but I cannot find examples of Google apps script-code for Admin SDK-AdminDirectory.
I have created a service account and have and have my Client ID and key ID. What do I need to do next? I found this https://developers.google.com/api-client-library/javascript/features/authentication but I can't figure out how to get the authorization to work.
Here is a minimal version of my script: (It will produce the full name of user edutett0707#edu.kristinehamn.se for authorized users)
function grupplistor() {
var userinfo = AdminDirectory.Users.get("edutett0707#edu.kristinehamn.se");
Logger.log ([userinfo.name.fullName]);
}
Try:
function grupplistor() {
var userinfo = AdminDirectory.Users.get({
userKey: "edutett0707#edu.kristinehamn.se",
viewType: "domain_public"});
Logger.log ([userinfo.name.fullName]);
}
viewType domain_public tells the api to return information about the user that's shared to all other users.
Jay
You can try using creating the service account and its credentials.
You need to create a service account and its credentials. During this procedure you need to gather information that will be used later for the Google Apps domain-wide delegation of authority and in your code to authorize with your service account. The three items you need are your service account’s:
Client ID.
Private key file.
Email address.
Note: Only users with access to the Admin APIs can access the Admin SDK Directory API, therefore your service account needs to impersonate one of those users to access the Admin SDK Directory API.
Source:
https://github.com/googlesamples/apps-script-oauth2
https://github.com/Spencer-Easton/Apps-Script-Drive-Service-Account-Library
Hope this helps
The following code works before I publish the G docs add-on. However the released version obtained via Google Docs Add-on/my_add-on doesn't work.
What concepts am I missing here?
onOpen(){
var email = Session.getActiveUser().getEmail();
}
The documentation explicitly states that:
If security policies do not allow access to the user's identity,
User.getEmail() returns a blank string. The circumstances in which the
email address is available vary: for example, the user's email address
is not available in any context that allows a script to run without
that user's authorization, like a simple onOpen(e) or onEdit(e)
trigger, a custom function in Google Sheets, or a web app deployed to
"execute as me" (that is, authorized by the developer instead of the
user). However, these restrictions generally do not apply if the
developer and the user belong to the same Google Apps for Business
domain.
So presumably your script fails to meet those conditions.
You need to run a function that the user has to authorize first in order to get their email.