In most cases, you must authorize an add-on before you can use it. For many Apps Script projects such as web apps, authorization is straightforward—the script project asks for any missing permissions it needs when you attempt to use it. Once authorized, you can use the script project freely. Everyone using the script project authorizes it separately.
The authorization model for Editor Add-ons is more complex. Because these add-ons function on files residing in Google Drive—files that can be shared with others—you must build editor add-ons with the different authorization modes in mind. The Google Workspace editor applications also provide an Add-ons menu in their UIs which is populated by the add-ons you've installed—even if you haven't authorized those add-ons yet. This adds some additional complexity to the authorization model.
Authorization model
Two properties of Editor Add-ons make them especially easy to share and use:
- Once you get an Editor Add-on from the store, you see it in the add-ons menu for every document you open or create. Collaborators on those documents won't see the add-on except in documents where you actually use it.
- Once you use an Editor Add-on in a document, your collaborators also see it in the add-ons menu, but just for that document (unless they have also installed that add-on).
This sharing model feels natural for most users. However, because an editor
add-on automatically runs its onOpen(e)
function to add menu items when a
document opens, the behavior above adds some complexity to Apps Script's
authorization rules. After all, users wouldn't be comfortable with an
add-on accessing personal data every time they open a document. This guide
should help you understand what your code can do and when.
Installed versus enabled
If you see an Editor Add-on in the menu, it's in one (or both) of two states: installed and enabled. An Editor Add-on is installed for a particular user after they choose the add-on in the store and authorize it to access their Google data. By contrast, an add-on is enabled in a given document when anyone uses it there. If two people collaborate on a document, and one of them uses an add-on, it is installed for the one user and enabled for the document.
The table below summarizes the two states. Note that when testing a script as an add-on you can choose to run the test in either or both of these states.
Installed | Enabled | |
---|---|---|
Applies to | User | Document |
Caused by | Getting an add-on from the store | Getting an add-on from the store while using that document, or Using a previously installed add-on in that document |
Menu visible to | Only that user, in all documents they open or create | All collaborators on that document |
onOpen(e) runs in |
AuthMode.NONE (unless also enabled, in which case
AuthMode.LIMITED) |
AuthMode.LIMITED |
Authorization modes
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.
Specifically, the installed and enabled states determine which authorization
mode the onOpen(e)
function runs in. Apps Script passes the authorization mode
as the authMode
property of the Apps Script
event parameter, e
; the value of
e.authMode
corresponds to a constant in the Apps Script
ScriptApp.AuthMode
enum.
If an Editor Add-on is enabled in the current document, onOpen(e)
runs in
AuthMode.LIMITED
. If the add-on is not enabled and is only installed,
onOpen(e)
runs in AuthMode.NONE
.
The concept of authorization modes applies to all Apps Script executions—such
as running from the script editor, from a menu item, or from an Apps Script
google.script.run
call—although
the e.authMode
property can only be inspected if the script runs as the result
of a trigger like onOpen(e)
, onEdit(e)
or onInstall(e)
. Custom functions
in Google Sheets use their own authorization mode, AuthMode.CUSTOM_FUNCTION
,
which is similar to LIMITED
but has slightly different restrictions. The
rest of the time, scripts run in AuthMode.FULL
, as detailed in the table
below.
NONE |
LIMITED |
CUSTOM_FUNCTION |
FULL |
|
---|---|---|---|---|
Occurs for | onOpen(e) (if the user has installed an add-on but not enabled it in the document) |
onOpen(e) (all other times)onEdit(e) (only in Sheets) |
Custom functions | All other times, including: installable triggers onInstall(e) google.script.run |
Access to user data | Locale only | Locale only | Locale only | Yes |
Access to document | No | Yes | Yes — read-only | Yes |
Access to user interface | Add menu items | Add menu items | No | Yes |
Access to Properties |
No | Yes | Yes | Yes |
Access to Jdbc , UrlFetch |
No | No | Yes | Yes |
Other services | Logger Utilities |
Any services that don’t access user data | Any services that don’t access user data | All services |
The complete lifecycle
If an add-on is either installed for the current user or enabled in the current
document, the add-on is loaded in the document, which causes it to appear in
the add-ons menu and start listening for the
simple triggers onInstall(e)
,
onOpen(e)
, and onEdit(e)
. If a user clicks one of the add-on’s menu items,
it runs.
Installing
When an Editor Add-on is installed from the store, its onInstall(e)
function
runs in AuthMode.FULL
. This allows the add-on to run a complex setup routine,
but it’s important to also use onInstall(e)
to create menu items, since the
document is already open and thus your onOpen(e)
function hasn’t run. For
convenience, you can just call onOpen(e)
from onInstall(e)
, as shown in
this sample:
function onInstall(e) {
onOpen(e);
// Perform additional setup as needed.
}
Opening
When a document opens, it loads every Editor Add-on that the current user has
installed or that any collaborator has enabled in the document, and calls each
of their onOpen(e)
functions. The authorization mode that onOpen(e)
runs
in depends on whether an add-on is installed or enabled.
If an add-on only creates a basic menu, the mode doesn’t matter. This sample
shows what a simple onOpen(e)
might look like:
function onOpen(e) {
SpreadsheetApp.getUi().createAddonMenu() // Or DocumentApp.
.addItem('Insert chart', 'insertChart')
.addItem('Update charts', 'updateCharts')
.addToUi();
}
However, if you want to add dynamic menu items based on stored Apps Script
properties, read the contents of the current
document, or perform other advanced tasks, you need to detect the authorization
mode and handle it appropriately. This sample shows what an advanced onOpen(e)
function might look like, changing its behavior based on the authorization mode:
function onOpen(e) {
var menu = SpreadsheetApp.getUi().createAddonMenu(); // Or DocumentApp.
if (e && e.authMode == ScriptApp.AuthMode.NONE) {
// Add a normal menu item (works in all authorization modes).
menu.addItem('Start workflow', 'startWorkflow');
} 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('Start workflow', 'startWorkflow');
}
}
menu.addToUi();
}
Running
When someone clicks one of an add-on's menu items, Apps Script first checks to
see whether the user has installed the add-on, and prompts them to do so if not.
If the user has authorized the add-on, the script runs the function that
corresponds to the menu item in AuthMode.FULL
. The add-on also becomes enabled
in the document if it wasn’t already.