◉GEMINI LABJP
●ARGON — gemini-4-argon is generally available as of 10/13, aimed at complex coding, agents, math and science●DEEP RES — deep-research-pro-preview-12-2025 shuts down 10/23, 6 days left. Move to deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 is GA (10/06). gemini-3.1-flash-image is deprecated with no shutdown date yet●MCP — One write-up cut an 85,000-token tool result to 310 tokens by wrapping it in an ADK FunctionTool●FLASH — gemini-3.7-flash and 3.5-flash now route automatically to newer Flash models (10/08)●NEW — Stop Re-Reading Every Crash Report: Gre…●ARGON — gemini-4-argon is generally available as of 10/13, aimed at complex coding, agents, math and science●DEEP RES — deep-research-pro-preview-12-2025 shuts down 10/23, 6 days left. Move to deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 is GA (10/06). gemini-3.1-flash-image is deprecated with no shutdown date yet●MCP — One write-up cut an 85,000-token tool result to 310 tokens by wrapping it in an ADK FunctionTool●FLASH — gemini-3.7-flash and 3.5-flash now route automatically to newer Flash models (10/08)●NEW — Stop Re-Reading Every Crash Report: Gre…
Articles/Dev Tools
⟐ Dev Tools/2026-03-21Intermediate

Gemini × Google Apps Script — Automate Spreadsheets, Email, and Docs with AI

Learn how to call the Gemini API from Google Apps Script to automate spreadsheet analysis, email summarization, document generation, and other everyday workflows

Google Apps ScriptGemini API249Automation14SpreadsheetsGAS

Gemini × Google Apps Script for Workflow Automation

Google Apps Script (GAS) gives you programmatic access to every corner of Google Workspace — Sheets, Gmail, Docs, Calendar, Drive, and more. Pair it with the Gemini API and you unlock a new tier of automation: AI-powered data analysis in spreadsheets, automatic email triage and summarization, draft generation for documents, and much more — all without spinning up a single server.

Why GAS + Gemini?

The combination works so well because of three things.

First, zero infrastructure. Apps Script runs on Google's servers. There's nothing to deploy, no containers to manage, and no cold starts to worry about. You open the script editor and start writing.

Second, native Workspace integration. GAS has built-in services for Gmail, Sheets, Docs, Calendar, Drive, Forms, and Slides. You can read a spreadsheet, send the data to Gemini for analysis, and write the results back — all in a few lines of code.

Third, trigger-based automation. Time-driven triggers, edit triggers, and form-submit triggers let you run scripts on autopilot. A Monday-morning sales analysis, a nightly inbox digest, or an instant document draft whenever a new row appears in a sheet — all are straightforward to set up.

Getting Started

1. Get a Gemini API Key

Head to Google AI Studio (https://aistudio.google.com) and create an API key. Store it safely in script properties rather than hard-coding it.

2. Create an Apps Script Project

Open any Google Spreadsheet, go to Extensions → Apps Script, and you'll land in the script editor. First, save your API key to script properties:

// Run once to store your API key
function setApiKey() {
  const props = PropertiesService.getScriptProperties();
  props.setProperty('GEMINI_API_KEY', 'your-api-key-here');
}

3. Build a Reusable Gemini Helper

This function handles the API call and can be shared across all your workflows:

function callGemini(prompt, model = 'gemini-2.5-flash') {
  const apiKey = PropertiesService.getScriptProperties()
    .getProperty('GEMINI_API_KEY');
  const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;
 
  const payload = {
    contents: [{ parts: [{ text: prompt }] }],
    generationConfig: {
      temperature: 0.7,
      maxOutputTokens: 2048
    }
  };
 
  const response = UrlFetchApp.fetch(url, {
    method: 'post',
    contentType: 'application/json',
    payload: JSON.stringify(payload),
    muteHttpExceptions: true
  });
 
  const json = JSON.parse(response.getContentText());
  if (json.candidates && json.candidates[0]) {
    return json.candidates[0].content.parts[0].text;
  }
  throw new Error('Gemini API error: ' + response.getContentText());
}

Practical Workflows

Workflow 1: Auto-Analyze Spreadsheet Data

Feed sales figures or survey responses into Gemini and get back a structured analysis — automatically.

function analyzeSalesData() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet()
    .getSheetByName('Sales Data');
  const data = sheet.getDataRange().getValues();
  const headers = data[0];
  const rows = data.slice(1);
 
  const csvText = [headers.join(','),
    ...rows.map(row => row.join(','))
  ].join('\n');
 
  const prompt = `Analyze the following sales data and provide:
1. Overall trends
2. Category performance highlights
3. Areas that need improvement
4. Concrete action items
 
Data:
${csvText}`;
 
  const analysis = callGemini(prompt);
 
  let resultSheet = SpreadsheetApp.getActiveSpreadsheet()
    .getSheetByName('AI Analysis');
  if (!resultSheet) {
    resultSheet = SpreadsheetApp.getActiveSpreadsheet()
      .insertSheet('AI Analysis');
  }
 
  resultSheet.getRange('A1').setValue('Analysis Date');
  resultSheet.getRange('B1').setValue(new Date());
  resultSheet.getRange('A3').setValue(analysis);
}

Workflow 2: Summarize Unread Emails

