Gmail-Nachrichten mit Gemini und Vertex AI analysieren und labeln

Bei dieser Lösung werden Gmail-Nachrichten mit Vertex AI und Gemini analysiert und anhand ihrer Stimmung gekennzeichnet.

Programmierkenntnisse: Mittelstufe
Dauer: 30 Minuten
Projekttyp: Google Workspace-Add-on

  • Ein Google Workspace-Add-on, das Gmail in einer Seitenleiste erweitert.
    Abbildung 1:Das Add-on Sentiment Analysis zeigt in Gmail eine Seitenleiste an, in der Nutzer Gemini auffordern können, Nachrichten anhand der Stimmung zu analysieren und Labels anzuwenden.
  • Eine Gmail-Nachricht mit neutraler Stimmung.
    Abbildung 2:Das Add-on kennzeichnet eine Gmail-Nachricht mit dem Label NEUTRALER TON 😐.
  • Eine Gmail-Nachricht mit positiver Stimmung.
    Abbildung 3:Das Add-on kennzeichnet eine Gmail-Nachricht mit dem Label HAPPY TONE 😊.
  • Eine Gmail-Nachricht mit verärgertem Tenor.
    Abbildung 4:Das Add-on kennzeichnet eine Gmail-Nachricht mit dem Label UPSET TONE 😡.

Lernziele

  • Verstehen, was die Lösung bewirkt.
  • Informationen dazu, was die Google-Dienste in der Lösung tun.
  • Umgebung einrichten
  • Richten Sie das Google Apps Script-Projekt ein.
  • Führen Sie das Skript aus.

Informationen zu dieser Lösung

Screenshot des Google Workspace-Add‑ons „Sentimentanalyse“

Diese Lösung ist ein Google Workspace-Add‑on, mit dem Labels basierend auf der Stimmung von Gmail-Nachrichten angewendet werden. Um den Inhalt der Nachricht zu analysieren, verwendet das Add-on Vertex AI, um das Gemini 2.5 Flash-Modell zu verwenden und eines der folgenden Stimmungen zurückzugeben:

  • Positiv
  • Negativ
  • Neutral

Anhand der Antwort von Gemini wendet das Add-on ein entsprechendes Gmail-Label auf die Nachricht an.

Um die Anfrage auf die Vertex AI API zu beschränken, werden mit diesem Add-on nur die zehn neuesten Nachrichten im Posteingang des Gmail-Nutzers analysiert und mit Labels versehen. Weitere Informationen zu Kontingenten und Limits finden Sie in der Vertex AI-Dokumentation.

Funktionsweise

Diese Lösung basiert auf Google Apps Script und verwendet die folgenden Google-Dienste und -Produkte:

  • Vertex AI API: Fordert das Gemini 2.5 Flash-Modell auf, den Inhalt von Gmail-Nachrichten zu analysieren und die Stimmung zu ermitteln.
  • Apps Script-Dienste:

    • Gmail-Dienst: Ruft Labels für Gmail-Nachrichten ab und wendet sie an. Optional: Erstellt Beispielnachrichten zum Testen des Add-ons.
    • Kartendienst: Erstellt die Benutzeroberfläche des Add-ons, die als Seitenleiste in Gmail angezeigt wird.
    • URL Fetch-Dienst: Stellt eine Verbindung zur Vertex AI API für die Sentimentanalyse her.
    • Script-Dienst: Zum Aufrufen der Vertex AI API wird mit der Methode getOAuthToken ein OAuth 2.0-Zugriffstoken für das Add-on abgerufen.

Vorbereitung

Umgebung einrichten

In diesem Abschnitt wird beschrieben, wie Sie Ihre Umgebung in der Google Cloud Console und in Apps Script konfigurieren und einrichten.

Cloud-Projekt in der Google Cloud Console konfigurieren

In diesem Abschnitt erfahren Sie, wie Sie die Vertex AI API aktivieren und den OAuth-Zustimmungsbildschirm in Ihrem Cloud-Projekt konfigurieren.

Vertex AI API aktivieren

  1. Öffnen Sie in der Google Cloud Console Ihr Google Cloud-Projekt und aktivieren Sie die Vertex AI API:

    API aktivieren

  2. Bestätigen Sie, dass Sie die API im richtigen Cloud-Projekt aktivieren, und klicken Sie dann auf Weiter.

  3. Prüfen Sie, ob Sie die richtige API aktivieren, und klicken Sie dann auf Aktivieren.

OAuth-Zustimmungsbildschirm konfigurieren

