问题
I would like to better clarify the question I have written. I am attempting to write an add-on that does the following:
When this add-on is installed in a document, I want it to send the user an email every time the document is opened, with the information of who opened the document. I have much more detail about my previous attempts below, but the big question is this: Is there a way for me to accomplish this?
Thanks to everyone who has helped.
I am working to write a Google Apps Script add-on that, once installed in a document, will execute a function to send an e-mail to the effective user every time the document is opened. What I am currently doing is the following:
function onInstall (e)
{
onOpen (e)
}
function onOpen (e)
{
if (/*Some Code*/)
{
DocumentApp.getUi().createAddonMenu()
.addItem('Start Notification', 'myFunction')
.addToUi();
}
else
{
myFunction ();
}
}
In that if statement, I have tried a few different things:
e.authMode == ScriptApp.AuthMode.NONE
did not seem to work quite right- although I did get the menu the way it was intended, the function did not execute when someone else opened the document. I think this is because for them, the authorization mode is also NONE, so it would merely run the if, not the else. So I tried this instead:
e.authMode == ScriptApp.AuthMode.NONE && Session.getEffectiveUser().getEmail() == ""
But that didn't work either. Again, I was able to see the add-on menu, and when I clicked the button to activate the code I can verify that 'myFunction' did indeed run, but it didn't execute myFunction() when someone else opened the document. I'm open to ideas and suggestions!
Here is myFunction ()
function myFunction() {
var doc = DocumentApp.getActiveDocument().getName();
var userEmail = Session.getEffectiveUser().getEmail();
var openerEmail = Session.getActiveUser().getEmail();
if (openerEmail != userEmail) {
GmailApp.sendEmail(userEmail, doc + ' opened', openerEmail + " opened the document.");
}
}
And one more addition, per the second response given: I was originally using this code, and pasting it into all of my documents. Because this is only used for users within my domain, it worked perfectly fine. Is there any way around this?
function myFunction() {
var email = Session.getActiveUser();
if (email != 'myEmail@domain.org') {
GmailApp.sendEmail('myEmail@domain.org', 'Document opened', email + " opened your document.");
}
}
function triggerBuilder ()
{
var doc = DocumentApp.getActiveDocument();
ScriptApp.newTrigger (myFunction)
.forDocument(doc)
.onOpen()
.create();
}
I would just run the trigger builder to make the installable trigger, or do it manually.
Some more info: I tested the following code, and found that when run, I was able to see the information when I myself opened the document, but not when someone else did. It seems that the onOpen(e) method may not have worked at all, as it did not appear in the Project Executions page either.
function onInstall (e)
{
onOpen (e);
}
function onOpen (e)
{
if (Session.getEffectiveUser().getEmail() == "")
{
DocumentApp.getUi().createMenu("Notification Test")
.addItem("Run function", 'myFunction')
.addToUi();
}
else
myFunction ();
}
function myFunction ()
{
Logger.log ("This is verification that the document was opened.");
Logger.log("Current user: " + Session.getActiveUser().getEmail());
}
回答1:
From Simple Triggers > Restrictions (emphasis mine)
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.
The workaround is to use an installable on open trigger instead of a simple trigger.
Related
- Sending email from spreadsheet onOpen
- Google Doc onOpen will not fire when spreadsheet is accessed
回答2:
It is not just about authorization. You can only run certain functions from onOpen
, i.e. functions that don't require user data. This is for security; otherwise you could share a link to your spreadsheet that when opened (and authorized) sends you the contents of the users Google drive.
Right now you are already trying to send an email documenting every person's opening of an email. The restrictions on onOpen
are meant for this very situation. You shouldn't be able to access someone's email address simply because they opened your spreadsheet, even if they authorize it -- the user needs to interact with your spreadsheet more deliberately, such as opening a menu item, before you can access their info. Your intentions may be benign, but imagine this installed as an add-on. The best you can do is log a 'user key' to the console using Session.getTemporaryActiveUserKey()
, which should be allowed in the restricted auth mode.
The somewhat vague documentation, with emphasis.
An editor add-on automatically runs its onOpen(e) function to add menu items when a document opens—but to protect users' data, Apps Script restricts what the onOpen(e) function can do. If the add-on hasn't been used in the current document, these restrictions become more severe.
来源:https://stackoverflow.com/questions/54029477/apps-script-add-on-onopene-with-if-to-show-a-menu-or-to-send-an-e-mail