onEdit trigger doesn't catch current user - google-apps-script

I'm trying to build a simple log for sheets that makes use of cell notes.
Somehow i can't include the email of the user who triggers the onEdit-event.
function onEdit(e){
var email = Session.getActiveUser().getEmail();
var date = String(Utilities.formatDate(new Date(), 'Europe/Berlin', 'HH:mm dd/MM/yy'));
var range = e.range;
range.setNote(email + " # " + date);
}
The note appears on the cell but the email is empty. Could that have to do with missing permissions? I assume if something would be wrong with my code the note wouldn't appear at all on the edited cell in sheets...

Here's what Google documentation says about the Session class
The Session class provides access to session information, such as the
user's email address (in some circumstances) and language setting.
In regards to 'getActiveUser()' method, it states
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 G Suite domain.
Because you use the simple trigger - onEdit() - the code will not execute unless explicitly authorized by the user. For installable triggers, that would mean executing the function manually from the script editor.
You can publish the project as a sheets add-on. In this case, users will be asked to grant permissions declared in the add-on manifest.
More info https://developers.google.com/apps-script/reference/base/session

Related

What is the best practice for accessing users email addresses for Add Ons on Google Products

I'm building an add on that needs to check how many units a customer has left. This code works for me as the developer however, it doesn't work when users actually install the application.
// When someone opens the sheet for the first time
function onOpen(e) {
var ui = SpreadsheetApp.getUi()
.createAddonMenu()
.addItem('SMS', 'sms')
.addItem('EMAIL', 'email')
.addItem('SMS and EMAIL', 'emailAndSMS')
.addToUi();
}
// The function for the SMS Side Bar
// It is here I run the code for getting the users email address.
// Nothing is logged to the console at all.
function sms() {
var html = HtmlService.createHtmlOutputFromFile('sms').setTitle('Heartbeat SMS');
SpreadsheetApp.getUi().showSidebar(html);
var userEmail = Session.getActiveUser().getEmail();
Logger.log(userEmail); // Nothing gets logged to the console.
}
I expected to see users Email addresses being logged, however I get an empty string back
According to the documentation on getActiveUser():
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).
So having your app deployed will be one of these scenarios when they cannot use them. the documentation do goes on to say:
However, these restrictions generally do not apply if the developer runs the script themselves or belongs to the same G Suite domain as the user.
What this means is that if another user ran your script from, for example, the GAS editor, it would work. for your intention to work, they would need to somehow submit their address, be it in a form, a document or part of the add-on.

Google Apps Script - I am unable to retrieve user's email address when add-on is published

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.

How can I get the editor's email onEdit(), or ask for Authorization on first edit

This is the first part of a larger script, but I need to get the email address of the person making edits to the cell. For the example I am just trying to add the editors email as a comment to the cell that was edited.
I know that the onEdit() runs in authMode=LIMITED which is the issue. And an installable trigger will also not work as it will only return the person who created the script and not the editor of the cell.
This means the below works for the owner of the script if I manually get them to authorize it, but will not work for any editors of the script.
I think I can get this to work if there is a way to force a user to authorize themselves on first edit.
function onEdit(e){
Logger.log(e);
var range = e.range;
var email1 = Session.getActiveUser().getEmail();
var email2 = Session.getEffectiveUser().getEmail();
range.setNote('Active User: ' + email1 + '\nEffective User: '+ email2);
}
The rules governing email visibility are quite complex, due to legacy behavior and privacy concerns. As you noted, you won't be able to get the email address of a user unless they have authorized the script themselves. The one special case are users within a Google Apps domain. If the owner of the script has authorized it, then it will be able to read the email address of other users within the domain.
There is no way to force authorization, so for the case where users aren't in the same domain, or are consumer accounts, you'll have to ask them to authorize the script, via a menu item, button, or other means.

Automatic Notification when Google Doc is opened

I have a Google Apps Script that contains the following code:
function onOpen() {
var emailAddress = "jthfortyone#gmail.com";
var message = "Viewed"
var subject = "Someone Viewed Your Resume";
MailApp.sendEmail(emailAddress, subject, message);
}
I want to receive an email every time someone views my resume
But for some reason I only receive an email if I am the one open it and not when anyone else does.
What do I need to change to get the desired results?
Your container-bound script in a shared document will only run if:
Sharing has granted edit privileges. (Viewing and Commenting aren't enough.)
User is logged in with a Google account. (Only scripts run as webapps can be triggered anonymously, at which time they run as the owner. No such option, in this case.)
User agrees to authorize the script. (A script that sends emails will require authorization.)
Since this is your resume, I think you're going to need to find another solution.
The onOpen trigger should run in response to the active user opening the document.
The active user is defined as:
The user (Google account) that causes a script to execute. Depending on the execution method this may be different from the effective user. You can also think of this as the user at the keyboard
Have you tried accessing the document with a dummy account?

onedit why cannot send email?

i've this simple script that should send an email when a cell is changed
function onEdit(e) {
var doc = e.source;
var r = doc.getActiveRange().getValue();
if (r == "Niccolò"){
var a = doc.getActiveRange().setBackground('#ff0000');
var b = GmailApp.sendEmail('name#gmail.com', 'subject', 'body');
}
}
This function change also cell colour.
THe problem is that the cell colour works, so it's change while doesn't send any email.
It looks so simple i don't understand why doesn't works!
Simple triggers like onEdit(), onOpen() or onFormSubmit() have a limited set of possible actions because they run without authorization , see the documentation for further details.
So this behavior you describe is normal.
You should use an installable trigger instead as explained in the same doc page.
here is an summary of the documentation :
These simple triggers run in response to actions in Google Spreadsheets, and they run as the active user. For example, if Bob opens the Spreadsheet, then the onOpen function runs as Bob, irrespective of who added the script to the Spreadsheet. For this reason, the simple triggers are restricted in what they are permitted to do:
They cannot execute when the Spreadsheet is opened in read-only mode.
They cannot determine the current user.
They cannot access any services that require authentication as that user. For example, the Google Translate service is anonymous and can be accessed by the simple triggers. Google Calendar, Gmail, and Sites are not anonymous and the simple triggers cannot access those services.
They can only modify the current Spreadsheet. Access to other Spreadsheets is forbidden.
For more information on event permissions, see Executing from a Container-Specific Trigger.