Run this every morning and you'll start your day with a prioritized snapshot of your inbox.

function summarizeUnreadEmails() {
  const threads = GmailApp.search('is:unread', 0, 20);
  const summaries = [];
 
  for (const thread of threads) {
    const messages = thread.getMessages();
    const latest = messages[messages.length - 1];
 
    const prompt = `Summarize this email in 1-2 sentences and rate
its urgency as high, medium, or low.
 
Subject: ${latest.getSubject()}
From: ${latest.getFrom()}
Body: ${latest.getPlainBody().substring(0, 1000)}
 
Respond in JSON: {"summary": "...", "urgency": "high|medium|low"}`;
 
    try {
      const result = callGemini(prompt);
      const parsed = JSON.parse(
        result.replace(/```json\n?/g, '').replace(/```/g, '')
      );
      summaries.push([
        new Date(),
        latest.getFrom(),
        latest.getSubject(),
        parsed.summary,
        parsed.urgency
      ]);
    } catch (e) {
      summaries.push([
        new Date(),
        latest.getFrom(),
        latest.getSubject(),
        'Summary failed',
        '-'
      ]);
    }
  }
 
  if (summaries.length > 0) {
    const sheet = SpreadsheetApp.getActiveSpreadsheet()
      .getSheetByName('Email Digest')
      || SpreadsheetApp.getActiveSpreadsheet()
        .insertSheet('Email Digest');
    const lastRow = sheet.getLastRow();
    sheet.getRange(lastRow + 1, 1, summaries.length, 5)
      .setValues(summaries);
  }
}

Workflow 3: Generate Document Drafts

List your topics in a spreadsheet and let Gemini produce first drafts as Google Docs.

function generateDocumentDraft() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet()
    .getSheetByName('Document Requests');
  const data = sheet.getDataRange().getValues();
 
  for (let i = 1; i < data.length; i++) {
    const [topic, audience, length, status] = data[i];
    if (status === 'Done') continue;
 
    const prompt = `Write a business document draft on the
following topic.
 
Topic: ${topic}
Target audience: ${audience}
Approximate length: ${length}
 
Use clear headings and a professional tone.`;
 
    const draft = callGemini(prompt);
 
    const doc = DocumentApp.create(`[AI Draft] ${topic}`);
    doc.getBody().setText(draft);
 
    sheet.getRange(i + 1, 4).setValue('Done');
    sheet.getRange(i + 1, 5).setValue(doc.getUrl());
  }
}

Setting Up Triggers

Use GAS triggers to run your workflows hands-free.

function createTriggers() {
  // Summarize emails every morning at 8 AM
  ScriptApp.newTrigger('summarizeUnreadEmails')
    .timeBased()
    .everyDays(1)
    .atHour(8)
    .create();
 
  // Run sales analysis every Monday at 9 AM
  ScriptApp.newTrigger('analyzeSalesData')
    .timeBased()
    .onWeekDay(ScriptApp.WeekDay.MONDAY)
    .atHour(9)
    .create();
}

You can also configure triggers through the Apps Script editor UI under Triggers in the left sidebar. For complex scheduling, the programmatic approach gives you more flexibility.

Error Handling and Rate Limits

In production, always wrap API calls with retry logic:

function callGeminiWithRetry(prompt, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return callGemini(prompt);
    } catch (e) {
      if (attempt === maxRetries - 1) throw e;
      Utilities.sleep(Math.pow(2, attempt) * 1000);
    }
  }
}

Keep in mind that free Google accounts have a 6-minute execution limit per run and a 90-minute daily cap. If you're processing large datasets, split the work into batches and persist progress in script properties so subsequent runs pick up where the last one left off.

Security Best Practices

Never hard-code your API key. Always use PropertiesService.getScriptProperties(). Be aware that anyone with editor access to the script can read those properties, so restrict sharing accordingly.

Before sending sensitive data to the Gemini API, check your organization's data policies. Workspace admins may have restrictions on external API calls from Apps Script. For enterprise use, consider routing requests through Vertex AI with IAM-based authentication instead of a plain API key.

Wrapping Up

Google Apps Script paired with the Gemini API is one of the lowest-friction ways to bring AI into your daily workflows. No servers, no deployment pipelines — just a script editor and a few dozen lines of code. Start with a single workflow, see the time savings add up, and expand from there.

Share

Thank You for Reading

Gemini Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

⟐ Dev Tools2026-09-10
Matching name variants in a print catalog: normalize first, then ask Gemini for candidates
When the same artist appears under three spellings, asking Gemini whether two names are the same person quietly merges different generations. Here is the two-layer alternative — deterministic normalization first, model-generated candidates second — with working code and a cost estimate.
⟐ Dev Tools2026-09-06
Icon-Only Buttons Can Stay Silent for Screen Readers, Even When Every Translation Is in Place
A fully translated app can still read as silence. Here is how I collect icon elements and labels from iOS and Android, settle everything mechanical locally, and send only the wording to Gemini — with the actual output from each stage.
⟐ Dev Tools2026-09-02
An agreement-rate gate approves the model swap, then your category shares move
Swapping the model behind an image classification batch can pass a golden-set agreement gate while category shares quietly shift. I measured the sample sizes each check really needs and rebuilt the gate as a paired comparison.