Analizzare ed etichettare i messaggi Gmail con Gemini e Vertex AI

Questa soluzione utilizza Vertex AI e Gemini per analizzare i messaggi Gmail e assegnare loro un'etichetta in base al sentiment.

Livello di programmazione: intermedio
Durata: 30 minuti
Tipo di progetto: componente aggiuntivo di Google Workspace

  • Un componente aggiuntivo di Google Workspace che estende Gmail in una barra laterale.
    Figura 1: il componente aggiuntivo Analisi del sentiment mostra una barra laterale in Gmail in cui gli utenti possono chiedere a Gemini di analizzare e applicare etichette ai messaggi in base al sentiment.
  • Un messaggio Gmail con un sentimento neutro.
    Figura 2: il componente aggiuntivo etichetta un messaggio Gmail con l'etichetta TONO NEUTRO 😐.
  • Un messaggio Gmail con un sentimento positivo.
    Figura 3: il componente aggiuntivo etichetta un messaggio Gmail con l'etichetta TONO FELICE 😊.
  • Un messaggio Gmail con un sentimento negativo.
    Figura 4: il componente aggiuntivo etichetta un messaggio Gmail con l'etichetta TONO DI RABBIA 😡.

Obiettivi

  • Comprendere cosa fa la soluzione.
  • Scopri cosa fanno i servizi Google all'interno della soluzione.
  • Configura l'ambiente.
  • Configura il progetto Google Apps Script.
  • Esegui lo script.

Informazioni su questa soluzione

Screenshot del componente aggiuntivo di Google Workspace per l'analisi del sentiment

Questa soluzione è un componente aggiuntivo di Google Workspace che applica etichette in base al sentimento dei messaggi Gmail. Per analizzare i contenuti del messaggio, il componente aggiuntivo utilizza Vertex AI per richiedere al modello Gemini 2.5 Flash e restituire uno dei seguenti sentiment:

  • Positivo
  • Negativo
  • Neutro

Con la risposta di Gemini, il componente aggiuntivo applica un'etichetta Gmail corrispondente al messaggio.

Per limitare la richiesta all'API Vertex AI, questo componente aggiuntivo analizza e applica etichette solo ai 10 messaggi più recenti nella Posta in arrivo dell'utente Gmail. Per saperne di più su quote e limiti, consulta la documentazione di Vertex AI.

Come funziona

Questa soluzione è creata in Google Apps Script e utilizza i seguenti servizi Apps Script e prodotti Google Cloud:

  • Servizio Gmail: recupera e applica etichette ai messaggi Gmail. (Facoltativo) crea messaggi di esempio per testare il componente aggiuntivo.
  • Servizio di schede: crea l'interfaccia utente del componente aggiuntivo che viene visualizzata come barra laterale in Gmail.
  • Servizio di recupero URL: si connette all'API Vertex AI per l'analisi del sentiment.
  • API Vertex AI: richiede al modello Gemini 2.5 Flash di analizzare il contenuto dei messaggi Gmail e identificare il sentiment.

Prerequisiti

Configura l'ambiente

Questa sezione spiega come configurare e impostare l'ambiente nella console Google Cloud e in Apps Script.

Configurare il progetto Cloud nella console Google Cloud

Questa sezione mostra come abilitare l'API Vertex AI e configurare la schermata per il consenso OAuth nel tuo progetto Cloud.

Abilita l'API Vertex AI

  1. Nella console Google Cloud, apri il tuo progetto Google Cloud e abilita l'API Vertex AI:

    Abilita l'API

  2. Verifica di abilitare l'API nel progetto Cloud corretto, poi fai clic su Avanti.

  3. Verifica di aver attivato l'API corretta, poi fai clic su Attiva.

Configura la schermata per il consenso OAuth

