Extending the message UI

Gmail add-ons can provide a user interface when the user is reading messages. This allows Gmail add-ons to automate tasks that respond to message content, such as displaying, retrieving, or sending out additional information related to the message.

A Gmail add-on can implement an extended message UI, an extended compose UI, or both. Universal actions can be added as well.

Accessing the add-on message UI

When a user attempts to open a message in Gmail, any add-ons that provide a message UI appear in the icon row. Clicking on an add-on icon causes a corresponding contextual trigger function to execute. The trigger also executes if the user switches to a different message while the add-on is still open. The contextual trigger function builds the message UI for that message, which Gmail then displays to the user.

Building a message add-on

You can add message functionality to an add-on by following these general steps:

  1. Add the appropriate fields to the add-on script project manifest, including the scopes required for message functionality.
  2. Implement a contextual trigger function that builds a message UI when the user selects the add-on in a message.
  3. Implement associated functions needed to respond to the user's UI interactions.

Contextual triggers

To provide users assistance when reading messages, Gmail add-ons can define a contextual trigger in their manifests. When the user opens a Gmail message (with the add-on open) that meets the trigger criteria* the trigger fires. A fired trigger executes a contextual trigger function that constructs the add-on user interface and returns it for Gmail to display. At that point the user can begin interacting with it.

Contextual triggers are defined in your add-on's project manifest. The trigger definition tells Gmail which trigger function to fire under which conditions. For example, this manifest snippet sets an unconditional trigger that calls the trigger function getContextualAddOn() when a message is opened:

  "gmail": {
    "name": "Quickstart Toolbar Label",
    "logoUrl": "https://www.example.com/hosted/images/2x/my-icon.png",
    "primaryColor": "#4285F4",
    "secondaryColor": "#4285F4",
    "contextualTriggers": [{
      "unconditional": {},
      "onTriggerFunction": "getContextualAddOn"
    }]
  }

Contextual trigger function

Every contextual trigger must have a corresponding trigger function that constructs your add-on's user interface. You specify this function in your manifest's onTriggerFunction field. You implement this function to accept an action event object argument and return an array of one or more built Card objects.

When a contextual trigger fires for a given Gmail message, it calls this function and passes it an action event object. Often trigger functions use the message ID provided by this event object to get the message text and other details using Apps Script's Gmail service. For example, your trigger function could extract message content using these functions:

  // Activate temporary Gmail add-on scopes, in this case to allow
  // message metadata and content to be read.
  var accessToken = e.messageMetadata.accessToken;
  GmailApp.setCurrentMessageAccessToken(accessToken);

  var messageId = e.messageMetadata.messageId;
  var message = GmailApp.getMessageById(messageId);
  var subject = message.getSubject();
  var sender = message.getFrom();
  var body = message.getPlainBody();
  var messageDate = message.getDate();

  // Setting the access token with a gmail.addons.current.message.readonly
  // scope also allows read access to the other messages in the thread.
  var thread = message.getThread();
  var threadMessages = thread.getMessages();
  // Using this link can avoid the need to copy message or thread content
  var threadLink = thread.getPermalink();

The trigger function can then act on this data, extracting the information that it needs for the interface. For example, an add-on that summarizes sales numbers can collect sales figures from the message body and organize them for display in a card.

The trigger function must build and return an array of built Card objects. For example, the following builds an add-on with a single card that just lists the subject and sender of the message:

  function getContextualAddOn(e) {
    // Activate temporary Gmail add-on scopes, in this case to allow
    // message metadata to be read.
    var accessToken = e.messageMetadata.accessToken;
    GmailApp.setCurrentMessageAccessToken(accessToken);

    var messageId = e.messageMetadata.messageId;
    var message = GmailApp.getMessageById(messageId);
    var subject = message.getSubject();
    var sender = message.getFrom();

    // Create a card with a single card section and two widgets.
    // Be sure to execute build() to finalize the card construction.
    var exampleCard = CardService.newCardBuilder()
        .setHeader(CardService.newCardHeader()
            .setTitle('Example card'))
        .addSection(CardService.newCardSection()
            .addWidget(CardService.newKeyValue()
                .setTopLabel('Subject')
                .setContent(subject))
            .addWidget(CardService.newKeyValue()
                .setTopLabel('From')
                .setContent(sender)))
        .build();   // Don't forget to build the Card!
    return [exampleCard];
  }