Flexible Labeling for Gmail using Gemini Pro API with Google Apps Script

Gists

Abstract

The release of Gemini API is expected to expand the future of Google Apps Script. This report introduces a sample script for flexible email labeling in Gmail using Gemini API with Google Apps Script.

Introduction

The recent release of the LLM model Gemini as an API on Vertex AI and Google AI Studio opens a world of possibilities. Ref and Ref I believe Gemini API significantly expands the potential of Google Apps Script and paves the way for diverse applications. In this report, I present a sample script for flexible email labeling in Gmail using Gemini Pro API with Google Apps Script.

Currently, Gmail email labeling relies on directly checking for specific words. This becomes cumbersome when users want to label emails based on their overall content, requiring manual review and understanding. Flexible labeling promises significant value in managing large volumes of emails. This report delves into the possibility of automating this process with a simple script leveraging Gemini API.

Usage

In order to test this script, please do the following flow.

1. Create an API key

Please access https://makersuite.google.com/app/apikey and create your API key. At that time, please enable Generative Language API at the API console. This API key is used for this sample script.

This official document can be also seen. Ref.

2. Create a Google Apps Script project

Please create a standalone Google Apps Script project. Of course, this script can be also used with the container-bound script.

And, please open the script editor of the Google Apps Script project.

3. Sample script

Please copy and paste the following script to the script editor, set your API key, and save the script.

Also, please modify labalObj to your actual situation.

When you run the function setLabelByGeminiAPI, the script retrieves the recent emails and adds labels using an object labalObj. This function can be run independently. If you want to run this function by the time-driven trigger, please run the function setTimeDrivenTrigger. By this, the function setLabelByGeminiAPI is automatically run every 10 minutes.

This script labels to emails using the object labalObj. In the case of sample value const labalObj = { "academic": "sampleLabel1", "finance": "sampleLabel2", "advertisement": "sampleLabel3", "other": "INBOX" }, when the email is related to academic, finance, and advertisement, the labels sampleLabel1, sampleLabel2, and sampleLabel3 are added, respectively. When the email is not related to academic, finance, and advertisement, the script is stopped.

This sample script uses v1beta. If the version is changed, please modify the endpoint. Also, please confirm the specifications of the new version.

function setLabelByGeminiAPI() {
  const apiKey = "###"; // Please set your API key.

  // Please set the keywards and the label names of the keywards.
  const labalObj = { "academic": "sampleLabel1", "finance": "sampleLabel2", "advertisement": "sampleLabel3", "other": "INBOX" };

  const now = new Date();
  const nowTime = now.getTime();
  const p = PropertiesService.getScriptProperties();
  let prev = p.getProperty("prev");
  if (!prev) {
    prev = nowTime - 60 * 60 * 1000; // If you run this script for the first time or prev is undefined, emails from your inbox in the past 1 hour are retrieved.
  }
  const threads = GmailApp.getInboxThreads().filter(t => t.getLastMessageDate().getTime() > prev);
  if (threads.length == 0) return;
  const keys = Object.keys(labalObj);
  threads.forEach(t => {
    const lastMessageDate = t.getLastMessageDate().getTime();
    const lastMessage = t.getMessages().find(m => m.getDate().getTime() == lastMessageDate);
    const text = lastMessage.getPlainBody();
    const q = `Read the following text and select one of the words of "${keys.join(",")}" related to the text.`;
    const url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=" + apiKey;
    const payload = { contents: [{ parts: [{ text: q }, { text }] }] };
    const options = {
      payload: JSON.stringify(payload),
      contentType: "application/json",
    }
    const res = UrlFetchApp.fetch(url, options);
    const obj = JSON.parse(res.getContentText());
    if (obj.candidates.length > 0 && obj.candidates[0].content.parts.length > 0) {
      const k = obj.candidates[0].content.parts[0].text.trim().toLowerCase();
      const kk = keys.find(e => k.includes(e)) || "other";
      iif (kk != "other" && labalObj[kk]) {
        t.moveToArchive();
        t.addLabel(GmailApp.getUserLabelByName(labalObj[kk]));
      }
    } else {
      console.warn("No response.");
    }
  });
  p.setProperty("prev", nowTime.toString());
}

function setTimeDrivenTrigger() {
  const functionName = "setLabelByGeminiAPI";
  ScriptApp.getProjectTriggers().forEach(t => {
    if (t.getHandlerFunction() == functionName) {
      ScriptApp.deleteTrigger(t);
    }
  });
  ScriptApp.newTrigger(functionName).timeBased().everyMinutes(10).create();
}

In this sample, Gemini API selects one of the keys of labalObj by reading the email, and the specific label is used using the selected key. This is an important point of this process.

If you don’t want to move the email to the folder of the label, please remove the line of t.moveToArchive();.

4. Testing

When I tested this script for sample emails, the labels were correctly added to about 90 % of emails. However, I think that I have still not been able to test various emails. So, if there is a large number of situations that the labels are not correctly added, I would like to recommend to consider modifying const q = Read the following text and select one of the words of “${keys.join(”,")}" related to the text.;. I would like to expect future updates to refine the Gemini API and further improve the overall accuracy.

Summary

From this result, I believe that Gemini API has the potential to be used for automatic labeling in Gmail.

Note

  • In the current stage, Gemini Pro API can be requested 60 times in 1 minute as the default. Ref Please be careful about this.

Reference

  • Method: models.generateContent

  • In the current stage, Gemini Pro can be freely used. But the official site says that the competitively priced will be given in the future. Ref

 Share!