IntegrationsIntermediate

How to auto-label and prioritize Gmail with AI using Apps Script

Write a Google Apps Script that sends new emails to an AI model and applies priority labels so your inbox sorts itself.

10 minIntermediate

Gmail filters match keywords, but they cannot judge what is actually urgent. This guide uses Google Apps Script (free, runs inside your Google account) to send each unread email to an AI model and apply a label like Priority, FYI, or Newsletter based on the content. A time trigger runs it every few minutes.

  • A Gmail account
  • An OpenAI API key (or another HTTP-callable model)
  • Five minutes of comfort with copy-pasting code
  • About 10 minutes total

Step 1: Create labels and open the script editor

In Gmail, create three labels: Priority, FYI, and Newsletter. Then go to script.google.com and start a new project. This script runs as you, so it already has permission to read and label your mail once you authorize it.

Step 2: Store your API key safely

Do not hardcode your API key in the script body. Use Script Properties instead. In the editor open Project Settings, scroll to Script Properties, and add a property named OPENAI_KEY with your key as the value.

Apps Script - Project Settings
Project Settings > Script Properties
+ Add script property
Property: OPENAI_KEY
Value: sk-... (hidden)
[ Save script properties ]
Script Properties keep the key out of your source code.

Step 3: Paste the classification script

This function reads the latest unread threads, asks the model for one of three labels, and applies it. It uses UrlFetchApp to call the API and PropertiesService to read your key.

Code.gs
function labelInbox() {
  const key = PropertiesService.getScriptProperties().getProperty('OPENAI_KEY');
  const threads = GmailApp.search('is:unread in:inbox', 0, 10);

  threads.forEach(function (thread) {
    const msg = thread.getMessages()[0];
    const text = (msg.getSubject() + '\n' + msg.getPlainBody()).slice(0, 4000);

    const res = UrlFetchApp.fetch('https://api.openai.com/v1/chat/completions', {
      method: 'post',
      contentType: 'application/json',
      headers: { Authorization: 'Bearer ' + key },
      payload: JSON.stringify({
        model: 'gpt-5-mini',
        messages: [{
          role: 'user',
          content: 'Reply with exactly one word, Priority FYI or Newsletter, ' +
                   'for this email:\n' + text
        }]
      })
    });

    const label = JSON.parse(res.getContentText())
      .choices[0].message.content.trim();

    const gmailLabel = GmailApp.getUserLabelByName(label);
    if (gmailLabel) thread.addLabel(gmailLabel);
  });
}
Mind the quota
UrlFetchApp and Gmail both have daily quotas on free accounts. Searching 10 threads per run is safe. Do not loop over thousands of emails at once or the script will hit a limit and stop.

Step 4: Add a time trigger

In the editor click the clock icon (Triggers), Add Trigger, choose the labelInbox function, event source Time-driven, and a minutes timer of every 5 minutes. Authorize the scopes when prompted. Your inbox now classifies itself in the background.

Apps Script - Execution log
Trigger fires every 5 minutes
labelInbox Started
Thread 'Invoice overdue' -> Priority
Thread 'Weekly digest' -> Newsletter
labelInbox Completed (1.9 s)
$

Result: new mail is tagged Priority, FYI, or Newsletter within minutes of arriving. You open the Priority label first and ignore the rest until you have time, all without a paid service.

Watch related tutorials

Tags
#gmail#apps-script#ai#labels