I componenti aggiuntivi di Google Workspace richiedono una configurazione della schermata di consenso. La configurazione della schermata per il consenso OAuth del componente aggiuntivo definisce ciò che Google mostra agli utenti.

  1. Nella console Google Cloud, vai a Menu > > Branding.

    Vai a Branding

  2. Se hai già configurato , puoi configurare le seguenti impostazioni della schermata per il consenso OAuth in Branding, Pubblico e Accesso ai dati. Se viene visualizzato il messaggio non ancora configurata, fai clic su Inizia:
    1. In Informazioni sull'app, nel campo Nome app, inserisci un nome per l'app.
    2. In Email dell'assistenza utente, scegli un indirizzo email dell'assistenza a cui gli utenti possono contattarti in caso di domande sul loro consenso.
    3. Fai clic su Avanti.
    4. Nella sezione Pubblico, seleziona Interno.
    5. Fai clic su Avanti.
    6. In Informazioni di contatto, inserisci un indirizzo email a cui ricevere notifiche in caso di modifiche al tuo progetto.
    7. Fai clic su Avanti.
    8. In Fine, esamina le Norme relative ai dati utente dei servizi API di Google e, se le accetti, seleziona Accetto le Norme relative ai dati utente dei servizi API di Google.
    9. Fai clic su Continua.
    10. Fai clic su Crea.
  3. Per ora puoi saltare l'aggiunta degli ambiti. In futuro, quando crei un'app da utilizzare al di fuori della tua organizzazione Google Workspace, devi modificare il Tipo di utente in Esterno. Poi aggiungi gli ambiti di autorizzazione richiesti dalla tua app. Per saperne di più, consulta la guida completa Configurare il consenso OAuth.

Creare e configurare il progetto Apps Script

Per creare e configurare il progetto Apps Script per il componente aggiuntivo, completa i seguenti passaggi:

  1. Fai clic sul pulsante seguente per aprire il progetto Analisi del sentiment di Gmail con Gemini e Vertex AI Apps Script.
    Apri il progetto Apps Script

  2. Fai clic su Panoramica .

  3. Nella pagina di panoramica, fai clic su Crea una copia L'icona per creare una copia.

  4. Recupera il numero del tuo progetto Cloud:

    1. Nella console Google Cloud, vai a Menu > IAM e amministrazione > Impostazioni.

      Vai a IAM e amministrazione > Impostazioni

    2. Nel campo Numero di progetto, copia il valore.
  5. Collega il tuo progetto Cloud al tuo progetto Apps Script:

    1. Nel progetto Apps Script copiato, fai clic su Impostazioni progetto L'icona delle impostazioni del progetto.
    2. In Progetto Google Cloud (GCP), fai clic su Cambia progetto.
    3. In Numero di progetto Google Cloud, incolla il numero di progetto Cloud.
    4. Fai clic su Imposta progetto.

Testare il componente aggiuntivo

Per provare il componente aggiuntivo, installa un deployment di test e poi apri il componente aggiuntivo in Gmail:

  1. Crea e installa un deployment di test di Apps Script:
    1. Nel progetto Apps Script copiato, fai clic su Editor .
    2. Apri il file Code.gs e fai clic su Esegui. Quando richiesto, autorizza lo script.
    3. Fai clic su Esegui il deployment > Testa i deployment.
    4. Fai clic su Installa > Fine.
  2. Apri Gmail.

    Vai a Gmail

  3. Nella barra laterale destra, apri il componente aggiuntivo Analisi del sentiment.

  4. Se richiesto, autorizza il componente aggiuntivo.

  5. (Facoltativo) Per creare messaggi da testare con il tuo componente aggiuntivo, fai clic su Genera email di esempio. Nella Posta in arrivo vengono visualizzati tre messaggi. Se non li vedi, aggiorna la pagina.

  6. Per aggiungere etichette, fai clic su Analizza email.

Il componente aggiuntivo esamina gli ultimi 10 messaggi nella tua casella di posta e poi applica una delle seguenti etichette in base al contenuto del messaggio:

  • TONO FELICE 😊
  • TONO NEUTRO 😐
  • TONO DI RABBIA 😡

Esamina il codice

Esamina il codice Apps Script per questa soluzione:

Visualizza codice sorgente

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"
}

Esegui la pulizia

Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, ti consigliamo di eliminare il progetto Cloud.

  1. Nella console Google Cloud, vai alla pagina Gestisci risorse. Fai clic su Menu > IAM e amministrazione > Gestisci risorse.

    Vai a Resource Manager

  2. Nell'elenco dei progetti, seleziona quello che vuoi eliminare, quindi fai clic su Elimina .
  3. Nella finestra di dialogo, digita l'ID progetto, quindi fai clic su Chiudi per eliminare il progetto.

Passaggi successivi