Add-on triggers

Apps Script triggers cause a specified script function (the trigger function) to execute whenever a specified event occurs. Only certain events can cause triggers, and each G Suite application supports a different set of events.

When a trigger function executes, it is passed an event object—a JSON object containing details about the event that caused the trigger to fire. See Event objects for details about the content of event objects.

This page provides guidelines on using Apps Script triggers in add-on projects.

Add-on trigger types

The following table shows the types of triggers that can be used by add-ons, and provides links to the corresponding event objects.

Event Event object Simple triggers Installable triggers Manifest triggers*
Open
An editor file is opened.
Docs onOpen event object
Forms onOpen event object
Sheets onOpen event object
Slides onOpen event object
Docs
Forms**
Sheets
Slides

function onOpen(e)

Docs
Forms**
Sheets
Install
The add-on is installed.
onInstall event object Docs
Forms
Sheets
Slides

function onInstall(e)

Edit
Spreadsheet cell content is changed.
Sheets onEdit event object Sheets

function onEdit(e)

Sheets
Change
Content in a sheet is edited or formatted.
Sheets onChange event object Sheets
Form-submit
A Google Form is submitted.
Forms form-submit event object
Sheets form-submit event object
Forms
Sheets
Time-driven (clock)
The trigger fires a a specifed time or interval.
Time-driven event object Docs
Forms
Sheets
Slides
Contextual (Gmail messages)
A message is opened in Gmail while the add-on is open.
Action event object Gmail
Compose (Gmail messages)
The add-on is opened from Gmail's compose interface.
Compose trigger event object Gmail

* These triggers are defined in the add-on manifest and as such you can't create or edit them using the Apps Script Script service. These triggers are unique to Gmail add-ons; they are never used in other types of Apps Script projects.

** The open event for Google Forms does not occur when a user opens a form to respond, but rather when an editor opens the form to modify it.

Simple triggers in add-ons

Simple triggers use a set a reserved function names, can't use services that require authorization, and are automatically enabled for use. In some cases, a simple trigger event can be handled by an installable trigger instead.

You can add a simple trigger to an add-on by simply implementing a function with one of the following reserved names:

  • onOpen(e) executes when a user opens a document, spreadsheet, or presentation. onOpen(e) also can execute when a form is opened in the editor (but not when responding to the form). It only executes if the user has permission to edit the file in question, and is most often used to create menu items.
  • onInstall(e) executes when a user installs an add-on. Usually onInstall(e) is just used to call onOpen(e); this ensures that the add-on menus appear immediately after install without requiring the user to refresh the page.
  • onEdit(e) executes when a user changes a cell value in a spreadsheet. This trigger does not fire in response to cell moves, formatting, or other changes that don't alter cell values.

Restrictions

Simple triggers in add-ons are subject to the same restrictions that govern simple triggers in other kinds of Apps Script projects. Take particular note of these restrictions when designing add-ons:

  • Simple triggers do not run if a file is opened in read-only (view or comment) mode. This behavior prevents your add-on menus from being populated.
  • In certain circumstances, editor add-ons run their onOpen(e) and onEdit(e) simple triggers in a no-authorization mode. This mode presents some additional complications as outlined in the add-on authorization model.
  • Simple triggers cannot use services or take other actions that require authorization, except as outlined in the add-on authorization model.
  • Simple triggers cannot run for longer than 30 seconds. Take care to minimize the amount of processing done in a simple trigger function.
  • Simple triggers are subject to Apps Script trigger quota limits.

Installable triggers in add-ons

Add-ons can programmatically create and modify installable triggers with the Apps Script Script service. Add-on installable triggers can't be created manually. Unlike simple triggers, installable triggers can use services that require authorization.

Installable triggers in add-ons don't send error emails to the user when they encounter errors, since in most cases a user is unable to address the problem. Because of this, you should design your add-on to gracefully handle errors on behalf of user whenever possible.

Add-ons can use the following installable triggers:

  • Open installable triggers execute when a user opens a document, spreadsheet, or when a form is opened in the editor (but not when responding to the form).
  • Edit installable triggers execute when a user changes a cell value in a spreadsheet. This trigger does not fire in response to formatting or other changes that don't alter cell values.
  • Change installable triggers execute when a user makes any change in a spreadsheet, including formatting edits and modifications to the spreadsheet itself (such as adding a row).
  • Form-submit installable triggers execute when a Google Form response is submitted.

  • Time-driven triggers (also called clock triggers) fire at a specific time or repeatedly on a regular time interval.

Authorizing installable triggers

Normally, if a developer updates an add-on to use new services that require additional authorization, users are prompted to re-authorize the add-on the next time they use it.

However, add-ons that use triggers encounter special authorization challenges. Imagine an add-on that uses a trigger to monitor form submissions: a form creator might authorize the add-on the first time they use it, then leave it to run for months or years without ever reopening the form. If the add-on developer were to update the add-on to use new services that require additional authorization, the form creator would never see the re-authorization dialog because they never reopened the form, and the add-on would stop working.