Für Google Workspace-Add-ons ist eine Konfiguration des Einwilligungsbildschirms erforderlich. Wenn Sie den OAuth-Zustimmungsbildschirm Ihres Add-ons konfigurieren, legen Sie fest, was Google Nutzern anzeigt.

  1. Rufen Sie in der Google Cloud Console das Menü  > > Branding auf.

    Zu Branding

  2. Wenn Sie die bereits konfiguriert haben, können Sie die folgenden Einstellungen für den OAuth-Zustimmungsbildschirm unter Branding, Zielgruppe und Datenzugriff konfigurieren. Wenn Sie die Meldung noch nicht konfiguriert sehen, klicken Sie auf Jetzt starten:
    1. Geben Sie unter App-Informationen im Feld App-Name einen Namen für die App ein.
    2. Wählen Sie unter E-Mail-Adresse des Nutzersupports eine Support-E-Mail-Adresse aus, über die Nutzer Sie mit Fragen zu ihrer Einwilligung kontaktieren können.
    3. Klicken Sie auf Weiter.
    4. Wählen Sie unter Zielgruppe die Option Intern aus.
    5. Klicken Sie auf Weiter.
    6. Geben Sie unter Kontaktdaten eine E-Mail-Adresse ein, unter der Sie über Änderungen an Ihrem Projekt benachrichtigt werden können.
    7. Klicken Sie auf Weiter.
    8. Sehen Sie sich unter Fertigstellen die Nutzerdatenrichtlinie für Google API-Dienste an. Wenn Sie damit einverstanden sind, wählen Sie Ich stimme der Nutzerdatenrichtlinie für Google API-Dienste zu aus.
    9. Klicken Sie auf Weiter.
    10. Klicken Sie auf Erstellen.
  3. Sie können das Hinzufügen von Bereichen vorerst überspringen. 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. Fügen Sie dann die Autorisierungsbereiche hinzu, die für Ihre App erforderlich sind. Weitere Informationen finden Sie in der vollständigen Anleitung OAuth-Zustimmung konfigurieren.

Apps Script-Projekt erstellen und einrichten

So erstellen und richten Sie Ihr Apps Script-Projekt für das Add-on ein:

  1. Klicken Sie auf die folgende Schaltfläche, um das Apps Script-Projekt Gmail Sentiment Analysis with Gemini and Vertex AI (Gmail-Stimmungsanalyse mit Gemini und Vertex AI) zu öffnen.
    Apps Script-Projekt öffnen

  2. Klicken Sie auf Übersicht .

  3. Klicken Sie auf der Übersichtsseite auf „Kopie erstellen“ Symbol zum Erstellen einer Kopie.

  4. Rufen Sie die Nummer Ihres Cloud-Projekts ab:

    1. Rufen Sie in der Google Cloud Console das Menü  > IAM & Verwaltung > Einstellungen auf.

      Weiter zur Seite „IAM & Verwaltung“

    2. Kopieren Sie den Wert aus dem Feld Projektnummer.
  5. Verknüpfen Sie Ihr Cloud-Projekt mit Ihrem Apps Script-Projekt:

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

Add-on testen

Wenn Sie das Add-on ausprobieren möchten, installieren Sie eine Testbereitstellung und öffnen Sie das Add-on dann in Gmail:

  1. Apps Script-Testbereitstellung erstellen und installieren:
    1. Klicken Sie in Ihrem kopierten Apps Script-Projekt auf Editor .
    2. Öffnen Sie die Datei Code.gs und klicken Sie auf Ausführen. Autorisieren Sie das Skript, wenn Sie dazu aufgefordert werden.
    3. Klicken Sie auf Bereitstellen > Testbereitstellungen.
    4. Klicken Sie auf Installieren > Fertig.
  2. Öffnen Sie Google Mail.

    Gmail aufrufen

  3. Öffnen Sie in der rechten Seitenleiste das Add-on Sentiment Analysis.

  4. Autorisieren Sie das Add‑on, wenn Sie dazu aufgefordert werden.

  5. Optional: Wenn Sie Nachrichten zum Testen Ihres Add-ons erstellen möchten, klicken Sie auf Beispiel-E‑Mails generieren. Drei Nachrichten werden in Ihrem Posteingang angezeigt. Wenn Sie sie nicht sehen, aktualisieren Sie die Seite.

  6. Klicken Sie auf E‑Mails analysieren, um Labels hinzuzufügen.

Das Add-on prüft die letzten 10 Nachrichten in Ihrem Posteingang und wendet dann basierend auf dem Inhalt der Nachricht eines der folgenden Labels an:

  • FREUNDLICHER TON 😊
  • NEUTRALER TON 😐
  • VERÄRGERT 😡

Code ansehen

Apps Script-Code für diese Lösung ansehen:

Quellcode ansehen

Code.gs

gmail-sentiment-analysis/Code.gs
/*
Copyright 2024 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
 * Triggered when the add-on is opened from the Gmail homepage.
 *
 * @param {Object} e - The event object.
 * @returns {Card} - The homepage card.
 */
