Google Workspace-Add-on mit Apps Script erstellen

In dieser Kurzanleitung wird ein einfaches Google Workspace-Add-on erstellt, das Startseiten, kontextbezogene Trigger und die Verbindung zu APIs von Drittanbietern veranschaulicht.

Das Add-on erstellt kontextbezogene und kontextunabhängige Benutzeroberflächen in Gmail, Google Kalender und Google Drive. Das Add-on zeigt ein zufälliges Bild einer Katze mit einem Text-Overlay an. Der Text ist entweder statisch für Startseiten oder wird für kontextbezogene Trigger aus dem Kontext der Hostanwendung übernommen.

Lernziele

  • die Umgebung einrichten
  • Richten Sie das Script ein.
  • Führen Sie das Skript aus.

Vorbereitung

Für die Verwendung dieses Beispiels sind die folgenden Voraussetzungen erforderlich:

  • Ein Google-Konto (für Google Workspace-Konten ist möglicherweise die Administratorzustimmung erforderlich).
  • Einen Webbrowser mit Internetzugriff.

  • Ein Google Cloud-Projekt

Umgebung einrichten

Cloud-Projekt in der Google Cloud Console öffnen

Öffnen Sie das Cloud-Projekt, das Sie für dieses Beispiel verwenden möchten, falls noch nicht geschehen:

  1. Rufen Sie in der Google Cloud Console die Seite Projekt auswählen auf.

    Cloud-Projekt auswählen

  2. Wählen Sie das Google Cloud-Projekt aus, das Sie verwenden möchten. Sie können auch auf Projekt erstellen klicken und der Anleitung auf dem Bildschirm folgen. Wenn Sie ein Google Cloud-Projekt erstellen, müssen Sie möglicherweise die Abrechnung für das Projekt aktivieren.

Für Google Workspace-Add-ons ist eine Konfiguration des Einwilligungsbildschirms erforderlich. Mit der Konfiguration des OAuth-Zustimmungsbildschirms Ihres Add-ons legen Sie fest, was Google Nutzern anzeigt.

  1. Klicken Sie in der Google Cloud Console auf das Dreistrich-Menü  > APIs und Dienste > OAuth-Zustimmungsbildschirm.

    Zum OAuth-Zustimmungsbildschirm

  2. Wählen Sie unter Nutzertyp die Option Intern aus und klicken Sie dann auf Erstellen.
  3. Füllen Sie das Formular zur App-Registrierung aus und klicken Sie dann auf Speichern und fortfahren.
  4. Sie können das Hinzufügen von Bereichen vorerst überspringen und auf Speichern und fortfahren klicken. Wenn Sie in Zukunft eine App für die Verwendung außerhalb Ihrer Google Workspace-Organisation erstellen, müssen Sie den Nutzertyp in Extern ändern und dann die erforderlichen Autorisierungsbereiche hinzufügen.

  5. Überprüfen Sie die Zusammenfassung der App-Registrierung. Wenn Sie Änderungen vornehmen möchten, klicken Sie auf Bearbeiten. Wenn die App-Registrierung korrekt ist, klicken Sie auf Zurück zum Dashboard.

Script einrichten

