AuthMode and menu items on install

656 views
Skip to first unread message

Mark Grimshaw-Aagaard

unread,
Apr 16, 2021, 1:27:32 AM4/16/21
to Google Apps Script Community
Hi,

I'm struggling through the verification process for a docs add-on.

I'm not getting on because of this report:
>>>>
Menu options not shown after App is installed.
Pending 

If your published add-on fails to add its menu items, look in the browser's JavaScript console to see if an error was thrown, then examine your script to see whether the onOpen(e) function or global variables call services that aren't allowed in AuthMode.NONE.

This can be a possible implementation issue why the menu options are not populated. When your onOpen(e) function runs, the entire script is loaded and any global statements are executed. These statements execute under the same authorization mode as onOpen(e) and fail if the mode prohibits them. This prevents onOpen(e) from running.

You can find more information about this on this link (https://developers.google.com/gsuite/add-ons/concepts/editor-auth-lifecycle#opening).
<<<<<<
I've looked at the link provided, and, as far as I can tell, I had it right to begin with in my main script:
function onOpen(e) {
DocumentApp.getUi().createAddonMenu()
.addItem('Insert WIKINDX references', 'showSidebar')
.addToUi();
}
function onInstall(e) {
onOpen(e);
}
function showSidebar() {
var ui = HtmlService.createHtmlOutputFromFile('sidebar')
.setTitle('WIKINDX');
DocumentApp.getUi().showSidebar(ui);
}

Any ideas what I need to change?

Mark





Leandro Zubrezki

unread,
Apr 16, 2021, 8:43:54 AM4/16/21
to Google Apps Script Community
Hi Mark!

Check for global variables, maybe you are reading them from PropertiesService somewhere?

Cheers!

Message has been deleted

Alan Wells

unread,
Apr 16, 2021, 10:15:02 AM4/16/21
to Google Apps Script Community
Actually, the order of the files isn't alphabetical, and you can change the order in which they are evaluated,
by simply dragging a file in the sidebar of the new code editor to a new position.
Sorry about that misinformation.  That is a new feature in the new code editor.
The code editors don't sort the files in alphabetically order, the files are typically displayed in the order in which they were created.
I'm accustomed to the Chrome extension sorting the files in the sidebar, and got used to thinking that was the parse order, but it's not.
So, that was a mistake.  The other information is correct.

On Friday, April 16, 2021 at 10:07:24 AM UTC-4 Alan Wells wrote:
Your code has an error in it.
The error is happening before the code even runs.
The error is preventing the onOpen function from running.
The error doesn't happen when the code runs, it happens when the code is being evaluated for being correct or not.
It's an "uncaught" error, meaning that the code editor saved your code even though there is a problem with it.
The code editor didn't find the problem, and tell you that there is a problem before the code was saved.
That makes it hard to debug of course.
The server files in your code are parsed in a certain order, which is the sort order that they are displayed in in the sidebar in the new code editor.
Any global variables should be put in a file at the top of the list, or at least somewhere before files that need the global variable.
For example, the default file name is Code.gs.
That's usually the first file in the list unless you have a file that you named with the first letter of an "A" or a "B".
If Code.gs is your first file in the sort order, then you could put your globals at the top of file Code.gs.
That would be the easiest solution.
Or if nothing in Code.gs needs your globals, then you could create a file for your globals, named
Cz_Globals
Which would be put in order directly after Code.gs.

Mark Grimshaw-Aagaard

unread,
Apr 16, 2021, 10:33:22 AM4/16/21
to Google Apps Script Community
Thanks for the response Leandro.

As far as I'm aware, I'm not using global variables (unless I misunderstand what one looks like in google script). I am using PropertiesService but within functions like javascript's sessionStorage:
´´´´
function getLocalStorage() {
  var userProperties = PropertiesService.getUserProperties();
// Debugging only – comment out in production!
//  userProperties.deleteAllProperties();
  return {
    localStorage: userProperties.getProperty('wikindx-localStorage')
  };
}

function setLocalStorage(jsonArray) {
  var userProperties = PropertiesService.getUserProperties();
  userProperties.setProperty('wikindx-localStorage', JSON.stringify(jsonArray));
}
´´´´
and that's it.

Mark

Mark Grimshaw-Aagaard

unread,
Apr 16, 2021, 10:44:07 AM4/16/21
to Google Apps Script Community
Thanks Alan,

As in my other response, I don't think I'm using global variables (but might not recognize them as such). I tend to use setters and getters.

my 'code.gs' (renamed) is at the top of the list after the manifes.json file. I do have a load of variables at the top of that file that ARE available in other .gs files so perhaps in this context they count as global variables. But then they are in the first file loaded . . .

I do get this error launching the add-on (but have always got the error and assumed it was just something with the google script environment) rather than my coding:
Screenshot 2021-04-16 at 16.38.28.png

Mark

Alan Wells

unread,
Apr 16, 2021, 11:00:25 AM4/16/21
to Google Apps Script Community
I don't remember seeing that error as one of the general errors that Chrome produces that are not related to something we, the developer did.
So, I'm assuming that one of your client side HTML files has a problem with it.
It can be difficult to determine where the error is.
I use templated HTML, so sometimes I just start excluding files until I don't get the error anymore.
Or I delete half my client side JS, and reload to see if the error went away.
Delete one half, then one quarter, and so forth until I find the section of code generating the error.

It's good that you're using getters and setters to avoid using globals.
I would put your onInstall function above your onOpen function.
It probably won't make any difference, but that's what I've gotten into the habit of doing.

This is a difficult situation, because if the problem only happens with the published add-on, then you need to publish it every time you need to test a change.
I suppose that you could create a whole separate Private add-on that didn't need to be verified and approved to do testing.

Mark Grimshaw-Aagaard

unread,
Apr 17, 2021, 4:32:29 AM4/17/21
to Google Apps Script Community
Some of those errors I posted appear to be Safari-only bugs:

I switched to Chrome and I now get only:
Screenshot 2021-04-17 at 09.33.14.png

If I comment out everything between the body tags in my sidebar.html (which includes js script elements), I still get the error.

According to a response here, it's nothing to do with my code, "it's Google":

I've moved my onInstall() above onOpen()

If I print e.authMode within one of those, I get 'Apps Script application'

Tried this page: https://developers.google.com/workspace/add-ons/how-tos/testing-editor-addons

Steps 6 and onward are only available when running the legacy editor . . . .

So, switch to legacy editor and complete the set-up for testing in both AuthMode.NONE and AuthMode-LIMITED. In both tests, my add-on menu displays as it should and so the add-on loads and is fully functional. 

After running several tests in different modes (where all works fine), suddenly the add-on no longer shows in the Add-ons menu . . .

I’ve no idea what else I can do . . . .

Mark

Alan Wells

unread,
Apr 17, 2021, 9:43:19 AM4/17/21
to Google Apps Script Community
Thanks for the update on that error.  It makes sense that it's a Google Chrome bug.
This has nothing to do with the add-on menu not showing up, but you don't need to use the "e" event object in either your onInstall or onEdit functions.  You aren't checking the authmode to determine whether to do one thing or the other (and you don't need to) so you can remove "e" from between the parenthesis.
Have you looked at your executions for that Apps Script project.
Go to:
Find your Apps Script project that the add-on is based on.
Click on the 3 dots on the right.
Choose "Failed Executions"
If the failed execution is expandable, then click the down arrow to see the details.

Mark Grimshaw-Aagaard

unread,
Apr 18, 2021, 4:21:50 AM4/18/21
to Google Apps Script Community
Thanks for your patience once again Alan.

Running test add-on, I get the following errors on onOpen():
1. Installed for current user (AuthMode.NONE):
Exception: You do not have permission to perform that action. at [unknown function](test:3:28)
(And the add-on does not appear in the Add-ons menu)

2. Enabled in current document (AuthMode.LIMITED):
All fine (but the console still shows that previous error: "message: "There was an error during the transport or processing of this request. Error code = 10, Path = /wardeninit" . . ." (So perhaps this console error is nothing to do with the add-on and can be ignored.)

3. Installed and enabled (AuthMode.LIMITED):
As in 2. above.

So, I guess the issue is the AuthMode.NONE. As I basically copied and pasted the sample code from the google sites, I'm not sure what the issue is. I do at least have a better idea of how to check if bugs are happening so I've learnt something.

If I look at: https://developers.google.com/workspace/add-ons/concepts/editor-auth-lifecycle, in the 'Opening' section, I follow "If an add-on only creates a basic menu, the mode doesn’t matter." and so use the example onInstall() and onOpen() functions.

In the top-level file (highest in the hierarchy), I have the following variables listed above onInstall() and onOpen() that could be classified as GLOBAL:
´´´´
/**
* Compatibility number. Must be equal to office.php's $officeVersion
*/
var compatibility = 1;

/** Error messages */
var errorJSON = "ERROR: Unspecified error. This could be any number of things from not being able to connect to the WIKINDX to no resources found matching your search.";
var errorAccess = 'The WIKINDX admin has not enabled read-only access.';
var errorCompatibility = 'ERROR: Incompatibility between add-in and WIKINDX.';
var errorXMLHTTP = "ERROR: XMLHTTP error – could not connect to the WIKINDX. <br/><br/>There could be any number of reasons for this including an incorrect WIKINDX URL, an incompatibility between this add-in and the WIKINDX, the WIKINDX admin has not enabled read-only access, a network error . . .";
var errorDuplicateUrl = "ERROR: Duplicate URL input.";
var errorDuplicateName = "ERROR: Duplicate name input.";
var errorStyles = "ERROR: Either no styles are defined on the selected WIKINDX or there are no available in-text citation styles.";
var errorStylesFinalize = "ERROR: No available in-text citation styles found in any of the wikindices used in the document.";
var errorNoResultsReferences = "No references found matching your search.";
var errorNoResultsCitations = "No citations found matching your search.";
var errorMissingID = "ERROR: Resource or citation ID not found in the selected WIKINDX.";

/** Success messages */
var successHeartbeat = "Yes, I am alive and kicking. Try searching me . . .";
var successNewUrl = "Stored new WIKINDX: ";
var successRemoveUrl = "Deleted WIKINDX URL(s).";
var successRemoveAllUrls = "Deleted all WIKINDX URLs.";
var successPreferredUrl = "Preference stored.";
var successEditUrl = "Edited WIKINDX URL.";
var errorNewUrl = "ERROR: Missing URL or name input.";
var successHeartbeat = "Yes, I am alive and kicking. Try searching me . . .";
var successRemoveUrl = "Deleted WIKINDX URL(s).";
var successRemoveAllUrls = "Deleted all WIKINDX URLs.";
var successPreferredUrl = "Preference stored.";
´´´´

In other words, just a compatibility check (with external database) and error/success messages. Nothing that could trigger errors as stated in the warning on the auth-lifecycle page (no global statements other than setting variables and no calling of any services).

Mark (still puzzled)

Alan Wells

unread,
Apr 18, 2021, 1:16:03 PM4/18/21
to Google Apps Script Community
I'm guessing that the only time that testing for AuthMode.NONE in the onInstall or onOpen function
would be of value is to know what happens when the user cancelled the OAuth permissions request,
in the OAuth dialog.  
Like if they looked at the permissions request, and thought to themselves,
"There' no way I'm going to allow this add-on access to my account."
And they click the Cancel button or close the OAuth dialog box.
I've never even bothered to test for those conditions.
Maybe I should, but if they choose not to accept the permissions request, 
then obviously the add-on isn't going to work.
If someone can explain why we'd ever test for AuthMode.NONE in the onInstall or onOpen then please let us know.

All those var assignments that you have are globals.
They are not inside of any code block.  A code block being curly braces.

I'm assuming that those globals are constants, there value doesn't ever change.

I want you to try putting all those globals inside of something called an IIFE.
Immediately Invoked Function Expression.

Do NOT use the "var" keyword, just make assignments.

(function(){
  var i;
  
  /*
    This function is to set GLOBALS that will have their values change while the code is running -
    Dont use this fnc for global constants that wont ever have their value change while the code is running
  */
  
  /* The code that I use will always need at least one Global var for the global object AJ_GLBL -
    This IIFE runs automatically and sets the globals
  */
  
  /*IMPORTANT - 
    Global variables can cause a fatal error during the parsing of the JavaScript before the code is even run-
    If that happens then your code will never run -
    Globals can stop the add-on menu from being displayed - 
    So setting the globals correctly is extremely important - 
  */
  
  /*IMPORTANT - Apps Script does not like globals defined as constants - it will cause the addon menu to not show up */
  /*IMPORTANT - Dont call any functions from the global scope -*/

  //You can NOT put services into a global variable - get errors
  
  //If a variable is assigned a value without a var key word then it is put into the globlal scope
  //Logger.log('IIFE 'ran')
    
  //TEST_GLBL = "SOMTHING";
  
  //Logger.log('TEST_GLBL inside: ' + TEST_GLBL)

  compatibility = 1;

  /** Error messages */
  errorJSON = "ERROR: Unspecified error. This could be any number of things from not being able to connect to the WIKINDX to no resources found matching your search.";
  errorAccess = 'The WIKINDX admin has not enabled read-only access.';
  errorCompatibility = 'ERROR: Incompatibility between add-in and WIKINDX.';
  
 //Add the rest of your global assignments  
})();

Mark Grimshaw-Aagaard

unread,
Apr 19, 2021, 4:03:56 AM4/19/21
to Google Apps Script Community
Thanks Alan,

Still no luck I'm afraid. Running the add-on in test mode AuthMode.NONE I still get:
"Google Apps Script: Exception: You do not have permission to perform that action."

I put in the IIFE as you suggested in the first .gs file in the hierarchy (above the call to onInstall()) and removed all global variables from other files putting them in that IIFE. If anyone else is following this thread, it's worth mentioning that variables assigned in the IIFE must be defined otherwise google throws an error.

I've also tried changing onOpen() to:
````
function onInstall(e) {
  onOpen(e);
}
function onOpen(e) {
    var menu = DocumentApp.getUi().createAddonMenu(); // Or DocumentApp.
  if (e && e.authMode == DocumentApp.AuthMode.NONE) {
    // Add a normal menu item (works in all authorization modes).
    menu.addItem('Insert WIKINDX references', 'showSidebar');
  } else {
    // Add a menu item based on properties (doesn't work in AuthMode.NONE).
    var properties = PropertiesService.getDocumentProperties();
    var workflowStarted = properties.getProperty('workflowStarted');
    if (workflowStarted) {
      menu.addItem('Check workflow status', 'checkWorkflow');
    } else {
      menu.addItem('Insert WIKINDX references', 'showSidebar');
    }
  }
  menu.addToUi();
}
````

but then I get the error:
"Google Apps Script: TypeError: Cannot read property 'NONE' of undefined"

Mark

Leandro Zubrezki

unread,
Apr 19, 2021, 7:39:10 AM4/19/21
to google-apps-sc...@googlegroups.com
Try with ScriptApp.AuthMode.NONE instead of DocumentApp.AuthMode.NONE

--
You received this message because you are subscribed to a topic in the Google Groups "Google Apps Script Community" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/google-apps-script-community/qC2WLgzLtVY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to google-apps-script-c...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-apps-script-community/25d6e381-5136-45f8-8120-8d4c19771634n%40googlegroups.com.


--
Leandro Zubrezki
Freelance Software Developer

Mark Grimshaw-Aagaard

unread,
Apr 19, 2021, 8:52:57 AM4/19/21
to Google Apps Script Community
You're absolutely right Leandro – my error.

Now, testing my add-on in all three test modes works fine other than the usual error of "There was an error during the transport or processing of this request. Error code = 10, Path = /wardeninit" which I have to assume is nothing to do with my scripts.

Thank you all for your help and advice! I'm one step closer to verification . . .

I am puzzled why this: https://developers.google.com/workspace/add-ons/concepts/editor-auth-lifecycle states: "If an add-on only creates a basic menu, the mode doesn’t matter" as I was originally using the onOpen() for a basic menu that did not meet these requirements: "dynamic menu items based on stored Apps Script properties, read the contents of the current document, or perform other advanced tasks."

Elsewhere in my scripts, I do indeed read/write the contents of the current document and use PropertiesService to store user input but not in the simple onOpen() function. Could that be it?

Mark

Alan Wells

unread,
Apr 19, 2021, 9:42:50 AM4/19/21
to Google Apps Script Community
If after changing:
DocumentApp.AuthMode.NONE
TO:
ScriptApp.AuthMode.NONE
The code works without an error, then something you did before that point fixed the problem.
Right?
Just for fun, did you test with the IIFE and without it to determine if that is what fixed the issue?
As for the issue with accessing properties service in code that is NOT used in your menu,
I believe that it does matter.
I'm not sure exactly what the logic is, or how the code is evaluated,
but it does seem that if the Auth mode is NONE, and you don't explicitly test for that Auth state in the onOpen function,
that it throws an error even if your menu doesn't use code that accesses Properties Service.
Probably the reason it's done that way, is that the internal code would need to check for whether the onOpen function
was using code that required permission, and that would complicate things, 
and whenever you complicate the code that your security depends on, it increases the chances of something going wrong.
Maybe that's the reason that Google just excludes it all together.
It's kind of like when Apps Script tells you that your own code was created by some external, unknown entity.
It's your code!  It's running from your account.
But whoever decides on how to handle this, opted to be safe and just view everything as dangerous,
even if it's your own code that you wrote.

Mark Grimshaw-Aagaard

unread,
Apr 19, 2021, 10:27:27 AM4/19/21
to Google Apps Script Community
HI Alan,

1.
Right before changing
DocumentApp.AuthMode.NONE
TO:
ScriptApp.AuthMode.NONE

I was using the simple onOpen() and it wasn't working so, as far as I can tell from what you are describing, the issue is to do with Properties Service elsewhere in my scripts and so needing the full onOpen(e) code (with the correct object that I overlooked).

2.
With the correct and fuller onOpen(e) code, removing the IIFE and running in all three test modes, the menu loads fine. So, I would conclude that the IIFE was not part of the solution but I haven't gone so far as to put back in global variables in each file where they were previously. That might lead to other problems once AuthMode.NONE was solved.

Mark

Alan Wells

unread,
Apr 19, 2021, 11:03:06 AM4/19/21
to Google Apps Script Community
The add-on menu issue problem has been something that's been happening for a long time.
If you determine an absolute perfect, reproducible cause, please let us know.

Mark Grimshaw-Aagaard

unread,
Apr 24, 2021, 1:55:36 AM4/24/21
to Google Apps Script Community
Thanks for all the help here. The add-on (WIKINDX) has now been published.

Mark

Alan Wells

unread,
Apr 24, 2021, 8:55:17 AM4/24/21
to Google Apps Script Community
I'm glad to know that it's now available to the public.
Are you satisfied with the final result?
Hopefully it will be well liked and useful.
Congratulations and I'm wishing your add-on success.
Do you think you'd create another Google add-on?

Mark Grimshaw-Aagaard

unread,
Apr 24, 2021, 9:54:46 AM4/24/21
to Google Apps Script Community
Thanks Alan,

I doubt very much I will do another one. This was an app intended to interface with another web-based program that I author and a port of a Word add-in I'd already done: I have no reason to write anything else for this environment.

Mark
Reply all
Reply to author
Forward
0 new messages