function onHomepageTrigger(e) {
  return buildHomepageCard();
}

Cards.gs

gmail-sentiment-analysis/Cards.gs
/*
Copyright 2024-2025 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
 * Builds the main card displayed on the Gmail homepage.
 *
 * @returns {Card} - The homepage card.
 */
function buildHomepageCard() {
  // Create a new card builder
  const cardBuilder = CardService.newCardBuilder();

  // Create a card header
  const cardHeader = CardService.newCardHeader();
  cardHeader.setImageUrl('https://fonts.gstatic.com/s/i/googlematerialicons/mail/v6/black-24dp/1x/gm_mail_black_24dp.png');
  cardHeader.setImageStyle(CardService.ImageStyle.CIRCLE);
  cardHeader.setTitle("Analyze your Gmail");

  // Add the header to the card
  cardBuilder.setHeader(cardHeader);

  // Create a card section
  const cardSection = CardService.newCardSection();

  // Create buttons for generating sample emails and analyzing sentiment
  const buttonSet = CardService.newButtonSet();

  // Create "Generate sample emails" button
  const generateButton = createFilledButton('Generate sample emails', 'generateSampleEmails', '#34A853');
  buttonSet.addButton(generateButton);

  // Create "Analyze emails" button
  const analyzeButton = createFilledButton('Analyze emails', 'analyzeSentiment', '#FF0000');
  buttonSet.addButton(analyzeButton);

  // Add the button set to the section
  cardSection.addWidget(buttonSet);

  // Add the section to the card
  cardBuilder.addSection(cardSection);

  // Build and return the card
  return cardBuilder.build();
}

/**
 * Creates a filled text button with the specified text, function, and color.
 *
 * @param {string} text - The text to display on the button.
 * @param {string} functionName - The name of the function to call when the button is clicked.
 * @param {string} color - The background color of the button.
 * @returns {TextButton} - The created text button.
 */
function createFilledButton(text, functionName, color) {
  // Create a new text button
  const textButton = CardService.newTextButton();

  // Set the button text
  textButton.setText(text);

  // Set the action to perform when the button is clicked
  const action = CardService.newAction();
  action.setFunctionName(functionName);
  textButton.setOnClickAction(action);

  // Set the button style to filled
  textButton.setTextButtonStyle(CardService.TextButtonStyle.FILLED);

  // Set the background color
  textButton.setBackgroundColor(color);

  return textButton;
}

/**
 * Creates a notification response with the specified text.
 *
 * @param {string} notificationText - The text to display in the notification.
 * @returns {ActionResponse} - The created action response.
 */
function buildNotificationResponse(notificationText) {
  // Create a new notification
  const notification = CardService.newNotification();
  notification.setText(notificationText);

  // Create a new action response builder
  const actionResponseBuilder = CardService.newActionResponseBuilder();

  // Set the notification for the action response
  actionResponseBuilder.setNotification(notification);

  // Build and return the action response
  return actionResponseBuilder.build();
}

Gmail.gs

gmail-sentiment-analysis/Gmail.gs
/*
Copyright 2024-2025 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
 * Analyzes the sentiment of the first 10 threads in the inbox
 * and labels them accordingly.
 *
 * @returns {ActionResponse} - A notification confirming completion.
 */
function analyzeSentiment() {
  // Analyze and label emails
  analyzeAndLabelEmailSentiment();

  // Return a notification
  return buildNotificationResponse("Successfully completed sentiment analysis");
}

/**
 * Analyzes the sentiment of emails and applies appropriate labels.
 */
function analyzeAndLabelEmailSentiment() {
  // Define label names
  const labelNames = ["HAPPY TONE 😊", "NEUTRAL TONE 😐", "UPSET TONE 😡"];

  // Get or create labels for each sentiment
  const positiveLabel = GmailApp.getUserLabelByName(labelNames[0]) || GmailApp.createLabel(labelNames[0]);
  const neutralLabel = GmailApp.getUserLabelByName(labelNames[1]) || GmailApp.createLabel(labelNames[1]);
  const negativeLabel = GmailApp.getUserLabelByName(labelNames[2]) || GmailApp.createLabel(labelNames[2]);

  // Get the first 10 threads in the inbox
  const threads = GmailApp.getInboxThreads(0, 10);

  // Iterate through each thread
  for (const thread of threads) {
    // Iterate through each message in the thread
    const messages = thread.getMessages();
    for (const message of messages) {
      // Get the plain text body of the message
      const emailBody = message.getPlainBody();

      // Analyze the sentiment of the email body
      const sentiment = processSentiment(emailBody);

      // Apply the appropriate label based on the sentiment
      if (sentiment === 'positive') {
        thread.addLabel(positiveLabel);
      } else if (sentiment === 'neutral') {
        thread.addLabel(neutralLabel);
      } else if (sentiment === 'negative') {
        thread.addLabel(negativeLabel);
      }
    }
  }
}