Apps Script-Projekt erstellen

  1. Wenn Sie ein neues Apps Script-Projekt erstellen möchten, rufen Sie script.new auf.
  2. Klicken Sie auf Unbenanntes Projekt.
  3. Benennen Sie das Apps Script-Projekt in Cats um und klicken Sie auf Umbenennen.
  4. Klicken Sie neben der Datei Code.gs auf das Dreipunkt-Menü  > Umbenennen. Benennen Sie die Datei Common.
  5. Klicken Sie auf „Datei hinzufügen“  > Script. Benennen Sie die Datei Gmail.
  6. Wiederholen Sie Schritt 5, um zwei weitere Scriptdateien mit den Namen Calendar und Drive zu erstellen. Sie sollten jetzt vier separate Scriptdateien haben.
  7. Ersetzen Sie den Inhalt jeder Datei durch den folgenden Code:

    Common.gs

      /**
     * This simple Google Workspace Add-on shows a random image of a cat in the
     * sidebar. When opened manually (the homepage card), some static text is
     * overlayed on the image, but when contextual cards are opened a new cat image
     * is shown with the text taken from that context (such as a message's subject
     * line) overlaying the image. There is also a button that updates the card with
     * a new random cat image.
     *
     * Click "File > Make a copy..." to copy the script, and "Publish > Deploy from
     * manifest > Install add-on" to install it.
     */
    
    /**
     * The maximum number of characters that can fit in the cat image.
     */
    var MAX_MESSAGE_LENGTH = 40;
    
    /**
     * Callback for rendering the homepage card.
     * @return {CardService.Card} The card to show to the user.
     */
    function onHomepage(e) {
      console.log(e);
      var hour = Number(Utilities.formatDate(new Date(), e.userTimezone.id, 'H'));
      var message;
      if (hour >= 6 && hour < 12) {
        message = 'Good morning';
      } else if (hour >= 12 && hour < 18) {
        message = 'Good afternoon';
      } else {
        message = 'Good night';
      }
      message += ' ' + e.hostApp;
      return createCatCard(message, true);
    }
    
    /**
     * Creates a card with an image of a cat, overlayed with the text.
     * @param {String} text The text to overlay on the image.
     * @param {Boolean} isHomepage True if the card created here is a homepage;
     *      false otherwise. Defaults to false.
     * @return {CardService.Card} The assembled card.
     */
    function createCatCard(text, isHomepage) {
      // Explicitly set the value of isHomepage as false if null or undefined.
      if (!isHomepage) {
        isHomepage = false;
      }
    
      // Use the "Cat as a service" API to get the cat image. Add a "time" URL
      // parameter to act as a cache buster.
      var now = new Date();
      // Replace forward slashes in the text, as they break the CataaS API.
      var caption = text.replace(/\//g, ' ');
      var imageUrl =
          Utilities.formatString('https://cataas.com/cat/says/%s?time=%s',
              encodeURIComponent(caption), now.getTime());
      var image = CardService.newImage()
          .setImageUrl(imageUrl)
          .setAltText('Meow')
    
      // Create a button that changes the cat image when pressed.
      // Note: Action parameter keys and values must be strings.
      var action = CardService.newAction()
          .setFunctionName('onChangeCat')
          .setParameters({text: text, isHomepage: isHomepage.toString()});
      var button = CardService.newTextButton()
          .setText('Change cat')
          .setOnClickAction(action)
          .setTextButtonStyle(CardService.TextButtonStyle.FILLED);
      var buttonSet = CardService.newButtonSet()
          .addButton(button);
    
      // Create a footer to be shown at the bottom.
      var footer = CardService.newFixedFooter()
          .setPrimaryButton(CardService.newTextButton()
              .setText('Powered by cataas.com')
              .setOpenLink(CardService.newOpenLink()
                  .setUrl('https://cataas.com')));
    
      // Assemble the widgets and return the card.
      var section = CardService.newCardSection()
          .addWidget(image)
          .addWidget(buttonSet);
      var card = CardService.newCardBuilder()
          .addSection(section)
          .setFixedFooter(footer);
    
      if (!isHomepage) {
        // Create the header shown when the card is minimized,
        // but only when this card is a contextual card. Peek headers
        // are never used by non-contexual cards like homepages.
        var peekHeader = CardService.newCardHeader()
          .setTitle('Contextual Cat')
          .setImageUrl('https://www.gstatic.com/images/icons/material/system/1x/pets_black_48dp.png')
          .setSubtitle(text);
        card.setPeekCardHeader(peekHeader)
      }
    
      return card.build();
    }
    
    /**
     * Callback for the "Change cat" button.
     * @param {Object} e The event object, documented {@link
     *     https://developers.google.com/gmail/add-ons/concepts/actions#action_event_objects
     *     here}.
     * @return {CardService.ActionResponse} The action response to apply.
     */
    function onChangeCat(e) {
      console.log(e);
      // Get the text that was shown in the current cat image. This was passed as a
      // parameter on the Action set for the button.
      var text = e.parameters.text;
    
      // The isHomepage parameter is passed as a string, so convert to a Boolean.
      var isHomepage = e.parameters.isHomepage === 'true';
    
      // Create a new card with the same text.
      var card = createCatCard(text, isHomepage);
    
      // Create an action response that instructs the add-on to replace
      // the current card with the new one.
      var navigation = CardService.newNavigation()
          .updateCard(card);
      var actionResponse = CardService.newActionResponseBuilder()
          .setNavigation(navigation);
      return actionResponse.build();
    }
    
    /**
     * Truncate a message to fit in the cat image.
     * @param {string} message The message to truncate.
     * @return {string} The truncated message.
     */
    function truncate(message) {
      if (message.length > MAX_MESSAGE_LENGTH) {
        message = message.slice(0, MAX_MESSAGE_LENGTH);
        message = message.slice(0, message.lastIndexOf(' ')) + '...';
      }
      return message;
    }
    
      

    Gmail.gs

      /**
     * Callback for rendering the card for a specific Gmail message.
     * @param {Object} e The event object.
     * @return {CardService.Card} The card to show to the user.
     */
    function onGmailMessage(e) {
      console.log(e);
      // Get the ID of the message the user has open.
      var messageId = e.gmail.messageId;
    
      // Get an access token scoped to the current message and use it for GmailApp
      // calls.
      var accessToken = e.gmail.accessToken;
      GmailApp.setCurrentMessageAccessToken(accessToken);
    
      // Get the subject of the email.
      var message = GmailApp.getMessageById(messageId);
      var subject = message.getThread().getFirstMessageSubject();
    
      // Remove labels and prefixes.
      subject = subject
          .replace(/^([rR][eE]|[fF][wW][dD])\:\s*/, '')
          .replace(/^\[.*?\]\s*/, '');
    
      // If neccessary, truncate the subject to fit in the image.
      subject = truncate(subject);
    
      return createCatCard(subject);
    }
    
    /**
     * Callback for rendering the card for the compose action dialog.
     * @param {Object} e The event object.
     * @return {CardService.Card} The card to show to the user.
     */
    function onGmailCompose(e) {
      console.log(e);
      var header = CardService.newCardHeader()
          .setTitle('Insert cat')
          .setSubtitle('Add a custom cat image to your email message.');
      // Create text input for entering the cat's message.
      var input = CardService.newTextInput()
          .setFieldName('text')
          .setTitle('Caption')
          .setHint('What do you want the cat to say?');
      // Create a button that inserts the cat image when pressed.
      var action = CardService.newAction()
          .setFunctionName('onGmailInsertCat');
      var button = CardService.newTextButton()
          .setText('Insert cat')
          .setOnClickAction(action)
          .setTextButtonStyle(CardService.TextButtonStyle.FILLED);
      var buttonSet = CardService.newButtonSet()
          .addButton(button);
      // Assemble the widgets and return the card.
      var section = CardService.newCardSection()
          .addWidget(input)
          .addWidget(buttonSet);
      var card = CardService.newCardBuilder()
          .setHeader(header)
          .addSection(section);
      return card.build();
    }
    
    /**
     * Callback for inserting a cat into the Gmail draft.
     * @param {Object} e The event object.
     * @return {CardService.UpdateDraftActionResponse} The draft update response.
     */
    function onGmailInsertCat(e) {
      console.log(e);
      // Get the text that was entered by the user.
      var text = e.formInput.text;
      // Use the "Cat as a service" API to get the cat image. Add a "time" URL
      // parameter to act as a cache buster.
      var now = new Date();
      var imageUrl = 'https://cataas.com/cat';
      if (text) {
        // Replace forward slashes in the text, as they break the CataaS API.
        var caption = text.replace(/\//g, ' ');
        imageUrl += Utilities.formatString('/says/%s?time=%s',
            encodeURIComponent(caption), now.getTime());
      }
      var imageHtmlContent = '<img style="display: block; max-height: 300px;" src="'
          + imageUrl + '"/>';
      var response = CardService.newUpdateDraftActionResponseBuilder()
          .setUpdateDraftBodyAction(CardService.newUpdateDraftBodyAction()
              .addUpdateContent(imageHtmlContent,CardService.ContentType.MUTABLE_HTML)
              .setUpdateType(CardService.UpdateDraftBodyType.IN_PLACE_INSERT))
          .build();
      return response;
    }
    
      

    Calendar.gs

      /**
     * Callback for rendering the card for a specific Calendar event.
     * @param {Object} e The event object.
     * @return {CardService.Card} The card to show to the user.
     */
    function onCalendarEventOpen(e) {
      console.log(e);
      var calendar = CalendarApp.getCalendarById(e.calendar.calendarId);
      // The event metadata doesn't include the event's title, so using the
      // calendar.readonly scope and fetching the event by it's ID.
      var event = calendar.getEventById(e.calendar.id);
      if (!event) {
        // This is a new event still being created.
        return createCatCard('A new event! Am I invited?');
      }
      var title = event.getTitle();
      // If necessary, truncate the title to fit in the image.
      title = truncate(title);
      return createCatCard(title);
    }
    
      

    Drive.gs

      /**
     * Callback for rendering the card for specific Drive items.
     * @param {Object} e The event object.
     * @return {CardService.Card} The card to show to the user.
     */
    function onDriveItemsSelected(e) {
      console.log(e);
      var items = e.drive.selectedItems;
      // Include at most 5 items in the text.
      items = items.slice(0, 5);
      var text = items.map(function(item) {
        var title = item.title;
        // If neccessary, truncate the title to fit in the image.
        title = truncate(title);
        return title;
      }).join('\n');
      return createCatCard(text);
    }
    
      

  8. Klicken Sie auf Projekteinstellungen Das Symbol für die Projekteinstellungen.

  9. Setzen Sie ein Häkchen in das Kästchen Manifestdatei „appsscript.json“ im Editor anzeigen.

  10. Klicken Sie auf Editor .

  11. Öffnen Sie die Datei appsscript.json, ersetzen Sie den Inhalt durch den folgenden Code und klicken Sie auf „Speichern Symbol „Speichern““.

    appsscript.json

       {
      "timeZone": "America/New_York",
      "dependencies": {
      },
      "exceptionLogging": "STACKDRIVER",
      "oauthScopes": [
        "https://www.googleapis.com/auth/calendar.addons.execute",
        "https://www.googleapis.com/auth/calendar.readonly",
        "https://www.googleapis.com/auth/drive.addons.metadata.readonly",
        "https://www.googleapis.com/auth/gmail.addons.current.action.compose",
        "https://www.googleapis.com/auth/gmail.addons.current.message.readonly",
        "https://www.googleapis.com/auth/gmail.addons.execute",
        "https://www.googleapis.com/auth/script.locale"],
      "runtimeVersion": "V8",
      "addOns": {
        "common": {
          "name": "Cats",
          "logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/pets_black_48dp.png",
          "useLocaleFromApp": true,
          "homepageTrigger": {
            "runFunction": "onHomepage",
            "enabled": true
          },
          "universalActions": [{
            "label": "Learn more about Cataas",
            "openLink": "https://cataas.com"
          }]
        },
        "gmail": {
          "contextualTriggers": [{
            "unconditional": {
            },
            "onTriggerFunction": "onGmailMessage"
          }],
          "composeTrigger": {
            "selectActions": [{
              "text": "Insert cat",
              "runFunction": "onGmailCompose"
            }],
            "draftAccess": "NONE"
          }
        },
        "drive": {
          "onItemsSelectedTrigger": {
            "runFunction": "onDriveItemsSelected"
          }
        },
        "calendar": {
          "eventOpenTrigger": {
            "runFunction": "onCalendarEventOpen"
          }
        }
      }
    }
    
      

Cloud-Projektnummer kopieren

  1. Klicken Sie in der Google Cloud Console auf das Dreipunkt-Menü  > IAM und Verwaltung > Einstellungen.

    Weiter zur Seite „IAM & Verwaltung“

  2. Kopieren Sie den Wert aus dem Feld Projektnummer.

Cloud-Projekt des Apps Script-Projekts festlegen

  1. Klicken Sie in Ihrem Apps Script-Projekt auf Projekteinstellungen Das Symbol für die Projekteinstellungen.
  2. Klicken Sie unter Google Cloud Platform-Projekt (GCP-Projekt) auf Projekt ändern.
  3. Fügen Sie unter GCP-Projektnummer die Google Cloud-Projektnummer ein.
  4. Klicken Sie auf Projekt festlegen.

Testbereitstellung installieren

  1. Klicken Sie in Ihrem Apps Script-Projekt auf Editor .
  2. Klicken Sie auf Bereitstellen > Bereitstellungen testen.
  3. Klicken Sie auf Installieren > Fertig.

Skript ausführen

  1. Rufen Sie Gmail auf.
  2. Klicken Sie in der rechten Seitenleiste auf „Katzen“ , um das Add-on zu öffnen.
  3. Autorisieren Sie das Add-on, wenn Sie dazu aufgefordert werden.
  4. Das Add-on zeigt ein Katzenbild und Text an. Wenn Sie das Bild ändern möchten, klicken Sie auf Kategorie ändern.
  5. Wenn Sie eine E-Mail öffnen, während das Add-on geöffnet ist, wird das Bild aktualisiert und der Text ändert sich in die Betreffzeile der E-Mail. Ist sie zu lang, wird sie abgeschnitten.

Ähnliche Funktionen finden Sie in Google Kalender und Google Drive. Sie müssen das Add-on nicht noch einmal autorisieren, um es in diesen Host-Apps zu verwenden.

Nächste Schritte