Unlike triggers in regular Apps Script projects, triggers in add-ons continue to fire even if they need re-authorization. However, the script still fails if it hits a line of code that requires authorization the script does not have. To avoid this situation, developers can use the method ScriptApp.getAuthorizationInfo() to gate access to parts of code that have changed between published versions of the add-on.

Below is an example of the recommended structure to use in trigger functions to avoid authorization pitfalls. The example trigger function responds to a form-submit event within a Google Sheets add-on and, if re-authorization is required, sends the user of the add-on an alert email using templated HTML.

Code.gs

triggers/form/Code.gs
/**
 * Responds to a form when submitted.
 * @param {event} e The Form submit event.
 */
function respondToFormSubmit(e) {
  var addonTitle = 'My Add-on Title';
  var props = PropertiesService.getDocumentProperties();
  var authInfo = ScriptApp.getAuthorizationInfo(ScriptApp.AuthMode.FULL);

  // Check if the actions of the trigger requires authorization that has not
  // been granted yet; if so, warn the user via email. This check is required
  // when using triggers with add-ons to maintain functional triggers.
  if (authInfo.getAuthorizationStatus() ==
      ScriptApp.AuthorizationStatus.REQUIRED) {
    // Re-authorization is required. In this case, the user needs to be alerted
    // that they need to re-authorize; the normal trigger action is not
    // conducted, since it requires authorization first. Send at most one
    // "Authorization Required" email per day to avoid spamming users.
    var lastAuthEmailDate = props.getProperty('lastAuthEmailDate');
    var today = new Date().toDateString();
    if (lastAuthEmailDate != today) {
      if (MailApp.getRemainingDailyQuota() > 0) {
        var html = HtmlService.createTemplateFromFile('AuthorizationEmail');
        html.url = authInfo.getAuthorizationUrl();
        html.addonTitle = addonTitle;
        var message = html.evaluate();
        MailApp.sendEmail(Session.getEffectiveUser().getEmail(),
            'Authorization Required',
            message.getContent(), {
                name: addonTitle,
                htmlBody: message.getContent()
            }
        );
      }
      props.setProperty('lastAuthEmailDate', today);
    }
  } else {
    // Authorization has been granted, so continue to respond to the trigger.
    // Main trigger logic here.
  }
}

authorizationemail.html

triggers/form/AuthorizationEmail.html
<p>The Google Sheets add-on <i><?= addonTitle ?></i> is set to run automatically
whenever a form is submitted. The add-on was recently updated and it needs you
to re-authorize it to run on your behalf.</p>

<p>The add-on's automatic functions are temporarily disabled until you
re-authorize it. To do so, open Google Sheets and run the add-on from the
Add-ons menu. Alternatively, you can click this link to authorize it:</p>

<p><a href="<?= url ?>">Re-authorize the add-on.</a></p>

<p>This notification email will be sent to you at most once per day until the
add-on is re-authorized.</p>

Restrictions

Installable triggers in add-ons are subject to the same restrictions that govern installable triggers in other kinds of Apps Script projects.

In addition to these restrictions, several restrictions apply to installable triggers in add-ons specifically:

  • Each add-on can only have one trigger of each type, per user, per document. For instance, in a given spreadsheet, a given user can only have one edit trigger, although the user could also have a form-submit trigger or a time-driven trigger in the same spreadsheet. A different user with access to the same spreadsheet could have their own separate set of triggers.
  • Add-ons can only create triggers for the file in which the add-on is used. That is, an add-on that is used in Google Doc A cannot create a trigger to monitor when Google Doc B is opened.
  • Time-driven triggers cannot run more frequently than once per hour.
  • Add-ons do not automatically send the user an email when code run by an installable trigger throws an exception. It is up to the developer to check for and handle failure cases gracefully.
  • Add-on triggers stop firing in any of the following situations:
    • If the add-on is uninstalled by the user,
    • If the add-on is disabled in a document (if it is re-enabled, the trigger becomes operational again), or
    • If the developer unpublishes the add-on or submits a broken version to the add-on store.
  • Add-on trigger functions execute until they reach code that uses an unauthorized service, at which point they stop. This is true only if the add-on is published; the same trigger in a regular Apps Script project or an unpublished add-on don't execute at all if any part of the script needs authorization.
  • Installable triggers are subject to Apps Script trigger quota limits.

Manifest triggers

There are two trigger types that a Gmail add-on can define in its manifest: contextual triggers and compose triggers.

Contextual triggers fire when messages that meet the trigger criteria are opened in Gmail while the add-on is also open. Contextual triggers are used to control what part of the add-on interface to displayed as the result of the message and its content.

Compose triggers are essentially callbacks. They fire when the user attempts to open the add-on from the Gmail compose window, and control what the add-on first displays.

For more information about these trigger types, see Extending the message UI and Extending the compose UI.

Restrictions

Contextual and compose triggers have certain restrictions to their use.

  • These triggers are only used in Gmail add-on projects; they have no purpose in any other application.
  • Since they are defined in the add-on manifest and not in its code, you can't use the Apps Script Script service to create or modify these triggers.
  • Contextual triggers currently can only have an unconditional criteria. This means contextual triggers fire for every email message, regardless of content.