/**
 * Generates sample emails for testing the sentiment analysis.
 *
 * @returns {ActionResponse} - A notification confirming email generation.
 */
function generateSampleEmails() {
  // Get the current user's email address
  const userEmail = Session.getActiveUser().getEmail();

  // Define sample emails
  const sampleEmails = [
    {
      subject: 'Thank you for amazing service!',
      body: 'Hi, I really enjoyed working with you. Thank you again!',
      name: 'Customer A'
    },
    {
      subject: 'Request for information',
      body: 'Hello, I need more information on your recent product launch. Thank you.',
      name: 'Customer B'
    },
    {
      subject: 'Complaint!',
      body: '',
      htmlBody: `<p>Hello, You are late in delivery, again.</p>
<p>Please contact me ASAP before I cancel our subscription.</p>`,
      name: 'Customer C'
    }
  ];

  // Send each sample email
  for (const email of sampleEmails) {
    GmailApp.sendEmail(userEmail, email.subject, email.body, {
      name: email.name,
      htmlBody: email.htmlBody
    });
  }

  // Return a notification
  return buildNotificationResponse("Successfully generated sample emails");
}

Vertex.gs

gmail-sentiment-analysis/Vertex.gs
/*
Copyright 2024-2025 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Replace with your project ID
const PROJECT_ID = '[ADD YOUR GCP PROJECT ID HERE]';

// Location for your Vertex AI model
const VERTEX_AI_LOCATION = 'us-central1';

// Model ID to use for sentiment analysis
const MODEL_ID = 'gemini-2.5-flash';

/**
 * Sends the email text to Vertex AI for sentiment analysis.
 *
 * @param {string} emailText - The text of the email to analyze.
 * @returns {string} - The sentiment of the email ('positive', 'negative', or 'neutral').
 */
function processSentiment(emailText) {
  // Construct the API endpoint URL
  const apiUrl = `https://${VERTEX_AI_LOCATION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${VERTEX_AI_LOCATION}/publishers/google/models/${MODEL_ID}:generateContent`;

  // Prepare the request payload
  const payload = {
    contents: [
      {
        role: "user",
        parts: [
          {
            text: `Analyze the sentiment of the following message: ${emailText}`
          }
        ]
      }
    ],
    generationConfig: {
      temperature: 0.9,
      maxOutputTokens: 1024,
      responseMimeType: "application/json",
      // Expected response format for simpler parsing.
      responseSchema: {
        type: "object",
        properties: {
          response: {
            type: "string",
            enum: ["positive", "negative", "neutral"]
          }
        }
      }
    }
  };

  // Prepare the request options
  const options = {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${ScriptApp.getOAuthToken()}`
    },
    contentType: 'application/json',
    muteHttpExceptions: true, // Set to true to inspect the error response
    payload: JSON.stringify(payload)
  };

  // Make the API request
  const response = UrlFetchApp.fetch(apiUrl, options);

  // Parse the response. There are two levels of JSON responses to parse.
  const parsedResponse = JSON.parse(response.getContentText());
  const sentimentResponse = JSON.parse(parsedResponse.candidates[0].content.parts[0].text).response;

  // Return the sentiment
  return sentimentResponse;
}

appsscript.json

gmail-sentiment-analysis/appsscript.json
{
  "timeZone": "America/Toronto",
  "oauthScopes": [
    "https://www.googleapis.com/auth/cloud-platform",
    "https://www.googleapis.com/auth/gmail.addons.execute",
    "https://www.googleapis.com/auth/gmail.labels",
    "https://www.googleapis.com/auth/gmail.modify",
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/userinfo.email"
  ],
  "addOns": {
    "common": {
      "name": "Sentiment Analysis",
      "logoUrl": "https://fonts.gstatic.com/s/i/googlematerialicons/sentiment_extremely_dissatisfied/v6/black-24dp/1x/gm_sentiment_extremely_dissatisfied_black_24dp.png"
    },
    "gmail": {
      "homepageTrigger": {
        "runFunction": "onHomepageTrigger",
        "enabled": true
      }
    }
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8"
}

Bereinigen

Damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, empfehlen wir, das Cloud-Projekt zu löschen.

  1. Wechseln Sie in der Google Cloud Console zur Seite Ressourcen verwalten. Klicken Sie auf das Menü > IAM & Verwaltung > Ressourcen verwalten.

    Zum Ressourcenmanager

  2. Wählen Sie in der Projektliste das Projekt aus, das Sie löschen möchten, und klicken Sie dann auf Löschen .
  3. Geben Sie im Dialogfeld die Projekt-ID ein und klicken Sie auf Beenden, um das Projekt zu löschen.

Nächste Schritte